abnormal behaviour of a CHECK CONSTRAINT with a regular expression when a trigger is added - Mailing list pgsql-bugs
| From | Daniel Struck |
|---|---|
| Subject | abnormal behaviour of a CHECK CONSTRAINT with a regular expression when a trigger is added |
| Date | |
| Msg-id | 20040210143024.63f8b5f8.struck.d@retrovirology.lu Whole thread Raw |
| Responses |
Re: abnormal behaviour of a CHECK CONSTRAINT with a regular expression when a trigger is added
Re: abnormal behaviour of a CHECK CONSTRAINT with a regular |
| List | pgsql-bugs |
Hello,
I think I have found a bug in postgresql:
When I construct a table with a check constraint with a regular expressions=
, it works as expected.
But when I add a trigger to the table. The check does not work anymore in s=
ome circumstances. It seems like the same check is influenced/ changed by t=
he trigger.
First my environment:
SELECT version();
version
-----------------------------------------------------------------------
PostgreSQL 7.4.1 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 3.3.2 200=
31218 (Gentoo Linux 3.3.2-r5, propolice-3.3-7)
(1 row)
The only difference with the standard installation:
datestyle =3D 'german, dmy' (/var/lib/postgresql/data/postgresql.conf)
The table to test this bug?:
CREATE TABLE test_reg1(
date_user VARCHAR(10) CHECK (date_user ~ '^([0-9]{1,2}\\.)?([0=
-9]{1,2}\\.)?[0-9]{4}$|^unkown$'),
date DATE,
date_quality INT CHECK (date_quality IN (1,2,3,4))
);
Some values I insert in the table, which should pass the CHECK constraint:
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('unkown');
INSERT 205697 1
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('1999');
INSERT 205698 1
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('11.1999');
INSERT 205699 1
retrovirology=3D#
Some values I insert in the table, which should not pass the CHECK constrai=
nt:
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('unk');
ERROR: new row for relation "test_reg1" violates check constraint "test_re=
g1_date_user"
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('19999');
ERROR: new row for relation "test_reg1" violates check constraint "test_re=
g1_date_user"
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('111.1999');
ERROR: new row for relation "test_reg1" violates check constraint "test_re=
g1_date_user"
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('11:1999');
ERROR: new row for relation "test_reg1" violates check constraint "test_re=
g1_date_user"
retrovirology=3D#
This part does work as expected.
Now I will add a trigger to this table.
(The background of the trigger is to allow the user to insert incomplete da=
tes. The user can add the year, the year and the month or the complete date=
. A quality of the date is inserted in the "date_quality" column and a comp=
lete date is inserted in the "date" column. The "date" column will later b=
e used to calculate stats, ...)
CREATE OR REPLACE FUNCTION function_test_reg1 ()
RETURNS trigger
AS 'BEGIN
IF new.date_user IS NOT NULL THEN
IF new.date_user =3D ''unkown'' THEN
new.date_quality :=3D 4;
END IF;
IF new.date_user ~ ''^([0-9]{1,2}\\.){1}([0-9]{1,2}\\.){1}[0-9]{4}$'' T=
HEN
new.date :=3D new.date_user;
new.date_quality :=3D 1;
END IF;
IF new.date_user ~ ''^([0-9]{1,2}\\.){1}[0-9]{4}$'' THEN
new.date :=3D ''15.'' || new.date_user;
new.date_quality :=3D 2;
END IF;
IF new.date_user ~ ''^[0-9]{4}$'' THEN
new.date :=3D ''15.06.'' || new.date_user;
new.date_quality :=3D 3;
END IF;
END IF;
RETURN new;
END;'
LANGUAGE plpgsql;
CREATE TRIGGER trigger_test_reg1
BEFORE INSERT OR UPDATE
ON test_reg1 FOR EACH ROW
EXECUTE PROCEDURE function_test_reg1();
Now I will insert the same values as before, the first part should be inser=
ted without a problem.
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('unkown');
INSERT 206770 1
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('1999');
INSERT 206771 1
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('11.1999');
INSERT 206772 1
retrovirology=3D# select * from test_reg1;
date_user | date | date_quality
-----------+------------+--------------
unkown | | 4
1999 | 15.06.1999 | 3
11.1999 | 15.11.1999 | 2
(3 rows)
You can see, that the trigger works as expected.
But now, I insert the values, which shouldn't pass the CHECK CONSTRAINT:
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('unk');
ERROR: new row for relation "test_reg1" violates check constraint "test_re=
g1_date_user"
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('19999');
ERROR: new row for relation "test_reg1" violates check constraint "test_re=
g1_date_user"
This seems right, the values are rejected by the CHECK CONSTRAINT. Now I in=
sert the other "wrong values":
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('111.1999');
ERROR: invalid input syntax for type date: "111.1999"
CONTEXT: PL/pgSQL function "function_test_reg1" line 8 at assignment
retrovirology=3D# INSERT INTO test_reg1 (date_user) VALUES ('11:1999');
ERROR: invalid input syntax for type date: "15.11:1999"
CONTEXT: PL/pgSQL function "function_test_reg1" line 12 at assignment
retrovirology=3D#
This values do pass NOW the CHECK CONSTRAINT ???? and are injected in the t=
rigger function. Normally the trigger shouldn't m have an influence an the =
CHECK CONSTRAINT.
Very strange?
Of course the trigger function now rejects the values, because they don't c=
onstitute a valid date.
Best regards,
Daniel Struck
--=20
Retrovirology Laboratory Luxembourg
Centre Hospitalier de Luxembourg
4, rue E. Barbl=E9
L-1210 Luxembourg
phone: +352-44116105
fax: +352-44116113
web: http://www.retrovirology.lu
e-mail: struck.d@retrovirology.lu
pgsql-bugs by date: