diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index e1fb7d42493469ee325ad205b3a2822f718b9e29..6b72e80e569905de6a8d455989334695c55bc9b3 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.200 2007/05/08 17:02:59 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.201 2007/05/21 17:10:28 petere Exp $ -->
 
  <chapter id="datatype">
   <title id="datatype-title">Data Types</title>
@@ -3213,7 +3213,7 @@ SELECT * FROM test;
   <sect1 id="datatype-uuid">
    <title><acronym>UUID</acronym> Type</title>
 
-   <indexterm zone="datatype-xml">
+   <indexterm zone="datatype-uuid">
     <primary>UUID</primary>
    </indexterm>
 
@@ -3289,6 +3289,8 @@ a0eebc999c0b4ef8bb6d6bb9bd380a11
     value is a full document or only a content fragment.
    </para>
 
+   <sect2>
+    <title>Creating XML Values</title>
    <para>
     To produce a value of type <type>xml</type> from character data,
     use the function
@@ -3299,7 +3301,7 @@ XMLPARSE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable>)
     Examples:
 <programlisting><![CDATA[
 XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter><book>')
-XMLPARSE (CONTENT 'abc<foo>bar</bar><bar>foo</foo>')
+XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>')
 ]]></programlisting>
     While this is the only way to convert character strings into XML
     values according to the SQL standard, the PostgreSQL-specific
@@ -3351,7 +3353,10 @@ SET xmloption TO { DOCUMENT | CONTENT };
     The default is <literal>CONTENT</literal>, so all forms of XML
     data are allowed.
    </para>
+   </sect2>
 
+   <sect2>
+    <title>Encoding Handling</title>
    <para>
     Care must be taken when dealing with multiple character encodings
     on the client, server, and in the XML data passed through them.
@@ -3398,6 +3403,41 @@ SET xmloption TO { DOCUMENT | CONTENT };
     processed in UTF-8, computations will be most efficient if the
     server encoding is also UTF-8.
    </para>
+   </sect2>
+
+   <sect2>
+   <title>Accessing XML Values</title>
+
+   <para>
+    The <type>xml</type> data type is unusual in that it does not
+    provide any comparison operators.  This is because there is no
+    well-defined and universally useful comparison algorithm for XML
+    data.  One consequence of this is that you cannot retrieve rows by
+    comparing an <type>xml</type> column against a search value.  XML
+    values should therefore typically be accompanied by a separate key
+    field such as an ID.  An alternative solution for comparing XML
+    values is to convert them to character strings first, but note
+    that character string comparison has little to do with a useful
+    XML comparison method.
+   </para>
+
+   <para>
+    Since there are no comparison operators for the <type>xml</type>
+    data type, it is not possible to create an index directly on a
+    column of this type.  If speedy searches in XML data are desired,
+    possible workarounds would be casting the expression to a
+    character string type and indexing that, or indexing an XPath
+    expression.  The actual query would of course have to be adjusted
+    to search by the indexed expression.
+   </para>
+
+   <para>
+    The full-text search module Tsearch2 could also be used to speed
+    up full-document searches in XML data.  The necessary
+    preprocessing support is, however, not available in the PostgreSQL
+    distribution in this release.
+   </para>
+   </sect2>
   </sect1>
 
   &array;
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 6c901f9cca6864236ee61c9d4a5d21f62861ec1b..9dd25928eb4737fc65cbb21667019c6fd2c64bdc 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.379 2007/05/07 07:53:26 petere Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.380 2007/05/21 17:10:28 petere Exp $ -->
 
  <chapter id="functions">
   <title>Functions and Operators</title>
@@ -7512,7 +7512,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
    type.  The function-like expressions <function>xmlparse</function>
    and <function>xmlserialize</function> for converting to and from
    type <type>xml</type> are not repeated here.  Use of many of these
-   <type>xml</type> functions requires the installation to have been built
+   functions requires the installation to have been built
    with <command>configure --with-libxml</>.
   </para>
 
