* by PostgreSQL
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.404 2005/03/14 18:57:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.405 2005/04/01 18:35:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static void getDependencies(void);
static void getDomainConstraints(TypeInfo *tinfo);
static void getTableData(TableInfo *tblinfo, int numTables, bool oids);
-static char *format_function_signature(FuncInfo *finfo, char **argnames,
- bool honor_quotes);
+static char *format_function_arguments(FuncInfo *finfo, int nallargs,
+ char **allargtypes,
+ char **argmodes,
+ char **argnames);
+static char *format_function_signature(FuncInfo *finfo, bool honor_quotes);
static const char *convertRegProcReference(const char *proc);
static const char *convertOperatorReference(const char *opr);
static Oid findLastBuiltinOid_V71(const char *);
}
/*
- * format_function_signature: generate function name and argument list
+ * format_function_arguments: generate function name and argument list
*
* The argument type names are qualified if needed. The function name
* is never qualified.
*
- * argnames may be NULL if no names are available.
+ * Any or all of allargtypes, argmodes, argnames may be NULL.
*/
static char *
-format_function_signature(FuncInfo *finfo, char **argnames,
- bool honor_quotes)
+format_function_arguments(FuncInfo *finfo, int nallargs,
+ char **allargtypes,
+ char **argmodes,
+ char **argnames)
{
PQExpBufferData fn;
int j;
initPQExpBuffer(&fn);
- if (honor_quotes)
- appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
- else
- appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
- for (j = 0; j < finfo->nargs; j++)
+ appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
+ for (j = 0; j < nallargs; j++)
{
+ Oid typid;
char *typname;
- char *argname;
+ const char *argmode;
+ const char *argname;
- typname = getFormattedTypeName(finfo->argtypes[j], zeroAsOpaque);
+ typid = allargtypes ? atooid(allargtypes[j]) : finfo->argtypes[j];
+ typname = getFormattedTypeName(typid, zeroAsOpaque);
+
+ if (argmodes)
+ {
+ switch (argmodes[j][0])
+ {
+ case 'i':
+ argmode = "";
+ break;
+ case 'o':
+ argmode = "OUT ";
+ break;
+ case 'b':
+ argmode = "INOUT ";
+ break;
+ default:
+ write_msg(NULL, "WARNING: bogus value in proargmodes array\n");
+ argmode = "";
+ break;
+ }
+ }
+ else
+ argmode = "";
argname = argnames ? argnames[j] : (char *) NULL;
if (argname && argname[0] == '\0')
argname = NULL;
- appendPQExpBuffer(&fn, "%s%s%s%s",
+ appendPQExpBuffer(&fn, "%s%s%s%s%s",
(j > 0) ? ", " : "",
+ argmode,
argname ? fmtId(argname) : "",
argname ? " " : "",
typname);
return fn.data;
}
+/*
+ * format_function_signature: generate function name and argument list
+ *
+ * This is like format_function_arguments except that only a minimal
+ * list of input argument types is generated; this is sufficient to
+ * reference the function, but not to define it.
+ *
+ * If honor_quotes is false then the function name is never quoted.
+ * This is appropriate for use in TOC tags, but not in SQL commands.
+ */
+static char *
+format_function_signature(FuncInfo *finfo, bool honor_quotes)
+{
+ PQExpBufferData fn;
+ int j;
+
+ initPQExpBuffer(&fn);
+ if (honor_quotes)
+ appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
+ else
+ appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
+ for (j = 0; j < finfo->nargs; j++)
+ {
+ char *typname;
+
+ typname = getFormattedTypeName(finfo->argtypes[j], zeroAsOpaque);
+
+ appendPQExpBuffer(&fn, "%s%s",
+ (j > 0) ? ", " : "",
+ typname);
+ free(typname);
+ }
+ appendPQExpBuffer(&fn, ")");
+ return fn.data;
+}
+
/*
* dumpFunc:
char *proretset;
char *prosrc;
char *probin;
+ char *proallargtypes;
+ char *proargmodes;
char *proargnames;
char *provolatile;
char *proisstrict;
char *prosecdef;
char *lanname;
char *rettypename;
- char **argnamearray = NULL;
+ int nallargs;
+ char **allargtypes = NULL;
+ char **argmodes = NULL;
+ char **argnames = NULL;
/* Dump only funcs in dumpable namespaces */
if (!finfo->dobj.namespace->dump || dataOnly)
selectSourceSchema(finfo->dobj.namespace->dobj.name);
/* Fetch function-specific details */
- if (g_fout->remoteVersion >= 80000)
+ if (g_fout->remoteVersion >= 80100)
+ {
+ appendPQExpBuffer(query,
+ "SELECT proretset, prosrc, probin, "
+ "proallargtypes, proargmodes, proargnames, "
+ "provolatile, proisstrict, prosecdef, "
+ "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
+ "FROM pg_catalog.pg_proc "
+ "WHERE oid = '%u'::pg_catalog.oid",
+ finfo->dobj.catId.oid);
+ }
+ else if (g_fout->remoteVersion >= 80000)
{
appendPQExpBuffer(query,
"SELECT proretset, prosrc, probin, "
+ "null::text as proallargtypes, "
+ "null::text as proargmodes, "
"proargnames, "
"provolatile, proisstrict, prosecdef, "
"(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
{
appendPQExpBuffer(query,
"SELECT proretset, prosrc, probin, "
+ "null::text as proallargtypes, "
+ "null::text as proargmodes, "
"null::text as proargnames, "
"provolatile, proisstrict, prosecdef, "
"(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
{
appendPQExpBuffer(query,
"SELECT proretset, prosrc, probin, "
+ "null::text as proallargtypes, "
+ "null::text as proargmodes, "
"null::text as proargnames, "
"case when proiscachable then 'i' else 'v' end as provolatile, "
"proisstrict, "
{
appendPQExpBuffer(query,
"SELECT proretset, prosrc, probin, "
+ "null::text as proallargtypes, "
+ "null::text as proargmodes, "
"null::text as proargnames, "
"case when proiscachable then 'i' else 'v' end as provolatile, "
"'f'::boolean as proisstrict, "
proretset = PQgetvalue(res, 0, PQfnumber(res, "proretset"));
prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
+ proallargtypes = PQgetvalue(res, 0, PQfnumber(res, "proallargtypes"));
+ proargmodes = PQgetvalue(res, 0, PQfnumber(res, "proargmodes"));
proargnames = PQgetvalue(res, 0, PQfnumber(res, "proargnames"));
provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
}
}
+ nallargs = finfo->nargs; /* unless we learn different from allargs */
+
+ if (proallargtypes && *proallargtypes)
+ {
+ int nitems = 0;
+
+ if (!parsePGArray(proallargtypes, &allargtypes, &nitems) ||
+ nitems < finfo->nargs)
+ {
+ write_msg(NULL, "WARNING: could not parse proallargtypes array\n");
+ if (allargtypes)
+ free(allargtypes);
+ allargtypes = NULL;
+ }
+ else
+ nallargs = nitems;
+ }
+
+ if (proargmodes && *proargmodes)
+ {
+ int nitems = 0;
+
+ if (!parsePGArray(proargmodes, &argmodes, &nitems) ||
+ nitems != nallargs)
+ {
+ write_msg(NULL, "WARNING: could not parse proargmodes array\n");
+ if (argmodes)
+ free(argmodes);
+ argmodes = NULL;
+ }
+ }
+
if (proargnames && *proargnames)
{
int nitems = 0;
- if (!parsePGArray(proargnames, &argnamearray, &nitems) ||
- nitems != finfo->nargs)
+ if (!parsePGArray(proargnames, &argnames, &nitems) ||
+ nitems != nallargs)
{
write_msg(NULL, "WARNING: could not parse proargnames array\n");
- if (argnamearray)
- free(argnamearray);
- argnamearray = NULL;
+ if (argnames)
+ free(argnames);
+ argnames = NULL;
}
}
- funcsig = format_function_signature(finfo, argnamearray, true);
- funcsig_tag = format_function_signature(finfo, NULL, false);
+ funcsig = format_function_arguments(finfo, nallargs, allargtypes,
+ argmodes, argnames);
+ funcsig_tag = format_function_signature(finfo, false);
/*
* DROP must be fully qualified in case same name appears in
destroyPQExpBuffer(asPart);
free(funcsig);
free(funcsig_tag);
- if (argnamearray)
- free(argnamearray);
+ if (allargtypes)
+ free(allargtypes);
+ if (argmodes)
+ free(argmodes);
+ if (argnames)
+ free(argnames);
}
appendPQExpBuffer(defqry, "WITH FUNCTION %s.",
fmtId(funcInfo->dobj.namespace->dobj.name));
appendPQExpBuffer(defqry, "%s",
- format_function_signature(funcInfo, NULL, true));
+ format_function_signature(funcInfo, true));
}
if (cast->castcontext == 'a')
free(aggsig);
free(aggsig_tag);
- aggsig = format_function_signature(&agginfo->aggfn, NULL, true);
- aggsig_tag = format_function_signature(&agginfo->aggfn, NULL, false);
+ aggsig = format_function_signature(&agginfo->aggfn, true);
+ aggsig_tag = format_function_signature(&agginfo->aggfn, false);
dumpACL(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId,
"FUNCTION",