diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2016-05-11 16:20:03 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2016-05-11 16:20:23 -0400 |
commit | 26e66184d6136643d16f6fb167db517fb18b8f89 (patch) | |
tree | 70e680b6778f1a698629c110ed389ba287fd151c /src/test | |
parent | 9be58a2b8ef222c1de80ccbb55b19ab0cff33237 (diff) | |
download | postgresql-26e66184d6136643d16f6fb167db517fb18b8f89.tar.gz postgresql-26e66184d6136643d16f6fb167db517fb18b8f89.zip |
Fix assorted missing infrastructure for ON CONFLICT.
subquery_planner() failed to apply expression preprocessing to the
arbiterElems and arbiterWhere fields of an OnConflictExpr. No doubt the
theory was that this wasn't necessary because we don't actually try to
execute those expressions; but that's wrong, because it results in failure
to match to index expressions or index predicates that are changed at all
by preprocessing. Per bug #14132 from Reynold Smith.
Also add pullup_replace_vars processing for onConflictWhere. Perhaps
it's impossible to have a subquery reference there, but I'm not exactly
convinced; and even if true today it's a failure waiting to happen.
Also add some comments to other places where one or another field of
OnConflictExpr is intentionally ignored, with explanation as to why it's
okay to do so.
Also, catalog/dependency.c failed to record any dependency on the named
constraint in ON CONFLICT ON CONSTRAINT, allowing such a constraint to
be dropped while rules exist that depend on it, and allowing pg_dump to
dump such a rule before the constraint it refers to. The normal execution
path managed to error out reasonably for a dangling constraint reference,
but ruleutils.c dumped core; so in addition to fixing the omission, add
a protective check in ruleutils.c, since we can't retroactively add a
dependency in existing databases.
Back-patch to 9.5 where this code was introduced.
Report: <20160510190350.2608.48667@wrigleys.postgresql.org>
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/regress/expected/insert_conflict.out | 15 | ||||
-rw-r--r-- | src/test/regress/sql/insert_conflict.sql | 22 |
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 f56cbd642de..e5c8b4aaacb 100644 --- a/src/test/regress/expected/insert_conflict.out +++ b/src/test/regress/expected/insert_conflict.out @@ -454,6 +454,21 @@ ERROR: column excluded.oid does not exist LINE 1: ...values (1) on conflict (key) do update set data = excluded.o... ^ drop table syscolconflicttest; +-- +-- Previous tests all managed to not test any expressions requiring +-- planner preprocessing ... +-- +create table insertconflict (a bigint, b bigint); +create unique index insertconflicti1 on insertconflict(coalesce(a, 0)); +create unique index insertconflicti2 on insertconflict(b) + where coalesce(a, 1) > 0; +insert into insertconflict values (1, 2) +on conflict (coalesce(a, 0)) do nothing; +insert into insertconflict values (1, 2) +on conflict (b) where coalesce(a, 1) > 0 do nothing; +insert into insertconflict values (1, 2) +on conflict (b) where coalesce(a, 1) > 1 do nothing; +drop table insertconflict; -- ****************************************************************** -- * * -- * Test inheritance (example taken from tutorial) * diff --git a/src/test/regress/sql/insert_conflict.sql b/src/test/regress/sql/insert_conflict.sql index 8d846f51df4..94b1b0aadee 100644 --- a/src/test/regress/sql/insert_conflict.sql +++ b/src/test/regress/sql/insert_conflict.sql @@ -261,6 +261,28 @@ insert into syscolconflicttest values (1) on conflict (key) do update set data = insert into syscolconflicttest values (1) on conflict (key) do update set data = excluded.oid::text; drop table syscolconflicttest; +-- +-- Previous tests all managed to not test any expressions requiring +-- planner preprocessing ... +-- +create table insertconflict (a bigint, b bigint); + +create unique index insertconflicti1 on insertconflict(coalesce(a, 0)); + +create unique index insertconflicti2 on insertconflict(b) + where coalesce(a, 1) > 0; + +insert into insertconflict values (1, 2) +on conflict (coalesce(a, 0)) do nothing; + +insert into insertconflict values (1, 2) +on conflict (b) where coalesce(a, 1) > 0 do nothing; + +insert into insertconflict values (1, 2) +on conflict (b) where coalesce(a, 1) > 1 do nothing; + +drop table insertconflict; + -- ****************************************************************** -- * * |