aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_expr.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2007-02-03 14:06:56 +0000
committerPeter Eisentraut <peter_e@gmx.net>2007-02-03 14:06:56 +0000
commitec020e1ceb94d0ceb3c0eee8c39cd197be7bb3cb (patch)
tree99f52eea439dd239d8e9a7f04f70f567b88ee798 /src/backend/parser/parse_expr.c
parent25dc46334b99f3161d931a608fb49f6eced42065 (diff)
downloadpostgresql-ec020e1ceb94d0ceb3c0eee8c39cd197be7bb3cb.tar.gz
postgresql-ec020e1ceb94d0ceb3c0eee8c39cd197be7bb3cb.zip
Implement XMLSERIALIZE for real. Analogously, make the xml to text cast
observe the xmloption. Reorganize the representation of the XML option in the parse tree and the API to make it easier to manage and understand. Add regression tests for parsing back XML expressions.
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r--src/backend/parser/parse_expr.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index a807ef12de4..e7a37a2cfa6 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.209 2007/01/25 11:53:51 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.210 2007/02/03 14:06:54 petere Exp $
*
*-------------------------------------------------------------------------
*/
@@ -57,6 +57,7 @@ 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 *transformXmlSerialize(ParseState *pstate, XmlSerialize *xs);
static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b);
static Node *transformColumnRef(ParseState *pstate, ColumnRef *cref);
static Node *transformWholeRowRef(ParseState *pstate, char *schemaname,
@@ -224,6 +225,10 @@ transformExpr(ParseState *pstate, Node *expr)
result = transformXmlExpr(pstate, (XmlExpr *) expr);
break;
+ case T_XmlSerialize:
+ result = transformXmlSerialize(pstate, (XmlSerialize *) expr);
+ break;
+
case T_NullTest:
{
NullTest *n = (NullTest *) expr;
@@ -1424,6 +1429,8 @@ transformXmlExpr(ParseState *pstate, XmlExpr *x)
newx->arg_names = lappend(newx->arg_names, makeString(argname));
}
+ newx->xmloption = x->xmloption;
+
if (x->op == IS_XMLELEMENT)
{
foreach(lc, newx->arg_names)
@@ -1484,6 +1491,9 @@ transformXmlExpr(ParseState *pstate, XmlExpr *x)
newe = coerce_to_specific_type(pstate, newe, INT4OID,
"XMLROOT");
break;
+ case IS_XMLSERIALIZE:
+ /* not handled here */
+ break;
case IS_DOCUMENT:
newe = coerce_to_specific_type(pstate, newe, XMLOID,
"IS DOCUMENT");
@@ -1497,6 +1507,38 @@ transformXmlExpr(ParseState *pstate, XmlExpr *x)
}
static Node *
+transformXmlSerialize(ParseState *pstate, XmlSerialize *xs)
+{
+ Oid targetType;
+ int32 targetTypmod;
+ XmlExpr *xexpr;
+
+ xexpr = makeNode(XmlExpr);
+ xexpr->op = IS_XMLSERIALIZE;
+ xexpr->args = list_make1(coerce_to_specific_type(pstate,
+ transformExpr(pstate, xs->expr),
+ XMLOID,
+ "XMLSERIALIZE"));
+
+ targetType = typenameTypeId(pstate, xs->typename);
+ targetTypmod = typenameTypeMod(pstate, xs->typename, targetType);
+
+ xexpr->xmloption = xs->xmloption;
+ /* We actually only need these to be able to parse back the expression. */
+ xexpr->type = targetType;
+ xexpr->typmod = targetTypmod;
+
+ /*
+ * The actual target type is determined this way. SQL allows char
+ * and varchar as target types. We allow anything that can be
+ * cast implicitly from text. This way, user-defined text-like
+ * data types automatically fit in.
+ */
+ return (Node *) coerce_to_target_type(pstate, (Node *) xexpr, TEXTOID, targetType, targetTypmod,
+ COERCION_IMPLICIT, COERCE_IMPLICIT_CAST);
+}
+
+static Node *
transformBooleanTest(ParseState *pstate, BooleanTest *b)
{
const char *clausename;
@@ -1789,6 +1831,8 @@ exprType(Node *expr)
case T_XmlExpr:
if (((XmlExpr *) expr)->op == IS_DOCUMENT)
type = BOOLOID;
+ else if (((XmlExpr *) expr)->op == IS_XMLSERIALIZE)
+ type = TEXTOID;
else
type = XMLOID;
break;