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 28 Jun 2005 00:22:34 -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"); *************** *** 2154,2168 **** if (g_fout->remoteVersion >= 70300) { appendPQExpBuffer(query, "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) { --- 2155,2190 ---- if (g_fout->remoteVersion >= 70300) { + /* + * We now collect info on pg_catalog resident functions, but + * only if they are language call handlers or validators, and + * only for non-default languages (i.e. not internal/C/SQL). + */ appendPQExpBuffer(query, "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); --- 2193,2201 ---- "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); *************** *** 2180,2191 **** { appendPQExpBuffer(query, "SELECT " ! "(SELECT oid FROM pg_class WHERE relname = 'pg_proc') AS tableoid, " "oid, proname, prolang, " "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); --- 2204,2218 ---- { appendPQExpBuffer(query, "SELECT " ! "(SELECT oid FROM pg_class " ! " WHERE relname = 'pg_proc') AS tableoid, " "oid, proname, prolang, " "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 **** --- 2237,2243 ---- 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++) { *************** *** 2218,2230 **** finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid)); AssignDumpId(&finfo[i].dobj); finfo[i].dobj.name = strdup(PQgetvalue(res, i, i_proname)); ! finfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)), finfo[i].dobj.catId.oid); finfo[i].usename = strdup(PQgetvalue(res, i, i_usename)); finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang)); 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)); if (finfo[i].nargs == 0) finfo[i].argtypes = NULL; else --- 2246,2261 ---- finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid)); AssignDumpId(&finfo[i].dobj); finfo[i].dobj.name = strdup(PQgetvalue(res, i, i_proname)); ! finfo[i].dobj.namespace = ! findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)), finfo[i].dobj.catId.oid); finfo[i].usename = strdup(PQgetvalue(res, i, i_usename)); finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang)); 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 *************** *** 2235,2241 **** } if (strlen(finfo[i].usename) == 0) ! write_msg(NULL, "WARNING: owner of function \"%s\" appears to be invalid\n", finfo[i].dobj.name); } --- 2266,2273 ---- } if (strlen(finfo[i].usename) == 0) ! write_msg(NULL, ! "WARNING: owner of function \"%s\" appears to be invalid\n", finfo[i].dobj.name); } *************** *** 4921,4943 **** return; /* ! * Current theory is to dump PLs iff their underlying functions will ! * be dumped (are in a dumpable namespace, or have a non-system OID in ! * pre-7.3 databases). Actually, we treat the PL itself as being in * the underlying function's namespace, though it isn't really. This * avoids searchpath problems for the HANDLER clause. * - * If the underlying function is in the pg_catalog namespace, we won't - * have loaded it into finfo[] at all; therefore, treat failure to - * find it in finfo[] as indicating we shouldn't dump it, not as an - * error condition. Ditto for the validator. */ funcInfo = findFuncByOid(plang->lanplcallfoid); if (funcInfo == NULL) return; ! if (!funcInfo->dobj.namespace->dump) return; if (OidIsValid(plang->lanvalidator)) --- 4953,4971 ---- return; /* ! * We dump PLs iff their underlying call handler functions have been ! * marked as language functions (or have a non-system OID in ! * pre-7.3 databases). We treat the PL itself as being in * the underlying function's namespace, though it isn't really. This * avoids searchpath problems for the HANDLER clause. * */ funcInfo = findFuncByOid(plang->lanplcallfoid); if (funcInfo == NULL) return; ! if (!funcInfo->isProlangFunc && !funcInfo->dobj.namespace->dump) return; if (OidIsValid(plang->lanvalidator)) *************** *** 5135,5144 **** char **argmodes = NULL; char **argnames = NULL; ! /* Dump only funcs in dumpable namespaces */ ! if (!finfo->dobj.namespace->dump || dataOnly) return; query = createPQExpBuffer(); q = createPQExpBuffer(); delqry = createPQExpBuffer(); --- 5163,5173 ---- char **argmodes = NULL; char **argnames = NULL; ! /* Dump only funcs in dumpable namespaces, or needed language handlers */ ! 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 28 Jun 2005 00:22:34 -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 28 Jun 2005 00:22:34 -0000 *************** *** 140,146 **** conn = connectDatabase(dbname, host, port, username, password, progname); ! printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", (CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" FROM pg_language WHERE lanispl IS TRUE;", _("Name"), _("yes"), _("no"), _("Trusted?")); result = executeQuery(conn, sql.data, progname, echo); memset(&popt, 0, sizeof(popt)); --- 140,149 ---- conn = connectDatabase(dbname, host, port, username, password, progname); ! printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", (CASE WHEN lanpltrusted " ! "THEN '%s' ELSE '%s' END) as \"%s\" FROM pg_language " ! "WHERE lanispl IS TRUE;", ! _("Name"), _("yes"), _("no"), _("Trusted?")); result = executeQuery(conn, sql.data, progname, echo); memset(&popt, 0, sizeof(popt)); *************** *** 209,216 **** } else { ! fprintf(stderr, _("%s: unsupported language \"%s\"\n"), progname, langname); ! fprintf(stderr, _("Supported languages are plpgsql, pltcl, pltclu, plperl, plperlu, and plpythonu.\n")); exit(1); } --- 212,221 ---- } else { ! fprintf(stderr, _("%s: unsupported language \"%s\"\n"), ! progname, langname); ! fprintf(stderr, _("Supported languages are plpgsql, pltcl, pltclu, " ! "plperl, plperlu, and plpythonu.\n")); exit(1); } *************** *** 219,231 **** /* * Make sure the language isn't already installed */ ! printfPQExpBuffer(&sql, "SELECT oid FROM pg_language WHERE lanname = '%s';", langname); result = executeQuery(conn, sql.data, progname, echo); if (PQntuples(result) > 0) { PQfinish(conn); fprintf(stderr, ! _("%s: language \"%s\" is already installed in database \"%s\"\n"), progname, langname, dbname); /* separate exit status for "already installed" */ exit(2); --- 224,239 ---- /* * Make sure the language isn't already installed */ ! printfPQExpBuffer(&sql, ! "SELECT oid FROM pg_language WHERE lanname = '%s';", ! langname); result = executeQuery(conn, sql.data, progname, echo); if (PQntuples(result) > 0) { PQfinish(conn); fprintf(stderr, ! _("%s: language \"%s\" is already installed in " ! "database \"%s\"\n"), progname, langname, dbname); /* separate exit status for "already installed" */ exit(2); *************** *** 235,241 **** /* * Check whether the call handler exists */ ! printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' AND prorettype = 'pg_catalog.language_handler'::regtype AND pronargs = 0;", handler); result = executeQuery(conn, sql.data, progname, echo); handlerexists = (PQntuples(result) > 0); PQclear(result); --- 243,251 ---- /* * Check whether the call handler exists */ ! printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' " ! "AND prorettype = 'pg_catalog.language_handler'::regtype " ! "AND pronargs = 0;", handler); result = executeQuery(conn, sql.data, progname, echo); handlerexists = (PQntuples(result) > 0); PQclear(result); *************** *** 245,251 **** */ if (validator) { ! printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' AND proargtypes[0] = 'pg_catalog.oid'::regtype AND pronargs = 1;", validator); result = executeQuery(conn, sql.data, progname, echo); validatorexists = (PQntuples(result) > 0); PQclear(result); --- 255,263 ---- */ if (validator) { ! printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s'" ! " AND proargtypes[0] = 'pg_catalog.oid'::regtype " ! " AND pronargs = 1;", validator); result = executeQuery(conn, sql.data, progname, echo); validatorexists = (PQntuples(result) > 0); PQclear(result); *************** *** 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"); --- 272,293 ---- 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 28 Jun 2005 00:22:34 -0000 *************** *** 52,57 **** --- 52,59 ---- Oid lanvalidator; char *handler; char *validator; + char *handler_ns; + char *validator_ns; bool keephandler; bool keepvalidator; *************** *** 135,143 **** { printQueryOpt popt; ! conn = connectDatabase(dbname, host, port, username, password, progname); ! printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", (CASE WHEN lanpltrusted THEN '%s' ELSE '%s' END) as \"%s\" FROM pg_language WHERE lanispl IS TRUE;", _("Name"), _("yes"), _("no"), _("Trusted?")); result = executeQuery(conn, sql.data, progname, echo); memset(&popt, 0, sizeof(popt)); --- 137,149 ---- { printQueryOpt popt; ! conn = connectDatabase(dbname, host, port, username, password, ! progname); ! printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", (CASE " ! "WHEN lanpltrusted THEN '%s' ELSE '%s' END) " ! "as \"%s\" FROM pg_language WHERE lanispl IS TRUE;", ! _("Name"), _("yes"), _("no"), _("Trusted?")); result = executeQuery(conn, sql.data, progname, echo); memset(&popt, 0, sizeof(popt)); *************** *** 153,160 **** if (langname == NULL) { ! fprintf(stderr, _("%s: missing required argument language name\n"), progname); ! fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } --- 159,168 ---- if (langname == NULL) { ! fprintf(stderr, _("%s: missing required argument language name\n"), ! progname); ! fprintf(stderr, _("Try \"%s --help\" for more information.\n"), ! progname); exit(1); } *************** *** 168,179 **** * Make sure the language is installed and find the OIDs of the * handler and validator functions */ ! printfPQExpBuffer(&sql, "SELECT lanplcallfoid, lanvalidator FROM pg_language WHERE lanname = '%s' AND lanispl;", langname); result = executeQuery(conn, sql.data, progname, echo); if (PQntuples(result) == 0) { PQfinish(conn); ! fprintf(stderr, _("%s: language \"%s\" is not installed in database \"%s\"\n"), progname, langname, dbname); exit(1); } --- 176,190 ---- * Make sure the language is installed and find the OIDs of the * handler and validator functions */ ! printfPQExpBuffer(&sql, "SELECT lanplcallfoid, lanvalidator " ! "FROM pg_language WHERE lanname = '%s' AND lanispl;", ! langname); result = executeQuery(conn, sql.data, progname, echo); if (PQntuples(result) == 0) { PQfinish(conn); ! fprintf(stderr, _("%s: language \"%s\" is not installed in " ! "database \"%s\"\n"), progname, langname, dbname); exit(1); } *************** *** 184,196 **** /* * Check that there are no functions left defined in that language */ ! printfPQExpBuffer(&sql, "SELECT count(proname) FROM pg_proc P, pg_language L WHERE P.prolang = L.oid AND L.lanname = '%s';", langname); result = executeQuery(conn, sql.data, progname, echo); if (strcmp(PQgetvalue(result, 0, 0), "0") != 0) { PQfinish(conn); fprintf(stderr, ! _("%s: still %s functions declared in language \"%s\"; language not removed\n"), progname, PQgetvalue(result, 0, 0), langname); exit(1); } --- 195,210 ---- /* * Check that there are no functions left defined in that language */ ! printfPQExpBuffer(&sql, "SELECT count(proname) FROM pg_proc P, " ! "pg_language L WHERE P.prolang = L.oid " ! "AND L.lanname = '%s';", langname); result = executeQuery(conn, sql.data, progname, echo); if (strcmp(PQgetvalue(result, 0, 0), "0") != 0) { PQfinish(conn); fprintf(stderr, ! _("%s: still %s functions declared in language \"%s\"; " ! "language not removed\n"), progname, PQgetvalue(result, 0, 0), langname); exit(1); } *************** *** 199,205 **** /* * Check that the handler function isn't used by some other language */ ! printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language WHERE lanplcallfoid = %u AND lanname <> '%s';", lanplcallfoid, langname); result = executeQuery(conn, sql.data, progname, echo); if (strcmp(PQgetvalue(result, 0, 0), "0") == 0) keephandler = false; --- 213,221 ---- /* * Check that the handler function isn't used by some other language */ ! printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language " ! "WHERE lanplcallfoid = %u AND lanname <> '%s';", ! lanplcallfoid, langname); result = executeQuery(conn, sql.data, progname, echo); if (strcmp(PQgetvalue(result, 0, 0), "0") == 0) keephandler = false; *************** *** 212,231 **** */ 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 */ if (OidIsValid(lanvalidator)) { ! printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language WHERE lanvalidator = %u AND lanname <> '%s';", lanvalidator, langname); result = executeQuery(conn, sql.data, progname, echo); if (strcmp(PQgetvalue(result, 0, 0), "0") == 0) keepvalidator = false; --- 228,256 ---- */ if (!keephandler) { ! printfPQExpBuffer(&sql, "SELECT proname, (SELECT nspname " ! "FROM pg_namespace ns WHERE ns.oid = pronamespace) " ! "AS prons FROM 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 */ if (OidIsValid(lanvalidator)) { ! printfPQExpBuffer(&sql, "SELECT count(*) FROM pg_language WHERE " ! "lanvalidator = %u AND lanname <> '%s';", ! lanvalidator, langname); result = executeQuery(conn, sql.data, progname, echo); if (strcmp(PQgetvalue(result, 0, 0), "0") == 0) keepvalidator = false; *************** *** 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); --- 266,296 ---- */ if (!keepvalidator) { ! printfPQExpBuffer(&sql, "SELECT proname, (SELECT nspname " ! "FROM pg_namespace ns WHERE ns.oid = pronamespace) " ! "AS prons FROM 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);