@@ -7848,6 +7848,51 @@ SELECT xmlroot(xmlparse(document '<?xml version="1.1"?><content>abc</content>'),
    </sect3>
   </sect2>
 
+  <sect2 id="functions-xml-processing">
+   <title>Processing XML</title>
+
+   <indexterm>
+    <primary>XPath</primary>
+   </indexterm>
+
+   <para>
+    To process values of data type <type>xml</type>, PostgreSQL offers
+    the function <function>xpath</function>, which evaluates XPath 1.0
+    expressions.
+   </para>
+
+<synopsis>
+<function>xpath</function>(<replaceable>xpath</replaceable>, <replaceable>xml</replaceable><optional>, <replaceable>nsarray</replaceable></optional>)
+</synopsis>
+
+   <para>
+    The function <function>xpath</function> evaluates the XPath
+    expression <replaceable>xpath</replaceable> against the XML value
+    <replaceable>xml</replaceable>.  It returns an array of XML values
+    corresponding to the node set produced by the XPath expression.
+   </para>
+
+   <para>
+    The third argument of the function is an array of namespace
+    mappings.  This array should be a two-dimensional array with the
+    length of the second axis being equal to 2 (i.e., it should be an
+    array of arrays, each of which consists of exactly 2 elements).
+    The first element of each array entry is the namespace name, the
+    second the namespace URI.
+   </para>
+
+   <para>
+    Example:
+<screen><![CDATA[
+SELECT xpath('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>', ARRAY[ARRAY['my', 'http://example.com']]);
+ xpath  
+--------
+ {test}
+(1 row)
+]]></screen>
+   </para>
+  </sect2>
+
   <sect2 id="functions-xml-mapping">
    <title>Mapping Tables to XML</title>
 
@@ -8097,75 +8142,6 @@ table2-mapping
 ]]></programlisting>
    </figure>
   </sect2>
-
-  <sect2>
-   <title>Processing XML</title>
-
-   <para>
-    <acronym>XML</> support is not just the existence of an
-    <type>xml</type> data type, but a variety of features supported by
-    a database system.  These capabilities include import/export,
-    indexing, searching, transforming, and <acronym>XML</> to
-    <acronym>SQL</> mapping.  <productname>PostgreSQL</> supports some
-    but not all of these <acronym>XML</> capabilities.  For an
-    overview of <acronym>XML</> use in databases, see <ulink
-    url="http://www.rpbourret.com/xml/XMLAndDatabases.htm"></>.
-   </para>
-
-   <variablelist>
-   <varlistentry>
-    <term>Indexing</term>
-    <listitem>
-
-     <para>
-      <filename>contrib/xml2/</> functions can be used in expression
-      indexes to index specific <acronym>XML</> fields.  To index the
-      full contents of <acronym>XML</> documents, the full-text
-      indexing tool <filename>contrib/tsearch2/</> can be used.  Of
-      course, Tsearch2 indexes have no <acronym>XML</> awareness so
-      additional <filename>contrib/xml2/</> checks should be added to
-      queries.
-     </para>
-    </listitem>
-   </varlistentry>
-
-   <varlistentry>
-    <term>Searching</term>
-    <listitem>
-
-     <para>
-      XPath searches are implemented using <filename>contrib/xml2/</>.
-      It processes <acronym>XML</> text documents and returns results
-      based on the requested query.
-     </para>
-    </listitem>
-   </varlistentry>
-
-   <varlistentry>
-    <term>Transforming</term>
-    <listitem>
-
-     <para>
-      <filename>contrib/xml2/</> supports <acronym>XSLT</> (Extensible
-      Stylesheet Language Transformation).
-     </para>
-    </listitem>
-   </varlistentry>
-
-   <varlistentry>
-    <term>XML to SQL Mapping</term>
-    <listitem>
-
-     <para>
-      This involves converting <acronym>XML</> data to and from
-      relational structures. <productname>PostgreSQL</> has no
-      internal support for such mapping, and relies on external tools
-      to do such conversions.
-     </para>
-    </listitem>
-   </varlistentry>
-   </variablelist>
-  </sect2>
  </sect1>
 
 
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index e873264e3a1fa896b539820cb6f3f459585dd040..f9fd48db66144128c4a862ab2a871260c51b05aa 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.42 2007/04/06 04:21:43 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.43 2007/05/21 17:10:29 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2991,90 +2991,94 @@ xml_xmlnodetoxmltype(xmlNodePtr cur)
 }
 #endif
 
