postgres.git / summary / log / commit / refs

commit    e4942f7a56efcfaabed5db7bde29ee21bef2f6e2
Author:   Andres Freund <andres@anarazel.de>
Date:     Mon May 18 23:55:10 2015 +0000
First released in: 9.5.0

    Attach ON CONFLICT SET ... WHERE to the correct planstate.
    
    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 | 2 +- src/test/regress/expected/insert_conflict.out | 16 ++++++++++++++++ src/test/regress/sql/insert_conflict.sql | 2 ++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 89f1f57ae3d..8112fb45b81 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -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; } diff --git a/src/test/regress/expected/insert_conflict.out b/src/test/regress/expected/insert_conflict.out index 3273d987932..8e4e33e6e6c 100644 --- a/src/test/regress/expected/insert_conflict.out +++ b/src/test/regress/expected/insert_conflict.out @@ -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 diff --git a/src/test/regress/sql/insert_conflict.sql b/src/test/regress/sql/insert_conflict.sql index ba2b66bdb67..a0bdd7f536e 100644 --- a/src/test/regress/sql/insert_conflict.sql +++ b/src/test/regress/sql/insert_conflict.sql @@ -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 [parent: 4db485e75b96]