aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r--src/backend/parser/parse_expr.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index b1b6ea81456..234a15b6afb 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.199 2006/12/10 22:13:26 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.200 2006/12/21 16:05:14 petere Exp $
*
*-------------------------------------------------------------------------
*/
@@ -33,6 +33,7 @@
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
+#include "utils/xml.h"
bool Transform_null_equals = false;
@@ -55,6 +56,7 @@ static Node *transformArrayExpr(ParseState *pstate, ArrayExpr *a);
static Node *transformRowExpr(ParseState *pstate, RowExpr *r);
static Node *transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c);
static Node *transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m);
+static Node *transformXmlExpr(ParseState *pstate, XmlExpr *x);
static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b);
static Node *transformColumnRef(ParseState *pstate, ColumnRef *cref);
static Node *transformWholeRowRef(ParseState *pstate, char *schemaname,
@@ -232,6 +234,10 @@ transformExpr(ParseState *pstate, Node *expr)
result = transformBooleanTest(pstate, (BooleanTest *) expr);
break;
+ case T_XmlExpr:
+ result = transformXmlExpr(pstate, (XmlExpr *) expr);
+ break;
+
/*********************************************
* Quietly accept node types that may be presented when we are
* called on an already-transformed tree.
@@ -1409,6 +1415,56 @@ transformBooleanTest(ParseState *pstate, BooleanTest *b)
return (Node *) b;
}
+static Node *
+transformXmlExpr(ParseState *pstate, XmlExpr *x)
+{
+ ListCell *lc;
+ XmlExpr *newx = makeNode(XmlExpr);
+
+ newx->op = x->op;
+ if (x->name)
+ newx->name = map_sql_identifier_to_xml_name(x->name, false);
+ else
+ newx->name = NULL;
+
+ foreach(lc, x->named_args)
+ {
+ ResTarget *r = (ResTarget *) lfirst(lc);
+ Node *expr = transformExpr(pstate, r->val);
+ char *argname = NULL;
+
+ if (r->name)
+ argname = map_sql_identifier_to_xml_name(r->name, false);
+ else if (IsA(r->val, ColumnRef))
+ argname = map_sql_identifier_to_xml_name(FigureColname(r->val), true);
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ x->op == IS_XMLELEMENT
+ ? errmsg("unnamed attribute value must be a column reference")
+ : errmsg("unnamed element value must be a column reference")));
+
+ newx->named_args = lappend(newx->named_args,
+ makeTargetEntry((Expr *) expr, 0, argname, false));
+ }
+
+ foreach(lc, x->args)
+ {
+ Node *e = (Node *) lfirst(lc);
+ Node *newe;
+
+ newe = coerce_to_xml(pstate, transformExpr(pstate, e),
+ (x->op == IS_XMLCONCAT
+ ? "XMLCONCAT"
+ : (x->op == IS_XMLELEMENT
+ ? "XMLELEMENT"
+ : "XMLFOREST")));
+ newx->args = lappend(newx->args, newe);
+ }
+
+ return (Node *) newx;
+}
+
/*
* Construct a whole-row reference to represent the notation "relation.*".
*
@@ -1668,6 +1724,9 @@ exprType(Node *expr)
case T_BooleanTest:
type = BOOLOID;
break;
+ case T_XmlExpr:
+ type = XMLOID;
+ break;
case T_CoerceToDomain:
type = ((CoerceToDomain *) expr)->resulttype;
break;