Skip to content

Commit 134fdf3

Browse files
committed
Fix ruleutils to produce correct output for array assignment, such
as UPDATE foo SET arr[3] = 42.
1 parent c333d2b commit 134fdf3

File tree

1 file changed

+50
-4
lines changed

1 file changed

+50
-4
lines changed

src/backend/utils/adt/ruleutils.c

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* out of its tuple
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.58 2000/08/08 15:42:21 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.59 2000/08/12 04:04:53 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -107,6 +107,7 @@ static void get_func_expr(Expr *expr, deparse_context *context);
107107
static void get_tle_expr(TargetEntry *tle, deparse_context *context);
108108
static void get_const_expr(Const *constval, deparse_context *context);
109109
static void get_sublink_expr(Node *node, deparse_context *context);
110+
static bool tleIsArrayAssign(TargetEntry *tle);
110111
static char *quote_identifier(char *ident);
111112
static char *get_relation_name(Oid relid);
112113
static char *get_attribute_name(Oid relid, int2 attnum);
@@ -1186,8 +1187,14 @@ get_update_query_def(Query *query, deparse_context *context)
11861187

11871188
appendStringInfo(buf, sep);
11881189
sep = ", ";
1189-
appendStringInfo(buf, "%s = ",
1190-
quote_identifier(tle->resdom->resname));
1190+
/*
1191+
* If the update expression is an array assignment, we mustn't
1192+
* put out "attname =" here; it will come out of the display
1193+
* of the ArrayRef node instead.
1194+
*/
1195+
if (! tleIsArrayAssign(tle))
1196+
appendStringInfo(buf, "%s = ",
1197+
quote_identifier(tle->resdom->resname));
11911198
get_tle_expr(tle, context);
11921199
}
11931200

@@ -1409,10 +1416,20 @@ get_rule_expr(Node *node, deparse_context *context)
14091416
case T_ArrayRef:
14101417
{
14111418
ArrayRef *aref = (ArrayRef *) node;
1419+
bool savevarprefix = context->varprefix;
14121420
List *lowlist;
14131421
List *uplist;
14141422

1423+
/*
1424+
* If we are doing UPDATE array[n] = expr, we need to
1425+
* suppress any prefix on the array name. Currently,
1426+
* that is the only context in which we will see a non-null
1427+
* refassgnexpr --- but someday a smarter test may be needed.
1428+
*/
1429+
if (aref->refassgnexpr)
1430+
context->varprefix = false;
14151431
get_rule_expr(aref->refexpr, context);
1432+
context->varprefix = savevarprefix;
14161433
lowlist = aref->reflowerindexpr;
14171434
foreach(uplist, aref->refupperindexpr)
14181435
{
@@ -1426,7 +1443,11 @@ get_rule_expr(Node *node, deparse_context *context)
14261443
get_rule_expr((Node *) lfirst(uplist), context);
14271444
appendStringInfo(buf, "]");
14281445
}
1429-
/* XXX need to do anything with refassgnexpr? */
1446+
if (aref->refassgnexpr)
1447+
{
1448+
appendStringInfo(buf, " = ");
1449+
get_rule_expr(aref->refassgnexpr, context);
1450+
}
14301451
}
14311452
break;
14321453

@@ -1842,6 +1863,31 @@ get_sublink_expr(Node *node, deparse_context *context)
18421863
appendStringInfoChar(buf, ')');
18431864
}
18441865

1866+
/* ----------
1867+
* tleIsArrayAssign - check for array assignment
1868+
* ----------
1869+
*/
1870+
static bool
1871+
tleIsArrayAssign(TargetEntry *tle)
1872+
{
1873+
ArrayRef *aref;
1874+
1875+
if (tle->expr == NULL || !IsA(tle->expr, ArrayRef))
1876+
return false;
1877+
aref = (ArrayRef *) tle->expr;
1878+
if (aref->refassgnexpr == NULL)
1879+
return false;
1880+
/*
1881+
* Currently, it should only be possible to see non-null refassgnexpr
1882+
* if we are indeed looking at an "UPDATE array[n] = expr" situation.
1883+
* So aref->refexpr ought to match the tle's target.
1884+
*/
1885+
if (aref->refexpr == NULL || !IsA(aref->refexpr, Var) ||
1886+
((Var *) aref->refexpr)->varno != tle->resdom->resno)
1887+
elog(NOTICE, "tleIsArrayAssign: I'm confused ...");
1888+
return true;
1889+
}
1890+
18451891
/* ----------
18461892
* quote_identifier - Quote an identifier only if needed
18471893
*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy