Fixed handling of renamed columns in PK constraints
This commit is contained in:
parent
ed7f37b7b1
commit
d63e41e9b2
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
@ -270,12 +270,14 @@ dumpSchema(Archive *fout,
|
||||
int numInherits;
|
||||
int numAggregates;
|
||||
int numOperators;
|
||||
int numIndices;
|
||||
TypeInfo *tinfo = NULL;
|
||||
FuncInfo *finfo = NULL;
|
||||
AggInfo *agginfo = NULL;
|
||||
TableInfo *tblinfo = NULL;
|
||||
InhInfo *inhinfo = NULL;
|
||||
OprInfo *oprinfo = NULL;
|
||||
IndInfo *indinfo = NULL;
|
||||
|
||||
if (g_verbose)
|
||||
fprintf(stderr, "%s reading user-defined types %s\n",
|
||||
@ -302,6 +304,11 @@ dumpSchema(Archive *fout,
|
||||
g_comment_start, g_comment_end);
|
||||
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)
|
||||
fprintf(stderr, "%s reading table inheritance information %s\n",
|
||||
g_comment_start, g_comment_end);
|
||||
@ -336,9 +343,18 @@ dumpSchema(Archive *fout,
|
||||
if (g_verbose)
|
||||
fprintf(stderr, "%s dumping out tables %s\n",
|
||||
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);
|
||||
|
||||
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 (g_verbose)
|
||||
@ -377,35 +393,8 @@ dumpSchema(Archive *fout,
|
||||
clearTypeInfo(tinfo, numTypes);
|
||||
clearFuncInfo(finfo, numFuncs);
|
||||
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);
|
||||
return tblinfo;
|
||||
}
|
||||
|
||||
/* flagInhAttrs -
|
||||
|
@ -62,7 +62,7 @@ typedef z_stream *z_streamp;
|
||||
|
||||
#define K_VERS_MAJOR 1
|
||||
#define K_VERS_MINOR 4
|
||||
#define K_VERS_REV 23
|
||||
#define K_VERS_REV 24
|
||||
|
||||
/* Data block types */
|
||||
#define BLK_DATA 1
|
||||
|
@ -22,7 +22,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
@ -155,6 +155,7 @@ static char *GetPrivileges(const char *s);
|
||||
|
||||
static int dumpBlobs(Archive *AH, char*, void*);
|
||||
static int dumpDatabase(Archive *AH);
|
||||
static PQExpBuffer getPKconstraint(TableInfo *tblInfo, IndInfo *indInfo);
|
||||
|
||||
extern char *optarg;
|
||||
extern int optind,
|
||||
@ -1027,7 +1028,6 @@ main(int argc, char **argv)
|
||||
if (!dataOnly) /* dump indexes and triggers at the end
|
||||
* for performance */
|
||||
{
|
||||
dumpSchemaIdx(g_fout, tablename, tblinfo, numTables);
|
||||
dumpTriggers(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, "BLOBS");
|
||||
MoveToEnd(g_fout, "INDEX");
|
||||
MoveToEnd(g_fout, "CONSTRAINT");
|
||||
MoveToEnd(g_fout, "TRIGGER");
|
||||
MoveToEnd(g_fout, "RULE");
|
||||
MoveToEnd(g_fout, "SEQUENCE SET");
|
||||
@ -1568,8 +1569,6 @@ clearTableInfo(TableInfo *tblinfo, int numTables)
|
||||
free(tblinfo[i].typnames);
|
||||
if (tblinfo[i].notnull)
|
||||
free(tblinfo[i].notnull);
|
||||
if (tblinfo[i].primary_key)
|
||||
free(tblinfo[i].primary_key);
|
||||
if (tblinfo[i].primary_key_name)
|
||||
free(tblinfo[i].primary_key_name);
|
||||
}
|
||||
@ -1656,6 +1655,8 @@ clearIndInfo(IndInfo *ind, int numIndices)
|
||||
free(ind[i].indproc);
|
||||
if (ind[i].indisunique)
|
||||
free(ind[i].indisunique);
|
||||
if (ind[i].indisprimary)
|
||||
free(ind[i].indisprimary);
|
||||
for (a = 0; a < INDEX_MAX_KEYS; ++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)
|
||||
{
|
||||
PGresult *res2;
|
||||
char str[INDEX_MAX_KEYS * (NAMEDATALEN * 2 + 4) + 1];
|
||||
int j;
|
||||
|
||||
resetPQExpBuffer(query);
|
||||
appendPQExpBuffer(query,
|
||||
"SELECT a.attname "
|
||||
"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 ",
|
||||
"SELECT Oid FROM pg_index i WHERE i.indisprimary AND i.indrelid = %s ",
|
||||
tblinfo[i].oid);
|
||||
res2 = PQexec(g_conn, query->data);
|
||||
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));
|
||||
exit_nicely(g_conn);
|
||||
}
|
||||
|
||||
str[0] = '\0';
|
||||
for (j = 0; j < PQntuples(res2); j++)
|
||||
{
|
||||
if (strlen(str) > 0)
|
||||
strcat(str, ", ");
|
||||
strcat(str, fmtId(PQgetvalue(res2, j, 0), force_quotes));
|
||||
if (PQntuples(res2) > 1) {
|
||||
fprintf(stderr, "getTables(): SELECT (for PRIMARY KEY) produced more than one row.\n");
|
||||
exit_nicely(g_conn);
|
||||
}
|
||||
|
||||
if (strlen(str) > 0)
|
||||
{
|
||||
tblinfo[i].primary_key = strdup(str);
|
||||
if (tblinfo[i].primary_key == NULL)
|
||||
{
|
||||
perror("strdup");
|
||||
exit(1);
|
||||
}
|
||||
if (PQntuples(res2) == 1) {
|
||||
tblinfo[i].pkIndexOid = strdup(PQgetvalue(res2, 0, 0));
|
||||
} else {
|
||||
tblinfo[i].pkIndexOid = NULL;
|
||||
}
|
||||
else
|
||||
tblinfo[i].primary_key = NULL;
|
||||
|
||||
}
|
||||
else
|
||||
tblinfo[i].primary_key = NULL;
|
||||
tblinfo[i].pkIndexOid = NULL;
|
||||
|
||||
/* Get primary key name (if primary key exist) */
|
||||
if (tblinfo[i].primary_key)
|
||||
if (tblinfo[i].pkIndexOid != NULL)
|
||||
{
|
||||
PGresult *res2;
|
||||
int n;
|
||||
@ -2695,6 +2682,8 @@ getIndices(int *numIndices)
|
||||
int i_indclass;
|
||||
int i_indisunique;
|
||||
int i_indoid;
|
||||
int i_oid;
|
||||
int i_indisprimary;
|
||||
|
||||
/*
|
||||
* find all the user-defined indices. We do not handle partial
|
||||
@ -2706,13 +2695,13 @@ getIndices(int *numIndices)
|
||||
*/
|
||||
|
||||
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, "
|
||||
"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 "
|
||||
"WHERE t1.oid = i.indexrelid and t2.oid = i.indrelid "
|
||||
"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);
|
||||
|
||||
res = PQexec(g_conn, query->data);
|
||||
@ -2732,6 +2721,7 @@ getIndices(int *numIndices)
|
||||
|
||||
memset((char *) indinfo, 0, ntups * sizeof(IndInfo));
|
||||
|
||||
i_oid = PQfnumber(res, "oid");
|
||||
i_indoid = PQfnumber(res, "indoid");
|
||||
i_indexrelname = PQfnumber(res, "indexrelname");
|
||||
i_indrelname = PQfnumber(res, "indrelname");
|
||||
@ -2740,9 +2730,11 @@ getIndices(int *numIndices)
|
||||
i_indkey = PQfnumber(res, "indkey");
|
||||
i_indclass = PQfnumber(res, "indclass");
|
||||
i_indisunique = PQfnumber(res, "indisunique");
|
||||
i_indisprimary = PQfnumber(res, "indisprimary");
|
||||
|
||||
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].indexrelname = strdup(PQgetvalue(res, i, i_indexrelname));
|
||||
indinfo[i].indrelname = strdup(PQgetvalue(res, i, i_indrelname));
|
||||
@ -2755,6 +2747,7 @@ getIndices(int *numIndices)
|
||||
indinfo[i].indclass,
|
||||
INDEX_MAX_KEYS);
|
||||
indinfo[i].indisunique = strdup(PQgetvalue(res, i, i_indisunique));
|
||||
indinfo[i].indisprimary = strdup(PQgetvalue(res, i, i_indisprimary));
|
||||
}
|
||||
PQclear(res);
|
||||
return indinfo;
|
||||
@ -3551,6 +3544,7 @@ dumpACL(Archive *fout, TableInfo tbinfo)
|
||||
|
||||
void
|
||||
dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
|
||||
IndInfo *indinfo, int numIndices,
|
||||
InhInfo *inhinfo, int numInherits,
|
||||
TypeInfo *tinfo, int numTypes, const char *tablename,
|
||||
const bool aclsSkip, const bool oids,
|
||||
@ -3651,6 +3645,8 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* put the CONSTRAINTS inside the table def */
|
||||
for (k = 0; k < tblinfo[i].ncheck; k++)
|
||||
{
|
||||
@ -3661,17 +3657,36 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
|
||||
tblinfo[i].check_expr[k]);
|
||||
}
|
||||
|
||||
/* PRIMARY KEY */
|
||||
if (tblinfo[i].primary_key)
|
||||
/* 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,
|
||||
"CONSTRAINT %s PRIMARY KEY (%s)",
|
||||
tblinfo[i].primary_key_name,
|
||||
tblinfo[i].primary_key);
|
||||
|
||||
appendPQExpBuffer(q, "%s", consDef->data);
|
||||
|
||||
destroyPQExpBuffer(consDef);
|
||||
}
|
||||
|
||||
|
||||
appendPQExpBuffer(q, "\n)");
|
||||
|
||||
if (numParents > 0)
|
||||
@ -3690,13 +3705,15 @@ dumpTables(Archive *fout, TableInfo *tblinfo, int numTables,
|
||||
}
|
||||
|
||||
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,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
if (!dataOnly && !aclsSkip)
|
||||
dumpACL(fout, tblinfo[i]);
|
||||
if (!aclsSkip)
|
||||
dumpACL(fout, tblinfo[i]);
|
||||
|
||||
}
|
||||
|
||||
/* 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:
|
||||
* write out to fout all the user-define indices
|
||||
@ -3755,6 +3807,31 @@ dumpIndices(Archive *fout, IndInfo *indinfo, int numIndices,
|
||||
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)
|
||||
funcname = NULL;
|
||||
else
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* 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
|
||||
*
|
||||
@ -116,7 +116,7 @@ typedef struct _tableInfo
|
||||
char **check_expr; /* [CONSTRAINT name] CHECK expressions */
|
||||
int ntrig; /* # of triggers */
|
||||
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 */
|
||||
} TableInfo;
|
||||
|
||||
@ -128,6 +128,7 @@ typedef struct _inhInfo
|
||||
|
||||
typedef struct _indInfo
|
||||
{
|
||||
char *oid; /* Oid of the pg_index entry */
|
||||
char *indoid; /* oid of the pg_class entry for the index */
|
||||
char *indexrelname; /* name of the secondary index class */
|
||||
char *indrelname; /* name of the indexed heap class */
|
||||
@ -139,6 +140,7 @@ typedef struct _indInfo
|
||||
* attributes */
|
||||
char *indclass[INDEX_MAX_KEYS]; /* opclass of the keys */
|
||||
char *indisunique; /* is this index unique? */
|
||||
char *indisprimary; /* is this a PK index? */
|
||||
} IndInfo;
|
||||
|
||||
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,
|
||||
TypeInfo *tinfo, int numTypes);
|
||||
extern void dumpTables(Archive *fout, TableInfo *tbinfo, int numTables,
|
||||
IndInfo *indinfo, int numIndices,
|
||||
InhInfo *inhinfo, int numInherits,
|
||||
TypeInfo *tinfo, int numTypes, const char *tablename,
|
||||
const bool acls, const bool oids,
|
||||
|
Loading…
x
Reference in New Issue
Block a user