mirror of
https://github.com/postgres/postgres.git
synced 2025-11-03 09:13:20 +03:00
Add support for NOT ENFORCED in CHECK constraints
This adds support for the NOT ENFORCED/ENFORCED flag for constraints, with support for check constraints. The plan is to eventually support this for foreign key constraints, where it is typically more useful. Note that CHECK constraints do not currently support ALTER operations, so changing the enforceability of an existing constraint isn't possible without dropping and recreating it. This could be added later. Author: Amul Sul <amul.sul@enterprisedb.com> Reviewed-by: Peter Eisentraut <peter@eisentraut.org> Reviewed-by: jian he <jian.universality@gmail.com> Tested-by: Triveni N <triveni.n@enterprisedb.com> Discussion: https://www.postgresql.org/message-id/flat/CAAJ_b962c5AcYW9KUt_R_ER5qs3fUGbe4az-SP-vuwPS-w-AGA@mail.gmail.com
This commit is contained in:
@@ -387,10 +387,12 @@ ALTER TABLE attmp3 validate constraint attmpconstr;
|
||||
-- Try a non-verified CHECK constraint
|
||||
ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10); -- fail
|
||||
ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten CHECK (b > 10) NOT VALID; -- succeeds
|
||||
ALTER TABLE attmp3 ADD CONSTRAINT b_greater_than_ten_not_enforced CHECK (b > 10) NOT ENFORCED; -- succeeds
|
||||
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- fails
|
||||
DELETE FROM attmp3 WHERE NOT b > 10;
|
||||
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
|
||||
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten; -- succeeds
|
||||
ALTER TABLE attmp3 VALIDATE CONSTRAINT b_greater_than_ten_not_enforced; -- fail
|
||||
|
||||
-- Test inherited NOT VALID CHECK constraints
|
||||
select * from attmp3;
|
||||
@@ -1188,6 +1190,11 @@ alter table renameColumn add column w int;
|
||||
-- this should fail
|
||||
alter table only renameColumn add column x int;
|
||||
|
||||
-- this should work
|
||||
alter table renameColumn add column x int check (x > 0) not enforced;
|
||||
|
||||
-- this should fail
|
||||
alter table renameColumn add column y int check (x > 0) not enforced enforced;
|
||||
|
||||
-- Test corner cases in dropping of inherited columns
|
||||
|
||||
|
||||
@@ -67,6 +67,18 @@ INSERT INTO CHECK_TBL VALUES (1);
|
||||
|
||||
SELECT * FROM CHECK_TBL;
|
||||
|
||||
CREATE TABLE NE_CHECK_TBL (x int,
|
||||
CONSTRAINT CHECK_CON CHECK (x > 3) NOT ENFORCED);
|
||||
|
||||
INSERT INTO NE_CHECK_TBL VALUES (5);
|
||||
INSERT INTO NE_CHECK_TBL VALUES (4);
|
||||
INSERT INTO NE_CHECK_TBL VALUES (3);
|
||||
INSERT INTO NE_CHECK_TBL VALUES (2);
|
||||
INSERT INTO NE_CHECK_TBL VALUES (6);
|
||||
INSERT INTO NE_CHECK_TBL VALUES (1);
|
||||
|
||||
SELECT * FROM NE_CHECK_TBL;
|
||||
|
||||
CREATE SEQUENCE CHECK_SEQ;
|
||||
|
||||
CREATE TABLE CHECK2_TBL (x int, y text, z int,
|
||||
@@ -92,7 +104,8 @@ CREATE TABLE INSERT_TBL (x INT DEFAULT nextval('insert_seq'),
|
||||
y TEXT DEFAULT '-NULL-',
|
||||
z INT DEFAULT -1 * currval('insert_seq'),
|
||||
CONSTRAINT INSERT_TBL_CON CHECK (x >= 3 AND y <> 'check failed' AND x < 8),
|
||||
CHECK (x + z = 0));
|
||||
CHECK (x + z = 0) ENFORCED, /* no change it is a default */
|
||||
CONSTRAINT NE_INSERT_TBL_CON CHECK (x + z = 1) NOT ENFORCED);
|
||||
|
||||
INSERT INTO INSERT_TBL(x,z) VALUES (2, -2);
|
||||
|
||||
@@ -518,6 +531,13 @@ COMMIT;
|
||||
|
||||
SELECT * FROM unique_tbl;
|
||||
|
||||
-- enforcibility cannot be specified or set for unique constrain
|
||||
CREATE TABLE UNIQUE_EN_TBL(i int UNIQUE ENFORCED);
|
||||
CREATE TABLE UNIQUE_NOTEN_TBL(i int UNIQUE NOT ENFORCED);
|
||||
-- XXX: error message is misleading here
|
||||
ALTER TABLE unique_tbl ALTER CONSTRAINT unique_tbl_i_key ENFORCED;
|
||||
ALTER TABLE unique_tbl ALTER CONSTRAINT unique_tbl_i_key NOT ENFORCED;
|
||||
|
||||
DROP TABLE unique_tbl;
|
||||
|
||||
--
|
||||
|
||||
@@ -128,7 +128,8 @@ CREATE TABLE inhz (x text REFERENCES inhz, LIKE inhx INCLUDING INDEXES);
|
||||
DROP TABLE inhz;
|
||||
|
||||
-- including storage and comments
|
||||
CREATE TABLE ctlt1 (a text CHECK (length(a) > 2) PRIMARY KEY, b text);
|
||||
CREATE TABLE ctlt1 (a text CHECK (length(a) > 2) ENFORCED PRIMARY KEY,
|
||||
b text CHECK (length(b) > 100) NOT ENFORCED);
|
||||
CREATE INDEX ctlt1_b_key ON ctlt1 (b);
|
||||
CREATE INDEX ctlt1_fnidx ON ctlt1 ((a || b));
|
||||
CREATE STATISTICS ctlt1_a_b_stat ON a,b FROM ctlt1;
|
||||
|
||||
@@ -880,6 +880,16 @@ select pg_basetype(1); -- expect NULL not error
|
||||
|
||||
drop domain mytext cascade;
|
||||
|
||||
--
|
||||
-- Explicit enforceability specification not allowed
|
||||
---
|
||||
CREATE DOMAIN constraint_enforced_dom AS int CONSTRAINT the_constraint CHECK (value > 0) ENFORCED;
|
||||
CREATE DOMAIN constraint_not_enforced_dom AS int CONSTRAINT the_constraint CHECK (value > 0) NOT ENFORCED;
|
||||
CREATE DOMAIN constraint_enforced_dom AS int;
|
||||
-- XXX misleading error messages
|
||||
ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) ENFORCED;
|
||||
ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) NOT ENFORCED;
|
||||
DROP DOMAIN constraint_enforced_dom;
|
||||
|
||||
--
|
||||
-- Information schema
|
||||
|
||||
@@ -468,12 +468,57 @@ alter table p1_c1 add constraint inh_check_constraint1 check (f1 > 0);
|
||||
alter table p1_c1 add constraint inh_check_constraint2 check (f1 < 10);
|
||||
alter table p1 add constraint inh_check_constraint2 check (f1 < 10);
|
||||
|
||||
select conrelid::regclass::text as relname, conname, conislocal, coninhcount
|
||||
alter table p1 add constraint inh_check_constraint3 check (f1 > 0) not enforced;
|
||||
alter table p1_c1 add constraint inh_check_constraint3 check (f1 > 0) not enforced;
|
||||
|
||||
alter table p1_c1 add constraint inh_check_constraint4 check (f1 < 10) not enforced;
|
||||
alter table p1 add constraint inh_check_constraint4 check (f1 < 10) not enforced;
|
||||
|
||||
-- allowed to merge enforced constraint with parent's not enforced constraint
|
||||
alter table p1_c1 add constraint inh_check_constraint5 check (f1 < 10) enforced;
|
||||
alter table p1 add constraint inh_check_constraint5 check (f1 < 10) not enforced;
|
||||
|
||||
alter table p1 add constraint inh_check_constraint6 check (f1 < 10) not enforced;
|
||||
alter table p1_c1 add constraint inh_check_constraint6 check (f1 < 10) enforced;
|
||||
|
||||
create table p1_c2(f1 int constraint inh_check_constraint4 check (f1 < 10)) inherits(p1);
|
||||
|
||||
-- but reverse is not allowed
|
||||
alter table p1_c1 add constraint inh_check_constraint7 check (f1 < 10) not enforced;
|
||||
alter table p1 add constraint inh_check_constraint7 check (f1 < 10) enforced;
|
||||
|
||||
alter table p1 add constraint inh_check_constraint8 check (f1 < 10) enforced;
|
||||
alter table p1_c1 add constraint inh_check_constraint8 check (f1 < 10) not enforced;
|
||||
|
||||
create table p1_fail(f1 int constraint inh_check_constraint2 check (f1 < 10) not enforced) inherits(p1);
|
||||
|
||||
-- constraints with different enforceability can be merged by marking them as ENFORCED
|
||||
create table p1_c3() inherits(p1, p1_c1);
|
||||
|
||||
-- but not allowed if the child constraint is explicitly asked to be NOT ENFORCED
|
||||
create table p1_fail(f1 int constraint inh_check_constraint6 check (f1 < 10) not enforced) inherits(p1, p1_c1);
|
||||
|
||||
select conrelid::regclass::text as relname, conname, conislocal, coninhcount, conenforced
|
||||
from pg_constraint where conname like 'inh\_check\_constraint%'
|
||||
order by 1, 2;
|
||||
|
||||
drop table p1 cascade;
|
||||
|
||||
--
|
||||
-- Similarly, check the merging of existing constraints; a parent constraint
|
||||
-- marked as NOT ENFORCED can merge with an ENFORCED child constraint, but the
|
||||
-- reverse is not allowed.
|
||||
--
|
||||
create table p1(f1 int constraint p1_a_check check (f1 > 0) not enforced);
|
||||
create table p1_c1(f1 int constraint p1_a_check check (f1 > 0) enforced);
|
||||
alter table p1_c1 inherit p1;
|
||||
drop table p1 cascade;
|
||||
|
||||
create table p1(f1 int constraint p1_a_check check (f1 > 0) enforced);
|
||||
create table p1_c1(f1 int constraint p1_a_check check (f1 > 0) not enforced);
|
||||
alter table p1_c1 inherit p1;
|
||||
drop table p1, p1_c1;
|
||||
|
||||
--
|
||||
-- Test DROP behavior of multiply-defined CHECK constraints
|
||||
--
|
||||
|
||||
Reference in New Issue
Block a user