PG18 - Normalize \d+ output in PG18 by filtering “Not-null constraints” blocks (#8183)

DESCRIPTION: Normalize \d+ output in PG18 by filtering “Not-null
constraints” blocks
fixes #8095 


**PR Description**
Postgres 18 started representing column `NOT NULL` as named constraints
in `pg_constraint`, and `psql \d+` now prints them under a `Not-null
constraints:` section. This caused extra diffs in our regression tests.

14e87ffa5c

This PR updates the normalization rules to strip those sections during
diff filtering by adding two regex rules:

* remove the `Not-null constraints:` header
* remove any indented constraint lines ending in `_not_null`
pull/8228/head
Mehmet YILMAZ 2025-10-02 13:48:27 +03:00 committed by GitHub
parent cec1848b13
commit d4dfdd765b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 315 additions and 193 deletions

View File

@ -473,25 +473,19 @@ SELECT create_distributed_table('color', 'color_id');
(1 row)
INSERT INTO color(color_name) VALUES ('Blue');
\d+ color
Table "generated_identities.color"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT pg_get_serial_sequence('color', 'color_id');
pg_get_serial_sequence
---------------------------------------------------------------------
color_id | bigint | | not null | generated always as identity | plain | |
color_name | character varying | | not null | | extended | |
Indexes:
"color_color_id_key" UNIQUE CONSTRAINT, btree (color_id)
generated_identities.color_color_id_seq
(1 row)
\c - - - :worker_1_port
SET search_path TO generated_identities;
\d+ color
Table "generated_identities.color"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT pg_get_serial_sequence('color', 'color_id');
pg_get_serial_sequence
---------------------------------------------------------------------
color_id | bigint | | not null | generated always as identity | plain | |
color_name | character varying | | not null | | extended | |
Indexes:
"color_color_id_key" UNIQUE CONSTRAINT, btree (color_id)
generated_identities.color_color_id_seq
(1 row)
INSERT INTO color(color_name) VALUES ('Red');
-- alter sequence .. restart

View File

@ -118,15 +118,17 @@ SELECT generate_alter_table_attach_partition_command('date_partition_2007');
(1 row)
-- detach and attach the partition by the command generated by us
\d+ date_partitioned_table
Partitioned table "public.date_partitioned_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'date_partitioned_table';
partition_name | partition_bound
---------------------------------------------------------------------
id | integer | | | | plain | |
time | date | | | | plain | |
Partition key: RANGE ("time")
Partitions: date_partition_2006 FOR VALUES FROM ('01-01-2006') TO ('01-01-2007'),
date_partition_2007 FOR VALUES FROM ('01-01-2007') TO ('01-01-2008')
date_partition_2006 | FOR VALUES FROM ('01-01-2006') TO ('01-01-2007')
date_partition_2007 | FOR VALUES FROM ('01-01-2007') TO ('01-01-2008')
(2 rows)
SELECT detach_and_attach_partition('date_partition_2007', 'date_partitioned_table');
detach_and_attach_partition
@ -135,15 +137,17 @@ SELECT detach_and_attach_partition('date_partition_2007', 'date_partitioned_tabl
(1 row)
-- check that both partitions are visiable
\d+ date_partitioned_table
Partitioned table "public.date_partitioned_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'date_partitioned_table';
partition_name | partition_bound
---------------------------------------------------------------------
id | integer | | | | plain | |
time | date | | | | plain | |
Partition key: RANGE ("time")
Partitions: date_partition_2006 FOR VALUES FROM ('01-01-2006') TO ('01-01-2007'),
date_partition_2007 FOR VALUES FROM ('01-01-2007') TO ('01-01-2008')
date_partition_2006 | FOR VALUES FROM ('01-01-2006') TO ('01-01-2007')
date_partition_2007 | FOR VALUES FROM ('01-01-2007') TO ('01-01-2008')
(2 rows)
-- make sure that inter shard commands work as expected
-- assume that the shardId is 100
@ -159,14 +163,16 @@ SELECT worker_apply_inter_shard_ddl_command(referencing_shard:=100, referencing_
(1 row)
-- the hierarcy is successfully created
\d+ date_partitioned_table_100
Partitioned table "public.date_partitioned_table_100"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'date_partitioned_table_100';
partition_name | partition_bound
---------------------------------------------------------------------
id | integer | | | | plain | |
time | date | | | | plain | |
Partition key: RANGE ("time")
Partitions: date_partition_2007_100 FOR VALUES FROM ('01-01-2007') TO ('01-02-2008')
date_partition_2007_100 | FOR VALUES FROM ('01-01-2007') TO ('01-02-2008')
(1 row)
-- Citus can also get the DDL events for the partitions as regular tables
SELECT master_get_table_ddl_events('date_partition_2007_100');
@ -186,14 +192,15 @@ SELECT worker_apply_inter_shard_ddl_command(referencing_shard:=100, referencing_
(1 row)
-- the hierarcy is successfully broken
\d+ date_partitioned_table_100
Partitioned table "public.date_partitioned_table_100"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'date_partitioned_table_100';
partition_name | partition_bound
---------------------------------------------------------------------
id | integer | | | | plain | |
time | date | | | | plain | |
Partition key: RANGE ("time")
Number of partitions: 0
(0 rows)
-- now lets have some more complex partitioning hierarcies with
-- tables on different schemas and constraints on the tables
@ -242,15 +249,17 @@ SELECT public.generate_alter_table_attach_partition_command('child_2');
SET search_path = 'partition_parent_schema';
-- detach and attach the partition by the command generated by us
\d+ parent_table
Partitioned table "partition_parent_schema.parent_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'parent_table';
partition_name | partition_bound
---------------------------------------------------------------------
id | integer | | not null | | plain | |
time | date | | | now() | plain | |
Partition key: RANGE ("time")
Partitions: partition_child_1_schema.child_1 FOR VALUES FROM ('01-01-2009') TO ('01-02-2010'),
partition_child_2_schema.child_2 FOR VALUES FROM ('01-01-2006') TO ('01-01-2007')
child_1 | FOR VALUES FROM ('01-01-2009') TO ('01-02-2010')
child_2 | FOR VALUES FROM ('01-01-2006') TO ('01-01-2007')
(2 rows)
SELECT public.detach_and_attach_partition('partition_child_1_schema.child_1', 'parent_table');
detach_and_attach_partition
@ -259,15 +268,17 @@ SELECT public.detach_and_attach_partition('partition_child_1_schema.child_1', 'p
(1 row)
-- check that both partitions are visiable
\d+ parent_table
Partitioned table "partition_parent_schema.parent_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'parent_table';
partition_name | partition_bound
---------------------------------------------------------------------
id | integer | | not null | | plain | |
time | date | | | now() | plain | |
Partition key: RANGE ("time")
Partitions: partition_child_1_schema.child_1 FOR VALUES FROM ('01-01-2009') TO ('01-02-2010'),
partition_child_2_schema.child_2 FOR VALUES FROM ('01-01-2006') TO ('01-01-2007')
child_2 | FOR VALUES FROM ('01-01-2006') TO ('01-01-2007')
child_1 | FOR VALUES FROM ('01-01-2009') TO ('01-02-2010')
(2 rows)
-- some very simple checks that should error out
SELECT public.generate_alter_table_attach_partition_command('parent_table');

View File

@ -743,15 +743,17 @@ SELECT create_distributed_table('partitioned_table', 'a');
CREATE TABLE pt_2 PARTITION OF partitioned_table FOR VALUES FROM (50) TO (1000);
-- (1) The partitioned table has pt_1 and pt_2 as its partitions
\d+ partitioned_table;
Partitioned table "pg17.partitioned_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'partitioned_table';
partition_name | partition_bound
---------------------------------------------------------------------
a | bigint | | not null | generated by default as identity | plain | |
c | integer | | | | plain | |
Partition key: RANGE (c)
Partitions: pt_1 FOR VALUES FROM (1) TO (50),
pt_2 FOR VALUES FROM (50) TO (1000)
pt_1 | FOR VALUES FROM (1) TO (50)
pt_2 | FOR VALUES FROM (50) TO (1000)
(2 rows)
-- (2) The partitions have the same identity column as the parent table;
-- This is PG17 behavior for support for identity in partitioned tables.
@ -774,16 +776,18 @@ Partition of: partitioned_table FOR VALUES FROM (50) TO (1000)
-- Attaching a partition inherits the identity column from the parent table
CREATE TABLE pt_3 (a bigint not null, c int);
ALTER TABLE partitioned_table ATTACH PARTITION pt_3 FOR VALUES FROM (1000) TO (2000);
\d+ partitioned_table;
Partitioned table "pg17.partitioned_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'partitioned_table';
partition_name | partition_bound
---------------------------------------------------------------------
a | bigint | | not null | generated by default as identity | plain | |
c | integer | | | | plain | |
Partition key: RANGE (c)
Partitions: pt_1 FOR VALUES FROM (1) TO (50),
pt_2 FOR VALUES FROM (50) TO (1000),
pt_3 FOR VALUES FROM (1000) TO (2000)
pt_1 | FOR VALUES FROM (1) TO (50)
pt_2 | FOR VALUES FROM (50) TO (1000)
pt_3 | FOR VALUES FROM (1000) TO (2000)
(3 rows)
\d pt_3;
Table "pg17.pt_3"
@ -803,16 +807,18 @@ DETAIL: The new partition may not contain an identity column.
SET search_path TO pg17;
-- Show that DDL for partitioned_table has correctly propagated to the worker node;
-- (1) The partitioned table has pt_1, pt_2 and pt_3 as its partitions
\d+ partitioned_table;
Partitioned table "pg17.partitioned_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'partitioned_table';
partition_name | partition_bound
---------------------------------------------------------------------
a | bigint | | not null | generated by default as identity | plain | |
c | integer | | | | plain | |
Partition key: RANGE (c)
Partitions: pt_1 FOR VALUES FROM (1) TO (50),
pt_2 FOR VALUES FROM (50) TO (1000),
pt_3 FOR VALUES FROM (1000) TO (2000)
pt_1 | FOR VALUES FROM (1) TO (50)
pt_2 | FOR VALUES FROM (50) TO (1000)
pt_3 | FOR VALUES FROM (1000) TO (2000)
(3 rows)
-- (2) The partititions have the same identity column as the parent table
\d pt_1;
@ -845,15 +851,17 @@ SET search_path TO pg17;
ALTER TABLE partitioned_table DETACH PARTITION pt_3;
-- partitioned_table has pt_1, pt_2 as its partitions
-- and pt_3 does not have an identity column
\d+ partitioned_table;
Partitioned table "pg17.partitioned_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'partitioned_table';
partition_name | partition_bound
---------------------------------------------------------------------
a | bigint | | not null | generated by default as identity | plain | |
c | integer | | | | plain | |
Partition key: RANGE (c)
Partitions: pt_1 FOR VALUES FROM (1) TO (50),
pt_2 FOR VALUES FROM (50) TO (1000)
pt_1 | FOR VALUES FROM (1) TO (50)
pt_2 | FOR VALUES FROM (50) TO (1000)
(2 rows)
\d pt_3;
Table "pg17.pt_3"
@ -865,15 +873,17 @@ Partitions: pt_1 FOR VALUES FROM (1) TO (50),
-- Verify that the detach has propagated to the worker node
\c - - - :worker_1_port
SET search_path TO pg17;
\d+ partitioned_table;
Partitioned table "pg17.partitioned_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'partitioned_table';
partition_name | partition_bound
---------------------------------------------------------------------
a | bigint | | not null | generated by default as identity | plain | |
c | integer | | | | plain | |
Partition key: RANGE (c)
Partitions: pt_1 FOR VALUES FROM (1) TO (50),
pt_2 FOR VALUES FROM (50) TO (1000)
pt_1 | FOR VALUES FROM (1) TO (50)
pt_2 | FOR VALUES FROM (50) TO (1000)
(2 rows)
\d pt_3;
Table "pg17.pt_3"
@ -903,16 +913,17 @@ ALTER TABLE alt_test ALTER COLUMN a SET GENERATED BY DEFAULT SET INCREMENT BY 2
ERROR: alter table command is currently unsupported
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP|VALIDATE CONSTRAINT, SET (), RESET (), ENABLE|DISABLE|NO FORCE|FORCE ROW LEVEL SECURITY, ATTACH|DETACH PARTITION and TYPE subcommands are supported.
-- Verify that the identity column was not added, on coordinator and worker nodes
\d+ alt_test;
Partitioned table "pg17.alt_test"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'alt_test';
partition_name | partition_bound
---------------------------------------------------------------------
a | integer | | | | plain | |
b | date | | | | plain | |
c | integer | | | | plain | |
Partition key: RANGE (c)
Partitions: alt_test_pt_1 FOR VALUES FROM (1) TO (50),
alt_test_pt_2 FOR VALUES FROM (50) TO (100)
alt_test_pt_1 | FOR VALUES FROM (1) TO (50)
alt_test_pt_2 | FOR VALUES FROM (50) TO (100)
(2 rows)
\d alt_test_pt_1;
Table "pg17.alt_test_pt_1"
@ -934,16 +945,17 @@ Partition of: alt_test FOR VALUES FROM (50) TO (100)
\c - - - :worker_1_port
SET search_path TO pg17;
\d+ alt_test;
Partitioned table "pg17.alt_test"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'alt_test';
partition_name | partition_bound
---------------------------------------------------------------------
a | integer | | | | plain | |
b | date | | | | plain | |
c | integer | | | | plain | |
Partition key: RANGE (c)
Partitions: alt_test_pt_1 FOR VALUES FROM (1) TO (50),
alt_test_pt_2 FOR VALUES FROM (50) TO (100)
alt_test_pt_1 | FOR VALUES FROM (1) TO (50)
alt_test_pt_2 | FOR VALUES FROM (50) TO (100)
(2 rows)
\d alt_test_pt_1;
Table "pg17.alt_test_pt_1"
@ -984,16 +996,17 @@ ALTER TABLE alt_test ALTER COLUMN a DROP IDENTITY;
ERROR: alter table command is currently unsupported
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP|VALIDATE CONSTRAINT, SET (), RESET (), ENABLE|DISABLE|NO FORCE|FORCE ROW LEVEL SECURITY, ATTACH|DETACH PARTITION and TYPE subcommands are supported.
-- Verify that alt_test still has identity on column a
\d+ alt_test;
Partitioned table "pg17.alt_test"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'alt_test';
partition_name | partition_bound
---------------------------------------------------------------------
a | bigint | | not null | generated by default as identity | plain | |
b | integer | | | | plain | |
c | integer | | | | plain | |
Partition key: RANGE (c)
Partitions: alt_test_pt_1 FOR VALUES FROM (1) TO (50),
alt_test_pt_2 FOR VALUES FROM (50) TO (100)
alt_test_pt_1 | FOR VALUES FROM (1) TO (50)
alt_test_pt_2 | FOR VALUES FROM (50) TO (100)
(2 rows)
\d alt_test_pt_1;
Table "pg17.alt_test_pt_1"
@ -1015,16 +1028,17 @@ Partition of: alt_test FOR VALUES FROM (50) TO (100)
\c - - - :worker_1_port
SET search_path TO pg17;
\d+ alt_test;
Partitioned table "pg17.alt_test"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'alt_test';
partition_name | partition_bound
---------------------------------------------------------------------
a | bigint | | not null | generated by default as identity | plain | |
b | integer | | | | plain | |
c | integer | | | | plain | |
Partition key: RANGE (c)
Partitions: alt_test_pt_1 FOR VALUES FROM (1) TO (50),
alt_test_pt_2 FOR VALUES FROM (50) TO (100)
alt_test_pt_1 | FOR VALUES FROM (1) TO (50)
alt_test_pt_2 | FOR VALUES FROM (50) TO (100)
(2 rows)
\d alt_test_pt_1;
Table "pg17.alt_test_pt_1"
@ -1064,16 +1078,18 @@ CREATE TABLE lpt_2 PARTITION OF local_partitioned_table FOR VALUES FROM (50) TO
CREATE TABLE lpt_3 (a bigint not null, c int);
ALTER TABLE local_partitioned_table ATTACH PARTITION lpt_3 FOR VALUES FROM (1000) TO (2000);
-- The partitions have the same identity column as the parent table, on coordinator and worker nodes
\d+ local_partitioned_table;
Partitioned table "pg17.local_partitioned_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'local_partitioned_table';
partition_name | partition_bound
---------------------------------------------------------------------
a | bigint | | not null | generated by default as identity | plain | |
c | integer | | | | plain | |
Partition key: RANGE (c)
Partitions: lpt_1 FOR VALUES FROM (1) TO (50),
lpt_2 FOR VALUES FROM (50) TO (1000),
lpt_3 FOR VALUES FROM (1000) TO (2000)
lpt_1 | FOR VALUES FROM (1) TO (50)
lpt_2 | FOR VALUES FROM (50) TO (1000)
lpt_3 | FOR VALUES FROM (1000) TO (2000)
(3 rows)
\d lpt_1;
Table "pg17.lpt_1"
@ -1101,16 +1117,18 @@ Partition of: local_partitioned_table FOR VALUES FROM (1000) TO (2000)
\c - - - :worker_1_port
SET search_path TO pg17;
\d+ local_partitioned_table;
Partitioned table "pg17.local_partitioned_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'local_partitioned_table';
partition_name | partition_bound
---------------------------------------------------------------------
a | bigint | | not null | generated by default as identity | plain | |
c | integer | | | | plain | |
Partition key: RANGE (c)
Partitions: lpt_1 FOR VALUES FROM (1) TO (50),
lpt_2 FOR VALUES FROM (50) TO (1000),
lpt_3 FOR VALUES FROM (1000) TO (2000)
lpt_1 | FOR VALUES FROM (1) TO (50)
lpt_2 | FOR VALUES FROM (50) TO (1000)
lpt_3 | FOR VALUES FROM (1000) TO (2000)
(3 rows)
\d lpt_1;
Table "pg17.lpt_1"
@ -1140,15 +1158,17 @@ Partition of: local_partitioned_table FOR VALUES FROM (1000) TO (2000)
SET search_path TO pg17;
-- Test detaching a partition with an identity column from a citus local table
ALTER TABLE local_partitioned_table DETACH PARTITION lpt_3;
\d+ local_partitioned_table;
Partitioned table "pg17.local_partitioned_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'local_partitioned_table';
partition_name | partition_bound
---------------------------------------------------------------------
a | bigint | | not null | generated by default as identity | plain | |
c | integer | | | | plain | |
Partition key: RANGE (c)
Partitions: lpt_1 FOR VALUES FROM (1) TO (50),
lpt_2 FOR VALUES FROM (50) TO (1000)
lpt_1 | FOR VALUES FROM (1) TO (50)
lpt_2 | FOR VALUES FROM (50) TO (1000)
(2 rows)
\d lpt_3;
Table "pg17.lpt_3"
@ -1159,15 +1179,17 @@ Partitions: lpt_1 FOR VALUES FROM (1) TO (50),
\c - - - :worker_1_port
SET search_path TO pg17;
\d+ local_partitioned_table;
Partitioned table "pg17.local_partitioned_table"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'local_partitioned_table';
partition_name | partition_bound
---------------------------------------------------------------------
a | bigint | | not null | generated by default as identity | plain | |
c | integer | | | | plain | |
Partition key: RANGE (c)
Partitions: lpt_1 FOR VALUES FROM (1) TO (50),
lpt_2 FOR VALUES FROM (50) TO (1000)
lpt_1 | FOR VALUES FROM (1) TO (50)
lpt_2 | FOR VALUES FROM (50) TO (1000)
(2 rows)
\d lpt_3;
Table "pg17.lpt_3"

View File

@ -242,11 +242,11 @@ CREATE TABLE color (
) USING columnar;
SELECT create_distributed_table('color', 'color_id');
INSERT INTO color(color_name) VALUES ('Blue');
\d+ color
SELECT pg_get_serial_sequence('color', 'color_id');
\c - - - :worker_1_port
SET search_path TO generated_identities;
\d+ color
SELECT pg_get_serial_sequence('color', 'color_id');
INSERT INTO color(color_name) VALUES ('Red');
-- alter sequence .. restart
ALTER SEQUENCE color_color_id_seq RESTART WITH 1000;

View File

@ -102,12 +102,22 @@ SELECT generate_alter_table_attach_partition_command('date_partition_2006');
SELECT generate_alter_table_attach_partition_command('date_partition_2007');
-- detach and attach the partition by the command generated by us
\d+ date_partitioned_table
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'date_partitioned_table';
SELECT detach_and_attach_partition('date_partition_2007', 'date_partitioned_table');
-- check that both partitions are visiable
\d+ date_partitioned_table
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'date_partitioned_table';
-- make sure that inter shard commands work as expected
@ -121,7 +131,12 @@ SELECT worker_apply_inter_shard_ddl_command(referencing_shard:=100, referencing_
command:='ALTER TABLE date_partitioned_table ATTACH PARTITION date_partition_2007 FOR VALUES FROM (''2007-01-01'') TO (''2008-01-02'')' );
-- the hierarcy is successfully created
\d+ date_partitioned_table_100
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'date_partitioned_table_100';
-- Citus can also get the DDL events for the partitions as regular tables
SELECT master_get_table_ddl_events('date_partition_2007_100');
@ -132,7 +147,12 @@ SELECT worker_apply_inter_shard_ddl_command(referencing_shard:=100, referencing_
command:='ALTER TABLE date_partitioned_table DETACH PARTITION date_partition_2007' );
-- the hierarcy is successfully broken
\d+ date_partitioned_table_100
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'date_partitioned_table_100';
-- now lets have some more complex partitioning hierarcies with
-- tables on different schemas and constraints on the tables
@ -171,12 +191,22 @@ SELECT public.generate_alter_table_attach_partition_command('child_2');
SET search_path = 'partition_parent_schema';
-- detach and attach the partition by the command generated by us
\d+ parent_table
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'parent_table';
SELECT public.detach_and_attach_partition('partition_child_1_schema.child_1', 'parent_table');
-- check that both partitions are visiable
\d+ parent_table
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'parent_table';
-- some very simple checks that should error out
SELECT public.generate_alter_table_attach_partition_command('parent_table');

View File

@ -449,7 +449,12 @@ SELECT create_distributed_table('partitioned_table', 'a');
CREATE TABLE pt_2 PARTITION OF partitioned_table FOR VALUES FROM (50) TO (1000);
-- (1) The partitioned table has pt_1 and pt_2 as its partitions
\d+ partitioned_table;
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'partitioned_table';
-- (2) The partitions have the same identity column as the parent table;
-- This is PG17 behavior for support for identity in partitioned tables.
@ -460,7 +465,12 @@ CREATE TABLE pt_2 PARTITION OF partitioned_table FOR VALUES FROM (50) TO (1000);
CREATE TABLE pt_3 (a bigint not null, c int);
ALTER TABLE partitioned_table ATTACH PARTITION pt_3 FOR VALUES FROM (1000) TO (2000);
\d+ partitioned_table;
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'partitioned_table';
\d pt_3;
-- Partition pt_4 has its own identity column, which is not allowed in PG17
@ -473,7 +483,12 @@ ALTER TABLE partitioned_table ATTACH PARTITION pt_4 FOR VALUES FROM (2000) TO (3
SET search_path TO pg17;
-- Show that DDL for partitioned_table has correctly propagated to the worker node;
-- (1) The partitioned table has pt_1, pt_2 and pt_3 as its partitions
\d+ partitioned_table;
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'partitioned_table';
-- (2) The partititions have the same identity column as the parent table
\d pt_1;
@ -488,14 +503,24 @@ ALTER TABLE partitioned_table DETACH PARTITION pt_3;
-- partitioned_table has pt_1, pt_2 as its partitions
-- and pt_3 does not have an identity column
\d+ partitioned_table;
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'partitioned_table';
\d pt_3;
-- Verify that the detach has propagated to the worker node
\c - - - :worker_1_port
SET search_path TO pg17;
\d+ partitioned_table;
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'partitioned_table';
\d pt_3;
\c - - - :master_port
@ -516,14 +541,24 @@ ALTER TABLE alt_test ADD COLUMN d bigint GENERATED BY DEFAULT AS IDENTITY (START
ALTER TABLE alt_test ALTER COLUMN a SET GENERATED BY DEFAULT SET INCREMENT BY 2 SET START WITH 75 RESTART;
-- Verify that the identity column was not added, on coordinator and worker nodes
\d+ alt_test;
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'alt_test';
\d alt_test_pt_1;
\d alt_test_pt_2;
\c - - - :worker_1_port
SET search_path TO pg17;
\d+ alt_test;
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'alt_test';
\d alt_test_pt_1;
\d alt_test_pt_2;
@ -545,14 +580,24 @@ CREATE TABLE alt_test_pt_2 PARTITION OF alt_test FOR VALUES FROM (50) TO (100);
ALTER TABLE alt_test ALTER COLUMN a DROP IDENTITY;
-- Verify that alt_test still has identity on column a
\d+ alt_test;
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'alt_test';
\d alt_test_pt_1;
\d alt_test_pt_2;
\c - - - :worker_1_port
SET search_path TO pg17;
\d+ alt_test;
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'alt_test';
\d alt_test_pt_1;
\d alt_test_pt_2
@ -577,7 +622,12 @@ CREATE TABLE lpt_3 (a bigint not null, c int);
ALTER TABLE local_partitioned_table ATTACH PARTITION lpt_3 FOR VALUES FROM (1000) TO (2000);
-- The partitions have the same identity column as the parent table, on coordinator and worker nodes
\d+ local_partitioned_table;
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'local_partitioned_table';
\d lpt_1;
\d lpt_2;
\d lpt_3;
@ -585,7 +635,12 @@ ALTER TABLE local_partitioned_table ATTACH PARTITION lpt_3 FOR VALUES FROM (1000
\c - - - :worker_1_port
SET search_path TO pg17;
\d+ local_partitioned_table;
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'local_partitioned_table';
\d lpt_1;
\d lpt_2;
\d lpt_3;
@ -596,13 +651,23 @@ SET search_path TO pg17;
-- Test detaching a partition with an identity column from a citus local table
ALTER TABLE local_partitioned_table DETACH PARTITION lpt_3;
\d+ local_partitioned_table;
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'local_partitioned_table';
\d lpt_3;
\c - - - :worker_1_port
SET search_path TO pg17;
\d+ local_partitioned_table;
SELECT child.relname AS partition_name,
pg_get_expr(child.relpartbound, child.oid) AS partition_bound
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
WHERE parent.relname = 'local_partitioned_table';
\d lpt_3;
\c - - - :master_port