Skip to content

Commit 4a2dbfc

Browse files
committed
Add tests for foreign keys with case-insensitive collations
Some of the behaviors of the different referential actions, such as the difference between NO ACTION and RESTRICT are best illustrated using a case-insensitive collation. So add some tests for that. (What is actually being tested here is the behavior with values that are "distinct" (binary different) but compare as equal. Another way to do that would be with positive and negative zeroes with float types. But this way seems nicer and more flexible.) Discussion: https://www.postgresql.org/message-id/[email protected]
1 parent 5bba054 commit 4a2dbfc

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

src/test/regress/expected/collate.icu.utf8.out

+62
Original file line numberDiff line numberDiff line change
@@ -2024,6 +2024,68 @@ CREATE TABLE test11pk (x text COLLATE case_insensitive PRIMARY KEY);
20242024
CREATE TABLE test11fk (x text COLLATE case_sensitive REFERENCES test11pk (x) ON UPDATE CASCADE ON DELETE CASCADE); -- error
20252025
ERROR: foreign key constraint "test11fk_x_fkey" cannot be implemented
20262026
DETAIL: Key columns "x" of the referencing table and "x" of the referenced table have incompatible collations: "case_sensitive" and "case_insensitive". If either collation is nondeterministic, then both collations have to be the same.
2027+
-- foreign key actions
2028+
-- Some of the behaviors are most easily visible with a
2029+
-- case-insensitive collation.
2030+
CREATE TABLE test12pk (x text COLLATE case_insensitive PRIMARY KEY);
2031+
CREATE TABLE test12fk (a int, b text COLLATE case_insensitive REFERENCES test12pk (x) ON UPDATE NO ACTION);
2032+
INSERT INTO test12pk VALUES ('abc');
2033+
INSERT INTO test12fk VALUES (1, 'abc'), (2, 'ABC');
2034+
UPDATE test12pk SET x = 'ABC' WHERE x = 'abc'; -- ok
2035+
SELECT * FROM test12pk;
2036+
x
2037+
-----
2038+
ABC
2039+
(1 row)
2040+
2041+
SELECT * FROM test12fk; -- no updates here
2042+
a | b
2043+
---+-----
2044+
1 | abc
2045+
2 | ABC
2046+
(2 rows)
2047+
2048+
DROP TABLE test12pk, test12fk;
2049+
CREATE TABLE test12pk (x text COLLATE case_insensitive PRIMARY KEY);
2050+
CREATE TABLE test12fk (a int, b text COLLATE case_insensitive REFERENCES test12pk (x) ON UPDATE RESTRICT);
2051+
INSERT INTO test12pk VALUES ('abc');
2052+
INSERT INTO test12fk VALUES (1, 'abc'), (2, 'ABC');
2053+
UPDATE test12pk SET x = 'ABC' WHERE x = 'abc'; -- restrict violation
2054+
ERROR: update or delete on table "test12pk" violates foreign key constraint "test12fk_b_fkey" on table "test12fk"
2055+
DETAIL: Key (x)=(abc) is still referenced from table "test12fk".
2056+
SELECT * FROM test12pk;
2057+
x
2058+
-----
2059+
abc
2060+
(1 row)
2061+
2062+
SELECT * FROM test12fk;
2063+
a | b
2064+
---+-----
2065+
1 | abc
2066+
2 | ABC
2067+
(2 rows)
2068+
2069+
DROP TABLE test12pk, test12fk;
2070+
CREATE TABLE test12pk (x text COLLATE case_insensitive PRIMARY KEY);
2071+
CREATE TABLE test12fk (a int, b text COLLATE case_insensitive REFERENCES test12pk (x) ON UPDATE CASCADE);
2072+
INSERT INTO test12pk VALUES ('abc');
2073+
INSERT INTO test12fk VALUES (1, 'abc'), (2, 'ABC');
2074+
UPDATE test12pk SET x = 'ABC' WHERE x = 'abc'; -- ok
2075+
SELECT * FROM test12pk;
2076+
x
2077+
-----
2078+
ABC
2079+
(1 row)
2080+
2081+
SELECT * FROM test12fk; -- was updated
2082+
a | b
2083+
---+-----
2084+
1 | ABC
2085+
2 | ABC
2086+
(2 rows)
2087+
2088+
DROP TABLE test12pk, test12fk;
20272089
-- partitioning
20282090
CREATE TABLE test20 (a int, b text COLLATE case_insensitive) PARTITION BY LIST (b);
20292091
CREATE TABLE test20_1 PARTITION OF test20 FOR VALUES IN ('abc');

src/test/regress/sql/collate.icu.utf8.sql

+30
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,36 @@ CREATE TABLE test10fk (x text COLLATE case_insensitive REFERENCES test10pk (x) O
743743
CREATE TABLE test11pk (x text COLLATE case_insensitive PRIMARY KEY);
744744
CREATE TABLE test11fk (x text COLLATE case_sensitive REFERENCES test11pk (x) ON UPDATE CASCADE ON DELETE CASCADE); -- error
745745
746+
-- foreign key actions
747+
-- Some of the behaviors are most easily visible with a
748+
-- case-insensitive collation.
749+
CREATE TABLE test12pk (x text COLLATE case_insensitive PRIMARY KEY);
750+
CREATE TABLE test12fk (a int, b text COLLATE case_insensitive REFERENCES test12pk (x) ON UPDATE NO ACTION);
751+
INSERT INTO test12pk VALUES ('abc');
752+
INSERT INTO test12fk VALUES (1, 'abc'), (2, 'ABC');
753+
UPDATE test12pk SET x = 'ABC' WHERE x = 'abc'; -- ok
754+
SELECT * FROM test12pk;
755+
SELECT * FROM test12fk; -- no updates here
756+
DROP TABLE test12pk, test12fk;
757+
758+
CREATE TABLE test12pk (x text COLLATE case_insensitive PRIMARY KEY);
759+
CREATE TABLE test12fk (a int, b text COLLATE case_insensitive REFERENCES test12pk (x) ON UPDATE RESTRICT);
760+
INSERT INTO test12pk VALUES ('abc');
761+
INSERT INTO test12fk VALUES (1, 'abc'), (2, 'ABC');
762+
UPDATE test12pk SET x = 'ABC' WHERE x = 'abc'; -- restrict violation
763+
SELECT * FROM test12pk;
764+
SELECT * FROM test12fk;
765+
DROP TABLE test12pk, test12fk;
766+
767+
CREATE TABLE test12pk (x text COLLATE case_insensitive PRIMARY KEY);
768+
CREATE TABLE test12fk (a int, b text COLLATE case_insensitive REFERENCES test12pk (x) ON UPDATE CASCADE);
769+
INSERT INTO test12pk VALUES ('abc');
770+
INSERT INTO test12fk VALUES (1, 'abc'), (2, 'ABC');
771+
UPDATE test12pk SET x = 'ABC' WHERE x = 'abc'; -- ok
772+
SELECT * FROM test12pk;
773+
SELECT * FROM test12fk; -- was updated
774+
DROP TABLE test12pk, test12fk;
775+
746776
-- partitioning
747777
CREATE TABLE test20 (a int, b text COLLATE case_insensitive) PARTITION BY LIST (b);
748778
CREATE TABLE test20_1 PARTITION OF test20 FOR VALUES IN ('abc');

0 commit comments

Comments
 (0)