]> granicus.if.org Git - postgresql/commitdiff
Change pg_dump to produce CREATE INDEX commands by using the backend's
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 1 Oct 2001 21:31:52 +0000 (21:31 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 1 Oct 2001 21:31:52 +0000 (21:31 +0000)
pg_get_indexdef() function, rather than reaching into the system catalogs
for itself.  This eliminates a fair amount of redundant code.  Also,
since I just changed pg_get_indexdef() to suppress display of default
index opclasses, this will mean that 7.2 and later dumps will not mention
opclasses unless they are non-default opclasses.  Should make life easier
for future index opclass reorganizations.

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

index 4f7004392fad63d21bb08cc820eab1f760e0ab2e..f959dd2581fb8f35b9de60d787dad5f499a5f234 100644 (file)
@@ -22,7 +22,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.230 2001/09/21 21:58:30 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.231 2001/10/01 21:31:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1763,22 +1763,14 @@ clearIndInfo(IndInfo *ind, int numIndexes)
                        free(ind[i].indexrelname);
                if (ind[i].indrelname)
                        free(ind[i].indrelname);
-               if (ind[i].indamname)
-                       free(ind[i].indamname);
-               if (ind[i].indproc)
-                       free(ind[i].indproc);
-               if (ind[i].indisunique)
-                       free(ind[i].indisunique);
+               if (ind[i].indexdef)
+                       free(ind[i].indexdef);
                if (ind[i].indisprimary)
                        free(ind[i].indisprimary);
-               if (ind[i].indhaspred)
-                       free(ind[i].indhaspred);
                for (a = 0; a < INDEX_MAX_KEYS; ++a)
                {
                        if (ind[i].indkey[a])
                                free(ind[i].indkey[a]);
-                       if (ind[i].indclass[a])
-                               free(ind[i].indclass[a]);
                }
        }
        free(ind);
@@ -2884,21 +2876,15 @@ getIndexes(int *numIndexes)
        int                     i_indreloid;
        int                     i_indexrelname;
        int                     i_indrelname;
-       int                     i_indamname;
-       int                     i_indproc;
-       int                     i_indkey;
-       int                     i_indclass;
-       int                     i_indisunique;
+       int                     i_indexdef;
        int                     i_indisprimary;
-       int                     i_indhaspred;
+       int                     i_indkey;
 
        /*
         * find all the user-defined indexes.
         *
         * Notice we skip indexes on system classes
         *
-        * this is a 4-way join !!
-        *
         * XXXX: Use LOJ
         */
 
@@ -2906,12 +2892,11 @@ getIndexes(int *numIndexes)
                                          "SELECT i.indexrelid as indexreloid, "
                                          "i.indrelid as indreloid, "
                                          "t1.relname as indexrelname, t2.relname as indrelname, "
-                                         "i.indproc :: oid AS indproc, i.indkey, i.indclass, "
-                                         "a.amname as indamname, i.indisunique, i.indisprimary, "
-                                         "length(i.indpred) > 0 as indhaspred "
-                                         "from pg_index i, pg_class t1, pg_class t2, pg_am a "
+                                         "pg_get_indexdef(i.indexrelid) as indexdef, "
+                                         "i.indisprimary, i.indkey "
+                                         "from pg_index i, pg_class t1, pg_class t2 "
                                          "WHERE t1.oid = i.indexrelid and t2.oid = i.indrelid "
-                                         "and t1.relam = a.oid and i.indexrelid > '%u'::oid "
+                                         "and i.indexrelid > '%u'::oid "
                                          "and t2.relname !~ '^pg_' ",
                                          g_last_builtin_oid);
 
@@ -2938,13 +2923,9 @@ getIndexes(int *numIndexes)
        i_indreloid = PQfnumber(res, "indreloid");
        i_indexrelname = PQfnumber(res, "indexrelname");
        i_indrelname = PQfnumber(res, "indrelname");
-       i_indamname = PQfnumber(res, "indamname");
-       i_indproc = PQfnumber(res, "indproc");
-       i_indkey = PQfnumber(res, "indkey");
-       i_indclass = PQfnumber(res, "indclass");
-       i_indisunique = PQfnumber(res, "indisunique");
+       i_indexdef = PQfnumber(res, "indexdef");
        i_indisprimary = PQfnumber(res, "indisprimary");
-       i_indhaspred = PQfnumber(res, "indhaspred");
+       i_indkey = PQfnumber(res, "indkey");
 
        for (i = 0; i < ntups; i++)
        {
@@ -2952,17 +2933,11 @@ getIndexes(int *numIndexes)
                indinfo[i].indreloid = strdup(PQgetvalue(res, i, i_indreloid));
                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));
