Andrew Dunstan wrote:
>
>
>>
>> Why --- what else is needed beyond the addition of those clauses to the
>> one query?
>>
>>
>
> There are tests for both the function and the handler based on
> finfo->dobj.namespace->dump that inhibit output if we're in the
> catalog schema.
>
> If we go down this path ISTM the simplest thing would be to add a
> field to the FuncInfo object to allow it to be marked as a a
> handler/validator.
demo patch attached. I need to fix up comments, but I think it works.
Comments welcome
>
> Also, I think pg_dump *never* quotes the handler name or qualifies it
> with a schema name - that looks like it might be a bug, regardless of
> this.
I was wrong about this.
cheers
andrew
Index: src/bin/pg_dump/pg_dump.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v
retrieving revision 1.410
diff -c -r1.410 pg_dump.c
*** src/bin/pg_dump/pg_dump.c 21 Jun 2005 20:45:44 -0000 1.410
--- src/bin/pg_dump/pg_dump.c 26 Jun 2005 21:58:00 -0000
***************
*** 2146,2151 ****
--- 2146,2152 ----
int i_proargtypes;
int i_prorettype;
int i_proacl;
+ int i_is_pl_handler;
/* Make sure we are in proper schema */
selectSourceSchema("pg_catalog");
***************
*** 2158,2168 ****
"SELECT tableoid, oid, proname, prolang, "
"pronargs, proargtypes, prorettype, proacl, "
"pronamespace, "
! "(select usename from pg_user where proowner = usesysid) as usename "
"FROM pg_proc "
"WHERE NOT proisagg "
! "AND pronamespace != "
! "(select oid from pg_namespace where nspname = 'pg_catalog')");
}
else if (g_fout->remoteVersion >= 70100)
{
--- 2159,2175 ----
"SELECT tableoid, oid, proname, prolang, "
"pronargs, proargtypes, prorettype, proacl, "
"pronamespace, "
! "(select usename from pg_user where proowner = usesysid) as usename, "
! "CASE WHEN oid in (select lanplcallfoid from pg_language where lanplcallfoid != 0) THEN
true"
! " WHEN oid in (select lanvalidator from pg_language where lanplcallfoid != 0) THEN true "
! " ELSE false END AS is_pl_handler "
"FROM pg_proc "
"WHERE NOT proisagg "
! "AND (pronamespace != "
! " (select oid from pg_namespace where nspname = 'pg_catalog')"
! " OR oid in (select lanplcallfoid from pg_language where lanplcallfoid != 0) "
! " OR oid in (select lanvalidator from pg_language where lanplcallfoid != 0))"
! );
}
else if (g_fout->remoteVersion >= 70100)
{
***************
*** 2171,2177 ****
"pronargs, proargtypes, prorettype, "
"'{=X}' as proacl, "
"0::oid as pronamespace, "
! "(select usename from pg_user where proowner = usesysid) as usename "
"FROM pg_proc "
"where pg_proc.oid > '%u'::oid",
g_last_builtin_oid);
--- 2178,2185 ----
"pronargs, proargtypes, prorettype, "
"'{=X}' as proacl, "
"0::oid as pronamespace, "
! "(select usename from pg_user where proowner = usesysid) as usename, "
! "false AS is_pl_handler "
"FROM pg_proc "
"where pg_proc.oid > '%u'::oid",
g_last_builtin_oid);
***************
*** 2185,2191 ****
"pronargs, proargtypes, prorettype, "
"'{=X}' as proacl, "
"0::oid as pronamespace, "
! "(select usename from pg_user where proowner = usesysid) as usename "
"FROM pg_proc "
"where pg_proc.oid > '%u'::oid",
g_last_builtin_oid);
--- 2193,2200 ----
"pronargs, proargtypes, prorettype, "
"'{=X}' as proacl, "
"0::oid as pronamespace, "
! "(select usename from pg_user where proowner = usesysid) as usename, "
! "false AS is_pl_handler "
"FROM pg_proc "
"where pg_proc.oid > '%u'::oid",
g_last_builtin_oid);
***************
*** 2210,2215 ****
--- 2219,2225 ----
i_proargtypes = PQfnumber(res, "proargtypes");
i_prorettype = PQfnumber(res, "prorettype");
i_proacl = PQfnumber(res, "proacl");
+ i_is_pl_handler = PQfnumber(res,"is_pl_handler");
for (i = 0; i < ntups; i++)
{
***************
*** 2225,2230 ****
--- 2235,2241 ----
finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
finfo[i].proacl = strdup(PQgetvalue(res, i, i_proacl));
finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
+ finfo[i].isProlangFunc = strcmp(PQgetvalue(res, i, i_is_pl_handler), "t") == 0;
if (finfo[i].nargs == 0)
finfo[i].argtypes = NULL;
else
***************
*** 4937,4943 ****
if (funcInfo == NULL)
return;
! if (!funcInfo->dobj.namespace->dump)
return;
if (OidIsValid(plang->lanvalidator))
--- 4948,4954 ----
if (funcInfo == NULL)
return;
! if (!funcInfo->isProlangFunc && !funcInfo->dobj.namespace->dump)
return;
if (OidIsValid(plang->lanvalidator))
***************
*** 5136,5144 ****
char **argnames = NULL;
/* Dump only funcs in dumpable namespaces */
! if (!finfo->dobj.namespace->dump || dataOnly)
return;
query = createPQExpBuffer();
q = createPQExpBuffer();
delqry = createPQExpBuffer();
--- 5147,5156 ----
char **argnames = NULL;
/* Dump only funcs in dumpable namespaces */
! if ((!finfo->isProlangFunc && !finfo->dobj.namespace->dump) || dataOnly)
return;
+
query = createPQExpBuffer();
q = createPQExpBuffer();
delqry = createPQExpBuffer();
Index: src/bin/pg_dump/pg_dump.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/pg_dump/pg_dump.h,v
retrieving revision 1.115
diff -c -r1.115 pg_dump.h
*** src/bin/pg_dump/pg_dump.h 31 Dec 2004 22:03:08 -0000 1.115
--- src/bin/pg_dump/pg_dump.h 26 Jun 2005 21:58:00 -0000
***************
*** 131,136 ****
--- 131,137 ----
Oid *argtypes;
Oid prorettype;
char *proacl;
+ bool isProlangFunc;
} FuncInfo;
/* AggInfo is a superset of FuncInfo */
Index: src/bin/scripts/createlang.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/scripts/createlang.c,v
retrieving revision 1.17
diff -c -r1.17 createlang.c
*** src/bin/scripts/createlang.c 22 Jun 2005 16:45:50 -0000 1.17
--- src/bin/scripts/createlang.c 26 Jun 2005 21:58:02 -0000
***************
*** 260,279 ****
if (!handlerexists)
appendPQExpBuffer(&sql,
! "CREATE FUNCTION \"%s\" () RETURNS language_handler AS '%s/%s' LANGUAGE C;\n",
handler, pglib, object);
if (!validatorexists)
appendPQExpBuffer(&sql,
! "CREATE FUNCTION \"%s\" (oid) RETURNS void AS '%s/%s' LANGUAGE C;\n",
validator, pglib, object);
appendPQExpBuffer(&sql,
! "CREATE %sLANGUAGE \"%s\" HANDLER \"%s\"",
(trusted ? "TRUSTED " : ""), langname, handler);
if (validator)
! appendPQExpBuffer(&sql, " VALIDATOR \"%s\"", validator);
appendPQExpBuffer(&sql, ";\n");
--- 260,279 ----
if (!handlerexists)
appendPQExpBuffer(&sql,
! "CREATE FUNCTION pg_catalog.\"%s\" () RETURNS language_handler AS '%s/%s' LANGUAGE C;\n",
handler, pglib, object);
if (!validatorexists)
appendPQExpBuffer(&sql,
! "CREATE FUNCTION pg_catalog.\"%s\" (oid) RETURNS void AS '%s/%s' LANGUAGE C;\n",
validator, pglib, object);
appendPQExpBuffer(&sql,
! "CREATE %sLANGUAGE \"%s\" HANDLER pg_catalog.\"%s\"",
(trusted ? "TRUSTED " : ""), langname, handler);
if (validator)
! appendPQExpBuffer(&sql, " VALIDATOR pg_catalog.\"%s\"", validator);
appendPQExpBuffer(&sql, ";\n");
Index: src/bin/scripts/droplang.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/scripts/droplang.c,v
retrieving revision 1.15
diff -c -r1.15 droplang.c
*** src/bin/scripts/droplang.c 14 Jun 2005 02:57:45 -0000 1.15
--- src/bin/scripts/droplang.c 26 Jun 2005 21:58:02 -0000
***************
*** 52,57 ****
--- 52,59 ----
Oid lanvalidator;
char *handler;
char *validator;
+ char *handler_ns;
+ char *validator_ns;
bool keephandler;
bool keepvalidator;
***************
*** 212,224 ****
*/
if (!keephandler)
{
! printfPQExpBuffer(&sql, "SELECT proname FROM pg_proc WHERE oid = %u;", lanplcallfoid);
result = executeQuery(conn, sql.data, progname, echo);
handler = strdup(PQgetvalue(result, 0, 0));
PQclear(result);
}
else
handler = NULL;
/*
* Check that the validator function isn't used by some other language
--- 214,230 ----
*/
if (!keephandler)
{
! printfPQExpBuffer(&sql, "SELECT proname, (SELECT nspname FROM pg_namespace ns WHERE ns.oid = pronamespace) AS
pronsFROM pg_proc WHERE oid = %u;", lanplcallfoid);
result = executeQuery(conn, sql.data, progname, echo);
handler = strdup(PQgetvalue(result, 0, 0));
+ handler_ns = strdup(PQgetvalue(result, 0, 1));
PQclear(result);
}
else
+ {
handler = NULL;
+ handler_ns = NULL;
+ }
/*
* Check that the validator function isn't used by some other language
***************
*** 241,262 ****
*/
if (!keepvalidator)
{
! printfPQExpBuffer(&sql, "SELECT proname FROM pg_proc WHERE oid = %u;", lanvalidator);
result = executeQuery(conn, sql.data, progname, echo);
validator = strdup(PQgetvalue(result, 0, 0));
PQclear(result);
}
else
validator = NULL;
/*
* Drop the language and the functions
*/
printfPQExpBuffer(&sql, "DROP LANGUAGE \"%s\";\n", langname);
if (!keephandler)
! appendPQExpBuffer(&sql, "DROP FUNCTION \"%s\" ();\n", handler);
if (!keepvalidator)
! appendPQExpBuffer(&sql, "DROP FUNCTION \"%s\" (oid);\n", validator);
if (echo)
printf("%s", sql.data);
result = PQexec(conn, sql.data);
--- 247,272 ----
*/
if (!keepvalidator)
{
! printfPQExpBuffer(&sql, "SELECT proname, (SELECT nspname FROM pg_namespace ns WHERE ns.oid = pronamespace) AS
pronsFROM pg_proc WHERE oid = %u;", lanvalidator);
result = executeQuery(conn, sql.data, progname, echo);
validator = strdup(PQgetvalue(result, 0, 0));
+ validator_ns = strdup(PQgetvalue(result, 0, 1));
PQclear(result);
}
else
+ {
validator = NULL;
+ validator_ns = NULL;
+ }
/*
* Drop the language and the functions
*/
printfPQExpBuffer(&sql, "DROP LANGUAGE \"%s\";\n", langname);
if (!keephandler)
! appendPQExpBuffer(&sql, "DROP FUNCTION \"%s\".\"%s\" ();\n", handler_ns, handler);
if (!keepvalidator)
! appendPQExpBuffer(&sql, "DROP FUNCTION \"%s\".\"%s\" (oid);\n", validator_ns, validator);
if (echo)
printf("%s", sql.data);
result = PQexec(conn, sql.data);