From a65dd5290e693fbb11593ebcfd15ac497dd27d31 Mon Sep 17 00:00:00 2001 From: "Vadim B. Mikheev" <vadim4o@yahoo.com> Date: Tue, 6 May 1997 05:20:21 +0000 Subject: [PATCH] 1. Multi-column indices support. 2. Fix for function indices with more than 1 attrs. --- src/bin/pg_dump/pg_dump.c | 117 +++++++++++++++++++++++++++++--------- src/bin/pg_dump/pg_dump.h | 6 +- 2 files changed, 94 insertions(+), 29 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 1fb22d008e9..17e21a678aa 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -21,7 +21,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.27 1997/04/12 09:24:07 scrappy Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.28 1997/05/06 05:20:18 vadim Exp $ * * Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb * @@ -55,6 +55,7 @@ #include "postgres.h" #include "access/htup.h" #include "catalog/pg_type.h" +#include "catalog/pg_index.h" #include "libpq-fe.h" #ifndef HAVE_STRDUP #include "strdup.h" @@ -1142,16 +1143,16 @@ getIndices(int *numIndices) int i_indamname; int i_indproc; int i_indkey; - int i_indclassname; + int i_indclass; int i_indisunique; - /* find all the user-defined indices. + /* + find all the user-defined indices. We do not handle partial indices. - We also assume that only single key indices skip 'Xinx*' - indices on inversion objects - this is a 5-way join !! + this is a 4-way join !! */ res = PQexec(g_conn, "begin"); @@ -1164,13 +1165,12 @@ getIndices(int *numIndices) sprintf(query, "SELECT t1.relname as indexrelname, t2.relname as indrelname, " - "i.indproc, i.indkey[0], o.opcname as indclassname, " - "a.amname as indamname, i.indisunique from pg_index i, pg_class t1, " - "pg_class t2, pg_opclass o, pg_am a " + "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 " "where t1.oid = i.indexrelid and t2.oid = i.indrelid " - "and o.oid = i.indclass[0] and t1.relam = a.oid and " - "i.indexrelid > '%d'::oid and t2.relname !~ '^pg_' " - "and t1.relname !~ '^Xinx' ;", + "and t1.relam = a.oid and i.indexrelid > '%d'::oid " + "and t2.relname !~ '^pg_' and t1.relname !~ '^Xinx' ;", g_last_builtin_oid); res = PQexec(g_conn, query); @@ -1191,7 +1191,7 @@ getIndices(int *numIndices) i_indamname = PQfnumber(res,"indamname"); i_indproc = PQfnumber(res,"indproc"); i_indkey = PQfnumber(res,"indkey"); - i_indclassname = PQfnumber(res,"indclassname"); + i_indclass = PQfnumber(res,"indclass"); i_indisunique = PQfnumber(res,"indisunique"); for (i=0;i<ntups;i++) { @@ -1199,8 +1199,10 @@ getIndices(int *numIndices) 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].indkey = strdup(PQgetvalue(res,i,i_indkey)); - indinfo[i].indclassname = strdup(PQgetvalue(res,i,i_indclassname)); + parseArgTypes ((char **)indinfo[i].indkey, + (const char*)PQgetvalue(res,i,i_indkey)); + parseArgTypes ((char **)indinfo[i].indclass, + (const char*)PQgetvalue(res,i,i_indclass)); indinfo[i].indisunique = strdup(PQgetvalue(res,i,i_indisunique)); } PQclear(res); @@ -1634,11 +1636,13 @@ void dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices, TableInfo* tblinfo, int numTables, const char *tablename) { - int i; + int i, k; int tableInd; - const char *attname; /* the name of the indexed attribute */ + char attlist[1000]; + char *classname[INDEX_MAX_KEYS]; char *funcname; /* the name of the function to comput the index key from*/ - int indkey; + int indkey, indclass; + int nclass; char q[MAXQUERYLEN]; PGresult *res; @@ -1646,11 +1650,7 @@ dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices, for (i=0;i<numIndices;i++) { tableInd = findTableByName(tblinfo, numTables, indinfo[i].indrelname); - indkey = atoi(indinfo[i].indkey) - 1; - if (indkey == ObjectIdAttributeNumber - 1) - attname = "oid"; - else - attname = tblinfo[tableInd].attnames[indkey]; + if (strcmp(indinfo[i].indproc,"0") == 0) { funcname = NULL; } else { @@ -1664,10 +1664,74 @@ dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices, "where pg_proc.oid = '%s'::oid", indinfo[i].indproc); res = PQexec(g_conn, q); + if ( !res || PQresultStatus(res) != PGRES_TUPLES_OK ) + { + fprintf(stderr,"dumpIndices(): SELECT (funcname) failed\n"); + exit_nicely(g_conn); + } funcname = strdup(PQgetvalue(res, 0, PQfnumber(res,"proname"))); PQclear(res); } + + /* convert opclass oid(s) into names */ + for (nclass = 0; nclass < INDEX_MAX_KEYS; nclass++) + { + indclass = atoi(indinfo[i].indclass[nclass]); + if ( indclass == 0 ) + break; + sprintf(q, + "SELECT opcname from pg_opclass " + "where pg_opclass.oid = '%u'::oid", + indclass); + res = PQexec(g_conn, q); + if ( !res || PQresultStatus(res) != PGRES_TUPLES_OK ) + { + fprintf(stderr,"dumpIndices(): SELECT (classname) failed\n"); + exit_nicely(g_conn); + } + classname[nclass] = strdup(PQgetvalue(res, 0, + PQfnumber(res,"opcname"))); + PQclear(res); + } + + if ( funcname && nclass != 1 ) + { + fprintf(stderr,"dumpIndices(): Must be exactly one OpClass " + "for functional index %s\n", indinfo[i].indexrelname); + exit_nicely(g_conn); + } + + /* convert attribute numbers into attribute list */ + for (k = 0, attlist[0] = 0; k < INDEX_MAX_KEYS; k++) + { + char * attname; + + indkey = atoi(indinfo[i].indkey[k]); + if ( indkey == 0 ) + break; + indkey--; + if (indkey == ObjectIdAttributeNumber - 1) + attname = "oid"; + else + attname = tblinfo[tableInd].attnames[indkey]; + if ( funcname ) + sprintf (attlist + strlen(attlist), "%s%s", + ( k == 0 ) ? "" : ", ", attname); + else + { + if ( k >= nclass ) + { + fprintf(stderr,"dumpIndices(): OpClass not found for " + "attribute %s of index %s\n", + attname, indinfo[i].indexrelname); + exit_nicely(g_conn); + } + sprintf (attlist + strlen(attlist), "%s%s %s", + ( k == 0 ) ? "" : ", ", attname, classname[k]); + free (classname[k]); + } + } if (!tablename || (!strcmp(indinfo[i].indrelname,tablename))) { @@ -1677,12 +1741,13 @@ dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices, indinfo[i].indrelname, indinfo[i].indamname); if (funcname) { - sprintf(q, "%s %s(%s) %s);\n", - q,funcname, attname, indinfo[i].indclassname); + sprintf(q, "%s %s (%s) %s );\n", + q, funcname, attlist, classname[0]); free(funcname); + free(classname[0]); } else - sprintf(q, "%s %s %s);\n", - q,attname,indinfo[i].indclassname); + sprintf(q, "%s %s );\n", + q, attlist); fputs(q,fout); } diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 988dbd0e196..1dbc95562a6 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: pg_dump.h,v 1.12 1997/04/12 09:24:14 scrappy Exp $ + * $Id: pg_dump.h,v 1.13 1997/05/06 05:20:21 vadim Exp $ * * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2 * @@ -87,8 +87,8 @@ typedef struct _indInfo { char *indrelname; /* name of the indexed heap class */ 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 *indkey; /* attribute number of the key attribute */ - char *indclassname; /* name of the opclass of the key */ + 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? */ } IndInfo; -- GitLab