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
|
* 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)
|
|||||||
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)
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
* 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)
|
|||||||
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;
|
|
||||||
|
|
||||||
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", 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, nspinfo->usename,
|
||||||
NULL, nsinfo[i].usename,
|
nspinfo->oid, "pg_namespace", 0, NULL);
|
||||||
nsinfo[i].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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
(*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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
(*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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
|||||||
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)
|
|||||||
|
|
||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
"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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
/* 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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
/*
|
/*
|
||||||
* 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,
|
|||||||
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,
|
|||||||
*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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
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,20 +4643,39 @@ 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)
|
||||||
" where rcrelid = '%s'::oid "
|
appendPQExpBuffer(query, "SELECT rcname, rcsrc"
|
||||||
" and not exists "
|
" from pg_catalog.pg_relcheck c1"
|
||||||
" (select 1 from pg_relcheck as c, "
|
" where rcrelid = '%s'::pg_catalog.oid "
|
||||||
" pg_inherits as i "
|
" and not exists "
|
||||||
" where i.inhrelid = pg_relcheck.rcrelid "
|
" (select 1 from "
|
||||||
" and (c.rcname = pg_relcheck.rcname "
|
" pg_catalog.pg_relcheck c2, "
|
||||||
" or (c.rcname[0] = '$' "
|
" pg_catalog.pg_inherits i "
|
||||||
" and pg_relcheck.rcname[0] = '$')"
|
" where i.inhrelid = c1.rcrelid "
|
||||||
" )"
|
" and (c2.rcname = c1.rcname "
|
||||||
" and c.rcsrc = pg_relcheck.rcsrc "
|
" or (c2.rcname[0] = '$' "
|
||||||
" and c.rcrelid = i.inhparent) "
|
" and c1.rcname[0] = '$')"
|
||||||
" order by rcname ",
|
" )"
|
||||||
tbinfo->oid);
|
" 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);
|
res2 = PQexec(g_conn, query->data);
|
||||||
if (!res2 ||
|
if (!res2 ||
|
||||||
PQresultStatus(res2) != PGRES_TUPLES_OK)
|
PQresultStatus(res2) != PGRES_TUPLES_OK)
|
||||||
@ -4694,17 +4832,31 @@ dumpIndexes(Archive *fout, TableInfo *tblinfo, int numTables)
|
|||||||
selectSourceSchema(tbinfo->relnamespace->nspname);
|
selectSourceSchema(tbinfo->relnamespace->nspname);
|
||||||
|
|
||||||
resetPQExpBuffer(query);
|
resetPQExpBuffer(query);
|
||||||
appendPQExpBuffer(query,
|
if (g_fout->remoteVersion >= 70300)
|
||||||
"SELECT i.indexrelid as indexreloid, "
|
appendPQExpBuffer(query,
|
||||||
"t.relname as indexrelname, "
|
"SELECT i.indexrelid as indexreloid, "
|
||||||
"pg_get_indexdef(i.indexrelid) as indexdef, "
|
"t.relname as indexrelname, "
|
||||||
"i.indisprimary, i.indkey, "
|
"pg_catalog.pg_get_indexdef(i.indexrelid) as indexdef, "
|
||||||
"t.relnatts as indnkeys "
|
"i.indisprimary, i.indkey, "
|
||||||
"FROM pg_index i, pg_class t "
|
"t.relnatts as indnkeys "
|
||||||
"WHERE t.oid = i.indexrelid "
|
"FROM pg_catalog.pg_index i, "
|
||||||
"AND i.indrelid = '%s'::oid "
|
"pg_catalog.pg_class t "
|
||||||
"ORDER BY indexrelname",
|
"WHERE t.oid = i.indexrelid "
|
||||||
tbinfo->oid);
|
"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);
|
res = PQexec(g_conn, query->data);
|
||||||
if (!res ||
|
if (!res ||
|
||||||
@ -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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
" 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)
|
|||||||
* 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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
exit_nicely();
|
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);
|
PQclear(res);
|
||||||
destroyPQExpBuffer(query);
|
destroyPQExpBuffer(query);
|
||||||
|
@ -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
|
|||||||
{
|
{
|
||||||
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
|
||||||
|
Loading…
Reference in New Issue
Block a user