aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bin/pg_dump/common.c29
-rw-r--r--src/bin/pg_dump/pg_dump.c10
2 files changed, 29 insertions, 10 deletions
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index a43f2e5553e..a2b74901e43 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -471,6 +471,13 @@ flagInhAttrs(DumpOptions *dopt, TableInfo *tblinfo, int numTables)
j,
k;
+ /*
+ * We scan the tables in OID order, since that's how tblinfo[] is sorted.
+ * Hence we will typically visit parents before their children --- but
+ * that is *not* guaranteed. Thus this loop must be careful that it does
+ * not alter table properties in a way that could change decisions made at
+ * child tables during other iterations.
+ */
for (i = 0; i < numTables; i++)
{
TableInfo *tbinfo = &(tblinfo[i]);
@@ -519,15 +526,18 @@ flagInhAttrs(DumpOptions *dopt, TableInfo *tblinfo, int numTables)
parent->numatts);
if (inhAttrInd >= 0)
{
+ AttrDefInfo *parentDef = parent->attrdefs[inhAttrInd];
+
foundNotNull |= parent->notnull[inhAttrInd];
- foundDefault |= (parent->attrdefs[inhAttrInd] != NULL &&
+ foundDefault |= (parentDef != NULL &&
+ strcmp(parentDef->adef_expr, "NULL") != 0 &&
!parent->attgenerated[inhAttrInd]);
if (parent->attgenerated[inhAttrInd])
{
/* these pointer nullness checks are just paranoia */
- if (parent->attrdefs[inhAttrInd] != NULL &&
+ if (parentDef != NULL &&
tbinfo->attrdefs[j] != NULL &&
- strcmp(parent->attrdefs[inhAttrInd]->adef_expr,
+ strcmp(parentDef->adef_expr,
tbinfo->attrdefs[j]->adef_expr) == 0)
foundSameGenerated = true;
else
@@ -539,7 +549,14 @@ flagInhAttrs(DumpOptions *dopt, TableInfo *tblinfo, int numTables)
/* Remember if we found inherited NOT NULL */
tbinfo->inhNotNull[j] = foundNotNull;
- /* Manufacture a DEFAULT NULL clause if necessary */
+ /*
+ * Manufacture a DEFAULT NULL clause if necessary. This breaks
+ * the advice given above to avoid changing state that might get
+ * inspected in other loop iterations. We prevent trouble by
+ * having the foundDefault test above check whether adef_expr is
+ * "NULL", so that it will reach the same conclusion before or
+ * after this is done.
+ */
if (foundDefault && tbinfo->attrdefs[j] == NULL)
{
AttrDefInfo *attrDef;
@@ -575,10 +592,10 @@ flagInhAttrs(DumpOptions *dopt, TableInfo *tblinfo, int numTables)
tbinfo->attrdefs[j] = attrDef;
}
- /* Remove generation expression from child if possible */
+ /* No need to dump generation expression if it's inheritable */
if (foundSameGenerated && !foundDiffGenerated &&
!tbinfo->ispartition && !dopt->binary_upgrade)
- tbinfo->attrdefs[j] = NULL;
+ tbinfo->attrdefs[j]->dobj.dump = DUMP_COMPONENT_NONE;
}
}
}
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 24ba936332d..655d39a81bc 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -8525,9 +8525,9 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
* Column generation expressions cannot be dumped separately,
* because there is no syntax for it. By setting separate to
* false here we prevent the "default" from being processed as
- * its own dumpable object, and flagInhAttrs() will remove it
- * from the table if possible (that is, if it can be inherited
- * from a parent).
+ * its own dumpable object. Later, flagInhAttrs() will mark
+ * it as not to be dumped at all, if possible (that is, if it
+ * can be inherited from a parent).
*/
attrdefs[j].separate = false;
}
@@ -15345,9 +15345,11 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
bool print_notnull;
/*
- * Default value --- suppress if to be printed separately.
+ * Default value --- suppress if to be printed separately
+ * or not at all.
*/
print_default = (tbinfo->attrdefs[j] != NULL &&
+ tbinfo->attrdefs[j]->dobj.dump &&
!tbinfo->attrdefs[j]->separate);
/*