]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Code review for XML patch. Instill a bit of sanity in the location of
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 24 Dec 2006 00:29:20 +0000 (00:29 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 24 Dec 2006 00:29:20 +0000 (00:29 +0000)
the XmlExpr code in various lists, use a representation that has some hope
of reverse-listing correctly (though it's still a de-escaping function
shy of correctness), generally try to make it look more like Postgres
coding conventions.

27 files changed:
doc/src/sgml/errcodes.sgml
doc/src/sgml/installation.sgml
src/backend/executor/execQual.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/backend/optimizer/util/clauses.c
src/backend/parser/gram.y
src/backend/parser/keywords.c
src/backend/parser/parse_clause.c
src/backend/parser/parse_coerce.c
src/backend/parser/parse_expr.c
src/backend/parser/parse_target.c
src/backend/utils/adt/ruleutils.c
src/backend/utils/adt/xml.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.h
src/include/nodes/execnodes.h
src/include/nodes/nodes.h
src/include/nodes/primnodes.h
src/include/parser/parse_coerce.h
src/include/utils/xml.h
src/pl/plpgsql/src/pl_exec.c
src/pl/plpgsql/src/plerrcodes.h
src/test/regress/expected/opr_sanity.out
src/test/regress/sql/opr_sanity.sql

index bf06cfaf5e5874d6f821c54acff1e8f51d0ae1d6..ced6197d978527fefb601f3cb9f6e0bedcd60eea 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.20 2006/06/16 23:29:26 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.21 2006/12/24 00:29:17 tgl Exp $ -->
 
 <appendix id="errcodes-appendix">
  <title><productname>PostgreSQL</productname> Error Codes</title>
 <entry>untranslatable_character</entry>
 </row>
 
+<row>
+<entry><literal>2200M</literal></entry>
+<entry>INVALID XML DOCUMENT</entry>
+<entry>invalid_xml_document</entry>
+</row>
+
+<row>
+<entry><literal>2200N</literal></entry>
+<entry>INVALID XML CONTENT</entry>
+<entry>invalid_xml_content</entry>
+</row>
+
+<row>
+<entry><literal>2200S</literal></entry>
+<entry>INVALID XML COMMENT</entry>
+<entry>invalid_xml_comment</entry>
+</row>
+
+<row>
+<entry><literal>2200T</literal></entry>
+<entry>INVALID XML PROCESSING INSTRUCTION</entry>
+<entry>invalid_xml_processing_instruction</entry>
+</row>
 
 <row>
 <entry spanname="span13"><emphasis role="bold">Class 23 &mdash; Integrity Constraint Violation</></entry>
index a56ba9ad9b8461c2fe02f34e61b2d8e86fc536dc..3119671fc4be7f443c38f8ecd6164b00e49317fa 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/installation.sgml,v 1.269 2006/12/21 16:05:13 petere Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/installation.sgml,v 1.270 2006/12/24 00:29:17 tgl Exp $ -->
 
 <chapter id="installation">
  <title><![%standalone-include[<productname>PostgreSQL</>]]>
@@ -909,7 +909,7 @@ su - postgres
        <term><option>--with-libxml</option></term>
        <listitem>
         <para>
-         Build with libxml, required for SQL/XML support.
+         Build with libxml (enables SQL/XML support).
         </para>
        </listitem>
       </varlistentry>
index 1e9865c300755d6c3998eb12d15a62d0b66f67c7..145da9b46368d67b3f98f50c19bbf5bd0664aaf3 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.201 2006/12/23 00:43:09 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.202 2006/12/24 00:29:18 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -117,11 +117,11 @@ static Datum ExecEvalCoalesce(CoalesceExprState *coalesceExpr,
 static Datum ExecEvalMinMax(MinMaxExprState *minmaxExpr,
                           ExprContext *econtext,
                           bool *isNull, ExprDoneCond *isDone);
+static Datum ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
+                                                bool *isNull, ExprDoneCond *isDone);
 static Datum ExecEvalNullIf(FuncExprState *nullIfExpr,
                           ExprContext *econtext,
                           bool *isNull, ExprDoneCond *isDone);
-static Datum ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
-                                                bool *isNull, ExprDoneCond *isDone);
 static Datum ExecEvalNullTest(NullTestState *nstate,
                                 ExprContext *econtext,
                                 bool *isNull, ExprDoneCond *isDone);
@@ -2638,6 +2638,237 @@ ExecEvalMinMax(MinMaxExprState *minmaxExpr, ExprContext *econtext,
        return result;
 }
 
