1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

Fix bug around assignment expressions containing indirections.

Handling of assigned-to expressions with indirection (e.g. set f1[1] =
3) was broken for ON CONFLICT DO UPDATE.  The problem was that
ParseState was consulted to determine if an INSERT-appropriate or
UPDATE-appropriate behavior should be used when transforming expressions
with indirections. When the wrong path was taken the old row was
substituted with NULL, leading to wrong results..

To fix remove p_is_update and only use p_is_insert to decide how to
transform the assignment expression, and uset p_is_insert while parsing
the on conflict statement. This isn't particularly pretty, but it's not
any worse than before.

Author: Peter Geoghegan, slightly edited by me
Discussion: CAM3SWZS8RPvA=KFxADZWw3wAHnnbxMxDzkEC6fNaFc7zSm411w@mail.gmail.com
Backpatch: 9.5, where the feature was introduced
This commit is contained in:
Andres Freund
2015-07-24 11:48:53 +02:00
parent 16c33c50e1
commit c1ca3a19df
4 changed files with 41 additions and 2 deletions

View File

@ -891,6 +891,12 @@ transformOnConflictClause(ParseState *pstate,
/* Process DO UPDATE */
if (onConflictClause->action == ONCONFLICT_UPDATE)
{
/*
* All INSERT expressions have been parsed, get ready for potentially
* existing SET statements that need to be processed like an UPDATE.
*/
pstate->p_is_insert = false;
exclRte = addRangeTableEntryForRelation(pstate,
pstate->p_target_relation,
makeAlias("excluded", NIL),
@ -1999,7 +2005,7 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
Node *qual;
qry->commandType = CMD_UPDATE;
pstate->p_is_update = true;
pstate->p_is_insert = false;
/* process the WITH clause independently of all else */
if (stmt->withClause)