Skip to content

Commit a65dd52

Browse files
committed
1. Multi-column indices support.
2. Fix for function indices with more than 1 attrs.
1 parent 13f41aa commit a65dd52

File tree

2 files changed

+94
-29
lines changed

2 files changed

+94
-29
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 91 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
*
2222
*
2323
* IDENTIFICATION
24-
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.27 1997/04/12 09:24:07 scrappy Exp $
24+
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.28 1997/05/06 05:20:18 vadim Exp $
2525
*
2626
* Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
2727
*
@@ -55,6 +55,7 @@
5555
#include "postgres.h"
5656
#include "access/htup.h"
5757
#include "catalog/pg_type.h"
58+
#include "catalog/pg_index.h"
5859
#include "libpq-fe.h"
5960
#ifndef HAVE_STRDUP
6061
#include "strdup.h"
@@ -1142,16 +1143,16 @@ getIndices(int *numIndices)
11421143
int i_indamname;
11431144
int i_indproc;
11441145
int i_indkey;
1145-
int i_indclassname;
1146+
int i_indclass;
11461147
int i_indisunique;
11471148

1148-
/* find all the user-defined indices.
1149+
/*
1150+
find all the user-defined indices.
11491151
We do not handle partial indices.
1150-
We also assume that only single key indices
11511152
11521153
skip 'Xinx*' - indices on inversion objects
11531154
1154-
this is a 5-way join !!
1155+
this is a 4-way join !!
11551156
*/
11561157

11571158
res = PQexec(g_conn, "begin");
@@ -1164,13 +1165,12 @@ getIndices(int *numIndices)
11641165

11651166
sprintf(query,
11661167
"SELECT t1.relname as indexrelname, t2.relname as indrelname, "
1167-
"i.indproc, i.indkey[0], o.opcname as indclassname, "
1168-
"a.amname as indamname, i.indisunique from pg_index i, pg_class t1, "
1169-
"pg_class t2, pg_opclass o, pg_am a "
1168+
"i.indproc, i.indkey, i.indclass, "
1169+
"a.amname as indamname, i.indisunique "
1170+
"from pg_index i, pg_class t1, pg_class t2, pg_am a "
11701171
"where t1.oid = i.indexrelid and t2.oid = i.indrelid "
1171-
"and o.oid = i.indclass[0] and t1.relam = a.oid and "
1172-
"i.indexrelid > '%d'::oid and t2.relname !~ '^pg_' "
1173-
"and t1.relname !~ '^Xinx' ;",
1172+
"and t1.relam = a.oid and i.indexrelid > '%d'::oid "
1173+
"and t2.relname !~ '^pg_' and t1.relname !~ '^Xinx' ;",
11741174
g_last_builtin_oid);
11751175

11761176
res = PQexec(g_conn, query);
@@ -1191,16 +1191,18 @@ getIndices(int *numIndices)
11911191
i_indamname = PQfnumber(res,"indamname");
11921192
i_indproc = PQfnumber(res,"indproc");
11931193
i_indkey = PQfnumber(res,"indkey");
1194-
i_indclassname = PQfnumber(res,"indclassname");
1194+
i_indclass = PQfnumber(res,"indclass");
11951195
i_indisunique = PQfnumber(res,"indisunique");
11961196