+/* ----------------------------------------------------------------
+ *             ExecEvalXml
+ * ----------------------------------------------------------------
+ */
+static Datum
+ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
+                       bool *isNull, ExprDoneCond *isDone)
+{
+       XmlExpr            *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
+       text               *result;
+       StringInfoData  buf;
+       Datum                   value;
+       bool                    isnull;
+       char               *str;
+       ListCell           *arg;
+       ListCell   *narg;
+       bool    found_arg;
+       int                     i;
+
+       if (isDone)
+               *isDone = ExprSingleResult;
+       *isNull = true;                         /* until we get a result */
+
+       switch (xexpr->op)
+       {
+               case IS_XMLCONCAT:
+                       initStringInfo(&buf);
+                       foreach(arg, xmlExpr->args)
+                       {
+                               ExprState       *e = (ExprState *) lfirst(arg);
+
+                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               if (!isnull)
+                               {
+                                       /* we know the value is XML type */
+                                       str = DatumGetCString(DirectFunctionCall1(xml_out,
+                                                                                                                         value));
+                                       appendStringInfoString(&buf, str);
+                                       pfree(str);
+                                       *isNull = false;
+                               }
+                       }
+                       break;
+
+               case IS_XMLELEMENT:
+                       initStringInfo(&buf);
+                       *isNull = false;
+                       appendStringInfo(&buf, "<%s", xexpr->name);
+                       i = 0;
+                       forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
+                       {
+                               ExprState       *e = (ExprState *) lfirst(arg);
+                               char    *argname = strVal(lfirst(narg));
+
+                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               if (!isnull)
+                               {
+                                       str = OutputFunctionCall(&xmlExpr->named_outfuncs[i],
+                                                                                        value);
+                                       appendStringInfo(&buf, " %s=\"%s\"", argname, str);
+                                       pfree(str);
+                               }
+                               i++;
+                       }
+
+                       found_arg = false;
+                       foreach(arg, xmlExpr->args)
+                       {
+                               ExprState       *e = (ExprState *) lfirst(arg);
+
+                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               if (!isnull)
+                               {
+                                       if (!found_arg)
+                                       {
+                                               appendStringInfoChar(&buf, '>');
+                                               found_arg = true;
+                                       }
+
+                                       /* we know the value is XML type */
+                                       str = DatumGetCString(DirectFunctionCall1(xml_out,
+                                                                                                                         value));
+                                       appendStringInfoString(&buf, str);
+                                       pfree(str);
+                               }
+                       }
+
+                       if (!found_arg)
+                               appendStringInfo(&buf, "/>");
+                       else
+                               appendStringInfo(&buf, "</%s>", xexpr->name);
+                       break;
+
+               case IS_XMLFOREST:
+                       initStringInfo(&buf);
+                       i = 0;
+                       forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
+                       {
+                               ExprState       *e = (ExprState *) lfirst(arg);
+                               char    *argname = strVal(lfirst(narg));
+
+                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               if (!isnull)
+                               {
+                                       str = OutputFunctionCall(&xmlExpr->named_outfuncs[i],
+                                                                                        value);
+                                       appendStringInfo(&buf, "<%s>%s</%s>",
+                                                                        argname, str, argname);
+                                       pfree(str);
+                                       *isNull = false;
+                               }
+                               i++;
+                       }
+                       break;
+
+                       /* The remaining cases don't need to set up buf */
+               case IS_XMLPARSE:
+                       {
+                               ExprState       *e;
+                               text        *data;
+                               bool            is_document;
+                               bool            preserve_whitespace;
+
+                               /* arguments are known to be text, bool, bool */
+                               Assert(list_length(xmlExpr->args) == 3);
+
+                               e = (ExprState *) linitial(xmlExpr->args);
+                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               if (isnull)
+                                       return (Datum) 0;
+                               data = DatumGetTextP(value);
+
+                               e = (ExprState *) lsecond(xmlExpr->args);
+                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               if (isnull)             /* probably can't happen */
+                                       return (Datum) 0;
+                               is_document = DatumGetBool(value);
+
+                               e = (ExprState *) lthird(xmlExpr->args);
+                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               if (isnull)             /* probably can't happen */
+                                       return (Datum) 0;
+                               preserve_whitespace = DatumGetBool(value);
+
+                               *isNull = false;
+
+                               return PointerGetDatum(xmlparse(data,
+                                                                                               is_document,
+                                                                                               preserve_whitespace));
+                       }
+                       break;
+
+               case IS_XMLPI:
+                       {
+                               ExprState       *e;
+                               text        *arg;
+
+                               /* optional argument is known to be text */
+                               Assert(list_length(xmlExpr->args) <= 1);
+
+                               if (xmlExpr->args)
+                               {
+                                       e = (ExprState *) linitial(xmlExpr->args);
+                                       value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                                       if (isnull)
+                                               return (Datum) 0;
+                                       arg = DatumGetTextP(value);
+                               }
+                               else
+                                       arg = NULL;
+
+                               *isNull = false;
+
+                               return PointerGetDatum(xmlpi(xexpr->name, arg));
+                       }
+                       break;
+
+               case IS_XMLROOT:
+                       {
+                               ExprState       *e;
+                               xmltype         *data;
+                               text            *version;
+                               int                     standalone;
+
+                               /* arguments are known to be xml, text, bool */
+                               Assert(list_length(xmlExpr->args) == 3);
+
+                               e = (ExprState *) linitial(xmlExpr->args);
+                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               if (isnull)
+                                       return (Datum) 0;
+                               data = DatumGetXmlP(value);
+
+                               e = (ExprState *) lsecond(xmlExpr->args);
+                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               if (isnull)
+                                       version = NULL;
+                               else
+                                       version = DatumGetTextP(value);
+
+                               e = (ExprState *) lthird(xmlExpr->args);
+                               value = ExecEvalExpr(e, econtext, &isnull, NULL);
+                               if (isnull)
+                                       standalone = 0;
+                               else
+                                       standalone = (DatumGetBool(value) ? 1 : -1);
+
+                               *isNull = false;
+
+                               return PointerGetDatum(xmlroot(data,
+                                                                                          version,
+                                                                                          standalone));
+                       }
+                       break;
+       }
+
+       if (*isNull)
+               result = NULL;
+       else
+       {
+               int             len = buf.len + VARHDRSZ;
+
+               result = palloc(len);
+               VARATT_SIZEP(result) = len;
+               memcpy(VARDATA(result), buf.data, buf.len);
+       }
+
+       pfree(buf.data);
+       return PointerGetDatum(result);
+}
+
 /* ----------------------------------------------------------------
  *             ExecEvalNullIf
  *
@@ -2881,120 +3112,6 @@ ExecEvalBooleanTest(GenericExprState *bstate,
        }
 }
 
-/* ----------------------------------------------------------------
- *             ExecEvalXml
- * ----------------------------------------------------------------
- */
-static Datum
-ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
-                       bool *isNull, ExprDoneCond *isDone)
-{
-       StringInfoData  buf;
-       bool                    isnull;
-       ListCell           *arg;
-       text               *result = NULL;
-       int                     len;
-
-       initStringInfo(&buf);
-
-       *isNull = false;
-
-       if (isDone)
-               *isDone = ExprSingleResult;
-
-       switch (xmlExpr->op)
-       {
-               case IS_XMLCONCAT:
-                       *isNull = true;
-
-                       foreach(arg, xmlExpr->args)
-                       {
-                               ExprState       *e = (ExprState *) lfirst(arg);
-                               Datum           value = ExecEvalExpr(e, econtext, &isnull, NULL);
-
-                               if (!isnull)
-                               {
-                                       appendStringInfoString(&buf, DatumGetCString(OidFunctionCall1(xmlExpr->arg_typeout, value)));
-                                       *isNull = false;
-                               }
-                       }
-                       break;
-
-               case IS_XMLELEMENT:
-                       {
-                               int state = 0, i = 0;
-                               appendStringInfo(&buf, "<%s", xmlExpr->name);
-                               foreach(arg, xmlExpr->named_args)
-                               {
-                                       GenericExprState *gstate = (GenericExprState *) lfirst(arg);
-                                       Datum value = ExecEvalExpr(gstate->arg, econtext, &isnull, NULL);
-                                       if (!isnull)
-                                       {
-                                               char *outstr = DatumGetCString(OidFunctionCall1(xmlExpr->named_args_tcache[i], value));
-                                               appendStringInfo(&buf, " %s=\"%s\"", xmlExpr->named_args_ncache[i], outstr);
-                                               pfree(outstr);
-                                       }
-                                       i++;
-                               }
-                               if (xmlExpr->args)
-                               {
-                                       ExprState       *expr = linitial(xmlExpr->args);
-                                       Datum           value = ExecEvalExpr(expr, econtext, &isnull, NULL);
-
-                                       if (!isnull)
-                                       {
-                                               char *outstr = DatumGetCString(OidFunctionCall1(xmlExpr->arg_typeout, value));
-                                               if (state == 0)
-                                               {
-                                                       appendStringInfoChar(&buf, '>');
-                                                       state = 1;
-                                               }
-                                               appendStringInfo(&buf, "%s", outstr);
-                                               pfree(outstr);
-                                       }
-                               }
-
-                               if (state == 0)
-                                       appendStringInfo(&buf, "/>");
-                               else if (state == 1)
-                                       appendStringInfo(&buf, "</%s>", xmlExpr->name);         
-
-                       }
-                       break;
-
-               case IS_XMLFOREST:
-                       {
-                               /* only if all argumets are null returns null */
-                               int i = 0; 
-                               *isNull = true;
-                               foreach(arg, xmlExpr->named_args)
-                               {
-                                       GenericExprState *gstate = (GenericExprState *) lfirst(arg);
-                                       Datum value = ExecEvalExpr(gstate->arg, econtext, &isnull, NULL);
-                                       if (!isnull)
-                                       {
-                                               char *outstr = DatumGetCString(OidFunctionCall1(xmlExpr->named_args_tcache[i], value));
-                                               appendStringInfo(&buf, "<%s>%s</%s>", xmlExpr->named_args_ncache[i], outstr, xmlExpr->named_args_ncache[i]);
-                                               pfree(outstr);
-                                               *isNull = false;
-                                       }
-                                       i += 1;
-                               }               
-                       }
-                       break;
-               default:
-                       break;
-       }
-
-       len = buf.len + VARHDRSZ;
-       result = palloc(len);
-       VARATT_SIZEP(result) = len;
-       memcpy(VARDATA(result), buf.data, buf.len);
-       pfree(buf.data);
-       PG_RETURN_TEXT_P(result);
-}
-
 /*
  * ExecEvalCoerceToDomain
  *
@@ -3794,59 +3911,45 @@ ExecInitExpr(Expr *node, PlanState *parent)
                        break;
                case T_XmlExpr:
                        {
-                               List                    *outlist; 
-                               ListCell                *arg;
                                XmlExpr                 *xexpr = (XmlExpr *) node;
                                XmlExprState    *xstate = makeNode(XmlExprState);
-                               int                             i = 0; 
-                               Oid                             typeout;
-               
-                               xstate->name = xexpr->name;
-                                                               
+                               List                    *outlist;
+                               ListCell                *arg;
+                               int                             i;
+
                                xstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalXml;
-                               xstate->op = xexpr->op;
-                               
+                               xstate->named_outfuncs = (FmgrInfo *)
+                                       palloc0(list_length(xexpr->named_args) * sizeof(FmgrInfo));
                                outlist = NIL;
-                               if (xexpr->named_args)
-                               {
-                                       xstate->named_args_tcache = (Oid *) palloc(list_length(xexpr->named_args) * sizeof(int));
-                                       xstate->named_args_ncache = (char **) palloc(list_length(xexpr->named_args) * sizeof(char *));
-                                       
-                                       i = 0;
-                                       foreach(arg, xexpr->named_args)
-                                       {
-                                               bool            tpisvarlena;
-                                               Expr            *e = (Expr *) lfirst(arg);
-                                               ExprState       *estate = ExecInitExpr(e, parent);
-                                               TargetEntry     *tle;
-                                               outlist = lappend(outlist, estate);                                     
-                                               tle = (TargetEntry *) ((GenericExprState *) estate)->xprstate.expr;
-                                               getTypeOutputInfo(exprType((Node *)tle->expr), &typeout, &tpisvarlena);
-                                               xstate->named_args_ncache[i] = tle->resname;
-                                               xstate->named_args_tcache[i] = typeout;
-                                               i++;
-                                       }       
-                               }
-                               else
+                               i = 0;
+                               foreach(arg, xexpr->named_args)
                                {
-                                       xstate->named_args_tcache = NULL;
-                                       xstate->named_args_ncache = NULL;
+                                       Expr            *e = (Expr *) lfirst(arg);
+                                       ExprState       *estate;
+                                       Oid                     typOutFunc;
+                                       bool            typIsVarlena;
+
+                                       estate = ExecInitExpr(e, parent);
+                                       outlist = lappend(outlist, estate);
+
+                                       getTypeOutputInfo(exprType((Node *) e),
+                                                                         &typOutFunc, &typIsVarlena);
+                                       fmgr_info(typOutFunc, &xstate->named_outfuncs[i]);
+                                       i++;
                                }
                                xstate->named_args = outlist;
 
-                               outlist = NIL;                          
+                               outlist = NIL;
                                foreach(arg, xexpr->args)
                                {
-                                       bool            tpisvarlena;
-                                       ExprState       *estate;
-                                       Expr            *e = (Expr *) lfirst(arg);
-                                       getTypeOutputInfo(exprType((Node *)e), &typeout, &tpisvarlena);
+                                       Expr            *e = (Expr *) lfirst(arg);
+                                       ExprState       *estate;
+
                                        estate = ExecInitExpr(e, parent);
                                        outlist = lappend(outlist, estate);
                                }
-                               xstate->arg_typeout = typeout;
                                xstate->args = outlist;
-                               
+
                                state = (ExprState *) xstate;
                        }
                        break;
index ca841cb181aaed174ed03f1aa83970da5198d0b3..d46ed57d830e0b7a85622fd0bb32024bf857701a 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.356 2006/12/23 00:43:09 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.357 2006/12/24 00:29:18 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1093,6 +1093,23 @@ _copyMinMaxExpr(MinMaxExpr *from)
        return newnode;
 }
 
+/*
+ * _copyXmlExpr
+ */
+static XmlExpr *
+_copyXmlExpr(XmlExpr *from)
+{
+       XmlExpr *newnode = makeNode(XmlExpr);
+
+       COPY_SCALAR_FIELD(op);
+       COPY_STRING_FIELD(name);
+       COPY_NODE_FIELD(named_args);
+       COPY_NODE_FIELD(arg_names);
+       COPY_NODE_FIELD(args);
+
+       return newnode;
+}
+
 /*
  * _copyNullIfExpr (same as OpExpr)
  */
@@ -1138,22 +1155,6 @@ _copyBooleanTest(BooleanTest *from)
        return newnode;
 }
 
-/*
- * _copyXmlExpr
- */
-static XmlExpr *
-_copyXmlExpr(XmlExpr *from)
-{
-       XmlExpr *newnode = makeNode(XmlExpr);
-
-       COPY_SCALAR_FIELD(op);
-       COPY_STRING_FIELD(name);
-       COPY_NODE_FIELD(named_args);
-       COPY_NODE_FIELD(args);
-
-       return newnode;
-}
-
 /*
  * _copyCoerceToDomain
  */
@@ -2977,6 +2978,9 @@ copyObject(void *from)
                case T_MinMaxExpr:
                        retval = _copyMinMaxExpr(from);
                        break;
+               case T_XmlExpr:
+                       retval = _copyXmlExpr(from);
+                       break;
                case T_NullIfExpr:
                        retval = _copyNullIfExpr(from);
                        break;
@@ -2986,9 +2990,6 @@ copyObject(void *from)
                case T_BooleanTest:
                        retval = _copyBooleanTest(from);
                        break;
-               case T_XmlExpr:
-                       retval = _copyXmlExpr(from);
-                       break;
                case T_CoerceToDomain:
                        retval = _copyCoerceToDomain(from);
                        break;
index a7c4ef4e2a819e5838176bf382ff7752088d5bd4..29bff448c7f53ce4387cb401cc66c13aa0876427 100644 (file)
@@ -18,7 +18,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.290 2006/12/23 00:43:10 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.291 2006/12/24 00:29:18 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -454,6 +454,18 @@ _equalMinMaxExpr(MinMaxExpr *a, MinMaxExpr *b)
        return true;
 }
 
+static bool
+_equalXmlExpr(XmlExpr *a, XmlExpr *b)
+{
+       COMPARE_SCALAR_FIELD(op);
+       COMPARE_STRING_FIELD(name);
+       COMPARE_NODE_FIELD(named_args);
+       COMPARE_NODE_FIELD(arg_names);
+       COMPARE_NODE_FIELD(args);
+
+       return true;
+}
+
 static bool
 _equalNullIfExpr(NullIfExpr *a, NullIfExpr *b)
 {
@@ -495,17 +507,6 @@ _equalBooleanTest(BooleanTest *a, BooleanTest *b)
        return true;
 }
 
-static bool
-_equalXmlExpr(XmlExpr *a, XmlExpr *b)
-{
-       COMPARE_SCALAR_FIELD(op);
-       COMPARE_STRING_FIELD(name);
-       COMPARE_NODE_FIELD(named_args);
-       COMPARE_NODE_FIELD(args);
-
-       return true;
-}
-
 static bool
 _equalCoerceToDomain(CoerceToDomain *a, CoerceToDomain *b)
 {
@@ -1971,6 +1972,9 @@ equal(void *a, void *b)
                case T_MinMaxExpr:
                        retval = _equalMinMaxExpr(a, b);
                        break;
+               case T_XmlExpr:
+                       retval = _equalXmlExpr(a, b);
+                       break;
                case T_NullIfExpr:
                        retval = _equalNullIfExpr(a, b);
                        break;
@@ -1980,9 +1984,6 @@ equal(void *a, void *b)
                case T_BooleanTest:
                        retval = _equalBooleanTest(a, b);
                        break;
-               case T_XmlExpr:
-                       retval = _equalXmlExpr(a, b);
-                       break;
                case T_CoerceToDomain:
                        retval = _equalCoerceToDomain(a, b);
                        break;
index b18b6988cfa776163141f877c8b570eaf6ae52c5..4911d6ed4044c33a197fe268836e5847783c213c 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.288 2006/12/23 00:43:10 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.289 2006/12/24 00:29:18 tgl Exp $
  *
  * NOTES
  *       Every node type that can appear in stored rules' parsetrees *must*
@@ -892,6 +892,18 @@ _outMinMaxExpr(StringInfo str, MinMaxExpr *node)
        WRITE_NODE_FIELD(args);
 }
 
+static void
+_outXmlExpr(StringInfo str, XmlExpr *node)
+{
+       WRITE_NODE_TYPE("XMLEXPR");
+       
+       WRITE_ENUM_FIELD(op, XmlExprOp);
+       WRITE_STRING_FIELD(name);
+       WRITE_NODE_FIELD(named_args);
+       WRITE_NODE_FIELD(arg_names);
+       WRITE_NODE_FIELD(args);
+}
+
 static void
 _outNullIfExpr(StringInfo str, NullIfExpr *node)
 {
@@ -922,17 +934,6 @@ _outBooleanTest(StringInfo str, BooleanTest *node)
        WRITE_ENUM_FIELD(booltesttype, BoolTestType);
 }
 
-static void
-_outXmlExpr(StringInfo str, XmlExpr *node)
-{
-       WRITE_NODE_TYPE("XMLEXPR");
-       
-       WRITE_ENUM_FIELD(op, XmlExprOp);
-       WRITE_STRING_FIELD(name);
-       WRITE_NODE_FIELD(named_args);
-       WRITE_NODE_FIELD(args);
-}
-
 static void
 _outCoerceToDomain(StringInfo str, CoerceToDomain *node)
 {
@@ -2026,6 +2027,9 @@ _outNode(StringInfo str, void *obj)
                        case T_MinMaxExpr:
                                _outMinMaxExpr(str, obj);
                                break;
+                       case T_XmlExpr:
+                               _outXmlExpr(str, obj);
+                               break;
                        case T_NullIfExpr:
                                _outNullIfExpr(str, obj);
                                break;
@@ -2035,9 +2039,6 @@ _outNode(StringInfo str, void *obj)
                        case T_BooleanTest:
                                _outBooleanTest(str, obj);
                                break;
-                       case T_XmlExpr:
-                               _outXmlExpr(str, obj);
-                               break;
                        case T_CoerceToDomain:
                                _outCoerceToDomain(str, obj);
                                break;
index 37b39439eb0d4f69066b5c5525f0497d654e38cb..781eeee14f16727414f863e12b051a74dd4d9d83 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.198 2006/12/23 00:43:10 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.199 2006/12/24 00:29:18 tgl Exp $
  *
  * NOTES
  *       Path and Plan nodes do not have any readfuncs support, because we
@@ -708,6 +708,23 @@ _readMinMaxExpr(void)
        READ_DONE();
 }
 
+/*
+ * _readXmlExpr
+ */
+static XmlExpr *
+_readXmlExpr(void)
+{
+       READ_LOCALS(XmlExpr);
+
+       READ_ENUM_FIELD(op, XmlExprOp);
+       READ_STRING_FIELD(name);
+       READ_NODE_FIELD(named_args);
+       READ_NODE_FIELD(arg_names);
+       READ_NODE_FIELD(args);
+
+       READ_DONE();
+}
+
 /*
  * _readNullIfExpr
  */
@@ -764,22 +781,6 @@ _readBooleanTest(void)
        READ_DONE();
 }
 
-/*
- * _readXmlExpr
- */
-static XmlExpr *
-_readXmlExpr(void)
-{
-       READ_LOCALS(XmlExpr);
-
-       READ_ENUM_FIELD(op, XmlExprOp);
-       READ_STRING_FIELD(name);
-       READ_NODE_FIELD(named_args);
-       READ_NODE_FIELD(args);
-
-       READ_DONE();
-}
-
 /*
  * _readCoerceToDomain
  */
@@ -1024,14 +1025,14 @@ parseNodeString(void)
                return_value = _readCoalesceExpr();
        else if (MATCH("MINMAX", 6))
                return_value = _readMinMaxExpr();
+       else if (MATCH("XMLEXPR", 7))
+               return_value = _readXmlExpr();
        else if (MATCH("NULLIFEXPR", 10))
                return_value = _readNullIfExpr();
        else if (MATCH("NULLTEST", 8))
                return_value = _readNullTest();
        else if (MATCH("BOOLEANTEST", 11))
                return_value = _readBooleanTest();
-       else if (MATCH("XMLEXPR", 7))
-               return_value = _readXmlExpr();
        else if (MATCH("COERCETODOMAIN", 14))
                return_value = _readCoerceToDomain();
        else if (MATCH("COERCETODOMAINVALUE", 19))
index 0f720c40e932e8a5563d1cdab4cd1188f62545ba..5ad97aabc3439d997d5246face2ccd16643d7b79 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.225 2006/12/23 00:43:10 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.226 2006/12/24 00:29:18 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -557,10 +557,10 @@ expression_returns_set_walker(Node *node, void *context)
                return false;
        if (IsA(node, MinMaxExpr))
                return false;
-       if (IsA(node, NullIfExpr))
-               return false;
        if (IsA(node, XmlExpr))
                return false;
+       if (IsA(node, NullIfExpr))
+               return false;
 
        return expression_tree_walker(node, expression_returns_set_walker,
                                                                  context);
@@ -872,14 +872,14 @@ contain_nonstrict_functions_walker(Node *node, void *context)
                return true;
        if (IsA(node, MinMaxExpr))
                return true;
+       if (IsA(node, XmlExpr))
+               return true;
        if (IsA(node, NullIfExpr))
                return true;
        if (IsA(node, NullTest))
                return true;
        if (IsA(node, BooleanTest))
                return true;
-       if (IsA(node, XmlExpr))
-               return true;
        return expression_tree_walker(node, contain_nonstrict_functions_walker,
                                                                  context);
 }
@@ -3328,22 +3328,23 @@ expression_tree_walker(Node *node,
                        return walker(((CoalesceExpr *) node)->args, context);
                case T_MinMaxExpr:
                        return walker(((MinMaxExpr *) node)->args, context);
-               case T_NullIfExpr:
-                       return walker(((NullIfExpr *) node)->args, context);
-               case T_NullTest:
-                       return walker(((NullTest *) node)->arg, context);
-               case T_BooleanTest:
-                       return walker(((BooleanTest *) node)->arg, context);
                case T_XmlExpr:
                        {
                                XmlExpr *xexpr = (XmlExpr *) node;
                                
                                if (walker(xexpr->named_args, context))
                                        return true;
+                               /* we assume walker doesn't care about arg_names */
                                if (walker(xexpr->args, context))
                                        return true;
                        }
                        break;
+               case T_NullIfExpr:
+                       return walker(((NullIfExpr *) node)->args, context);
+               case T_NullTest:
+                       return walker(((NullTest *) node)->arg, context);
+               case T_BooleanTest:
+                       return walker(((BooleanTest *) node)->arg, context);
                case T_CoerceToDomain:
                        return walker(((CoerceToDomain *) node)->arg, context);
                case T_TargetEntry:
@@ -3874,6 +3875,7 @@ expression_tree_mutator(Node *node,
 
                                FLATCOPY(newnode, xexpr, XmlExpr);
                                MUTATE(newnode->named_args, xexpr->named_args, List *);
+                               /* assume mutator does not care about arg_names */
                                MUTATE(newnode->args, xexpr->args, List *);
                                return (Node *) newnode;
                        }
index cc400407363e660df5060a223cf8c1b27a8cf152..a1511870f28a425bd6f37e69b33313d9bca2a9c8 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.569 2006/12/21 16:05:14 petere Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.570 2006/12/24 00:29:18 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -348,8 +348,8 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
 
 %type <target> xml_attribute_el
 %type <list>   xml_attribute_list xml_attributes
-%type <node>   xml_root_version
-%type <ival>   opt_xml_root_standalone document_or_content xml_whitespace_option
+%type <node>   xml_root_version opt_xml_root_standalone
+%type <boolean>        document_or_content xml_whitespace_option
 
 
 /*
@@ -371,13 +371,13 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
        CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
        CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
        COMMITTED CONCURRENTLY CONNECTION CONSTRAINT CONSTRAINTS
-       CONTENT CONVERSION_P CONVERT COPY CREATE CREATEDB
+       CONTENT_P CONVERSION_P CONVERT COPY CREATE CREATEDB
        CREATEROLE CREATEUSER CROSS CSV CURRENT_DATE CURRENT_ROLE CURRENT_TIME
        CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
 
        DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
        DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS
-       DESC DISABLE_P DISTINCT DO DOCUMENT DOMAIN_P DOUBLE_P DROP
+       DESC DISABLE_P DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
 
        EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING
        EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
@@ -404,7 +404,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
 
        MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
 
-       NAME NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
+       NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
        NOCREATEROLE NOCREATEUSER NOINHERIT NOLOGIN_P NONE NOSUPERUSER
        NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NUMERIC
 
@@ -423,9 +423,9 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
 
        SAVEPOINT SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE
        SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
-       SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE START STATEMENT
-       STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP SUBSTRING SUPERUSER_P SYMMETRIC
-       SYSID SYSTEM_P
+       SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
+       STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
+       SYMMETRIC SYSID SYSTEM_P
 
        TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP
        TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
@@ -434,15 +434,15 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
        UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
        UPDATE USER USING
 
-       VACUUM VALID VALIDATOR VALUE VALUES VARCHAR VARYING
-       VERBOSE VERSION VIEW VOLATILE
+       VACUUM VALID VALIDATOR VALUE_P VALUES VARCHAR VARYING
+       VERBOSE VERSION_P VIEW VOLATILE
 
-       WHEN WHERE WHITESPACE WITH WITHOUT WORK WRITE
+       WHEN WHERE WHITESPACE_P WITH WITHOUT WORK WRITE
 
        XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLFOREST XMLPARSE
        XMLPI XMLROOT XMLSERIALIZE
 
-       YEAR_P YES
+       YEAR_P YES_P
 
        ZONE
 
@@ -493,7 +493,8 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
  * left-associativity among the JOIN rules themselves.
  */
 %left          JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
-%right         PRESERVE STRIP
+/* kluge to keep xml_whitespace_option from causing shift/reduce conflicts */
+%right         PRESERVE STRIP_P
 %%
 
 /*
@@ -7880,95 +7881,54 @@ func_expr:      func_name '(' ')'
                                }
                        | XMLCONCAT '(' expr_list ')'
                                {               
-                                       $$ = makeXmlExpr(IS_XMLCONCAT, NULL, NULL, $3);
+                                       $$ = makeXmlExpr(IS_XMLCONCAT, NULL, NIL, $3);
                                }
-                       | XMLELEMENT '(' NAME ColLabel ')'
+                       | XMLELEMENT '(' NAME_P ColLabel ')'
                                {
-                                       $$ = makeXmlExpr(IS_XMLELEMENT, $4, NULL, NULL);
+                                       $$ = makeXmlExpr(IS_XMLELEMENT, $4, NIL, NIL);
                                }
-                       | XMLELEMENT '(' NAME ColLabel ',' xml_attributes ')'
+                       | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ')'
                                {
-                                       $$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, NULL);
+                                       $$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, NIL);
                                }
-                       | XMLELEMENT '(' NAME ColLabel ',' expr_list ')'
+                       | XMLELEMENT '(' NAME_P ColLabel ',' expr_list ')'
                                {
-                                       $$ = makeXmlExpr(IS_XMLELEMENT, $4, NULL, $6);
+                                       $$ = makeXmlExpr(IS_XMLELEMENT, $4, NIL, $6);
                                }
-                       | XMLELEMENT '(' NAME ColLabel ',' xml_attributes ',' expr_list ')'
+                       | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ',' expr_list ')'
                                {
                                        $$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, $8);
                                }
                        | XMLFOREST '(' xml_attribute_list ')'
                                {
-                                       $$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NULL);
+                                       $$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NIL);
                                }
                        | XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')'
                                {
-                                       FuncCall *n = makeNode(FuncCall);
-                                       n->funcname = SystemFuncName("xmlparse");
-                                       n->args = list_make3(makeBoolAConst($3 == DOCUMENT), $4, makeBoolAConst($5 == PRESERVE));
-                                       n->agg_star = FALSE;
-                                       n->agg_distinct = FALSE;
-                                       n->location = @1;
-                                       $$ = (Node *)n;
+                                       $$ = makeXmlExpr(IS_XMLPARSE, NULL, NIL,
+                                                                        list_make3($4,
+                                                                                               makeBoolAConst($3),
+                                                                                               makeBoolAConst($5)));
                                }
-                       | XMLPI '(' NAME ColLabel ')'
+                       | XMLPI '(' NAME_P ColLabel ')'
                                {
-                                       FuncCall *n = makeNode(FuncCall);
-                                       n->funcname = SystemFuncName("xmlpi");
-                                       n->args = list_make1(makeStringConst($4, NULL));
-                                       n->agg_star = FALSE;
-                                       n->agg_distinct = FALSE;
-                                       n->location = @1;
-                                       $$ = (Node *)n;
+                                       $$ = makeXmlExpr(IS_XMLPI, $4, NULL, NIL);
                                }
-                       | XMLPI '(' NAME ColLabel ',' a_expr ')'
+                       | XMLPI '(' NAME_P ColLabel ',' a_expr ')'
                                {
-                                       FuncCall *n = makeNode(FuncCall);
-                                       n->funcname = SystemFuncName("xmlpi");
-                                       n->args = list_make2(makeStringConst($4, NULL), $6);
-                                       n->agg_star = FALSE;
-                                       n->agg_distinct = FALSE;
-                                       n->location = @1;
-                                       $$ = (Node *)n;
+                                       $$ = makeXmlExpr(IS_XMLPI, $4, NULL, list_make1($6));
                                }
                        | XMLROOT '(' a_expr ',' xml_root_version opt_xml_root_standalone ')'
                                {
-                                       FuncCall *n = makeNode(FuncCall);
-                                       Node *ver;
-                                       A_Const *sa;
-
-                                       if ($5)
-                                               ver = $5;
-                                       else
-                                       {
-                                               A_Const *val;
-
-                                               val = makeNode(A_Const);
-                                               val->val.type = T_Null;
-                                               ver = (Node *) val;
-                                       }
-
-                                       if ($6)
-                                               sa = makeBoolAConst($6 == 1);
-                                       else
-                                       {
-                                               sa = makeNode(A_Const);
-                                               sa->val.type = T_Null;
-                                       }
-
-                                       n->funcname = SystemFuncName("xmlroot");
-                                       n->args = list_make3($3, ver, sa);
-                                       n->agg_star = FALSE;
-                                       n->agg_distinct = FALSE;
-                                       n->location = @1;
-                                       $$ = (Node *)n;
+                                       $$ = makeXmlExpr(IS_XMLROOT, NULL, NIL,
+                                                                        list_make3($3, $5, $6));
                                }
                        | XMLSERIALIZE '(' document_or_content a_expr AS Typename ')'
                                {
                                        /*
                                         * FIXME: This should be made distinguishable from
-                                        * CAST (for reverse compilation at least).
+                                        * CAST (for reverse compilation at least).  Also,
+                                        * what about the document/content option??
                                         */
                                        $$ = makeTypeCast($4, $6);
                                }
@@ -7977,17 +7937,35 @@ func_expr:      func_name '(' ')'
 /*
  * SQL/XML support
  */
-xml_root_version: VERSION a_expr       { $$ = $2; }
-                       | VERSION NO VALUE              { $$ = NULL; }
+xml_root_version: VERSION_P a_expr
+                               { $$ = $2; }
+                       | VERSION_P NO VALUE_P
+                               {
+                                       A_Const *val = makeNode(A_Const);
+                                       val->val.type = T_Null;
+                                       $$ = (Node *) val;
+                               }
                ;
 
-opt_xml_root_standalone: ',' STANDALONE YES    { $$ = 1; }
-                       | ',' STANDALONE NO                             { $$ = -1; }
-                       | ',' STANDALONE NO VALUE               { $$ = 0; }
-                       | /*EMPTY*/                                             { $$ = 0; }
+opt_xml_root_standalone: ',' STANDALONE_P YES_P
+                               { $$ = (Node *) makeBoolAConst(true); }
+                       | ',' STANDALONE_P NO
+                               { $$ = (Node *) makeBoolAConst(false); }
+                       | ',' STANDALONE_P NO VALUE_P
+                               {
+                                       A_Const *val = makeNode(A_Const);
+                                       val->val.type = T_Null;
+                                       $$ = (Node *) val;
+                               }
+                       | /*EMPTY*/
+                               {
+                                       A_Const *val = makeNode(A_Const);
+                                       val->val.type = T_Null;
+                                       $$ = (Node *) val;
+                               }
                ;
 
-xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; }
+xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')'       { $$ = $3; }
                ;
 
 xml_attribute_list:    xml_attribute_el                                        { $$ = list_make1($1); }
@@ -8000,7 +7978,7 @@ xml_attribute_el: a_expr AS ColLabel
                                        $$->name = $3;
                                        $$->indirection = NULL;
                                        $$->val = (Node *) $1;
-
+                                       $$->location = @1;
                                }
                        | a_expr
                                {
@@ -8008,16 +7986,21 @@ xml_attribute_el: a_expr AS ColLabel
                                        $$->name = NULL;
                                        $$->indirection = NULL;
                                        $$->val = (Node *) $1;                          
+                                       $$->location = @1;
                                }
                ;
 
-document_or_content: DOCUMENT { $$ = DOCUMENT; }
-                       | CONTENT { $$ = CONTENT; }
+document_or_content: DOCUMENT_P                                                { $$ = TRUE; }
+                       | CONTENT_P                                                             { $$ = FALSE; }
                ;
 
-xml_whitespace_option: PRESERVE WHITESPACE { $$ = PRESERVE; }
-                       | STRIP WHITESPACE { $$ = STRIP; }
-                       | /*EMPTY*/ { $$ = STRIP; }
+/*
+ * XXX per SQL spec, the default should be STRIP WHITESPACE, but since we
+ * haven't implemented that yet, temporarily default to PRESERVE.
+ */
+xml_whitespace_option: PRESERVE WHITESPACE_P           { $$ = TRUE; }
+                       | STRIP_P WHITESPACE_P                                  { $$ = FALSE; }
+                       | /*EMPTY*/                                                             { $$ = TRUE; }
                ;
 
 /*
@@ -8712,7 +8695,7 @@ unreserved_keyword:
                        | CONCURRENTLY
                        | CONNECTION
                        | CONSTRAINTS
-                       | CONTENT
+                       | CONTENT_P
                        | CONVERSION_P
                        | COPY
                        | CREATEDB
@@ -8732,7 +8715,7 @@ unreserved_keyword:
                        | DELIMITER
                        | DELIMITERS
                        | DISABLE_P
-                       | DOCUMENT
+                       | DOCUMENT_P
                        | DOMAIN_P
                        | DOUBLE_P
                        | DROP
@@ -8792,7 +8775,7 @@ unreserved_keyword:
                        | MODE
                        | MONTH_P
                        | MOVE
-                       | NAME
+                       | NAME_P
                        | NAMES
                        | NEXT
                        | NO
@@ -8853,18 +8836,18 @@ unreserved_keyword:
                        | SHOW
                        | SIMPLE
                        | STABLE
-                       | STANDALONE
+                       | STANDALONE_P
                        | START
                        | STATEMENT
                        | STATISTICS
                        | STDIN
                        | STDOUT
                        | STORAGE
-                       | STRIP
+                       | STRICT_P
+                       | STRIP_P
                        | SUPERUSER_P
                        | SYSID
                        | SYSTEM_P
-                       | STRICT_P
                        | TABLESPACE
                        | TEMP
                        | TEMPLATE
@@ -8883,18 +8866,18 @@ unreserved_keyword:
                        | VACUUM
                        | VALID
                        | VALIDATOR
+                       | VALUE_P
                        | VARYING
-                       | VERSION
+                       | VERSION_P
                        | VIEW
-                       | VALUE
                        | VOLATILE
-                       | WHITESPACE
+                       | WHITESPACE_P
                        | WITH
                        | WITHOUT
                        | WORK
                        | WRITE
                        | YEAR_P
-                       | YES
+                       | YES_P
                        | ZONE
                ;
 
@@ -8948,8 +8931,8 @@ col_name_keyword:
                        | VALUES
                        | VARCHAR
                        | XMLATTRIBUTES
-                       | XMLELEMENT
                        | XMLCONCAT
+                       | XMLELEMENT
                        | XMLFOREST
                        | XMLPARSE
                        | XMLPI
@@ -9492,10 +9475,16 @@ doNegateFloat(Value *v)
 static Node *
 makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
 {
-       XmlExpr *x = makeNode(XmlExpr);
+       XmlExpr    *x = makeNode(XmlExpr);
+
        x->op = op;
        x->name = name;
+       /*
+        * named_args is a list of ResTarget; it'll be split apart into separate
+        * expression and name lists in transformXmlExpr().
+        */
        x->named_args = named_args;
+       x->arg_names = NIL;
        x->args = args;
        return (Node *) x;
 }
index b5e49e955fc1e30173731bff1f457b0a30e8e6e7..4865d360b3efd2e51d77f9a780f4bceaacb65300 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.178 2006/12/21 16:05:14 petere Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.179 2006/12/24 00:29:18 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -89,7 +89,7 @@ static const ScanKeyword ScanKeywords[] = {
        {"connection", CONNECTION},
        {"constraint", CONSTRAINT},
        {"constraints", CONSTRAINTS},
-       {"content", CONTENT},
+       {"content", CONTENT_P},
        {"conversion", CONVERSION_P},
        {"convert", CONVERT},
        {"copy", COPY},
@@ -124,7 +124,7 @@ static const ScanKeyword ScanKeywords[] = {
        {"disable", DISABLE_P},
        {"distinct", DISTINCT},
        {"do", DO},
-       {"document", DOCUMENT},
+       {"document", DOCUMENT_P},
        {"domain", DOMAIN_P},
        {"double", DOUBLE_P},
        {"drop", DROP},
@@ -220,7 +220,7 @@ static const ScanKeyword ScanKeywords[] = {
        {"mode", MODE},
        {"month", MONTH_P},
        {"move", MOVE},
-       {"name", NAME},
+       {"name", NAME_P},
        {"names", NAMES},
        {"national", NATIONAL},
        {"natural", NATURAL},
@@ -317,7 +317,7 @@ static const ScanKeyword ScanKeywords[] = {
        {"smallint", SMALLINT},
        {"some", SOME},
        {"stable", STABLE},
-       {"standalone", STANDALONE},
+       {"standalone", STANDALONE_P},
        {"start", START},
        {"statement", STATEMENT},
        {"statistics", STATISTICS},
@@ -325,7 +325,7 @@ static const ScanKeyword ScanKeywords[] = {
        {"stdout", STDOUT},
        {"storage", STORAGE},
        {"strict", STRICT_P},
-       {"strip", STRIP},
+       {"strip", STRIP_P},
        {"substring", SUBSTRING},
        {"superuser", SUPERUSER_P},
        {"symmetric", SYMMETRIC},
@@ -362,17 +362,17 @@ static const ScanKeyword ScanKeywords[] = {
        {"vacuum", VACUUM},
        {"valid", VALID},
        {"validator", VALIDATOR},
-       {"value", VALUE},
+       {"value", VALUE_P},
        {"values", VALUES},
        {"varchar", VARCHAR},
        {"varying", VARYING},
        {"verbose", VERBOSE},
-       {"version", VERSION},
+       {"version", VERSION_P},
        {"view", VIEW},
        {"volatile", VOLATILE},
        {"when", WHEN},
        {"where", WHERE},
-       {"whitespace", WHITESPACE},
+       {"whitespace", WHITESPACE_P},
        {"with", WITH},
        {"without", WITHOUT},
        {"work", WORK},
@@ -386,7 +386,7 @@ static const ScanKeyword ScanKeywords[] = {
        {"xmlroot", XMLROOT},
        {"xmlserialize", XMLSERIALIZE},
        {"year", YEAR_P},
-       {"yes", YES},
+       {"yes", YES_P},
        {"zone", ZONE},
 };
 
index 996c724d1cec46c1709e0d239d81c26336446037..145caab101a47822c76dfbd1ad28b1812d28ccf8 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.159 2006/11/28 12:54:41 petere Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.160 2006/12/24 00:29:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1094,7 +1094,7 @@ transformLimitClause(ParseState *pstate, Node *clause,
 
        qual = transformExpr(pstate, clause);
 
-       qual = coerce_to_bigint(pstate, qual, constructName);
+       qual = coerce_to_specific_type(pstate, qual, INT8OID, constructName);
 
        /*
         * LIMIT can't refer to any vars or aggregates of the current query; we
index 5670ed4fe742188c1b00a03f57340b95a4881edd..45c8e97be1d24f5ab95a2c402c8b8176af83f362 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.148 2006/12/21 16:05:14 petere Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.149 2006/12/24 00:29:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -840,8 +840,8 @@ coerce_to_boolean(ParseState *pstate, Node *node,
 }
 
 /*
- * coerce_to_integer()
- *             Coerce an argument of a construct that requires integer input.
+ * coerce_to_specific_type()
+ *             Coerce an argument of a construct that requires a specific data type.
  *             Also check that input is not a set.
  *
  * Returns the possibly-transformed node tree.
@@ -850,103 +850,26 @@ coerce_to_boolean(ParseState *pstate, Node *node,
  * processing is wanted.
  */
 Node *
-coerce_to_integer(ParseState *pstate, Node *node,
-                                 const char *constructName)
-{
-       Oid                     inputTypeId = exprType(node);
-
-       if (inputTypeId != INT4OID)
-       {
-               node = coerce_to_target_type(pstate, node, inputTypeId,
-                                                                        INT4OID, -1,
-                                                                        COERCION_ASSIGNMENT,
-                                                                        COERCE_IMPLICIT_CAST);
-               if (node == NULL)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_DATATYPE_MISMATCH),
-                       /* translator: first %s is name of a SQL construct, eg LIMIT */
-                                  errmsg("argument of %s must be type integer, not type %s",
-                                                 constructName, format_type_be(inputTypeId))));
-       }
-
-       if (expression_returns_set(node))
-               ereport(ERROR,
-                               (errcode(ERRCODE_DATATYPE_MISMATCH),
-               /* translator: %s is name of a SQL construct, eg LIMIT */
-                                errmsg("argument of %s must not return a set",
-                                               constructName)));
-
-       return node;
-}
-
-/*
- * coerce_to_bigint()
- *             Coerce an argument of a construct that requires int8 input.
- *             Also check that input is not a set.
- *
- * Returns the possibly-transformed node tree.
- *
- * As with coerce_type, pstate may be NULL if no special unknown-Param
- * processing is wanted.
- */
-Node *
-coerce_to_bigint(ParseState *pstate, Node *node,
-                                const char *constructName)
-{
-       Oid                     inputTypeId = exprType(node);
-
-       if (inputTypeId != INT8OID)
-       {
-               node = coerce_to_target_type(pstate, node, inputTypeId,
-                                                                        INT8OID, -1,
-                                                                        COERCION_ASSIGNMENT,
-                                                                        COERCE_IMPLICIT_CAST);
-               if (node == NULL)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_DATATYPE_MISMATCH),
-                       /* translator: first %s is name of a SQL construct, eg LIMIT */
-                                        errmsg("argument of %s must be type bigint, not type %s",
-                                                       constructName, format_type_be(inputTypeId))));
-       }
-
-       if (expression_returns_set(node))
-               ereport(ERROR,
-                               (errcode(ERRCODE_DATATYPE_MISMATCH),
-               /* translator: %s is name of a SQL construct, eg LIMIT */
-                                errmsg("argument of %s must not return a set",
-                                               constructName)));
-
-       return node;
-}
-
-/*
- * coerce_to_xml()
- *             Coerce an argument of a construct that requires xml input.
- *             Also check that input is not a set.
- *
- * Returns the possibly-transformed node tree.
- *
- * As with coerce_type, pstate may be NULL if no special unknown-Param
- * processing is wanted.
- */
-Node *
-coerce_to_xml(ParseState *pstate, Node *node,
-                                const char *constructName)
+coerce_to_specific_type(ParseState *pstate, Node *node,
+                                               Oid targetTypeId,
+                                               const char *constructName)
 {
        Oid                     inputTypeId = exprType(node);
 
-       if (inputTypeId != XMLOID)
+       if (inputTypeId != targetTypeId)
        {
                node = coerce_to_target_type(pstate, node, inputTypeId,
-                                                                        XMLOID, -1,
+                                                                        targetTypeId, -1,
                                                                         COERCION_ASSIGNMENT,
                                                                         COERCE_IMPLICIT_CAST);
                if (node == NULL)
                        ereport(ERROR,
                                        (errcode(ERRCODE_DATATYPE_MISMATCH),
                        /* translator: first %s is name of a SQL construct, eg LIMIT */
-                                        errmsg("argument of %s must be type xml, not type %s",
-                                                       constructName, format_type_be(inputTypeId))));
+                                  errmsg("argument of %s must be type %s, not type %s",
+                                                 constructName,
+                                                 format_type_be(targetTypeId),
+                                                 format_type_be(inputTypeId))));
        }
 
        if (expression_returns_set(node))
index 2a48741b3a2fef31be935b3beacca84411c3c1f3..7dbbb9a33a8637b97338756d22cd8cf027dc2416 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.201 2006/12/23 00:43:11 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.202 2006/12/24 00:29:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -220,6 +220,10 @@ transformExpr(ParseState *pstate, Node *expr)
                        result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr);
                        break;
 
+               case T_XmlExpr:
+                       result = transformXmlExpr(pstate, (XmlExpr *) expr);
+                       break;
+
                case T_NullTest:
                        {
                                NullTest   *n = (NullTest *) expr;
@@ -234,10 +238,6 @@ 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.
@@ -1375,6 +1375,107 @@ transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m)
        return (Node *) newm;
 }
 
