mirror of
https://github.com/postgres/postgres.git
synced 2025-05-20 00:03:14 -04:00
Fix ruleutils to produce correct output for array assignment, such
as UPDATE foo SET arr[3] = 42.
This commit is contained in:
parent
c333d2b329
commit
134fdf34d6
@ -3,7 +3,7 @@
|
||||
* out of its tuple
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
@ -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_const_expr(Const *constval, 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 *get_relation_name(Oid relid);
|
||||
static char *get_attribute_name(Oid relid, int2 attnum);
|
||||
@ -1186,8 +1187,14 @@ get_update_query_def(Query *query, deparse_context *context)
|
||||
|
||||
appendStringInfo(buf, 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);
|
||||
}
|
||||
|
||||
@ -1409,10 +1416,20 @@ get_rule_expr(Node *node, deparse_context *context)
|
||||
case T_ArrayRef:
|
||||
{
|
||||
ArrayRef *aref = (ArrayRef *) node;
|
||||
bool savevarprefix = context->varprefix;
|
||||
List *lowlist;
|
||||
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);
|
||||
context->varprefix = savevarprefix;
|
||||
lowlist = aref->reflowerindexpr;
|
||||
foreach(uplist, aref->refupperindexpr)
|
||||
{
|
||||
@ -1426,7 +1443,11 @@ get_rule_expr(Node *node, deparse_context *context)
|
||||
get_rule_expr((Node *) lfirst(uplist), context);
|
||||
appendStringInfo(buf, "]");
|
||||
}
|
||||
/* XXX need to do anything with refassgnexpr? */
|
||||
if (aref->refassgnexpr)
|
||||
{
|
||||
appendStringInfo(buf, " = ");
|
||||
get_rule_expr(aref->refassgnexpr, context);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1842,6 +1863,31 @@ get_sublink_expr(Node *node, deparse_context *context)
|
||||
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
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user