From 19990918d3fa2a445561627ed415b5891602f7fe Mon Sep 17 00:00:00 2001 From: Stephen Frost Date: Wed, 21 Dec 2016 13:47:06 -0500 Subject: [PATCH] For 8.0 servers, get last built-in oid from pg_database We didn't start ensuring that all built-in objects had OIDs less than 16384 until 8.1, so for 8.0 servers we still need to query the value out of pg_database. We need this, in particular, to distinguish which casts were built-in and which were user-defined. For HEAD, we only worry about going back to 8.0, for the back-branches, we also ensure that 7.0-7.4 work. Discussion: https://www.postgresql.org/message-id/flat/20160504183952.GE10850%40tamriel.snowman.net --- src/bin/pg_dump/pg_dump.c | 60 +++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index c5adc9da38..83e172e728 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -96,6 +96,12 @@ bool g_verbose; /* User wants verbose narration of our /* subquery used to convert user ID (eg, datdba) to user name */ static const char *username_subquery; +/* + * For 8.0 and earlier servers, pulled from pg_database, for 8.1+ we use + * FirstNormalObjectId - 1. + */ +static Oid g_last_builtin_oid; /* value of the last builtin oid */ + /* The specified names/patterns should to match at least one entity */ static int strict_names = 0; @@ -233,6 +239,7 @@ static char *convertRegProcReference(Archive *fout, const char *proc); static char *convertOperatorReference(Archive *fout, const char *opr); static char *convertTSFunction(Archive *fout, Oid funcOid); +static Oid findLastBuiltinOid_V71(Archive *fout, const char *); static void selectSourceSchema(Archive *fout, const char *schemaName); static char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts); static void getBlobs(Archive *fout); @@ -684,6 +691,20 @@ main(int argc, char **argv) exit_horribly(NULL, "Exported snapshots are not supported by this server version.\n"); + /* + * Find the last built-in OID, if needed (prior to 8.1) + * + * With 8.1 and above, we can just use FirstNormalObjectId - 1. + */ + if (fout->remoteVersion < 80100) + g_last_builtin_oid = findLastBuiltinOid_V71(fout, + PQdb(GetConnection(fout))); + else + g_last_builtin_oid = FirstNormalObjectId - 1; + + if (g_verbose) + write_msg(NULL, "last built-in OID is %u\n", g_last_builtin_oid); + /* Expand schema selection patterns into OID lists */ if (schema_include_patterns.head != NULL) { @@ -1494,7 +1515,7 @@ selectDumpableCast(CastInfo *cast, Archive *fout) * This would be DUMP_COMPONENT_ACL for from-initdb casts, but they do not * support ACLs currently. */ - if (cast->dobj.catId.oid < (Oid) FirstNormalObjectId) + if (cast->dobj.catId.oid <= (Oid) g_last_builtin_oid) cast->dobj.dump = DUMP_COMPONENT_NONE; else cast->dobj.dump = fout->dopt->include_everything ? @@ -1526,7 +1547,7 @@ selectDumpableProcLang(ProcLangInfo *plang, Archive *fout) plang->dobj.dump = DUMP_COMPONENT_NONE; else { - if (plang->dobj.catId.oid < (Oid) FirstNormalObjectId) + if (plang->dobj.catId.oid <= (Oid) g_last_builtin_oid) plang->dobj.dump = fout->remoteVersion < 90600 ? DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL; else @@ -1552,7 +1573,7 @@ selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) * This would be DUMP_COMPONENT_ACL for from-initdb access methods, but * they do not support ACLs currently. */ - if (method->dobj.catId.oid < (Oid) FirstNormalObjectId) + if (method->dobj.catId.oid <= (Oid) g_last_builtin_oid) method->dobj.dump = DUMP_COMPONENT_NONE; else method->dobj.dump = fout->dopt->include_everything ? @@ -1577,7 +1598,7 @@ selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt) * change permissions on those objects, if they wish to, and have those * changes preserved. */ - if (dopt->binary_upgrade && extinfo->dobj.catId.oid < (Oid) FirstNormalObjectId) + if (dopt->binary_upgrade && extinfo->dobj.catId.oid <= (Oid) g_last_builtin_oid) extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_ACL; else extinfo->dobj.dump = extinfo->dobj.dump_contains = @@ -8820,8 +8841,8 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo) /* * We unconditionally create the extension, so we must drop it if it * exists. This could happen if the user deleted 'plpgsql' and then - * readded it, causing its oid to be greater than FirstNormalObjectId. - * The FirstNormalObjectId test was kept to avoid repeatedly dropping + * readded it, causing its oid to be greater than g_last_builtin_oid. + * The g_last_builtin_oid test was kept to avoid repeatedly dropping * and recreating extensions like 'plpgsql'. */ appendPQExpBuffer(q, "DROP EXTENSION IF EXISTS %s;\n", qextname); @@ -15324,6 +15345,33 @@ dumpTableConstraintComment(Archive *fout, ConstraintInfo *coninfo) destroyPQExpBuffer(labelq); } +/* + * findLastBuiltinOid_V71 - + * + * find the last built in oid + * + * For 7.1 through 8.0, we do this by retrieving datlastsysoid from the + * pg_database entry for the current database. + */ +static Oid +findLastBuiltinOid_V71(Archive *fout, const char *dbname) +{ + PGresult *res; + Oid last_oid; + PQExpBuffer query = createPQExpBuffer(); + + resetPQExpBuffer(query); + appendPQExpBufferStr(query, "SELECT datlastsysoid from pg_database where datname = "); + appendStringLiteralAH(query, dbname, fout); + + res = ExecuteSqlQueryForSingleRow(fout, query->data); + last_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "datlastsysoid"))); + PQclear(res); + destroyPQExpBuffer(query); + + return last_oid; +} + /* * dumpSequence * write the declaration (not data) of one user-defined sequence -- 2.40.0