Re: [PATCH] no table rewrite when set column type to constrained domain

From: jian he <jian(dot)universality(at)gmail(dot)com>
To: solai v <solai(dot)cdac(at)gmail(dot)com>
Cc: Viktor Holmberg <v(at)viktorh(dot)net>, Aditya Gollamudi <adigollamudi(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: [PATCH] no table rewrite when set column type to constrained domain
Date: 2026-07-09 02:15:20
Message-ID: CACJufxGtwwJyTnSgkMHdwnhsNdXi1mi0baa2J0PjnX9+dDnQnA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu, May 14, 2026 at 5:18 PM solai v <solai(dot)cdac(at)gmail(dot)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/

Attachment Content-Type Size
v7-0001-Skipping-table-rewrites-for-changing-column-types-in-some-cases.patch text/x-patch 24.3 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Fujii Masao 2026-07-09 02:24:31 Fix data checksum processing for temp relations and dropped databases
Previous Message Peter Smith 2026-07-09 01:36:34 Re: Include sequences in publications created by pg_createsubscriber