Commit 36a1e732 authored by Tom Lane's avatar Tom Lane

Rework pg_dump namespace search criteria so that dumping of user objects

having names conflicting with system objects will work --- the search
path is now user-schema, pg_catalog rather than implicitly the other way
around.  Note this requires being careful to explicitly qualify references
to system names whenever pg_catalog is not first in the search path.
Also, add support for dumping ACLs of schemas.
parent 5a8ab29a
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.46 2002/05/10 22:36:26 tgl Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.47 2002/05/28 22:26:56 tgl Exp $
* *
* Modifications - 28-Jun-2000 - pjw@rhyme.com.au * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
* *
...@@ -2097,17 +2097,23 @@ _reconnectAsOwner(ArchiveHandle *AH, const char *dbname, TocEntry *te) ...@@ -2097,17 +2097,23 @@ _reconnectAsOwner(ArchiveHandle *AH, const char *dbname, TocEntry *te)
static void static void
_selectOutputSchema(ArchiveHandle *AH, const char *schemaName) _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
{ {
PQExpBuffer qry;
if (!schemaName || *schemaName == '\0' || if (!schemaName || *schemaName == '\0' ||
strcmp(AH->currSchema, schemaName) == 0) strcmp(AH->currSchema, schemaName) == 0)
return; /* no need to do anything */ return; /* no need to do anything */
qry = createPQExpBuffer();
appendPQExpBuffer(qry, "SET search_path = %s",
fmtId(schemaName, false));
if (strcmp(schemaName, "pg_catalog") != 0)
appendPQExpBuffer(qry, ", pg_catalog");
if (RestoringToDB(AH)) if (RestoringToDB(AH))
{ {
PQExpBuffer qry = createPQExpBuffer();
PGresult *res; PGresult *res;
appendPQExpBuffer(qry, "SET search_path = %s;",
fmtId(schemaName, false));
res = PQexec(AH->connection, qry->data); res = PQexec(AH->connection, qry->data);
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
...@@ -2115,15 +2121,15 @@ _selectOutputSchema(ArchiveHandle *AH, const char *schemaName) ...@@ -2115,15 +2121,15 @@ _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
schemaName, PQerrorMessage(AH->connection)); schemaName, PQerrorMessage(AH->connection));
PQclear(res); PQclear(res);
destroyPQExpBuffer(qry);
} }
else else
ahprintf(AH, "SET search_path = %s;\n\n", ahprintf(AH, "%s;\n\n", qry->data);
fmtId(schemaName, false));
if (AH->currSchema) if (AH->currSchema)
free(AH->currSchema); free(AH->currSchema);
AH->currSchema = strdup(schemaName); AH->currSchema = strdup(schemaName);
destroyPQExpBuffer(qry);
} }
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.264 2002/05/22 17:21:00 petere Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.265 2002/05/28 22:26:56 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1779,7 +1779,7 @@ getAggregates(int *numAggs) ...@@ -1779,7 +1779,7 @@ getAggregates(int *numAggs)
{ {
appendPQExpBuffer(query, "SELECT pg_proc.oid, proname as aggname, " appendPQExpBuffer(query, "SELECT pg_proc.oid, proname as aggname, "
"pronamespace as aggnamespace, " "pronamespace as aggnamespace, "
"proargtypes[0]::regtype as aggbasetype, " "proargtypes[0] as aggbasetype, "
"(select usename from pg_user where proowner = usesysid) as usename, " "(select usename from pg_user where proowner = usesysid) as usename, "
"proacl as aggacl " "proacl as aggacl "
"FROM pg_proc " "FROM pg_proc "
...@@ -1791,10 +1791,9 @@ getAggregates(int *numAggs) ...@@ -1791,10 +1791,9 @@ getAggregates(int *numAggs)
{ {
appendPQExpBuffer(query, "SELECT pg_aggregate.oid, aggname, " appendPQExpBuffer(query, "SELECT pg_aggregate.oid, aggname, "
"0::oid as aggnamespace, " "0::oid as aggnamespace, "
"CASE WHEN aggbasetype = 0 THEN '-' " "aggbasetype, "
"ELSE format_type(aggbasetype, NULL) END as aggbasetype, "
"(select usename from pg_user where aggowner = usesysid) as usename, " "(select usename from pg_user where aggowner = usesysid) as usename, "
"cast('{=X}' as aclitem[]) as aggacl " "'{=X}' as aggacl "
"from pg_aggregate " "from pg_aggregate "
"where oid > '%u'::oid", "where oid > '%u'::oid",
g_last_builtin_oid); g_last_builtin_oid);
...@@ -1833,6 +1832,7 @@ getAggregates(int *numAggs) ...@@ -1833,6 +1832,7 @@ getAggregates(int *numAggs)
write_msg(NULL, "WARNING: owner of aggregate function \"%s\" appears to be invalid\n", write_msg(NULL, "WARNING: owner of aggregate function \"%s\" appears to be invalid\n",
agginfo[i].aggname); agginfo[i].aggname);
agginfo[i].aggacl = strdup(PQgetvalue(res, i, i_aggacl)); agginfo[i].aggacl = strdup(PQgetvalue(res, i, i_aggacl));
agginfo[i].fmtbasetype = NULL; /* computed when it's dumped */
} }
PQclear(res); PQclear(res);
...@@ -1890,7 +1890,7 @@ getFuncs(int *numFuncs) ...@@ -1890,7 +1890,7 @@ getFuncs(int *numFuncs)
appendPQExpBuffer(query, appendPQExpBuffer(query,
"SELECT pg_proc.oid, proname, prolang, " "SELECT pg_proc.oid, proname, prolang, "
"pronargs, proargtypes, prorettype, " "pronargs, proargtypes, prorettype, "
"cast('{=X}' as aclitem[]) as proacl, " "'{=X}' as proacl, "
"0::oid as pronamespace, " "0::oid as pronamespace, "
"(select usename from pg_user where proowner = usesysid) as usename " "(select usename from pg_user where proowner = usesysid) as usename "
"FROM pg_proc " "FROM pg_proc "
...@@ -2290,7 +2290,18 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -2290,7 +2290,18 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
resetPQExpBuffer(q); resetPQExpBuffer(q);
if (g_fout->remoteVersion >= 70100) if (g_fout->remoteVersion >= 70300)
{
appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, "
"attnotnull, atthasdef, "
"pg_catalog.format_type(atttypid,atttypmod) as atttypname "
"from pg_catalog.pg_attribute a "
"where attrelid = '%s'::pg_catalog.oid "
"and attnum > 0::pg_catalog.int2 "
"order by attrelid, attnum",
tblinfo[i].oid);
}
else if (g_fout->remoteVersion >= 70100)
{ {
appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, " appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, "
"attnotnull, atthasdef, " "attnotnull, atthasdef, "
...@@ -2367,7 +2378,15 @@ getTableAttrs(TableInfo *tblinfo, int numTables) ...@@ -2367,7 +2378,15 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
tblinfo[i].relname); tblinfo[i].relname);
resetPQExpBuffer(q); resetPQExpBuffer(q);
if (g_fout->remoteVersion >= 70200) if (g_fout->remoteVersion >= 70300)
{
appendPQExpBuffer(q, "SELECT adnum, "
"pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc "
"FROM pg_catalog.pg_attrdef "
"WHERE adrelid = '%s'::pg_catalog.oid",
tblinfo[i].oid);
}
else if (g_fout->remoteVersion >= 70200)
{ {
appendPQExpBuffer(q, "SELECT adnum, " appendPQExpBuffer(q, "SELECT adnum, "
"pg_get_expr(adbin, adrelid) AS adsrc " "pg_get_expr(adbin, adrelid) AS adsrc "
...@@ -2452,8 +2471,8 @@ dumpComment(Archive *fout, const char *target, ...@@ -2452,8 +2471,8 @@ dumpComment(Archive *fout, const char *target,
if (fout->remoteVersion >= 70300) if (fout->remoteVersion >= 70300)
{ {
appendPQExpBuffer(query, "SELECT description FROM pg_catalog.pg_description " appendPQExpBuffer(query, "SELECT description FROM pg_catalog.pg_description "
"WHERE objoid = '%s'::oid and classoid = " "WHERE objoid = '%s'::pg_catalog.oid and classoid = "
"'pg_catalog.%s'::regclass " "'pg_catalog.%s'::pg_catalog.regclass "
"and objsubid = %d", "and objsubid = %d",
oid, classname, subid); oid, classname, subid);
} }
...@@ -2537,8 +2556,8 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo, ...@@ -2537,8 +2556,8 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
if (fout->remoteVersion >= 70300) if (fout->remoteVersion >= 70300)
{ {
appendPQExpBuffer(query, "SELECT description, objsubid FROM pg_catalog.pg_description " appendPQExpBuffer(query, "SELECT description, objsubid FROM pg_catalog.pg_description "
"WHERE objoid = '%s'::oid and classoid = " "WHERE objoid = '%s'::pg_catalog.oid and classoid = "
"'pg_catalog.pg_class'::regclass " "'pg_catalog.pg_class'::pg_catalog.regclass "
"ORDER BY objoid, classoid, objsubid", "ORDER BY objoid, classoid, objsubid",
tbinfo->oid); tbinfo->oid);
} }
...@@ -2622,9 +2641,7 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo, ...@@ -2622,9 +2641,7 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
* dumpDBComment -- * dumpDBComment --
* *
* This routine is used to dump any comments associated with the * This routine is used to dump any comments associated with the
* database to which we are currently connected. If the user chose * database to which we are currently connected.
* to dump the schema of the database, then this is the first
* statement issued.
*/ */
void void
dumpDBComment(Archive *fout) dumpDBComment(Archive *fout)
...@@ -2677,45 +2694,63 @@ dumpNamespaces(Archive *fout, NamespaceInfo *nsinfo, int numNamespaces) ...@@ -2677,45 +2694,63 @@ dumpNamespaces(Archive *fout, NamespaceInfo *nsinfo, int numNamespaces)
PQExpBuffer q = createPQExpBuffer(); PQExpBuffer q = createPQExpBuffer();
PQExpBuffer delq = createPQExpBuffer(); PQExpBuffer delq = createPQExpBuffer();
int i; int i;
char *qnspname;
for (i = 0; i < numNamespaces; i++) for (i = 0; i < numNamespaces; i++)
{ {
NamespaceInfo *nspinfo = &nsinfo[i];
/* skip if not to be dumped */ /* skip if not to be dumped */
if (!nsinfo[i].dump) if (!nspinfo->dump)
continue; continue;
/* don't dump dummy namespace from pre-7.3 source */ /* don't dump dummy namespace from pre-7.3 source */
if (strlen(nsinfo[i].nspname) == 0) if (strlen(nspinfo->nspname) == 0)
continue; continue;
/* quick hack: don't dump CREATE SCHEMA for public namespace */ qnspname = strdup(fmtId(nspinfo->nspname, force_quotes));
/* XXX need a better idea */
if (strcmp(nsinfo[i].nspname, "public") == 0)
continue;
/*
* If it's the PUBLIC namespace, don't emit a CREATE SCHEMA
* record for it, since we expect PUBLIC to exist already in
* the destination database. And emit ACL info only if the ACL
* isn't the standard value for PUBLIC.
*/
if (strcmp(nspinfo->nspname, "public") == 0)
{
if (!aclsSkip && strcmp(nspinfo->nspacl, "{=UC}") != 0)
dumpACL(fout, "SCHEMA", qnspname, NULL,
nspinfo->usename, nspinfo->nspacl,
nspinfo->oid);
}
else
{
resetPQExpBuffer(q); resetPQExpBuffer(q);
resetPQExpBuffer(delq); resetPQExpBuffer(delq);
#ifdef NOTYET /* suppress till DROP SCHEMA works */ appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
appendPQExpBuffer(delq, "DROP SCHEMA %s;\n",
fmtId(nsinfo[i].nspname, force_quotes));
#endif
appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
fmtId(nsinfo[i].nspname, force_quotes));
ArchiveEntry(fout, nsinfo[i].oid, nsinfo[i].nspname, ArchiveEntry(fout, nspinfo->oid, nspinfo->nspname,
NULL, NULL,
nsinfo[i].usename, "SCHEMA", NULL, nspinfo->usename, "SCHEMA", NULL,
q->data, delq->data, NULL, NULL, NULL); q->data, delq->data, NULL, NULL, NULL);
/*** Dump Schema Comments ***/ /*** Dump Schema Comments ***/
resetPQExpBuffer(q); resetPQExpBuffer(q);
appendPQExpBuffer(q, "SCHEMA %s", appendPQExpBuffer(q, "SCHEMA %s", qnspname);
fmtId(nsinfo[i].nspname, force_quotes));
dumpComment(fout, q->data, dumpComment(fout, q->data,
NULL, nsinfo[i].usename, NULL, nspinfo->usename,
nsinfo[i].oid, "pg_namespace", 0, NULL); nspinfo->oid, "pg_namespace", 0, NULL);
if (!aclsSkip)
dumpACL(fout, "SCHEMA", qnspname, NULL,
nspinfo->usename, nspinfo->nspacl,
nspinfo->oid);
}
free(qnspname);
} }
destroyPQExpBuffer(q); destroyPQExpBuffer(q);
...@@ -2762,7 +2797,21 @@ dumpOneBaseType(Archive *fout, TypeInfo *tinfo, ...@@ -2762,7 +2797,21 @@ dumpOneBaseType(Archive *fout, TypeInfo *tinfo,
selectSourceSchema(tinfo->typnamespace->nspname); selectSourceSchema(tinfo->typnamespace->nspname);
/* Fetch type-specific details */ /* Fetch type-specific details */
if (fout->remoteVersion >= 70100) if (fout->remoteVersion >= 70300)
{
appendPQExpBuffer(query, "SELECT typlen, typprtlen, "
"typinput, typoutput, typreceive, typsend, "
"typinput::pg_catalog.oid as typinputoid, "
"typoutput::pg_catalog.oid as typoutputoid, "
"typreceive::pg_catalog.oid as typreceiveoid, "
"typsend::pg_catalog.oid as typsendoid, "
"typdelim, typdefault, typbyval, typalign, "
"typstorage "
"FROM pg_catalog.pg_type "
"WHERE oid = '%s'::pg_catalog.oid",
tinfo->oid);
}
else if (fout->remoteVersion >= 70100)
{ {
appendPQExpBuffer(query, "SELECT typlen, typprtlen, " appendPQExpBuffer(query, "SELECT typlen, typprtlen, "
"typinput, typoutput, typreceive, typsend, " "typinput, typoutput, typreceive, typsend, "
...@@ -2823,7 +2872,7 @@ dumpOneBaseType(Archive *fout, TypeInfo *tinfo, ...@@ -2823,7 +2872,7 @@ dumpOneBaseType(Archive *fout, TypeInfo *tinfo,
if (PQgetisnull(res, 0, PQfnumber(res, "typdefault"))) if (PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
typdefault = NULL; typdefault = NULL;
else else
typdefault = strdup(PQgetvalue(res, 0, PQfnumber(res, "typdefault"))); typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval")); typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign")); typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage")); typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
...@@ -2856,7 +2905,10 @@ dumpOneBaseType(Archive *fout, TypeInfo *tinfo, ...@@ -2856,7 +2905,10 @@ dumpOneBaseType(Archive *fout, TypeInfo *tinfo,
(*deps)[depIdx++] = strdup(typsendoid); (*deps)[depIdx++] = strdup(typsendoid);
} }
appendPQExpBuffer(delq, "DROP TYPE %s;\n", /* DROP must be fully qualified in case same name appears in pg_catalog */
appendPQExpBuffer(delq, "DROP TYPE %s.",
fmtId(tinfo->typnamespace->nspname, force_quotes));
appendPQExpBuffer(delq, "%s;\n",
fmtId(tinfo->typname, force_quotes)); fmtId(tinfo->typname, force_quotes));
appendPQExpBuffer(q, appendPQExpBuffer(q,
...@@ -2977,11 +3029,12 @@ dumpOneDomain(Archive *fout, TypeInfo *tinfo) ...@@ -2977,11 +3029,12 @@ dumpOneDomain(Archive *fout, TypeInfo *tinfo)
selectSourceSchema(tinfo->typnamespace->nspname); selectSourceSchema(tinfo->typnamespace->nspname);
/* Fetch domain specific details */ /* Fetch domain specific details */
/* We assume here that remoteVersion must be at least 70300 */
appendPQExpBuffer(query, "SELECT typnotnull, " appendPQExpBuffer(query, "SELECT typnotnull, "
"format_type(typbasetype, typtypmod) as typdefn, " "pg_catalog.format_type(typbasetype, typtypmod) as typdefn, "
"typdefault, typbasetype " "typdefault, typbasetype "
"FROM pg_type " "FROM pg_catalog.pg_type "
"WHERE oid = '%s'::oid", "WHERE oid = '%s'::pg_catalog.oid",
tinfo->oid); tinfo->oid);
res = PQexec(g_conn, query->data); res = PQexec(g_conn, query->data);
...@@ -3006,11 +3059,13 @@ dumpOneDomain(Archive *fout, TypeInfo *tinfo) ...@@ -3006,11 +3059,13 @@ dumpOneDomain(Archive *fout, TypeInfo *tinfo)
if (PQgetisnull(res, 0, PQfnumber(res, "typdefault"))) if (PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
typdefault = NULL; typdefault = NULL;
else else
typdefault = strdup(PQgetvalue(res, 0, PQfnumber(res, "typdefault"))); typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
typbasetype = PQgetvalue(res, 0, PQfnumber(res, "typbasetype")); typbasetype = PQgetvalue(res, 0, PQfnumber(res, "typbasetype"));
/* Command to drop the old copy */ /* DROP must be fully qualified in case same name appears in pg_catalog */
appendPQExpBuffer(delq, "DROP DOMAIN %s RESTRICT;\n", appendPQExpBuffer(delq, "DROP DOMAIN %s.",
fmtId(tinfo->typnamespace->nspname, force_quotes));
appendPQExpBuffer(delq, "%s RESTRICT;\n",
fmtId(tinfo->typname, force_quotes)); fmtId(tinfo->typname, force_quotes));
appendPQExpBuffer(q, appendPQExpBuffer(q,
...@@ -3025,11 +3080,7 @@ dumpOneDomain(Archive *fout, TypeInfo *tinfo) ...@@ -3025,11 +3080,7 @@ dumpOneDomain(Archive *fout, TypeInfo *tinfo)
appendPQExpBuffer(q, " NOT NULL"); appendPQExpBuffer(q, " NOT NULL");
if (typdefault) if (typdefault)
{ appendPQExpBuffer(q, " DEFAULT %s", typdefault);
appendPQExpBuffer(q,
" DEFAULT %s",
typdefault);
}
appendPQExpBuffer(q, ";\n"); appendPQExpBuffer(q, ";\n");
...@@ -3206,7 +3257,8 @@ dumpProcLangs(Archive *fout, FuncInfo finfo[], int numFuncs) ...@@ -3206,7 +3257,8 @@ dumpProcLangs(Archive *fout, FuncInfo finfo[], int numFuncs)
(*deps)[depIdx++] = strdup(lanplcallfoid); (*deps)[depIdx++] = strdup(lanplcallfoid);
appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n", fmtId(lanname, force_quotes)); appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
fmtId(lanname, force_quotes));
appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s", appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
(PQgetvalue(res, i, i_lanpltrusted)[0] == 't') ? (PQgetvalue(res, i, i_lanpltrusted)[0] == 't') ?
...@@ -3216,7 +3268,13 @@ dumpProcLangs(Archive *fout, FuncInfo finfo[], int numFuncs) ...@@ -3216,7 +3268,13 @@ dumpProcLangs(Archive *fout, FuncInfo finfo[], int numFuncs)
fmtId(finfo[fidx].proname, force_quotes)); fmtId(finfo[fidx].proname, force_quotes));
if (strcmp(lanvalidator, "0")!=0) if (strcmp(lanvalidator, "0")!=0)
{ {
appendPQExpBuffer(defqry, " VALIDATOR %s", appendPQExpBuffer(defqry, " VALIDATOR ");
/* Cope with possibility that validator is in different schema */
if (finfo[vidx].pronamespace != finfo[fidx].pronamespace)
appendPQExpBuffer(defqry, "%s.",
fmtId(finfo[vidx].pronamespace->nspname,
force_quotes));
appendPQExpBuffer(defqry, "%s",
fmtId(finfo[vidx].proname, force_quotes)); fmtId(finfo[vidx].proname, force_quotes));
(*deps)[depIdx++] = strdup(lanvalidator); (*deps)[depIdx++] = strdup(lanvalidator);
} }
...@@ -3266,7 +3324,12 @@ dumpFuncs(Archive *fout, FuncInfo finfo[], int numFuncs) ...@@ -3266,7 +3324,12 @@ dumpFuncs(Archive *fout, FuncInfo finfo[], int numFuncs)
} }
} }
/*
* format_function_signature: generate function name and argument list
*
* The argument type names are qualified if needed. The function name
* is never qualified.
*/
static char * static char *
format_function_signature(FuncInfo *finfo) format_function_signature(FuncInfo *finfo)
{ {
...@@ -3340,9 +3403,9 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo) ...@@ -3340,9 +3403,9 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
appendPQExpBuffer(query, appendPQExpBuffer(query,
"SELECT proretset, prosrc, probin, " "SELECT proretset, prosrc, probin, "
"provolatile, proimplicit, proisstrict, prosecdef, " "provolatile, proimplicit, proisstrict, prosecdef, "
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname " "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
"FROM pg_proc " "FROM pg_catalog.pg_proc "
"WHERE oid = '%s'::oid", "WHERE oid = '%s'::pg_catalog.oid",
finfo->oid); finfo->oid);
} }
else if (g_fout->remoteVersion >= 70100) else if (g_fout->remoteVersion >= 70100)
...@@ -3424,7 +3487,10 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo) ...@@ -3424,7 +3487,10 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
funcsig = format_function_signature(finfo); funcsig = format_function_signature(finfo);
appendPQExpBuffer(delqry, "DROP FUNCTION %s;\n", funcsig); /* DROP must be fully qualified in case same name appears in pg_catalog */
appendPQExpBuffer(delqry, "DROP FUNCTION %s.%s;\n",
fmtId(finfo->pronamespace->nspname, force_quotes),
funcsig);
rettypename = getFormattedTypeName(finfo->prorettype, zeroAsOpaque); rettypename = getFormattedTypeName(finfo->prorettype, zeroAsOpaque);
...@@ -3561,15 +3627,21 @@ dumpOneOpr(Archive *fout, OprInfo *oprinfo, ...@@ -3561,15 +3627,21 @@ dumpOneOpr(Archive *fout, OprInfo *oprinfo,
if (g_fout->remoteVersion >= 70300) if (g_fout->remoteVersion >= 70300)
{ {
appendPQExpBuffer(query, "SELECT oprkind, oprcode::regprocedure, " appendPQExpBuffer(query, "SELECT oprkind, "
"oprleft::regtype, oprright::regtype, " "oprcode::pg_catalog.regprocedure, "
"oprcom::regoperator, oprnegate::regoperator, " "oprleft::pg_catalog.regtype, "
"oprrest::regprocedure, oprjoin::regprocedure, " "oprright::pg_catalog.regtype, "
"oprcom::pg_catalog.regoperator, "
"oprnegate::pg_catalog.regoperator, "
"oprrest::pg_catalog.regprocedure, "
"oprjoin::pg_catalog.regprocedure, "
"oprcanhash, " "oprcanhash, "
"oprlsortop::regoperator, oprrsortop::regoperator, " "oprlsortop::pg_catalog.regoperator, "
"oprltcmpop::regoperator, oprgtcmpop::regoperator " "oprrsortop::pg_catalog.regoperator, "
"from pg_operator " "oprltcmpop::pg_catalog.regoperator, "
"where oid = '%s'::oid", "oprgtcmpop::pg_catalog.regoperator "
"from pg_catalog.pg_operator "
"where oid = '%s'::pg_catalog.oid",
oprinfo->oid); oprinfo->oid);
} }
else if (g_fout->remoteVersion >= 70100) else if (g_fout->remoteVersion >= 70100)
...@@ -3717,7 +3789,9 @@ dumpOneOpr(Archive *fout, OprInfo *oprinfo, ...@@ -3717,7 +3789,9 @@ dumpOneOpr(Archive *fout, OprInfo *oprinfo,
if (name) if (name)
appendPQExpBuffer(details, ",\n\tGTCMP = %s ", name); appendPQExpBuffer(details, ",\n\tGTCMP = %s ", name);
appendPQExpBuffer(delq, "DROP OPERATOR %s;\n", /* DROP must be fully qualified in case same name appears in pg_catalog */
appendPQExpBuffer(delq, "DROP OPERATOR %s.%s;\n",
fmtId(oprinfo->oprnamespace->nspname, force_quotes),
oprid->data); oprid->data);
appendPQExpBuffer(q, "CREATE OPERATOR %s (%s);\n", appendPQExpBuffer(q, "CREATE OPERATOR %s (%s);\n",
...@@ -3856,6 +3930,12 @@ dumpAggs(Archive *fout, AggInfo agginfo[], int numAggs) ...@@ -3856,6 +3930,12 @@ dumpAggs(Archive *fout, AggInfo agginfo[], int numAggs)
} }
/*
* format_aggregate_signature: generate aggregate name and argument list
*
* The argument type names are qualified if needed. The aggregate name
* is never qualified.
*/
static char * static char *
format_aggregate_signature(AggInfo *agginfo, Archive *fout) format_aggregate_signature(AggInfo *agginfo, Archive *fout)
{ {
...@@ -3866,15 +3946,15 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout) ...@@ -3866,15 +3946,15 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout)
appendPQExpBuffer(&buf, "%s", appendPQExpBuffer(&buf, "%s",
fmtId(agginfo->aggname, force_quotes)); fmtId(agginfo->aggname, force_quotes));
anybasetype = (strcmp(agginfo->aggbasetype, "-") == 0); anybasetype = (strcmp(agginfo->aggbasetype, "0") == 0);
/* If using regtype or format_type, name is already quoted */ /* If using regtype or format_type, fmtbasetype is already quoted */
if (fout->remoteVersion >= 70100) if (fout->remoteVersion >= 70100)
{ {
if (anybasetype) if (anybasetype)
appendPQExpBuffer(&buf, "(*)"); appendPQExpBuffer(&buf, "(*)");
else else
appendPQExpBuffer(&buf, "(%s)", agginfo->aggbasetype); appendPQExpBuffer(&buf, "(%s)", agginfo->fmtbasetype);
} }
else else
{ {
...@@ -3882,7 +3962,7 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout) ...@@ -3882,7 +3962,7 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout)
appendPQExpBuffer(&buf, "(*)"); appendPQExpBuffer(&buf, "(*)");
else else
appendPQExpBuffer(&buf, "(%s)", appendPQExpBuffer(&buf, "(%s)",
fmtId(agginfo->aggbasetype, force_quotes)); fmtId(agginfo->fmtbasetype, force_quotes));
} }
return buf.data; return buf.data;
...@@ -3919,6 +3999,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo) ...@@ -3919,6 +3999,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
int i_aggfinalfn; int i_aggfinalfn;
int i_aggtranstype; int i_aggtranstype;
int i_agginitval; int i_agginitval;
int i_fmtbasetype;
int i_convertok; int i_convertok;
const char *aggtransfn; const char *aggtransfn;
const char *aggfinalfn; const char *aggfinalfn;
...@@ -3934,19 +4015,23 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo) ...@@ -3934,19 +4015,23 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
if (g_fout->remoteVersion >= 70300) if (g_fout->remoteVersion >= 70300)
{ {
appendPQExpBuffer(query, "SELECT aggtransfn, " appendPQExpBuffer(query, "SELECT aggtransfn, "
"aggfinalfn, aggtranstype::regtype, " "aggfinalfn, aggtranstype::pg_catalog.regtype, "
"agginitval, " "agginitval, "
"proargtypes[0]::pg_catalog.regtype as fmtbasetype, "
"'t'::boolean as convertok " "'t'::boolean as convertok "
"from pg_aggregate a, pg_proc p " "from pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
"where a.aggfnoid = p.oid " "where a.aggfnoid = p.oid "
"and p.oid = '%s'::oid", "and p.oid = '%s'::pg_catalog.oid",
agginfo->oid); agginfo->oid);
} }
else if (g_fout->remoteVersion >= 70100) else if (g_fout->remoteVersion >= 70100)
{ {
appendPQExpBuffer(query, "SELECT aggtransfn, aggfinalfn, " appendPQExpBuffer(query, "SELECT aggtransfn, aggfinalfn, "
"format_type(aggtranstype, NULL) as aggtranstype, " "format_type(aggtranstype, NULL) as aggtranstype, "
"agginitval, 't'::boolean as convertok " "agginitval, "
"CASE WHEN aggbasetype = 0 THEN '-' "
"ELSE format_type(aggbasetype, NULL) END as fmtbasetype, "
"'t'::boolean as convertok "
"from pg_aggregate " "from pg_aggregate "
"where oid = '%s'::oid", "where oid = '%s'::oid",
agginfo->oid); agginfo->oid);
...@@ -3957,6 +4042,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo) ...@@ -3957,6 +4042,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
"aggfinalfn, " "aggfinalfn, "
"(select typname from pg_type where oid = aggtranstype1) as aggtranstype, " "(select typname from pg_type where oid = aggtranstype1) as aggtranstype, "
"agginitval1 as agginitval, " "agginitval1 as agginitval, "
"(select typname from pg_type where oid = aggbasetype) as fmtbasetype, "
"(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) as convertok " "(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) as convertok "
"from pg_aggregate " "from pg_aggregate "
"where oid = '%s'::oid", "where oid = '%s'::oid",
...@@ -3985,12 +4071,15 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo) ...@@ -3985,12 +4071,15 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
i_aggfinalfn = PQfnumber(res, "aggfinalfn"); i_aggfinalfn = PQfnumber(res, "aggfinalfn");
i_aggtranstype = PQfnumber(res, "aggtranstype"); i_aggtranstype = PQfnumber(res, "aggtranstype");
i_agginitval = PQfnumber(res, "agginitval"); i_agginitval = PQfnumber(res, "agginitval");
i_fmtbasetype = PQfnumber(res, "fmtbasetype");
i_convertok = PQfnumber(res, "convertok"); i_convertok = PQfnumber(res, "convertok");
aggtransfn = PQgetvalue(res, 0, i_aggtransfn); aggtransfn = PQgetvalue(res, 0, i_aggtransfn);
aggfinalfn = PQgetvalue(res, 0, i_aggfinalfn); aggfinalfn = PQgetvalue(res, 0, i_aggfinalfn);
aggtranstype = PQgetvalue(res, 0, i_aggtranstype); aggtranstype = PQgetvalue(res, 0, i_aggtranstype);
agginitval = PQgetvalue(res, 0, i_agginitval); agginitval = PQgetvalue(res, 0, i_agginitval);
/* we save fmtbasetype so that dumpAggACL can use it later */
agginfo->fmtbasetype = strdup(PQgetvalue(res, 0, i_fmtbasetype));
convertok = (PQgetvalue(res, 0, i_convertok)[0] == 't'); convertok = (PQgetvalue(res, 0, i_convertok)[0] == 't');
aggSig = format_aggregate_signature(agginfo, g_fout); aggSig = format_aggregate_signature(agginfo, g_fout);
...@@ -4010,13 +4099,13 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo) ...@@ -4010,13 +4099,13 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
return; return;
} }
anybasetype = (strcmp(agginfo->aggbasetype, "-") == 0); anybasetype = (strcmp(agginfo->aggbasetype, "0") == 0);
if (g_fout->remoteVersion >= 70300) if (g_fout->remoteVersion >= 70300)
{ {
/* If using 7.3's regproc or regtype, data is already quoted */ /* If using 7.3's regproc or regtype, data is already quoted */
appendPQExpBuffer(details, "BASETYPE = %s, SFUNC = %s, STYPE = %s", appendPQExpBuffer(details, "BASETYPE = %s, SFUNC = %s, STYPE = %s",
anybasetype ? "'any'" : agginfo->aggbasetype, anybasetype ? "'any'" : agginfo->fmtbasetype,
aggtransfn, aggtransfn,
aggtranstype); aggtranstype);
} }
...@@ -4024,7 +4113,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo) ...@@ -4024,7 +4113,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
{ {
/* format_type quotes, regproc does not */ /* format_type quotes, regproc does not */
appendPQExpBuffer(details, "BASETYPE = %s, SFUNC = %s, STYPE = %s", appendPQExpBuffer(details, "BASETYPE = %s, SFUNC = %s, STYPE = %s",
anybasetype ? "'any'" : agginfo->aggbasetype, anybasetype ? "'any'" : agginfo->fmtbasetype,
fmtId(aggtransfn, force_quotes), fmtId(aggtransfn, force_quotes),
aggtranstype); aggtranstype);
} }
...@@ -4033,7 +4122,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo) ...@@ -4033,7 +4122,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
/* need quotes all around */ /* need quotes all around */
appendPQExpBuffer(details, "BASETYPE = %s, ", appendPQExpBuffer(details, "BASETYPE = %s, ",
anybasetype ? "'any'" : anybasetype ? "'any'" :
fmtId(agginfo->aggbasetype, force_quotes)); fmtId(agginfo->fmtbasetype, force_quotes));
appendPQExpBuffer(details, "SFUNC = %s, ", appendPQExpBuffer(details, "SFUNC = %s, ",
fmtId(aggtransfn, force_quotes)); fmtId(aggtransfn, force_quotes));
appendPQExpBuffer(details, "STYPE = %s", appendPQExpBuffer(details, "STYPE = %s",
...@@ -4052,7 +4141,10 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo) ...@@ -4052,7 +4141,10 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
aggfinalfn); aggfinalfn);
} }
appendPQExpBuffer(delq, "DROP AGGREGATE %s;\n", aggSig); /* DROP must be fully qualified in case same name appears in pg_catalog */
appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
fmtId(agginfo->aggnamespace->nspname, force_quotes),
aggSig);
appendPQExpBuffer(q, "CREATE AGGREGATE %s ( %s );\n", appendPQExpBuffer(q, "CREATE AGGREGATE %s ( %s );\n",
fmtId(agginfo->aggname, force_quotes), fmtId(agginfo->aggname, force_quotes),
...@@ -4152,6 +4244,11 @@ GetPrivileges(Archive *AH, const char *s, const char *type) ...@@ -4152,6 +4244,11 @@ GetPrivileges(Archive *AH, const char *s, const char *type)
{ {
CONVERT_PRIV('U', "USAGE"); CONVERT_PRIV('U', "USAGE");
} }
else if (strcmp(type, "SCHEMA")==0)
{
CONVERT_PRIV('C', "CREATE");
CONVERT_PRIV('U', "USAGE");
}
else else
abort(); abort();
...@@ -4167,13 +4264,13 @@ GetPrivileges(Archive *AH, const char *s, const char *type) ...@@ -4167,13 +4264,13 @@ GetPrivileges(Archive *AH, const char *s, const char *type)
/* /*
* Write out grant/revoke information * Write out grant/revoke information
* *
* 'type' must be TABLE, FUNCTION, or LANGUAGE. 'name' is the * 'type' must be TABLE, FUNCTION, LANGUAGE, or SCHEMA. 'name' is the
* formatted name of the object. Must be quoted etc. already. * formatted name of the object. Must be quoted etc. already.
* 'nspname' is the namespace the object is in. 'usename' is the * 'nspname' is the namespace the object is in (NULL if none).
* owner, NULL if there is no owner (for languages). 'acls' is the * 'usename' is the owner, NULL if there is no owner (for languages).
* string read out of the fooacl system catalog field; it will be * 'acls' is the string read out of the fooacl system catalog field;
* parsed here. 'objoid' is the OID of the object for purposes of * it will be parsed here.
* ordering. * 'objoid' is the OID of the object for purposes of ordering.
*/ */
static void static void
dumpACL(Archive *fout, const char *type, const char *name, dumpACL(Archive *fout, const char *type, const char *name,
...@@ -4188,7 +4285,7 @@ dumpACL(Archive *fout, const char *type, const char *name, ...@@ -4188,7 +4285,7 @@ dumpACL(Archive *fout, const char *type, const char *name,
bool found_owner_privs = false; bool found_owner_privs = false;
if (strlen(acls) == 0) if (strlen(acls) == 0)
return; /* table has default permissions */ return; /* object has default permissions */
sql = createPQExpBuffer(); sql = createPQExpBuffer();
...@@ -4218,8 +4315,7 @@ dumpACL(Archive *fout, const char *type, const char *name, ...@@ -4218,8 +4315,7 @@ dumpACL(Archive *fout, const char *type, const char *name,
*eqpos = '\0'; /* it's ok to clobber aclbuf */ *eqpos = '\0'; /* it's ok to clobber aclbuf */
/* /*
* Parse the privileges (right-hand side). Skip if there are * Parse the privileges (right-hand side).
* none.
*/ */
priv = GetPrivileges(fout, eqpos + 1, type); priv = GetPrivileges(fout, eqpos + 1, type);
...@@ -4262,6 +4358,23 @@ dumpACL(Archive *fout, const char *type, const char *name, ...@@ -4262,6 +4358,23 @@ dumpACL(Archive *fout, const char *type, const char *name,
appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes)); appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes));
} }
} }
else
{
/* No privileges. Issue explicit REVOKE for safety. */
appendPQExpBuffer(sql, "REVOKE ALL ON %s %s FROM ",
type, name);
if (eqpos == tok)
{
/* Empty left-hand side means "PUBLIC" */
appendPQExpBuffer(sql, "PUBLIC;\n");
}
else if (strncmp(tok, "group ", strlen("group ")) == 0)
appendPQExpBuffer(sql, "GROUP %s;\n",
fmtId(tok + strlen("group "),
force_quotes));
else
appendPQExpBuffer(sql, "%s;\n", fmtId(tok, force_quotes));
}
free(priv); free(priv);
} }
...@@ -4275,11 +4388,10 @@ dumpACL(Archive *fout, const char *type, const char *name, ...@@ -4275,11 +4388,10 @@ dumpACL(Archive *fout, const char *type, const char *name,
appendPQExpBuffer(sql, "%s;\n", fmtId(usename, force_quotes)); appendPQExpBuffer(sql, "%s;\n", fmtId(usename, force_quotes));
} }
free(aclbuf);
ArchiveEntry(fout, objoid, name, nspname, usename ? usename : "", ArchiveEntry(fout, objoid, name, nspname, usename ? usename : "",
"ACL", NULL, sql->data, "", NULL, NULL, NULL); "ACL", NULL, sql->data, "", NULL, NULL, NULL);
free(aclbuf);
destroyPQExpBuffer(sql); destroyPQExpBuffer(sql);
} }
...@@ -4373,10 +4485,10 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo) ...@@ -4373,10 +4485,10 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo)
if (g_fout->remoteVersion >= 70300) if (g_fout->remoteVersion >= 70300)
{ {
/* Beginning in 7.3, viewname is not unique; use OID */ /* Beginning in 7.3, viewname is not unique; use OID */
appendPQExpBuffer(query, "SELECT pg_get_viewdef(ev_class) as viewdef, " appendPQExpBuffer(query, "SELECT pg_catalog.pg_get_viewdef(ev_class) as viewdef, "
"oid as view_oid" "oid as view_oid"
" from pg_rewrite where" " from pg_catalog.pg_rewrite where"
" ev_class = '%s'::oid and" " ev_class = '%s'::pg_catalog.oid and"
" rulename = '_RETURN';", " rulename = '_RETURN';",
tbinfo->oid); tbinfo->oid);
} }
...@@ -4430,8 +4542,12 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo) ...@@ -4430,8 +4542,12 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo)
/* Save it for use by dumpACL, too */ /* Save it for use by dumpACL, too */
tbinfo->viewoid = objoid; tbinfo->viewoid = objoid;
appendPQExpBuffer(delq, "DROP VIEW %s;\n", /* DROP must be fully qualified in case same name appears in pg_catalog */
appendPQExpBuffer(delq, "DROP VIEW %s.",
fmtId(tbinfo->relnamespace->nspname, force_quotes));
appendPQExpBuffer(delq, "%s;\n",
fmtId(tbinfo->relname, force_quotes)); fmtId(tbinfo->relname, force_quotes));
appendPQExpBuffer(q, "CREATE VIEW %s AS %s\n", appendPQExpBuffer(q, "CREATE VIEW %s AS %s\n",
fmtId(tbinfo->relname, force_quotes), viewdef); fmtId(tbinfo->relname, force_quotes), viewdef);
...@@ -4466,7 +4582,10 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo) ...@@ -4466,7 +4582,10 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo)
numParents = tbinfo->numParents; numParents = tbinfo->numParents;
parentIndexes = tbinfo->parentIndexes; parentIndexes = tbinfo->parentIndexes;
appendPQExpBuffer(delq, "DROP TABLE %s;\n", /* DROP must be fully qualified in case same name appears in pg_catalog */
appendPQExpBuffer(delq, "DROP TABLE %s.",
fmtId(tbinfo->relnamespace->nspname, force_quotes));
appendPQExpBuffer(delq, "%s;\n",
fmtId(tbinfo->relname, force_quotes)); fmtId(tbinfo->relname, force_quotes));
appendPQExpBuffer(q, "CREATE TABLE %s (\n\t", appendPQExpBuffer(q, "CREATE TABLE %s (\n\t",
...@@ -4524,18 +4643,37 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo) ...@@ -4524,18 +4643,37 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo)
tbinfo->relname); tbinfo->relname);
resetPQExpBuffer(query); resetPQExpBuffer(query);
appendPQExpBuffer(query, "SELECT rcname, rcsrc from pg_relcheck " if (g_fout->remoteVersion >= 70300)
appendPQExpBuffer(query, "SELECT rcname, rcsrc"
" from pg_catalog.pg_relcheck c1"
" where rcrelid = '%s'::pg_catalog.oid "
" and not exists "
" (select 1 from "
" pg_catalog.pg_relcheck c2, "
" pg_catalog.pg_inherits i "
" where i.inhrelid = c1.rcrelid "
" and (c2.rcname = c1.rcname "
" or (c2.rcname[0] = '$' "
" and c1.rcname[0] = '$')"
" )"
" and c2.rcsrc = c1.rcsrc "
" and c2.rcrelid = i.inhparent) "
" order by rcname ",
tbinfo->oid);
else
appendPQExpBuffer(query, "SELECT rcname, rcsrc"
" from pg_relcheck c1"
" where rcrelid = '%s'::oid " " where rcrelid = '%s'::oid "
" and not exists " " and not exists "
" (select 1 from pg_relcheck as c, " " (select 1 from pg_relcheck c2, "
" pg_inherits as i " " pg_inherits i "
" where i.inhrelid = pg_relcheck.rcrelid " " where i.inhrelid = c1.rcrelid "
" and (c.rcname = pg_relcheck.rcname " " and (c2.rcname = c1.rcname "
" or (c.rcname[0] = '$' " " or (c2.rcname[0] = '$' "
" and pg_relcheck.rcname[0] = '$')" " and c1.rcname[0] = '$')"
" )" " )"
" and c.rcsrc = pg_relcheck.rcsrc " " and c2.rcsrc = c1.rcsrc "
" and c.rcrelid = i.inhparent) " " and c2.rcrelid = i.inhparent) "
" order by rcname ", " order by rcname ",
tbinfo->oid); tbinfo->oid);
res2 = PQexec(g_conn, query->data); res2 = PQexec(g_conn, query->data);
...@@ -4694,6 +4832,20 @@ dumpIndexes(Archive *fout, TableInfo *tblinfo, int numTables) ...@@ -4694,6 +4832,20 @@ dumpIndexes(Archive *fout, TableInfo *tblinfo, int numTables)
selectSourceSchema(tbinfo->relnamespace->nspname); selectSourceSchema(tbinfo->relnamespace->nspname);
resetPQExpBuffer(query); resetPQExpBuffer(query);
if (g_fout->remoteVersion >= 70300)
appendPQExpBuffer(query,
"SELECT i.indexrelid as indexreloid, "
"t.relname as indexrelname, "
"pg_catalog.pg_get_indexdef(i.indexrelid) as indexdef, "
"i.indisprimary, i.indkey, "
"t.relnatts as indnkeys "
"FROM pg_catalog.pg_index i, "
"pg_catalog.pg_class t "
"WHERE t.oid = i.indexrelid "
"AND i.indrelid = '%s'::pg_catalog.oid "
"ORDER BY indexrelname",
tbinfo->oid);
else
appendPQExpBuffer(query, appendPQExpBuffer(query,
"SELECT i.indexrelid as indexreloid, " "SELECT i.indexrelid as indexreloid, "
"t.relname as indexrelname, " "t.relname as indexrelname, "
...@@ -4779,7 +4931,10 @@ dumpIndexes(Archive *fout, TableInfo *tblinfo, int numTables) ...@@ -4779,7 +4931,10 @@ dumpIndexes(Archive *fout, TableInfo *tblinfo, int numTables)
/* Plain secondary index */ /* Plain secondary index */
appendPQExpBuffer(q, "%s;\n", indexdef); appendPQExpBuffer(q, "%s;\n", indexdef);
appendPQExpBuffer(delq, "DROP INDEX %s;\n", /* DROP must be fully qualified in case same name appears in pg_catalog */
appendPQExpBuffer(delq, "DROP INDEX %s.",
fmtId(tbinfo->relnamespace->nspname, force_quotes));
appendPQExpBuffer(delq, "%s;\n",
fmtId(indexrelname, force_quotes)); fmtId(indexrelname, force_quotes));
ArchiveEntry(fout, indexreloid, ArchiveEntry(fout, indexreloid,
...@@ -4821,7 +4976,7 @@ setMaxOid(Archive *fout) ...@@ -4821,7 +4976,7 @@ setMaxOid(Archive *fout)
Oid max_oid; Oid max_oid;
char sql[1024]; char sql[1024];
res = PQexec(g_conn, "CREATE TEMPORARY TABLE pgdump_oid (dummy int4)"); res = PQexec(g_conn, "CREATE TEMPORARY TABLE pgdump_oid (dummy integer)");
if (!res || if (!res ||
PQresultStatus(res) != PGRES_COMMAND_OK) PQresultStatus(res) != PGRES_COMMAND_OK)
{ {
...@@ -4854,7 +5009,7 @@ setMaxOid(Archive *fout) ...@@ -4854,7 +5009,7 @@ setMaxOid(Archive *fout)
if (g_verbose) if (g_verbose)
write_msg(NULL, "maximum system oid is %u\n", max_oid); write_msg(NULL, "maximum system oid is %u\n", max_oid);
snprintf(sql, 1024, snprintf(sql, 1024,
"CREATE TEMPORARY TABLE pgdump_oid (dummy int4);\n" "CREATE TEMPORARY TABLE pgdump_oid (dummy integer);\n"
"COPY pgdump_oid WITH OIDS FROM stdin;\n" "COPY pgdump_oid WITH OIDS FROM stdin;\n"
"%u\t0\n" "%u\t0\n"
"\\.\n" "\\.\n"
...@@ -5014,7 +5169,11 @@ dumpOneSequence(Archive *fout, TableInfo *tbinfo, ...@@ -5014,7 +5169,11 @@ dumpOneSequence(Archive *fout, TableInfo *tbinfo,
if (!dataOnly) if (!dataOnly)
{ {
resetPQExpBuffer(delqry); resetPQExpBuffer(delqry);
appendPQExpBuffer(delqry, "DROP SEQUENCE %s;\n",
/* DROP must be fully qualified in case same name appears in pg_catalog */
appendPQExpBuffer(delqry, "DROP SEQUENCE %s.",
fmtId(tbinfo->relnamespace->nspname, force_quotes));
appendPQExpBuffer(delqry, "%s;\n",
fmtId(tbinfo->relname, force_quotes)); fmtId(tbinfo->relname, force_quotes));
resetPQExpBuffer(query); resetPQExpBuffer(query);
...@@ -5036,7 +5195,7 @@ dumpOneSequence(Archive *fout, TableInfo *tbinfo, ...@@ -5036,7 +5195,7 @@ dumpOneSequence(Archive *fout, TableInfo *tbinfo,
if (!schemaOnly) if (!schemaOnly)
{ {
resetPQExpBuffer(query); resetPQExpBuffer(query);
appendPQExpBuffer(query, "SELECT setval ("); appendPQExpBuffer(query, "SELECT pg_catalog.setval (");
formatStringLiteral(query, fmtId(tbinfo->relname, force_quotes), CONV_ALL); formatStringLiteral(query, fmtId(tbinfo->relname, force_quotes), CONV_ALL);
appendPQExpBuffer(query, ", %s, %s);\n", appendPQExpBuffer(query, ", %s, %s);\n",
last, (called ? "true" : "false")); last, (called ? "true" : "false"));
...@@ -5106,13 +5265,14 @@ dumpTriggers(Archive *fout, TableInfo *tblinfo, int numTables) ...@@ -5106,13 +5265,14 @@ dumpTriggers(Archive *fout, TableInfo *tblinfo, int numTables)
if (g_fout->remoteVersion >= 70300) if (g_fout->remoteVersion >= 70300)
{ {
appendPQExpBuffer(query, appendPQExpBuffer(query,
"SELECT tgname, tgfoid::regproc as tgfname, " "SELECT tgname, "
"tgfoid::pg_catalog.regproc as tgfname, "
"tgtype, tgnargs, tgargs, " "tgtype, tgnargs, tgargs, "
"tgisconstraint, tgconstrname, tgdeferrable, " "tgisconstraint, tgconstrname, tgdeferrable, "
"tgconstrrelid, tginitdeferred, oid, " "tgconstrrelid, tginitdeferred, oid, "
"tgconstrrelid::regclass as tgconstrrelname " "tgconstrrelid::pg_catalog.regclass as tgconstrrelname "
"from pg_trigger " "from pg_catalog.pg_trigger "
"where tgrelid = '%s'::oid", "where tgrelid = '%s'::pg_catalog.oid",
tbinfo->oid); tbinfo->oid);
} }
else else
...@@ -5186,9 +5346,12 @@ dumpTriggers(Archive *fout, TableInfo *tblinfo, int numTables) ...@@ -5186,9 +5346,12 @@ dumpTriggers(Archive *fout, TableInfo *tblinfo, int numTables)
tginitdeferred = 1; tginitdeferred = 1;
resetPQExpBuffer(delqry); resetPQExpBuffer(delqry);
/* DROP must be fully qualified in case same name appears in pg_catalog */
appendPQExpBuffer(delqry, "DROP TRIGGER %s ", appendPQExpBuffer(delqry, "DROP TRIGGER %s ",
fmtId(tgname, force_quotes)); fmtId(tgname, force_quotes));
appendPQExpBuffer(delqry, "ON %s;\n", appendPQExpBuffer(delqry, "ON %s.",
fmtId(tbinfo->relnamespace->nspname, force_quotes));
appendPQExpBuffer(delqry, "%s;\n",
fmtId(tbinfo->relname, force_quotes)); fmtId(tbinfo->relname, force_quotes));
resetPQExpBuffer(query); resetPQExpBuffer(query);
...@@ -5370,7 +5533,18 @@ dumpRules(Archive *fout, TableInfo *tblinfo, int numTables) ...@@ -5370,7 +5533,18 @@ dumpRules(Archive *fout, TableInfo *tblinfo, int numTables)
*/ */
resetPQExpBuffer(query); resetPQExpBuffer(query);
if (g_fout->remoteVersion < 70300) if (g_fout->remoteVersion >= 70300)
{
appendPQExpBuffer(query,
"SELECT pg_catalog.pg_get_ruledef(oid) AS definition,"
" oid, rulename "
"FROM pg_catalog.pg_rewrite "
"WHERE ev_class = '%s'::pg_catalog.oid "
"AND rulename != '_RETURN' "
"ORDER BY oid",
tbinfo->oid);
}
else
{ {
/* /*
* We include pg_rules in the cross since it filters out all view * We include pg_rules in the cross since it filters out all view
...@@ -5387,17 +5561,6 @@ dumpRules(Archive *fout, TableInfo *tblinfo, int numTables) ...@@ -5387,17 +5561,6 @@ dumpRules(Archive *fout, TableInfo *tblinfo, int numTables)
" AND pg_rules.rulename = pg_rewrite.rulename " " AND pg_rules.rulename = pg_rewrite.rulename "
"ORDER BY pg_rewrite.oid"); "ORDER BY pg_rewrite.oid");
} }
else
{
appendPQExpBuffer(query,
"SELECT pg_get_ruledef(oid) AS definition,"
" oid, rulename "
"FROM pg_rewrite "
"WHERE ev_class = '%s'::oid "
"AND rulename != '_RETURN' "
"ORDER BY oid",
tbinfo->oid);
}
res = PQexec(g_conn, query->data); res = PQexec(g_conn, query->data);
if (!res || if (!res ||
...@@ -5450,9 +5613,13 @@ dumpRules(Archive *fout, TableInfo *tblinfo, int numTables) ...@@ -5450,9 +5613,13 @@ dumpRules(Archive *fout, TableInfo *tblinfo, int numTables)
* selectSourceSchema - make the specified schema the active search path * selectSourceSchema - make the specified schema the active search path
* in the source database. * in the source database.
* *
* NB: pg_catalog is implicitly searched before the specified schema; * NB: pg_catalog is explicitly searched after the specified schema;
* so system names are never qualified, and user names are only qualified * so user names are only qualified if they are cross-schema references,
* if they are cross-schema references or duplicate system names. * and system names are only qualified if they conflict with a user name
* in the current schema.
*
* Whenever the selected schema is not pg_catalog, be careful to qualify
* references to system catalogs and types in our emitted commands!
*/ */
static void static void
selectSourceSchema(const char *schemaName) selectSourceSchema(const char *schemaName)
...@@ -5474,6 +5641,8 @@ selectSourceSchema(const char *schemaName) ...@@ -5474,6 +5641,8 @@ selectSourceSchema(const char *schemaName)
query = createPQExpBuffer(); query = createPQExpBuffer();
appendPQExpBuffer(query, "SET search_path = %s", appendPQExpBuffer(query, "SET search_path = %s",
fmtId(schemaName, force_quotes)); fmtId(schemaName, force_quotes));
if (strcmp(schemaName, "pg_catalog") != 0)
appendPQExpBuffer(query, ", pg_catalog");
res = PQexec(g_conn, query->data); res = PQexec(g_conn, query->data);
if (!res || if (!res ||
PQresultStatus(res) != PGRES_COMMAND_OK) PQresultStatus(res) != PGRES_COMMAND_OK)
...@@ -5518,7 +5687,12 @@ getFormattedTypeName(const char *oid, OidOptions opts) ...@@ -5518,7 +5687,12 @@ getFormattedTypeName(const char *oid, OidOptions opts)
} }
query = createPQExpBuffer(); query = createPQExpBuffer();
if (g_fout->remoteVersion >= 70100) if (g_fout->remoteVersion >= 70300)
{
appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%s'::pg_catalog.oid, NULL)",
oid);
}
else if (g_fout->remoteVersion >= 70100)
{ {
appendPQExpBuffer(query, "SELECT format_type('%s'::oid, NULL)", appendPQExpBuffer(query, "SELECT format_type('%s'::oid, NULL)",
oid); oid);
...@@ -5549,7 +5723,16 @@ getFormattedTypeName(const char *oid, OidOptions opts) ...@@ -5549,7 +5723,16 @@ getFormattedTypeName(const char *oid, OidOptions opts)
exit_nicely(); exit_nicely();
} }
if (g_fout->remoteVersion >= 70100)
{
/* already quoted */
result = strdup(PQgetvalue(res, 0, 0)); result = strdup(PQgetvalue(res, 0, 0));
}
else
{
/* may need to quote it */
result = strdup(fmtId(PQgetvalue(res, 0, 0), false));
}
PQclear(res); PQclear(res);
destroyPQExpBuffer(query); destroyPQExpBuffer(query);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_dump.h,v 1.86 2002/05/19 10:08:25 petere Exp $ * $Id: pg_dump.h,v 1.87 2002/05/28 22:26:57 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -70,10 +70,11 @@ typedef struct _aggInfo ...@@ -70,10 +70,11 @@ typedef struct _aggInfo
{ {
char *oid; char *oid;
char *aggname; char *aggname;
char *aggbasetype; char *aggbasetype; /* OID */
NamespaceInfo *aggnamespace; /* link to containing namespace */ NamespaceInfo *aggnamespace; /* link to containing namespace */
char *usename; char *usename;
char *aggacl; char *aggacl;
char *fmtbasetype; /* formatted type name */
} AggInfo; } AggInfo;
typedef struct _oprInfo typedef struct _oprInfo
......
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