On Thu, May 14, 2026 at 5:18 PM solai v <solai.cdac@gmail.com> wrote:
>
> Hi,
> I tested the latest v6 patch on current master with a few different
> scenarios.For the simple int to constrained-domain type change
> case,the scan-only patch was used and the relfilenode stayed unchanged
> before and after ALTER TABLE ,so the rewrite was avoided as expected.
> I also tried USING expression cases,invalid domain values,and NULL
> values.The behavior looked correct in those cases as well.
> I tested with both small tables and a 1M row table.
>
Thanks for testing!
Actually this has a correctness issue. A domain check constraint
expression can be arbitrary, so it may have side effects.
``````
drop table if exists t22;
drop domain if exists d1;
create table t22(a int);
insert into t22 values (1), (2);
create or replace function domain_test() returns bool language plpgsql
as $$
begin
delete from t22;
return true;
end$$;
create domain d1 as int check (domain_test());
alter table t22 alter column a set data type d1;
table t22;
``````
The test above shows that the V6 patch in [1] produces results that differ from
master. Therefore, to skip the table rewrite when ALTER TABLE ... SET DATA
TYPE changes a column to a constrained domain, we need to be conservative and
ensure that:
A. The domain's direct base type is a built-in data type.
B. The domain's CHECK constraint contains only IMMUTABLE functions.
Implementing these checks adds extra complexity, but that's not unusual — for
example, we already limit virtual generated columns to built-in data types only.
That said, the benefit is limited: skip table rewrite for constrained domain
only covers constrained domains over built-in data types, not domain-over-domain
cases.
Is this worth it? Anyway, the attached patch implements this.
-----------------------------------------
The above means that commens below in function ATColumnChangeRequiresRewrite
is partially correct.
``````
* In the case of a constrained domain, we could get by with scanning the
* table and checking the constraint rather than actually rewriting it, but we
* don't currently try to do that.
``````
[1]: https://www.postgresql.org/message-id/CACJufxEwb8sViRHJ0zVTAo99R0avc9sW0tkysmHp7v5LT7F0yg@mail.gmail.com
--
jian
https://www.enterprisedb.com/