@@ -8188,9 +8188,12 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
81888188 * Normally this is always true, but it's false for dropped columns, as well
81898189 * as those that were inherited without any local definition. (If we print
81908190 * such a column it will mistakenly get pg_attribute.attislocal set to true.)
8191- * However, in binary_upgrade mode, we must print all such columns anyway and
8192- * fix the attislocal/attisdropped state later, so as to keep control of the
8193- * physical column order.
8191+ * For partitions, it's always true, because we want the partitions to be
8192+ * created independently and ATTACH PARTITION used afterwards.
8193+ *
8194+ * In binary_upgrade mode, we must print all columns and fix the attislocal/
8195+ * attisdropped state later, so as to keep control of the physical column
8196+ * order.
81948197 *
81958198 * This function exists because there are scattered nonobvious places that
81968199 * must be kept in sync with this decision.
@@ -8200,7 +8203,9 @@ shouldPrintColumn(DumpOptions *dopt, TableInfo *tbinfo, int colno)
82008203{
82018204 if (dopt->binary_upgrade)
82028205 return true;
8203- return (tbinfo->attislocal[colno] && !tbinfo->attisdropped[colno]);
8206+ if (tbinfo->attisdropped[colno])
8207+ return false;
8208+ return (tbinfo->attislocal[colno] || tbinfo->ispartition);
82048209}
82058210
82068211
@@ -14963,27 +14968,6 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1496314968 if (tbinfo->reloftype && !dopt->binary_upgrade)
1496414969 appendPQExpBuffer(q, " OF %s", tbinfo->reloftype);
1496514970
14966- /*
14967- * If the table is a partition, dump it as such; except in the case of
14968- * a binary upgrade, we dump the table normally and attach it to the
14969- * parent afterward.
14970- */
14971- if (tbinfo->ispartition && !dopt->binary_upgrade)
14972- {
14973- TableInfo *parentRel = tbinfo->parents[0];
14974-
14975- /*
14976- * With partitions, unlike inheritance, there can only be one
14977- * parent.
14978- */
14979- if (tbinfo->numParents != 1)
14980- exit_horribly(NULL, "invalid number of parents %d for table \"%s\"\n",
14981- tbinfo->numParents, tbinfo->dobj.name);
14982-
14983- appendPQExpBuffer(q, " PARTITION OF %s",
14984- fmtQualifiedDumpable(parentRel));
14985- }
14986-
1498714971 if (tbinfo->relkind != RELKIND_MATVIEW)
1498814972 {
1498914973 /* Dump the attributes */
@@ -14998,26 +14982,30 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1499814982 */
1499914983 if (shouldPrintColumn(dopt, tbinfo, j))
1500014984 {
14985+ bool print_default;
14986+ bool print_notnull;
14987+
1500114988 /*
1500214989 * Default value --- suppress if to be printed separately.
1500314990 */
15004- bool has_default = (tbinfo->attrdefs[j] != NULL &&
15005- !tbinfo->attrdefs[j]->separate);
14991+ print_default = (tbinfo->attrdefs[j] != NULL &&
14992+ !tbinfo->attrdefs[j]->separate);
1500614993
1500714994 /*
1500814995 * Not Null constraint --- suppress if inherited, except
15009- * in binary-upgrade case where that won't work.
14996+ * if partition, or in binary-upgrade case where that
14997+ * won't work.
1501014998 */
15011- bool has_notnull = (tbinfo->notnull[j] &&
15012- (!tbinfo->inhNotNull[j] ||
15013- dopt->binary_upgrade));
14999+ print_notnull = (tbinfo->notnull[j] &&
15000+ (!tbinfo->inhNotNull[j] ||
15001+ tbinfo->ispartition || dopt->binary_upgrade));
1501415002
1501515003 /*
15016- * Skip column if fully defined by reloftype or the
15017- * partition parent.
15004+ * Skip column if fully defined by reloftype, except in
15005+ * binary upgrade
1501815006 */
15019- if (( tbinfo->reloftype || tbinfo->ispartition) &&
15020- !has_default && !has_notnull && ! dopt->binary_upgrade)
15007+ if (tbinfo->reloftype && !print_default && !print_notnull &&
15008+ !dopt->binary_upgrade)
1502115009 continue;
1502215010
1502315011 /* Format properly if not first attr */
@@ -15040,20 +15028,16 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1504015028 * clean things up later.
1504115029 */
1504215030 appendPQExpBufferStr(q, " INTEGER /* dummy */");
15043- /* Skip all the rest, too */
15031+ /* and skip to the next column */
1504415032 continue;
1504515033 }
1504615034
1504715035 /*
15048- * Attribute type
15049- *
15050- * In binary-upgrade mode, we always include the type. If
15051- * we aren't in binary-upgrade mode, then we skip the type
15052- * when creating a typed table ('OF type_name') or a
15053- * partition ('PARTITION OF'), since the type comes from
15054- * the parent/partitioned table.
15036+ * Attribute type; print it except when creating a typed
15037+ * table ('OF type_name'), but in binary-upgrade mode,
15038+ * print it in that case too.
1505515039 */
15056- if (dopt->binary_upgrade || ( !tbinfo->reloftype && !tbinfo->ispartition) )
15040+ if (dopt->binary_upgrade || !tbinfo->reloftype)
1505715041 {
1505815042 appendPQExpBuffer(q, " %s",
1505915043 tbinfo->atttypnames[j]);
@@ -15070,23 +15054,29 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1507015054 fmtQualifiedDumpable(coll));
1507115055 }
1507215056
15073- if (has_default )
15057+ if (print_default )
1507415058 appendPQExpBuffer(q, " DEFAULT %s",
1507515059 tbinfo->attrdefs[j]->adef_expr);
1507615060
15077- if (has_notnull )
15061+ if (print_notnull )
1507815062 appendPQExpBufferStr(q, " NOT NULL");
1507915063 }
1508015064 }
1508115065
1508215066 /*
1508315067 * Add non-inherited CHECK constraints, if any.
15068+ *
15069+ * For partitions, we need to include check constraints even if
15070+ * they're not defined locally, because the ALTER TABLE ATTACH
15071+ * PARTITION that we'll emit later expects the constraint to be
15072+ * there. (No need to fix conislocal: ATTACH PARTITION does that)
1508415073 */
1508515074 for (j = 0; j < tbinfo->ncheck; j++)
1508615075 {
1508715076 ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
1508815077
15089- if (constr->separate || !constr->conislocal)
15078+ if (constr->separate ||
15079+ (!constr->conislocal && !tbinfo->ispartition))
1509015080 continue;
1509115081
1509215082 if (actual_atts == 0)
@@ -15103,25 +15093,20 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1510315093
1510415094 if (actual_atts)
1510515095 appendPQExpBufferStr(q, "\n)");
15106- else if (!((tbinfo->reloftype || tbinfo->ispartition) &&
15107- !dopt->binary_upgrade))
15096+ else if (!(tbinfo->reloftype && !dopt->binary_upgrade))
1510815097 {
1510915098 /*
15110- * We must have a parenthesized attribute list, even though
15111- * empty, when not using the OF TYPE or PARTITION OF syntax.
15099+ * No attributes? we must have a parenthesized attribute list,
15100+ * even though empty, when not using the OF TYPE syntax.
1511215101 */
1511315102 appendPQExpBufferStr(q, " (\n)");
1511415103 }
1511515104
15116- if (tbinfo->ispartition && !dopt->binary_upgrade)
15117- {
15118- appendPQExpBufferStr(q, "\n");
15119- appendPQExpBufferStr(q, tbinfo->partbound);
15120- }
15121-
15122- /* Emit the INHERITS clause, except if this is a partition. */
15123- if (numParents > 0 &&
15124- !tbinfo->ispartition &&
15105+ /*
15106+ * Emit the INHERITS clause (not for partitions), except in
15107+ * binary-upgrade mode.
15108+ */
15109+ if (numParents > 0 && !tbinfo->ispartition &&
1512515110 !dopt->binary_upgrade)
1512615111 {
1512715112 appendPQExpBufferStr(q, "\nINHERITS (");
@@ -15249,11 +15234,17 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1524915234 }
1525015235 }
1525115236
15237+ /*
15238+ * Add inherited CHECK constraints, if any.
15239+ *
15240+ * For partitions, they were already dumped, and conislocal
15241+ * doesn't need fixing.
15242+ */
1525215243 for (k = 0; k < tbinfo->ncheck; k++)
1525315244 {
1525415245 ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
1525515246
15256- if (constr->separate || constr->conislocal)
15247+ if (constr->separate || constr->conislocal || tbinfo->ispartition )
1525715248 continue;
1525815249
1525915250 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraint.\n");
@@ -15271,30 +15262,16 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1527115262 appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
1527215263 }
1527315264
15274- if (numParents > 0)
15265+ if (numParents > 0 && !tbinfo->ispartition )
1527515266 {
15276- appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance and partitioning this way.\n");
15267+ appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance this way.\n");
1527715268 for (k = 0; k < numParents; k++)
1527815269 {
1527915270 TableInfo *parentRel = parents[k];
1528015271
15281- /* In the partitioning case, we alter the parent */
15282- if (tbinfo->ispartition)
15283- appendPQExpBuffer(q,
15284- "ALTER TABLE ONLY %s ATTACH PARTITION ",
15285- fmtQualifiedDumpable(parentRel));
15286- else
15287- appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT ",
15288- qualrelname);
15289-
15290- /* Partition needs specifying the bounds */
15291- if (tbinfo->ispartition)
15292- appendPQExpBuffer(q, "%s %s;\n",
15293- qualrelname,
15294- tbinfo->partbound);
15295- else
15296- appendPQExpBuffer(q, "%s;\n",
15297- fmtQualifiedDumpable(parentRel));
15272+ appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT %s;\n",
15273+ qualrelname,
15274+ fmtQualifiedDumpable(parentRel));
1529815275 }
1529915276 }
1530015277
@@ -15307,6 +15284,27 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1530715284 }
1530815285 }
1530915286
15287+ /*
15288+ * For partitioned tables, emit the ATTACH PARTITION clause. Note
15289+ * that we always want to create partitions this way instead of using
15290+ * CREATE TABLE .. PARTITION OF, mainly to preserve a possible column
15291+ * layout discrepancy with the parent, but also to ensure it gets the
15292+ * correct tablespace setting if it differs from the parent's.
15293+ */
15294+ if (tbinfo->ispartition)
15295+ {
15296+ /* With partitions there can only be one parent */
15297+ if (tbinfo->numParents != 1)
15298+ exit_horribly(NULL, "invalid number of parents %d for table \"%s\"\n",
15299+ tbinfo->numParents, tbinfo->dobj.name);
15300+
15301+ /* Perform ALTER TABLE on the parent */
15302+ appendPQExpBuffer(q,
15303+ "ALTER TABLE ONLY %s ATTACH PARTITION %s %s;\n",
15304+ fmtQualifiedDumpable(parents[0]),
15305+ qualrelname, tbinfo->partbound);
15306+ }
15307+
1531015308 /*
1531115309 * In binary_upgrade mode, arrange to restore the old relfrozenxid and
1531215310 * relminmxid of all vacuumable relations. (While vacuum.c processes
0 commit comments