+
 /*
  * Evaluate XPath expression and return array of XML values.
  * As we have no support of XQuery sequences yet, this functions seems
  * to be the most useful one (array of XML functions plays a role of
  * some kind of substritution for XQuery sequences).
-
+ *
  * Workaround here: we parse XML data in different way to allow XPath for
  * fragments (see "XPath for fragment" TODO comment inside).
  */
 Datum
-xmlpath(PG_FUNCTION_ARGS)
+xpath(PG_FUNCTION_ARGS)
 {
 #ifdef USE_LIBXML
-	ArrayBuildState		*astate = NULL;
+	text	   *xpath_expr_text = PG_GETARG_TEXT_P(0);
+	xmltype	   *data = PG_GETARG_XML_P(1);
+	ArrayType  *namespaces = PG_GETARG_ARRAYTYPE_P(2);
+
+	ArrayBuildState	   *astate = NULL;
 	xmlParserCtxtPtr	ctxt = NULL;
 	xmlDocPtr			doc = NULL;
 	xmlXPathContextPtr	xpathctx = NULL;
 	xmlXPathCompExprPtr	xpathcomp = NULL;
 	xmlXPathObjectPtr	xpathobj = NULL;
-	int32				len, xpath_len;
-	xmlChar				*string, *xpath_expr;
-	bool				res_is_null = FALSE;
-	int					i;
-	xmltype				*data;
-	text				*xpath_expr_text;
-	ArrayType			*namespaces;
-	int					*dims, ndims, ns_count = 0, bitmask = 1;
-	char				*ptr;
-	bits8				*bitmap;
-	char				**ns_names = NULL, **ns_uris = NULL;
-	int16				typlen;
-	bool				typbyval;
-	char				typalign;
-	
-	/* the function is not strict, we must check first two args */
-	if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
-		PG_RETURN_NULL();
-	
-	xpath_expr_text = PG_GETARG_TEXT_P(0);
-	data  = PG_GETARG_XML_P(1);
-	
-	/* Namespace mappings passed as text[].
-	 * Assume that 2-dimensional array has been passed, 
-	 * the 1st subarray is array of names, the 2nd -- array of URIs,
-	 * example: ARRAY[ARRAY['myns', 'myns2'], ARRAY['http://example.com', 'http://example2.com']]. 
+	int32		len;
+	int32		xpath_len;
+	xmlChar	   *string;
+	xmlChar	   *xpath_expr;
+	int			i;
+	int			res_nitems;
+	int			ndim;
+	int			ns_count;
+	char	  **ns_names;
+	char	  **ns_uris;
+
+	/*
+	 * Namespace mappings are passed as text[].  If an empty array is
+	 * passed (ndim = 0, "0-dimentional"), then there are no namespace
+	 * mappings.  Else, a 2-dimentional array with length of the
+	 * second axis being equal to 2 should be passed, i.e., every
+	 * subarray contains 2 elements, the first element defining the
+	 * name, the second one the URI.  Example: ARRAY[ARRAY['myns',
+	 * 'http://example.com'], ARRAY['myns2', 'http://example2.com']].
 	 */
-	if (!PG_ARGISNULL(2))
+	ndim = ARR_NDIM(namespaces);
+	if (ndim != 0)
 	{
-		namespaces = PG_GETARG_ARRAYTYPE_P(2);
-		ndims = ARR_NDIM(namespaces);
+		bits8	   *bitmap;
+		int			bitmask;
+		int16		typlen;
+		bool		typbyval;
+		char		typalign;
+		char	   *ptr;
+		int		   *dims;
+
 		dims = ARR_DIMS(namespaces);
-		
-		/* Sanity check */
-		if (ndims != 2)
-			ereport(ERROR, (errmsg("invalid array passed for namespace mappings"),
-							errdetail("Only 2-dimensional array may be used for namespace mappings.")));
-		
+
+		if (ndim != 2 || dims[1] != 2)
+			ereport(ERROR, (errmsg("invalid array for XML namespace mapping"),
+							errdetail("The array must be two-dimensional with length of the second axis equal to 2."),
+							errcode(ERRCODE_DATA_EXCEPTION)));
+
 		Assert(ARR_ELEMTYPE(namespaces) == TEXTOID);
-		
-		ns_count = ArrayGetNItems(ndims, dims) / 2;
+
+		ns_count = ArrayGetNItems(ndim, dims) / 2; /* number of NS mappings */
 		get_typlenbyvalalign(ARR_ELEMTYPE(namespaces),
 							 &typlen, &typbyval, &typalign);
-		ns_names = (char **) palloc(ns_count * sizeof(char *));
-		ns_uris = (char **) palloc(ns_count * sizeof(char *));
+		ns_names = palloc(ns_count * sizeof(char *));
+		ns_uris = palloc(ns_count * sizeof(char *));
 		ptr = ARR_DATA_PTR(namespaces);
 		bitmap = ARR_NULLBITMAP(namespaces);
 		bitmask = 1;
-		
 		for (i = 0; i < ns_count * 2; i++)
 		{
 			if (bitmap && (*bitmap & bitmask) == 0)
-				ereport(ERROR, (errmsg("neither namespace nor URI may be NULL"))); /* TODO: better message */
+				ereport(ERROR, (errmsg("neither namespace name nor URI may be null")));
 			else
 			{
-				if (i < ns_count)
-					ns_names[i] = DatumGetCString(DirectFunctionCall1(textout,
-														  PointerGetDatum(ptr)));
+				if (i % 2 == 0)
+					ns_names[i / 2] = DatumGetCString(DirectFunctionCall1(textout,
+																		  PointerGetDatum(ptr)));
 				else
-					ns_uris[i - ns_count] = DatumGetCString(DirectFunctionCall1(textout,
-														  PointerGetDatum(ptr)));
+					ns_uris[i / 2] = DatumGetCString(DirectFunctionCall1(textout,
+																		 PointerGetDatum(ptr)));
 				ptr = att_addlength_pointer(ptr, typlen, ptr);
 				ptr = (char *) att_align_nominal(ptr, typalign);
 			}
-	
+
 			/* advance bitmap pointer if any */
 			if (bitmap)
 			{
@@ -3087,37 +3091,55 @@ xmlpath(PG_FUNCTION_ARGS)
 			}
 		}
 	}
-	
+	else
+	{
+		ns_count = 0;
+		ns_names = NULL;
+		ns_uris = NULL;
+	}
+
 	len = VARSIZE(data) - VARHDRSZ;
 	xpath_len = VARSIZE(xpath_expr_text) - VARHDRSZ;
 	if (xpath_len == 0)
-		ereport(ERROR, (errmsg("empty XPath expression")));
-	
-	if (xmlStrncmp((xmlChar *) VARDATA(data), (xmlChar *) "<?xml", 5) == 0)
+		ereport(ERROR, (errmsg("empty XPath expression"),
+						errcode(ERRCODE_DATA_EXCEPTION)));
+
+	/*
+	 * To handle both documents and fragments, regardless of the fact
+	 * whether the XML datum has a single root (XML well-formedness),
+	 * we wrap the XML datum in a dummy element (<x>...</x>) and
+	 * extend the XPath expression accordingly.  To do it, throw away
+	 * the XML prolog, if any.
+	 */
+	if ((len > 4) && xmlStrncmp((xmlChar *) VARDATA(data), (xmlChar *) "<?xml", 5) == 0)
 	{
-		string = palloc(len + 1);
-		memcpy(string, VARDATA(data), len);
-		string[len] = '\0';
-		xpath_expr = palloc(xpath_len + 1);
-		memcpy(xpath_expr, VARDATA(xpath_expr_text), xpath_len);
-		xpath_expr[xpath_len] = '\0';
+		i = 5;
+		while ((i < len) && (('?' != (VARDATA(data))[i - 1]) || ('>' != (VARDATA(data))[i])))
+			i++;
+
+		if (i == len)
+			xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR,
+						"could not parse XML data");
+
+		++i;
+		string = xmlStrncatNew((xmlChar *) "<x>", (xmlChar *) VARDATA(data) + i, len - i);
 	}
 	else
-	{
-		/* use "<x>...</x>" as dummy root element to enable XPath for fragments */
-		/* TODO: (XPath for fragment) find better solution to work with XML fragment! */
 		string = xmlStrncatNew((xmlChar *) "<x>", (xmlChar *) VARDATA(data), len);
-		string = xmlStrncat(string, (xmlChar *) "</x>", 5);
-		len += 7;
-		xpath_expr = xmlStrncatNew((xmlChar *) "/x", (xmlChar *) VARDATA(xpath_expr_text), xpath_len);
-		len += 2;
-	}
-	
+
+	string = xmlStrncat(string, (xmlChar *) "</x>", 5);
+	len += 7;
+	xpath_expr = xmlStrncatNew((xmlChar *) "/x", (xmlChar *) VARDATA(xpath_expr_text), xpath_len);
+	xpath_len += 2;
+
 	xml_init();
 
 	PG_TRY();
 	{
-		/* redundant XML parsing (two parsings for the same value in the same session are possible) */
+		/*
+		 * redundant XML parsing (two parsings for the same value *
+		 * during one command execution are possible)
+		 */
 		ctxt = xmlNewParserCtxt();
 		if (ctxt == NULL)
 			xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR,
@@ -3133,34 +3155,33 @@ xmlpath(PG_FUNCTION_ARGS)
 		xpathctx->node = xmlDocGetRootElement(doc);
 		if (xpathctx->node == NULL)
 			xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR,
-						"could not find root XML element"); 
+						"could not find root XML element");
 
 		/* register namespaces, if any */
 		if ((ns_count > 0) && ns_names && ns_uris)
 			for (i = 0; i < ns_count; i++)
 				if (0 != xmlXPathRegisterNs(xpathctx, (xmlChar *) ns_names[i], (xmlChar *) ns_uris[i]))
-					ereport(ERROR, 
-						(errmsg("could not register XML namespace with prefix=\"%s\" and href=\"%s\"", ns_names[i], ns_uris[i])));
-		
+					ereport(ERROR,
+							(errmsg("could not register XML namespace with name \"%s\" and URI \"%s\"",
+									ns_names[i], ns_uris[i])));
+
 		xpathcomp = xmlXPathCompile(xpath_expr);
 		if (xpathcomp == NULL)
 			xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR,
 						"invalid XPath expression"); /* TODO: show proper XPath error details */
-		
+
 		xpathobj = xmlXPathCompiledEval(xpathcomp, xpathctx);
 		xmlXPathFreeCompExpr(xpathcomp);
 		if (xpathobj == NULL)
-			ereport(ERROR, (errmsg("could not create XPath object")));
-		
+			ereport(ERROR, (errmsg("could not create XPath object"))); /* TODO: reason? */
+
+		/* return empty array in cases when nothing is found */
 		if (xpathobj->nodesetval == NULL)
-			res_is_null = TRUE;
-		
-		if (!res_is_null && xpathobj->nodesetval->nodeNr == 0)
-			/* TODO maybe empty array should be here, not NULL? (if so -- fix segfault) */
-			/*PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, CurrentMemoryContext));*/
-			res_is_null = TRUE;
-		
-		if (!res_is_null) 
+			res_nitems = 0;
+		else
+			res_nitems = xpathobj->nodesetval->nodeNr;
+
+		if (res_nitems)
 			for (i = 0; i < xpathobj->nodesetval->nodeNr; i++)
 			{
 				Datum		elem;
@@ -3170,7 +3191,7 @@ xmlpath(PG_FUNCTION_ARGS)
 										  elemisnull, XMLOID,
 										  CurrentMemoryContext);
 			}
-		
+
 		xmlXPathFreeObject(xpathobj);
 		xmlXPathFreeContext(xpathctx);
 		xmlFreeParserCtxt(ctxt);
@@ -3194,15 +3215,11 @@ xmlpath(PG_FUNCTION_ARGS)
 		PG_RE_THROW();
 	}
 	PG_END_TRY();
