Fixed handling of renamed columns in PK constraints

This commit is contained in:
Philip Warner 2001-01-12 15:41:29 +00:00
parent ed7f37b7b1
commit d63e41e9b2
4 changed files with 146 additions and 77 deletions

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
* *
@ -270,12 +270,14 @@ dumpSchema(Archive *fout,
int numInherits; int numInherits;
int numAggregates; int numAggregates;
int numOperators; int numOperators;
int numIndices;
TypeInfo *tinfo = NULL; TypeInfo *tinfo = NULL;
FuncInfo *finfo = NULL; FuncInfo *finfo = NULL;
AggInfo *agginfo = NULL; AggInfo *agginfo = NULL;
TableInfo *tblinfo = NULL; TableInfo *tblinfo = NULL;
InhInfo *inhinfo = NULL; InhInfo *inhinfo = NULL;
OprInfo *oprinfo = NULL; OprInfo *oprinfo = NULL;
IndInfo *indinfo = NULL;
if (g_verbose) if (g_verbose)
fprintf(stderr, "%s reading user-defined types %s\n", fprintf(stderr, "%s reading user-defined types %s\n",
@ -302,6 +304,11 @@ dumpSchema(Archive *fout,
g_comment_start, g_comment_end); g_comment_start, g_comment_end);
tblinfo = getTables(&numTables, finfo, numFuncs); 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) if (g_verbose)
fprintf(stderr, "%s reading table inheritance information %s\n", fprintf(stderr, "%s reading table inheritance information %s\n",
g_comment_start, g_comment_end); g_comment_start, g_comment_end);
@ -336,9 +343,18 @@ dumpSchema(Archive *fout,
if (g_verbose) if (g_verbose)
fprintf(stderr, "%s dumping out tables %s\n", fprintf(stderr, "%s dumping out tables %s\n",
g_comment_start, g_comment_end); 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); 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 (!tablename && !dataOnly)
{ {
if (g_verbose) if (g_verbose)
@ -377,35 +393,8 @@ dumpSchema(Archive *fout,
clearTypeInfo(tinfo, numTypes); clearTypeInfo(tinfo, numTypes);
clearFuncInfo(finfo, numFuncs); clearFuncInfo(finfo, numFuncs);
clearInhInfo(inhinfo, numInherits); 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); clearIndInfo(indinfo, numIndices);
return tblinfo;
} }
/* flagInhAttrs - /* flagInhAttrs -

View File

@ -62,7 +62,7 @@ typedef z_stream *z_streamp;
#define K_VERS_MAJOR 1 #define K_VERS_MAJOR 1
#define K_VERS_MINOR 4 #define K_VERS_MINOR 4
#define K_VERS_REV 23 #define K_VERS_REV 24
/* Data block types */ /* Data block types */
#define BLK_DATA 1 #define BLK_DATA 1

View File

@ -22,7 +22,7 @@
* *
* *
* IDENTIFICATION * 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 * 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 dumpBlobs(Archive *AH, char*, void*);
static int dumpDatabase(Archive *AH); static int dumpDatabase(Archive *AH);
static PQExpBuffer getPKconstraint(TableInfo *tblInfo, IndInfo *indInfo);
extern char *optarg; extern char *optarg;
extern int optind, extern int optind,
@ -1027,7 +1028,6 @@ main(int argc, char **argv)
if (!dataOnly) /* dump indexes and triggers at the end if (!dataOnly) /* dump indexes and triggers at the end
* for performance */ * for performance */
{ {
dumpSchemaIdx(g_fout, tablename, tblinfo, numTables);
dumpTriggers(g_fout, tablename, tblinfo, numTables); dumpTriggers(g_fout, tablename, tblinfo, numTables);
dumpRules(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, "TABLE DATA");
MoveToEnd(g_fout, "BLOBS"); MoveToEnd(g_fout, "BLOBS");
MoveToEnd(g_fout, "INDEX"); MoveToEnd(g_fout, "INDEX");
MoveToEnd(g_fout, "CONSTRAINT");
MoveToEnd(g_fout, "TRIGGER"); MoveToEnd(g_fout, "TRIGGER");
MoveToEnd(g_fout, "RULE"); MoveToEnd(g_fout, "RULE");
MoveToEnd(g_fout, "SEQUENCE SET"); MoveToEnd(g_fout, "SEQUENCE SET");
@ -1568,8 +1569,6 @@ clearTableInfo(TableInfo *tblinfo, int numTables)
free(tblinfo[i].typnames); free(tblinfo[i].typnames);
if (tblinfo[i].notnull) if (tblinfo[i].notnull)
free(tblinfo[i].notnull); free(tblinfo[i].notnull);
if (tblinfo[i].primary_key)
free(tblinfo[i].primary_key);
if (tblinfo[i].primary_key_name) if (tblinfo[i].primary_key_name)
free(tblinfo[i].primary_key_name); free(tblinfo[i].primary_key_name);
} }
@ -1656,6 +1655,8 @@ clearIndInfo(IndInfo *ind, int numIndices)
free(ind[i].indproc); free(ind[i].indproc);
if (ind[i].indisunique) if (ind[i].indisunique)
free(ind[i].indisunique); free(ind[i].indisunique);
if (ind[i].indisprimary)
free(ind[i].indisprimary);
for (a = 0; a < INDEX_MAX_KEYS; ++a) for (a = 0; a < INDEX_MAX_KEYS; ++a)
{ {
if (ind[i].indkey[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) if (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0)
{ {
PGresult *res2; PGresult *res2;
char str[INDEX_MAX_KEYS * (NAMEDATALEN * 2 + 4) + 1];
int j;
resetPQExpBuffer(query); resetPQExpBuffer(query);
appendPQExpBuffer(query, appendPQExpBuffer(query,
"SELECT a.attname " "SELECT Oid FROM pg_index i WHERE i.indisprimary AND i.indrelid = %s ",
"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 ",
tblinfo[i].oid); tblinfo[i].oid);
res2 = PQexec(g_conn, query->data); res2 = PQexec(g_conn, query->data);
if (!res2 || PQresultStatus(res2) != PGRES_TUPLES_OK) 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)); PQerrorMessage(g_conn));
exit_nicely(g_conn); exit_nicely(g_conn);
} }
str[0] = '\0'; if (PQntuples(res2) > 1) {
for (j = 0; j < PQntuples(res2); j++) fprintf(stderr, "getTables(): SELECT (for PRIMARY KEY) produced more than one row.\n");
{ exit_nicely(g_conn);
if (strlen(str) > 0)
strcat(str, ", ");
strcat(str, fmtId(PQgetvalue(res2, j, 0), force_quotes));
} }
if (strlen(str) > 0) if (PQntuples(res2) == 1) {
{ tblinfo[i].pkIndexOid = strdup(PQgetvalue(res2, 0, 0));
tblinfo[i].primary_key = strdup(str); } else {
if (tblinfo[i].primary_key == NULL) tblinfo[i].pkIndexOid = NULL;
{
perror("strdup");
exit(1);
}
} }
else
tblinfo[i].primary_key = NULL;
} }
else else
tblinfo[i].primary_key = NULL; tblinfo[i].pkIndexOid = NULL;
/* Get primary key name (if primary key exist) */ /* Get primary key name (if primary key exist) */
if (tblinfo[i].primary_key) if (tblinfo[i].pkIndexOid != NULL)
{ {
PGresult *res2; PGresult *res2;
int n; int n;
@ -2695,6 +2682,8 @@ getIndices(int *numIndices)
int i_indclass; int i_indclass;
int i_indisunique; int i_indisunique;
int i_indoid; int i_indoid;
int i_oid;
int i_indisprimary;
/* /*
* find all the user-defined indices. We do not handle partial * find all the user-defined indices. We do not handle partial
@ -2706,13 +2695,13 @@ getIndices(int *numIndices)
*/ */
appendPQExpBuffer(query, 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, " "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 " "from pg_index i, pg_class t1, pg_class t2, pg_am a "
"WHERE t1.oid = i.indexrelid and t2.oid = i.indrelid " "WHERE t1.oid = i.indexrelid and t2.oid = i.indrelid "
"and t1.relam = a.oid and i.indexrelid > '%u'::oid " "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); g_last_builtin_oid);
res = PQexec(g_conn, query->data); res = PQexec(g_conn, query->data);
@ -2732,6 +2721,7 @@ getIndices(int *numIndices)
memset((char *) indinfo, 0, ntups * sizeof(IndInfo)); memset((char *) indinfo, 0, ntups * sizeof(IndInfo));
i_oid = PQfnumber(res, "oid");
i_indoid = PQfnumber(res, "indoid"); i_indoid = PQfnumber(res, "indoid");
i_indexrelname = PQfnumber(res, "indexrelname"); i_indexrelname = PQfnumber(res, "indexrelname");
i_indrelname = PQfnumber(res, "indrelname"); i_indrelname = PQfnumber(res, "indrelname");
@ -2740,9 +2730,11 @@ getIndices(int *numIndices)
i_indkey = PQfnumber(res, "indkey"); i_indkey = PQfnumber(res, "indkey");
i_indclass = PQfnumber(res, "indclass"); i_indclass = PQfnumber(res, "indclass");
i_indisunique = PQfnumber(res, "indisunique"); i_indisunique = PQfnumber(res, "indisunique");
i_indisprimary = PQfnumber(res, "indisprimary");
for (i = 0; i < ntups; i++) 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].indoid = strdup(PQgetvalue(res, i, i_indoid));
indinfo[i].indexrelname = strdup(PQgetvalue(res, i, i_indexrelname)); indinfo[i].indexrelname = strdup(PQgetvalue(res, i, i_indexrelname));
indinfo[i].indrelname = strdup(PQgetvalue(res, i, i_indrelname)); indinfo[i].indrelname = strdup(PQgetvalue(res, i, i_indrelname));
@ -2755,6 +2747,7 @@ getIndices(int *numIndices)
indinfo[i].indclass, indinfo[i].indclass,
INDEX_MAX_KEYS); INDEX_MAX_KEYS);
indinfo[i].indisunique = strdup(PQgetvalue(res, i, i_indisunique)); indinfo[i].indisunique = strdup(PQgetvalue(res, i, i_indisunique));
indinfo[i].indisprimary = strdup(PQgetvalue(res, i, i_indisprimary));
} }
PQclear(res); PQclear(res);
return indinfo; return indinfo;
@ -3551,6 +3544,7 @@ dumpACL(Archive *fout, TableInfo tbinfo)
void void
dumpTables(Archive *fout, TableInfo *tblinfo, int numTables, dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
IndInfo *indinfo, int numIndices,
InhInfo *inhinfo, int numInherits, InhInfo *inhinfo, int numInherits,
TypeInfo *tinfo, int numTypes, const char *tablename, TypeInfo *tinfo, int numTypes, const char *tablename,
const bool aclsSkip, const bool oids, const bool aclsSkip, const bool oids,
@ -3651,6 +3645,8 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
} }
} }
/* put the CONSTRAINTS inside the table def */ /* put the CONSTRAINTS inside the table def */
for (k = 0; k < tblinfo[i].ncheck; k++) for (k = 0; k < tblinfo[i].ncheck; k++)
{ {
@ -3661,17 +3657,36 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
tblinfo[i].check_expr[k]); tblinfo[i].check_expr[k]);
} }
/* PRIMARY KEY */ /* Primary Key */
if (tblinfo[i].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, ",\n\t");
appendPQExpBuffer(q,
"CONSTRAINT %s PRIMARY KEY (%s)", appendPQExpBuffer(q, "%s", consDef->data);
tblinfo[i].primary_key_name,
tblinfo[i].primary_key); destroyPQExpBuffer(consDef);
} }
appendPQExpBuffer(q, "\n)"); appendPQExpBuffer(q, "\n)");
if (numParents > 0) if (numParents > 0)
@ -3690,13 +3705,15 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
} }
if (!dataOnly) { 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, reltypename, NULL, q->data, delq->data, "", tblinfo[i].usename,
NULL, NULL); NULL, NULL);
}
if (!dataOnly && !aclsSkip) if (!aclsSkip)
dumpACL(fout, tblinfo[i]); dumpACL(fout, tblinfo[i]);
}
/* Dump Field Comments */ /* 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: * dumpIndices:
* write out to fout all the user-define indices * write out to fout all the user-define indices
@ -3755,6 +3807,31 @@ dumpIndices(Archive *fout, IndInfo *indinfo, int numIndices,
exit(1); 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) if (strcmp(indinfo[i].indproc, "0") == 0)
funcname = NULL; funcname = NULL;
else else

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * 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 * 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 */ char **check_expr; /* [CONSTRAINT name] CHECK expressions */
int ntrig; /* # of triggers */ int ntrig; /* # of triggers */
TrigInfo *triggers; /* Triggers on the table */ 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 */ char *primary_key_name; /* PRIMARY KEY name, if any */
} TableInfo; } TableInfo;
@ -128,6 +128,7 @@ typedef struct _inhInfo
typedef struct _indInfo typedef struct _indInfo
{ {
char *oid; /* Oid of the pg_index entry */
char *indoid; /* oid of the pg_class entry for the index */ char *indoid; /* oid of the pg_class entry for the index */
char *indexrelname; /* name of the secondary index class */ char *indexrelname; /* name of the secondary index class */
char *indrelname; /* name of the indexed heap class */ char *indrelname; /* name of the indexed heap class */
@ -139,6 +140,7 @@ typedef struct _indInfo
* attributes */ * attributes */
char *indclass[INDEX_MAX_KEYS]; /* opclass of the keys */ char *indclass[INDEX_MAX_KEYS]; /* opclass of the keys */
char *indisunique; /* is this index unique? */ char *indisunique; /* is this index unique? */
char *indisprimary; /* is this a PK index? */
} IndInfo; } IndInfo;
typedef struct _aggInfo 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, extern void dumpOprs(Archive *fout, OprInfo *agginfo, int numOperators,
TypeInfo *tinfo, int numTypes); TypeInfo *tinfo, int numTypes);
extern void dumpTables(Archive *fout, TableInfo *tbinfo, int numTables, extern void dumpTables(Archive *fout, TableInfo *tbinfo, int numTables,
IndInfo *indinfo, int numIndices,
InhInfo *inhinfo, int numInherits, InhInfo *inhinfo, int numInherits,
TypeInfo *tinfo, int numTypes, const char *tablename, TypeInfo *tinfo, int numTypes, const char *tablename,
const bool acls, const bool oids, const bool acls, const bool oids,