Re: Add SPLIT PARTITION/MERGE PARTITIONS commands

jian he <jian.universality@gmail.com>

From: jian he <jian.universality@gmail.com>
To: Dmitry Koval <d.koval@postgrespro.ru>
Cc: pgsql-hackers@lists.postgresql.org
Date: 2025-08-29T10:31:58Z
Lists: pgsql-hackers

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Adjust errcode in checkPartition()

  2. Fix usage of palloc() in MERGE/SPLIT PARTITION(s) code

  3. Implement ALTER TABLE ... SPLIT PARTITION ... command

  4. Implement ALTER TABLE ... MERGE PARTITIONS ... command

  5. Calculate agglevelsup correctly when Aggref contains a CTE.

  6. Use PqMsg_* macros in applyparallelworker.c.

  7. Restrict psql meta-commands in plain-text dumps.

  8. Ensure we have a snapshot when updating various system catalogs.

  9. Use specific collation where needed in new test

  10. Expand virtual generated columns in the planner

  11. Virtual generated columns

  12. Define PG_LOGICAL_DIR for path pg_logical/ in data folder

  13. Revert support for ALTER TABLE ... MERGE/SPLIT PARTITION(S) commands

  14. Avoid repeated table name lookups in createPartitionTable()

  15. Provide deterministic order for catalog queries in partition_split.sql

  16. Don't copy extended statistics during MERGE/SPLIT partition operations

  17. Fix the name collision detection in MERGE/SPLIT partition operations

  18. Fix regression tests conflict in 3ca43dbbb6

  19. Add permission check for MERGE/SPLIT partition operations

  20. Fix one more portability shortcoming in new test_pg_dump test.

  21. Inherit parent's AM for partition MERGE/SPLIT operations

  22. Add tab completion for partition MERGE/SPLIT operations

  23. Rename tables in tests of partition MERGE/SPLIT operations

  24. Make new partitions with parent's persistence during MERGE/SPLIT

  25. Document the way partition MERGE/SPLIT operations create new partitions

  26. Change the way ATExecMergePartitions() handles the name collision

  27. Grammar fixes for split/merge partitions code

  28. Checks for ALTER TABLE ... SPLIT/MERGE PARTITIONS ... commands

  29. Fix some grammer errors from error messages and codes comments

  30. Support TZ and OF format codes in to_timestamp().

  31. Support identity columns in partitioned tables

  32. Fix indentation in twophase.c

  33. Fix corner-case planner failure for MERGE.

  34. Doc: fix documentation example for bytea hex output format.

  35. Avoid repeated name lookups during table and index DDL.

Attachments

On Tue, Aug 26, 2025 at 4:05 PM Dmitry Koval <d.koval@postgrespro.ru> wrote:
>
> Hi!
> Thanks for the notes and patches!
>
hi.

ORDER BY regclass seems not stable, see
https://git.postgresql.org/cgit/postgresql.git/commit/?id=17bcf4f5450430f67b744c225566c9e0e6413e95
some of the SQL tests seem not necessary, so I refactored tests.

+static List *
+getAttributesList(Relation parent_rel)
+{
.....
+
+ for (parent_attno = 1; parent_attno <= modelDesc->natts;
+ parent_attno++)
+ {
....
+
+ /* Add to column list */
+ colList = lappend(colList, def);
+
+ /*
+ * Although we don't transfer the column's default/generation
+ * expression now, we need to mark it GENERATED if appropriate.
+ */
+ if (attribute->atthasdef && attribute->attgenerated)
+ def->generated = attribute->attgenerated;
+
+ def->storage = attribute->attstorage;
+
+ /* Likewise, copy compression if requested */
+ if (CompressionMethodIsValid(attribute->attcompression))
+ def->compression =
+ pstrdup(GetCompressionMethodName(attribute->attcompression));
+ else
+ def->compression = NULL;
+ }
+
+ return colList;

the last part seems intuitive?
"colList = lappend(colList, def);" should be at the end of the for loop?


+-- Indexname values should be 'tp_1_2_pkey' and 'tp_1_2_i_idx'.
+-- Not-null constraint name should be 'tp_1_2_i_not_null'.
+\d+ tp_1_2
+                          Table "partitions_merge_schema.tp_1_2"
+ Column |  Type   | Collation | Nullable | Default | Storage | Stats
target | Description
+--------+---------+-----------+----------+---------+---------+--------------+-------------
+ i      | integer |           | not null |         | plain   |              |
+Partition of: t FOR VALUES FROM (0) TO (2)
+Partition constraint: ((i IS NOT NULL) AND (i >= 0) AND (i < 2))
+Indexes:
+    "tp_1_2_pkey" PRIMARY KEY, btree (i)
+    "tp_1_2_i_idx" btree (i)
+Not-null constraints:
+    "t_i_not_null" NOT NULL "i" (inherited)
+
"-- Not-null constraint name should be 'tp_1_2_i_not_null'.
Comments conflict with the result.


+ /*
+ * We reject whole-row variables because the whole point of LIKE is
+ * that the new table's rowtype might later diverge from the parent's.
+ * So, while translation might be possible right now, it wouldn't be
+ * possible to guarantee it would work in future.
+ */
+ if (found_whole_row)
+ elog(ERROR, "Constraint \"%s\" contains a whole-row reference to
table \"%s\".",
+ ccname,
+ RelationGetRelationName(parent_rel));
the above comment needs change, since LIKE is not related to here.


+ foreach_ptr(NewConstraint, con, tab->constraints)
+ {
+ switch (con->contype)
+ {
+ case CONSTR_CHECK:
+
+ /*
+ * We already expanded virtual expression in
+ * createTableConstraints.
+ */
+ con->qualstate = ExecPrepareExpr((Expr *)
expand_generated_columns_in_expr(con->qual, newPartRel, 1), estate);
+ break;
here, we don't need expand_generated_columns_in_expr, the comment also
explained it.

the attached patch is the changes for the above comments.