OSDN Git Service

Bruce,
authorBruce Momjian <bruce@momjian.us>
Tue, 18 Jan 2000 18:09:02 +0000 (18:09 +0000)
committerBruce Momjian <bruce@momjian.us>
Tue, 18 Jan 2000 18:09:02 +0000 (18:09 +0000)
Attached is a patch which patches cleanly against the Sunday afternoon
snapshot. It modifies pg_dump to dump COMMENT ON statements for
user-definable descriptions. In addition, it also modifies comment.c so
that the operator behavior is as Peter E. would like: a comment on an
operator is applied to the underlying function.

Thanks,

Mike Mascari

src/backend/commands/comment.c
src/bin/pg_dump/common.c
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h

index 9ebf207..dc82476 100644 (file)
@@ -19,6 +19,7 @@
 #include "catalog/pg_aggregate.h"
 #include "catalog/pg_database.h"
 #include "catalog/pg_description.h"
+#include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_rewrite.h"
 #include "catalog/pg_shadow.h"
@@ -658,6 +659,7 @@ void CommentProc(char *function, List *arguments, char *comment)
 
 void CommentOperator(char *opername, List *arguments, char *comment) {
 
+  Form_pg_operator data;
   HeapTuple optuple;
   Oid oid, leftoid = InvalidOid, rightoid = InvalidOid;
   bool defined;
@@ -719,6 +721,14 @@ void CommentOperator(char *opername, List *arguments, char *comment) {
   }
   #endif
 
+  /*** Get the procedure associated with the operator ***/
+
+  data = (Form_pg_operator) GETSTRUCT(optuple);
+  oid = regproctooid(data->oprcode);
+  if (oid == InvalidOid) {
+         elog(ERROR, "operator '%s' does not have an underlying function", opername);
+  }
+  
   /*** Call CreateComments() to create/drop the comments ***/
 
   CreateComments(oid, comment);
index 9b6d641..f111ca5 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.38 2000/01/18 07:29:58 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.39 2000/01/18 18:09:02 momjian Exp $
  *
  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  *
@@ -292,6 +292,14 @@ dumpSchema(FILE *fout,
        if (!tablename && fout)
        {
                if (g_verbose)
+                       fprintf(stderr, "%s dumping out database comment %s\n",
+                                       g_comment_start, g_comment_end);
+               dumpDBComment(fout);
+       }
+
+       if (!tablename && fout)
+       {
+               if (g_verbose)
                        fprintf(stderr, "%s dumping out user-defined types %s\n",
                                        g_comment_start, g_comment_end);
                dumpTypes(fout, finfo, numFuncs, tinfo, numTypes);
index 82e55c3..a4f2676 100644 (file)
@@ -21,7 +21,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.134 2000/01/18 07:29:58 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.135 2000/01/18 18:09:02 momjian Exp $
  *
  * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
  *
@@ -78,6 +78,7 @@
 
 #include "pg_dump.h"
 
+static void dumpComment(FILE *outfile, const char *target, const char *oid);
 static void dumpSequence(FILE *fout, TableInfo tbinfo);
 static void dumpACL(FILE *fout, TableInfo tbinfo);
 static void dumpTriggers(FILE *fout, const char *tablename,
@@ -1136,6 +1137,8 @@ clearTableInfo(TableInfo *tblinfo, int numTables)
                /* Process Attributes */
                for (j = 0; j < tblinfo[i].numatts; j++)
                {
+                       if (tblinfo[i].attoids[j])
+                               free(tblinfo[i].attoids[j]);
                        if (tblinfo[i].attnames[j])
                                free(tblinfo[i].attnames[j]);
                        if (tblinfo[i].typnames[j])
@@ -1225,6 +1228,8 @@ clearIndInfo(IndInfo *ind, int numIndices)
                return;
        for (i = 0; i < numIndices; ++i)
        {
+               if (ind[i].indoid)
+                       free(ind[i].indoid);
                if (ind[i].indexrelname)
                        free(ind[i].indexrelname);
                if (ind[i].indrelname)
@@ -1692,7 +1697,8 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
                if (tblinfo[i].ntrig > 0)
                {
                        PGresult   *res2;
-                       int                     i_tgname,
+                       int                     i_tgoid,
+                                       i_tgname,
                                                i_tgfoid,
                                                i_tgtype,
                                                i_tgnargs,
@@ -1707,7 +1713,7 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
                                                g_comment_end);
 
                        resetPQExpBuffer(query);
-                       appendPQExpBuffer(query, "SELECT tgname, tgfoid, tgtype, tgnargs, tgargs "
+                       appendPQExpBuffer(query, "SELECT tgname, tgfoid, tgtype, tgnargs, tgargs, oid "
                                        "from pg_trigger "
                                        "where tgrelid = '%s'::oid ",
                                        tblinfo[i].oid);
@@ -1730,7 +1736,10 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
                        i_tgtype = PQfnumber(res2, "tgtype");
                        i_tgnargs = PQfnumber(res2, "tgnargs");
                        i_tgargs = PQfnumber(res2, "tgargs");
+                       i_tgoid = PQfnumber(res2, "oid");
                        tblinfo[i].triggers = (char **) malloc(ntups2 * sizeof(char *));
+                       tblinfo[i].trcomments = (char **) malloc(ntups2 * sizeof(char *));
+                       tblinfo[i].troids = (char **) malloc(ntups2 * sizeof(char *));
                        resetPQExpBuffer(query);
                        for (i2 = 0; i2 < ntups2; i2++)
                        {
@@ -1842,11 +1851,27 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
                                }
                                appendPQExpBuffer(query, ");\n");
                                tblinfo[i].triggers[i2] = strdup(query->data);
+
+                               /*** Initialize trcomments and troids ***/
+                               
+                               resetPQExpBuffer(query);
+                               appendPQExpBuffer(query, "TRIGGER %s ", 
+                                                                 fmtId(PQgetvalue(res2, i2, i_tgname), force_quotes));
+                               appendPQExpBuffer(query, "ON %s",
+                                                                 fmtId(tblinfo[i].relname, force_quotes));
+                               tblinfo[i].trcomments[i2] = strdup(query->data);
+                               tblinfo[i].troids[i2] = strdup(PQgetvalue(res2, i2, i_tgoid));
+
                        }
                        PQclear(res2);
                }
                else
+               {
                        tblinfo[i].triggers = NULL;
+                       tblinfo[i].trcomments = NULL;
+                       tblinfo[i].troids = NULL;
+               }
+                 
        }
 
        PQclear(res);
@@ -1928,6 +1953,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
        int                     i_atttypmod;
        int                     i_attnotnull;
        int                     i_atthasdef;
+       int         i_attoid;
        PGresult        *res;
        int                     ntups;
 
@@ -1951,7 +1977,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                        g_comment_end);
 
                resetPQExpBuffer(q);
-               appendPQExpBuffer(q, "SELECT a.attnum, a.attname, t.typname, a.atttypmod, "
+               appendPQExpBuffer(q, "SELECT a.oid as attoid, a.attnum, a.attname, t.typname, a.atttypmod, "
                                "a.attnotnull, a.atthasdef "
                                "from pg_attribute a, pg_type t "
                                "where a.attrelid = '%s'::oid and a.atttypid = t.oid "
@@ -1967,6 +1993,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 
                ntups = PQntuples(res);
 
+               i_attoid = PQfnumber(res, "attoid");
                i_attname = PQfnumber(res, "attname");
                i_typname = PQfnumber(res, "typname");
                i_atttypmod = PQfnumber(res, "atttypmod");
@@ -1974,6 +2001,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                i_atthasdef = PQfnumber(res, "atthasdef");
 
                tblinfo[i].numatts = ntups;
+               tblinfo[i].attoids = (char **) malloc(ntups * sizeof(char *));
                tblinfo[i].attnames = (char **) malloc(ntups * sizeof(char *));
                tblinfo[i].typnames = (char **) malloc(ntups * sizeof(char *));
                tblinfo[i].atttypmod = (int *) malloc(ntups * sizeof(int));
@@ -1984,6 +2012,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                tblinfo[i].numParents = 0;
                for (j = 0; j < ntups; j++)
                {
+                       tblinfo[i].attoids[j] = strdup(PQgetvalue(res, j, i_attoid));
                        tblinfo[i].attnames[j] = strdup(PQgetvalue(res, j, i_attname));
                        tblinfo[i].typnames[j] = strdup(PQgetvalue(res, j, i_typname));
                        tblinfo[i].atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod));
@@ -2047,6 +2076,7 @@ getIndices(int *numIndices)
        int                     i_indkey;
        int                     i_indclass;
        int                     i_indisunique;
+       int         i_indoid;
 
        /*
         * find all the user-defined indices. We do not handle partial
@@ -2058,7 +2088,7 @@ getIndices(int *numIndices)
         */
 
        appendPQExpBuffer(query,
-           "SELECT t1.relname as indexrelname, t2.relname as indrelname, "
+           "SELECT t1.oid as indoid, t1.relname as indexrelname, t2.relname as indrelname, "
                        "i.indproc, i.indkey, i.indclass, "
                        "a.amname as indamname, i.indisunique "
                        "from pg_index i, pg_class t1, pg_class t2, pg_am a "
@@ -2083,6 +2113,7 @@ getIndices(int *numIndices)
 
        memset((char *) indinfo, 0, ntups * sizeof(IndInfo));
 
+       i_indoid = PQfnumber(res, "indoid");
        i_indexrelname = PQfnumber(res, "indexrelname");
        i_indrelname = PQfnumber(res, "indrelname");
        i_indamname = PQfnumber(res, "indamname");
@@ -2093,6 +2124,7 @@ getIndices(int *numIndices)
 
        for (i = 0; i < ntups; i++)
        {
+               indinfo[i].indoid = strdup(PQgetvalue(res, i, i_indoid));
                indinfo[i].indexrelname = strdup(PQgetvalue(res, i, i_indexrelname));
                indinfo[i].indrelname = strdup(PQgetvalue(res, i, i_indrelname));
                indinfo[i].indamname = strdup(PQgetvalue(res, i, i_indamname));
@@ -2109,6 +2141,100 @@ getIndices(int *numIndices)
        return indinfo;
 }
 
+/*------------------------------------------------------------------
+ * dumpComments -- 
+ *
+ * This routine is used to dump any comments associated with the 
+ * oid handed to this routine. The routine takes a constant character
+ * string for the target part of the object and the oid of the object
+ * whose comments are to be dumped. It is perfectly acceptable
+ * to hand an oid to this routine which has not been commented. In
+ * addition, the routine takes the stdio FILE handle to which the 
+ * output should be written.
+ *------------------------------------------------------------------
+*/
+
+void dumpComment(FILE *fout, const char *target, const char *oid) {
+
+       PGresult *res;
+       PQExpBuffer query;
+       int i_description;
+
+       /*** Build query to find comment ***/
+
+       query = createPQExpBuffer();
+       appendPQExpBuffer(query, "SELECT description FROM pg_description WHERE objoid = ");
+       appendPQExpBuffer(query, oid);
+
+       /*** Execute query ***/
+
+       res = PQexec(g_conn, query->data);
+       if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) {
+               fprintf(stderr, "DumpComment: SELECT failed: '%s'.\n",
+                               PQerrorMessage(g_conn));
+               exit_nicely(g_conn);
+       }
+
+       /*** If a comment exists, build COMMENT ON statement ***/
+
+       if (PQntuples(res) != 0) {
+               i_description = PQfnumber(res, "description");
+               fprintf(fout, "COMMENT ON %s IS '%s';\n", 
+                               target, checkForQuote(PQgetvalue(res, 0, i_description)));
+       }
+
+       /*** Clear the statement buffer and return ***/
+
+       PQclear(res);
+    
+}
+
+/*------------------------------------------------------------------
+ * 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.
+ *------------------------------------------------------------------
+*/
+
+void dumpDBComment(FILE *fout) {
+
+       PGresult *res;
+       PQExpBuffer query;
+       int i_oid;
+
+       /*** Build query to find comment ***/
+
+       query = createPQExpBuffer();
+       appendPQExpBuffer(query, "SELECT oid FROM pg_database WHERE datname = '%s'",
+                                         PQdb(g_conn));
+
+       /*** Execute query ***/
+
+       res = PQexec(g_conn, query->data);
+       if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) {
+               fprintf(stderr, "dumpDBComment: SELECT failed: '%s'.\n",
+                               PQerrorMessage(g_conn));
+               exit_nicely(g_conn);
+       }
+
+       /*** If a comment exists, build COMMENT ON statement ***/
+
+       if (PQntuples(res) != 0) {
+               i_oid = PQfnumber(res, "oid");
+               resetPQExpBuffer(query);
+               appendPQExpBuffer(query, "DATABASE %s", fmtId(PQdb(g_conn), force_quotes));
+               dumpComment(fout, query->data, PQgetvalue(res, 0, i_oid));
+       }
+
+       /*** Clear the statement buffer and return ***/
+
+       PQclear(res);
+       
+}
+
 /*
  * dumpTypes
  *       writes out to fout the queries to recreate all the user-defined types
@@ -2188,6 +2314,13 @@ dumpTypes(FILE *fout, FuncInfo *finfo, int numFuncs,
                        appendPQExpBuffer(q, ");\n");
 
                fputs(q->data, fout);
+
+               /*** Dump Type Comments ***/
+
+               resetPQExpBuffer(q);
+               appendPQExpBuffer(q, "TYPE %s", fmtId(tinfo[i].typname, force_quotes));
+               dumpComment(fout, q->data, tinfo[i].oid);
+
        }
 }
 
@@ -2294,6 +2427,7 @@ dumpOneFunc(FILE *fout, FuncInfo *finfo, int i,
                        TypeInfo *tinfo, int numTypes)
 {
        PQExpBuffer     q = createPQExpBuffer();
+       PQExpBuffer fnlist = createPQExpBuffer();
        int                     j;
        char            *func_def;
        char            func_lang[NAMEDATALEN + 1];
@@ -2381,6 +2515,9 @@ dumpOneFunc(FILE *fout, FuncInfo *finfo, int i,
                appendPQExpBuffer(q, "%s%s",
                                (j > 0) ? "," : "",
                                fmtId(typname, false));
+               appendPQExpBuffer(fnlist, "%s%s",
+                                                 (j > 0) ? "," : "",
+                                                 fmtId(typname, false));
        }
        appendPQExpBuffer(q, " ) RETURNS %s%s AS '%s' LANGUAGE '%s';\n",
                        (finfo[i].retset) ? " SETOF " : "",
@@ -2389,6 +2526,14 @@ dumpOneFunc(FILE *fout, FuncInfo *finfo, int i,
 
        fputs(q->data, fout);
 
+       /*** Dump Function Comments ***/
+
+       resetPQExpBuffer(q);
+       appendPQExpBuffer(q, "FUNCTION %s ",
+                                         fmtId(finfo[i].proname, force_quotes));
+       appendPQExpBuffer(q, "( %s )", fnlist->data);
+       dumpComment(fout, q->data, finfo[i].oid);
+
 }
 
 /*
@@ -2602,6 +2747,14 @@ dumpAggs(FILE *fout, AggInfo *agginfo, int numAggs,
                                finalfunc->data);
 
                fputs(q->data, fout);
+
+               /*** Dump Aggregate Comments ***/
+
+               resetPQExpBuffer(q);
+               appendPQExpBuffer(q, "AGGREGATE %s %s", agginfo[i].aggname, 
+                                                 fmtId(findTypeByOid(tinfo, numTypes, agginfo[i].aggbasetype), false));
+               dumpComment(fout, q->data, agginfo[i].oid);
+
        }
 }
 
@@ -2918,6 +3071,22 @@ dumpTables(FILE *fout, TableInfo *tblinfo, int numTables,
                        if (!aclsSkip)
                                dumpACL(fout, tblinfo[i]);
 
+                         /* Dump Field Comments */
+
+                       for (j = 0; j < tblinfo[i].numatts; j++) {                 
+                               resetPQExpBuffer(q);
+                               appendPQExpBuffer(q, "COLUMN %s", fmtId(tblinfo[i].relname, force_quotes));
+                               appendPQExpBuffer(q, ".");
+                               appendPQExpBuffer(q, "%s", fmtId(tblinfo[i].attnames[j], force_quotes));
+                               dumpComment(fout, q->data, tblinfo[i].attoids[j]);
+                       }
+         
+                       /* Dump Table Comments */
+                       
+                       resetPQExpBuffer(q);
+                       appendPQExpBuffer(q, "TABLE %s", fmtId(tblinfo[i].relname, force_quotes));
+                       dumpComment(fout, q->data, tblinfo[i].oid);
+                       
                }
        }
 }
