summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2007-10-28 19:08:25 +0000
committerTom Lane2007-10-28 19:08:25 +0000
commitba5e258ef97a450e3ea993bb7a08e18d25eb310b (patch)
tree1dd7356d4ba0b4375b286b46c9541379ff91988d
parenta4c8494e7b0589ba50cd2d1b00a9b6e2eaaecd15 (diff)
Fix a couple of issues with pg_dump's handling of inheritance child tables
that have default expressions different from their parent. First, if the parent table's default expression has to be split out as a separate ALTER TABLE command, we need a dependency constraint to ensure that the child's command is given second. This is because the ALTER TABLE on the parent will propagate to the child. (We can't prevent that by using ONLY on the parent's command, since it's possible that other children exist that should receive the inherited default.) Second, if the child has a NULL default where the parent does not, we have to explicitly say DEFAULT NULL on the child in order for this state to be preserved after reload. (The latter actually doesn't work right because of a backend bug, but that is a separate issue.) Backpatch as far as 8.0. 7.x pg_dump has enough issues with altered tables (due to lack of dependency analysis) that trying to fix this one doesn't seem very productive.
-rw-r--r--src/bin/pg_dump/common.c52
1 files changed, 42 insertions, 10 deletions
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index f4ae06e86f3..040e1c653e4 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.85.4.1 2005/06/27 02:18:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.85.4.2 2007/10/28 19:08:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -290,19 +290,51 @@ flagInhAttrs(TableInfo *tblinfo, int numTables,
if (inhAttrInd != -1)
{
+ AttrDefInfo *inhDef = parent->attrdefs[inhAttrInd];
+
foundAttr = true;
foundNotNull |= parent->notnull[inhAttrInd];
- if (attrDef != NULL) /* If we have a default,
- * check parent */
+ if (inhDef != NULL)
{
- AttrDefInfo *inhDef;
-
- inhDef = parent->attrdefs[inhAttrInd];
- if (inhDef != NULL)
+ defaultsFound = true;
+ /*
+ * If any parent has a default and the child doesn't,
+ * we have to emit an explicit DEFAULT NULL clause
+ * for the child, else the parent's default will win.
+ */
+ if (attrDef == NULL)
+ {
+ attrDef = (AttrDefInfo *) malloc(sizeof(AttrDefInfo));
+ attrDef->dobj.objType = DO_ATTRDEF;
+ attrDef->dobj.catId.tableoid = 0;
+ attrDef->dobj.catId.oid = 0;
+ AssignDumpId(&attrDef->dobj);
+ attrDef->adtable = tbinfo;
+ attrDef->adnum = j + 1;
+ attrDef->adef_expr = strdup("NULL");
+
+ attrDef->dobj.name = strdup(tbinfo->dobj.name);
+ attrDef->dobj.namespace = tbinfo->dobj.namespace;
+
+ attrDef->separate = false;
+ addObjectDependency(&tbinfo->dobj,
+ attrDef->dobj.dumpId);
+
+ tbinfo->attrdefs[j] = attrDef;
+ }
+ if (strcmp(attrDef->adef_expr, inhDef->adef_expr) != 0)
{
- defaultsFound = true;
- defaultsMatch &= (strcmp(attrDef->adef_expr,
- inhDef->adef_expr) == 0);
+ defaultsMatch = false;
+ /*
+ * Whenever there is a non-matching parent
+ * default, add a dependency to force the parent
+ * default to be dumped first, in case the
+ * defaults end up being dumped as separate
+ * commands. Otherwise the parent default will
+ * override the child's when it is applied.
+ */
+ addObjectDependency(&attrDef->dobj,
+ inhDef->dobj.dumpId);
}
}
}