aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_dump/pg_dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/pg_dump/pg_dump.c')
-rw-r--r--src/bin/pg_dump/pg_dump.c125
1 files changed, 110 insertions, 15 deletions
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);