@@ -8631,9 +8631,12 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
8631
8631
* Normally this is always true, but it's false for dropped columns, as well
8632
8632
* as those that were inherited without any local definition. (If we print
8633
8633
* such a column it will mistakenly get pg_attribute.attislocal set to true.)
8634
- * However, in binary_upgrade mode, we must print all such columns anyway and
8635
- * fix the attislocal/attisdropped state later, so as to keep control of the
8636
- * physical column order.
8634
+ * For partitions, it's always true, because we want the partitions to be
8635
+ * created independently and ATTACH PARTITION used afterwards.
8636
+ *
8637
+ * In binary_upgrade mode, we must print all columns and fix the attislocal/
8638
+ * attisdropped state later, so as to keep control of the physical column
8639
+ * order.
8637
8640
*
8638
8641
* This function exists because there are scattered nonobvious places that
8639
8642
* must be kept in sync with this decision.
@@ -8643,7 +8646,9 @@ shouldPrintColumn(DumpOptions *dopt, TableInfo *tbinfo, int colno)
8643
8646
{
8644
8647
if (dopt->binary_upgrade)
8645
8648
return true;
8646
- return (tbinfo->attislocal[colno] && !tbinfo->attisdropped[colno]);
8649
+ if (tbinfo->attisdropped[colno])
8650
+ return false;
8651
+ return (tbinfo->attislocal[colno] || tbinfo->ispartition);
8647
8652
}
8648
8653
8649
8654
@@ -15594,27 +15599,6 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
15594
15599
if (tbinfo->reloftype && !dopt->binary_upgrade)
15595
15600
appendPQExpBuffer(q, " OF %s", tbinfo->reloftype);
15596
15601
15597
- /*
15598
- * If the table is a partition, dump it as such; except in the case of
15599
- * a binary upgrade, we dump the table normally and attach it to the
15600
- * parent afterward.
15601
- */
15602
- if (tbinfo->ispartition && !dopt->binary_upgrade)
15603
- {
15604
- TableInfo *parentRel = tbinfo->parents[0];
15605
-
15606
- /*
15607
- * With partitions, unlike inheritance, there can only be one
15608
- * parent.
15609
- */
15610
- if (tbinfo->numParents != 1)
15611
- fatal("invalid number of parents %d for table \"%s\"",
15612
- tbinfo->numParents, tbinfo->dobj.name);
15613
-
15614
- appendPQExpBuffer(q, " PARTITION OF %s",
15615
- fmtQualifiedDumpable(parentRel));
15616
- }
15617
-
15618
15602
if (tbinfo->relkind != RELKIND_MATVIEW)
15619
15603
{
15620
15604
/* Dump the attributes */
@@ -15629,26 +15613,30 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
15629
15613
*/
15630
15614
if (shouldPrintColumn(dopt, tbinfo, j))
15631
15615
{
15616
+ bool print_default;
15617
+ bool print_notnull;
15618
+
15632
15619
/*
15633
15620
* Default value --- suppress if to be printed separately.
15634
15621
*/
15635
- bool has_default = (tbinfo->attrdefs[j] != NULL &&
15636
- !tbinfo->attrdefs[j]->separate);
15622
+ print_default = (tbinfo->attrdefs[j] != NULL &&
15623
+ !tbinfo->attrdefs[j]->separate);
15637
15624
15638
15625
/*
15639
15626
* Not Null constraint --- suppress if inherited, except
15640
- * in binary-upgrade case where that won't work.
15627
+ * if partition, or in binary-upgrade case where that
15628
+ * won't work.
15641
15629
*/
15642
- bool has_notnull = (tbinfo->notnull[j] &&
15643
- (!tbinfo->inhNotNull[j] ||
15644
- dopt->binary_upgrade));
15630
+ print_notnull = (tbinfo->notnull[j] &&
15631
+ (!tbinfo->inhNotNull[j] ||
15632
+ tbinfo->ispartition || dopt->binary_upgrade));
15645
15633
15646
15634
/*
15647
- * Skip column if fully defined by reloftype or the
15648
- * partition parent.
15635
+ * Skip column if fully defined by reloftype, except in
15636
+ * binary upgrade
15649
15637
*/
15650
- if (( tbinfo->reloftype || tbinfo->ispartition) &&
15651
- !has_default && !has_notnull && ! dopt->binary_upgrade)
15638
+ if (tbinfo->reloftype && !print_default && !print_notnull &&
15639
+ !dopt->binary_upgrade)
15652
15640
continue;
15653
15641
15654
15642
/* Format properly if not first attr */
@@ -15671,26 +15659,22 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
15671
15659
* clean things up later.
15672
15660
*/
15673
15661
appendPQExpBufferStr(q, " INTEGER /* dummy */");
15674
- /* Skip all the rest, too */
15662
+ /* and skip to the next column */
15675
15663
continue;
15676
15664
}
15677
15665
15678
15666
/*
15679
- * Attribute type
15680
- *
15681
- * In binary-upgrade mode, we always include the type. If
15682
- * we aren't in binary-upgrade mode, then we skip the type
15683
- * when creating a typed table ('OF type_name') or a
15684
- * partition ('PARTITION OF'), since the type comes from
15685
- * the parent/partitioned table.
15667
+ * Attribute type; print it except when creating a typed
15668
+ * table ('OF type_name'), but in binary-upgrade mode,
15669
+ * print it in that case too.
15686
15670
*/
15687
- if (dopt->binary_upgrade || ( !tbinfo->reloftype && !tbinfo->ispartition) )
15671
+ if (dopt->binary_upgrade || !tbinfo->reloftype)
15688
15672
{
15689
15673
appendPQExpBuffer(q, " %s",
15690
15674
tbinfo->atttypnames[j]);
15691
15675
}
15692
15676
15693
- if (has_default )
15677
+ if (print_default )
15694
15678
{
15695
15679
if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_STORED)
15696
15680
appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s) STORED",
@@ -15701,7 +15685,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
15701
15685
}
15702
15686
15703
15687
15704
- if (has_notnull )
15688
+ if (print_notnull )
15705
15689
appendPQExpBufferStr(q, " NOT NULL");
15706
15690
15707
15691
/* Add collation if not default for the type */
@@ -15719,12 +15703,18 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
15719
15703
15720
15704
/*
15721
15705
* Add non-inherited CHECK constraints, if any.
15706
+ *
15707
+ * For partitions, we need to include check constraints even if
15708
+ * they're not defined locally, because the ALTER TABLE ATTACH
15709
+ * PARTITION that we'll emit later expects the constraint to be
15710
+ * there. (No need to fix conislocal: ATTACH PARTITION does that)
15722
15711
*/
15723
15712
for (j = 0; j < tbinfo->ncheck; j++)
15724
15713
{
15725
15714
ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
15726
15715
15727
- if (constr->separate || !constr->conislocal)
15716
+ if (constr->separate ||
15717
+ (!constr->conislocal && !tbinfo->ispartition))
15728
15718
continue;
15729
15719
15730
15720
if (actual_atts == 0)
@@ -15741,25 +15731,20 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
15741
15731
15742
15732
if (actual_atts)
15743
15733
appendPQExpBufferStr(q, "\n)");
15744
- else if (!((tbinfo->reloftype || tbinfo->ispartition) &&
15745
- !dopt->binary_upgrade))
15734
+ else if (!(tbinfo->reloftype && !dopt->binary_upgrade))
15746
15735
{
15747
15736
/*
15748
- * We must have a parenthesized attribute list, even though
15749
- * empty, when not using the OF TYPE or PARTITION OF syntax.
15737
+ * No attributes? we must have a parenthesized attribute list,
15738
+ * even though empty, when not using the OF TYPE syntax.
15750
15739
*/
15751
15740
appendPQExpBufferStr(q, " (\n)");
15752
15741
}
15753
15742
15754
- if (tbinfo->ispartition && !dopt->binary_upgrade)
15755
- {
15756
- appendPQExpBufferChar(q, '\n');
15757
- appendPQExpBufferStr(q, tbinfo->partbound);
15758
- }
15759
-
15760
- /* Emit the INHERITS clause, except if this is a partition. */
15761
- if (numParents > 0 &&
15762
- !tbinfo->ispartition &&
15743
+ /*
15744
+ * Emit the INHERITS clause (not for partitions), except in
15745
+ * binary-upgrade mode.
15746
+ */
15747
+ if (numParents > 0 && !tbinfo->ispartition &&
15763
15748
!dopt->binary_upgrade)
15764
15749
{
15765
15750
appendPQExpBufferStr(q, "\nINHERITS (");
@@ -15910,11 +15895,17 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
15910
15895
}
15911
15896
}
15912
15897
15898
+ /*
15899
+ * Add inherited CHECK constraints, if any.
15900
+ *
15901
+ * For partitions, they were already dumped, and conislocal
15902
+ * doesn't need fixing.
15903
+ */
15913
15904
for (k = 0; k < tbinfo->ncheck; k++)
15914
15905
{
15915
15906
ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
15916
15907
15917
- if (constr->separate || constr->conislocal)
15908
+ if (constr->separate || constr->conislocal || tbinfo->ispartition )
15918
15909
continue;
15919
15910
15920
15911
appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraint.\n");
@@ -15932,30 +15923,16 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
15932
15923
appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
15933
15924
}
15934
15925
15935
- if (numParents > 0)
15926
+ if (numParents > 0 && !tbinfo->ispartition )
15936
15927
{
15937
- appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance and partitioning this way.\n");
15928
+ appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance this way.\n");
15938
15929
for (k = 0; k < numParents; k++)
15939
15930
{
15940
15931
TableInfo *parentRel = parents[k];
15941
15932
15942
- /* In the partitioning case, we alter the parent */
15943
- if (tbinfo->ispartition)
15944
- appendPQExpBuffer(q,
15945
- "ALTER TABLE ONLY %s ATTACH PARTITION ",
15946
- fmtQualifiedDumpable(parentRel));
15947
- else
15948
- appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT ",
15949
- qualrelname);
15950
-
15951
- /* Partition needs specifying the bounds */
15952
- if (tbinfo->ispartition)
15953
- appendPQExpBuffer(q, "%s %s;\n",
15954
- qualrelname,
15955
- tbinfo->partbound);
15956
- else
15957
- appendPQExpBuffer(q, "%s;\n",
15958
- fmtQualifiedDumpable(parentRel));
15933
+ appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT %s;\n",
15934
+ qualrelname,
15935
+ fmtQualifiedDumpable(parentRel));
15959
15936
}
15960
15937
}
15961
15938
@@ -15968,6 +15945,27 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
15968
15945
}
15969
15946
}
15970
15947
15948
+ /*
15949
+ * For partitioned tables, emit the ATTACH PARTITION clause. Note
15950
+ * that we always want to create partitions this way instead of using
15951
+ * CREATE TABLE .. PARTITION OF, mainly to preserve a possible column
15952
+ * layout discrepancy with the parent, but also to ensure it gets the
15953
+ * correct tablespace setting if it differs from the parent's.
15954
+ */
15955
+ if (tbinfo->ispartition)
15956
+ {
15957
+ /* With partitions there can only be one parent */
15958
+ if (tbinfo->numParents != 1)
15959
+ fatal("invalid number of parents %d for table \"%s\"",
15960
+ tbinfo->numParents, tbinfo->dobj.name);
15961
+
15962
+ /* Perform ALTER TABLE on the parent */
15963
+ appendPQExpBuffer(q,
15964
+ "ALTER TABLE ONLY %s ATTACH PARTITION %s %s;\n",
15965
+ fmtQualifiedDumpable(parents[0]),
15966
+ qualrelname, tbinfo->partbound);
15967
+ }
15968
+
15971
15969
/*
15972
15970
* In binary_upgrade mode, arrange to restore the old relfrozenxid and
15973
15971
* relminmxid of all vacuumable relations. (While vacuum.c processes
0 commit comments