@@ -3086,6 +3255,13 @@ dumpIndices(FILE *fout, IndInfo *indinfo, int numIndices,
                        }
                        else
                                fprintf(fout, " %s );\n", attlist->data);
+
+                       /* Dump Index Comments */
+
+                       resetPQExpBuffer(q);
+                       appendPQExpBuffer(q, "INDEX %s", id1->data);
+                       dumpComment(fout, q->data, indinfo[i].indoid);
+                       
                }
        }
 
@@ -3354,6 +3530,12 @@ dumpSequence(FILE *fout, TableInfo tbinfo)
 
        fputs(query->data, fout);
 
+       /* Dump Sequence Comments */
+
+       resetPQExpBuffer(query);
+       appendPQExpBuffer(query, "SEQUENCE %s", fmtId(tbinfo.relname, force_quotes));
+       dumpComment(fout, query->data, tbinfo.oid);
+
        if (called == 'f')
                return;                                 /* nothing to do more */
 
@@ -3383,6 +3565,7 @@ dumpTriggers(FILE *fout, const char *tablename,
                {
                        becomeUser(fout, tblinfo[i].usename);
                        fputs(tblinfo[i].triggers[j], fout);
+                       dumpComment(fout, tblinfo[i].trcomments[j], tblinfo[i].troids[j]);
                }
        }
 }
