aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/analyze.c
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2015-07-24 11:48:53 +0200
committerAndres Freund <andres@anarazel.de>2015-07-24 11:52:22 +0200
commitbb0203f26fa5f09fe2689a9db4bc632c1435edec (patch)
treec1dbfcf28c36c17b93d282058f6383a168a93429 /src/backend/parser/analyze.c
parentfbf8dc21738749470f73f91a95ac01912c9deb10 (diff)
downloadpostgresql-bb0203f26fa5f09fe2689a9db4bc632c1435edec.tar.gz
postgresql-bb0203f26fa5f09fe2689a9db4bc632c1435edec.zip
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
Diffstat (limited to 'src/backend/parser/analyze.c')
-rw-r--r--src/backend/parser/analyze.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index fc463faa6be..a0dfbf900a9 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -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)