Commit b3bc63ef authored by Tom Lane's avatar Tom Lane

Fix pg_dump's handling of extension-member casts and languages.

pg_dump has some heuristic rules for whether to dump casts and procedural
languages, since it's not all that easy to distinguish built-in ones from
user-defined ones.  However, we should not apply those rules to objects
that belong to an extension, but just use the perfectly well-defined rules
for what to do with extension member objects.  Otherwise we might
mistakenly lose extension member objects during a binary upgrade (which is
the only time that we'd want to dump extension members).
parent e728701f
...@@ -8252,6 +8252,9 @@ dumpShellType(Archive *fout, ShellTypeInfo *stinfo) ...@@ -8252,6 +8252,9 @@ dumpShellType(Archive *fout, ShellTypeInfo *stinfo)
* For some backwards compatibility with the older behavior, we forcibly * For some backwards compatibility with the older behavior, we forcibly
* dump a PL if its handler function (and validator if any) are in a * dump a PL if its handler function (and validator if any) are in a
* dumpable namespace. That case is not checked here. * dumpable namespace. That case is not checked here.
*
* Also, if the PL belongs to an extension, we do not use this heuristic.
* That case isn't checked here either.
*/ */
static bool static bool
shouldDumpProcLangs(void) shouldDumpProcLangs(void)
...@@ -8316,13 +8319,22 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang) ...@@ -8316,13 +8319,22 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
* If the functions are dumpable then emit a traditional CREATE LANGUAGE * If the functions are dumpable then emit a traditional CREATE LANGUAGE
* with parameters. Otherwise, dump only if shouldDumpProcLangs() says to * with parameters. Otherwise, dump only if shouldDumpProcLangs() says to
* dump it. * dump it.
*
* However, for a language that belongs to an extension, we must not use
* the shouldDumpProcLangs heuristic, but just dump the language iff we're
* told to (via dobj.dump). Generally the support functions will belong
* to the same extension and so have the same dump flags ... if they don't,
* this might not work terribly nicely.
*/ */
useParams = (funcInfo != NULL && useParams = (funcInfo != NULL &&
(inlineInfo != NULL || !OidIsValid(plang->laninline)) && (inlineInfo != NULL || !OidIsValid(plang->laninline)) &&
(validatorInfo != NULL || !OidIsValid(plang->lanvalidator))); (validatorInfo != NULL || !OidIsValid(plang->lanvalidator)));
if (!useParams && !shouldDumpProcLangs()) if (!plang->dobj.ext_member)
return; {
if (!useParams && !shouldDumpProcLangs())
return;
}
defqry = createPQExpBuffer(); defqry = createPQExpBuffer();
delqry = createPQExpBuffer(); delqry = createPQExpBuffer();
...@@ -9013,13 +9025,12 @@ dumpCast(Archive *fout, CastInfo *cast) ...@@ -9013,13 +9025,12 @@ dumpCast(Archive *fout, CastInfo *cast)
PQExpBuffer delqry; PQExpBuffer delqry;
PQExpBuffer labelq; PQExpBuffer labelq;
FuncInfo *funcInfo = NULL; FuncInfo *funcInfo = NULL;
TypeInfo *sourceInfo;
TypeInfo *targetInfo;
/* Skip if not to be dumped */ /* Skip if not to be dumped */
if (!cast->dobj.dump || dataOnly) if (!cast->dobj.dump || dataOnly)
return; return;
/* Cannot dump if we don't have the cast function's info */
if (OidIsValid(cast->castfunc)) if (OidIsValid(cast->castfunc))
{ {
funcInfo = findFuncByOid(cast->castfunc); funcInfo = findFuncByOid(cast->castfunc);
...@@ -9032,43 +9043,49 @@ dumpCast(Archive *fout, CastInfo *cast) ...@@ -9032,43 +9043,49 @@ dumpCast(Archive *fout, CastInfo *cast)
* objects (the conversion function and the two data types) are not * objects (the conversion function and the two data types) are not
* builtin AND if all of the non-builtin objects are included in the dump. * builtin AND if all of the non-builtin objects are included in the dump.
* Builtin meaning, the namespace name does not start with "pg_". * Builtin meaning, the namespace name does not start with "pg_".
*
* However, for a cast that belongs to an extension, we must not use this
* heuristic, but just dump the cast iff we're told to (via dobj.dump).
*/ */
sourceInfo = findTypeByOid(cast->castsource); if (!cast->dobj.ext_member)
targetInfo = findTypeByOid(cast->casttarget); {
TypeInfo *sourceInfo = findTypeByOid(cast->castsource);
TypeInfo *targetInfo = findTypeByOid(cast->casttarget);
if (sourceInfo == NULL || targetInfo == NULL) if (sourceInfo == NULL || targetInfo == NULL)
return; return;
/* /*
* Skip this cast if all objects are from pg_ * Skip this cast if all objects are from pg_
*/ */
if ((funcInfo == NULL || if ((funcInfo == NULL ||
strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) == 0) && strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) == 0) &&
strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) == 0 && strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) == 0 &&
strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) == 0) strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) == 0)
return; return;
/* /*
* Skip cast if function isn't from pg_ and is not to be dumped. * Skip cast if function isn't from pg_ and is not to be dumped.
*/ */
if (funcInfo && if (funcInfo &&
strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 && strncmp(funcInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
!funcInfo->dobj.dump) !funcInfo->dobj.dump)
return; return;
/* /*
* Same for the source type * Same for the source type
*/ */
if (strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 && if (strncmp(sourceInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
!sourceInfo->dobj.dump) !sourceInfo->dobj.dump)
return; return;
/* /*
* and the target type. * and the target type.
*/ */
if (strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 && if (strncmp(targetInfo->dobj.namespace->dobj.name, "pg_", 3) != 0 &&
!targetInfo->dobj.dump) !targetInfo->dobj.dump)
return; return;
}
/* Make sure we are in proper schema (needed for getFormattedTypeName) */ /* Make sure we are in proper schema (needed for getFormattedTypeName) */
selectSourceSchema("pg_catalog"); selectSourceSchema("pg_catalog");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment