diff options
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r-- | src/backend/parser/parse_expr.c | 46 |
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; |