Rework pg_dump namespace search criteria so that dumping of user objects
authorTom Lane
Tue, 28 May 2002 22:26:57 +0000 (22:26 +0000)
committerTom Lane
Tue, 28 May 2002 22:26:57 +0000 (22:26 +0000)
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.

src/bin/pg_dump/pg_backup_archiver.c
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h

index 272b98cecef23a756c18bc0bed3f9dd030bc9a0c..0236a54478ff129933eecdb92881d6d12bfbdc5c 100644 (file)
@@ -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 - [email protected]
  *
@@ -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);
 }
 
 
index 2e0295fc8448925b4b73962adad6beb0e066af86..109ab0bb94359248b137ad2dfc3871d97d07a08e 100644 (file)
@@ -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);
index c78439a0c55d9776e7f157cd9ffd6f4dbcdef8c2..d2600ce45e0ce8abd04d8ee7fc63a4ab249ea16d 100644 (file)
@@ -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