11971197
for (i=0;i<ntups;i++) {
11981198
indinfo[i].indexrelname = strdup(PQgetvalue(res,i,i_indexrelname));
11991199
indinfo[i].indrelname = strdup(PQgetvalue(res,i,i_indrelname));
12001200
indinfo[i].indamname = strdup(PQgetvalue(res,i,i_indamname));
12011201
indinfo[i].indproc = strdup(PQgetvalue(res,i,i_indproc));
1202-
indinfo[i].indkey = strdup(PQgetvalue(res,i,i_indkey));
1203-
indinfo[i].indclassname = strdup(PQgetvalue(res,i,i_indclassname));
1202+
parseArgTypes ((char **)indinfo[i].indkey,
1203+
(const char*)PQgetvalue(res,i,i_indkey));
1204+
parseArgTypes ((char **)indinfo[i].indclass,
1205+
(const char*)PQgetvalue(res,i,i_indclass));
12041206
indinfo[i].indisunique = strdup(PQgetvalue(res,i,i_indisunique));
12051207
}
12061208
PQclear(res);
@@ -1634,23 +1636,21 @@ void
16341636
dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices,
16351637
TableInfo* tblinfo, int numTables, const char *tablename)
16361638
{
1637-
int i;
1639+
int i, k;
16381640
int tableInd;
1639-
const char *attname; /* the name of the indexed attribute */
1641+
char attlist[1000];
1642+
char *classname[INDEX_MAX_KEYS];
16401643
char *funcname; /* the name of the function to comput the index key from*/
1641-
int indkey;
1644+
int indkey, indclass;
1645+
int nclass;
16421646

16431647
char q[MAXQUERYLEN];
16441648
PGresult *res;
16451649

16461650
for (i=0;i<numIndices;i++) {
16471651
tableInd = findTableByName(tblinfo, numTables,
16481652
indinfo[i].indrelname);
1649-
indkey = atoi(indinfo[i].indkey) - 1;
1650-
if (indkey == ObjectIdAttributeNumber - 1)
1651-
attname = "oid";
1652-
else
1653-
attname = tblinfo[tableInd].attnames[indkey];
1653+
16541654
if (strcmp(indinfo[i].indproc,"0") == 0) {
16551655
funcname = NULL;
16561656
} else {
@@ -1664,10 +1664,74 @@ dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices,
16641664
"where pg_proc.oid = '%s'::oid",
16651665
indinfo[i].indproc);
16661666
res = PQexec(g_conn, q);
1667+
if ( !res || PQresultStatus(res) != PGRES_TUPLES_OK )
1668+
{
1669+
fprintf(stderr,"dumpIndices(): SELECT (funcname) failed\n");
1670+
exit_nicely(g_conn);
1671+
}
16671672
funcname = strdup(PQgetvalue(res, 0,
16681673
PQfnumber(res,"proname")));
16691674
PQclear(res);
16701675
}
1676+
1677+
/* convert opclass oid(s) into names */
1678+
for (nclass = 0; nclass < INDEX_MAX_KEYS; nclass++)
1679+
{
1680+
indclass = atoi(indinfo[i].indclass[nclass]);
1681+
if ( indclass == 0 )
1682+
break;
1683+
sprintf(q,
1684+
"SELECT opcname from pg_opclass "
1685+
"where pg_opclass.oid = '%u'::oid",
1686+
indclass);
1687+
res = PQexec(g_conn, q);
1688+
if ( !res || PQresultStatus(res) != PGRES_TUPLES_OK )
1689+
{
1690+
fprintf(stderr,"dumpIndices(): SELECT (classname) failed\n");
1691+
exit_nicely(g_conn);
1692+
}
1693+
classname[nclass] = strdup(PQgetvalue(res, 0,
1694+
PQfnumber(res,"opcname")));
1695+
PQclear(res);
1696+
}
1697+
1698+
if ( funcname && nclass != 1 )
1699+
{
1700+
fprintf(stderr,"dumpIndices(): Must be exactly one OpClass "
1701+
"for functional index %s\n", indinfo[i].indexrelname);
1702+
exit_nicely(g_conn);
1703+
}
1704+
1705+
/* convert attribute numbers into attribute list */
1706+
for (k = 0, attlist[0] = 0; k < INDEX_MAX_KEYS; k++)
1707+
{
1708+
char * attname;
1709+
1710+
indkey = atoi(indinfo[i].indkey[k]);
1711+
if ( indkey == 0 )
1712+
break;
1713+
indkey--;
1714+
if (indkey == ObjectIdAttributeNumber - 1)
1715+
attname = "oid";
1716+
else
1717+
attname = tblinfo[tableInd].attnames[indkey];
1718+
if ( funcname )
1719+
sprintf (attlist + strlen(attlist), "%s%s",
1720+
( k == 0 ) ? "" : ", ", attname);
1721+
else
1722+
{
1723+
if ( k >= nclass )
1724+
{
1725+
fprintf(stderr,"dumpIndices(): OpClass not found for "
1726+
"attribute %s of index %s\n",
1727+
attname, indinfo[i].indexrelname);
1728+
exit_nicely(g_conn);
1729+
}
1730+
sprintf (attlist + strlen(attlist), "%s%s %s",
1731+
( k == 0 ) ? "" : ", ", attname, classname[k]);
1732+
free (classname[k]);
1733+
}
1734+
}
16711735

16721736
if (!tablename || (!strcmp(indinfo[i].indrelname,tablename))) {
16731737

@@ -1677,12 +1741,13 @@ dumpIndices(FILE* fout, IndInfo* indinfo, int numIndices,
16771741
indinfo[i].indrelname,
16781742
indinfo[i].indamname);
16791743
if (funcname) {
1680-
sprintf(q, "%s %s(%s) %s);\n",
1681-
q,funcname, attname, indinfo[i].indclassname);
1744+
sprintf(q, "%s %s (%s) %s );\n",
1745+
q, funcname, attlist, classname[0]);
16821746
free(funcname);
1747+
free(classname[0]);
16831748
} else
1684-
sprintf(q, "%s %s %s);\n",
1685-
q,attname,indinfo[i].indclassname);
1749+
sprintf(q, "%s %s );\n",
1750+
q, attlist);
16861751

16871752
fputs(q,fout);
16881753
}

src/bin/pg_dump/pg_dump.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Copyright (c) 1994, Regents of the University of California
77
*
8-
* $Id: pg_dump.h,v 1.12 1997/04/12 09:24:14 scrappy Exp $
8+
* $Id: pg_dump.h,v 1.13 1997/05/06 05:20:21 vadim Exp $
99
*
1010
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
1111
*
@@ -87,8 +87,8 @@ typedef struct _indInfo {
8787
char *indrelname; /* name of the indexed heap class */
8888
char *indamname; /* name of the access method (e.g. btree, rtree, etc.) */
8989
char *indproc; /* oid of the function to compute the index, 0 if none*/
90-
char *indkey; /* attribute number of the key attribute */
91-
char *indclassname; /* name of the opclass of the key */
90+
char *indkey[INDEX_MAX_KEYS]; /* attribute numbers of the key attributes */
91+
char *indclass[INDEX_MAX_KEYS]; /* opclass of the keys */
9292
char *indisunique; /* is this index unique? */
9393
} IndInfo;
9494

0 commit comments

Comments
 (0)