I have received an update XML syntax patch from Nikolay (summer of code)
based on David Fetter's patch from 2005.

Comments?  It would be nice to have for 8.2.

-- 
  Bruce Momjian   [EMAIL PROTECTED]
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +
Index: src/include/utils/builtins.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/builtins.h,v
retrieving revision 1.281
diff -u -r1.281 builtins.h
--- src/include/utils/builtins.h	28 Jul 2006 18:33:04 -0000	1.281
+++ src/include/utils/builtins.h	4 Sep 2006 23:33:10 -0000
@@ -905,4 +905,9 @@
 /* utils/mmgr/portalmem.c */
 extern Datum pg_cursor(PG_FUNCTION_ARGS);
 
+/* SQL/XML auxilliary functions (now as a part of varchar.c) */
+extern Datum text_xmlagg_accum(PG_FUNCTION_ARGS);
+extern Datum text_xmlagg(PG_FUNCTION_ARGS);
+
+
 #endif   /* BUILTINS_H */
Index: src/include/catalog/pg_proc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_proc.h,v
retrieving revision 1.422
diff -u -r1.422 pg_proc.h
--- src/include/catalog/pg_proc.h	19 Aug 2006 01:36:33 -0000	1.422
+++ src/include/catalog/pg_proc.h	4 Sep 2006 23:33:02 -0000
@@ -2756,6 +2756,12 @@
 DESCR("COVAR_SAMP(double, double) aggregate final function");
 DATA(insert OID = 2817 (  float8_corr				PGNSP PGUID 12 f f t f i 1 701 "1022" _null_ _null_ _null_ float8_corr - _null_ ));
 DESCR("CORR(double, double) aggregate final function");
+DATA(insert OID = 5011 (  text_xmlagg_accum			PGNSP PGUID 12 f f f f i 2 25 "25 25" _null_ _null_ _null_  text_xmlagg_accum - _null_ ));
+DESCR("XMLAGG accumulate function");
+DATA(insert OID = 5012 (  text_xmlagg				PGNSP PGUID 12 f f t f i 1 25 "25" _null_ _null_ _null_  text_xmlagg - _null_ ));
+DESCR("XMLAGG aggregate final function");
+DATA(insert OID = 5010 (  xmlagg					PGNSP PGUID 12 t f f f i 1 25 "25" _null_ _null_ _null_	aggregate_dummy - _null_ ));
+DESCR("XMLAGG");
 
 /* 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_ ));
Index: src/include/catalog/pg_aggregate.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_aggregate.h,v
retrieving revision 1.57
diff -u -r1.57 pg_aggregate.h
--- src/include/catalog/pg_aggregate.h	28 Jul 2006 18:33:04 -0000	1.57
+++ src/include/catalog/pg_aggregate.h	4 Sep 2006 23:32:43 -0000
@@ -221,6 +221,9 @@
 DATA(insert ( 2242 bitand		  -					0	1560	_null_ ));
 DATA(insert ( 2243 bitor		  -					0	1560	_null_ ));
 
+/* xml */
+DATA(insert ( 5010	text_xmlagg_accum	text_xmlagg	0	25	_null_ ));
+
 /*
  * prototypes for functions in pg_aggregate.c
  */
Index: src/include/nodes/nodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/nodes.h,v
retrieving revision 1.187
diff -u -r1.187 nodes.h
--- src/include/nodes/nodes.h	2 Aug 2006 01:59:47 -0000	1.187
+++ src/include/nodes/nodes.h	4 Sep 2006 23:33:05 -0000
@@ -140,6 +140,8 @@
 	T_RangeTblRef,
 	T_JoinExpr,
 	T_FromExpr,
+	T_XmlExpr,
+	T_XmlParams,
 
 	/*
 	 * TAGS FOR EXPRESSION STATE NODES (execnodes.h)
@@ -167,6 +169,7 @@
 	T_MinMaxExprState,
 	T_CoerceToDomainState,
 	T_DomainConstraintState,
+	T_XmlExprState,
 
 	/*
 	 * TAGS FOR PLANNER NODES (relation.h)
Index: src/include/nodes/execnodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/execnodes.h,v
retrieving revision 1.160
diff -u -r1.160 execnodes.h
--- src/include/nodes/execnodes.h	25 Aug 2006 04:06:56 -0000	1.160
+++ src/include/nodes/execnodes.h	4 Sep 2006 23:33:05 -0000
@@ -706,6 +706,24 @@
 } MinMaxExprState;
 
 /* ----------------
+ *		XmlExprState 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/primnodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/primnodes.h,v
retrieving revision 1.115
diff -u -r1.115 primnodes.h
--- src/include/nodes/primnodes.h	27 Jul 2006 19:52:07 -0000	1.115
+++ src/include/nodes/primnodes.h	4 Sep 2006 23:33:07 -0000
@@ -706,6 +706,57 @@
 } 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
Index: src/backend/optimizer/util/clauses.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v
retrieving revision 1.219
diff -u -r1.219 clauses.c
--- src/backend/optimizer/util/clauses.c	12 Aug 2006 20:05:55 -0000	1.219
+++ src/backend/optimizer/util/clauses.c	4 Sep 2006 23:32:11 -0000
@@ -557,6 +557,8 @@
 		return false;
 	if (IsA(node, MinMaxExpr))
 		return false;
+	if (IsA(node, XmlExpr))
+		return false;
 	if (IsA(node, NullIfExpr))
 		return false;
 
@@ -870,6 +872,8 @@
 		return true;
 	if (IsA(node, MinMaxExpr))
 		return true;
+	if (IsA(node, XmlExpr))
+		return true;
 	if (IsA(node, NullIfExpr))
 		return true;
 	if (IsA(node, NullTest))
@@ -3243,6 +3247,18 @@
 			return walker(((CoalesceExpr *) node)->args, context);
 		case T_MinMaxExpr:
 			return walker(((MinMaxExpr *) 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_NullIfExpr:
 			return walker(((NullIfExpr *) node)->args, context);
 		case T_NullTest:
@@ -3740,6 +3756,18 @@
 				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_NullIfExpr:
 			{
 				NullIfExpr *expr = (NullIfExpr *) node;
Index: src/backend/utils/adt/varchar.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/varchar.c,v
retrieving revision 1.118
diff -u -r1.118 varchar.c
--- src/backend/utils/adt/varchar.c	14 Jul 2006 14:52:24 -0000	1.118
+++ src/backend/utils/adt/varchar.c	4 Sep 2006 23:32:43 -0000
@@ -19,7 +19,7 @@
 #include "libpq/pqformat.h"
 #include "utils/builtins.h"
 #include "mb/pg_wchar.h"
-
+#include "nodes/execnodes.h"
 
 /*
  * CHAR() and VARCHAR() types are part of the ANSI SQL standard. CHAR()
@@ -806,3 +806,95 @@
 
 	return result;
 }
+
+/*
+ * Temp. aux. functions for XMLAGG SQL/XML function.
+ * In the future, this should be adapted for XML type. 
+ *
+ */
+
+/* TODO this (struct and next 2 funcs) should be moved from here */
+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;
+	int 	len;
+	text 	*str;
+	
+	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))
+	{
+		str = PG_GETARG_TEXT_P(1);
+		d->isNull = false;
+		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;
+	text 	*str;
+
+	if (PG_ARGISNULL(0))
+		elog(ERROR, "internal error");
+		
+	d = (data *) PG_GETARG_POINTER(0);
+	if (d->isNull)
+		PG_RETURN_NULL();
+	else
+	{
+		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/backend/utils/adt/ruleutils.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v
retrieving revision 1.232
diff -u -r1.232 ruleutils.c
--- src/backend/utils/adt/ruleutils.c	21 Aug 2006 00:57:25 -0000	1.232
+++ src/backend/utils/adt/ruleutils.c	4 Sep 2006 23:32:42 -0000
@@ -2984,6 +2984,7 @@
 		case T_RowExpr:
 		case T_CoalesceExpr:
 		case T_MinMaxExpr:
+		case T_XmlExpr:
 		case T_NullIfExpr:
 		case T_Aggref:
 		case T_FuncExpr:
@@ -3092,6 +3093,7 @@
 				case T_RowExpr:	/* other separators */
 				case T_CoalesceExpr:	/* own parentheses */
 				case T_MinMaxExpr:		/* own parentheses */
+				case T_XmlExpr:			/* own parentheses */
 				case T_NullIfExpr:		/* other separators */
 				case T_Aggref:	/* own parentheses */
 				case T_CaseExpr:		/* other separators */
@@ -3140,6 +3142,7 @@
 				case T_RowExpr:	/* other separators */
 				case T_CoalesceExpr:	/* own parentheses */
 				case T_MinMaxExpr:		/* own parentheses */
+				case T_XmlExpr:			/* own parentheses */
 				case T_NullIfExpr:		/* other separators */
 				case T_Aggref:	/* own parentheses */
 				case T_CaseExpr:		/* other separators */
@@ -3767,6 +3770,43 @@
 			}
 			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_XMLAGG:
+					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_NullIfExpr:
 			{
 				NullIfExpr *nullifexpr = (NullIfExpr *) node;
Index: src/backend/parser/gram.y
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.565
diff -u -r2.565 gram.y
--- src/backend/parser/gram.y	3 Sep 2006 22:37:05 -0000	2.565
+++ src/backend/parser/gram.y	4 Sep 2006 23:32:27 -0000
@@ -107,6 +107,10 @@
 static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
 static Node *doNegate(Node *n, int location);
 static void doNegateFloat(Value *v);
+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);
 
 %}
 
@@ -144,6 +148,10 @@
 
 	InsertStmt			*istmt;
 	VariableSetStmt		*vsetstmt;
+	
+	XmlExpr				*xmlexpr;
+	XmlParams			*xmlparams;
+	XmlParam			xmlparam;
 }
 
 %type <node>	stmt schema_stmt
@@ -346,6 +354,12 @@
 %type <str>		OptTableSpace OptConsTableSpace OptTableSpaceOwner
 %type <list>	opt_check_option
 
+%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
@@ -399,7 +413,7 @@
 
 	MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
 
-	NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
+	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
 
@@ -418,7 +432,7 @@
 
 	SAVEPOINT SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE
 	SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
-	SHOW SIMILAR SIMPLE SMALLINT SOME STABLE START STATEMENT
+	SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE START STATEMENT
 	STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SUPERUSER_P SYMMETRIC
 	SYSID SYSTEM_P
 
@@ -430,10 +444,13 @@
 	UPDATE USER USING
 
 	VACUUM VALID VALIDATOR VALUES VARCHAR VARYING
-	VERBOSE VIEW VOLATILE
+	VERBOSE VERSION VIEW VOLATILE
 
 	WHEN WHERE WITH WITHOUT WORK WRITE
 
+	XMLAGG XMLATTRIBUTES XMLCOMMENT XMLCONCAT XMLELEMENT XMLFOREST
+	XMLPI XMLROOT XMLSERIALIZE
+
 	YEAR_P
 
 	ZONE
@@ -7889,6 +7906,139 @@
 					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 '(' NAME ColLabel ')'
+				{
+					$$ = makeXmlExpr(IS_XMLPI, $4, NULL, NULL, NULL, NULL);
+				}
+			| XMLPI '(' NAME ColLabel ',' a_expr ')'
+				{
+					$$ = makeXmlExpr(IS_XMLPI, $4, NULL, NULL, list_make1($6), 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;				
+				}
 		;
 
 /*
@@ -8290,6 +8440,20 @@
 					$$->val = (Node *)n;
 					$$->location = @1;
 				}
+			| xmlexpr AS ColLabel
+				{
+					$$ = makeNode(ResTarget);
+					$$->name = $3;
+					$$->indirection = NIL;
+					$$->val = (Node *)$1;
+				}
+			| xmlexpr
+				{
+					$$ = makeNode(ResTarget);
+					$$->name = NULL;
+					$$->indirection = NIL;
+					$$->val = (Node *)$1;
+				}
 		;
 
 
@@ -8661,6 +8825,7 @@
 			| MODE
 			| MONTH_P
 			| MOVE
+			| NAME
 			| NAMES
 			| NEXT
 			| NO
@@ -8721,6 +8886,7 @@
 			| SHOW
 			| SIMPLE
 			| STABLE
+			| STANDALONE
 			| START
 			| STATEMENT
 			| STATISTICS
@@ -8750,6 +8916,7 @@
 			| VALID
 			| VALIDATOR
 			| VARYING
+			| VERSION
 			| VIEW
 			| VOLATILE
 			| WITH
@@ -8809,6 +8976,15 @@
 			| TRIM
 			| VALUES
 			| VARCHAR
+			| XMLAGG
+			| XMLATTRIBUTES
+			| XMLELEMENT
+			| XMLCOMMENT
+			| XMLCONCAT
+			| XMLFOREST
+			| XMLPI
+			| XMLROOT
+			| XMLSERIALIZE
 		;
 
 /* Function identifier --- keywords that can be function names.
@@ -9380,10 +9556,56 @@
 	}
 }
 
+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;
+}
+
 /*
  * Must undefine base_yylex before including scan.c, since we want it
  * to create the function base_yylex not filtered_base_yylex.
  */
 #undef base_yylex
 
-#include "scan.c"
+#include "scan.c"
\ No newline at end of file
Index: src/backend/parser/parse_target.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/parse_target.c,v
retrieving revision 1.148
diff -u -r1.148 parse_target.c
--- src/backend/parser/parse_target.c	14 Aug 2006 23:39:32 -0000	1.148
+++ src/backend/parser/parse_target.c	4 Sep 2006 23:32:34 -0000
@@ -1315,6 +1315,39 @@
 					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/parser/parse_expr.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/parse_expr.c,v
retrieving revision 1.197
diff -u -r1.197 parse_expr.c
--- src/backend/parser/parse_expr.c	12 Aug 2006 20:05:55 -0000	1.197
+++ src/backend/parser/parse_expr.c	4 Sep 2006 23:32:29 -0000
@@ -55,6 +55,8 @@
 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 *transformXmlList(ParseState *pstate, List *list, int level);
 static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b);
 static Node *transformColumnRef(ParseState *pstate, ColumnRef *cref);
 static Node *transformWholeRowRef(ParseState *pstate, char *schemaname,
@@ -71,6 +73,7 @@
 static Expr *make_distinct_op(ParseState *pstate, List *opname,
 				 Node *ltree, Node *rtree, int location);
 
+extern char *FigureColname(Node *e);
 
 /*
  * transformExpr -
@@ -218,6 +221,10 @@
 			result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr);
 			break;
 
+		case T_XmlExpr:
+			result = transformXmlExpr(pstate, (XmlExpr *) expr);
+			break;
+
 		case T_NullTest:
 			{
 				NullTest   *n = (NullTest *) expr;
@@ -1368,6 +1375,98 @@
 }
 
 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 *te;
+		Node *e = (Node *) lfirst(arg);
+		((XmlExpr *)e)->level = level;
+		te = transformExpr(pstate, e);
+		newlist = lappend(newlist, te);
+	}
+	return (Node *) newlist;
+}
+
+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)
+		{
+			FuncCall 	*n;
+		    XmlExpr 	*p = (XmlExpr *) linitial(x->xml_args);
+		    p->level = x->level + 1;
+		    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);
+		}	
+	}
+	 
+	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)
 {
 	const char *clausename;
@@ -1399,10 +1498,7 @@
 	}
 
 	b->arg = (Expr *) transformExpr(pstate, (Node *) b->arg);
-
-	b->arg = (Expr *) coerce_to_boolean(pstate,
-										(Node *) b->arg,
-										clausename);
+	b->arg = (Expr *) coerce_to_boolean(pstate, (Node *) b->arg, clausename);
 
 	return (Node *) b;
 }
@@ -1657,6 +1753,9 @@
 		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/keywords.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/keywords.c,v
retrieving revision 1.176
diff -u -r1.176 keywords.c
--- src/backend/parser/keywords.c	25 Aug 2006 04:06:52 -0000	1.176
+++ src/backend/parser/keywords.c	4 Sep 2006 23:32:28 -0000
@@ -217,6 +217,7 @@
 	{"mode", MODE},
 	{"month", MONTH_P},
 	{"move", MOVE},
+	{"name", NAME},
 	{"names", NAMES},
 	{"national", NATIONAL},
 	{"natural", NATURAL},
@@ -313,6 +314,7 @@
 	{"smallint", SMALLINT},
 	{"some", SOME},
 	{"stable", STABLE},
+	{"standalone", STANDALONE},
 	{"start", START},
 	{"statement", STATEMENT},
 	{"statistics", STATISTICS},
@@ -360,6 +362,7 @@
 	{"varchar", VARCHAR},
 	{"varying", VARYING},
 	{"verbose", VERBOSE},
+	{"version", VERSION},
 	{"view", VIEW},
 	{"volatile", VOLATILE},
 	{"when", WHEN},
@@ -368,6 +371,15 @@
 	{"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/nodes/readfuncs.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/nodes/readfuncs.c,v
retrieving revision 1.195
diff -u -r1.195 readfuncs.c
--- src/backend/nodes/readfuncs.c	12 Aug 2006 02:52:04 -0000	1.195
+++ src/backend/nodes/readfuncs.c	4 Sep 2006 23:32:05 -0000
@@ -707,6 +707,34 @@
 	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
  */
@@ -1007,6 +1035,10 @@
 		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/nodes/outfuncs.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/nodes/outfuncs.c,v
retrieving revision 1.284
diff -u -r1.284 outfuncs.c
--- src/backend/nodes/outfuncs.c	25 Aug 2006 04:06:50 -0000	1.284
+++ src/backend/nodes/outfuncs.c	4 Sep 2006 23:32:02 -0000
@@ -890,6 +890,19 @@
 }
 
 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");
@@ -2008,6 +2021,9 @@
 			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/equalfuncs.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v
retrieving revision 1.284
diff -u -r1.284 equalfuncs.c
--- src/backend/nodes/equalfuncs.c	30 Aug 2006 23:34:21 -0000	1.284
+++ src/backend/nodes/equalfuncs.c	4 Sep 2006 23:32:01 -0000
@@ -454,6 +454,28 @@
 }
 
 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)
 {
 	COMPARE_SCALAR_FIELD(opno);
@@ -1959,6 +1981,12 @@
 		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/copyfuncs.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v
retrieving revision 1.350
diff -u -r1.350 copyfuncs.c
--- src/backend/nodes/copyfuncs.c	30 Aug 2006 23:34:21 -0000	1.350
+++ src/backend/nodes/copyfuncs.c	4 Sep 2006 23:31:57 -0000
@@ -1091,6 +1091,36 @@
 }
 
 /*
+ * _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 *
@@ -2957,6 +2987,12 @@
 		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/executor/execQual.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/executor/execQual.c,v
retrieving revision 1.193
diff -u -r1.193 execQual.c
--- src/backend/executor/execQual.c	27 Jul 2006 19:52:05 -0000	1.193
+++ src/backend/executor/execQual.c	4 Sep 2006 23:31:53 -0000
@@ -52,6 +52,9 @@
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
 #include "utils/typcache.h"
+#include "lib/stringinfo.h"
+
+#include <string.h>
 
 
 /* static function decls */
