Re: adding a nullable column of type domain w/ check constraint runs checks?

Lists: pgsql-general
From: Joe Van Dyk <joe(at)tanga(dot)com>
To: "pgsql-general(at)postgresql(dot)org" <pgsql-general(at)postgresql(dot)org>
Subject: adding a nullable column of type domain w/ check constraint runs checks?
Date: 2014-08-19 22:10:53
Message-ID: CACfv+pJ2HATOBUoG2MkeA84wSpK5MWVxF9YvvREtBBm2JZeyUw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

I have a large table that I don't want to lock for more than couple
seconds. I want to add a nullable column to the table, the type of the
column is a domain with a check constraint.

It appears that the check constraint is being checked for each row, even
though the column can be nullable? Is there a way around this?

BEGIN
Timing is on.

create domain test_enum numeric check (value > 0);
CREATE DOMAIN
Time: 1.817 ms

create table test_enum_table (id serial primary key);
CREATE TABLE
Time: 2.213 ms

insert into test_enum_table select * from generate_series(1, 2000000);
INSERT 0 2000000
Time: 4299.000 ms

alter table test_enum_table add column t test_enum;
ALTER TABLE
Time: 3165.869 ms -- Takes 3 seconds in this test example


From: Joe Van Dyk <joe(at)tanga(dot)com>
To: "pgsql-general(at)postgresql(dot)org" <pgsql-general(at)postgresql(dot)org>
Subject: Re: adding a nullable column of type domain w/ check constraint runs checks?
Date: 2014-08-19 22:16:37
Message-ID: CACfv+pKUc+eF2Sf1sF2BUZV7R-qGTgcON78EBCAoS1_0e7kpsg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

On Tue, Aug 19, 2014 at 3:10 PM, Joe Van Dyk <joe(at)tanga(dot)com> wrote:

> I have a large table that I don't want to lock for more than couple
> seconds. I want to add a nullable column to the table, the type of the
> column is a domain with a check constraint.
>
> It appears that the check constraint is being checked for each row, even
> though the column can be nullable? Is there a way around this?
>
> BEGIN
> Timing is on.
>
> create domain test_enum numeric check (value > 0);
> CREATE DOMAIN
> Time: 1.817 ms
>
> create table test_enum_table (id serial primary key);
> CREATE TABLE
> Time: 2.213 ms
>
> insert into test_enum_table select * from generate_series(1, 2000000);
> INSERT 0 2000000
> Time: 4299.000 ms
>
> alter table test_enum_table add column t test_enum;
> ALTER TABLE
> Time: 3165.869 ms -- Takes 3 seconds in this test example
>
> Also:

alter table test_enum_table add column t1 numeric check (t1 > 0);
ALTER TABLE
Time: 140.185 ms

which is much more reasonable.


From: Joe Van Dyk <joe(at)tanga(dot)com>
To: "pgsql-general(at)postgresql(dot)org" <pgsql-general(at)postgresql(dot)org>
Subject: Re: adding a nullable column of type domain w/ check constraint runs checks?
Date: 2014-08-19 22:20:10
Message-ID: CACfv+p+rZQwYE1-nBxSaJLVGVCAYveWccmBGOhCduhnUOU2d2g@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

On Tue, Aug 19, 2014 at 3:16 PM, Joe Van Dyk <joe(at)tanga(dot)com> wrote:

> On Tue, Aug 19, 2014 at 3:10 PM, Joe Van Dyk <joe(at)tanga(dot)com> wrote:
>
>> I have a large table that I don't want to lock for more than couple
>> seconds. I want to add a nullable column to the table, the type of the
>> column is a domain with a check constraint.
>>
>> It appears that the check constraint is being checked for each row, even
>> though the column can be nullable? Is there a way around this?
>>
>> BEGIN
>> Timing is on.
>>
>> create domain test_enum numeric check (value > 0);
>> CREATE DOMAIN
>> Time: 1.817 ms
>>
>> create table test_enum_table (id serial primary key);
>> CREATE TABLE
>> Time: 2.213 ms
>>
>> insert into test_enum_table select * from generate_series(1, 2000000);
>> INSERT 0 2000000
>> Time: 4299.000 ms
>>
>> alter table test_enum_table add column t test_enum;
>> ALTER TABLE
>> Time: 3165.869 ms -- Takes 3 seconds in this test example
>>
>> Also:
>
> alter table test_enum_table add column t1 numeric check (t1 > 0);
> ALTER TABLE
> Time: 140.185 ms
>
> which is much more reasonable.
>

johnto on irc says:

"I'm not sure why it's done this way. it seems like it could test the
domain once against NULL and see whether that's rejected or not. instead
it just forces a rewrite :-("


From: Joe Van Dyk <joe(at)tanga(dot)com>
To: "pgsql-general(at)postgresql(dot)org" <pgsql-general(at)postgresql(dot)org>
Subject: Re: adding a nullable column of type domain w/ check constraint runs checks?
Date: 2014-09-03 00:11:29
Message-ID: CACfv+p+8dToaR7h06_M_YMjpV5Na-CQq7kN=KgJq_k84H7UHWA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

On Tue, Aug 19, 2014 at 3:20 PM, Joe Van Dyk <joe(at)tanga(dot)com> wrote:

> On Tue, Aug 19, 2014 at 3:16 PM, Joe Van Dyk <joe(at)tanga(dot)com> wrote:
>
>> On Tue, Aug 19, 2014 at 3:10 PM, Joe Van Dyk <joe(at)tanga(dot)com> wrote:
>>
>>> I have a large table that I don't want to lock for more than couple
>>> seconds. I want to add a nullable column to the table, the type of the
>>> column is a domain with a check constraint.
>>>
>>> It appears that the check constraint is being checked for each row, even
>>> though the column can be nullable? Is there a way around this?
>>>
>>> BEGIN
>>> Timing is on.
>>>
>>> create domain test_enum numeric check (value > 0);
>>> CREATE DOMAIN
>>> Time: 1.817 ms
>>>
>>> create table test_enum_table (id serial primary key);
>>> CREATE TABLE
>>> Time: 2.213 ms
>>>
>>> insert into test_enum_table select * from generate_series(1, 2000000);
>>> INSERT 0 2000000
>>> Time: 4299.000 ms
>>>
>>> alter table test_enum_table add column t test_enum;
>>> ALTER TABLE
>>> Time: 3165.869 ms -- Takes 3 seconds in this test example
>>>
>>> Also:
>>
>> alter table test_enum_table add column t1 numeric check (t1 > 0);
>> ALTER TABLE
>> Time: 140.185 ms
>>
>> which is much more reasonable.
>>
>
> johnto on irc says:
>
> "I'm not sure why it's done this way. it seems like it could test the
> domain once against NULL and see whether that's rejected or not. instead
> it just forces a rewrite :-("
>

Would it be possible to check the domain against null and if that works,
then don't check any of the rows?

Joe