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:

Previous
From: Marko Kreen
Date:
Subject: Re: latest pgcrypto patches cause compile errors
Next
From: Bruce Momjian
Date:
Subject: Re: [PATCHES] Proposed TODO: --encoding option for pg_dump