Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0793108

Browse files
committed
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 ;-) Andrew Dunstan
1 parent d51df91 commit 0793108

File tree

4 files changed

+125
-47
lines changed

4 files changed

+125
-47
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* by PostgreSQL
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.413 2005/07/02 17:01:51 momjian Exp $
15+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.414 2005/07/10 14:26:29 momjian Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
@@ -2258,6 +2258,7 @@ getFuncs(int *numFuncs)
22582258
int i_proargtypes;
22592259
int i_prorettype;
22602260
int i_proacl;
2261+
int i_is_pl_handler;
22612262

22622263
/* Make sure we are in proper schema */
22632264
selectSourceSchema("pg_catalog");
@@ -2266,15 +2267,36 @@ getFuncs(int *numFuncs)
22662267

22672268
if (g_fout->remoteVersion >= 70300)
22682269
{
2270+
/*
2271+
* We now collect info on pg_catalog resident functions, but
2272+
* only if they are language call handlers or validators, and
2273+
* only for non-default languages (i.e. not internal/C/SQL).
2274+
*/
22692275
appendPQExpBuffer(query,
22702276
"SELECT tableoid, oid, proname, prolang, "
22712277
"pronargs, proargtypes, prorettype, proacl, "
22722278
"pronamespace, "
2273-
"(select usename from pg_user where proowner = usesysid) as usename "
2279+
"(select usename from pg_user "
2280+
" where proowner = usesysid) as usename, "
2281+
"CASE WHEN oid IN "
2282+
" (select lanplcallfoid from pg_language "
2283+
" where lanplcallfoid != 0) THEN true "
2284+
" WHEN oid IN "
2285+
" (select lanvalidator from pg_language "
2286+
" where lanplcallfoid != 0) THEN true "
2287+
" ELSE false END AS is_pl_handler "
22742288
"FROM pg_proc "
22752289
"WHERE NOT proisagg "
2276-
"AND pronamespace != "
2277-
"(select oid from pg_namespace where nspname = 'pg_catalog')");
2290+
"AND (pronamespace != "
2291+
" (select oid from pg_namespace "
2292+
" where nspname = 'pg_catalog')"
2293+
" OR oid IN "
2294+
" (select lanplcallfoid from pg_language "
2295+
" where lanplcallfoid != 0) "
2296+
" OR oid IN "
2297+
" (select lanvalidator from pg_language "
2298+
" where lanplcallfoid != 0))"
2299+
);
22782300
}
22792301
else if (g_fout->remoteVersion >= 70100)
22802302
{
@@ -2283,7 +2305,9 @@ getFuncs(int *numFuncs)
22832305
"pronargs, proargtypes, prorettype, "
22842306
"'{=X}' as proacl, "
22852307
"0::oid as pronamespace, "
2286-
"(select usename from pg_user where proowner = usesysid) as usename "
2308+
"(select usename from pg_user "
2309+
" where proowner = usesysid) as usename, "
2310+
"false AS is_pl_handler "
22872311
"FROM pg_proc "
22882312
"where pg_proc.oid > '%u'::oid",
22892313
g_last_builtin_oid);
@@ -2292,12 +2316,15 @@ getFuncs(int *numFuncs)
22922316
{
22932317
appendPQExpBuffer(query,
22942318
"SELECT "
2295-
"(SELECT oid FROM pg_class WHERE relname = 'pg_proc') AS tableoid, "
2319+
"(SELECT oid FROM pg_class "
2320+
" WHERE relname = 'pg_proc') AS tableoid, "
22962321
"oid, proname, prolang, "
22972322
"pronargs, proargtypes, prorettype, "
22982323
"'{=X}' as proacl, "
22992324
"0::oid as pronamespace, "
2300-
"(select usename from pg_user where proowner = usesysid) as usename "
2325+
"(select usename from pg_user "
2326+
" where proowner = usesysid) as usename, "
2327+
"false AS is_pl_handler "
23012328
"FROM pg_proc "
23022329
"where pg_proc.oid > '%u'::oid",
23032330
g_last_builtin_oid);
@@ -2322,6 +2349,7 @@ getFuncs(int *numFuncs)
23222349
i_proargtypes = PQfnumber(res, "proargtypes");
23232350
i_prorettype = PQfnumber(res, "prorettype");
23242351
i_proacl = PQfnumber(res, "proacl");
2352+
i_is_pl_handler = PQfnumber(res,"is_pl_handler");
23252353

23262354
for (i = 0; i < ntups; i++)
23272355
{
@@ -2330,13 +2358,16 @@ getFuncs(int *numFuncs)
23302358
finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
23312359
AssignDumpId(&finfo[i].dobj);
23322360
finfo[i].dobj.name = strdup(PQgetvalue(res, i, i_proname));
2333-
finfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)),
2361+
finfo[i].dobj.namespace =
2362+
findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)),
23342363
finfo[i].dobj.catId.oid);
23352364
finfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
23362365
finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
23372366
finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
23382367
finfo[i].proacl = strdup(PQgetvalue(res, i, i_proacl));
23392368
finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
2369+
finfo[i].isProlangFunc =
2370+
strcmp(PQgetvalue(res, i, i_is_pl_handler), "t") == 0;
23402371
if (finfo[i].nargs == 0)
23412372
finfo[i].argtypes = NULL;
23422373
else
@@ -2347,7 +2378,8 @@ getFuncs(int *numFuncs)
23472378
}
23482379

