]> granicus.if.org Git - postgresql/commitdiff
Remove munging of xml and xpath params to xpath(). The XML must now be a well formed...
authorAndrew Dunstan <andrew@dunslane.net>
Mon, 23 Mar 2009 21:00:39 +0000 (21:00 +0000)
committerAndrew Dunstan <andrew@dunslane.net>
Mon, 23 Mar 2009 21:00:39 +0000 (21:00 +0000)
doc/src/sgml/func.sgml
src/backend/utils/adt/xml.c

index 8fd954e49d6eb53b6ca4ac69cb5cfad171f6dab1..c07d0ce0adddfff2deb98789116947fd5e3dd610 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.472 2009/02/07 14:16:45 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.473 2009/03/23 21:00:38 adunstan Exp $ -->
 
  <chapter id="functions">
   <title>Functions and Operators</title>
@@ -8447,6 +8447,11 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
     corresponding to the node set produced by the XPath expression.
    </para>
 
+  <para>
+    The second argument must be a well formed XML document. In particular,
+    it must have a single root node element.
+  </para>
+
    <para>
     The third argument of the function is an array of namespace
     mappings.  This array should be a two-dimensional array with the
index fcfc05ba5155900b7d9821fdfca218029e98d451..f31cb02b6b8b53d2cc11a8e97097fb2ec9629606 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.83 2009/01/07 13:44:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.84 2009/03/23 21:00:39 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3182,8 +3182,9 @@ xml_xmlnodetoxmltype(xmlNodePtr cur)
  * to be the most useful one (array of XML functions plays a role of
  * some kind of substitution for XQuery sequences).
  *
- * Workaround here: we parse XML data in different way to allow XPath for
- * fragments (see "XPath for fragment" TODO comment inside).
+ * It is up to the user to ensure that the XML passed is in fact
+ * an XML document - XPath doesn't work easily on fragments without
+ * a context node being known.
  */
 Datum
 xpath(PG_FUNCTION_ARGS)
@@ -3258,41 +3259,13 @@ xpath(PG_FUNCTION_ARGS)
 
        xml_init();
 
-       /*
-        * 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 >= 5 &&
-               xmlStrncmp((xmlChar *) datastr, (xmlChar *) "<?xml", 5) == 0)
-       {
-               i = 5;
-               while (i < len &&
-                          !(datastr[i - 1] == '?' && datastr[i] == '>'))
-                       i++;
-
-               if (i == len)
-                       xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR,
-                                               "could not parse XML data");
-
-               ++i;
-
-               datastr += i;
-               len -= i;
-       }
-
-       string = (xmlChar *) palloc((len + 8) * sizeof(xmlChar));
-       memcpy(string, "<x>", 3);
-       memcpy(string + 3, datastr, len);
-       memcpy(string + 3 + len, "</x>", 5);
-       len += 7;
+       string = (xmlChar *) palloc((len + 1) * sizeof(xmlChar));
+       memcpy(string, datastr, len);
+       string[len] = '\0';
 
-       xpath_expr = (xmlChar *) palloc((xpath_len + 3) * sizeof(xmlChar));
-       memcpy(xpath_expr, "/x", 2);
-       memcpy(xpath_expr + 2, VARDATA(xpath_expr_text), xpath_len);
-       xpath_expr[xpath_len + 2] = '\0';
-       xpath_len += 2;
+       xpath_expr = (xmlChar *) palloc((xpath_len +1) * sizeof(xmlChar));
+       memcpy(xpath_expr, VARDATA(xpath_expr_text), xpath_len);
+       xpath_expr[xpath_len] = '\0';
 
        xmlInitParser();
 
@@ -3307,7 +3280,7 @@ xpath(PG_FUNCTION_ARGS)
        doc = xmlCtxtReadMemory(ctxt, (char *) string, len, NULL, NULL, 0);
        if (doc == NULL)
                xml_ereport(ERROR, ERRCODE_INVALID_XML_DOCUMENT,
-                                       "could not parse XML data");
+                                       "could not parse XML document");
        xpathctx = xmlXPathNewContext(doc);
        if (xpathctx == NULL)
                xml_ereport(ERROR, ERRCODE_OUT_OF_MEMORY,