Re: language handlers in public schema - Mailing list pgsql-hackers
From | Bruce Momjian |
---|---|
Subject | Re: language handlers in public schema |
Date | |
Msg-id | 200507101426.j6AEQRL11215@candle.pha.pa.us Whole thread Raw |
In response to | language handlers in public schema (Andrew Dunstan <andrew@dunslane.net>) |
List | pgsql-hackers |
Patch applied. Thanks. --------------------------------------------------------------------------- Andrew Dunstan wrote: > > This patch implements putting language handlers for the optional PLs > into pg_catalog rather than public, and supports dumping languages whose > handlers are found there. This will make it easier to drop the public > schema if desired. > > Unlike the previous patch, the comments have been updated and I have > reformatted some code to meet Alvarro's request to stick to 80 cols. (I > actually aghree with this - it makes printing the code much nicer). > > I think I did the right thing w.r.t versions earlier than 7.3, but I > have no real way of checking, so that should be checked by someone with > more/older knowledge than me ;-) > > 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 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'::regtypeAND 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'::regtypeAND 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); > > ---------------------------(end of broadcast)--------------------------- > TIP 5: Have you checked our extensive FAQ? > > http://www.postgresql.org/docs/faq -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001+ If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania19073
pgsql-hackers by date: