OSDN Git Service

Fixed handling of renamed columns in PK constraints
authorPhilip Warner <pjw@rhyme.com.au>
Fri, 12 Jan 2001 15:41:29 +0000 (15:41 +0000)
committerPhilip Warner <pjw@rhyme.com.au>
Fri, 12 Jan 2001 15:41:29 +0000 (15:41 +0000)
src/bin/pg_dump/common.c
src/bin/pg_dump/pg_backup_archiver.h
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h

index 4711a76..a466daf 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.48 2000/12/03 20:45:37 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.49 2001/01/12 15:41:29 pjw Exp $
  *
  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  *
@@ -270,12 +270,14 @@ dumpSchema(Archive  *fout,
        int                     numInherits;
        int                     numAggregates;
        int                     numOperators;
+       int                     numIndices;
        TypeInfo   *tinfo = NULL;
        FuncInfo   *finfo = NULL;
        AggInfo    *agginfo = NULL;
        TableInfo  *tblinfo = NULL;
        InhInfo    *inhinfo = NULL;
        OprInfo    *oprinfo = NULL;
+       IndInfo    *indinfo = NULL;
 
        if (g_verbose)
                fprintf(stderr, "%s reading user-defined types %s\n",
@@ -303,6 +305,11 @@ dumpSchema(Archive  *fout,
        tblinfo = getTables(&numTables, finfo, numFuncs);
 
        if (g_verbose)
+               fprintf(stderr, "%s reading indices information %s\n",
+                               g_comment_start, g_comment_end);
+       indinfo = getIndices(&numIndices);
+
+       if (g_verbose)
                fprintf(stderr, "%s reading table inheritance information %s\n",
                                g_comment_start, g_comment_end);
        inhinfo = getInherits(&numInherits);
@@ -336,9 +343,18 @@ dumpSchema(Archive  *fout,
        if (g_verbose)
                fprintf(stderr, "%s dumping out tables %s\n",
                                g_comment_start, g_comment_end);
-       dumpTables(fout, tblinfo, numTables, inhinfo, numInherits,
+
+       dumpTables(fout, tblinfo, numTables, indinfo, numIndices, inhinfo, numInherits,
                           tinfo, numTypes, tablename, aclsSkip, oids, schemaOnly, dataOnly);
 
+       if (fout && !dataOnly)
+       {
+               if (g_verbose)
+                       fprintf(stderr, "%s dumping out indices %s\n",
+                                       g_comment_start, g_comment_end);
+               dumpIndices(fout, indinfo, numIndices, tblinfo, numTables, tablename);
+       }
+
        if (!tablename && !dataOnly)
        {
                if (g_verbose)
@@ -377,35 +393,8 @@ dumpSchema(Archive  *fout,
        clearTypeInfo(tinfo, numTypes);
        clearFuncInfo(finfo, numFuncs);
        clearInhInfo(inhinfo, numInherits);
-       return tblinfo;
-}
-
-/*
- * dumpSchemaIdx:
- *       dump indexes at the end for performance
- *
- */
-
-extern void
-dumpSchemaIdx(Archive *fout, const char *tablename,
-                         TableInfo *tblinfo, int numTables)
-{
-       int                     numIndices;
-       IndInfo    *indinfo;
-
-       if (g_verbose)
-               fprintf(stderr, "%s reading indices information %s\n",
-                               g_comment_start, g_comment_end);
-       indinfo = getIndices(&numIndices);
-
-       if (fout)
-       {
-               if (g_verbose)
-                       fprintf(stderr, "%s dumping out indices %s\n",
-                                       g_comment_start, g_comment_end);
-               dumpIndices(fout, indinfo, numIndices, tblinfo, numTables, tablename);
-       }
        clearIndInfo(indinfo, numIndices);
+       return tblinfo;
 }
 
 /* flagInhAttrs -
index 9a9c2e7..0808af3 100644 (file)
@@ -62,7 +62,7 @@ typedef z_stream *z_streamp;
 
 #define K_VERS_MAJOR 1
 #define K_VERS_MINOR 4 
-#define K_VERS_REV 23 
+#define K_VERS_REV 24 
 
 /* Data block types */
 #define BLK_DATA 1
index ba10354..a383ec7 100644 (file)
@@ -22,7 +22,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.186 2001/01/12 04:32:07 pjw Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.187 2001/01/12 15:41:29 pjw Exp $
  *
  * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
  *
@@ -155,6 +155,7 @@ static char *GetPrivileges(const char *s);
 
 static int dumpBlobs(Archive *AH, char*, void*);
 static int dumpDatabase(Archive *AH);
+static PQExpBuffer getPKconstraint(TableInfo *tblInfo, IndInfo *indInfo);
 
 extern char *optarg;
 extern int     optind,
@@ -1027,7 +1028,6 @@ main(int argc, char **argv)
        if (!dataOnly)                          /* dump indexes and triggers at the end
                                                                 * for performance */
        {
-               dumpSchemaIdx(g_fout, tablename, tblinfo, numTables);
                dumpTriggers(g_fout, tablename, tblinfo, numTables);
                dumpRules(g_fout, tablename, tblinfo, numTables);
        }
@@ -1038,6 +1038,7 @@ main(int argc, char **argv)
        MoveToEnd(g_fout, "TABLE DATA");
        MoveToEnd(g_fout, "BLOBS");
        MoveToEnd(g_fout, "INDEX");
+       MoveToEnd(g_fout, "CONSTRAINT");
        MoveToEnd(g_fout, "TRIGGER");
        MoveToEnd(g_fout, "RULE");
        MoveToEnd(g_fout, "SEQUENCE SET");
@@ -1568,8 +1569,6 @@ clearTableInfo(TableInfo *tblinfo, int numTables)
                        free(tblinfo[i].typnames);
                if (tblinfo[i].notnull)
                        free(tblinfo[i].notnull);
-               if (tblinfo[i].primary_key)
-                       free(tblinfo[i].primary_key);
                if (tblinfo[i].primary_key_name)
                        free(tblinfo[i].primary_key_name);
        }
@@ -1656,6 +1655,8 @@ clearIndInfo(IndInfo *ind, int numIndices)
                        free(ind[i].indproc);
                if (ind[i].indisunique)
                        free(ind[i].indisunique);
+               if (ind[i].indisprimary)
+                       free(ind[i].indisprimary);
                for (a = 0; a < INDEX_MAX_KEYS; ++a)
                {
                        if (ind[i].indkey[a])
@@ -2132,50 +2133,36 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
                if (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0)
                {
                        PGresult   *res2;
-                       char            str[INDEX_MAX_KEYS * (NAMEDATALEN * 2 + 4) + 1];
-                       int                     j;
 
                        resetPQExpBuffer(query);
                        appendPQExpBuffer(query,
-                                                         "SELECT a.attname "
-                                                  "FROM pg_index i, pg_class c, pg_attribute a "
-                                                         "WHERE i.indisprimary AND i.indrelid = %s "
-                                                         "  AND i.indexrelid = c.oid AND a.attnum > 0 AND a.attrelid = c.oid "
-                                                         "ORDER BY a.attnum ",
+                                                         "SELECT Oid FROM pg_index i WHERE i.indisprimary AND i.indrelid = %s ",
                                                          tblinfo[i].oid);
                        res2 = PQexec(g_conn, query->data);
                        if (!res2 || PQresultStatus(res2) != PGRES_TUPLES_OK)
                        {
-                               fprintf(stderr, "getTables(): SELECT (for PRIMARY KEY) failed.  Explanation from backend: %s",
+                               fprintf(stderr, "getTables(): SELECT (for PRIMARY KEY) failed.  Explanation from backend: %s\n",
                                                PQerrorMessage(g_conn));
                                exit_nicely(g_conn);
                        }
 
-                       str[0] = '\0';
-                       for (j = 0; j < PQntuples(res2); j++)
-                       {
-                               if (strlen(str) > 0)
-                                       strcat(str, ", ");
-                               strcat(str, fmtId(PQgetvalue(res2, j, 0), force_quotes));
+                       if (PQntuples(res2) > 1) {
+                               fprintf(stderr, "getTables(): SELECT (for PRIMARY KEY) produced more than one row.\n");
+                               exit_nicely(g_conn);
                        }
 
-                       if (strlen(str) > 0)
-                       {
-                               tblinfo[i].primary_key = strdup(str);
-                               if (tblinfo[i].primary_key == NULL)
-                               {
-                                       perror("strdup");
-                                       exit(1);
-                               }
+                       if (PQntuples(res2) == 1) {
+                               tblinfo[i].pkIndexOid = strdup(PQgetvalue(res2, 0, 0));
+                       } else {
+                               tblinfo[i].pkIndexOid = NULL;
                        }
-                       else
-                               tblinfo[i].primary_key = NULL;
+
                }
                else
-                       tblinfo[i].primary_key = NULL;
+                       tblinfo[i].pkIndexOid = NULL;
 
                /* Get primary key name (if primary key exist) */
-               if (tblinfo[i].primary_key)
+               if (tblinfo[i].pkIndexOid != NULL)
                {
                        PGresult   *res2;
                        int                n;
@@ -2695,6 +2682,8 @@ getIndices(int *numIndices)
        int                     i_indclass;
        int                     i_indisunique;
        int                     i_indoid;
+       int                     i_oid;
+       int                     i_indisprimary;
 
        /*
         * find all the user-defined indices. We do not handle partial
@@ -2706,13 +2695,13 @@ getIndices(int *numIndices)
         */
 
        appendPQExpBuffer(query,
-                                         "SELECT t1.oid as indoid, t1.relname as indexrelname, t2.relname as indrelname, "
+                                         "SELECT i.oid, t1.oid as indoid, t1.relname as indexrelname, t2.relname as indrelname, "
                                          "i.indproc, i.indkey, i.indclass, "
-                                         "a.amname as indamname, i.indisunique "
+                                         "a.amname as indamname, i.indisunique, i.indisprimary "
                                        "from pg_index i, pg_class t1, pg_class t2, pg_am a "
                                   "WHERE t1.oid = i.indexrelid and t2.oid = i.indrelid "
                                          "and t1.relam = a.oid and i.indexrelid > '%u'::oid "
-                                         "and t2.relname !~ '^pg_' and not i.indisprimary",
+                                         "and t2.relname !~ '^pg_' ",
                                          g_last_builtin_oid);
 
        res = PQexec(g_conn, query->data);
@@ -2732,6 +2721,7 @@ getIndices(int *numIndices)
 
        memset((char *) indinfo, 0, ntups * sizeof(IndInfo));
 
+       i_oid = PQfnumber(res, "oid");
        i_indoid = PQfnumber(res, "indoid");
        i_indexrelname = PQfnumber(res, "indexrelname");
        i_indrelname = PQfnumber(res, "indrelname");
@@ -2740,9 +2730,11 @@ getIndices(int *numIndices)
        i_indkey = PQfnumber(res, "indkey");
        i_indclass = PQfnumber(res, "indclass");
        i_indisunique = PQfnumber(res, "indisunique");
+       i_indisprimary = PQfnumber(res, "indisprimary");
 
        for (i = 0; i < ntups; i++)
        {
+               indinfo[i].oid = strdup(PQgetvalue(res, i, i_oid));
                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));
@@ -2755,6 +2747,7 @@ getIndices(int *numIndices)
                                                  indinfo[i].indclass,
                                                  INDEX_MAX_KEYS);
                indinfo[i].indisunique = strdup(PQgetvalue(res, i, i_indisunique));
+               indinfo[i].indisprimary = strdup(PQgetvalue(res, i, i_indisprimary));
        }
        PQclear(res);
        return indinfo;
@@ -3551,6 +3544,7 @@ dumpACL(Archive *fout, TableInfo tbinfo)
 
 void
 dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
+                  IndInfo *indinfo, int numIndices,
                   InhInfo *inhinfo, int numInherits,
                   TypeInfo *tinfo, int numTypes, const char *tablename,
                   const bool aclsSkip, const bool oids,
@@ -3651,6 +3645,8 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
                                        }
                                }
 
+
+
                                /* put the CONSTRAINTS inside the table def */
                                for (k = 0; k < tblinfo[i].ncheck; k++)
                                {
@@ -3661,17 +3657,36 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
                                                                  tblinfo[i].check_expr[k]);
                                }
 
-                               /* PRIMARY KEY */
-                               if (tblinfo[i].primary_key)
+                               /* Primary Key */
+                               if (tblinfo[i].pkIndexOid != NULL)
                                {
-                                       if (actual_atts + tblinfo[i].ncheck > 0)
+                                       PQExpBuffer     consDef;
+
+                                       /* Find the corresponding index */
+                                       for (k = 0; k < numIndices; k++)
+                                       {
+                                               if (strcmp(indinfo[k].oid, tblinfo[i].pkIndexOid) == 0) 
+                                                       break;
+                                       }
+
+                                       if (k >= numIndices)
+                                       {
+                                               fprintf(stderr, "dumpTables(): failed sanity check, could not find index (%s) for PK constraint\n",
+                                                                       tblinfo[i].pkIndexOid);
+                                               exit_nicely(g_conn);
+                                       }
+
+                                       consDef = getPKconstraint(&tblinfo[i], &indinfo[k]);
+
+                                       if ( (actual_atts + tblinfo[i].ncheck) > 0)
                                                appendPQExpBuffer(q, ",\n\t");
-                                       appendPQExpBuffer(q,
-                                                                         "CONSTRAINT %s PRIMARY KEY (%s)",
-                                                                         tblinfo[i].primary_key_name,
-                                                                         tblinfo[i].primary_key);
+
+                                       appendPQExpBuffer(q, "%s", consDef->data);
+
+                                       destroyPQExpBuffer(consDef);
                                }
 
+
                                appendPQExpBuffer(q, "\n)");
 
                                if (numParents > 0)
@@ -3690,13 +3705,15 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
                        }
 
                        if (!dataOnly) {
-                                       ArchiveEntry(fout, tblinfo[i].oid, fmtId(tblinfo[i].relname, false),
+
+                               ArchiveEntry(fout, tblinfo[i].oid, fmtId(tblinfo[i].relname, false),
                                                                reltypename, NULL, q->data, delq->data, "", tblinfo[i].usename,
                                                                NULL, NULL);
-                       }
 
-                       if (!dataOnly && !aclsSkip)
-                               dumpACL(fout, tblinfo[i]);
+                               if (!aclsSkip)
+                                       dumpACL(fout, tblinfo[i]);
+
+                       }
 
                        /* Dump Field Comments */
 
@@ -3719,6 +3736,41 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
        }
 }
 
+static PQExpBuffer getPKconstraint(TableInfo *tblInfo, IndInfo *indInfo)
+{
+       PQExpBuffer     pkBuf = createPQExpBuffer();
+       int                             k;
+       int                             indkey;
+
+       resetPQExpBuffer(pkBuf);
+
+       appendPQExpBuffer(pkBuf, "Constraint %s Primary Key (",
+                                               tblInfo->primary_key_name);
+
+
+       for (k = 0; k < INDEX_MAX_KEYS; k++)
+       {
+               char       *attname;
+
+               indkey = atoi(indInfo->indkey[k]);
+               if (indkey == InvalidAttrNumber)
+                       break;
+               indkey--;
+               if (indkey == ObjectIdAttributeNumber - 1)
+                       attname = "oid";
+               else
+                       attname = tblInfo->attnames[indkey];
+
+               appendPQExpBuffer(pkBuf, "%s%s",
+                                                       (k == 0) ? "" : ", ", 
+                                                       fmtId(attname, force_quotes));
+       }
+
+       appendPQExpBuffer(pkBuf, ")");
+
+       return pkBuf;
+}
+
 /*
  * dumpIndices:
  *       write out to fout all the user-define indices
@@ -3755,6 +3807,31 @@ dumpIndices(Archive *fout, IndInfo *indinfo, int numIndices,
                        exit(1);
                }
 
+               /* Handle PK indexes */
+               if (strcmp(indinfo[i].indisprimary, "t") == 0)
+               {
+/*
+ *                     ***PK: Enable this code when ALTER TABLE supports PK constraints. ***
+ *
+ *                     PQExpBuffer     consDef = getPKconstraint(&tblinfo[tableInd], &indinfo[i]);
+ *
+ *                     resetPQExpBuffer(attlist);
+ *
+ *                     appendPQExpBuffer(attlist, "Alter Table %s Add %s;", 
+ *                                                             fmtId(tblinfo[tableInd].relname, force_quotes),
+ *                                                             consDef->data);
+ *
+ *                     ArchiveEntry(fout, indinfo[i].oid, tblinfo[tableInd].primary_key_name, "CONSTRAINT", NULL, 
+ *                                                     attlist->data, "",
+ *                                                     "", tblinfo[tableInd].usename, NULL, NULL);
+ *
+ *                     destroyPQExpBuffer(consDef);
+ */
+                       /* Don't need to do anything else for this system-generated index */
+                       continue;
+               }
+
+
                if (strcmp(indinfo[i].indproc, "0") == 0)
                        funcname = NULL;
                else
index 1871ed3..c734cf2 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_dump.h,v 1.55 2000/11/27 20:51:40 momjian Exp $
+ * $Id: pg_dump.h,v 1.56 2001/01/12 15:41:29 pjw Exp $
  *
  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  *
@@ -116,7 +116,7 @@ typedef struct _tableInfo
        char      **check_expr;         /* [CONSTRAINT name] CHECK expressions */
        int                     ntrig;                  /* # of triggers */
        TrigInfo        *triggers;              /* Triggers on the table */
-       char       *primary_key;        /* PRIMARY KEY of the table, if any */
+       char       *pkIndexOid;         /* Primary Key index OID */
        char       *primary_key_name;   /* PRIMARY KEY name, if any */
 } TableInfo;
 
@@ -128,6 +128,7 @@ typedef struct _inhInfo
 
 typedef struct _indInfo
 {
+       char       *oid;                        /* Oid of the pg_index entry */
        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 */
@@ -139,6 +140,7 @@ typedef struct _indInfo
                                                                                 * attributes */
        char       *indclass[INDEX_MAX_KEYS];           /* opclass of the keys */
        char       *indisunique;        /* is this index unique? */
+       char       *indisprimary;       /* is this a PK index? */
 } IndInfo;
 
 typedef struct _aggInfo
@@ -253,6 +255,7 @@ extern void dumpAggs(Archive *fout, AggInfo *agginfo, int numAggregates,
 extern void dumpOprs(Archive *fout, OprInfo *agginfo, int numOperators,
                 TypeInfo *tinfo, int numTypes);
 extern void dumpTables(Archive *fout, TableInfo *tbinfo, int numTables,
+                  IndInfo *indinfo, int numIndices,
                   InhInfo *inhinfo, int numInherits,
                   TypeInfo *tinfo, int numTypes, const char *tablename,
                   const bool acls, const bool oids,