+static Node *
+transformXmlExpr(ParseState *pstate, XmlExpr *x)
+{
+       XmlExpr *newx = makeNode(XmlExpr);
+       ListCell        *lc;
+       int                     i;
+
+       newx->op = x->op;
+       if (x->name)
+               newx->name = map_sql_identifier_to_xml_name(x->name, false);
+       else
+               newx->name = NULL;
+
+       /*
+        * gram.y built the named args as a list of ResTarget.  Transform each,
+        * and break the names out as a separate list.
+        */
+       newx->named_args = NIL;
+       newx->arg_names = NIL;
+
+       foreach(lc, x->named_args)
+       {
+               ResTarget       *r = (ResTarget *) lfirst(lc);
+               Node            *expr;
+               char            *argname;
+
+               Assert(IsA(r, ResTarget));
+
+               expr = transformExpr(pstate, r->val);
+
+               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")));
+                       argname = NULL;         /* keep compiler quiet */
+               }
+
+               newx->named_args = lappend(newx->named_args, expr);
+               newx->arg_names = lappend(newx->arg_names, makeString(argname));
+       }
+
+       /* The other arguments are of varying types depending on the function */
+       newx->args = NIL;
+       i = 0;
+       foreach(lc, x->args)
+       {
+               Node       *e = (Node *) lfirst(lc);
+               Node       *newe;
+
+               newe = transformExpr(pstate, e);
+               switch (x->op)
+               {
+                       case IS_XMLCONCAT:
+                               newe = coerce_to_specific_type(pstate, newe, XMLOID,
+                                                                                          "XMLCONCAT");
+                               break;
+                       case IS_XMLELEMENT:
+                               newe = coerce_to_specific_type(pstate, newe, XMLOID,
+                                                                                          "XMLELEMENT");
+                               break;
+                       case IS_XMLFOREST:
+                               newe = coerce_to_specific_type(pstate, newe, XMLOID,
+                                                                                          "XMLFOREST");
+                               break;
+                       case IS_XMLPARSE:
+                               if (i == 0)
+                                       newe = coerce_to_specific_type(pstate, newe, TEXTOID,
+                                                                                                  "XMLPARSE");
+                               else
+                                       newe = coerce_to_boolean(pstate, newe, "XMLPARSE");
+                               break;
+                       case IS_XMLPI:
+                               newe = coerce_to_specific_type(pstate, newe, TEXTOID,
+                                                                                          "XMLPI");
+                               break;
+                       case IS_XMLROOT:
+                               if (i == 0)
+                                       newe = coerce_to_specific_type(pstate, newe, XMLOID,
+                                                                                                  "XMLROOT");
+                               else if (i == 1)
+                                       newe = coerce_to_specific_type(pstate, newe, TEXTOID,
+                                                                                                  "XMLROOT");
+                               else
+                                       newe = coerce_to_boolean(pstate, newe, "XMLROOT");
+                               break;
+               }
+               newx->args = lappend(newx->args, newe);
+               i++;
+       }
+               
+       return (Node *) newx;
+}
+
 static Node *
 transformBooleanTest(ParseState *pstate, BooleanTest *b)
 {
@@ -1415,56 +1516,6 @@ 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.*".
  *
@@ -1715,6 +1766,9 @@ exprType(Node *expr)
                case T_MinMaxExpr:
                        type = ((MinMaxExpr *) expr)->minmaxtype;
                        break;
+               case T_XmlExpr:
+                       type = XMLOID;
+                       break;
                case T_NullIfExpr:
                        type = exprType((Node *) linitial(((NullIfExpr *) expr)->args));
                        break;
@@ -1724,9 +1778,6 @@ exprType(Node *expr)
                case T_BooleanTest:
                        type = BOOLOID;
                        break;
-               case T_XmlExpr:
-                       type = XMLOID;
-                       break;
                case T_CoerceToDomain:
                        type = ((CoerceToDomain *) expr)->resulttype;
                        break;
index 906d96e45c6c6f069476dae44952c5236819a0b5..ef4b9083ac652c702aef78cf4e9e727c94ad0d02 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.150 2006/12/21 16:05:14 petere Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.151 2006/12/24 00:29:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1328,6 +1328,15 @@ FigureColnameInternal(Node *node, char **name)
                                case IS_XMLFOREST:
                                        *name = "xmlforest";
                                        return 2;
+                               case IS_XMLPARSE:
+                                       *name = "xmlparse";
+                                       return 2;
+                               case IS_XMLPI:
+                                       *name = "xmlpi";
+                                       return 2;
+                               case IS_XMLROOT:
+                                       *name = "xmlroot";
+                                       return 2;
                        } 
                        break;
                default:
index b2ff95f457b758576b38504e6a1355384b87ec95..699b4a9370462431f72d0b6223fae151cf3da660 100644 (file)
@@ -2,7 +2,7 @@
  * ruleutils.c - Functions to convert stored expressions/querytrees
  *                             back to source text
  *
- *       $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.237 2006/12/23 00:43:11 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.238 2006/12/24 00:29:19 tgl Exp $
  **********************************************************************/
 
 #include "postgres.h"
@@ -2988,8 +2988,8 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
                case T_RowExpr:
                case T_CoalesceExpr:
                case T_MinMaxExpr:
-               case T_NullIfExpr:
                case T_XmlExpr:
+               case T_NullIfExpr:
                case T_Aggref:
                case T_FuncExpr:
                        /* function-like: name(..) or name[..] */
@@ -3097,8 +3097,8 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
                                case T_RowExpr: /* other separators */
                                case T_CoalesceExpr:    /* own parentheses */
                                case T_MinMaxExpr:              /* own parentheses */
-                               case T_NullIfExpr:              /* other separators */
                                case T_XmlExpr:                 /* own parentheses */
+                               case T_NullIfExpr:              /* other separators */
                                case T_Aggref:  /* own parentheses */
                                case T_CaseExpr:                /* other separators */
                                        return true;
@@ -3146,8 +3146,8 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
                                case T_RowExpr: /* other separators */
                                case T_CoalesceExpr:    /* own parentheses */
                                case T_MinMaxExpr:              /* own parentheses */
-                               case T_NullIfExpr:              /* other separators */
                                case T_XmlExpr:                 /* own parentheses */
+                               case T_NullIfExpr:              /* other separators */
                                case T_Aggref:  /* own parentheses */
                                case T_CaseExpr:                /* other separators */
                                        return true;
@@ -3779,6 +3779,140 @@ get_rule_expr(Node *node, deparse_context *context,
                        }
                        break;
 
+               case T_XmlExpr:
+                       {
+                               XmlExpr *xexpr = (XmlExpr *) node;
+                               bool    needcomma = false;
+                               ListCell   *arg;
+                               ListCell   *narg;
+                               Const      *con;
+
+                               switch (xexpr->op)
+                               {
+                                       case IS_XMLCONCAT:
+                                               appendStringInfoString(buf, "XMLCONCAT(");
+                                               break;
+                                       case IS_XMLELEMENT:
+                                               appendStringInfoString(buf, "XMLELEMENT(");
+                                               break;
+                                       case IS_XMLFOREST:
+                                               appendStringInfoString(buf, "XMLFOREST(");
+                                               break;
+                                       case IS_XMLPARSE:
+                                               appendStringInfoString(buf, "XMLPARSE(");
+                                               break;
+                                       case IS_XMLPI:
+                                               appendStringInfoString(buf, "XMLPI(");
+                                               break;
+                                       case IS_XMLROOT:
+                                               appendStringInfoString(buf, "XMLROOT(");
+                                               break;
+                               }
+                               if (xexpr->name)
+                               {
+                                       /*
+                                        * XXX need to de-escape the name
+                                        */
+                                       appendStringInfo(buf, "NAME %s",
+                                                                        quote_identifier(xexpr->name));
+                                       needcomma = true;
+                               }
+                               if (xexpr->named_args)
+                               {
+                                       if (xexpr->op != IS_XMLFOREST)
+                                       {
+                                               if (needcomma)
+                                                       appendStringInfoString(buf, ", ");
+                                               appendStringInfoString(buf, "XMLATTRIBUTES(");
+                                               needcomma = false;
+                                       }
+                                       forboth(arg, xexpr->named_args, narg, xexpr->arg_names)
+                                       {
+                                               Node    *e = (Node *) lfirst(arg);
+                                               char    *argname = strVal(lfirst(narg));
+
+                                               if (needcomma)
+                                                       appendStringInfoString(buf, ", ");
+                                               get_rule_expr((Node *) e, context, true);
+                                               /*
+                                                * XXX need to de-escape the name
+                                                */
+                                               appendStringInfo(buf, " AS %s",
+                                                                                quote_identifier(argname));
+                                               needcomma = true;
+                                       }
+                                       if (xexpr->op != IS_XMLFOREST)
+                                               appendStringInfoChar(buf, ')');
+                               }
+                               if (xexpr->args)
+                               {
+                                       if (needcomma)
+                                               appendStringInfoString(buf, ", ");
+                                       switch (xexpr->op)
+                                       {
+                                               case IS_XMLCONCAT:
+                                               case IS_XMLELEMENT:
+                                               case IS_XMLFOREST:
+                                               case IS_XMLPI:
+                                                       /* no extra decoration needed */
+                                                       get_rule_expr((Node *) xexpr->args, context, true);
+                                                       break;
+                                               case IS_XMLPARSE:
+                                                       Assert(list_length(xexpr->args) == 3);
+
+                                                       con = (Const *) lsecond(xexpr->args);
+                                                       Assert(IsA(con, Const));
+                                                       Assert(!con->constisnull);
+                                                       if (DatumGetBool(con->constvalue))
+                                                               appendStringInfoString(buf, "DOCUMENT ");
+                                                       else
+                                                               appendStringInfoString(buf, "CONTENT ");
+
+                                                       get_rule_expr((Node *) linitial(xexpr->args),
+                                                                                 context, true);
+
+                                                       con = (Const *) lthird(xexpr->args);
+                                                       Assert(IsA(con, Const));
+                                                       Assert(!con->constisnull);
+                                                       if (DatumGetBool(con->constvalue))
+                                                               appendStringInfoString(buf,
+                                                                                                          " PRESERVE WHITESPACE");
+                                                       else
+                                                               appendStringInfoString(buf,
+                                                                                                          " STRIP WHITESPACE");
+                                                       break;
+                                               case IS_XMLROOT:
+                                                       Assert(list_length(xexpr->args) == 3);
+
+                                                       get_rule_expr((Node *) linitial(xexpr->args),
+                                                                                 context, true);
+
+                                                       appendStringInfoString(buf, ", VERSION ");
+                                                       con = (Const *) lsecond(xexpr->args);
+                                                       if (IsA(con, Const) &&
+                                                               con->constisnull)
+                                                               appendStringInfoString(buf, "NO VALUE");
+                                                       else
+                                                               get_rule_expr((Node *) con, context, false);
+
+                                                       con = (Const *) lthird(xexpr->args);
+                                                       Assert(IsA(con, Const));
+                                                       if (con->constisnull)
+                                                               /* suppress STANDALONE NO VALUE */ ;
+                                                       else if (DatumGetBool(con->constvalue))
+                                                               appendStringInfoString(buf,
+                                                                                                          ", STANDALONE YES");
+                                                       else
+                                                               appendStringInfoString(buf,
+                                                                                                          ", STANDALONE NO");
+                                                       break;
+                                       }
+
+                               }
+                               appendStringInfoChar(buf, ')');
+                       }
+                       break;
+
                case T_NullIfExpr:
                        {
                                NullIfExpr *nullifexpr = (NullIfExpr *) node;
@@ -3849,28 +3983,6 @@ get_rule_expr(Node *node, deparse_context *context,
                        }
                        break;
 
-               case T_XmlExpr:
-                       {
-                               XmlExpr *xexpr = (XmlExpr *) node;
-
-                               switch (xexpr->op)
-                               {
-                                       case IS_XMLCONCAT:
-                                               appendStringInfo(buf, "XMLCONCAT(");
-                                               break;
-                                       case IS_XMLELEMENT:
-                                               appendStringInfo(buf, "XMLELEMENT(");
-                                               break;
-                                       case IS_XMLFOREST:
-                                               appendStringInfo(buf, "XMLFOREST(");
-                                               break;
-                               }
-                               get_rule_expr((Node *) xexpr->named_args, context, true);
-                               get_rule_expr((Node *) xexpr->args, context, true);
-                               appendStringInfoChar(buf, ')');
-                       }
-                       break;
-
                case T_CoerceToDomain:
                        {
                                CoerceToDomain *ctest = (CoerceToDomain *) node;
index d765c8657fb5a5110ca464b1a4af8e5d5b9be805..a6dc1a6e5f02a876e46add2f20e783b32912e494 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.2 2006/12/23 04:56:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.3 2006/12/24 00:29:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #ifdef USE_LIBXML
 
-/*
- * A couple of useful macros (similar to ones from libxml/parse.c)
- */
-#define CMP4( s, c1, c2, c3, c4 ) \
-  ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
-    ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
-#define CMP5( s, c1, c2, c3, c4, c5 ) \
-  ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
-
 #define PG_XML_DEFAULT_URI "dummy.xml"
 #define XML_ERRBUF_SIZE 200
 
@@ -177,31 +168,18 @@ xmlcomment(PG_FUNCTION_ARGS)
 
 
 Datum
-xmlparse(PG_FUNCTION_ARGS)
+texttoxml(PG_FUNCTION_ARGS)
 {
-#ifdef USE_LIBXML
-       text       *data;
-       bool            is_document;
-       bool            preserve_whitespace;
-
-       data = PG_GETARG_TEXT_P(0);
+       text       *data = PG_GETARG_TEXT_P(0);
 
-       if (PG_NARGS() >= 2)
-               is_document = PG_GETARG_BOOL(1);
-       else
-               is_document = false;
+       PG_RETURN_XML_P(xmlparse(data, false, true));
+}
 
-       if (PG_NARGS() >= 3)
-               preserve_whitespace = PG_GETARG_BOOL(2);
-       else
-               /*
-                * Since the XMLPARSE grammar makes STRIP WHITESPACE the
-                * default, this argument should really default to false.  But
-                * until we have actually implemented whitespace stripping,
-                * this would be annoying.
-                */
-               preserve_whitespace = true;
 
+xmltype *
+xmlparse(text *data, bool is_document, bool preserve_whitespace)
+{
+#ifdef USE_LIBXML
        if (!preserve_whitespace)
                ereport(WARNING,
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -213,111 +191,93 @@ xmlparse(PG_FUNCTION_ARGS)
         * valies defined by internal DTD are applied'.  As for external
         * DTDs, we try to support them too, (see SQL/XML:10.16.7.e)
         */
-       xml_parse(data, XML_PARSE_DTDATTR, is_document); /* assume that ERROR occurred if parsing failed */
+       xml_parse(data, XML_PARSE_DTDATTR, is_document);
 
-       PG_RETURN_XML_P(data);
+       return (xmltype *) data;
 #else
        NO_XML_SUPPORT();
-       return 0;
+       return NULL;
 #endif
 }
 
 
-Datum
-xmlpi(PG_FUNCTION_ARGS)
+xmltype *
+xmlpi(char *target, text *arg)
 {
 #ifdef USE_LIBXML
-       char       *target = NameStr(*PG_GETARG_NAME(0));
+       xmltype *result;
        StringInfoData buf;
 
-       if (strlen(target) >= 3
-               && (target[0] == 'x' || target[0] == 'X')
-               && (target[1] == 'm' || target[1] == 'M')
-               && (target[2] == 'l' || target[2] == 'L'))
-       {
+       if (pg_strncasecmp(target, "xml", 3) == 0)
                ereport(ERROR,
-                               (errcode(ERRCODE_SYNTAX_ERROR),
+                               (errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
                                 errmsg("invalid XML processing instruction"),
                                 errdetail("XML processing instruction target name cannot start with \"xml\".")));
-       }
 
        initStringInfo(&buf);
 
-       appendStringInfo(&buf, "<?");
-       appendStringInfoString(&buf, map_sql_identifier_to_xml_name(target, false));
-       if (PG_NARGS() > 1)
+       appendStringInfo(&buf, "<?%s", target);
+
+       if (arg != NULL)
        {
-               text *arg = PG_GETARG_TEXT_P(1);
                char *string;
 
-               string = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(arg)));
-               if (strstr(string, "?>"))
+               string = DatumGetCString(DirectFunctionCall1(textout,
+                                                                                                        PointerGetDatum(arg)));
+               if (strstr(string, "?>") != NULL)
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
                                 errmsg("invalid XML processing instruction"),
                                 errdetail("XML processing instruction cannot contain \"?>\".")));
 
-               appendStringInfoString(&buf, " ");
+               appendStringInfoChar(&buf, ' ');
                appendStringInfoString(&buf, string);
+               pfree(string);
        }
        appendStringInfoString(&buf, "?>");
 
-       PG_RETURN_XML_P(stringinfo_to_xmltype(&buf));
+       result = stringinfo_to_xmltype(&buf);
+       pfree(buf.data);
+       return result;
 #else
        NO_XML_SUPPORT();
-       return 0;
+       return NULL;
 #endif
 }
 
 