-               indinfo[i].indproc = strdup(PQgetvalue(res, i, i_indproc));
+               indinfo[i].indexdef = strdup(PQgetvalue(res, i, i_indexdef));
+               indinfo[i].indisprimary = strdup(PQgetvalue(res, i, i_indisprimary));
                parseNumericArray(PQgetvalue(res, i, i_indkey),
                                                  indinfo[i].indkey,
                                                  INDEX_MAX_KEYS);
-               parseNumericArray(PQgetvalue(res, i, i_indclass),
-                                                 indinfo[i].indclass,
-                                                 INDEX_MAX_KEYS);
-               indinfo[i].indisunique = strdup(PQgetvalue(res, i, i_indisunique));
-               indinfo[i].indisprimary = strdup(PQgetvalue(res, i, i_indisprimary));
-               indinfo[i].indhaspred = strdup(PQgetvalue(res, i, i_indhaspred));
        }
        PQclear(res);
 
@@ -4346,23 +4321,18 @@ void
 dumpIndexes(Archive *fout, IndInfo *indinfo, int numIndexes,
                        TableInfo *tblinfo, int numTables, const char *tablename)
 {
-       int                     i,
-                               k;
+       int                     i;
        int                     tableInd;
-       PQExpBuffer attlist = createPQExpBuffer();
        PQExpBuffer q = createPQExpBuffer();
        PQExpBuffer delq = createPQExpBuffer();
        PQExpBuffer id1 = createPQExpBuffer();
-       PQExpBuffer id2 = createPQExpBuffer();
-       char       *classname[INDEX_MAX_KEYS];
-       char       *funcname;           /* the name of the function to comput the
-                                                                * index key from */
-       Oid                     indclass;
-       int                     nclass;
-       PGresult   *res;
 
        for (i = 0; i < numIndexes; i++)
        {
+               if (tablename && tablename[0] &&
+                       (strcmp(indinfo[i].indrelname, tablename) != 0))
+                       continue;
+
                tableInd = findTableByName(tblinfo, numTables,
                                                                   indinfo[i].indrelname);
                if (tableInd < 0)
@@ -4380,14 +4350,14 @@ dumpIndexes(Archive *fout, IndInfo *indinfo, int numIndexes,
 
                        PQExpBuffer consDef = getPKconstraint(&tblinfo[tableInd], &indinfo[i]);
 
-                       resetPQExpBuffer(attlist);
+                       resetPQExpBuffer(q);
 
-                       appendPQExpBuffer(attlist, "Alter Table %s Add %s;",
+                       appendPQExpBuffer(q, "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, "",
+                                                "CONSTRAINT", NULL, q->data, "",
                                                 "", tblinfo[tableInd].usename, NULL, NULL);
 
                        destroyPQExpBuffer(consDef);
@@ -4400,205 +4370,34 @@ dumpIndexes(Archive *fout, IndInfo *indinfo, int numIndexes,
                        continue;
                }
 
+               resetPQExpBuffer(id1);
+               appendPQExpBuffer(id1, fmtId(indinfo[i].indexrelname, force_quotes));
 
-               if (strcmp(indinfo[i].indproc, "0") == 0)
-                       funcname = NULL;
-               else
-               {
-                       int                     numFuncs;
-
-                       /*
-                        * the indproc is an oid which we use to find the name of the
-                        * pg_proc.  We need to do this because getFuncs() only reads
-                        * in the user-defined funcs not all the funcs.  We might not
-                        * find what we want by looking in FuncInfo*
-                        */
-                       resetPQExpBuffer(q);
-                       appendPQExpBuffer(q,
-                                                         "SELECT proname from pg_proc "
-                                                         "where pg_proc.oid = '%s'::oid",
-                                                         indinfo[i].indproc);
-                       res = PQexec(g_conn, q->data);
-                       if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
-                       {
-                               write_msg(NULL, "query to get function name of oid %s failed: %s",
-                                                 indinfo[i].indproc, PQerrorMessage(g_conn));
-                               exit_nicely();
-                       }
-
-                       /* Sanity: Check we got only one tuple */
-                       numFuncs = PQntuples(res);
-                       if (numFuncs != 1)
-                       {
-                               write_msg(NULL, "query to get function name of oid %s returned %d rows; expected 1\n",
-                                                 indinfo[i].indproc, numFuncs);
-                               exit_nicely();
-                       }
-
-                       funcname = strdup(PQgetvalue(res, 0, PQfnumber(res, "proname")));
-                       PQclear(res);
-               }
-
-               /* convert opclass oid(s) into names */
-               for (nclass = 0; nclass < INDEX_MAX_KEYS; nclass++)
-               {
-                       int                     numRows;
-
-                       indclass = atooid(indinfo[i].indclass[nclass]);
-                       if (indclass == 0)
-                               break;
-                       resetPQExpBuffer(q);
-                       appendPQExpBuffer(q,
-                                                         "SELECT opcname from pg_opclass "
-                                                         "where pg_opclass.oid = '%u'::oid",
-                                                         indclass);
-                       res = PQexec(g_conn, q->data);
-                       if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
-                       {
-                               write_msg(NULL, "query to get operator class name of oid %u failed: %s",
-                                                 indclass, PQerrorMessage(g_conn));
-                               exit_nicely();
-                       }
-
-                       /* Sanity: Check we got only one tuple */
-                       numRows = PQntuples(res);
-                       if (numRows != 1)
-                       {
-                               write_msg(NULL, "query to get operator class name of oid %u returned %d rows; expected 1\n",
-                                                 indclass, numRows);
-                               exit_nicely();
-                       }
-
-                       classname[nclass] = strdup(PQgetvalue(res, 0, PQfnumber(res, "opcname")));
-                       PQclear(res);
-               }
-
-               if (funcname && nclass != 1)
-               {
-                       write_msg(NULL, "There must be exactly one OpClass for functional index \"%s\".\n",
-                                         indinfo[i].indexrelname);
-                       exit_nicely();
-               }
-
-               /* convert attribute numbers into attribute list */
-               resetPQExpBuffer(attlist);
-               for (k = 0; k < INDEX_MAX_KEYS; k++)
-               {
-                       int                     indkey;
-                       const char *attname;
-
-                       indkey = atoi(indinfo[i].indkey[k]);
-                       if (indkey == InvalidAttrNumber)
-                               break;
-                       attname = getAttrName(indkey, &tblinfo[tableInd]);
-                       if (funcname)
-                               appendPQExpBuffer(attlist, "%s%s",
-                                                                 (k == 0) ? "" : ", ",
-                                                                 fmtId(attname, force_quotes));
-                       else
-                       {
-                               if (k >= nclass)
-                               {
-                                       write_msg(NULL, "no operator class found for column \"%s\" of index \"%s\"\n",
-                                                       attname, indinfo[i].indexrelname);
-                                       exit_nicely();
-                               }
-                               resetPQExpBuffer(id1);
-                               resetPQExpBuffer(id2);
-                               appendPQExpBuffer(id1, fmtId(attname, force_quotes));
-                               appendPQExpBuffer(id2, fmtId(classname[k], force_quotes));
-                               appendPQExpBuffer(attlist, "%s%s %s",
-                                                                 (k == 0) ? "" : ", ",
-                                                                 id1->data, id2->data);
-                               free(classname[k]);
-                       }
-               }
-
-               if (!tablename || (strcmp(indinfo[i].indrelname, tablename) == 0) || (strlen(tablename) == 0))
-               {
-                       resetPQExpBuffer(id1);
-                       resetPQExpBuffer(id2);
-                       appendPQExpBuffer(id1, fmtId(indinfo[i].indexrelname, force_quotes));
-                       appendPQExpBuffer(id2, fmtId(indinfo[i].indrelname, force_quotes));
-
-                       resetPQExpBuffer(delq);
-                       appendPQExpBuffer(delq, "DROP INDEX %s;\n", id1->data);
-
-                       resetPQExpBuffer(q);
-                       appendPQExpBuffer(q, "CREATE %s INDEX %s on %s using %s (",
-                         (strcmp(indinfo[i].indisunique, "t") == 0) ? "UNIQUE" : "",
-                                                         id1->data,
-                                                         id2->data,
-                                                         indinfo[i].indamname);
-                       if (funcname)
-                       {
-                               /* need 2 printf's here cuz fmtId has static return area */
-                               appendPQExpBuffer(q, " %s", fmtId(funcname, false));
-                               appendPQExpBuffer(q, " (%s) %s )", attlist->data,
-                                                                 fmtId(classname[0], force_quotes));
-                               free(funcname);
-                               free(classname[0]);
-                       }
-                       else
-                               appendPQExpBuffer(q, " %s )", attlist->data);
-                               
-                       if (strcmp(indinfo[i].indhaspred, "t") == 0)
-                       {
-                               /* There is an index predicate, so fetch and dump it */
-                               int numRows;
-                               PQExpBuffer pred = createPQExpBuffer();
-                               
-                               appendPQExpBuffer(pred, "SELECT pg_get_expr(indpred,indrelid) as pred FROM pg_index WHERE indexrelid = '%s'::oid",
-                                                                 indinfo[i].indexreloid);
-                               res = PQexec(g_conn, pred->data);
-                               if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
-                               {
-                                       fprintf(stderr, "dumpIndices(): SELECT (indpred) failed.  "
-                                                       "Explanation from backend: '%s'.\n",
-                                                       PQerrorMessage(g_conn));
-                                       exit_nicely();
-                               }
-       
-                               /* Sanity: Check we got only one tuple */
-                               numRows = PQntuples(res);
-                               if (numRows != 1)
-                               {
-                                       fprintf(stderr, "dumpIndices(): SELECT (indpred) for index %s returned %d tuples. Expected 1.\n",
-                                                       indinfo[i].indrelname, numRows);
-                                       exit_nicely();
-                               }
-       
-                               appendPQExpBuffer(q, " WHERE %s",
-                                                                 PQgetvalue(res, 0, PQfnumber(res, "pred")));
-
-                               PQclear(res);
-                               destroyPQExpBuffer( pred );
-                       }
-                       appendPQExpBuffer(q, ";\n");
+               resetPQExpBuffer(q);
+               appendPQExpBuffer(q, "%s;\n", indinfo[i].indexdef);
 
-                       /*
-                        * We make the index belong to the owner of its table, which
-                        * is not necessarily right but should answer 99% of the time.
-                        * Would have to add owner name to IndInfo to do it right.
-                        */
-                       ArchiveEntry(fout, indinfo[i].indexreloid, id1->data,
-                                                "INDEX", NULL, q->data, delq->data,
-                                                "", tblinfo[tableInd].usename, NULL, NULL);
+               resetPQExpBuffer(delq);
+               appendPQExpBuffer(delq, "DROP INDEX %s;\n", id1->data);
 
-                       /* Dump Index Comments */
-                       resetPQExpBuffer(q);
-                       appendPQExpBuffer(q, "INDEX %s", id1->data);
-                       dumpComment(fout, q->data, indinfo[i].indexreloid,
-                                               "pg_class", 0, NULL);
+               /*
+                * We make the index belong to the owner of its table, which
+                * is not necessarily right but should answer 99% of the time.
+                * Would have to add owner name to IndInfo to do it right.
+                */
+               ArchiveEntry(fout, indinfo[i].indexreloid, id1->data,
+                                        "INDEX", NULL, q->data, delq->data,
+                                        "", tblinfo[tableInd].usename, NULL, NULL);
 
-               }
+               /* Dump Index Comments */
+               resetPQExpBuffer(q);
+               appendPQExpBuffer(q, "INDEX %s", id1->data);
+               dumpComment(fout, q->data, indinfo[i].indexreloid,
+                                       "pg_class", 0, NULL);
        }
 
-       destroyPQExpBuffer(attlist);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
        destroyPQExpBuffer(id1);
-       destroyPQExpBuffer(id2);
 }
 
 /*
index aff3bc7ea00aaae19cd3a1d6cbc5219c443f95e6..02833d3798578e7782e07d5668b8c2d56887b328 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.70 2001/08/22 20:23:23 petere Exp $
+ * $Id: pg_dump.h,v 1.71 2001/10/01 21:31:52 tgl Exp $
  *
  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  *
@@ -141,16 +141,10 @@ typedef struct _indInfo
        char       *indreloid;          /* oid of the table the index is on */
        char       *indexrelname;       /* name of the index itself */
        char       *indrelname;         /* name of the indexed table */
-       char       *indamname;          /* name of the access method (e.g. btree,
-                                                                * rtree, etc.) */
-       char       *indproc;            /* oid of the function to compute the
-                                                                * index, 0 if none */
+       char       *indexdef;           /* index definitional command */
+       char       *indisprimary;       /* is this a PK index? */
        char       *indkey[INDEX_MAX_KEYS]; /* attribute numbers of the key
                                                                                 * attributes */
-       char       *indclass[INDEX_MAX_KEYS];           /* opclass of the keys */
-       char       *indisunique;        /* is this index unique? */
-       char       *indisprimary;       /* is this a PK index? */
-       char       *indhaspred;         /* does this index have a predicate? */
 } IndInfo;
 
 typedef struct _aggInfo