-	
-	if (res_is_null)
-	{
-		PG_RETURN_NULL();
-	}
+
+	if (res_nitems == 0)
+		PG_RETURN_ARRAYTYPE_P(construct_empty_array(XMLOID));
 	else
-	{
 		PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, CurrentMemoryContext));
-	}
 #else
 	NO_XML_SUPPORT();
 	return 0;
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index b0d562f842480b380eda92b005bef69105cf40ca..9ae142387cab1b6a070167cbb98b05805bd556d2 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.406 2007/05/11 17:57:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.407 2007/05/21 17:10:29 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	200705111
+#define CATALOG_VERSION_NO	200705211
 
 #endif
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index b300f9b92c488d4a76f434743c463126a09d850e..7d297e8a83eacff66b69fc2890e27de03712f5a3 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.455 2007/05/08 18:56:48 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.456 2007/05/21 17:10:29 petere Exp $
  *
  * NOTES
  *	  The script catalog/genbki.sh reads this file and generates .bki
@@ -4116,9 +4116,9 @@ DESCR("map database structure to XML Schema");
 DATA(insert OID = 2938 (  database_to_xml_and_xmlschema PGNSP PGUID 12 100 0 f f t f s 3 142 "16 16 25" _null_ _null_ "{nulls,tableforest,targetns}" database_to_xml_and_xmlschema - _null_ ));
 DESCR("map database contents and structure to XML and XML Schema");
 
-DATA(insert OID = 2931 (  xmlpath      PGNSP PGUID 12 1 0 f f f f i 3 143 "25 142 1009" _null_ _null_ _null_ xmlpath - _null_ ));
+DATA(insert OID = 2931 (  xpath      PGNSP PGUID 12 1 0 f f t f i 3 143 "25 142 1009" _null_ _null_ _null_ xpath - _null_ ));
 DESCR("evaluate XPath expression, with namespaces support");
-DATA(insert OID = 2932 (  xmlpath      PGNSP PGUID 14 1 0 f f f f i 2 143 "25 142" _null_ _null_ _null_ "select pg_catalog.xmlpath($1, $2, NULL)" - _null_ ));
+DATA(insert OID = 2932 (  xpath      PGNSP PGUID 14 1 0 f f t f i 2 143 "25 142" _null_ _null_ _null_ "select pg_catalog.xpath($1, $2, ''{}''::_text)" - _null_ ));
 DESCR("evaluate XPath expression");
 
 /* uuid */ 
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index 15ba500d5078654eb8b66a984ceca67e1083138b..8e750f764f8551ee2fa558ccc080e663ec88fba3 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.18 2007/04/01 09:00:26 petere Exp $
+ * $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.19 2007/05/21 17:10:29 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -36,7 +36,7 @@ extern Datum xmlconcat2(PG_FUNCTION_ARGS);
 extern Datum texttoxml(PG_FUNCTION_ARGS);
 extern Datum xmltotext(PG_FUNCTION_ARGS);
 extern Datum xmlvalidate(PG_FUNCTION_ARGS);
-extern Datum xmlpath(PG_FUNCTION_ARGS);
+extern Datum xpath(PG_FUNCTION_ARGS);
 
 extern Datum table_to_xml(PG_FUNCTION_ARGS);
 extern Datum query_to_xml(PG_FUNCTION_ARGS);
diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out
index 20520d97606a2ac789d56d48063a2f81366d056a..cec9ea294420bb1506aedd4e287096246dd47959 100644
--- a/src/test/regress/expected/xml.out
+++ b/src/test/regress/expected/xml.out
@@ -402,37 +402,37 @@ SELECT table_name, view_definition FROM information_schema.views
 (9 rows)
 
 -- Text XPath expressions evaluation
-SELECT xmlpath('/value', data) FROM xmltest;
-       xmlpath        
+SELECT xpath('/value', data) FROM xmltest;
+        xpath         
 ----------------------
  {<value>one</value>}
  {<value>two</value>}
 (2 rows)
 
