Attach ON CONFLICT SET ... WHERE to the correct planstate.
authorAndres Freund <andres@anarazel.de>
Mon, 18 May 2015 23:55:10 +0000 (01:55 +0200)
committerAndres Freund <andres@anarazel.de>
Mon, 18 May 2015 23:55:10 +0000 (01:55 +0200)
The previous coding was a leftover from attempting to hang all the on
conflict logic onto modify table's child nodes. It appears to not have
actually caused problems except for explain.

Add test exercising the broken and some other code paths.

Author: Peter Geoghegan and Andres Freund

src/backend/executor/nodeModifyTable.c
src/test/regress/expected/insert_conflict.out
src/test/regress/sql/insert_conflict.sql

index 89f1f57ae3dcce4ac684196db4bb7188a0838f7e..8112fb45b815e6671c3cc13ef18ef2efcc05c356 100644 (file)
@@ -1697,7 +1697,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
                        ExprState  *qualexpr;
 
                        qualexpr = ExecInitExpr((Expr *) node->onConflictWhere,
-                                                                       mtstate->mt_plans[0]);
+                                                                       &mtstate->ps);
 
                        resultRelInfo->ri_onConflictSetWhere = (List *) qualexpr;
                }
index 3273d987932415c1ff713edd13a5cb9e921a030a..8e4e33e6e6c0766dc9185c542c3eae494daf8875 100644 (file)
@@ -43,6 +43,22 @@ explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on con
    ->  Result
 (4 rows)
 
+explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit) do update set fruit = excluded.fruit
+  where exists (select 1 from insertconflicttest ii where ii.key = excluded.key);
+                                  QUERY PLAN                                   
+-------------------------------------------------------------------------------
+ Insert on insertconflicttest
+   Conflict Resolution: UPDATE
+   Conflict Arbiter Indexes: op_index_key, collation_index_key, both_index_key
+   Conflict Filter: (alternatives: SubPlan 1 or hashed SubPlan 2)
+   ->  Result
+   SubPlan 1
+     ->  Index Only Scan using both_index_expr_key on insertconflicttest ii
+           Index Cond: (key = excluded.key)
+   SubPlan 2
+     ->  Seq Scan on insertconflicttest ii_1
+(10 rows)
+
 -- Neither collation nor operator class specifications are required --
 -- supplying them merely *limits* matches to indexes with matching opclasses
 -- used for relevant indexes
index ba2b66bdb6739c120b93f460f262e73aa7ec1706..a0bdd7f536ee9a1a2d98ce5b88a1f9e6e20ff14d 100644 (file)
@@ -20,6 +20,8 @@ explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on con
 explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit) do nothing;
 explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (fruit, key, fruit, key) do nothing;
 explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit), key, lower(fruit), key) do nothing;
+explain (costs off) insert into insertconflicttest values(0, 'Crowberry') on conflict (key, fruit) do update set fruit = excluded.fruit
+  where exists (select 1 from insertconflicttest ii where ii.key = excluded.key);
 -- Neither collation nor operator class specifications are required --
 -- supplying them merely *limits* matches to indexes with matching opclasses
 -- used for relevant indexes