Hi.

Reproducer:

drop table if exists t;
CREATE TABLE t (
  a int,
  b int GENERATED ALWAYS AS (NULLIF(a, 1)) STORED NOT NULL,
  constraint cc check (b > 0)) PARTITION BY RANGE (a);
CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (10) TO (20);
ALTER TABLE tp_0_1 ALTER COLUMN b SET EXPRESSION AS (a);

-- expect two row, now nothing
select conname, contype from pg_constraint where conrelid = 'tp_0_1'::regclass;

This issue has existed since PG17.

ATPostAlterTypeCleanup only generates the ALTER TABLE ADD CONSTRAINT command for
the root (parent) table, not for the partitions themselves.
For a partition table, it only drops the old constraint without
rebuilding it: because a partition's pg_constraint.conislocal is false.

See the comments in ATPostAlterTypeCleanup below:
        /*
         * If the constraint is inherited (only), we don't want to inject a
         * new definition here; it'll get recreated when
         * ATAddCheckNNConstraint recurses from adding the parent table's
         * constraint.  But we had to carry the info this far so that we can
         * drop the constraint below.
         */

I don't have a clear idea how to solve this issue other than by erroring out.
It seems non-trivial to drop an inherited constraint, recreate it and
correctly integrate it into the constraint inheritance hierarchy.
I checked src/test/regress/sql/generated_stored.sql, no related tests for it.



--
jian
https://www.enterprisedb.com/


Reply via email to