-SELECT xmlpath(NULL, NULL) IS NULL FROM xmltest;
+SELECT xpath(NULL, NULL) IS NULL FROM xmltest;
  ?column? 
 ----------
  t
  t
 (2 rows)
 
-SELECT xmlpath('', '<!-- error -->');
+SELECT xpath('', '<!-- error -->');
 ERROR:  empty XPath expression
-CONTEXT:  SQL function "xmlpath" statement 1
-SELECT xmlpath('//text()', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>');
-    xmlpath     
+CONTEXT:  SQL function "xpath" statement 1
+SELECT xpath('//text()', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>');
+     xpath      
 ----------------
  {"number one"}
 (1 row)
 
-SELECT xmlpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc'], ARRAY['http://127.0.0.1']]);
- xmlpath 
----------
+SELECT xpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]);
+ xpath 
+-------
  {1,2}
 (1 row)
 
-SELECT xmlpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');
-         xmlpath         
+SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');
+          xpath          
 -------------------------
  {<b>two</b>,<b>etc</b>}
 (1 row)
diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out
index e922107f8d3fd8b9f7f0847d196908d62216e8e9..2bf910577057dc26ff3aaf4556ffeec5694ede9f 100644
--- a/src/test/regress/expected/xml_1.out
+++ b/src/test/regress/expected/xml_1.out
@@ -326,29 +326,29 @@ SELECT table_name, view_definition FROM information_schema.views
 (2 rows)
 
 -- Text XPath expressions evaluation
-SELECT xmlpath('/value', data) FROM xmltest;
- xmlpath 
----------
+SELECT xpath('/value', data) FROM xmltest;
+ xpath 
+-------
 (0 rows)
 
-SELECT xmlpath(NULL, NULL) IS NULL FROM xmltest;
-ERROR:  unsupported XML feature
-DETAIL:  This functionality requires libxml support.
-HINT:  You need to re-compile PostgreSQL using --with-libxml.
-CONTEXT:  SQL function "xmlpath" statement 1
-SELECT xmlpath('', '<!-- error -->');
+SELECT xpath(NULL, NULL) IS NULL FROM xmltest;
+ ?column? 
+----------
+(0 rows)
+
+SELECT xpath('', '<!-- error -->');
 ERROR:  unsupported XML feature
 DETAIL:  This functionality requires libxml support.
 HINT:  You need to re-compile PostgreSQL using --with-libxml.
-SELECT xmlpath('//text()', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>');
+SELECT xpath('//text()', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>');
 ERROR:  unsupported XML feature
 DETAIL:  This functionality requires libxml support.
 HINT:  You need to re-compile PostgreSQL using --with-libxml.
-SELECT xmlpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc'], ARRAY['http://127.0.0.1']]);
+SELECT xpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]);
 ERROR:  unsupported XML feature
 DETAIL:  This functionality requires libxml support.
 HINT:  You need to re-compile PostgreSQL using --with-libxml.
-SELECT xmlpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');
+SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');
 ERROR:  unsupported XML feature
 DETAIL:  This functionality requires libxml support.
 HINT:  You need to re-compile PostgreSQL using --with-libxml.
diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql
index 1658a3803650f772bc01c2109c478fe1f66a5592..2c9db299fda33d1df0917e6b199f2fc008b13524 100644
--- a/src/test/regress/sql/xml.sql
+++ b/src/test/regress/sql/xml.sql
@@ -147,9 +147,9 @@ SELECT table_name, view_definition FROM information_schema.views
 
 -- Text XPath expressions evaluation
 
-SELECT xmlpath('/value', data) FROM xmltest;
-SELECT xmlpath(NULL, NULL) IS NULL FROM xmltest;
-SELECT xmlpath('', '<!-- error -->');
-SELECT xmlpath('//text()', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>');
-SELECT xmlpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc'], ARRAY['http://127.0.0.1']]);
-SELECT xmlpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');
+SELECT xpath('/value', data) FROM xmltest;
+SELECT xpath(NULL, NULL) IS NULL FROM xmltest;
+SELECT xpath('', '<!-- error -->');
+SELECT xpath('//text()', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>');
+SELECT xpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]);
+SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');