-Datum
-xmlroot(PG_FUNCTION_ARGS)
+xmltype *
+xmlroot(xmltype *data, text *version, int standalone)
 {
 #ifdef USE_LIBXML
-       xmltype    *data;
-       text       *version;
-       int                     standalone;
+       xmltype *result;
        StringInfoData buf;
 
-       if (PG_ARGISNULL(0))
-               PG_RETURN_NULL();
-       else
-               data = PG_GETARG_XML_P(0);
-
-       if (PG_ARGISNULL(1))
-               version = NULL;
-       else
-               version = PG_GETARG_TEXT_P(1);
-
-       if (PG_ARGISNULL(2))
-               standalone = 0;
-       else
-       {
-               bool tmp = PG_GETARG_BOOL(2);
-               standalone = (tmp ? 1 : -1);
-       }
+       initStringInfo(&buf);
 
        /*
         * FIXME: This is probably supposed to be cleverer if there
         * already is an XML preamble.
         */
-       initStringInfo(&buf);
-
        appendStringInfo(&buf,"<?xml");
-       if (version) {
+       if (version)
+       {
                appendStringInfo(&buf, " version=\"");
                appendStringInfoText(&buf, version);
                appendStringInfo(&buf, "\"");
        }
        if (standalone)
-               appendStringInfo(&buf, " standalone=\"%s\"", (standalone == 1 ? "yes" : "no"));
+               appendStringInfo(&buf, " standalone=\"%s\"",
+                                                (standalone == 1 ? "yes" : "no"));
        appendStringInfo(&buf, "?>");
        appendStringInfoText(&buf, (text *) data);
 
-       PG_RETURN_XML_P(stringinfo_to_xmltype(&buf));
+       result = stringinfo_to_xmltype(&buf);
+       pfree(buf.data);
+       return result;
 #else
        NO_XML_SUPPORT();
-       return 0;
+       return NULL;
 #endif
 }
 
@@ -456,7 +416,7 @@ xml_parse(text *data, int opts, bool is_document)
 
        /* first, we try to parse the string as XML doc, then, as XML chunk */
        ereport(DEBUG3, (errmsg("string to parse: %s", string)));
-       if (len > 4 && CMP5(string, '<', '?', 'x', 'm', 'l'))
+       if (len >= 5 && strncmp((char *) string, "<?xml", 5) == 0)
        {
                /* consider it as DOCUMENT */
                doc = xmlCtxtReadMemory(ctxt, (char *) string, len,
@@ -918,10 +878,8 @@ map_sql_identifier_to_xml_name(char *ident, bool fully_escaped)
                        appendStringInfo(&buf, "_x003A_");
                else if (*p == '_' && *(p+1) == 'x')
                        appendStringInfo(&buf, "_x005F_");
-               else if (fully_escaped && p == ident
-                                && ( *p == 'x' || *p == 'X')
-                                && ( *(p+1) == 'm' || *(p+1) == 'M')
-                                && ( *(p+2) == 'l' || *(p+2) == 'L'))
+               else if (fully_escaped && p == ident &&
+                                pg_strncasecmp(p, "xml", 3) == 0)
                {
                        if (*p == 'x')
                                appendStringInfo(&buf, "_x0078_");
@@ -932,9 +890,10 @@ map_sql_identifier_to_xml_name(char *ident, bool fully_escaped)
                {
                        pg_wchar u = sqlchar_to_unicode(p);
 
-                       if (!is_valid_xml_namechar(u)
-                               || (p == ident && !is_valid_xml_namefirst(u)))
-                       appendStringInfo(&buf, "_x%04X_", (unsigned int) u);
+                       if ((p == ident)
+                               ? !is_valid_xml_namefirst(u)
+                               : !is_valid_xml_namechar(u))
+                               appendStringInfo(&buf, "_x%04X_", (unsigned int) u);
                        else
                                appendBinaryStringInfo(&buf, p, pg_mblen(p));
                }
index f0a840a3ddef5d349d23362731a9968b3b167258..68f5a639347d493d242ba5a5e7ca4a9962251a34 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.365 2006/12/23 00:43:12 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.366 2006/12/24 00:29:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200612221
+#define CATALOG_VERSION_NO     200612231
 
 #endif
index 974a2db360ca4c5eca15e02174296ba348be78f6..0a3ccc07f6cd541a7334cc5cae5fd4bf7e857ba4 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.431 2006/12/21 16:05:15 petere Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.432 2006/12/24 00:29:19 tgl Exp $
  *
  * NOTES
  *       The script catalog/genbki.sh reads this file and generates .bki
@@ -3983,17 +3983,9 @@ DATA(insert OID = 2894 (  xml_out                   PGNSP PGUID 12 f f t f i 1 2275 "142" _nul
 DESCR("I/O");
 DATA(insert OID = 2895 (  xmlcomment      PGNSP PGUID 12 f f t f i 1 142 "25" _null_ _null_ _null_ xmlcomment - _null_ ));
 DESCR("generate an XML comment");
-DATA(insert OID = 2896 (  xmlparse                PGNSP PGUID 12 f f t f i 1 142 "25" _null_ _null_ _null_ xmlparse - _null_ ));
+DATA(insert OID = 2896 (  xml                     PGNSP PGUID 12 f f t f i 1 142 "25" _null_ _null_ _null_ texttoxml - _null_ ));
 DESCR("perform a non-validating parse of a character string to produce an XML value");
-DATA(insert OID = 2897 (  xmlparse                PGNSP PGUID 12 f f t f i 3 142 "25 16 16" _null_ _null_ _null_ xmlparse - _null_ ));
-DESCR("perform a non-validating parse of a character string to produce an XML value");
-DATA(insert OID = 2898 (  xmlpi                           PGNSP PGUID 12 f f t f i 1 142 "19" _null_ _null_ _null_ xmlpi - _null_ ));
-DESCR("generate an XML processing instruction");
-DATA(insert OID = 2899 (  xmlpi                           PGNSP PGUID 12 f f t f i 2 142 "19 25" _null_ _null_ _null_ xmlpi - _null_ ));
-DESCR("generate an XML processing instruction");
-DATA(insert OID = 2900 (  xmlroot                 PGNSP PGUID 12 f f f f i 3 142 "142 25 16" _null_ _null_ _null_ xmlroot - _null_ ));
-DESCR("create an XML value by modifying the properties of the XML root information item of another XML value");
-DATA(insert OID = 2901 (  xmlvalidate     PGNSP PGUID 12 f f t f i 2 16 "142 25" _null_ _null_ _null_ xmlvalidate - _null_ ));
+DATA(insert OID = 2897 (  xmlvalidate     PGNSP PGUID 12 f f t f i 2 16 "142 25" _null_ _null_ _null_ xmlvalidate - _null_ ));
 DESCR("validate an XML value");
 
 /*
index 1db920aa0c1b0c4836c5b3e32b9d9ea564b123b9..f8e8f15a5dba916194f2b556a51c3d629b5f0579 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.163 2006/12/21 16:05:16 petere Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.164 2006/12/24 00:29:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -710,6 +710,18 @@ typedef struct MinMaxExprState
        FmgrInfo        cfunc;                  /* lookup info for comparison func */
 } MinMaxExprState;
 
+/* ----------------
+ *             XmlExprState node
+ * ----------------
+ */
+typedef struct XmlExprState
+{
+       ExprState       xprstate;
+       List       *named_args;         /* ExprStates for named arguments */
+       FmgrInfo   *named_outfuncs;     /* array of output fns for named arguments */
+       List       *args;                       /* ExprStates for other arguments */
+} XmlExprState;
+
 /* ----------------
  *             NullTestState node
  * ----------------
@@ -723,22 +735,6 @@ typedef struct NullTestState
        TupleDesc       argdesc;                /* tupdesc for most recent input */
 } NullTestState;
 
-/* ----------------
- *             XmlExprState node
- * ----------------
- */
-typedef struct XmlExprState
-{
-       ExprState       xprstate;
-       XmlExprOp       op;
-       char       *name;
-       List       *named_args;
-       List       *args;
-       Oid                *named_args_tcache;
-       char      **named_args_ncache;
-       Oid                     arg_typeout;
-} XmlExprState;
-
 /* ----------------
  *             CoerceToDomainState node
  * ----------------
index eb6ba18adab390357a05f9865d3b98b570b92b11..fa9dff9d961ba8f7857a31001b80201cf88f10c7 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.189 2006/12/21 16:05:16 petere Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.190 2006/12/24 00:29:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -130,6 +130,7 @@ typedef enum NodeTag
        T_RowCompareExpr,
        T_CoalesceExpr,
        T_MinMaxExpr,
+       T_XmlExpr,
        T_NullIfExpr,
        T_NullTest,
        T_BooleanTest,
@@ -140,7 +141,6 @@ typedef enum NodeTag
        T_RangeTblRef,
        T_JoinExpr,
        T_FromExpr,
-       T_XmlExpr,
 
        /*
         * TAGS FOR EXPRESSION STATE NODES (execnodes.h)
@@ -166,10 +166,10 @@ typedef enum NodeTag
        T_RowCompareExprState,
        T_CoalesceExprState,
        T_MinMaxExprState,
+       T_XmlExprState,
        T_NullTestState,
        T_CoerceToDomainState,
        T_DomainConstraintState,
-       T_XmlExprState,
 
        /*
         * TAGS FOR PLANNER NODES (relation.h)
index 5946300c9751fdc4a359dc421a8a6b8dce53f4f2..bd2c39040fc1253853650eeed5dbd43e51fc967d 100644 (file)
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.120 2006/12/23 00:43:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.121 2006/12/24 00:29:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -711,6 +711,33 @@ typedef struct MinMaxExpr
        List       *args;                       /* the arguments */
 } MinMaxExpr;
 
+/*
+ * XmlExpr - various SQL/XML functions requiring special grammar productions
+ *
+ * 'name' carries the "NAME foo" argument (already XML-escaped).
+ * 'named_args' and 'arg_names' represent an xml_attribute list.
+ * 'args' carries all other arguments.
+ */
+typedef enum XmlExprOp
+{
+       IS_XMLCONCAT,                           /* XMLCONCAT(args) */
+       IS_XMLELEMENT,                          /* XMLELEMENT(name, xml_attributes, args) */
+       IS_XMLFOREST,                           /* XMLFOREST(xml_attributes) */
+       IS_XMLPARSE,                            /* XMLPARSE(text, is_doc, preserve_ws) */
+       IS_XMLPI,                                       /* XMLPI(name [, args]) */
+       IS_XMLROOT                                      /* XMLROOT(xml, version, standalone) */
+} XmlExprOp;
+
+typedef struct XmlExpr
+{
+       Expr            xpr;
+       XmlExprOp       op;                             /* xml function ID */
+       char       *name;                       /* name in xml(NAME foo ...) syntaxes */
+       List       *named_args;         /* non-XML expressions for xml_attributes */
+       List       *arg_names;          /* parallel list of Value strings */
+       List       *args;                       /* list of expressions */
+} XmlExpr;
+
 /*
  * NullIfExpr - a NULLIF expression
  *
@@ -765,26 +792,6 @@ typedef struct BooleanTest
        BoolTestType booltesttype;      /* test type */
 } BooleanTest;
 
-/*
- * XmlExpr - holder for SQL/XML functions XMLCONCAT,
- * XMLELEMENT, XMLFOREST
- */
-typedef enum XmlExprOp
-{
-       IS_XMLCONCAT,
-       IS_XMLELEMENT,
-       IS_XMLFOREST,
-} XmlExprOp;
-
-typedef struct XmlExpr
-{
-       Expr            xpr;
-       XmlExprOp       op;                             /* xml expression type */
-       char       *name;                       /* element name */
-       List       *named_args;
-       List       *args;
-} XmlExpr;
-
 /*
  * CoerceToDomain
  *
index 9c077095e9e563822fff96fd50244bb74fec66f7..08573abd1ef422a9e75b34e7c682c3a1bf4c1ae2 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/parser/parse_coerce.h,v 1.67 2006/12/21 16:05:16 petere Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_coerce.h,v 1.68 2006/12/24 00:29:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -55,12 +55,9 @@ extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod,
 
 extern Node *coerce_to_boolean(ParseState *pstate, Node *node,
                                  const char *constructName);
-extern Node *coerce_to_integer(ParseState *pstate, Node *node,
-                                 const char *constructName);
-extern Node *coerce_to_bigint(ParseState *pstate, Node *node,
-                                const char *constructName);
-extern Node *coerce_to_xml(ParseState *pstate, Node *node,
-                                const char *constructName);
+extern Node *coerce_to_specific_type(ParseState *pstate, Node *node,
+                                                                        Oid targetTypeId,
+                                                                        const char *constructName);
 
 extern Oid     select_common_type(List *typeids, const char *context);
 extern Node *coerce_to_common_type(ParseState *pstate, Node *node,
index a353d8837c93268aff4acd8aec7045ae8aef7804..713bdaeb115259f402ed1e62909a1f49543bc05b 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.2 2006/12/23 04:56:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.3 2006/12/24 00:29:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -27,11 +27,13 @@ typedef struct varlena xmltype;
 extern Datum xml_in(PG_FUNCTION_ARGS);
 extern Datum xml_out(PG_FUNCTION_ARGS);
 extern Datum xmlcomment(PG_FUNCTION_ARGS);
-extern Datum xmlparse(PG_FUNCTION_ARGS);
-extern Datum xmlpi(PG_FUNCTION_ARGS);
-extern Datum xmlroot(PG_FUNCTION_ARGS);
+extern Datum texttoxml(PG_FUNCTION_ARGS);
 extern Datum xmlvalidate(PG_FUNCTION_ARGS);
 
+extern xmltype *xmlparse(text *data, bool is_doc, bool preserve_whitespace);
+extern xmltype *xmlpi(char *target, text *arg);
+extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
+
 extern char *map_sql_identifier_to_xml_name(char *ident, bool fully_escaped);
 
 #endif /* XML_H */
index c28c2c6c8f3597a5535029b383afb6c3c23bc94e..bff815206169bc37e874743d859accc4aeaf6e19 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.180 2006/10/04 00:30:13 momjian Exp $
+ *       $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.181 2006/12/24 00:29:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -4493,6 +4493,18 @@ exec_simple_check_node(Node *node)
                                return TRUE;
                        }
 
+               case T_XmlExpr:
+                       {
+                               XmlExpr *expr = (XmlExpr *) node;
+
+                               if (!exec_simple_check_node((Node *) expr->named_args))
+                                       return FALSE;
+                               if (!exec_simple_check_node((Node *) expr->args))
+                                       return FALSE;
+
+                               return TRUE;
+                       }
+
                case T_NullIfExpr:
                        {
                                NullIfExpr *expr = (NullIfExpr *) node;
index 478bf3b080683a8ca5526c450c198291946b465c..ba0c229ccd14be2d30d8ad71e6b72cab22fd1397 100644 (file)
@@ -9,7 +9,7 @@
  *
  * Copyright (c) 2003-2006, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/plerrcodes.h,v 1.9 2006/06/16 23:29:27 tgl Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/plerrcodes.h,v 1.10 2006/12/24 00:29:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
        "untranslatable_character", ERRCODE_UNTRANSLATABLE_CHARACTER
 },
 
+{
+       "invalid_xml_document", ERRCODE_INVALID_XML_DOCUMENT
+},
+
+{
+       "invalid_xml_content", ERRCODE_INVALID_XML_CONTENT
+},
+
+{
+       "invalid_xml_comment", ERRCODE_INVALID_XML_COMMENT
+},
+
+{
+       "invalid_xml_processing_instruction", ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION
+},
+
 {
        "integrity_constraint_violation", ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION
 },
index a0e9483ebd0b172d65474078b1e34175670b7e21..7bfa35a46f8c4c25e5c1059ca8ed2d9d40e3e962 100644 (file)
@@ -74,7 +74,7 @@ WHERE p1.oid != p2.oid AND
 SELECT p1.oid, p1.proname, p2.oid, p2.proname
 FROM pg_proc AS p1, pg_proc AS p2
 WHERE p1.oid < p2.oid AND
-    p1.prosrc = p2.prosrc AND p1.prosrc NOT IN ('xmlparse', 'xmlpi') AND
+    p1.prosrc = p2.prosrc AND
     p1.prolang = 12 AND p2.prolang = 12 AND
     (p1.proisagg = false OR p2.proisagg = false) AND
     (p1.prolang != p2.prolang OR
index 4dd39eb164e8ed8a5717ccce590e194b83c8609a..b8c184f784b41804cca26365792c36fab55e63cd 100644 (file)
@@ -77,7 +77,7 @@ WHERE p1.oid != p2.oid AND
 SELECT p1.oid, p1.proname, p2.oid, p2.proname
 FROM pg_proc AS p1, pg_proc AS p2
 WHERE p1.oid < p2.oid AND
-    p1.prosrc = p2.prosrc AND p1.prosrc NOT IN ('xmlparse', 'xmlpi') AND
+    p1.prosrc = p2.prosrc AND
     p1.prolang = 12 AND p2.prolang = 12 AND
     (p1.proisagg = false OR p2.proisagg = false) AND
     (p1.prolang != p2.prolang OR