23492380
if (strlen(finfo[i].usename) == 0)
2350-
write_msg(NULL, "WARNING: owner of function \"%s\" appears to be invalid\n",
2381+
write_msg(NULL,
2382+
"WARNING: owner of function \"%s\" appears to be invalid\n",
23512383
finfo[i].dobj.name);
23522384
}
23532385

@@ -5040,23 +5072,19 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
50405072
return;
50415073

50425074
/*
5043-
* Current theory is to dump PLs iff their underlying functions will
5044-
* be dumped (are in a dumpable namespace, or have a non-system OID in
5045-
* pre-7.3 databases). Actually, we treat the PL itself as being in
5075+
* We dump PLs iff their underlying call handler functions have been
5076+
* marked as language functions (or have a non-system OID in
5077+
* pre-7.3 databases). We treat the PL itself as being in
50465078
* the underlying function's namespace, though it isn't really. This
50475079
* avoids searchpath problems for the HANDLER clause.
50485080
*
5049-
* If the underlying function is in the pg_catalog namespace, we won't
5050-
* have loaded it into finfo[] at all; therefore, treat failure to
5051-
* find it in finfo[] as indicating we shouldn't dump it, not as an
5052-
* error condition. Ditto for the validator.
50535081
*/
50545082

50555083
funcInfo = findFuncByOid(plang->lanplcallfoid);
50565084
if (funcInfo == NULL)
50575085
return;
50585086

5059-
if (!funcInfo->dobj.namespace->dump)
5087+
if (!funcInfo->isProlangFunc && !funcInfo->dobj.namespace->dump)
50605088
return;
50615089

50625090
if (OidIsValid(plang->lanvalidator))
@@ -5254,10 +5282,11 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
52545282
char **argmodes = NULL;
52555283
char **argnames = NULL;
52565284

5257-
/* Dump only funcs in dumpable namespaces */
5258-
if (!finfo->dobj.namespace->dump || dataOnly)
5285+
/* Dump only funcs in dumpable namespaces, or needed language handlers */
5286+
if ((!finfo->isProlangFunc && !finfo->dobj.namespace->dump) || dataOnly)
52595287
return;
52605288

5289+
52615290
query = createPQExpBuffer();
52625291
q = createPQExpBuffer();
52635292
delqry = createPQExpBuffer();

src/bin/pg_dump/pg_dump.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.116 2005/06/30 03:03:02 tgl Exp $
9+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.117 2005/07/10 14:26:29 momjian Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -132,6 +132,7 @@ typedef struct _funcInfo
132132
Oid *argtypes;
133133
Oid prorettype;
134134
char *proacl;
135+
bool isProlangFunc;
135136
} FuncInfo;
136137

137138
/* AggInfo is a superset of FuncInfo */

src/bin/scripts/createlang.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
66
* Portions Copyright (c) 1994, Regents of the University of California
77
*
8-
* $PostgreSQL: pgsql/src/bin/scripts/createlang.c,v 1.17 2005/06/22 16:45:50 tgl Exp $
8+
* $PostgreSQL: pgsql/src/bin/scripts/createlang.c,v 1.18 2005/07/10 14:26:30 momjian Exp $
99
*
1010
*-------------------------------------------------------------------------
1111
*/
@@ -140,7 +140,10 @@ main(int argc, char *argv[])
140140

141141
conn = connectDatabase(dbname, host, port, username, password, progname);
142142

143-
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?"));
143+
printfPQExpBuffer(&sql, "SELECT lanname as \"%s\", (CASE WHEN lanpltrusted "
144+
"THEN '%s' ELSE '%s' END) as \"%s\" FROM pg_language "
145+
"WHERE lanispl IS TRUE;",
146+
_("Name"), _("yes"), _("no"), _("Trusted?"));
144147
result = executeQuery(conn, sql.data, progname, echo);
145148

