On Wed, Sep 28, 2005 at 04:30:54PM +0200, Pavel Stehule wrote:
> Hello
> 
> base type changed to text, better registration xmlagg function
> 
> Regards Pavel Stehule

Now with some slightly improved documentation, works vs. CVS tip as of
this writing.

Cheers,
D
-- 
David Fetter [EMAIL PROTECTED] http://fetter.org/
phone: +1 510 893 6100   mobile: +1 415 235 3778

Remember to vote!
Index: doc/src/sgml/func.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/func.sgml,v
retrieving revision 1.286
diff -c -r1.286 func.sgml
*** doc/src/sgml/func.sgml      16 Sep 2005 05:35:39 -0000      1.286
--- doc/src/sgml/func.sgml      2 Oct 2005 23:50:12 -0000
***************
*** 9707,9712 ****
--- 9707,9836 ----
     </para>
  
    </sect1>
+ 
+  <sect1 id="functions-sqlxml">
+   <title>SQL/XML public functions</title>
+ 
+   <sect2>
+    <title><literal>XMLAGG</literal></title>
+ 
+   <indexterm>
+    <primary>XMLAGG</primary>
+   </indexterm>
+ 
+ <synopsis>
+ <function>XMLAGG</function>(<replaceable>xml expr</replaceable>)
+ </synopsis>
+ 
+    <para>
+     This combines a collection of rows, each containing a single XML
+     value, to create a single value containing an XML forest.
+    </para>
+    </sect2>
+ 
+   <sect2>
+    <title><literal>XMLCOMMENT</literal></title>
+ 
+   <indexterm>
+    <primary>XMLCOMMENT</primary>
+   </indexterm>
+ 
+ <synopsis>
+ <function>XMLCOMMENT</function>(<replaceable>text</replaceable>)
+ </synopsis>
+ 
+    <para>
+     Creates an XML comment.
+    </para>
+    </sect2>
+ 
+ 
+   <sect2>
+    <title><literal>XMLCONCAT</literal></title>
+ 
+   <indexterm>
+    <primary>XMLCONCAT</primary>
+   </indexterm>
+ 
+ <synopsis>
+ <function>XMLCONCAT</function>(<replaceable>xml expr</replaceable><optional>, 
xml expr</optional>)
+ </synopsis>
+ 
+    <para>
+     Combines a list of individual XML values to create a
+     single value containing an XML forest.
+    </para>
+    </sect2>
+ 
+   <sect2>
+    <title><literal>XMLELEMENT</literal></title>
+ 
+   <indexterm>
+    <primary>XMLELEMENT</primary>
+   </indexterm>
+ 
+ <synopsis>
+ <function>XMLELEMENT</function>(Name 
<replaceable>name</replaceable><optional>, 
XMLATTRIBUTES(<replaceable>value</replaceable> <optional>AS 
<replaceable>label</replaceable></optional><optional>, ... 
</optional>)</optional>
+ <optional>, xml expr list</optional>
+ <optional><replaceable>, value</replaceable></optional>)
+ </synopsis>
+ 
+    <para>
+     Creates an XML element, allowing the name to be specified.
+    </para>
+    </sect2>
+ 
+   <sect2>
+    <title><literal>XMLFOREST</literal></title>
+ 
+   <indexterm>
+    <primary>XMLFOREST</primary>
+   </indexterm>
+ 
+ <synopsis>
+ <function>XMLFOREST</function>(<replaceable>value</replaceable> <optional>AS 
<replaceable>label</replaceable></optional><optional>, ...</optional>)
+ </synopsis>
+ 
+    <para>
+     Creates XML elements from columns, using the name of each
+     column as the name of the corresponding element.
+    </para>
+    </sect2>
+ 
+   <sect2>
+    <title><literal>XMLPI</literal></title>
+ 
+   <indexterm>
+    <primary>XMLPI</primary>
+   </indexterm>
+ 
+ <synopsis>
+ <function>XMLPI</function>(<replaceable>text</replaceable>)
+ </synopsis>
+ 
+    <para>
+     Creates an XML processing instruction.
+    </para>
+    </sect2>
+ 
+   <sect2>
+    <title><literal>XMLROOT</literal></title>
+ 
+   <indexterm>
+    <primary>XMLROOT</primary>
+   </indexterm>
+ 
+ <synopsis>
+ <function>XMLROOT</function>(<replaceable>xml expr</replaceable>
+ <optional>, VERSION|ENCODING|STANDALONE = <replaceable>text<replaceable>, ... 
</optional>)
+ </synopsis>
+ 
+    <para>
+     Creates the root node of an XML document.
+    </para>
+    </sect2>
+ 
+   </sect1>
  </chapter>
  
  <!-- Keep this comment at the end of the file
Index: src/backend/executor/execQual.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/executor/execQual.c,v
retrieving revision 1.180
diff -c -r1.180 execQual.c
*** src/backend/executor/execQual.c     26 Jun 2005 22:05:36 -0000      1.180
--- src/backend/executor/execQual.c     2 Oct 2005 23:50:15 -0000
***************
*** 53,59 ****
  #include "utils/lsyscache.h"
  #include "utils/memutils.h"
  #include "utils/typcache.h"
! 
  
  /* static function decls */
  static Datum ExecEvalArrayRef(ArrayRefExprState *astate,
--- 53,60 ----
  #include "utils/lsyscache.h"
  #include "utils/memutils.h"
  #include "utils/typcache.h"
! #include "lib/stringinfo.h" 
! #include <string.h>
  
  /* static function decls */
  static Datum ExecEvalArrayRef(ArrayRefExprState *astate,
***************
*** 111,116 ****
--- 112,119 ----
  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(GenericExprState *nstate,
                                 ExprContext *econtext,
                                 bool *isNull, ExprDoneCond *isDone);
***************
*** 218,223 ****
--- 221,228 ----
   * have to know the difference (that's what they need refattrlength for).
   *----------
   */
+  
+ 
  static Datum
  ExecEvalArrayRef(ArrayRefExprState *astate,
                                 ExprContext *econtext,
***************
*** 2304,2312 ****
                }
        }
  
!       return result;
  }
  
  /* ----------------------------------------------------------------
   *            ExecEvalNullIf
   *
--- 2309,2507 ----
                }
        }
  
!       return result;
! }
! 
! /* ----------------------------------------------------------------
!  *            ExecEvalXml
!  * ----------------------------------------------------------------
!  */
!  
! static char *
! getXmlParam(XmlParams *params, XmlParamOp op)
! {
!       if (params == NULL)
!               return NULL;
!       switch (op)
!       {
!               case IS_XMLNAME:
!                       return params->name;
!               case IS_XMLVERSION:
!                       return params->version;
!               case IS_XMLENCODING:
!                       return params->encoding;
!               case IS_XMLSTANDALONE:
!                       return params->standalone;
!       }
!       return NULL;
! }
! 
! static void
! appendStringInfoText(StringInfo str, const text *t)
! {
!       appendBinaryStringInfo(str, VARDATA(t), VARSIZE(t) - VARHDRSZ);
! }
! 
! 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->xml_args)
!                                   {
!                                           ExprState  *e = (ExprState *) 
lfirst(arg);
!                                           Datum value = ExecEvalExpr(e, 
econtext, &isnull, NULL);
!                                           if (!isnull)
!                                           {
!                                               appendStringInfoText(&buf, 
(text *)value);
!                                               *isNull = false;
!                                           }
!                                   }
!                           }
!                           break;
!                   case IS_XMLELEMENT:
!                           {
!                                   appendStringInfo(&buf, "<%s",  
getXmlParam(xmlExpr->params, IS_XMLNAME));
!                                   int state = 0;
!                                   int i = 0;
!                                   foreach(arg, xmlExpr->nargs)
!                                   {
!                                               GenericExprState *gstate = 
(GenericExprState *) lfirst(arg);
!                                               Datum value = 
ExecEvalExpr(gstate->arg, econtext, &isnull, NULL);
!                                               if (!isnull)
!                                               {
!                                                           char *outstr = 
DatumGetCString(OidFunctionCall1(xmlExpr->nargs_tcache[i], value));
!                                                           
appendStringInfo(&buf, " %s=\"%s\"", xmlExpr->nargs_ncache[i], outstr);
!                                                           pfree(outstr);
!                                               }
!                                               i += 1;                         
                
!                                   }
!                                   foreach(arg, xmlExpr->xml_args)
!                                   {
!                                           ExprState  *e = (ExprState *) 
lfirst(arg);
!                                           Datum value = ExecEvalExpr(e, 
econtext, &isnull, NULL);
!                                           if (!isnull)
!                                           {
!                                                   if (state == 0)
!                                                   {
!                                                           
appendStringInfoChar(&buf, '>');
!                                                           state = 1;
!                                                   }   
!                                                   appendStringInfoText(&buf,  
(text *)value);
!                                           }
!                                   }
!                                   if (xmlExpr->args)
!                                   {
!                                           ExprState *expr = 
linitial(xmlExpr->args);
!                                           Datum value = ExecEvalExpr(expr, 
econtext, &isnull, NULL);
!                                   
!                                           if (!isnull)
!                                           {
!                                                   char *outstr = 
DatumGetCString(OidFunctionCall1(xmlExpr->arg_typeId, 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>",  
getXmlParam(xmlExpr->params, IS_XMLNAME));             
! 
!                           }
!                           break;
!                   case IS_XMLFOREST:
!                           {
!                                   /* only if all argumets are null returns 
null */
!                                   int i = 0; *isNull = true;
!                                   foreach(arg, xmlExpr->nargs)
!                                   {
!                                               GenericExprState *gstate = 
(GenericExprState *) lfirst(arg);
!                                               Datum value = 
ExecEvalExpr(gstate->arg, econtext, &isnull, NULL);
!                                               if (!isnull)
!                                               {
!                                                           char *outstr = 
DatumGetCString(OidFunctionCall1(xmlExpr->nargs_tcache[i], value));
!                                                           
appendStringInfo(&buf, "<%s>%s</%s>",  xmlExpr->nargs_ncache[i], outstr, 
xmlExpr->nargs_ncache[i]);                                                     
!                                                           pfree(outstr);
!                                                           *isNull = false;
!                                               }
!                                               i += 1;
!                                   }           
!                           }
!                           break;
!                   case IS_XMLCOMMENT:
!                   case IS_XMLPI:
!                           {
!                                       bool isnull;
!                                       ExprState *arg = 
linitial(xmlExpr->args);
!                                       Datum value = ExecEvalExpr(arg, 
econtext, &isnull, NULL);
!                                       char *outstr = 
DatumGetCString(OidFunctionCall1(xmlExpr->arg_typeId, value));
!                                       if (xmlExpr->op == IS_XMLCOMMENT)
!                                               appendStringInfo(&buf, "<-- %s 
-->",  outstr);
!                                       if (xmlExpr->op == IS_XMLPI)
!                                               appendStringInfo(&buf, "<? %s 
?>",  outstr);
!                                       pfree(outstr);
!                           }
!                           break;
!                   case IS_XMLROOT:
!                           {
!                                       ExprState *xarg = 
linitial(xmlExpr->xml_args);
!                                       Datum value = ExecEvalExpr(xarg, 
econtext, &isnull, NULL);
!                                       
!                                       appendStringInfo(&buf,"<?xml");
!                                       if (getXmlParam(xmlExpr->params, 
IS_XMLVERSION))
!                                               appendStringInfo(&buf, " 
version=\"%s\"", getXmlParam(xmlExpr->params, IS_XMLVERSION));
!                                       if (getXmlParam(xmlExpr->params, 
IS_XMLENCODING))
!                                               appendStringInfo(&buf, " 
encoding=\"%s\"", getXmlParam(xmlExpr->params,IS_XMLENCODING));
!                                       if (getXmlParam(xmlExpr->params, 
IS_XMLSTANDALONE)) 
!                                               appendStringInfo(&buf, " 
standalone=\"%s\"", getXmlParam(xmlExpr->params,IS_XMLSTANDALONE));
!                                       appendStringInfo(&buf, "?>");
!                                       appendStringInfoText(&buf, (text *) 
value);
!                           }
!                           break;
!                   case IS_XMLSERIALIZE:
!                           {
!                                       ExprState  *arg = 
linitial(xmlExpr->xml_args);
!                                       Datum value = ExecEvalExpr(arg, 
econtext, isNull, NULL);
!                                       PG_RETURN_TEXT_P(value);
!                           }
!                           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);
!               
  }
  
+ 
  /* ----------------------------------------------------------------
   *            ExecEvalNullIf
   *
***************
*** 3296,3301 ****
--- 3491,3565 ----
                                state = (ExprState *) mstate;
                        }
                        break;
+               case T_XmlExpr:
+                       {
+                               List *outlist; ListCell *arg;
+                               XmlExpr *xexpr = (XmlExpr *) node;
+                               XmlExprState *xstate = makeNode(XmlExprState);
+                               int i = 0; Oid typid;
+               
+                               xstate->level = xexpr->level;
+                               xstate->params = xexpr->params;
+                                                               
+                               xstate->xprstate.evalfunc = (ExprStateEvalFunc) 
ExecEvalXml;
+                               xstate->op = xexpr->op;
+                               
+                               outlist = NIL;
+                               if (xexpr->nargs)
+                               {
+                                       xstate->nargs_tcache = 
(int*)palloc(list_length(xexpr->nargs)*sizeof(int));
+                                       xstate->nargs_ncache = 
(char**)palloc(list_length(xexpr->nargs)*sizeof(char*));
+                                       
+                                       i = 0;
+                                       foreach(arg, xexpr->nargs)
+                                       {
+                                               bool tpisvarlena;
+                                               Expr *e = (Expr *) lfirst(arg);
+                                               ExprState *estate = 
ExecInitExpr(e, parent);
+                                               
+                                               outlist = lappend(outlist, 
estate);                                     
+                                               TargetEntry *tle = (TargetEntry 
*) ((GenericExprState *) estate)->xprstate.expr;
+                                               
getTypeOutputInfo(exprType((Node *)tle->expr), &typid, &tpisvarlena);
+                                               xstate->nargs_ncache[i] = 
tle->resname;
+                                               xstate->nargs_tcache[i++] = 
typid;
+                                       }       
+                               }
+                               else
+                               {
+                                       xstate->nargs_tcache = NULL;
+                                       xstate->nargs_ncache = NULL;
+                               }
+                               xstate->nargs = outlist;
+ 
+                               outlist = NIL;                          
+                               if (xexpr->xml_args)
+                               {
+                                       foreach(arg, xexpr->xml_args)
+                                       {
+                                               Expr *e = (Expr *) lfirst(arg);
+                                               ExprState *estate = 
ExecInitExpr(e, parent);
+                                               
+                                               outlist = lappend(outlist, 
estate);                                     
+                                       }       
+                               }
+                               xstate->xml_args = outlist;
+                               
+                               outlist = NIL;
+                               foreach(arg, xexpr->args)
+                               {
+                                       bool tpisvarlena;
+                                       Expr *e = (Expr *) lfirst(arg);
+                                       getTypeOutputInfo(exprType((Node *)e), 
&typid, &tpisvarlena);
+                                       ExprState *estate = ExecInitExpr(e, 
parent);
+                                       outlist = lappend(outlist, estate);
+                               }
+                               xstate->arg_typeId = typid;
+                               xstate->args = outlist;
+                               
+                               state = (ExprState *) xstate;
+                       }
+                       break;
+ 
                case T_NullIfExpr:
                        {
                                NullIfExpr *nullifexpr = (NullIfExpr *) node;
Index: src/backend/nodes/copyfuncs.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v
retrieving revision 1.315
diff -c -r1.315 copyfuncs.c
*** src/backend/nodes/copyfuncs.c       1 Aug 2005 20:31:08 -0000       1.315
--- src/backend/nodes/copyfuncs.c       2 Oct 2005 23:50:17 -0000
***************
*** 1063,1068 ****
--- 1063,1098 ----
  }
  
  /*
+  * _copyXmlExpr
+  */
+ 
+ static XmlParams *
+ _copyXmlParams(XmlParams *from)
+ {
+       XmlParams *newnode = makeNode(XmlParams);
+       COPY_STRING_FIELD(name);
+       COPY_STRING_FIELD(version);
+       COPY_STRING_FIELD(encoding);
+       COPY_STRING_FIELD(standalone);
+       
+       return newnode;
+ } 
+  
+ static XmlExpr *
+ _copyXmlExpr(XmlExpr *from)
+ {
+       XmlExpr *newnode = makeNode(XmlExpr);
+       COPY_SCALAR_FIELD(op);
+       COPY_NODE_FIELD(xml_args);
+       COPY_NODE_FIELD(nargs);
+       COPY_NODE_FIELD(args);
+       COPY_NODE_FIELD(params);
+       COPY_SCALAR_FIELD(level);
+     
+       return newnode;
+ }
+ 
+ /*
   * _copyNullIfExpr (same as OpExpr)
   */
  static NullIfExpr *
***************
*** 2843,2848 ****
--- 2873,2884 ----
                case T_MinMaxExpr:
                        retval = _copyMinMaxExpr(from);
                        break;
+               case T_XmlParams:
+                       retval = _copyXmlParams(from);
+                       break;
+               case T_XmlExpr:
+                       retval = _copyXmlExpr(from);
+                       break;
                case T_NullIfExpr:
                        retval = _copyNullIfExpr(from);
                        break;
Index: src/backend/nodes/equalfuncs.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v
retrieving revision 1.252
diff -c -r1.252 equalfuncs.c
*** src/backend/nodes/equalfuncs.c      1 Aug 2005 20:31:08 -0000       1.252
--- src/backend/nodes/equalfuncs.c      2 Oct 2005 23:50:18 -0000
***************
*** 460,465 ****
--- 460,488 ----
        return true;
  }
  
+ 
+ static bool
+ _equalXmlParams(XmlParams *a, XmlParams *b)
+ {
+       COMPARE_STRING_FIELD(name);
+       COMPARE_STRING_FIELD(version);
+       COMPARE_STRING_FIELD(encoding);
+       COMPARE_STRING_FIELD(standalone);
+ }
+ 
+ static bool
+ _equalXmlExpr(XmlExpr *a, XmlExpr *b)
+ {
+       COMPARE_SCALAR_FIELD(op);
+       COMPARE_NODE_FIELD(xml_args);
+       COMPARE_NODE_FIELD(args);
+       COMPARE_NODE_FIELD(nargs);
+       COMPARE_NODE_FIELD(params);
+       COMPARE_SCALAR_FIELD(level);
+       
+       return true;
+ }
+ 
  static bool
  _equalNullIfExpr(NullIfExpr *a, NullIfExpr *b)
  {
***************
*** 1899,1904 ****
--- 1922,1933 ----
                case T_MinMaxExpr:
                        retval = _equalMinMaxExpr(a, b);
                        break;
+               case T_XmlParams:
+                       retval = _equalXmlParams(a, b);
+                       break;
+               case T_XmlExpr:
+                       retval = _equalXmlExpr(a, b);
+                       break;
                case T_NullIfExpr:
                        retval = _equalNullIfExpr(a, b);
                        break;
Index: src/backend/nodes/outfuncs.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/nodes/outfuncs.c,v
retrieving revision 1.260
diff -c -r1.260 outfuncs.c
*** src/backend/nodes/outfuncs.c        27 Aug 2005 22:13:43 -0000      1.260
--- src/backend/nodes/outfuncs.c        2 Oct 2005 23:50:19 -0000
***************
*** 875,880 ****
--- 875,904 ----
  }
  
  static void
+ _outXmlParams(StringInfo str, XmlParams *node)
+ {
+       WRITE_NODE_TYPE("XMLPARAMS");
+       
+       WRITE_STRING_FIELD(name);
+       WRITE_STRING_FIELD(encoding);
+       WRITE_STRING_FIELD(version);
+       WRITE_STRING_FIELD(standalone);
+ }
+ 
+ static void
+ _outXmlExpr(StringInfo str, XmlExpr *node)
+ {
+       WRITE_NODE_TYPE("XMLEXPR");
+       
+       WRITE_ENUM_FIELD(op, XmlExprOp);
+       WRITE_NODE_FIELD(xml_args);
+       WRITE_NODE_FIELD(nargs);
+       WRITE_NODE_FIELD(args);
+       WRITE_NODE_FIELD(params);
+       WRITE_INT_FIELD(level);
+ }
+ 
+ static void
  _outNullIfExpr(StringInfo str, NullIfExpr *node)
  {
        WRITE_NODE_TYPE("NULLIFEXPR");
***************
*** 1925,1930 ****
--- 1949,1957 ----
                        case T_MinMaxExpr:
                                _outMinMaxExpr(str, obj);
                                break;
+                       case T_XmlExpr:
+                               _outXmlExpr(str, obj);
+                               break;
                        case T_NullIfExpr:
                                _outNullIfExpr(str, obj);
                                break;
Index: src/backend/nodes/readfuncs.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/nodes/readfuncs.c,v
retrieving revision 1.181
diff -c -r1.181 readfuncs.c
*** src/backend/nodes/readfuncs.c       1 Aug 2005 20:31:08 -0000       1.181
--- src/backend/nodes/readfuncs.c       2 Oct 2005 23:50:20 -0000
***************
*** 81,87 ****
  
  /* Read a float field */
  #define READ_FLOAT_FIELD(fldname) \
!       token = pg_strtok(&length);             /* skip :fldname */ \
        token = pg_strtok(&length);             /* get field value */ \
        local_node->fldname = atof(token)
  
--- 81,87 ----
  
  /* Read a float field */
  #define READ_FLOAT_FIELD(fldname) \
!               /* skip :fldname */ \
        token = pg_strtok(&length);             /* get field value */ \
        local_node->fldname = atof(token)
  
***************
*** 674,679 ****
--- 674,707 ----
        READ_DONE();
  }
  
+ static XmlParams *
+ _readXmlParams(void)
+ {
+       READ_LOCALS(XmlParams);
+ 
+       READ_STRING_FIELD(name);
+       READ_STRING_FIELD(encoding);
+       READ_STRING_FIELD(version);
+       READ_STRING_FIELD(standalone);
+ 
+       READ_DONE();
+ }     
+ 
+ static XmlExpr *
+ _readXmlExpr(void)
+ {
+       READ_LOCALS(XmlExpr);
+     
+       READ_ENUM_FIELD(op, XmlExprOp);
+       READ_NODE_FIELD(xml_args);
+       READ_NODE_FIELD(nargs);
+       READ_NODE_FIELD(args);
+       READ_NODE_FIELD(params);
+       READ_INT_FIELD(level);
+     
+       READ_DONE();
+ }
+ 
  /*
   * _readNullIfExpr
   */
***************
*** 1000,1005 ****
--- 1028,1037 ----
                return_value = _readCoalesceExpr();
        else if (MATCH("MINMAX", 6))
                return_value = _readMinMaxExpr();
+       else if (MATCH("XMLPARAMS", 9))
+               return_value = _readXmlParams();
+       else if (MATCH("XMLEXPR", 7))
+               return_value = _readXmlExpr();
        else if (MATCH("NULLIFEXPR", 10))
                return_value = _readNullIfExpr();
        else if (MATCH("NULLTEST", 8))
Index: src/backend/optimizer/util/clauses.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v
retrieving revision 1.200
diff -c -r1.200 clauses.c
*** src/backend/optimizer/util/clauses.c        3 Jul 2005 21:14:17 -0000       
1.200
--- src/backend/optimizer/util/clauses.c        2 Oct 2005 23:50:22 -0000
***************
*** 546,551 ****
--- 546,553 ----
                return false;
        if (IsA(node, NullIfExpr))
                return false;
+       if (IsA(node, XmlExpr))
+               return false;
  
        return expression_tree_walker(node, expression_returns_set_walker,
                                                                  context);
***************
*** 853,858 ****
--- 855,862 ----
                return true;
        if (IsA(node, NullIfExpr))
                return true;
+       if (IsA(node, XmlExpr))
+               return true;
        if (IsA(node, NullTest))
                return true;
        if (IsA(node, BooleanTest))
***************
*** 2944,2949 ****
--- 2948,2964 ----
                        return walker(((MinMaxExpr *) node)->args, context);
                case T_NullIfExpr:
                        return walker(((NullIfExpr *) node)->args, context);
+               case T_XmlExpr:
+                       {
+                               XmlExpr *xexpr = (XmlExpr *) node;
+                               if (walker(xexpr->nargs, context))
+                                       return true;
+                               if (walker(xexpr->xml_args, context))
+                                       return true;
+                               if (walker(xexpr->args, context))
+                                       return true;
+                       }
+                       break;
                case T_NullTest:
                        return walker(((NullTest *) node)->arg, context);
                case T_BooleanTest:
***************
*** 3422,3427 ****
--- 3437,3454 ----
                                return (Node *) newnode;
                        }
                        break;
+               case T_XmlExpr:
+                       {
+                               XmlExpr *xexpr = (XmlExpr *) node;
+                               XmlExpr *newnode;
+                               
+                               FLATCOPY(newnode, xexpr, XmlExpr);
+                               MUTATE(newnode->nargs, xexpr->nargs, List *);
+                               MUTATE(newnode->xml_args, xexpr->xml_args, List 
*);
+                               MUTATE(newnode->args, xexpr->args, List *);
+                               return (Node *) newnode;
+                       }
+                       break;
                case T_NullTest:
                        {
                                NullTest   *ntest = (NullTest *) node;
Index: src/backend/parser/gram.y
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.511
diff -c -r2.511 gram.y
*** src/backend/parser/gram.y   23 Sep 2005 22:25:25 -0000      2.511
--- src/backend/parser/gram.y   2 Oct 2005 23:50:28 -0000
***************
*** 91,96 ****
--- 91,101 ----
                                                                Node 
*limitOffset, Node *limitCount);
  static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
  static Node *doNegate(Node *n);
+ static XmlExpr *makeXmlExpr(XmlExprOp op, char *name, 
+                                                       List *xml_attr, List 
*xml_args, 
+                                                       List *args, XmlParams 
*params);
+ static XmlParams *setXmlParam(XmlParams *params, XmlParamOp op, char *value);
+ 
  static void doNegateFloat(Value *v);
  
  %}
***************
*** 128,133 ****
--- 133,141 ----
  
        InsertStmt                      *istmt;
        VariableSetStmt         *vsetstmt;
+       XmlExpr                 *xmlexpr;
+       XmlParams               *xmlparams;
+       XmlParam                xmlparam;
  }
  
  %type <node>  stmt schema_stmt
***************
*** 325,330 ****
--- 333,345 ----
  %type <boolean> constraints_set_mode
  %type <str>           OptTableSpace OptConsTableSpace OptTableSpaceOwner
  
+ %type <target>        n_expr_el
+ %type <xmlexpr> xmlexpr xml_args
+ %type <list>  xmlexpr_list n_expr_list
+ %type <xmlparams> xmlroot_par_list
+ %type <xmlparam> xmlroot_param 
+ 
+ 
  
  /*
   * If you make any token changes, update the keyword table in
***************
*** 377,383 ****
  
        MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
  
!       NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
        NOCREATEROLE NOCREATEUSER NOINHERIT NOLOGIN_P NONE NOSUPERUSER
        NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NUMERIC
  
--- 392,398 ----
  
        MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
  
!       NAME NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
        NOCREATEROLE NOCREATEUSER NOINHERIT NOLOGIN_P NONE NOSUPERUSER
        NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NUMERIC
  
***************
*** 398,404 ****
        SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
        SHOW SIMILAR SIMPLE SMALLINT SOME STABLE START STATEMENT
        STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SUPERUSER_P SYMMETRIC
!       SYSID SYSTEM_P
  
        TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP
        TO TOAST TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
--- 413,419 ----
        SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
        SHOW SIMILAR SIMPLE SMALLINT SOME STABLE START STATEMENT
        STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SUPERUSER_P SYMMETRIC
!       SYSID SYSTEM_P STANDALONE
  
        TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP
        TO TOAST TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
***************
*** 408,416 ****
        UPDATE USER USING
  
        VACUUM VALID VALIDATOR VALUES VARCHAR VARYING
!       VERBOSE VIEW VOLATILE
  
        WHEN WHERE WITH WITHOUT WORK WRITE
  
        YEAR_P
  
--- 423,434 ----
        UPDATE USER USING
  
        VACUUM VALID VALIDATOR VALUES VARCHAR VARYING
!       VERBOSE VERSION VIEW VOLATILE
  
        WHEN WHERE WITH WITHOUT WORK WRITE
+       
+       XMLAGG XMLATTRIBUTES XMLCOMMENT XMLCONCAT XMLELEMENT XMLFOREST 
+       XMLPI XMLROOT XMLSERIALIZE
  
        YEAR_P
  
***************
*** 7408,7413 ****
--- 7426,7560 ----
                                        v->op = IS_LEAST;
                                        $$ = (Node *)v;
                                }
+                       | XMLSERIALIZE '(' xmlexpr ')'
+                               {
+                                       $$ = (Node *)
+                                           makeXmlExpr(IS_XMLSERIALIZE, NULL, 
NULL, list_make1($3), NULL, NULL);
+                               }
+               ;
+               
+ /*
+  *  Supporting SQL/XML functions, use only for publishing. For storing results
+  *  to tables and using them in pub. functions is neccessery support xml 
datatype, 
+  *  one part of xmlexpr will be col with xml value. 
+  */
+  
+ xmlexpr:              XMLAGG '(' a_expr ')' /* for nested xmlagg */
+                               {
+                                       $$ = makeXmlExpr(IS_XMLAGG, NULL, NULL, 
NULL, list_make1($3), NULL);
+                               }
+                       | XMLAGG '(' xmlexpr ')'
+                               {       
+                                       $$ = makeXmlExpr(IS_XMLAGG, NULL, NULL, 
list_make1($3), NULL, NULL);
+                               }
+                       | XMLCOMMENT '(' a_expr ')'
+                               {
+                                       $$ = makeXmlExpr(IS_XMLCOMMENT, NULL, 
NULL, NULL, list_make1($3), NULL);
+                               }                       
+                       | XMLCONCAT '(' xmlexpr_list ')'
+                               {               
+                                       $$ = makeXmlExpr(IS_XMLCONCAT, NULL, 
NULL, $3, NULL, NULL);
+                               }                       
+                       | XMLELEMENT '(' NAME ColLabel ',' xml_args ')'
+                               { 
+                                       $6->params = setXmlParam($6->params, 
IS_XMLNAME, $4);
+                                       $6->op = IS_XMLELEMENT;
+                                       $$ = $6;
+                               }
+                       | XMLELEMENT '(' NAME ColLabel ')'
+                               {
+                                       $$ = makeXmlExpr(IS_XMLELEMENT, $4, 
NULL, NULL, NULL, NULL);
+                               }                       
+ 
+                       | XMLELEMENT '(' NAME ColLabel ',' XMLATTRIBUTES '(' 
n_expr_list ')' ',' xml_args ')'
+                               {
+                                       $11->params = setXmlParam($11->params, 
IS_XMLNAME, $4);
+                                       $11->nargs = $8;
+                                       $11->op = IS_XMLELEMENT;
+                                       $$ = $11;
+                               }
+                       | XMLELEMENT '(' NAME ColLabel ',' XMLATTRIBUTES '(' 
n_expr_list ')' ')'
+                               {
+                                       $$ = makeXmlExpr(IS_XMLELEMENT, $4, $8, 
NULL, NULL, NULL);
+                               }                       
+                       | XMLFOREST '(' n_expr_list ')'
+                               {
+                                       $$ = makeXmlExpr(IS_XMLFOREST, NULL, 
$3, NULL, NULL, NULL);
+                               }
+                       | XMLPI '(' a_expr ')'
+                               {
+                                       $$ = makeXmlExpr(IS_XMLPI, NULL, NULL, 
NULL, list_make1($3), NULL);
+                               }
+                       | XMLROOT '(' xmlexpr ',' xmlroot_par_list ')'
+                               {
+                                       $$ = makeXmlExpr(IS_XMLROOT, NULL, 
NULL, list_make1($3), NULL, $5);
+                               }
+                       | XMLROOT '(' xmlexpr ')'
+                               {
+                                       $$ = makeXmlExpr(IS_XMLROOT, NULL, 
NULL, list_make1($3), NULL, NULL);
+                               } 
+               ;
+ 
+ 
+ xmlroot_par_list:     xmlroot_param                                   { $$ = 
setXmlParam(NULL, $1.op, $1.value); }
+                       | xmlroot_par_list ',' xmlroot_param            { $$ = 
setXmlParam($1, $3.op, $3.value); }
+               ;
+           
+ 
+ xmlroot_param:                VERSION Sconst  
+                               {
+                                       $$.op = IS_XMLVERSION;
+                                       $$.value = $2;
+                               }
+                       | ENCODING Sconst
+                               {
+                                       $$.op = IS_XMLENCODING;
+                                       $$.value = $2;
+                               }
+                       | STANDALONE Sconst
+                               {
+                                       $$.op = IS_XMLSTANDALONE;
+                                       $$.value = $2;
+                               }
+               ;
+               
+ xml_args:             xmlexpr_list ',' a_expr
+                               {
+                                       $$ = makeXmlExpr(IS_XMLUNKNOWN, NULL, 
NULL, $1, list_make1($3), NULL);
+                               }
+                       | a_expr
+                               {
+                                       $$ = makeXmlExpr(IS_XMLUNKNOWN, NULL, 
NULL, NULL, list_make1($1), NULL);
+                               }                               
+                       | xmlexpr_list
+                               {
+                                       $$ = makeXmlExpr(IS_XMLUNKNOWN, NULL, 
NULL, $1, NULL, NULL);
+                               }
+               ;
+               
+ xmlexpr_list:         xmlexpr                                 { $$ = 
list_make1($1); }
+                       | xmlexpr_list ',' xmlexpr              { $$ = 
lappend($1, $3); }
+               ;
+                       
+ n_expr_list:          n_expr_el                               { $$ = 
list_make1($1); }
+                       | n_expr_list ',' n_expr_el             { $$ = 
lappend($1, $3); }
+               ;
+               
+ n_expr_el:            a_expr AS ColLabel
+                               {
+                                       $$ = makeNode(ResTarget);
+                                       $$->name = $3;
+                                       $$->indirection = NULL;
+                                       $$->val = (Node *) $1;
+                                       
+                               }
+                       | a_expr
+                               {
+                                       $$ = makeNode(ResTarget);
+                                       $$->name = NULL;
+                                       $$->indirection = NULL;
+                                       $$->val = (Node *) $1;                  
        
+                               }
                ;
  
  /*
***************
*** 7770,7775 ****
--- 7917,7936 ----
                                        $$->indirection = NIL;
                                        $$->val = (Node *)n;
                                }
+                       | xmlexpr AS ColLabel
+                               {
+                                       $$ = makeNode(ResTarget);
+                                       $$->name = $3;
+                                       $$->indirection = NIL;
+                                       $$->val = (Node *)$1;
+                               }
+                       | xmlexpr
+                               {
+                                       $$ = makeNode(ResTarget);
+                                       $$->name = NULL;
+                                       $$->indirection = NIL;
+                                       $$->val = (Node *)$1;
+                               }
                ;
  
  update_target_list:
***************
*** 8240,8245 ****
--- 8401,8407 ----
                        | SHOW
                        | SIMPLE
                        | STABLE
+                       | STANDALONE
                        | START
                        | STATEMENT
                        | STATISTICS
***************
*** 8279,8284 ****
--- 8441,8448 ----
                        | WRITE
                        | YEAR_P
                        | ZONE
+                       | NAME
+                       | VERSION
                ;
  
  /* Column identifier --- keywords that can be column, table, etc names.
***************
*** 8329,8334 ****
--- 8493,8507 ----
                        | TREAT
                        | TRIM
                        | VARCHAR
+                       | XMLAGG
+                       | XMLATTRIBUTES
+                       | XMLELEMENT
+                       | XMLCOMMENT
+                       | XMLCONCAT
+                       | XMLFOREST
+                       | XMLROOT
+                       | XMLSERIALIZE
+                       | XMLPI
                ;
  
  /* Function identifier --- keywords that can be function names.
***************
*** 8914,8917 ****
--- 9087,9138 ----
        }
  }
  
+ static XmlParams *
+ setXmlParam(XmlParams *params, XmlParamOp op, char *value)
+ {
+       if (value == NULL)
+               return params;
+                       
+       if (params == NULL)
+       {
+               params = makeNode(XmlParams);
+               params->encoding = NULL;
+               params->name = NULL;
+               params->version = NULL;
+               params->standalone = NULL;
+       }
+       switch (op)
+       {
+               case IS_XMLENCODING:
+                       params->encoding = value;
+                       break;
+               case IS_XMLVERSION:
+                       params->version = value;
+                       break;
+               case IS_XMLNAME:
+                       params->name = value;
+                       break;
+               case IS_XMLSTANDALONE:
+                       params->standalone = value;
+                       break;
+       }
+       return params;
+ }
+ 
+ static XmlExpr *
+ makeXmlExpr(XmlExprOp op, char *name, List *nargs, List *xml_args, 
+     List *args, XmlParams *params)
+ {
+       
+       XmlExpr *x = makeNode(XmlExpr);
+       x->op = op;
+       x->nargs = nargs;
+       x->xml_args = xml_args;
+       x->args = args;
+       x->level = 0;
+       x->params = setXmlParam(params, IS_XMLNAME, name);
+       return x;
+ }
+ 
+ 
  #include "scan.c"
Index: src/backend/parser/keywords.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/keywords.c,v
retrieving revision 1.165
diff -c -r1.165 keywords.c
*** src/backend/parser/keywords.c       23 Aug 2005 22:40:27 -0000      1.165
--- src/backend/parser/keywords.c       2 Oct 2005 23:50:28 -0000
***************
*** 213,218 ****
--- 213,219 ----
        {"mode", MODE},
        {"month", MONTH_P},
        {"move", MOVE},
+       {"name", NAME},
        {"names", NAMES},
        {"national", NATIONAL},
        {"natural", NATURAL},
***************
*** 306,311 ****
--- 307,313 ----
        {"smallint", SMALLINT},
        {"some", SOME},
        {"stable", STABLE},
+       {"standalone", STANDALONE},
        {"start", START},
        {"statement", STATEMENT},
        {"statistics", STATISTICS},
***************
*** 354,359 ****
--- 356,362 ----
        {"varchar", VARCHAR},
        {"varying", VARYING},
        {"verbose", VERBOSE},
+       {"version", VERSION},
        {"view", VIEW},
        {"volatile", VOLATILE},
        {"when", WHEN},
***************
*** 362,367 ****
--- 365,379 ----
        {"without", WITHOUT},
        {"work", WORK},
        {"write", WRITE},
+       {"xmlagg", XMLAGG},
+       {"xmlattributes", XMLATTRIBUTES},
+       {"xmlcomment", XMLCOMMENT},
+       {"xmlconcat", XMLCONCAT},
+       {"xmlelement", XMLELEMENT},
+       {"xmlforest", XMLFOREST},
+       {"xmlpi", XMLPI},
+       {"xmlroot", XMLROOT},
+       {"xmlserialize", XMLSERIALIZE},
        {"year", YEAR_P},
        {"zone", ZONE},
  };
Index: src/backend/parser/parse_expr.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/parse_expr.c,v
retrieving revision 1.184
diff -c -r1.184 parse_expr.c
*** src/backend/parser/parse_expr.c     26 Jun 2005 22:05:39 -0000      1.184
--- src/backend/parser/parse_expr.c     2 Oct 2005 23:50:30 -0000
***************
*** 54,59 ****
--- 54,60 ----
  static Node *transformRowExpr(ParseState *pstate, RowExpr *r);
  static Node *transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c);
  static Node *transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m);
+ static Node *transformXmlExpr(ParseState *pstate, XmlExpr *x);
  static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b);
  static Node *transformColumnRef(ParseState *pstate, ColumnRef *cref);
  static Node *transformWholeRowRef(ParseState *pstate, char *schemaname,
***************
*** 70,75 ****
--- 71,77 ----
  static Expr *make_distinct_op(ParseState *pstate, List *opname,
                                 Node *ltree, Node *rtree);
  
+ extern char *FigureColname(Node *e);
  
  /*
   * transformExpr -
***************
*** 213,219 ****
                case T_MinMaxExpr:
                        result = transformMinMaxExpr(pstate, (MinMaxExpr *) 
expr);
                        break;
! 
                case T_NullTest:
                        {
                                NullTest   *n = (NullTest *) expr;
--- 215,225 ----
                case T_MinMaxExpr:
                        result = transformMinMaxExpr(pstate, (MinMaxExpr *) 
expr);
                        break;
!               
!               case T_XmlExpr:
!                       result = transformXmlExpr(pstate, (XmlExpr *) expr);
!                       break;
!                       
                case T_NullTest:
                        {
                                NullTest   *n = (NullTest *) expr;
***************
*** 1272,1277 ****
--- 1278,1382 ----
        return (Node *) newm;
  }
  
+               
+ static Node *
+ transformList(ParseState *pstate, List *list)
+ {
+       List *newlist = NIL;
+       ListCell *arg;
+       foreach(arg, list)
+       {
+               Node *e = (Node*)lfirst(arg);
+               Node *te = transformExpr(pstate, e);
+               newlist = lappend(newlist, te);
+       }
+       return (Node *)newlist;
+ }
+ 
+ static Node *
+ transformXmlList(ParseState *pstate, List *list, int level)
+ {
+       List *newlist = NIL;
+       ListCell *arg;
+       foreach(arg, list)
+       {
+               Node *e = (Node*)lfirst(arg);
+               ((XmlExpr *)e)->level = level;
+               Node *te = transformExpr(pstate, e);
+               newlist = lappend(newlist, te);
+       }
+       return (Node *)newlist;
+ }
+ 
+ 
+ /* transformation named expressions */
+ 
+ static Node *
+ transformNPList(ParseState *pstate, List *list)
+ {     
+       List *newlist = NIL;
+       ListCell *arg;
+       foreach(arg, list)
+       {
+           ResTarget *r = (ResTarget *) lfirst(arg);
+           Node *expr = transformExpr(pstate, r->val);
+           char *colname = r->name;
+           if (colname == NULL)
+               colname = FigureColname(r->val);
+           newlist = lappend(newlist, 
+                                       makeTargetEntry((Expr *) expr, 0, 
colname, false)); 
+       } 
+       return (Node *)newlist;
+ }
+ 
+ static Node *
+ transformXmlExpr(ParseState *pstate, XmlExpr *x)
+ {
+       XmlExpr *newx = makeNode(XmlExpr);
+       
+       if (x->op == IS_XMLAGG)
+       {
+               /* set level */
+               if (x->xml_args)
+               {
+                   XmlExpr *p = (XmlExpr *) linitial(x->xml_args);
+                   p->level = x->level + 1;
+               
+                   FuncCall *n = makeNode(FuncCall);
+                   n->funcname = SystemFuncName("xmlagg");
+                   n->args = x->xml_args;
+                   n->agg_star = FALSE;
+                   n->agg_distinct = FALSE;
+                   return transformExpr(pstate, (Node *) n);
+ 
+               } else
+               {
+                   FuncCall *n = makeNode(FuncCall);
+                   n->funcname = SystemFuncName("xmlagg");
+                   n->args = x->args;
+                   n->agg_star = FALSE;
+                   n->agg_distinct = FALSE;
+               
+                   return transformExpr(pstate, (Node *) n);
+ 
+               }       
+       }
+ 
+ 
+       /* Mechanismem transformace dokazu vnutit podrizenym xmlfunkcim level,
+        * v budoucnu napriklad ukazatel na hash s tagy a attributy */
+        
+       newx->nargs = (List *)transformNPList(pstate, x->nargs);
+       newx->xml_args = (List *)transformXmlList(pstate, x->xml_args, 
x->level+1);     
+         newx->args = (List *)transformList(pstate, x->args);
+           
+       newx->params = x->params;
+       newx->op = x->op;
+       newx->level = x->level;
+               
+       return (Node *) newx;
+ }
+ 
  static Node *
  transformBooleanTest(ParseState *pstate, BooleanTest *b)
  {
***************
*** 1549,1554 ****
--- 1654,1662 ----
                case T_MinMaxExpr:
                        type = ((MinMaxExpr *) expr)->minmaxtype;
                        break;
+               case T_XmlExpr:
+                       type = TEXTOID;
+                       break;
                case T_NullIfExpr:
                        type = exprType((Node *) linitial(((NullIfExpr *) 
expr)->args));
                        break;
Index: src/backend/parser/parse_target.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/parse_target.c,v
retrieving revision 1.137
diff -c -r1.137 parse_target.c
*** src/backend/parser/parse_target.c   26 Jun 2005 22:05:40 -0000      1.137
--- src/backend/parser/parse_target.c   2 Oct 2005 23:50:30 -0000
***************
*** 1135,1140 ****
--- 1135,1173 ----
                                        return 2;
                        }
                        break;