@@ -119,6 +122,8 @@
 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);
@@ -2613,6 +2618,230 @@
 }
 
 /* ----------------------------------------------------------------
+ *		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:
+			{
+				int state = 0, i = 0;
+				appendStringInfo(&buf, "<%s", getXmlParam(xmlExpr->params, IS_XMLNAME));
+				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++;
+				}
+				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:
+			{
+				bool 		isnull;
+				char 		*outstr;
+				ExprState 	*arg = linitial(xmlExpr->args);
+				Datum 		value = ExecEvalExpr(arg, econtext, &isnull, NULL);
+				/* In case of NULL input, return NULL, according SQL/XML standard */
+				if (isnull)
+					*isNull = true;
+				else
+				{
+					outstr = DatumGetCString(OidFunctionCall1(xmlExpr->arg_typeId, value));
+					appendStringInfo(&buf, "<!--%s-->", outstr);
+					pfree(outstr);
+				}
+			}
+			break;
+		case IS_XMLPI:
+			{
+				bool 		isnull;
+				char		*piname = getXmlParam(xmlExpr->params, IS_XMLNAME);
+				int32		pinamelen = strlen(piname);
+				if (pinamelen > 2
+					&& (piname[0] == 'x' || piname[0] == 'X')
+					&& (piname[1] == 'm' || piname[1] == 'M')
+					&& (piname[2] == 'l' || piname[2] == 'L'))
+				{
+					ereport(ERROR, (
+						errmsg("invalid name of XML processing instruction"),
+						errdetail("XML processing instruction name cannot start with 'xml' ('%s' provided)", piname)));
+				}
+				appendStringInfo(&buf, "<?%s", piname);
+				if (xmlExpr->args != NULL)
+				{
+					char 		*outstr;
+					ExprState 	*arg = linitial(xmlExpr->args);
+					Datum 		value = ExecEvalExpr(arg, econtext, &isnull, NULL);
+					/* In case of NULL input, return NULL, according SQL/XML standard */
+					if (isnull)
+						*isNull = true;
+					else
+					{
+						outstr = DatumGetCString(OidFunctionCall1(xmlExpr->arg_typeId, value));
+						appendStringInfo(&buf, " %s", outstr);
+						pfree(outstr);
+					}
+				}
+				appendStringInfo(&buf, "?>");
+			}
+			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
  *
  * Note that this is *always* derived from the equals operator,
@@ -3594,6 +3823,77 @@
 				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 = (Oid *) 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);
+						TargetEntry	*tle;
+						outlist = lappend(outlist, estate);					
+						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;
+					ExprState 	*estate;
+					Expr 		*e = (Expr *) lfirst(arg);
+					getTypeOutputInfo(exprType((Node *)e), &typid, &tpisvarlena);
+					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: doc/src/sgml/func.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/func.sgml,v
retrieving revision 1.333
diff -u -r1.333 func.sgml
--- doc/src/sgml/func.sgml	4 Sep 2006 21:47:25 -0000	1.333
+++ doc/src/sgml/func.sgml	4 Sep 2006 23:31:46 -0000
@@ -10530,8 +10530,129 @@
    </para>
 
   </sect1>
-</chapter>
+  <sect1 id="functions-sqlxml">
+   <title>SQL/XML publishing 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><optional>, ...</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
 Local variables:
 mode:sgml
@@ -10547,4 +10668,4 @@
 sgml-local-catalogs:("/usr/lib/sgml/catalog")
 sgml-local-ecat-files:nil
 End:
--->
+-->
\ No newline at end of file
---------------------------(end of broadcast)---------------------------
TIP 1: if posting/reading through Usenet, please send an appropriate
       subscribe-nomail command to [EMAIL PROTECTED] so that your
       message can get through to the mailing list cleanly

Reply via email to