I have this DDL:
CREATE TABLE checkout_value (
id BIGSERIAL PRIMARY KEY,
start_value INTEGER,
end_value INTEGER,
);
With an e-commerce in mind, I want to save several ranges of possible values, where future rules will be applied at checkout. examples:
This way, I want to allow one null value, but if both are not null, start_value
should be smaller than end_value
.
I though about triggers, but I'm trying to do this using a check constraint, this way:
CREATE TABLE checkout_value (
id BIGSERIAL PRIMARY KEY,
start_value INTEGER,
end_value INTEGER,
CHECK
(
(start_value IS NOT NULL AND end_value IS NULL)
OR
(start_value IS NULL AND end_value IS NOT NULL)
OR
(start_value IS NOT NULL AND end_value IS NOT NULL AND end_value > start_value)
)
);
this works! but when I run \d checkout_value
, it prints without any parenthesis:
Check constraints:
"checkout_value_check" CHECK (start_value IS NOT NULL AND end_value IS NULL OR start_value IS NULL AND end_value IS NOT NULL OR start_value IS NOT NULL AND end_value IS NOT NULL AND end_value > start_value)
which, without parenthesis, would lead to an unwanted rule. Is this a bug at printing the details of the table? Is there an easier way to apply while documenting these rules in a more explicit way?
AND
binds stronger than OR
, so both versions are equivalent. PostgreSQL doesn't store the string, but the parsed expression.