Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alter check constraint on Postgres domain

Tags:

postgresql

Given an existing Postgres DOMAIN with CHECK constraint:

CREATE DOMAIN code as CHAR(1) 
CHECK (value IN ('A', 'B', 'C'));

I need to alter the CHECK constraint to add D as a member to the valid set A, B and C.

Since the new constraint is a superset of the first it seemed acceptable to first DROP the existing constraint and then ADD it again; i.e:

ALTER DOMAIN code 
DROP CONSTRAINT code_check; -- constraint is implicitly named `code_check`

ALTER DOMAIN code 
ADD CONSTRAINT code_check 
CHECK (value IN ('A', 'B', 'C', 'D')); -- new constraint

Are there possible issues with this approach, or is there a better method?

like image 990
Darragh Enright Avatar asked Oct 26 '19 00:10

Darragh Enright


People also ask

How do you change constraints in PostgreSQL?

The PostgreSQL ALTER TABLE command is used to add, delete or modify columns in an existing table. You would also use ALTER TABLE command to add and drop various constraints on an existing table.

How do I write a check constraint in PostgreSQL?

The CHECK constraint consists of the keyword CHECK followed by parenthesized conditions. The attempt will be rejected when update or insert column values that will make the condition false. The CHECK constraint in PostgreSQL can be defined as a separate name.

How do I change the domain of a column in a table?

You must own the domain to use ALTER DOMAIN . To change the schema of a domain, you must also have CREATE privilege on the new schema. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have CREATE privilege on the domain's schema.


1 Answers

Theoretically, it is possible that a concurrent session will insert a row that violates the constraint at the moment the domain has no constraint. Reversing the order of commands will prevent this possibility. Since the new constraint is a superset of the old one you can suppress checking values in existing columns using the domain:

ALTER DOMAIN code 
ADD CONSTRAINT code_check_new 
CHECK (value IN ('A', 'B', 'C', 'D')) NOT VALID;

ALTER DOMAIN code 
DROP CONSTRAINT code_check;

-- if for some reason the constraint name is important:
ALTER DOMAIN code 
RENAME CONSTRAINT code_check_new TO code_check;

Per the documentation:

Newly inserted or updated rows are always checked against all constraints, even those marked NOT VALID.

like image 84
klin Avatar answered Sep 27 '22 17:09

klin