How to create a column constant in Postgresql
For the default, you can use the function,
CREATE TABLE test(
t_id SERIAL primary key,
t_date date DEFAULT now()
);
about constant
, I've never used, not even other SQL (!), only in the context of PL / SQL ...
If you need a no refresh constraint, you can use a trigger. Example:
CREATE FUNCTION correct_update() RETURNS trigger AS $$
BEGIN
NEW.t_date=OLD.t_date;
RETURN NEW;
END
$$ LANGUAGE plpgsql;
CREATE TRIGGER no_date_update
BEFORE BEFORE UPDATE ON test
FOR EACH ROW
WHEN (OLD.t_date IS DISTINCT FROM NEW.t_date)
EXECUTE PROCEDURE correct_update();
For full control, you also need to fire the INSERT event (and no longer need the default as the insert trigger will be involved):
create table test(
t_id SERIAL primary key,
t_date date -- a default will be redundant
);
CREATE FUNCTION correct_date() RETURNS trigger AS $$
BEGIN
IF TG_OP = 'INSERT' THEN
NEW.t_date=now(); -- default value
ELSIF TG_OP = 'UPDATE' THEN -- optional AND OLD.t_date != NEW.t_date
NEW.t_date=OLD.t_date; -- "constant" behaviour
END IF;
RETURN NEW;
END
$$ LANGUAGE plpgsql;
CREATE TRIGGER constant_date
BEFORE INSERT OR UPDATE ON test
FOR EACH ROW
EXECUTE PROCEDURE correct_date();
The comparison OLD.t_date != NEW.t_date
is optional as it does not affect performance ... But it is good practice to use it. Another way is to test the trigger for WHEN
, but only update triggers can use OLD
... So, the best create triggers for the same function correct_date()
(no old / new comparison):
CREATE TRIGGER constant_date_ins
BEFORE INSERT ON test
FOR EACH ROW
EXECUTE PROCEDURE correct_date();
CREATE TRIGGER constant_date_upd
BEFORE UPDATE ON test
FOR EACH ROW
WHEN (OLD.t_date IS DISTINCT FROM NEW.t_date)
EXECUTE PROCEDURE correct_date();
Contextualization in a script
As noted above in the question, there is a lack of contextualization for example. explaining why you think it should work and what it should do.
Scenario-1: db-master needs to block unwary programmers
We can imagine a framework like CakePHP with a "crafted" field and a database wizard that wants this field to have "persistent behavior", preventing careless programmers from affecting this "expected constraint".
This script was used by anwser.
Scenario-2: project decision should be notified by mistake
This is @IgorRomanchenko's suggestion ...
... now here as a Wiki, you can EDIT and add new solution/example ...
source to share
Restriction required check
create table test(
t_id SERIAL primary key,
t_date date default CURRENT_DATE check(t_date = current_date)
);
insert into test(t_date) values (default);
INSERT 0 1
insert into test(t_date) values ('2014-01-01');
ERROR: new row for relation "test" violates check constraint "test_t_date_check"
DETAIL: Failing row contains (2, 2014-01-01).
Or there might be a constraint foreign key
that allows multiple possible values ββand can be updated without changing the table schema
create table date_constraint (
date_constraint date primary key
);
insert into date_constraint (date_constraint) values (current_date);
create table test(
t_id SERIAL primary key,
t_date date
default CURRENT_DATE
references date_constraint(date_constraint)
);
insert into test(t_date) values (default);
INSERT 0 1
insert into test(t_date) values ('2014-01-01');
ERROR: insert or update on table "test" violates foreign key constraint "test_t_date_fkey"
DETAIL: Key (t_date)=(2014-01-01) is not present in table "date_constraint".
http://www.postgresql.org/docs/current/static/ddl-constraints.html
source to share