mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-23 19:39:53 +08:00
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.
This commit is contained in:
parent
5a8ab29adf
commit
36a1e732a6
@ -15,7 +15,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
@ -2097,17 +2097,23 @@ _reconnectAsOwner(ArchiveHandle *AH, const char *dbname, TocEntry *te)
|
||||
static void
|
||||
_selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
|
||||
{
|
||||
PQExpBuffer qry;
|
||||
|
||||
if (!schemaName || *schemaName == '\0' ||
|
||||
strcmp(AH->currSchema, schemaName) == 0)
|
||||
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))
|
||||
{
|
||||
PQExpBuffer qry = createPQExpBuffer();
|
||||
PGresult *res;
|
||||
|
||||
appendPQExpBuffer(qry, "SET search_path = %s;",
|
||||
fmtId(schemaName, false));
|
||||
res = PQexec(AH->connection, qry->data);
|
||||
|
||||
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
@ -2115,15 +2121,15 @@ _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
|
||||
schemaName, PQerrorMessage(AH->connection));
|
||||
|
||||
PQclear(res);
|
||||
destroyPQExpBuffer(qry);
|
||||
}
|
||||
else
|
||||
ahprintf(AH, "SET search_path = %s;\n\n",
|
||||
fmtId(schemaName, false));
|
||||
ahprintf(AH, "%s;\n\n", qry->data);
|
||||
|
||||
if (AH->currSchema)
|
||||
free(AH->currSchema);
|
||||
AH->currSchema = strdup(schemaName);
|
||||
|
||||
destroyPQExpBuffer(qry);
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
*
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
appendPQExpBuffer(query, "SELECT pg_proc.oid, proname as aggname, "
|
||||
"pronamespace as aggnamespace, "
|
||||
"proargtypes[0]::regtype as aggbasetype, "
|
||||
"proargtypes[0] as aggbasetype, "
|
||||
"(select usename from pg_user where proowner = usesysid) as usename, "
|
||||
"proacl as aggacl "
|
||||
"FROM pg_proc "
|
||||
@ -1791,10 +1791,9 @@ getAggregates(int *numAggs)
|
||||
{
|
||||
appendPQExpBuffer(query, "SELECT pg_aggregate.oid, aggname, "
|
||||
"0::oid as aggnamespace, "
|
||||
"CASE WHEN aggbasetype = 0 THEN '-' "
|
||||
"ELSE format_type(aggbasetype, NULL) END as aggbasetype, "
|
||||
"aggbasetype, "
|
||||
"(select usename from pg_user where aggowner = usesysid) as usename, "
|
||||
"cast('{=X}' as aclitem[]) as aggacl "
|
||||
"'{=X}' as aggacl "
|
||||
"from pg_aggregate "
|
||||
"where oid > '%u'::oid",
|
||||
g_last_builtin_oid);
|
||||
@ -1833,6 +1832,7 @@ getAggregates(int *numAggs)
|
||||
write_msg(NULL, "WARNING: owner of aggregate function \"%s\" appears to be invalid\n",
|
||||
agginfo[i].aggname);
|
||||
agginfo[i].aggacl = strdup(PQgetvalue(res, i, i_aggacl));
|
||||
agginfo[i].fmtbasetype = NULL; /* computed when it's dumped */
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
@ -1890,7 +1890,7 @@ getFuncs(int *numFuncs)
|
||||
appendPQExpBuffer(query,
|
||||
"SELECT pg_proc.oid, proname, prolang, "
|
||||
"pronargs, proargtypes, prorettype, "
|
||||
"cast('{=X}' as aclitem[]) as proacl, "
|
||||
"'{=X}' as proacl, "
|
||||
"0::oid as pronamespace, "
|
||||
"(select usename from pg_user where proowner = usesysid) as usename "
|
||||
"FROM pg_proc "
|
||||
@ -2290,7 +2290,18 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
|
||||
|
||||
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, "
|
||||
"attnotnull, atthasdef, "
|
||||
@ -2367,7 +2378,15 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
|
||||
tblinfo[i].relname);
|
||||
|
||||
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, "
|
||||
"pg_get_expr(adbin, adrelid) AS adsrc "
|
||||
@ -2452,8 +2471,8 @@ dumpComment(Archive *fout, const char *target,
|
||||
if (fout->remoteVersion >= 70300)
|
||||
{
|
||||
appendPQExpBuffer(query, "SELECT description FROM pg_catalog.pg_description "
|
||||
"WHERE objoid = '%s'::oid and classoid = "
|
||||
"'pg_catalog.%s'::regclass "
|
||||
"WHERE objoid = '%s'::pg_catalog.oid and classoid = "
|
||||
"'pg_catalog.%s'::pg_catalog.regclass "
|
||||
"and objsubid = %d",
|
||||
oid, classname, subid);
|
||||
}
|
||||
@ -2537,8 +2556,8 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
|
||||
if (fout->remoteVersion >= 70300)
|
||||
{
|
||||
appendPQExpBuffer(query, "SELECT description, objsubid FROM pg_catalog.pg_description "
|
||||
"WHERE objoid = '%s'::oid and classoid = "
|
||||
"'pg_catalog.pg_class'::regclass "
|
||||
"WHERE objoid = '%s'::pg_catalog.oid and classoid = "
|
||||
"'pg_catalog.pg_class'::pg_catalog.regclass "
|
||||
"ORDER BY objoid, classoid, objsubid",
|
||||
tbinfo->oid);
|
||||
}
|
||||
@ -2622,9 +2641,7 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
|
||||
* dumpDBComment --
|
||||
*
|
||||
* This routine is used to dump any comments associated with the
|
||||
* database to which we are currently connected. If the user chose
|
||||
* to dump the schema of the database, then this is the first
|
||||
* statement issued.
|
||||
* database to which we are currently connected.
|
||||
*/
|
||||
void
|
||||
dumpDBComment(Archive *fout)
|
||||
@ -2677,45 +2694,63 @@ dumpNamespaces(Archive *fout, NamespaceInfo *nsinfo, int numNamespaces)
|
||||
PQExpBuffer q = createPQExpBuffer();
|
||||
PQExpBuffer delq = createPQExpBuffer();
|
||||
int i;
|
||||
char *qnspname;
|
||||
|
||||
for (i = 0; i < numNamespaces; i++)
|
||||
{
|
||||
NamespaceInfo *nspinfo = &nsinfo[i];
|
||||
|
||||
/* skip if not to be dumped */
|
||||
if (!nsinfo[i].dump)
|
||||
if (!nspinfo->dump)
|
||||
continue;
|
||||
|
||||
/* don't dump dummy namespace from pre-7.3 source */
|
||||
if (strlen(nsinfo[i].nspname) == 0)
|
||||
if (strlen(nspinfo->nspname) == 0)
|
||||
continue;
|
||||
|
||||
/* quick hack: don't dump CREATE SCHEMA for public namespace */
|
||||
/* XXX need a better idea */
|
||||
if (strcmp(nsinfo[i].nspname, "public") == 0)
|
||||
continue;
|
||||
qnspname = strdup(fmtId(nspinfo->nspname, force_quotes));
|
||||
|
||||
resetPQExpBuffer(q);
|
||||
resetPQExpBuffer(delq);
|
||||
/*
|
||||
* 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(delq);
|
||||
|
||||
#ifdef NOTYET /* suppress till DROP SCHEMA works */
|
||||
appendPQExpBuffer(delq, "DROP SCHEMA %s;\n",
|
||||
fmtId(nsinfo[i].nspname, force_quotes));
|
||||
#endif
|
||||
appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
|
||||
|
||||
appendPQExpBuffer(q, "CREATE SCHEMA %s;\n",
|
||||
fmtId(nsinfo[i].nspname, force_quotes));
|
||||
appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
|
||||
|
||||
ArchiveEntry(fout, nsinfo[i].oid, nsinfo[i].nspname,
|
||||
NULL,
|
||||
nsinfo[i].usename, "SCHEMA", NULL,
|
||||
q->data, delq->data, NULL, NULL, NULL);
|
||||
ArchiveEntry(fout, nspinfo->oid, nspinfo->nspname,
|
||||
NULL,
|
||||
nspinfo->usename, "SCHEMA", NULL,
|
||||
q->data, delq->data, NULL, NULL, NULL);
|
||||
|
||||
/*** Dump Schema Comments ***/
|
||||
resetPQExpBuffer(q);
|
||||
appendPQExpBuffer(q, "SCHEMA %s",
|
||||
fmtId(nsinfo[i].nspname, force_quotes));
|
||||
dumpComment(fout, q->data,
|
||||
NULL, nsinfo[i].usename,
|
||||
nsinfo[i].oid, "pg_namespace", 0, NULL);
|
||||
/*** Dump Schema Comments ***/
|
||||
resetPQExpBuffer(q);
|
||||
appendPQExpBuffer(q, "SCHEMA %s", qnspname);
|
||||
dumpComment(fout, q->data,
|
||||
NULL, nspinfo->usename,
|
||||
nspinfo->oid, "pg_namespace", 0, NULL);
|
||||
|
||||
if (!aclsSkip)
|
||||
dumpACL(fout, "SCHEMA", qnspname, NULL,
|
||||
nspinfo->usename, nspinfo->nspacl,
|
||||
nspinfo->oid);
|
||||
}
|
||||
|
||||
free(qnspname);
|
||||
}
|
||||
|
||||
destroyPQExpBuffer(q);
|
||||
@ -2762,7 +2797,21 @@ dumpOneBaseType(Archive *fout, TypeInfo *tinfo,
|
||||
selectSourceSchema(tinfo->typnamespace->nspname);
|
||||
|
||||
/* 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, "
|
||||
"typinput, typoutput, typreceive, typsend, "
|
||||
@ -2823,7 +2872,7 @@ dumpOneBaseType(Archive *fout, TypeInfo *tinfo,
|
||||
if (PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
|
||||
typdefault = NULL;
|
||||
else
|
||||
typdefault = strdup(PQgetvalue(res, 0, PQfnumber(res, "typdefault")));
|
||||
typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
|
||||
typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
|
||||
typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
|
||||
typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
|
||||
@ -2856,7 +2905,10 @@ dumpOneBaseType(Archive *fout, TypeInfo *tinfo,
|
||||
(*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));
|
||||
|
||||
appendPQExpBuffer(q,
|
||||
@ -2977,11 +3029,12 @@ dumpOneDomain(Archive *fout, TypeInfo *tinfo)
|
||||
selectSourceSchema(tinfo->typnamespace->nspname);
|
||||
|
||||
/* Fetch domain specific details */
|
||||
/* We assume here that remoteVersion must be at least 70300 */
|
||||
appendPQExpBuffer(query, "SELECT typnotnull, "
|
||||
"format_type(typbasetype, typtypmod) as typdefn, "
|
||||
"pg_catalog.format_type(typbasetype, typtypmod) as typdefn, "
|
||||
"typdefault, typbasetype "
|
||||
"FROM pg_type "
|
||||
"WHERE oid = '%s'::oid",
|
||||
"FROM pg_catalog.pg_type "
|
||||
"WHERE oid = '%s'::pg_catalog.oid",
|
||||
tinfo->oid);
|
||||
|
||||
res = PQexec(g_conn, query->data);
|
||||
@ -3006,11 +3059,13 @@ dumpOneDomain(Archive *fout, TypeInfo *tinfo)
|
||||
if (PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
|
||||
typdefault = NULL;
|
||||
else
|
||||
typdefault = strdup(PQgetvalue(res, 0, PQfnumber(res, "typdefault")));
|
||||
typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
|
||||
typbasetype = PQgetvalue(res, 0, PQfnumber(res, "typbasetype"));
|
||||
|
||||
/* Command to drop the old copy */
|
||||
appendPQExpBuffer(delq, "DROP DOMAIN %s RESTRICT;\n",
|
||||
/* DROP must be fully qualified in case same name appears in pg_catalog */
|
||||
appendPQExpBuffer(delq, "DROP DOMAIN %s.",
|
||||
fmtId(tinfo->typnamespace->nspname, force_quotes));
|
||||
appendPQExpBuffer(delq, "%s RESTRICT;\n",
|
||||
fmtId(tinfo->typname, force_quotes));
|
||||
|
||||
appendPQExpBuffer(q,
|
||||
@ -3025,11 +3080,7 @@ dumpOneDomain(Archive *fout, TypeInfo *tinfo)
|
||||
appendPQExpBuffer(q, " NOT NULL");
|
||||
|
||||
if (typdefault)
|
||||
{
|
||||
appendPQExpBuffer(q,
|
||||
" DEFAULT %s",
|
||||
typdefault);
|
||||
}
|
||||
appendPQExpBuffer(q, " DEFAULT %s", typdefault);
|
||||
|
||||
appendPQExpBuffer(q, ";\n");
|
||||
|
||||
@ -3206,7 +3257,8 @@ dumpProcLangs(Archive *fout, FuncInfo finfo[], int numFuncs)
|
||||
|
||||
(*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",
|
||||
(PQgetvalue(res, i, i_lanpltrusted)[0] == 't') ?
|
||||
@ -3216,7 +3268,13 @@ dumpProcLangs(Archive *fout, FuncInfo finfo[], int numFuncs)
|
||||
fmtId(finfo[fidx].proname, force_quotes));
|
||||
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));
|
||||
(*deps)[depIdx++] = strdup(lanvalidator);
|
||||
}
|
||||
@ -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 *
|
||||
format_function_signature(FuncInfo *finfo)
|
||||
{
|
||||
@ -3340,9 +3403,9 @@ dumpOneFunc(Archive *fout, FuncInfo *finfo)
|
||||
appendPQExpBuffer(query,
|
||||
"SELECT proretset, prosrc, probin, "
|
||||
"provolatile, proimplicit, proisstrict, prosecdef, "
|
||||
"(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
|
||||
"FROM pg_proc "
|
||||
"WHERE oid = '%s'::oid",
|
||||
"(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
|
||||
"FROM pg_catalog.pg_proc "
|
||||
"WHERE oid = '%s'::pg_catalog.oid",
|
||||
finfo->oid);
|
||||
}
|
||||
else if (g_fout->remoteVersion >= 70100)
|
||||
@ -3424,7 +3487,10 @@ dumpOneFunc(Archive *fout, FuncInfo *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);
|
||||
|
||||
@ -3561,15 +3627,21 @@ dumpOneOpr(Archive *fout, OprInfo *oprinfo,
|
||||
|
||||
if (g_fout->remoteVersion >= 70300)
|
||||
{
|
||||
appendPQExpBuffer(query, "SELECT oprkind, oprcode::regprocedure, "
|
||||
"oprleft::regtype, oprright::regtype, "
|
||||
"oprcom::regoperator, oprnegate::regoperator, "
|
||||
"oprrest::regprocedure, oprjoin::regprocedure, "
|
||||
appendPQExpBuffer(query, "SELECT oprkind, "
|
||||
"oprcode::pg_catalog.regprocedure, "
|
||||
"oprleft::pg_catalog.regtype, "
|
||||
"oprright::pg_catalog.regtype, "
|
||||
"oprcom::pg_catalog.regoperator, "
|
||||
"oprnegate::pg_catalog.regoperator, "
|
||||
"oprrest::pg_catalog.regprocedure, "
|
||||
"oprjoin::pg_catalog.regprocedure, "
|
||||
"oprcanhash, "
|
||||
"oprlsortop::regoperator, oprrsortop::regoperator, "
|
||||
"oprltcmpop::regoperator, oprgtcmpop::regoperator "
|
||||
"from pg_operator "
|
||||
"where oid = '%s'::oid",
|
||||
"oprlsortop::pg_catalog.regoperator, "
|
||||
"oprrsortop::pg_catalog.regoperator, "
|
||||
"oprltcmpop::pg_catalog.regoperator, "
|
||||
"oprgtcmpop::pg_catalog.regoperator "
|
||||
"from pg_catalog.pg_operator "
|
||||
"where oid = '%s'::pg_catalog.oid",
|
||||
oprinfo->oid);
|
||||
}
|
||||
else if (g_fout->remoteVersion >= 70100)
|
||||
@ -3717,7 +3789,9 @@ dumpOneOpr(Archive *fout, OprInfo *oprinfo,
|
||||
if (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);
|
||||
|
||||
appendPQExpBuffer(q, "CREATE OPERATOR %s (%s);\n",
|
||||
@ -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 *
|
||||
format_aggregate_signature(AggInfo *agginfo, Archive *fout)
|
||||
{
|
||||
@ -3866,15 +3946,15 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout)
|
||||
appendPQExpBuffer(&buf, "%s",
|
||||
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 (anybasetype)
|
||||
appendPQExpBuffer(&buf, "(*)");
|
||||
else
|
||||
appendPQExpBuffer(&buf, "(%s)", agginfo->aggbasetype);
|
||||
appendPQExpBuffer(&buf, "(%s)", agginfo->fmtbasetype);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3882,7 +3962,7 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout)
|
||||
appendPQExpBuffer(&buf, "(*)");
|
||||
else
|
||||
appendPQExpBuffer(&buf, "(%s)",
|
||||
fmtId(agginfo->aggbasetype, force_quotes));
|
||||
fmtId(agginfo->fmtbasetype, force_quotes));
|
||||
}
|
||||
|
||||
return buf.data;
|
||||
@ -3919,6 +3999,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
||||
int i_aggfinalfn;
|
||||
int i_aggtranstype;
|
||||
int i_agginitval;
|
||||
int i_fmtbasetype;
|
||||
int i_convertok;
|
||||
const char *aggtransfn;
|
||||
const char *aggfinalfn;
|
||||
@ -3934,19 +4015,23 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
||||
if (g_fout->remoteVersion >= 70300)
|
||||
{
|
||||
appendPQExpBuffer(query, "SELECT aggtransfn, "
|
||||
"aggfinalfn, aggtranstype::regtype, "
|
||||
"aggfinalfn, aggtranstype::pg_catalog.regtype, "
|
||||
"agginitval, "
|
||||
"proargtypes[0]::pg_catalog.regtype as fmtbasetype, "
|
||||
"'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 "
|
||||
"and p.oid = '%s'::oid",
|
||||
"and p.oid = '%s'::pg_catalog.oid",
|
||||
agginfo->oid);
|
||||
}
|
||||
else if (g_fout->remoteVersion >= 70100)
|
||||
{
|
||||
appendPQExpBuffer(query, "SELECT aggtransfn, aggfinalfn, "
|
||||
"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 "
|
||||
"where oid = '%s'::oid",
|
||||
agginfo->oid);
|
||||
@ -3957,6 +4042,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
||||
"aggfinalfn, "
|
||||
"(select typname from pg_type where oid = aggtranstype1) as aggtranstype, "
|
||||
"agginitval1 as agginitval, "
|
||||
"(select typname from pg_type where oid = aggbasetype) as fmtbasetype, "
|
||||
"(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) as convertok "
|
||||
"from pg_aggregate "
|
||||
"where oid = '%s'::oid",
|
||||
@ -3985,12 +4071,15 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
||||
i_aggfinalfn = PQfnumber(res, "aggfinalfn");
|
||||
i_aggtranstype = PQfnumber(res, "aggtranstype");
|
||||
i_agginitval = PQfnumber(res, "agginitval");
|
||||
i_fmtbasetype = PQfnumber(res, "fmtbasetype");
|
||||
i_convertok = PQfnumber(res, "convertok");
|
||||
|
||||
aggtransfn = PQgetvalue(res, 0, i_aggtransfn);
|
||||
aggfinalfn = PQgetvalue(res, 0, i_aggfinalfn);
|
||||
aggtranstype = PQgetvalue(res, 0, i_aggtranstype);
|
||||
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');
|
||||
|
||||
aggSig = format_aggregate_signature(agginfo, g_fout);
|
||||
@ -4010,13 +4099,13 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
||||
return;
|
||||
}
|
||||
|
||||
anybasetype = (strcmp(agginfo->aggbasetype, "-") == 0);
|
||||
anybasetype = (strcmp(agginfo->aggbasetype, "0") == 0);
|
||||
|
||||
if (g_fout->remoteVersion >= 70300)
|
||||
{
|
||||
/* If using 7.3's regproc or regtype, data is already quoted */
|
||||
appendPQExpBuffer(details, "BASETYPE = %s, SFUNC = %s, STYPE = %s",
|
||||
anybasetype ? "'any'" : agginfo->aggbasetype,
|
||||
anybasetype ? "'any'" : agginfo->fmtbasetype,
|
||||
aggtransfn,
|
||||
aggtranstype);
|
||||
}
|
||||
@ -4024,7 +4113,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
||||
{
|
||||
/* format_type quotes, regproc does not */
|
||||
appendPQExpBuffer(details, "BASETYPE = %s, SFUNC = %s, STYPE = %s",
|
||||
anybasetype ? "'any'" : agginfo->aggbasetype,
|
||||
anybasetype ? "'any'" : agginfo->fmtbasetype,
|
||||
fmtId(aggtransfn, force_quotes),
|
||||
aggtranstype);
|
||||
}
|
||||
@ -4033,7 +4122,7 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
||||
/* need quotes all around */
|
||||
appendPQExpBuffer(details, "BASETYPE = %s, ",
|
||||
anybasetype ? "'any'" :
|
||||
fmtId(agginfo->aggbasetype, force_quotes));
|
||||
fmtId(agginfo->fmtbasetype, force_quotes));
|
||||
appendPQExpBuffer(details, "SFUNC = %s, ",
|
||||
fmtId(aggtransfn, force_quotes));
|
||||
appendPQExpBuffer(details, "STYPE = %s",
|
||||
@ -4052,7 +4141,10 @@ dumpOneAgg(Archive *fout, AggInfo *agginfo)
|
||||
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",
|
||||
fmtId(agginfo->aggname, force_quotes),
|
||||
@ -4152,6 +4244,11 @@ GetPrivileges(Archive *AH, const char *s, const char *type)
|
||||
{
|
||||
CONVERT_PRIV('U', "USAGE");
|
||||
}
|
||||
else if (strcmp(type, "SCHEMA")==0)
|
||||
{
|
||||
CONVERT_PRIV('C', "CREATE");
|
||||
CONVERT_PRIV('U', "USAGE");
|
||||
}
|
||||
else
|
||||
abort();
|
||||
|
||||
@ -4167,13 +4264,13 @@ GetPrivileges(Archive *AH, const char *s, const char *type)
|
||||
/*
|
||||
* 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.
|
||||
* 'nspname' is the namespace the object is in. 'usename' is the
|
||||
* owner, NULL if there is no owner (for languages). 'acls' is the
|
||||
* string read out of the fooacl system catalog field; it will be
|
||||
* parsed here. 'objoid' is the OID of the object for purposes of
|
||||
* ordering.
|
||||
* 'nspname' is the namespace the object is in (NULL if none).
|
||||
* 'usename' is the owner, NULL if there is no owner (for languages).
|
||||
* 'acls' is the string read out of the fooacl system catalog field;
|
||||
* it will be parsed here.
|
||||
* 'objoid' is the OID of the object for purposes of ordering.
|
||||
*/
|
||||
static void
|
||||
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;
|
||||
|
||||
if (strlen(acls) == 0)
|
||||
return; /* table has default permissions */
|
||||
return; /* object has default permissions */
|
||||
|
||||
sql = createPQExpBuffer();
|
||||
|
||||
@ -4218,8 +4315,7 @@ dumpACL(Archive *fout, const char *type, const char *name,
|
||||
*eqpos = '\0'; /* it's ok to clobber aclbuf */
|
||||
|
||||
/*
|
||||
* Parse the privileges (right-hand side). Skip if there are
|
||||
* none.
|
||||
* Parse the privileges (right-hand side).
|
||||
*/
|
||||
priv = GetPrivileges(fout, eqpos + 1, type);
|
||||
|
||||
@ -4262,6 +4358,23 @@ dumpACL(Archive *fout, const char *type, const char *name,
|
||||
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);
|
||||
}
|
||||
|
||||
@ -4275,11 +4388,10 @@ dumpACL(Archive *fout, const char *type, const char *name,
|
||||
appendPQExpBuffer(sql, "%s;\n", fmtId(usename, force_quotes));
|
||||
}
|
||||
|
||||
free(aclbuf);
|
||||
|
||||
ArchiveEntry(fout, objoid, name, nspname, usename ? usename : "",
|
||||
"ACL", NULL, sql->data, "", NULL, NULL, NULL);
|
||||
|
||||
free(aclbuf);
|
||||
destroyPQExpBuffer(sql);
|
||||
}
|
||||
|
||||
@ -4373,10 +4485,10 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo)
|
||||
if (g_fout->remoteVersion >= 70300)
|
||||
{
|
||||
/* 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"
|
||||
" from pg_rewrite where"
|
||||
" ev_class = '%s'::oid and"
|
||||
" from pg_catalog.pg_rewrite where"
|
||||
" ev_class = '%s'::pg_catalog.oid and"
|
||||
" rulename = '_RETURN';",
|
||||
tbinfo->oid);
|
||||
}
|
||||
@ -4430,8 +4542,12 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo)
|
||||
/* Save it for use by dumpACL, too */
|
||||
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));
|
||||
|
||||
appendPQExpBuffer(q, "CREATE VIEW %s AS %s\n",
|
||||
fmtId(tbinfo->relname, force_quotes), viewdef);
|
||||
|
||||
@ -4466,7 +4582,10 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo)
|
||||
numParents = tbinfo->numParents;
|
||||
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));
|
||||
|
||||
appendPQExpBuffer(q, "CREATE TABLE %s (\n\t",
|
||||
@ -4524,20 +4643,39 @@ dumpOneTable(Archive *fout, TableInfo *tbinfo, TableInfo *g_tblinfo)
|
||||
tbinfo->relname);
|
||||
|
||||
resetPQExpBuffer(query);
|
||||
appendPQExpBuffer(query, "SELECT rcname, rcsrc from pg_relcheck "
|
||||
" where rcrelid = '%s'::oid "
|
||||
" and not exists "
|
||||
" (select 1 from pg_relcheck as c, "
|
||||
" pg_inherits as i "
|
||||
" where i.inhrelid = pg_relcheck.rcrelid "
|
||||
" and (c.rcname = pg_relcheck.rcname "
|
||||
" or (c.rcname[0] = '$' "
|
||||
" and pg_relcheck.rcname[0] = '$')"
|
||||
" )"
|
||||
" and c.rcsrc = pg_relcheck.rcsrc "
|
||||
" and c.rcrelid = i.inhparent) "
|
||||
" order by rcname ",
|
||||
tbinfo->oid);
|
||||
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 "
|
||||
" and not exists "
|
||||
" (select 1 from pg_relcheck c2, "
|
||||
" 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);
|
||||
res2 = PQexec(g_conn, query->data);
|
||||
if (!res2 ||
|
||||
PQresultStatus(res2) != PGRES_TUPLES_OK)
|
||||
@ -4694,17 +4832,31 @@ dumpIndexes(Archive *fout, TableInfo *tblinfo, int numTables)
|
||||
selectSourceSchema(tbinfo->relnamespace->nspname);
|
||||
|
||||
resetPQExpBuffer(query);
|
||||
appendPQExpBuffer(query,
|
||||
"SELECT i.indexrelid as indexreloid, "
|
||||
"t.relname as indexrelname, "
|
||||
"pg_get_indexdef(i.indexrelid) as indexdef, "
|
||||
"i.indisprimary, i.indkey, "
|
||||
"t.relnatts as indnkeys "
|
||||
"FROM pg_index i, pg_class t "
|
||||
"WHERE t.oid = i.indexrelid "
|
||||
"AND i.indrelid = '%s'::oid "
|
||||
"ORDER BY indexrelname",
|
||||
tbinfo->oid);
|
||||
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,
|
||||
"SELECT i.indexrelid as indexreloid, "
|
||||
"t.relname as indexrelname, "
|
||||
"pg_get_indexdef(i.indexrelid) as indexdef, "
|
||||
"i.indisprimary, i.indkey, "
|
||||
"t.relnatts as indnkeys "
|
||||
"FROM pg_index i, pg_class t "
|
||||
"WHERE t.oid = i.indexrelid "
|
||||
"AND i.indrelid = '%s'::oid "
|
||||
"ORDER BY indexrelname",
|
||||
tbinfo->oid);
|
||||
|
||||
res = PQexec(g_conn, query->data);
|
||||
if (!res ||
|
||||
@ -4779,7 +4931,10 @@ dumpIndexes(Archive *fout, TableInfo *tblinfo, int numTables)
|
||||
/* Plain secondary index */
|
||||
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));
|
||||
|
||||
ArchiveEntry(fout, indexreloid,
|
||||
@ -4821,7 +4976,7 @@ setMaxOid(Archive *fout)
|
||||
Oid max_oid;
|
||||
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 ||
|
||||
PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
@ -4854,7 +5009,7 @@ setMaxOid(Archive *fout)
|
||||
if (g_verbose)
|
||||
write_msg(NULL, "maximum system oid is %u\n", max_oid);
|
||||
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"
|
||||
"%u\t0\n"
|
||||
"\\.\n"
|
||||
@ -5014,7 +5169,11 @@ dumpOneSequence(Archive *fout, TableInfo *tbinfo,
|
||||
if (!dataOnly)
|
||||
{
|
||||
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));
|
||||
|
||||
resetPQExpBuffer(query);
|
||||
@ -5036,7 +5195,7 @@ dumpOneSequence(Archive *fout, TableInfo *tbinfo,
|
||||
if (!schemaOnly)
|
||||
{
|
||||
resetPQExpBuffer(query);
|
||||
appendPQExpBuffer(query, "SELECT setval (");
|
||||
appendPQExpBuffer(query, "SELECT pg_catalog.setval (");
|
||||
formatStringLiteral(query, fmtId(tbinfo->relname, force_quotes), CONV_ALL);
|
||||
appendPQExpBuffer(query, ", %s, %s);\n",
|
||||
last, (called ? "true" : "false"));
|
||||
@ -5106,13 +5265,14 @@ dumpTriggers(Archive *fout, TableInfo *tblinfo, int numTables)
|
||||
if (g_fout->remoteVersion >= 70300)
|
||||
{
|
||||
appendPQExpBuffer(query,
|
||||
"SELECT tgname, tgfoid::regproc as tgfname, "
|
||||
"SELECT tgname, "
|
||||
"tgfoid::pg_catalog.regproc as tgfname, "
|
||||
"tgtype, tgnargs, tgargs, "
|
||||
"tgisconstraint, tgconstrname, tgdeferrable, "
|
||||
"tgconstrrelid, tginitdeferred, oid, "
|
||||
"tgconstrrelid::regclass as tgconstrrelname "
|
||||
"from pg_trigger "
|
||||
"where tgrelid = '%s'::oid",
|
||||
"tgconstrrelid::pg_catalog.regclass as tgconstrrelname "
|
||||
"from pg_catalog.pg_trigger "
|
||||
"where tgrelid = '%s'::pg_catalog.oid",
|
||||
tbinfo->oid);
|
||||
}
|
||||
else
|
||||
@ -5186,9 +5346,12 @@ dumpTriggers(Archive *fout, TableInfo *tblinfo, int numTables)
|
||||
tginitdeferred = 1;
|
||||
|
||||
resetPQExpBuffer(delqry);
|
||||
/* DROP must be fully qualified in case same name appears in pg_catalog */
|
||||
appendPQExpBuffer(delqry, "DROP TRIGGER %s ",
|
||||
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));
|
||||
|
||||
resetPQExpBuffer(query);
|
||||
@ -5370,7 +5533,18 @@ dumpRules(Archive *fout, TableInfo *tblinfo, int numTables)
|
||||
*/
|
||||
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
|
||||
@ -5387,17 +5561,6 @@ dumpRules(Archive *fout, TableInfo *tblinfo, int numTables)
|
||||
" AND pg_rules.rulename = pg_rewrite.rulename "
|
||||
"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);
|
||||
if (!res ||
|
||||
@ -5450,9 +5613,13 @@ dumpRules(Archive *fout, TableInfo *tblinfo, int numTables)
|
||||
* selectSourceSchema - make the specified schema the active search path
|
||||
* in the source database.
|
||||
*
|
||||
* NB: pg_catalog is implicitly searched before the specified schema;
|
||||
* so system names are never qualified, and user names are only qualified
|
||||
* if they are cross-schema references or duplicate system names.
|
||||
* NB: pg_catalog is explicitly searched after the specified schema;
|
||||
* so user names are only qualified if they are cross-schema references,
|
||||
* 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
|
||||
selectSourceSchema(const char *schemaName)
|
||||
@ -5474,6 +5641,8 @@ selectSourceSchema(const char *schemaName)
|
||||
query = createPQExpBuffer();
|
||||
appendPQExpBuffer(query, "SET search_path = %s",
|
||||
fmtId(schemaName, force_quotes));
|
||||
if (strcmp(schemaName, "pg_catalog") != 0)
|
||||
appendPQExpBuffer(query, ", pg_catalog");
|
||||
res = PQexec(g_conn, query->data);
|
||||
if (!res ||
|
||||
PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
@ -5518,7 +5687,12 @@ getFormattedTypeName(const char *oid, OidOptions opts)
|
||||
}
|
||||
|
||||
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)",
|
||||
oid);
|
||||
@ -5549,7 +5723,16 @@ getFormattedTypeName(const char *oid, OidOptions opts)
|
||||
exit_nicely();
|
||||
}
|
||||
|
||||
result = strdup(PQgetvalue(res, 0, 0));
|
||||
if (g_fout->remoteVersion >= 70100)
|
||||
{
|
||||
/* already quoted */
|
||||
result = strdup(PQgetvalue(res, 0, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* may need to quote it */
|
||||
result = strdup(fmtId(PQgetvalue(res, 0, 0), false));
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
destroyPQExpBuffer(query);
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* 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
|
||||
{
|
||||
char *oid;
|
||||
char *aggname;
|
||||
char *aggbasetype;
|
||||
char *aggbasetype; /* OID */
|
||||
NamespaceInfo *aggnamespace; /* link to containing namespace */
|
||||
char *usename;
|
||||
char *aggacl;
|
||||
char *fmtbasetype; /* formatted type name */
|
||||
} AggInfo;
|
||||
|
||||
typedef struct _oprInfo
|
||||
|
Loading…
Reference in New Issue
Block a user