@@ -3399,6 +3582,8 @@ dumpRules(FILE *fout, const char *tablename,
        PQExpBuffer     query = createPQExpBuffer();
 
        int                     i_definition;
+       int         i_oid;
+       int         i_rulename;
 
        if (g_verbose)
                fprintf(stderr, "%s dumping out rules %s\n",
@@ -3417,7 +3602,7 @@ dumpRules(FILE *fout, const char *tablename,
                 */
                resetPQExpBuffer(query);
                appendPQExpBuffer(query, "SELECT pg_get_ruledef(pg_rewrite.rulename) "
-                               "AS definition FROM pg_rewrite, pg_class "
+                               "AS definition, pg_rewrite.oid, pg_rewrite.rulename FROM pg_rewrite, pg_class "
                                "WHERE pg_class.relname = '%s' "
                                "AND pg_rewrite.ev_class = pg_class.oid "
                                "ORDER BY pg_rewrite.oid",
@@ -3433,13 +3618,25 @@ dumpRules(FILE *fout, const char *tablename,
 
                nrules = PQntuples(res);
                i_definition = PQfnumber(res, "definition");
+               i_oid = PQfnumber(res, "oid");
+               i_rulename = PQfnumber(res, "rulename");
 
                /*
                 * Dump them out
                 */
-               for (i = 0; i < nrules; i++)
+
+               for (i = 0; i < nrules; i++) {
+                       
                        fprintf(fout, "%s\n", PQgetvalue(res, i, i_definition));
 
+                       /* Dump rule comments */
+
+                       resetPQExpBuffer(query);
+                       appendPQExpBuffer(query, "RULE %s", fmtId(PQgetvalue(res, i, i_rulename), force_quotes));
+                       dumpComment(fout, query->data, PQgetvalue(res, i, i_oid));
+                       
+               }
+
                PQclear(res);
        }
 }
index 80c6e49..5b5e296 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_dump.h,v 1.45 2000/01/16 03:54:58 tgl Exp $
+ * $Id: pg_dump.h,v 1.46 2000/01/18 18:09:02 momjian Exp $
  *
  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  *
@@ -74,6 +74,7 @@ typedef struct _tableInfo
                                                                 * attribute if the value is 1, then this
                                                                 * attribute is an inherited attribute */
        char      **attnames;           /* the attribute names */
+       char      **attoids;        /* oids of the various attributes */
        char      **typnames;           /* fill out attributes */
        bool       *notnull;            /* Not null constraints of an attribute */
        char      **adef_expr;          /* DEFAULT expressions */
@@ -93,6 +94,8 @@ typedef struct _tableInfo
        char      **check_expr;         /* [CONSTRAINT name] CHECK expressions */
        int                     ntrig;                  /* # of triggers */
        char      **triggers;           /* CREATE TRIGGER ... */
+       char      **trcomments;     /* COMMENT ON TRIGGER ... */
+       char      **troids;         /* TRIGGER oids */
     char       *primary_key;    /* PRIMARY KEY of the table, if any */
 } TableInfo;
 
@@ -104,6 +107,7 @@ typedef struct _inhInfo
 
 typedef struct _indInfo
 {
+       char       *indoid;         /* oid of the pg_class entry for the index */
        char       *indexrelname;       /* name of the secondary index class */
        char       *indrelname;         /* name of the indexed heap class */
        char       *indamname;          /* name of the access method (e.g. btree,
@@ -210,6 +214,7 @@ extern TableInfo *getTables(int *numTables, FuncInfo *finfo, int numFuncs);
 extern InhInfo *getInherits(int *numInherits);
 extern void getTableAttrs(TableInfo *tbinfo, int numTables);
 extern IndInfo *getIndices(int *numIndices);
+extern void dumpDBComment(FILE *outfile);
 extern void dumpTypes(FILE *fout, FuncInfo *finfo, int numFuncs,
                  TypeInfo *tinfo, int numTypes);
 extern void dumpProcLangs(FILE *fout, FuncInfo *finfo, int numFuncs,