Commit 134fdf34 authored by Tom Lane's avatar Tom Lane

Fix ruleutils to produce correct output for array assignment, such

as UPDATE foo SET arr[3] = 42.
parent c333d2b3
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* out of its tuple * out of its tuple
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.58 2000/08/08 15:42:21 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.59 2000/08/12 04:04:53 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -107,6 +107,7 @@ static void get_func_expr(Expr *expr, deparse_context *context); ...@@ -107,6 +107,7 @@ static void get_func_expr(Expr *expr, deparse_context *context);
static void get_tle_expr(TargetEntry *tle, deparse_context *context); static void get_tle_expr(TargetEntry *tle, deparse_context *context);
static void get_const_expr(Const *constval, deparse_context *context); static void get_const_expr(Const *constval, deparse_context *context);
static void get_sublink_expr(Node *node, deparse_context *context); static void get_sublink_expr(Node *node, deparse_context *context);
static bool tleIsArrayAssign(TargetEntry *tle);
static char *quote_identifier(char *ident); static char *quote_identifier(char *ident);
static char *get_relation_name(Oid relid); static char *get_relation_name(Oid relid);
static char *get_attribute_name(Oid relid, int2 attnum); static char *get_attribute_name(Oid relid, int2 attnum);
...@@ -1186,8 +1187,14 @@ get_update_query_def(Query *query, deparse_context *context) ...@@ -1186,8 +1187,14 @@ get_update_query_def(Query *query, deparse_context *context)
appendStringInfo(buf, sep); appendStringInfo(buf, sep);
sep = ", "; sep = ", ";
appendStringInfo(buf, "%s = ", /*
quote_identifier(tle->resdom->resname)); * If the update expression is an array assignment, we mustn't
* put out "attname =" here; it will come out of the display
* of the ArrayRef node instead.
*/
if (! tleIsArrayAssign(tle))
appendStringInfo(buf, "%s = ",
quote_identifier(tle->resdom->resname));
get_tle_expr(tle, context); get_tle_expr(tle, context);
} }
...@@ -1409,10 +1416,20 @@ get_rule_expr(Node *node, deparse_context *context) ...@@ -1409,10 +1416,20 @@ get_rule_expr(Node *node, deparse_context *context)
case T_ArrayRef: case T_ArrayRef:
{ {
ArrayRef *aref = (ArrayRef *) node; ArrayRef *aref = (ArrayRef *) node;
bool savevarprefix = context->varprefix;
List *lowlist; List *lowlist;
List *uplist; List *uplist;
/*
* If we are doing UPDATE array[n] = expr, we need to
* suppress any prefix on the array name. Currently,
* that is the only context in which we will see a non-null
* refassgnexpr --- but someday a smarter test may be needed.
*/
if (aref->refassgnexpr)
context->varprefix = false;
get_rule_expr(aref->refexpr, context); get_rule_expr(aref->refexpr, context);
context->varprefix = savevarprefix;
lowlist = aref->reflowerindexpr; lowlist = aref->reflowerindexpr;
foreach(uplist, aref->refupperindexpr) foreach(uplist, aref->refupperindexpr)
{ {
...@@ -1426,7 +1443,11 @@ get_rule_expr(Node *node, deparse_context *context) ...@@ -1426,7 +1443,11 @@ get_rule_expr(Node *node, deparse_context *context)
get_rule_expr((Node *) lfirst(uplist), context); get_rule_expr((Node *) lfirst(uplist), context);
appendStringInfo(buf, "]"); appendStringInfo(buf, "]");
} }
/* XXX need to do anything with refassgnexpr? */ if (aref->refassgnexpr)
{
appendStringInfo(buf, " = ");
get_rule_expr(aref->refassgnexpr, context);
}
} }
break; break;
...@@ -1842,6 +1863,31 @@ get_sublink_expr(Node *node, deparse_context *context) ...@@ -1842,6 +1863,31 @@ get_sublink_expr(Node *node, deparse_context *context)
appendStringInfoChar(buf, ')'); appendStringInfoChar(buf, ')');
} }
/* ----------
* tleIsArrayAssign - check for array assignment
* ----------
*/
static bool
tleIsArrayAssign(TargetEntry *tle)
{
ArrayRef *aref;
if (tle->expr == NULL || !IsA(tle->expr, ArrayRef))
return false;
aref = (ArrayRef *) tle->expr;
if (aref->refassgnexpr == NULL)
return false;
/*
* Currently, it should only be possible to see non-null refassgnexpr
* if we are indeed looking at an "UPDATE array[n] = expr" situation.
* So aref->refexpr ought to match the tle's target.
*/
if (aref->refexpr == NULL || !IsA(aref->refexpr, Var) ||
((Var *) aref->refexpr)->varno != tle->resdom->resno)
elog(NOTICE, "tleIsArrayAssign: I'm confused ...");
return true;
}
/* ---------- /* ----------
* quote_identifier - Quote an identifier only if needed * quote_identifier - Quote an identifier only if needed
* *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment