aboutsummaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/pg_dump/common.c47
-rw-r--r--src/bin/pg_dump/pg_dump.c125
-rw-r--r--src/bin/pg_dump/pg_dump.h4
3 files changed, 116 insertions, 60 deletions
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 2d41a52e191..8950dee0ca8 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.103 2008/03/27 03:57:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.104 2008/05/09 23:32:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -62,8 +62,7 @@ static DumpableObject **oprinfoindex;
static void flagInhTables(TableInfo *tbinfo, int numTables,
InhInfo *inhinfo, int numInherits);
-static void flagInhAttrs(TableInfo *tbinfo, int numTables,
- InhInfo *inhinfo, int numInherits);
+static void flagInhAttrs(TableInfo *tblinfo, int numTables);
static DumpableObject **buildIndexArray(void *objArray, int numObjs,
Size objSize);
static int DOCatalogIdCompare(const void *p1, const void *p2);
@@ -191,7 +190,7 @@ getSchemaData(int *numTablesPtr)
if (g_verbose)
write_msg(NULL, "flagging inherited columns in subtables\n");
- flagInhAttrs(tblinfo, numTables, inhinfo, numInherits);
+ flagInhAttrs(tblinfo, numTables);
if (g_verbose)
write_msg(NULL, "reading indexes\n");
@@ -257,8 +256,7 @@ flagInhTables(TableInfo *tblinfo, int numTables,
* modifies tblinfo
*/
static void
-flagInhAttrs(TableInfo *tblinfo, int numTables,
- InhInfo *inhinfo, int numInherits)
+flagInhAttrs(TableInfo *tblinfo, int numTables)
{
int i,
j,
@@ -414,43 +412,6 @@ flagInhAttrs(TableInfo *tblinfo, int numTables,
tbinfo->inhAttrs[j] = false;
}
}
-
- /*
- * Check for inherited CHECK constraints. We assume a constraint is
- * inherited if its name matches the name of any constraint in the
- * parent. Originally this code tried to compare the expression
- * texts, but that can fail if the parent and child tables are in
- * different schemas, because reverse-listing of function calls may
- * produce different text (schema-qualified or not) depending on
- * search path. We really need a more bulletproof way of detecting
- * inherited constraints --- pg_constraint should record this
- * explicitly!
- */
- for (j = 0; j < tbinfo->ncheck; j++)
- {
- ConstraintInfo *constr;
-
- constr = &(tbinfo->checkexprs[j]);
-
- for (k = 0; k < numParents; k++)
- {
- int l;
-
- parent = parents[k];
- for (l = 0; l < parent->ncheck; l++)
- {
- ConstraintInfo *pconstr = &(parent->checkexprs[l]);
-
- if (strcmp(pconstr->dobj.name, constr->dobj.name) == 0)
- {
- constr->coninherited = true;
- break;
- }
- }
- if (constr->coninherited)
- break;
- }
- }
}
}
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index f7ac1706de8..18e83f4a9ee 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.489 2008/05/03 23:32:32 adunstan Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.490 2008/05/09 23:32:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -120,6 +120,7 @@ static void expand_table_name_patterns(SimpleStringList *patterns,
SimpleOidList *oids);
static NamespaceInfo *findNamespace(Oid nsoid, Oid objoid);
static void dumpTableData(Archive *fout, TableDataInfo *tdinfo);
+static void guessConstraintInheritance(TableInfo *tblinfo, int numTables);
static void dumpComment(Archive *fout, const char *target,
const char *namespace, const char *owner,
CatalogId catalogId, int subid, DumpId dumpId);
@@ -645,6 +646,9 @@ main(int argc, char **argv)
*/
tblinfo = getSchemaData(&numTables);
+ if (g_fout->remoteVersion < 80400)
+ guessConstraintInheritance(tblinfo, numTables);
+
if (!schemaOnly)
getTableData(tblinfo, numTables, oids);
@@ -1384,6 +1388,81 @@ getTableData(TableInfo *tblinfo, int numTables, bool oids)
/*
+ * guessConstraintInheritance:
+ * In pre-8.4 databases, we can't tell for certain which constraints
+ * are inherited. We assume a CHECK constraint is inherited if its name
+ * matches the name of any constraint in the parent. Originally this code
+ * tried to compare the expression texts, but that can fail for various
+ * reasons --- for example, if the parent and child tables are in different
+ * schemas, reverse-listing of function calls may produce different text
+ * (schema-qualified or not) depending on search path.
+ *
+ * In 8.4 and up we can rely on the conislocal field to decide which
+ * constraints must be dumped; much safer.
+ *
+ * This function assumes all conislocal flags were initialized to TRUE.
+ * It clears the flag on anything that seems to be inherited.
+ */
+static void
+guessConstraintInheritance(TableInfo *tblinfo, int numTables)
+{
+ int i,
+ j,
+ k;
+
+ for (i = 0; i < numTables; i++)
+ {
+ TableInfo *tbinfo = &(tblinfo[i]);
+ int numParents;
+ TableInfo **parents;
+ TableInfo *parent;
+
+ /* Sequences and views never have parents */
+ if (tbinfo->relkind == RELKIND_SEQUENCE ||
+ tbinfo->relkind == RELKIND_VIEW)
+ continue;
+
+ /* Don't bother computing anything for non-target tables, either */
+ if (!tbinfo->dobj.dump)
+ continue;
+
+ numParents = tbinfo->numParents;
+ parents = tbinfo->parents;
+
+ if (numParents == 0)
+ continue; /* nothing to see here, move along */
+
+ /* scan for inherited CHECK constraints */
+ for (j = 0; j < tbinfo->ncheck; j++)
+ {
+ ConstraintInfo *constr;
+
+ constr = &(tbinfo->checkexprs[j]);
+
+ for (k = 0; k < numParents; k++)
+ {
+ int l;
+
+ parent = parents[k];
+ for (l = 0; l < parent->ncheck; l++)
+ {
+ ConstraintInfo *pconstr = &(parent->checkexprs[l]);
+
+ if (strcmp(pconstr->dobj.name, constr->dobj.name) == 0)
+ {
+ constr->conislocal = false;
+ break;
+ }
+ }
+ if (!constr->conislocal)
+ break;
+ }
+ }
+ }
+}
+
+
+/*
* dumpDatabase:
* dump the database definition
*/
@@ -3522,7 +3601,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
constrinfo[j].contype = contype;
constrinfo[j].condef = NULL;
constrinfo[j].conindex = indxinfo[j].dobj.dumpId;
- constrinfo[j].coninherited = false;
+ constrinfo[j].conislocal = true;
constrinfo[j].separate = true;
indxinfo[j].indexconstraint = constrinfo[j].dobj.dumpId;
@@ -3623,7 +3702,7 @@ getConstraints(TableInfo tblinfo[], int numTables)
constrinfo[j].contype = 'f';
constrinfo[j].condef = strdup(PQgetvalue(res, j, i_condef));
constrinfo[j].conindex = 0;
- constrinfo[j].coninherited = false;
+ constrinfo[j].conislocal = true;
constrinfo[j].separate = true;
}
@@ -3706,7 +3785,7 @@ getDomainConstraints(TypeInfo *tinfo)
constrinfo[i].contype = 'c';
constrinfo[i].condef = strdup(PQgetvalue(res, i, i_consrc));
constrinfo[i].conindex = 0;
- constrinfo[i].coninherited = false;
+ constrinfo[i].conislocal = true;
constrinfo[i].separate = false;
/*
@@ -4586,10 +4665,22 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
tbinfo->dobj.name);
resetPQExpBuffer(q);
- if (g_fout->remoteVersion >= 70400)
+ if (g_fout->remoteVersion >= 80400)
+ {
+ appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
+ "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
+ "conislocal "
+ "FROM pg_catalog.pg_constraint "
+ "WHERE conrelid = '%u'::pg_catalog.oid "
+ " AND contype = 'c' "
+ "ORDER BY conname",
+ tbinfo->dobj.catId.oid);
+ }
+ else if (g_fout->remoteVersion >= 70400)
{
appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
- "pg_catalog.pg_get_constraintdef(oid) AS consrc "
+ "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
+ "true as conislocal "
"FROM pg_catalog.pg_constraint "
"WHERE conrelid = '%u'::pg_catalog.oid "
" AND contype = 'c' "
@@ -4600,7 +4691,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
{
/* no pg_get_constraintdef, must use consrc */
appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
- "'CHECK (' || consrc || ')' AS consrc "
+ "'CHECK (' || consrc || ')' AS consrc, "
+ "true as conislocal "
"FROM pg_catalog.pg_constraint "
"WHERE conrelid = '%u'::pg_catalog.oid "
" AND contype = 'c' "
@@ -4612,7 +4704,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
/* 7.2 did not have OIDs in pg_relcheck */
appendPQExpBuffer(q, "SELECT tableoid, 0 as oid, "
"rcname AS conname, "
- "'CHECK (' || rcsrc || ')' AS consrc "
+ "'CHECK (' || rcsrc || ')' AS consrc, "
+ "true as conislocal "
"FROM pg_relcheck "
"WHERE rcrelid = '%u'::oid "
"ORDER BY rcname",
@@ -4622,7 +4715,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
{
appendPQExpBuffer(q, "SELECT tableoid, oid, "
"rcname AS conname, "
- "'CHECK (' || rcsrc || ')' AS consrc "
+ "'CHECK (' || rcsrc || ')' AS consrc, "
+ "true as conislocal "
"FROM pg_relcheck "
"WHERE rcrelid = '%u'::oid "
"ORDER BY rcname",
@@ -4634,7 +4728,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
appendPQExpBuffer(q, "SELECT "
"(SELECT oid FROM pg_class WHERE relname = 'pg_relcheck') AS tableoid, "
"oid, rcname AS conname, "
- "'CHECK (' || rcsrc || ')' AS consrc "
+ "'CHECK (' || rcsrc || ')' AS consrc, "
+ "true as conislocal "
"FROM pg_relcheck "
"WHERE rcrelid = '%u'::oid "
"ORDER BY rcname",
@@ -4668,7 +4763,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
constrs[j].contype = 'c';
constrs[j].condef = strdup(PQgetvalue(res, j, 3));
constrs[j].conindex = 0;
- constrs[j].coninherited = false;
+ constrs[j].conislocal = (PQgetvalue(res, j, 4)[0] == 't');
constrs[j].separate = false;
constrs[j].dobj.dump = tbinfo->dobj.dump;
@@ -4684,8 +4779,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
/*
* If the constraint is inherited, this will be detected
- * later. We also detect later if the constraint must be
- * split out from the table definition.
+ * later (in pre-8.4 databases). We also detect later if the
+ * constraint must be split out from the table definition.
*/
}
PQclear(res);
@@ -8840,7 +8935,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
{
ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
- if (constr->coninherited || constr->separate)
+ if (constr->separate || !constr->conislocal)
continue;
if (actual_atts > 0)
@@ -8955,7 +9050,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
{
ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
- if (constr->coninherited || constr->separate)
+ if (constr->separate || !constr->conislocal)
continue;
dumpTableConstraintComment(fout, constr);
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index d4b40e9d887..8fbe98221b6 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.139 2008/01/01 19:45:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.140 2008/05/09 23:32:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -353,7 +353,7 @@ typedef struct _constraintInfo
char contype;
char *condef; /* definition, if CHECK or FOREIGN KEY */
DumpId conindex; /* identifies associated index if any */
- bool coninherited; /* TRUE if appears to be inherited */
+ bool conislocal; /* TRUE if constraint has local definition */
bool separate; /* TRUE if must dump as separate item */
} ConstraintInfo;