146149
memset(&popt, 0, sizeof(popt));
@@ -209,8 +212,10 @@ main(int argc, char *argv[])
209212
}
210213
else
211214
{
212-
fprintf(stderr, _("%s: unsupported language \"%s\"\n"), progname, langname);
213-
fprintf(stderr, _("Supported languages are plpgsql, pltcl, pltclu, plperl, plperlu, and plpythonu.\n"));
215+
fprintf(stderr, _("%s: unsupported language \"%s\"\n"),
216+
progname, langname);
217+
fprintf(stderr, _("Supported languages are plpgsql, pltcl, pltclu, "
218+
"plperl, plperlu, and plpythonu.\n"));
214219
exit(1);
215220
}
216221

@@ -219,13 +224,16 @@ main(int argc, char *argv[])
219224
/*
220225
* Make sure the language isn't already installed
221226
*/
222-
printfPQExpBuffer(&sql, "SELECT oid FROM pg_language WHERE lanname = '%s';", langname);
227+
printfPQExpBuffer(&sql,
228+
"SELECT oid FROM pg_language WHERE lanname = '%s';",
229+
langname);
223230
result = executeQuery(conn, sql.data, progname, echo);
224231
if (PQntuples(result) > 0)
225232
{
226233
PQfinish(conn);
227234
fprintf(stderr,
228-
_("%s: language \"%s\" is already installed in database \"%s\"\n"),
235+
_("%s: language \"%s\" is already installed in "
236+
"database \"%s\"\n"),
229237
progname, langname, dbname);
230238
/* separate exit status for "already installed" */
231239
exit(2);
@@ -235,7 +243,9 @@ main(int argc, char *argv[])
235243
/*
236244
* Check whether the call handler exists
237245
*/
238-
printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' AND prorettype = 'pg_catalog.language_handler'::regtype AND pronargs = 0;", handler);
246+
printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' "
247+
"AND prorettype = 'pg_catalog.language_handler'::regtype "
248+
"AND pronargs = 0;", handler);
239249
result = executeQuery(conn, sql.data, progname, echo);
240250
handlerexists = (PQntuples(result) > 0);
241251
PQclear(result);
@@ -245,7 +255,9 @@ main(int argc, char *argv[])
245255
*/
246256
if (validator)
247257
{
248-
printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s' AND proargtypes[0] = 'pg_catalog.oid'::regtype AND pronargs = 1;", validator);
258+
printfPQExpBuffer(&sql, "SELECT oid FROM pg_proc WHERE proname = '%s'"
259+
" AND proargtypes[0] = 'pg_catalog.oid'::regtype "
260+
" AND pronargs = 1;", validator);
249261
result = executeQuery(conn, sql.data, progname, echo);
250262
validatorexists = (PQntuples(result) > 0);
251263
PQclear(result);
@@ -260,20 +272,22 @@ main(int argc, char *argv[])
260272

261273
if (!handlerexists)
262274
appendPQExpBuffer(&sql,
263-
"CREATE FUNCTION \"%s\" () RETURNS language_handler AS '%s/%s' LANGUAGE C;\n",
275+
"CREATE FUNCTION pg_catalog.\"%s\" () RETURNS "
276+
"language_handler AS '%s/%s' LANGUAGE C;\n",
264277
handler, pglib, object);
265278

266279
if (!validatorexists)
267280
appendPQExpBuffer(&sql,
268-
"CREATE FUNCTION \"%s\" (oid) RETURNS void AS '%s/%s' LANGUAGE C;\n",
281+
"CREATE FUNCTION pg_catalog.\"%s\" (oid) RETURNS "
282+
"void AS '%s/%s' LANGUAGE C;\n",
269283
validator, pglib, object);
270284

271285
appendPQExpBuffer(&sql,
272-
"CREATE %sLANGUAGE \"%s\" HANDLER \"%s\"",
286+
"CREATE %sLANGUAGE \"%s\" HANDLER pg_catalog.\"%s\"",
273287
(trusted ? "TRUSTED " : ""), langname, handler);
274288

275289
if (validator)
276-
appendPQExpBuffer(&sql, " VALIDATOR \"%s\"", validator);
290+
appendPQExpBuffer(&sql, " VALIDATOR pg_catalog.\"%s\"", validator);
277291

278292
appendPQExpBuffer(&sql, ";\n");
279293

0 commit comments

Comments
 (0)