*
*
* 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
*
#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"
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");
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);
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++) {
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);
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;
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 {
"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))) {
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);
}