summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorTom Lane2016-07-04 20:09:11 +0000
committerTom Lane2016-07-04 20:09:11 +0000
commit9c810a2edccaffe0ff48b50d31c47a155e4f9815 (patch)
tree62b834fa1bba35c137e555c757559fce72aa70d3 /src/test
parent29a2195de645759d66ee7e77c4c05b2c4aeb6729 (diff)
Fix failure to handle conflicts in non-arbiter exclusion constraints.
ExecInsertIndexTuples treated an exclusion constraint as subject to noDupErr processing even when it was not listed in arbiterIndexes, and would therefore not error out for a conflict in such a constraint, instead returning it as an arbiter-index failure. That led to an infinite loop in ExecInsert, since ExecCheckIndexConstraints ignored the index as-intended and therefore didn't throw the expected error. To fix, make the exclusion constraint code path use the same condition as the index_insert call does to decide whether no-error-for-duplicates behavior is appropriate. While at it, refactor a little bit to avoid unnecessary list_member_oid calls. (That surely wouldn't save anything worth noticing, but I find the code a bit clearer this way.) Per bug report from Heikki Rauhala. Back-patch to 9.5 where ON CONFLICT was introduced. Report: <4C976D6B-76B4-434C-8052-D009F7B7AEDA@reaktor.fi>
Diffstat (limited to 'src/test')
-rw-r--r--src/test/regress/expected/insert_conflict.out23
-rw-r--r--src/test/regress/sql/insert_conflict.sql14
2 files changed, 37 insertions, 0 deletions
diff --git a/src/test/regress/expected/insert_conflict.out b/src/test/regress/expected/insert_conflict.out
index 6f4ec867d9f..155774ecfab 100644
--- a/src/test/regress/expected/insert_conflict.out
+++ b/src/test/regress/expected/insert_conflict.out
@@ -704,3 +704,26 @@ insert into dropcol(key, keep1, keep2) values(1, '5', 5) on conflict(key)
;
DROP TABLE dropcol;
+-- check handling of regular btree constraint along with gist constraint
+create table twoconstraints (f1 int unique, f2 box,
+ exclude using gist(f2 with &&));
+insert into twoconstraints values(1, '((0,0),(1,1))');
+insert into twoconstraints values(1, '((2,2),(3,3))'); -- fail on f1
+ERROR: duplicate key value violates unique constraint "twoconstraints_f1_key"
+DETAIL: Key (f1)=(1) already exists.
+insert into twoconstraints values(2, '((0,0),(1,2))'); -- fail on f2
+ERROR: conflicting key value violates exclusion constraint "twoconstraints_f2_excl"
+DETAIL: Key (f2)=((1,2),(0,0)) conflicts with existing key (f2)=((1,1),(0,0)).
+insert into twoconstraints values(2, '((0,0),(1,2))')
+ on conflict on constraint twoconstraints_f1_key do nothing; -- fail on f2
+ERROR: conflicting key value violates exclusion constraint "twoconstraints_f2_excl"
+DETAIL: Key (f2)=((1,2),(0,0)) conflicts with existing key (f2)=((1,1),(0,0)).
+insert into twoconstraints values(2, '((0,0),(1,2))')
+ on conflict on constraint twoconstraints_f2_excl do nothing; -- do nothing
+select * from twoconstraints;
+ f1 | f2
+----+-------------
+ 1 | (1,1),(0,0)
+(1 row)
+
+drop table twoconstraints;
diff --git a/src/test/regress/sql/insert_conflict.sql b/src/test/regress/sql/insert_conflict.sql
index 94b1b0aadee..190c6055623 100644
--- a/src/test/regress/sql/insert_conflict.sql
+++ b/src/test/regress/sql/insert_conflict.sql
@@ -407,3 +407,17 @@ insert into dropcol(key, keep1, keep2) values(1, '5', 5) on conflict(key)
;
DROP TABLE dropcol;
+
+-- check handling of regular btree constraint along with gist constraint
+
+create table twoconstraints (f1 int unique, f2 box,
+ exclude using gist(f2 with &&));
+insert into twoconstraints values(1, '((0,0),(1,1))');
+insert into twoconstraints values(1, '((2,2),(3,3))'); -- fail on f1
+insert into twoconstraints values(2, '((0,0),(1,2))'); -- fail on f2
+insert into twoconstraints values(2, '((0,0),(1,2))')
+ on conflict on constraint twoconstraints_f1_key do nothing; -- fail on f2
+insert into twoconstraints values(2, '((0,0),(1,2))')
+ on conflict on constraint twoconstraints_f2_excl do nothing; -- do nothing
+select * from twoconstraints;
+drop table twoconstraints;