Thread: SQL/XML publishing function experimental patch II

SQL/XML publishing function experimental patch II

From
"Pavel Stehule"
Date:
Hello

base type changed to text, better registration xmlagg function

Regards
Pavel Stehule

_________________________________________________________________
Emotikony a pozadi programu MSN Messenger ozivi vasi konverzaci.
http://messenger.msn.cz/

Attachment

Re: SQL/XML publishing function experimental patch II

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

Interesting.  The SGML docs appear to be machine-generated stubs.
Could you point to a reference for them so they can be filled in?

Cheers,
D
--
David Fetter david@fetter.org http://fetter.org/
phone: +1 510 893 6100   mobile: +1 415 235 3778

Remember to vote!

Re: SQL/XML publishing function experimental patch II

From
David Fetter
Date:
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 david@fetter.org http://fetter.org/
phone: +1 510 893 6100   mobile: +1 415 235 3778

Remember to vote!

Attachment

Re: SQL/XML publishing function experimental patch II

From
Bruce Momjian
Date:
This has been saved for the 8.2 release:

    http://momjian.postgresql.org/cgi-bin/pgpatches_hold

---------------------------------------------------------------------------

David Fetter wrote:
> 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 david@fetter.org http://fetter.org/
> phone: +1 510 893 6100   mobile: +1 415 235 3778
>
> Remember to vote!

[ Attachment, skipping... ]

>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: explain analyze is your friend

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

Re: SQL/XML publishing function experimental patch II

From
Bruce Momjian
Date:
Do we want this XML patch in the backend?  It needs syntax support so I
don't see how it could be done in /contrib.  Attached.

---------------------------------------------------------------------------

David Fetter wrote:
> 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 david@fetter.org http://fetter.org/
> phone: +1 510 893 6100   mobile: +1 415 235 3778
>
> Remember to vote!

[ Attachment, skipping... ]

>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: explain analyze is your friend

--
  Bruce Momjian   http://candle.pha.pa.us
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +
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 */

Re: SQL/XML publishing function experimental patch II

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> Do we want this XML patch in the backend?  It needs syntax support so I
> don't see how it could be done in /contrib.  Attached.

I think this could easily be done as an external module if it didn't
insist on random additions to the function-call syntax.  AFAICS there
isn't anything there that couldn't be done without that.

            regards, tom lane

Re: SQL/XML publishing function experimental patch II

From
Peter Eisentraut
Date:
Tom Lane wrote:
> I think this could easily be done as an external module if it didn't
> insist on random additions to the function-call syntax.  AFAICS there
> isn't anything there that couldn't be done without that.

This is part of the SQL standard.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

Re: SQL/XML publishing function experimental patch II

From
Bruce Momjian
Date:
Peter Eisentraut wrote:
> Tom Lane wrote:
> > I think this could easily be done as an external module if it didn't
> > insist on random additions to the function-call syntax.  AFAICS there
> > isn't anything there that couldn't be done without that.
>
> This is part of the SQL standard.

Ah, I suspected that might be true.

--
  Bruce Momjian   http://candle.pha.pa.us
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: SQL/XML publishing function experimental patch II

From
Tom Lane
Date:
Peter Eisentraut <peter_e@gmx.net> writes:
> This is part of the SQL standard.

[ shrug ] There is a *boatload* of new stuff in SQL2003, most of which
we probably won't ever implement.  The foundation alone has enough new
cruft to keep us busy for years ... never mind stuff that shows up only
in Part 14.

Basically, SQL2003 is way too big for the argument "it's in the spec"
to be an automatic trump card for putting features into core PG.
We have to think about distribution size and maintainability versus
the usefulness of specific features.

If there were a serious amount of demand for the SQL2003 XML features
then I wouldn't be averse to putting them in, but right now it looks
like bloat with little redeeming social value.  Who other than the
submitter has asked for this?  I don't even see "XML" listed in TODO.

            regards, tom lane

Re: SQL/XML publishing function experimental patch II

From
Bruce Momjian
Date:
Tom Lane wrote:
> Peter Eisentraut <peter_e@gmx.net> writes:
> > This is part of the SQL standard.
>
> [ shrug ] There is a *boatload* of new stuff in SQL2003, most of which
> we probably won't ever implement.  The foundation alone has enough new
> cruft to keep us busy for years ... never mind stuff that shows up only
> in Part 14.
>
> Basically, SQL2003 is way too big for the argument "it's in the spec"
> to be an automatic trump card for putting features into core PG.
> We have to think about distribution size and maintainability versus
> the usefulness of specific features.
>
> If there were a serious amount of demand for the SQL2003 XML features
> then I wouldn't be averse to putting them in, but right now it looks
> like bloat with little redeeming social value.  Who other than the
> submitter has asked for this?  I don't even see "XML" listed in TODO.

Well, we have been pushing XML out of the database into side projects,
which I think is the way to go until we have an XML-standard export
format.  With this one, I don't see how we can do it externally and meet
the spec.  I would like to see an outline of what XML things we support
and what we don't.  Is this XML patch a major missing thing?  No idea.

--
  Bruce Momjian   http://candle.pha.pa.us
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: SQL/XML publishing function experimental patch II

From
"Pavel Stehule"
Date:
>
>Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > Do we want this XML patch in the backend?  It needs syntax support so I
> > don't see how it could be done in /contrib.  Attached.
>
>I think this could easily be done as an external module if it didn't
>insist on random additions to the function-call syntax.  AFAICS there
>isn't anything there that couldn't be done without that.
>

No, I am sorry, it's cannot be external module. Or cannot be without losting
functionality and elegance of SQL/XML. It's really depend on parser. People
which generate XML from database used it. But not now, because PostgreSQL
don't support it. But it's the moust faster way for generating XML files,
10x faster then PHP or Perl. Please look again on this patch. I am not sure
about solution without ANSI compatibility.

Regards
Pavel Stehule

_________________________________________________________________
Emotikony a pozadi programu MSN Messenger ozivi vasi konverzaci.
http://messenger.msn.cz/


Re: SQL/XML publishing function experimental patch II

From
"Pavel Stehule"
Date:
>
>Well, we have been pushing XML out of the database into side projects,
>which I think is the way to go until we have an XML-standard export
>format.  With this one, I don't see how we can do it externally and meet
>the spec.  I would like to see an outline of what XML things we support
>and what we don't.  Is this XML patch a major missing thing?  No idea.
>
We don't need export XML. I need XML directly from database. I understand so
this patch add some rows to server, but it's save thousands lines on client
sides. Every AJAX or .NET scripts can use it.

Regards
Pavel Stehule

_________________________________________________________________
Najdete si svou lasku a nove pratele na Match.com. http://www.msn.cz/


Re: SQL/XML publishing function experimental patch II

From
"Pavel Stehule"
Date:
Hello
>
>If there were a serious amount of demand for the SQL2003 XML features
>then I wouldn't be averse to putting them in, but right now it looks
>like bloat with little redeeming social value.  Who other than the
>submitter has asked for this?  I don't even see "XML" listed in TODO.

1. integrating SQL/XML into engine put some possibilities for faster and
eficient generating XML file. Is important for generating large XML files.
XML has recursive sturucture and normal (classic functions) interface isn't
eficient, because it's need more XML->text conversions. Inside parser I know
if I inside recursion or outside.

2. Some people use my patch. Without my patch there will be more request for
it.

Best regards
Pavel Stehule

_________________________________________________________________
Chcete sdilet sve obrazky a hudbu s prateli? http://messenger.msn.cz/


Re: SQL/XML publishing function experimental patch II

From
Bruce Momjian
Date:
Pavel Stehule wrote:
> Hello
> >
> >If there were a serious amount of demand for the SQL2003 XML features
> >then I wouldn't be averse to putting them in, but right now it looks
> >like bloat with little redeeming social value.  Who other than the
> >submitter has asked for this?  I don't even see "XML" listed in TODO.
>
> 1. integrating SQL/XML into engine put some possibilities for faster and
> eficient generating XML file. Is important for generating large XML files.
> XML has recursive sturucture and normal (classic functions) interface isn't
> eficient, because it's need more XML->text conversions. Inside parser I know
> if I inside recursion or outside.
>
> 2. Some people use my patch. Without my patch there will be more request for
> it.

OK, got it.  One thing I would like is a summary of what we support
directly, in /contrib, and externally.  I would like something that can
be eventually put in our documentation, because right now, people say,
"I need XML", and they are not clear about exactly what they need.
Things like:

    storing xml
    searching xml
    exporting xml
    building xml structures
    etc.

--
  Bruce Momjian   http://candle.pha.pa.us
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: SQL/XML publishing function experimental patch II

From
Peter Eisentraut
Date:
Tom Lane wrote:
> If there were a serious amount of demand for the SQL2003 XML features
> then I wouldn't be averse to putting them in, but right now it looks
> like bloat with little redeeming social value.  Who other than the
> submitter has asked for this?  I don't even see "XML" listed in TODO.

There have been inquiries about some kind of XML support every few weeks
for years now.  Clearly, we need to sort out what that really means.
I'm preparing a session about that for the Toronto summit.

There is now a Summer of Code project for creating an XML data type,
which should be integrated with this work and the xpath stuff in
contrib.  Plus, there were a few rejected projects about creating
special index support for XML.

Whether or not this part is really useful I can't judge, but it's part
of an overall system.

--
Peter Eisentraut
http://developer.postgresql.org/~petere/

Re: SQL/XML publishing function experimental patch II

From
Tom Lane
Date:
Peter Eisentraut <peter_e@gmx.net> writes:
> There have been inquiries about some kind of XML support every few weeks
> for years now.  Clearly, we need to sort out what that really means.

Agreed.  We need a road map of some sort.

> I'm preparing a session about that for the Toronto summit.

Looking forward to it...

            regards, tom lane

Re: SQL/XML publishing function experimental patch II

From
"Nikolay Samokhvalov"
Date:
I'll prepare some classification of differend kinds of XML support,
including a brief overview for oracle, sql server and db2 (I'm a
person who works on that SoC project)

As for Pavel's patch, I think it's pretty complete piece of several
SQL/XML functions and could be usefull for people (e.g for me).

But it isn't fulll 'XML support' yet. On the road to XML type I see
more grammar hacks (if standard compliance should be established) -
for example, one of possible xml-column declarations is '...col1
XML(SEQUENCE (UNTYPED))...', what breaks postgres' syntax for types
descriptors, if I'm not mistaken..

Yes, standard is bloated and there is no dbms that supports part 14
entirely (e.g., oracle doesn't accept xquery sequnces for xml type, ms
calls its type 'xmltype' and doesn't support sql/xml functions), but
it contains some collection of experience. Many people want to store
xml and to work with it - so some work should take place. Another
point: no open-source dbms has good xml support, so... Anyway, it
would be attractive feature (speaking about marketing - look at the
db2 v.9 'viper' description: xml, xml, xml...)


On 6/15/06, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Peter Eisentraut <peter_e@gmx.net> writes:
> > There have been inquiries about some kind of XML support every few weeks
> > for years now.  Clearly, we need to sort out what that really means.
>
> Agreed.  We need a road map of some sort.
>
> > I'm preparing a session about that for the Toronto summit.
>
> Looking forward to it...
>
>             regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: don't forget to increase your free space map settings
>


--
Best regards,
Nikolay

Re: SQL/XML publishing function experimental patch

From
Bruce Momjian
Date:
I am still waiting for some documentation on what XML support we have,
and what we need.  We can't decide on this patch until we have that.

---------------------------------------------------------------------------

Nikolay Samokhvalov wrote:
> I'll prepare some classification of differend kinds of XML support,
> including a brief overview for oracle, sql server and db2 (I'm a
> person who works on that SoC project)
>
> As for Pavel's patch, I think it's pretty complete piece of several
> SQL/XML functions and could be usefull for people (e.g for me).
>
> But it isn't fulll 'XML support' yet. On the road to XML type I see
> more grammar hacks (if standard compliance should be established) -
> for example, one of possible xml-column declarations is '...col1
> XML(SEQUENCE (UNTYPED))...', what breaks postgres' syntax for types
> descriptors, if I'm not mistaken..
>
> Yes, standard is bloated and there is no dbms that supports part 14
> entirely (e.g., oracle doesn't accept xquery sequnces for xml type, ms
> calls its type 'xmltype' and doesn't support sql/xml functions), but
> it contains some collection of experience. Many people want to store
> xml and to work with it - so some work should take place. Another
> point: no open-source dbms has good xml support, so... Anyway, it
> would be attractive feature (speaking about marketing - look at the
> db2 v.9 'viper' description: xml, xml, xml...)
>
>
> On 6/15/06, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> > Peter Eisentraut <peter_e@gmx.net> writes:
> > > There have been inquiries about some kind of XML support every few weeks
> > > for years now.  Clearly, we need to sort out what that really means.
> >
> > Agreed.  We need a road map of some sort.
> >
> > > I'm preparing a session about that for the Toronto summit.
> >
> > Looking forward to it...
> >
> >             regards, tom lane
> >
> > ---------------------------(end of broadcast)---------------------------
> > TIP 5: don't forget to increase your free space map settings
> >
>
>
> --
> Best regards,
> Nikolay
>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: explain analyze is your friend

--
  Bruce Momjian   bruce@momjian.us
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: SQL/XML publishing function experimental patch II

From
"Nikolay Samokhvalov"
Date:
On 8/22/06, Bruce Momjian <bruce@momjian.us> wrote:
>
> I am still waiting for some documentation on what XML support we have,
> and what we need.  We can't decide on this patch until we have that.
>

Here is my thoughts:
http://nikolay.samokhvalov.com/2006/08/23/xml-and-relational/
(maybe too much words - sorry for it - but classification is very
simple and then I give some simple but important examples; if you them
too boring, read the two comments and the end).

As for that patch itself, I can say two things:
  1. It's really useful but can be considered only as the first step
to XML type support; I personally would be very happy if it will be
included in 8.2 not by default, but with "--with-xml" configure option
(the patch changes the grammar... is it possible to provide the user
with capabilities to define during configuration process what parts of
gram.y will be turned on?)
 2. It has some problems such as following:
    a) "SELECT XMLELEMENT(NAME "A<!--111", 222);" produces invalid XML
(the substring "--" cannot be used in element names, and even as text
value of XML elements). In other words, patch uses ColCabel to define
XML element names, which is not correct (needs additional narrowing);
    b) subqueries inside some constructions are not possible, e.g.:
"SELECT XMLCONCAT((SELECT XMLELEMENT(NAME aaa, 111)), XMLELEMENT(NAME
bbb, 222));" doesn't work (only straight list of xmlexpr can be
accepted). Another simple example of this issue is XMLCONCAT of NULLs
(NULL is valid XML value according to SQL/XML:200{3,6});
    c) XMLPI should have "NAME" keyword before the first argument
(similar to XMLELEMENT), according to SQL/XML:2003.

Since I use this patch in my work on SoC's "initial support of XML
type" (I'll describe results and provide the code in the separate
messages later), I've improved some of issues as long as typos - such
as "<-- ... -->" instead of "<!-- ... -->" in XMLCOMMENT definition,
code style cleanup, etc. If you decide to include Pavel's patch to
8.2, I'll be glad to create the slightly improved version of his
patch.

I plan to continue discussing the theme of XML-enabled databases and
discuss abilities that Postgres has in this area.

Hope, this will help. Please, if you see that I am wrong somewhere -
let me know / let's discuss it.

--
Best regards,
Nikolay