diff options
Diffstat (limited to 'src/bin/pg_dump/pg_dump.c')
-rw-r--r-- | src/bin/pg_dump/pg_dump.c | 125 |
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); |