* 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.
*
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);
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);
}
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)
{
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;
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
*