+               case T_XmlExpr:
+                       /* make SQL/XML functions act like a regular function */
+                       switch (((XmlExpr*) node)->op)
+                       {               
+                               case IS_XMLCOMMENT:
+                                       *name = "xmlcomment";
+                                       return 2;
+                               case IS_XMLCONCAT:
+                                       *name = "xmlconcat";
+                                       return 2;
+                               case IS_XMLELEMENT:
+                                       *name = "xmlelement";
+                                       return 2;
+                               case IS_XMLFOREST:
+                                       *name = "xmlforest";
+                                       return 2;
+                               case IS_XMLPI:
+                                       *name = "xmlpi";
+                                       return 2;
+                               case IS_XMLROOT:
+                                       *name = "xmlroot";
+                                       return 2;
+                               case IS_XMLSERIALIZE:
+                                       *name = "xmlserialize";
+                                       return 2;
+                               case IS_XMLUNKNOWN:
+                                       *name = "unknown xml function";
+                                       return 2;
+                               case IS_XMLAGG:
+                                       *name = "xmlagg";
+                                       return 2;
+                       } 
+                       break;
                default:
                        break;
        }
Index: src/backend/utils/adt/ruleutils.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v
retrieving revision 1.205
diff -c -r1.205 ruleutils.c
*** src/backend/utils/adt/ruleutils.c   1 Aug 2005 20:31:12 -0000       1.205
--- src/backend/utils/adt/ruleutils.c   2 Oct 2005 23:50:34 -0000
***************
*** 2793,2798 ****
--- 2793,2799 ----
                case T_CoalesceExpr:
                case T_MinMaxExpr:
                case T_NullIfExpr:
+               case T_XmlExpr:
                case T_Aggref:
                case T_FuncExpr:
                        /* function-like: name(..) or name[..] */
***************
*** 2901,2906 ****
--- 2902,2908 ----
                                case T_CoalesceExpr:    /* own parentheses */
                                case T_MinMaxExpr:              /* own 
parentheses */
                                case T_NullIfExpr:              /* other 
separators */
+                               case T_XmlExpr:                 /* own 
parentheses */
                                case T_Aggref:                  /* own 
parentheses */
                                case T_CaseExpr:                /* other 
separators */
                                        return true;
***************
*** 2949,2954 ****
--- 2951,2957 ----
                                case T_CoalesceExpr:    /* own parentheses */
                                case T_MinMaxExpr:              /* own 
parentheses */
                                case T_NullIfExpr:              /* other 
separators */
+                               case T_XmlExpr:                 /* own 
parentheses */
                                case T_Aggref:                  /* own 
parentheses */
                                case T_CaseExpr:                /* other 
separators */
                                        return true;
***************
*** 3531,3537 ****
                                appendStringInfoChar(buf, ')');
                        }
                        break;
! 
                case T_NullTest:
                        {
                                NullTest   *ntest = (NullTest *) node;
--- 3534,3576 ----
                                appendStringInfoChar(buf, ')');
                        }
                        break;
!               
!               case T_XmlExpr:
!                       {
!                               XmlExpr *xexpr = (XmlExpr *) node;
!                               switch (xexpr->op)
!                               {
!                                       case IS_XMLCOMMENT:
!                                               
appendStringInfo(buf,"XMLCOMMENT(");
!                                               break;
!                                       case IS_XMLCONCAT:
!                                               
appendStringInfo(buf,"XMLCONCAT(");
!                                               break;
!                                       case IS_XMLELEMENT:
!                                               
appendStringInfo(buf,"XMLELEMENT(");
!                                               break;
!                                       case IS_XMLFOREST:
!                                               
appendStringInfo(buf,"XMLFOREST(");
!                                               break;
!                                       case IS_XMLPI:
!                                               appendStringInfo(buf,"XMLPI(");
!                                               break;
!                                       case IS_XMLROOT:
!                                               
appendStringInfo(buf,"XMLROOT(");
!                                               break;
!                                       case IS_XMLSERIALIZE:
!                                               
appendStringInfo(buf,"XMLSERIALIZE(");
!                                               break;
!                                       case IS_XMLUNKNOWN:  /* quite compiler 
warnings */
!                                               break;
!                               }
!                               get_rule_expr((Node *) xexpr->nargs, context, 
true);
!                               get_rule_expr((Node *) xexpr->xml_args, 
context, true);
!                               get_rule_expr((Node *) xexpr->args, context, 
true);
!                               appendStringInfoChar(buf, ')');
!                       }
!                       break;
!                       
                case T_NullTest:
                        {
                                NullTest   *ntest = (NullTest *) node;
Index: src/backend/utils/adt/varchar.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/varchar.c,v
retrieving revision 1.112
diff -c -r1.112 varchar.c
*** src/backend/utils/adt/varchar.c     29 Jul 2005 12:59:15 -0000      1.112
--- src/backend/utils/adt/varchar.c     2 Oct 2005 23:50:34 -0000
***************
*** 25,30 ****
--- 25,31 ----
  
  #include "mb/pg_wchar.h"
  
+ #include "nodes/execnodes.h"
  
  /*
   * CHAR() and VARCHAR() types are part of the ANSI SQL standard. CHAR()
***************
*** 805,807 ****
--- 806,896 ----
  
        return result;
  }
+ 
+ /*
+  * Temp. aux. func for xmlagg function
+  *
+  */
+  
+ 
+ typedef struct 
+ {
+   int32 size;  // varlena requirment
+   int max;
+   int offset;
+   bool isNull;
+   char data[1];
+ } data;
+ 
+ 
+ static data *
+ makeData(AggState *aggstate, int sz)
+ {
+       data *d = (data *) MemoryContextAlloc(aggstate->aggcontext, 
sz+sizeof(data));
+       d->size = sz+sizeof(data);
+       d->max = sz;
+       d->offset = 0;
+       d->data[0] = '\0';
+       d->isNull = true;
+       return d;
+ }
+ 
+ static data *
+ reallocData(AggState *aggstate, data *d, int sz)
+ {
+       data *nd = makeData(aggstate, sz);
+       memcpy(nd->data, d->data, d->offset);
+       nd->offset = d->offset;
+       nd->isNull = d->isNull; 
+       return nd;
+ }
+ 
+ 
+ Datum
+ text_xmlagg_accum(PG_FUNCTION_ARGS)
+ {
+       data *d;
+       if (PG_ARGISNULL(0))
+               d = NULL;
+       else
+               d = (data *) PG_GETARG_POINTER(0);
+       if (!d)
+               d = makeData((AggState *) fcinfo->context, 1000);
+ 
+       if (!PG_ARGISNULL(1))
+       {
+               text *str = PG_GETARG_TEXT_P(1);
+               d->isNull = false;
+               int len = VARSIZE(str) - VARHDRSZ;
+               while (d->max < d->offset + len)
+               {
+                       int nmax = d->max *2;
+                       data *dn = reallocData((AggState *) fcinfo->context, d, 
nmax);
+                       d = dn;       
+               }
+               memcpy(&d->data[d->offset], VARDATA(str), len);
+               d->offset += len;
+       }
+ 
+   PG_RETURN_POINTER(d);
+ }
+                   
+ Datum
+ text_xmlagg(PG_FUNCTION_ARGS)
+ {
+       data *d;
+ 
+       if (PG_ARGISNULL(0))
+               elog(ERROR, "internal error");
+               
+       d = (data *) PG_GETARG_POINTER(0);
+       if (d->isNull)
+               PG_RETURN_NULL();
+       else
+       {
+               text *str = palloc(d->offset+VARHDRSZ);
+               VARATT_SIZEP(str) = d->offset+VARHDRSZ;
+               memcpy(VARDATA(str), d->data, d->offset);
+               PG_RETURN_TEXT_P(str); 
+       }   
+ }
Index: src/include/catalog/pg_aggregate.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_aggregate.h,v
retrieving revision 1.51
diff -c -r1.51 pg_aggregate.h
*** src/include/catalog/pg_aggregate.h  14 Apr 2005 01:38:20 -0000      1.51
--- src/include/catalog/pg_aggregate.h  2 Oct 2005 23:50:35 -0000
***************
*** 175,180 ****
--- 175,183 ----
  DATA(insert ( 2242 bitand               -                                     
0       1560    _null_ ));
  DATA(insert ( 2243 bitor                -                                     
0       1560    _null_ ));
  
+ /* xmlagg */
+ DATA(insert ( 1079    text_xmlagg_accum       text_xmlagg     0       25      
_null_ ));
+ 
  /*
   * prototypes for functions in pg_aggregate.c
   */
Index: src/include/catalog/pg_proc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_proc.h,v
retrieving revision 1.385
diff -c -r1.385 pg_proc.h
*** src/include/catalog/pg_proc.h       16 Sep 2005 05:35:40 -0000      1.385
--- src/include/catalog/pg_proc.h       2 Oct 2005 23:50:42 -0000
***************
*** 807,813 ****
  DESCR("convert name to char(n)");
  DATA(insert OID =  409 (  name                           PGNSP PGUID 12 f f t 
f i 1 19 "1042" _null_ _null_ _null_    bpchar_name - _null_ ));
  DESCR("convert char(n) to name");
- 
  DATA(insert OID = 440 (  hashgettuple    PGNSP PGUID 12 f f t f v 2 16 "2281 
2281" _null_ _null_ _null_  hashgettuple - _null_ ));
  DESCR("hash(internal)");
  DATA(insert OID = 637 (  hashgetmulti    PGNSP PGUID 12 f f t f v 4 16 "2281 
2281 2281 2281" _null_ _null_ _null_  hashgetmulti - _null_ ));
--- 807,812 ----
***************
*** 2710,2715 ****
--- 2709,2719 ----
  DESCR("AVG(int4) transition function");
  DATA(insert OID = 1964 (  int8_avg               PGNSP PGUID 12 f f t f i 1 
1700 "1016" _null_ _null_ _null_  int8_avg - _null_ ));
  DESCR("AVG(int) aggregate final function");
+ DATA(insert OID =  1136 ( text_xmlagg_accum      PGNSP PGUID 12 f f f f i 2 
25 "25 25" _null_ _null_ _null_  text_xmlagg_accum - _null_ ));           
+ DESCR("trans fce for fast string");
+ DATA(insert OID =  1137 ( text_xmlagg         PGNSP PGUID 12 f f t f i 1 25 
"25" _null_ _null_ _null_  text_xmlagg - _null_ ));
+ DESCR("final fce for fast string");
+ 
  
  /* To ASCII conversion */
  DATA(insert OID = 1845 ( to_ascii     PGNSP PGUID 12 f f t f i 1      25 "25" 
_null_ _null_ _null_    to_ascii_default - _null_ ));
***************
*** 3135,3140 ****
--- 3139,3146 ----
  DATA(insert OID = 2158 (  stddev                      PGNSP PGUID 12 t f f f 
i 1 701 "701" _null_ _null_ _null_  aggregate_dummy - _null_ ));
  DATA(insert OID = 2159 (  stddev                      PGNSP PGUID 12 t f f f 
i 1 1700 "1700" _null_ _null_ _null_     aggregate_dummy - _null_ ));
  
+ DATA(insert OID = 1079 (  xmlagg                      PGNSP PGUID 12 t f f f 
i 1 25 "25" _null_ _null_ _null_ aggregate_dummy - _null_ ));
+ 
  DATA(insert OID = 2160 ( text_pattern_lt       PGNSP PGUID 12 f f t f i 2 16 
"25 25" _null_ _null_ _null_ text_pattern_lt - _null_ ));
  DATA(insert OID = 2161 ( text_pattern_le       PGNSP PGUID 12 f f t f i 2 16 
"25 25" _null_ _null_ _null_ text_pattern_le - _null_ ));
  DATA(insert OID = 2162 ( text_pattern_eq       PGNSP PGUID 12 f f t f i 2 16 
"25 25" _null_ _null_ _null_ text_pattern_eq - _null_ ));
Index: src/include/nodes/execnodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/execnodes.h,v
retrieving revision 1.138
diff -c -r1.138 execnodes.h
*** src/include/nodes/execnodes.h       25 Sep 2005 19:37:35 -0000      1.138
--- src/include/nodes/execnodes.h       2 Oct 2005 23:50:43 -0000
***************
*** 686,691 ****
--- 686,710 ----
  } MinMaxExprState;
  
  /* ----------------
+  *            MinMaxExprState node
+  * ----------------
+  */
+ typedef struct XmlExprState
+ {
+       ExprState       xprstate;
+       XmlExprOp       op;
+       List            *nargs;                 /* the named arguments */
+       List            *args;                  /* the arguments, only last 
should be non xml */
+       List       *xml_args;                   /* xml arguments, result is 
always cstring */
+       Oid        *nargs_tcache;
+       char       **nargs_ncache;
+       Oid        arg_typeId;
+       XmlParams  *params;
+       int     level;                          /* info about tabs now, shared 
tag's table in future */
+ } XmlExprState;
+ 
+ 
+ /* ----------------
   *            CoerceToDomainState node
   * ----------------
   */
Index: src/include/nodes/nodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/nodes.h,v
retrieving revision 1.175
diff -c -r1.175 nodes.h
*** src/include/nodes/nodes.h   1 Aug 2005 20:31:15 -0000       1.175
--- src/include/nodes/nodes.h   2 Oct 2005 23:50:44 -0000
***************
*** 137,142 ****
--- 137,144 ----
        T_RangeTblRef,
        T_JoinExpr,
        T_FromExpr,
+       T_XmlExpr,
+       T_XmlParams,
  
        /*
         * TAGS FOR EXPRESSION STATE NODES (execnodes.h)
***************
*** 163,169 ****
        T_MinMaxExprState,
        T_CoerceToDomainState,
        T_DomainConstraintState,
! 
        /*
         * TAGS FOR PLANNER NODES (relation.h)
         */
--- 165,172 ----
        T_MinMaxExprState,
        T_CoerceToDomainState,
        T_DomainConstraintState,
!       T_XmlExprState,
!       
        /*
         * TAGS FOR PLANNER NODES (relation.h)
         */
Index: src/include/nodes/primnodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/primnodes.h,v
retrieving revision 1.108
diff -c -r1.108 primnodes.h
*** src/include/nodes/primnodes.h       26 Jun 2005 22:05:41 -0000      1.108
--- src/include/nodes/primnodes.h       2 Oct 2005 23:50:44 -0000
***************
*** 675,680 ****
--- 675,731 ----
  } MinMaxExpr;
  
  /*
+  * XmlExpr - holder SQL/XML functions xmlroot, xmlforest, xmlelement, xmlpi, 
+  * xmlcomment, xmlconcat
+  */
+ typedef enum XmlExprOp
+ {
+       IS_XMLUNKNOWN = 0,
+       IS_XMLAGG,
+       IS_XMLROOT,
+       IS_XMLELEMENT,
+       IS_XMLFOREST,
+       IS_XMLPI,
+       IS_XMLCOMMENT,
+       IS_XMLCONCAT,
+       IS_XMLSERIALIZE
+ } XmlExprOp;
+ 
+ typedef enum XmlParamOp
+ {
+     IS_XMLENCODING,
+     IS_XMLVERSION,
+     IS_XMLNAME,
+     IS_XMLSTANDALONE
+ } XmlParamOp;
+ 
+ typedef struct XmlParam
+ {
+     XmlParamOp op;
+     char *value;
+ } XmlParam;
+ 
+ typedef struct XmlParams
+ {
+     NodeTag type;
+     char *encoding;
+     char *version;
+     char *name;
+     char *standalone;
+ } XmlParams;
+ 
+ typedef struct XmlExpr
+ {
+       Expr            xpr;
+       XmlExprOp       op;                             /* function to execute 
*/
+       List    *xml_args;                              /* xml arguments */
+       List    *nargs;                                 /* named arguments */
+       List    *args;
+       XmlParams *params;                              /* non xml argument */
+       int     level;
+ } XmlExpr;
+ 
+ /*
   * NullIfExpr - a NULLIF expression
   *
   * Like DistinctExpr, this is represented the same as an OpExpr referencing
***************
*** 940,943 ****
--- 991,995 ----
        Node       *quals;                      /* qualifiers on join, if any */
  } FromExpr;
  
+ 
  #endif   /* PRIMNODES_H */
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Reply via email to