postgres 11+如何在删除默认值后保持默认值?
How does postgres 11+ maintain default value after the default is dropped?
给定以下命令:
create table foo(id serial primary key);
insert into foo values (1), (2), (3), (4);
alter table foo add column bar integer not null default 10;
alter table foo alter column bar drop default;
当我执行 select * from foo;
时,我得到:
id | bar
----+------
1 | 10
2 | 10
3 | 10
4 | 10
如果从 postgresql 11+ 开始,它会延迟计算 not null 默认值,这怎么可能?
列默认值存储在系统目录 pg_attrdef
中,而列定义存储在 pg_attribute
中。如果删除默认值,将删除 pg_attrdef
行,但不会删除 pg_attribute
行。
你观察到的秘密是“缺失的属性值”存储在pg_attribute
中,所以它不受影响:
SELECT attmissingval
FROM pg_attribute
WHERE attrelid = 'foo'::regclass
AND attname = 'bar';
attmissingval
═══════════════
{10}
(1 row)
分解每个更改语句:
alter table foo add column bar integer not null default 10
这将添加新列,并且由于 not null default 10
,每行的列值都被赋予 10
。
此时,所有 existing 行都有 10
并且所有 future 行将被赋予 10
如果插入时未提供值。
alter table foo alter column bar drop default
这不会影响现有行。它只影响 未来 插入的行,现在 需要 一个值,因为约束 not null
仍然存在,但默认值没有。
给定以下命令:
create table foo(id serial primary key);
insert into foo values (1), (2), (3), (4);
alter table foo add column bar integer not null default 10;
alter table foo alter column bar drop default;
当我执行 select * from foo;
时,我得到:
id | bar
----+------
1 | 10
2 | 10
3 | 10
4 | 10
如果从 postgresql 11+ 开始,它会延迟计算 not null 默认值,这怎么可能?
列默认值存储在系统目录 pg_attrdef
中,而列定义存储在 pg_attribute
中。如果删除默认值,将删除 pg_attrdef
行,但不会删除 pg_attribute
行。
你观察到的秘密是“缺失的属性值”存储在pg_attribute
中,所以它不受影响:
SELECT attmissingval
FROM pg_attribute
WHERE attrelid = 'foo'::regclass
AND attname = 'bar';
attmissingval
═══════════════
{10}
(1 row)
分解每个更改语句:
alter table foo add column bar integer not null default 10
这将添加新列,并且由于 not null default 10
,每行的列值都被赋予 10
。
此时,所有 existing 行都有 10
并且所有 future 行将被赋予 10
如果插入时未提供值。
alter table foo alter column bar drop default
这不会影响现有行。它只影响 未来 插入的行,现在 需要 一个值,因为约束 not null
仍然存在,但默认值没有。