On 04/01/19 17:34, Alvaro Herrera wrote:
> I think there were some outright bugs in the docs, at least for
> XMLTABLE, that maybe we should backpatch.  If you have the energy to
> cherry-pick a minimal doc update to 10/11, I offer to back-patch it.

I don't know if this fits your intention for "minimal". What I've done
is taken the doc commit made by Tom for 12 (12d46a), then revised it
so it describes the unfixed behavior for the bugs whose fixes weren't
backpatched to 11 or 10.

I don't know if it's too late to get in the upcoming minor releases,
but maybe it can, if it looks ok, or the next ones, if that's too rushed.

11.patch applies cleanly to 11, 10.patch to 10.

I've confirmed the 11 docs build successfully, but without sgml tools,
I haven't confirmed that for 10.

Regards,
-Chap
>From f55fb4daa47ed249e87bc417b111e842403fc1a9 Mon Sep 17 00:00:00 2001
From: nobody <nob...@halvard.anastigmatix.net>
Date: Fri, 2 Aug 2019 22:47:10 -0400
Subject: [PATCH] Improve documentation about our XML functionality.

Add a section explaining how our XML features depart from current
versions of the SQL standard.  Update and clarify the descriptions
of some XML functions.

Chapman Flack, reviewed by Ryan Lambert

Discussion: https://postgr.es/m/5bd1284c.1010...@anastigmatix.net
Discussion: https://postgr.es/m/5c81f8c0.6090...@anastigmatix.net
Discussion: https://postgr.es/m/can-v+g-6jquqeqz55q3toxen6d5ez5uvzl4vr+8ktvjkj31...@mail.gmail.com

This version for backpatching PG 11 and 10, taken from Tom's commit
for 12, then edited to correctly describe behaviors that are fixed
in 12 but still broken in 11 and 10.
---
 doc/src/sgml/datatype.sgml           |   5 +
 doc/src/sgml/features.sgml           | 381 ++++++++++++++++++++++++++++++++++-
 doc/src/sgml/func.sgml               | 184 +++++++++--------
 src/backend/catalog/sql_features.txt |   6 +-
 4 files changed, 490 insertions(+), 86 deletions(-)

diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 401a2f0..fa505e0 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4228,6 +4228,11 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
     value is a full document or only a content fragment.
    </para>
 
+   <para>
+    Limits and compatibility notes for the <type>xml</type> data type
+    can be found in <xref linkend="xml-limits-conformance"/>.
+   </para>
+
    <sect2>
     <title>Creating XML Values</title>
    <para>
diff --git a/doc/src/sgml/features.sgml b/doc/src/sgml/features.sgml
index 6c22d69..253ec87 100644
--- a/doc/src/sgml/features.sgml
+++ b/doc/src/sgml/features.sgml
@@ -16,7 +16,8 @@
   Language SQL</quote>.  A revised version of the standard is released
   from time to time; the most recent update appearing in 2011.
   The 2011 version is referred to as ISO/IEC 9075:2011, or simply as SQL:2011.
-  The versions prior to that were SQL:2008, SQL:2003, SQL:1999, and SQL-92.  Each version
+  The versions prior to that were SQL:2008, SQL:2006, SQL:2003, SQL:1999,
+  and SQL-92.  Each version
   replaces the previous one, so claims of conformance to earlier
   versions have no official merit.
   <productname>PostgreSQL</productname> development aims for
@@ -155,4 +156,382 @@
    </para>
   </sect1>
 
+  <sect1 id="xml-limits-conformance">
+   <title>XML Limits and Conformance to SQL/XML</title>
+
+   <indexterm>
+    <primary>SQL/XML</primary>
+    <secondary>limits and conformance</secondary>
+   </indexterm>
+
+   <para>
+    Significant revisions to the XML-related specifications in ISO/IEC 9075-14
+    (SQL/XML) were introduced with SQL:2006.
+    <productname>PostgreSQL</productname>'s implementation of the XML data
+    type and related functions largely follows the earlier 2003 edition,
+    with some borrowing from later editions.  In particular:
+    <itemizedlist>
+     <listitem>
+      <para>
+       Where the current standard provides a family of XML data types
+       to hold <quote>document</quote> or <quote>content</quote> in
+       untyped or XML Schema-typed variants, and a type
+       <type>XML(SEQUENCE)</type> to hold arbitrary pieces of XML content,
+       <productname>PostgreSQL</productname> provides the single
+       <type>xml</type> type, which can hold <quote>document</quote> or
+       <quote>content</quote>.  There is no equivalent of the
+       standard's <quote>sequence</quote> type.
+      </para>
+     </listitem>
+
+     <listitem>
+      <para>
+       <productname>PostgreSQL</productname> provides two functions
+       introduced in SQL:2006, but in variants that use the XPath 1.0
+       language, rather than XML Query as specified for them in the
+       standard.
+      </para>
+     </listitem>
+    </itemizedlist>
+   </para>
+
+   <para>
+    This section presents some of the resulting differences you may encounter.
+   </para>
+
+   <sect2 id="functions-xml-limits-xpath1">
+    <title>Queries are restricted to XPath 1.0</title>
+
+    <para>
+     The <productname>PostgreSQL</productname>-specific functions
+     <function>xpath()</function> and <function>xpath_exists()</function>
+     query XML documents using the XPath language.
+     <productname>PostgreSQL</productname> also provides XPath-only variants
+     of the standard functions <function>XMLEXISTS</function> and
+     <function>XMLTABLE</function>, which officially use
+     the XQuery language. For all of these functions,
+     <productname>PostgreSQL</productname> relies on the
+     <application>libxml2</application> library, which provides only XPath 1.0.
+    </para>
+
+    <para>
+     There is a strong connection between the XQuery language and XPath
+     versions 2.0 and later: any expression that is syntactically valid and
+     executes successfully in both produces the same result (with a minor
+     exception for expressions containing numeric character references or
+     predefined entity references, which XQuery replaces with the
+     corresponding character while XPath leaves them alone).  But there is
+     no such connection between these languages and XPath 1.0; it was an
+     earlier language and differs in many respects.
+    </para>
+
+    <para>
+     There are two categories of limitation to keep in mind: the restriction
+     from XQuery to XPath for the functions specified in the SQL standard, and
+     the restriction of XPath to version 1.0 for both the standard and the
+     <productname>PostgreSQL</productname>-specific functions.
+    </para>
+
+    <sect3>
+     <title>Restriction of XQuery to XPath</title>
+
+     <para>
+      Features of XQuery beyond those of XPath include:
+
+      <itemizedlist>
+       <listitem>
+        <para>
+         XQuery expressions can construct and return new XML nodes, in
+         addition to all possible XPath values.  XPath can create and return
+         values of the atomic types (numbers, strings, and so on) but can
+         only return XML nodes that were already present in documents
+         supplied as input to the expression.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         XQuery has control constructs for iteration, sorting, and grouping.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         XQuery allows declaration and use of local functions.
+        </para>
+       </listitem>
+      </itemizedlist>
+     </para>
+
+     <para>
+      Recent XPath versions begin to offer capabilities overlapping with
+      these (such as functional-style <function>for-each</function> and
+      <function>sort</function>, anonymous functions, and
+      <function>parse-xml</function> to create a node from a string),
+      but such features were not available before XPath 3.0.
+     </para>
+    </sect3>
+
+    <sect3 id="xml-xpath-1-specifics">
+     <title>Restriction of XPath to 1.0</title>
+
+     <para>
+      For developers familiar with XQuery and XPath 2.0 or later, XPath 1.0
+      presents a number of differences to contend with:
+
+      <itemizedlist>
+       <listitem>
+        <para>
+         The fundamental type of an XQuery/XPath expression, the
+         <type>sequence</type>, which can contain XML nodes, atomic values,
+         or both, does not exist in XPath 1.0. A 1.0 expression can only
+         produce a node-set (containing zero or more XML nodes), or a single
+         atomic value.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+          Unlike an XQuery/XPath sequence, which can contain any desired
+          items in any desired order, an XPath 1.0 node-set has no
+          guaranteed order and, like any set, does not allow multiple
+          appearances of the same item.
+         <note>
+          <para>
+           The <application>libxml2</application> library does seem to
+           always return node-sets to <productname>PostgreSQL</productname>
+           with their members in the same relative order they had in the
+           input document.  Its documentation does not commit to this
+           behavior, and an XPath 1.0 expression cannot control it.
+          </para>
+         </note>
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         While XQuery/XPath provides all of the types defined in XML Schema
+         and many operators and functions over those types, XPath 1.0 has only
+         node-sets and the three atomic types <type>boolean</type>,
+         <type>double</type>, and <type>string</type>.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         XPath 1.0 has no conditional operator. An XQuery/XPath expression
+         such as <literal>if ( hat ) then hat/@size else "no hat"</literal>
+         has no XPath 1.0 equivalent.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         XPath 1.0 has no ordering comparison operator for strings. Both
+         <literal>"cat" &lt; "dog"</literal> and
+         <literal>"cat" &gt; "dog"</literal> are false, because each is a
+         numeric comparison of two <literal>NaN</literal>s. In contrast,
+         <literal>=</literal> and <literal>!=</literal> do compare the strings
+         as strings.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         XPath 1.0 blurs the distinction between
+         <firstterm>value comparisons</firstterm> and
+         <firstterm>general comparisons</firstterm> as XQuery/XPath define
+         them.  Both <literal>sale/@hatsize = 7</literal> and
+         <literal>sale/@customer = "alice"</literal> are existentially
+         quantified comparisons, true if there is
+         any <literal>sale</literal> with the given value for the
+         attribute, but <literal>sale/@taxable = false()</literal> is a
+         value comparison to the
+         <firstterm>effective boolean value</firstterm> of a whole node-set.
+         It is true only if no <literal>sale</literal> has
+         a <literal>taxable</literal> attribute at all.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         In the XQuery/XPath data model, a <firstterm>document
+         node</firstterm> can have either document form (i.e., exactly one
+         top-level element, with only comments and processing instructions
+         outside of it) or content form (with those constraints
+         relaxed). Its equivalent in XPath 1.0, the
+         <firstterm>root node</firstterm>, can only be in document form.
+         This is part of the reason an <type>xml</type> value passed as the
+         context item to any <productname>PostgreSQL</productname>
+         XPath-based function must be in document form.
+        </para>
+       </listitem>
+      </itemizedlist>
+     </para>
+
+     <para>
+      The differences highlighted here are not all of them. In XQuery and
+      the 2.0 and later versions of XPath, there is an XPath 1.0 compatibility
+      mode, and the W3C lists of
+      <ulink url='https://www.w3.org/TR/2010/REC-xpath-functions-20101214/#xpath1-compatibility'>function library changes</ulink>
+      and
+      <ulink url='https://www.w3.org/TR/xpath20/#id-backwards-compatibility'>language changes</ulink>
+      applied in that mode offer a more complete (but still not exhaustive)
+      account of the differences.  The compatibility mode cannot make the
+      later languages exactly equivalent to XPath 1.0.
+     </para>
+    </sect3>
+
+    <sect3 id="functions-xml-limits-casts">
+     <title>Mappings between SQL and XML data types and values</title>
+
+     <para>
+      In SQL:2006 and later, both directions of conversion between standard SQL
+      data types and the XML Schema types are specified precisely. However, the
+      rules are expressed using the types and semantics of XQuery/XPath, and
+      have no direct application to the different data model of XPath 1.0.
+     </para>
+
+     <para>
+      When <productname>PostgreSQL</productname> maps SQL data values to XML
+      (as in <function>xmlelement</function>), or XML to SQL (as in the output
+      columns of <function>xmltable</function>), except for a few cases
+      treated specially, <productname>PostgreSQL</productname> simply assumes
+      that the XML data type's XPath 1.0 string form will be valid as the
+      text-input form of the SQL datatype, and conversely. This rule has the
+      virtue of simplicity while producing, for many data types, results similar
+      to the mappings specified in the standard. In this release,
+      an explicit cast is needed if an <function>xmltable</function> column
+      expression produces a boolean or double value; see
+      <xref linkend="functions-xml-limits-postgresql"/>.
+     </para>
+
+     <para>
+      Where interoperability with other systems is a concern, for some data
+      types, it may be necessary to use data type formatting functions (such
+      as those in <xref linkend="functions-formatting"/>) explicitly to
+      produce the standard mappings.
+     </para>
+    </sect3>
+   </sect2>
+
+   <sect2 id="functions-xml-limits-postgresql">
+    <title>
+     Incidental limits of the implementation
+    </title>
+
+    <para>
+     This section concerns limits that are not inherent in the
+     <application>libxml2</application> library, but apply to the current
+     implementation in <productname>PostgreSQL</productname>.
+    </para>
+
+    <sect3>
+     <title>
+      Cast needed for <function>xmltable</function> column
+      of boolean or double type
+     </title>
+
+     <para>
+      An <function>xmltable</function> column expression evaluating to an XPath
+      boolean or number result will produce an <quote>unexpected XPath object
+      type</quote> error. The workaround is to rewrite the column expression to
+      be inside the XPath <function>string</function> function;
+      <productname>PostgreSQL</productname> will then assign the string value
+      successfully to an SQL output column of boolean or double type.
+     </para>
+    </sect3>
+
+    <sect3>
+     <title>
+      Column path result or SQL result column of XML type
+     </title>
+
+     <para>
+      In this release, a <function>xmltable</function> column expression
+      that evaluates to an XML node-set can be assigned to an SQL result
+      column of XML type, producing a concatenation of: for most types of
+      node in the node-set, a text node containing the XPath 1.0
+      <firstterm>string-value</firstterm> of the node, but for an element node,
+      a copy of the node itself. Such a node-set may be assigned to an SQL
+      column of non-XML type only if the node-set has a single node, with the
+      string-value of most node types replaced with an empty string, the
+      string-value of an element node replaced with a concatenation of only its
+      direct text-node children (excluding those of descendants), and the
+      string-value of a text or attribute node being as defined in XPath 1.0.
+      An XPath string value assigned to a result column of XML type must be
+      parsable as XML.
+     </para>
+
+     <para>
+      It is best not to develop code that relies on these behaviors, which have
+      little resemblance to the spec, and are changed in
+      <productname>PostgreSQL 12</productname>.
+     </para>
+    </sect3>
+
+    <sect3>
+     <title>Only <literal>BY VALUE</literal> passing mechanism is supported</title>
+
+     <para>
+      The SQL standard defines two <firstterm>passing mechanisms</firstterm>
+      that apply when passing an XML argument from SQL to an XML function or
+      receiving a result: <literal>BY REF</literal>, in which a particular XML
+      value retains its node identity, and <literal>BY VALUE</literal>, in which
+      the content of the XML is passed but node identity is not preserved. A
+      mechanism can be specified before a list of parameters, as the default
+      mechanism for all of them, or after any parameter, to override the
+      default.
+     </para>
+
+     <para>
+      To illustrate the difference, if
+      <replaceable>x</replaceable> is an XML value, these two queries in
+      an SQL:2006 environment would produce true and false, respectively:
+
+<programlisting>
+SELECT XMLQUERY('$a is $b' PASSING BY REF <replaceable>x</replaceable> AS a, <replaceable>x</replaceable> AS b NULL ON EMPTY);
+SELECT XMLQUERY('$a is $b' PASSING BY VALUE <replaceable>x</replaceable> AS a, <replaceable>x</replaceable> AS b NULL ON EMPTY);
+</programlisting>
+     </para>
+
+     <para>
+      In this release, <productname>PostgreSQL</productname> will accept
+      <literal>BY REF</literal> in an
+      <function>XMLEXISTS</function> or <function>XMLTABLE</function>
+      construct, but will ignore it.  The <type>xml</type> data type holds
+      a character-string serialized representation, so there is no node
+      identity to preserve, and passing is always effectively <literal>BY
+      VALUE</literal>.
+     </para>
+    </sect3>
+
+    <sect3>
+     <title>Cannot pass named parameters to queries</title>
+
+     <para>
+      The XPath-based functions support passing one parameter to serve as the
+      XPath expression's context item, but do not support passing additional
+      values to be available to the expression as named parameters.
+     </para>
+    </sect3>
+
+    <sect3>
+     <title>No <type>XML(SEQUENCE)</type> type</title>
+
+     <para>
+      The <productname>PostgreSQL</productname> <type>xml</type> data type
+      can only hold a value in <literal>DOCUMENT</literal>
+      or <literal>CONTENT</literal> form.  An XQuery/XPath expression
+      context item must be a single XML node or atomic value, but XPath 1.0
+      further restricts it to be only an XML node, and has no node type
+      allowing <literal>CONTENT</literal>.  The upshot is that a
+      well-formed <literal>DOCUMENT</literal> is the only form of XML value
+      that <productname>PostgreSQL</productname> can supply as an XPath
+      context item.
+     </para>
+    </sect3>
+   </sect2>
+  </sect1>
+
  </appendix>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index cfa1e78..bec1b87 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -10045,16 +10045,25 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
 
 
  <sect1 id="functions-xml">
+
   <title>XML Functions</title>
 
+  <indexterm>
+   <primary>XML Functions</primary>
+  </indexterm>
+
   <para>
    The functions and function-like expressions described in this
-   section operate on values of type <type>xml</type>.  Check <xref
+   section operate on values of type <type>xml</type>.  See <xref
    linkend="datatype-xml"/> for information about the <type>xml</type>
    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 most of these
-   functions requires the installation to have been built
+   type <type>xml</type> are documented there, not in this section.
+  </para>
+
+  <para>
+   Use of most of these functions
+   requires <productname>PostgreSQL</productname> to have been built
    with <command>configure --with-libxml</command>.
   </para>
 
@@ -10249,8 +10258,8 @@ SELECT xmlelement(name foo, xmlattributes('xyz' as bar),
      encoding, depending on the setting of the configuration parameter
      <xref linkend="guc-xmlbinary"/>.  The particular behavior for
      individual data types is expected to evolve in order to align the
-     SQL and PostgreSQL data types with the XML Schema specification,
-     at which point a more precise description will appear.
+     PostgreSQL mappings with those specified in SQL:2006 and later,
+     as discussed in <xref linkend="functions-xml-limits-casts"/>.
     </para>
    </sect3>
 
@@ -10492,10 +10501,13 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
 </synopsis>
 
     <para>
-     The function <function>xmlexists</function> returns true if the
-     XPath expression in the first argument returns any nodes, and
-     false otherwise.  (If either argument is null, the result is
-     null.)
+     The function <function>xmlexists</function> evaluates an XPath 1.0
+     expression (the first argument), with the passed XML value as its context
+     item.  The function returns false if the result of that evaluation
+     yields an empty node-set, true if it yields any other value.  The
+     function returns null if any argument is null.  A nonnull value
+     passed as the context item must be an XML document, not a content
+     fragment or any non-XML value.
     </para>
 
     <para>
@@ -10511,14 +10523,14 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Tor
     </para>
 
     <para>
-     The <literal>BY REF</literal> clauses have no effect in
-     PostgreSQL, but are allowed for SQL conformance and compatibility
-     with other implementations.  Per SQL standard, the
-     first <literal>BY REF</literal> is required, the second is
-     optional.  Also note that the SQL standard specifies
-     the <function>xmlexists</function> construct to take an XQuery
-     expression as first argument, but PostgreSQL currently only
-     supports XPath, which is a subset of XQuery.
+     The <literal>BY REF</literal> clauses
+     are accepted in <productname>PostgreSQL</productname>, but are ignored,
+     as discussed in <xref linkend="functions-xml-limits-postgresql"/>.
+     In the SQL standard, the <function>xmlexists</function> function
+     evaluates an expression in the XML Query language,
+     but <productname>PostgreSQL</productname> allows only an XPath 1.0
+     expression, as discussed in
+     <xref linkend="functions-xml-limits-xpath1"/>.
     </para>
    </sect3>
 
@@ -10624,12 +10636,12 @@ SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuf
 </synopsis>
 
     <para>
-     The function <function>xpath</function> evaluates the XPath
+     The function <function>xpath</function> evaluates the XPath 1.0
      expression <replaceable>xpath</replaceable> (a <type>text</type> value)
      against the XML value
      <replaceable>xml</replaceable>.  It returns an array of XML values
-     corresponding to the node set produced by the XPath expression.
-     If the XPath expression returns a scalar value rather than a node set,
+     corresponding to the node-set produced by the XPath expression.
+     If the XPath expression returns a scalar value rather than a node-set,
      a single-element array is returned.
     </para>
 
@@ -10691,9 +10703,10 @@ SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com";><b>test</b></a
     <para>
      The function <function>xpath_exists</function> is a specialized form
      of the <function>xpath</function> function.  Instead of returning the
-     individual XML values that satisfy the XPath, this function returns a
-     Boolean indicating whether the query was satisfied or not.  This
-     function is equivalent to the standard <literal>XMLEXISTS</literal> predicate,
+     individual XML values that satisfy the XPath 1.0 expression, this function
+     returns a Boolean indicating whether the query was satisfied or not
+     (specifically, whether it produced any value other than an empty node-set).
+     This function is equivalent to the <literal>XMLEXISTS</literal> predicate,
      except that it also offers support for a namespace mapping argument.
     </para>
 
@@ -10734,8 +10747,8 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com";>test</m
 
     <para>
      The <function>xmltable</function> function produces a table based
-     on the given XML value, an XPath filter to extract rows, and an
-     optional set of column definitions.
+     on the given XML value, an XPath filter to extract rows, and a
+     set of column definitions.
     </para>
 
     <para>
@@ -10746,30 +10759,34 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com";>test</m
     </para>
 
     <para>
-     The required <replaceable>row_expression</replaceable> argument is an XPath
-     expression that is evaluated against the supplied XML document to
-     obtain an ordered sequence of XML nodes. This sequence is what
-     <function>xmltable</function> transforms into output rows.
+     The required <replaceable>row_expression</replaceable> argument is
+     an XPath 1.0 expression that is evaluated, passing the
+     <replaceable>document_expression</replaceable> as its context item, to
+     obtain a set of XML nodes. These nodes are what
+     <function>xmltable</function> transforms into output rows. No rows
+     will be produced if the <replaceable>document_expression</replaceable>
+     is null, nor if the <replaceable>row_expression</replaceable> produces
+     an empty node-set or any value other than a node-set.
     </para>
 
     <para>
-     <replaceable>document_expression</replaceable> provides the XML document to
-     operate on.
-     The <literal>BY REF</literal> clauses have no effect in PostgreSQL,
-     but are allowed for SQL conformance and compatibility with other
-     implementations.
-     The argument must be a well-formed XML document; fragments/forests
-     are not accepted.
+     <replaceable>document_expression</replaceable> provides the context
+     item for the <replaceable>row_expression</replaceable>. It must be a
+     well-formed XML document; fragments/forests are not accepted.
+     The <literal>BY REF</literal> clauses
+     are accepted but ignored, as discussed in
+     <xref linkend="functions-xml-limits-postgresql"/>.
+     In the SQL standard, the <function>xmltable</function> function
+     evaluates expressions in the XML Query language,
+     but <productname>PostgreSQL</productname> allows only XPath 1.0
+     expressions, as discussed in
+     <xref linkend="functions-xml-limits-xpath1"/>.
     </para>
 
     <para>
      The mandatory <literal>COLUMNS</literal> clause specifies the list
      of columns in the output table.
-     If the <literal>COLUMNS</literal> clause is omitted, the rows in the result
-     set contain a single column of type <literal>xml</literal> containing the
-     data matched by <replaceable>row_expression</replaceable>.
-     If <literal>COLUMNS</literal> is specified, each entry describes a
-     single column.
+     Each entry describes a single column.
      See the syntax summary above for the format.
      The column name and type are required; the path, default and
      nullability clauses are optional.
@@ -10777,48 +10794,57 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com";>test</m
 
     <para>
      A column marked <literal>FOR ORDINALITY</literal> will be populated
-     with row numbers matching the order in which the
-     output rows appeared in the original input XML document.
+     with row numbers, starting with 1, in the order of nodes retrieved from
+     the <replaceable>row_expression</replaceable>'s result node-set.
      At most one column may be marked <literal>FOR ORDINALITY</literal>.
     </para>
 
+    <note>
+     <para>
+      XPath 1.0 does not specify an order for nodes in a node-set, so code
+      that relies on a particular order of the results will be
+      implementation-dependent.  Details can be found in
+      <xref linkend="xml-xpath-1-specifics"/>.
+     </para>
+    </note>
+
     <para>
-     The <literal>column_expression</literal> for a column is an XPath expression
-     that is evaluated for each row, relative to the result of the
-     <replaceable>row_expression</replaceable>, to find the value of the column.
-     If no <literal>column_expression</literal> is given, then the column name
-     is used as an implicit path.
+     The <replaceable>column_expression</replaceable> for a column is an
+     XPath 1.0 expression that is evaluated for each row, with the current
+     node from the <replaceable>row_expression</replaceable> result as its
+     context item, to find the value of the column.  If
+     no <replaceable>column_expression</replaceable> is given, then the
+     column name is used as an implicit path.
     </para>
 
     <para>
-     If a column's XPath expression returns multiple elements, an error
-     is raised.
-     If the expression matches an empty tag, the result is an
-     empty string (not <literal>NULL</literal>).
-     Any <literal>xsi:nil</literal> attributes are ignored.
+     If a column's XPath expression returns a non-XML value (limited to
+     string, boolean, or double in XPath 1.0) and the column has a
+     PostgreSQL type other than <type>xml</type>, the column will be set
+     as if by assigning the value's string representation to the PostgreSQL
+     type. In this release, an XPath boolean or double result must be explicitly
+     cast to string (that is, the XPath 1.0 <function>string</function> function
+     wrapped around the original column expression);
+     <productname>PostgreSQL</productname> can then successfully assign the
+     string to an SQL result column of boolean or double type.
+     These conversion rules differ from those of the SQL
+     standard, as discussed in <xref linkend="functions-xml-limits-casts"/>.
     </para>
 
     <para>
-     The text body of the XML matched by the <replaceable>column_expression</replaceable>
-     is used as the column value. Multiple <literal>text()</literal> nodes
-     within an element are concatenated in order. Any child elements,
-     processing instructions, and comments are ignored, but the text contents
-     of child elements are concatenated to the result.
-     Note that the whitespace-only <literal>text()</literal> node between two non-text
-     elements is preserved, and that leading whitespace on a <literal>text()</literal>
-     node is not flattened.
+     In this release, SQL result columns of <type>xml</type> type, or
+     column XPath expressions evaluating to an XML type, regardless of the
+     output column SQL type, are handled as described in
+     <xref linkend="functions-xml-limits-postgresql"/>; the behavior
+     changes significantly in <productname>PostgreSQL 12</productname>.
     </para>
 
     <para>
-     If the path expression does not match for a given row but
-     <replaceable>default_expression</replaceable> is specified, the value resulting
-     from evaluating that expression is used.
-     If no <literal>DEFAULT</literal> clause is given for the column,
-     the field will be set to <literal>NULL</literal>.
-     It is possible for a <replaceable>default_expression</replaceable> to reference
-     the value of output columns that appear prior to it in the column list,
-     so the default of one column may be based on the value of another
-     column.
+     If the path expression returns an empty node-set
+     (typically, when it does not match)
+     for a given row, the column will be set to <literal>NULL</literal>, unless
+     a <replaceable>default_expression</replaceable> is specified; then the
+     value resulting from evaluating that expression is used.
     </para>
 
     <para>
@@ -10830,20 +10856,14 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com";>test</m
     </para>
 
     <para>
-     Unlike regular PostgreSQL functions, <replaceable>column_expression</replaceable>
-     and <replaceable>default_expression</replaceable> are not evaluated to a simple
-     value before calling the function.
-     <replaceable>column_expression</replaceable> is normally evaluated
-     exactly once per input row, and <replaceable>default_expression</replaceable>
-     is evaluated each time a default is needed for a field.
-     If the expression qualifies as stable or immutable the repeat
+     A <replaceable>default_expression</replaceable>, rather than being
+     evaluated immediately when <function>xmltable</function> is called,
+     is evaluated each time a default is needed for the column.
+     If the expression qualifies as stable or immutable, the repeat
      evaluation may be skipped.
-     Effectively <function>xmltable</function> behaves more like a subquery than a
-     function call.
      This means that you can usefully use volatile functions like
-     <function>nextval</function> in <replaceable>default_expression</replaceable>, and
-     <replaceable>column_expression</replaceable> may depend on other parts of the
-     XML document.
+     <function>nextval</function> in
+     <replaceable>default_expression</replaceable>.
     </para>
 
     <para>
diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt
index aeb262a..915696e 100644
--- a/src/backend/catalog/sql_features.txt
+++ b/src/backend/catalog/sql_features.txt
@@ -593,7 +593,7 @@ X085	Predefined namespace prefixes			NO
 X086	XML namespace declarations in XMLTable			NO	
 X090	XML document predicate			YES	
 X091	XML content predicate			NO	
-X096	XMLExists			NO	XPath only
+X096	XMLExists			NO	XPath 1.0 only
 X100	Host language support for XML: CONTENT option			NO	
 X101	Host language support for XML: DOCUMENT option			NO	
 X110	Host language support for XML: VARCHAR mapping			NO	
@@ -661,11 +661,11 @@ X282	XMLValidate with CONTENT option			NO
 X283	XMLValidate with SEQUENCE option			NO	
 X284	XMLValidate: NAMESPACE without ELEMENT clause			NO	
 X286	XMLValidate: NO NAMESPACE with ELEMENT clause			NO	
-X300	XMLTable			NO	XPath only
+X300	XMLTable			NO	XPath 1.0 only
 X301	XMLTable: derived column list option			YES	
 X302	XMLTable: ordinality column option			YES	
 X303	XMLTable: column default option			YES	
-X304	XMLTable: passing a context item			YES	
+X304	XMLTable: passing a context item			YES	must be XML DOCUMENT
 X305	XMLTable: initializing an XQuery variable			NO	
 X400	Name and identifier mapping			YES	
 X410	Alter column data type: XML type			YES	
-- 
2.7.3

>From 387631f79b0a7824d053296965f768efca14e30d Mon Sep 17 00:00:00 2001
From: nobody <nob...@halvard.anastigmatix.net>
Date: Fri, 2 Aug 2019 22:47:10 -0400
Subject: [PATCH] Improve documentation about our XML functionality.

Add a section explaining how our XML features depart from current
versions of the SQL standard.  Update and clarify the descriptions
of some XML functions.

Chapman Flack, reviewed by Ryan Lambert

Discussion: https://postgr.es/m/5bd1284c.1010...@anastigmatix.net
Discussion: https://postgr.es/m/5c81f8c0.6090...@anastigmatix.net
Discussion: https://postgr.es/m/can-v+g-6jquqeqz55q3toxen6d5ez5uvzl4vr+8ktvjkj31...@mail.gmail.com

This version for backpatching PG 10, taken from Tom's commit
for 12, then edited to correctly describe behaviors that are fixed
in 12 but still broken in 10.
---
 doc/src/sgml/datatype.sgml           |   5 +
 doc/src/sgml/features.sgml           | 381 ++++++++++++++++++++++++++++++++++-
 doc/src/sgml/func.sgml               | 190 +++++++++--------
 src/backend/catalog/sql_features.txt |   6 +-
 4 files changed, 493 insertions(+), 89 deletions(-)

diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index cd5f5f0..6b9010f 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4228,6 +4228,11 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
     value is a full document or only a content fragment.
    </para>
 
+   <para>
+    Limits and compatibility notes for the <type>xml</type> data type
+    can be found in <xref linkend="xml-limits-conformance"/>.
+   </para>
+
    <sect2>
     <title>Creating XML Values</title>
    <para>
diff --git a/doc/src/sgml/features.sgml b/doc/src/sgml/features.sgml
index 6c22d69..253ec87 100644
--- a/doc/src/sgml/features.sgml
+++ b/doc/src/sgml/features.sgml
@@ -16,7 +16,8 @@
   Language SQL</quote>.  A revised version of the standard is released
   from time to time; the most recent update appearing in 2011.
   The 2011 version is referred to as ISO/IEC 9075:2011, or simply as SQL:2011.
-  The versions prior to that were SQL:2008, SQL:2003, SQL:1999, and SQL-92.  Each version
+  The versions prior to that were SQL:2008, SQL:2006, SQL:2003, SQL:1999,
+  and SQL-92.  Each version
   replaces the previous one, so claims of conformance to earlier
   versions have no official merit.
   <productname>PostgreSQL</productname> development aims for
@@ -155,4 +156,382 @@
    </para>
   </sect1>
 
+  <sect1 id="xml-limits-conformance">
+   <title>XML Limits and Conformance to SQL/XML</title>
+
+   <indexterm>
+    <primary>SQL/XML</primary>
+    <secondary>limits and conformance</secondary>
+   </indexterm>
+
+   <para>
+    Significant revisions to the XML-related specifications in ISO/IEC 9075-14
+    (SQL/XML) were introduced with SQL:2006.
+    <productname>PostgreSQL</productname>'s implementation of the XML data
+    type and related functions largely follows the earlier 2003 edition,
+    with some borrowing from later editions.  In particular:
+    <itemizedlist>
+     <listitem>
+      <para>
+       Where the current standard provides a family of XML data types
+       to hold <quote>document</quote> or <quote>content</quote> in
+       untyped or XML Schema-typed variants, and a type
+       <type>XML(SEQUENCE)</type> to hold arbitrary pieces of XML content,
+       <productname>PostgreSQL</productname> provides the single
+       <type>xml</type> type, which can hold <quote>document</quote> or
+       <quote>content</quote>.  There is no equivalent of the
+       standard's <quote>sequence</quote> type.
+      </para>
+     </listitem>
+
+     <listitem>
+      <para>
+       <productname>PostgreSQL</productname> provides two functions
+       introduced in SQL:2006, but in variants that use the XPath 1.0
+       language, rather than XML Query as specified for them in the
+       standard.
+      </para>
+     </listitem>
+    </itemizedlist>
+   </para>
+
+   <para>
+    This section presents some of the resulting differences you may encounter.
+   </para>
+
+   <sect2 id="functions-xml-limits-xpath1">
+    <title>Queries are restricted to XPath 1.0</title>
+
+    <para>
+     The <productname>PostgreSQL</productname>-specific functions
+     <function>xpath()</function> and <function>xpath_exists()</function>
+     query XML documents using the XPath language.
+     <productname>PostgreSQL</productname> also provides XPath-only variants
+     of the standard functions <function>XMLEXISTS</function> and
+     <function>XMLTABLE</function>, which officially use
+     the XQuery language. For all of these functions,
+     <productname>PostgreSQL</productname> relies on the
+     <application>libxml2</application> library, which provides only XPath 1.0.
+    </para>
+
+    <para>
+     There is a strong connection between the XQuery language and XPath
+     versions 2.0 and later: any expression that is syntactically valid and
+     executes successfully in both produces the same result (with a minor
+     exception for expressions containing numeric character references or
+     predefined entity references, which XQuery replaces with the
+     corresponding character while XPath leaves them alone).  But there is
+     no such connection between these languages and XPath 1.0; it was an
+     earlier language and differs in many respects.
+    </para>
+
+    <para>
+     There are two categories of limitation to keep in mind: the restriction
+     from XQuery to XPath for the functions specified in the SQL standard, and
+     the restriction of XPath to version 1.0 for both the standard and the
+     <productname>PostgreSQL</productname>-specific functions.
+    </para>
+
+    <sect3>
+     <title>Restriction of XQuery to XPath</title>
+
+     <para>
+      Features of XQuery beyond those of XPath include:
+
+      <itemizedlist>
+       <listitem>
+        <para>
+         XQuery expressions can construct and return new XML nodes, in
+         addition to all possible XPath values.  XPath can create and return
+         values of the atomic types (numbers, strings, and so on) but can
+         only return XML nodes that were already present in documents
+         supplied as input to the expression.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         XQuery has control constructs for iteration, sorting, and grouping.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         XQuery allows declaration and use of local functions.
+        </para>
+       </listitem>
+      </itemizedlist>
+     </para>
+
+     <para>
+      Recent XPath versions begin to offer capabilities overlapping with
+      these (such as functional-style <function>for-each</function> and
+      <function>sort</function>, anonymous functions, and
+      <function>parse-xml</function> to create a node from a string),
+      but such features were not available before XPath 3.0.
+     </para>
+    </sect3>
+
+    <sect3 id="xml-xpath-1-specifics">
+     <title>Restriction of XPath to 1.0</title>
+
+     <para>
+      For developers familiar with XQuery and XPath 2.0 or later, XPath 1.0
+      presents a number of differences to contend with:
+
+      <itemizedlist>
+       <listitem>
+        <para>
+         The fundamental type of an XQuery/XPath expression, the
+         <type>sequence</type>, which can contain XML nodes, atomic values,
+         or both, does not exist in XPath 1.0. A 1.0 expression can only
+         produce a node-set (containing zero or more XML nodes), or a single
+         atomic value.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+          Unlike an XQuery/XPath sequence, which can contain any desired
+          items in any desired order, an XPath 1.0 node-set has no
+          guaranteed order and, like any set, does not allow multiple
+          appearances of the same item.
+         <note>
+          <para>
+           The <application>libxml2</application> library does seem to
+           always return node-sets to <productname>PostgreSQL</productname>
+           with their members in the same relative order they had in the
+           input document.  Its documentation does not commit to this
+           behavior, and an XPath 1.0 expression cannot control it.
+          </para>
+         </note>
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         While XQuery/XPath provides all of the types defined in XML Schema
+         and many operators and functions over those types, XPath 1.0 has only
+         node-sets and the three atomic types <type>boolean</type>,
+         <type>double</type>, and <type>string</type>.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         XPath 1.0 has no conditional operator. An XQuery/XPath expression
+         such as <literal>if ( hat ) then hat/@size else "no hat"</literal>
+         has no XPath 1.0 equivalent.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         XPath 1.0 has no ordering comparison operator for strings. Both
+         <literal>"cat" &lt; "dog"</literal> and
+         <literal>"cat" &gt; "dog"</literal> are false, because each is a
+         numeric comparison of two <literal>NaN</literal>s. In contrast,
+         <literal>=</literal> and <literal>!=</literal> do compare the strings
+         as strings.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         XPath 1.0 blurs the distinction between
+         <firstterm>value comparisons</firstterm> and
+         <firstterm>general comparisons</firstterm> as XQuery/XPath define
+         them.  Both <literal>sale/@hatsize = 7</literal> and
+         <literal>sale/@customer = "alice"</literal> are existentially
+         quantified comparisons, true if there is
+         any <literal>sale</literal> with the given value for the
+         attribute, but <literal>sale/@taxable = false()</literal> is a
+         value comparison to the
+         <firstterm>effective boolean value</firstterm> of a whole node-set.
+         It is true only if no <literal>sale</literal> has
+         a <literal>taxable</literal> attribute at all.
+        </para>
+       </listitem>
+
+       <listitem>
+        <para>
+         In the XQuery/XPath data model, a <firstterm>document
+         node</firstterm> can have either document form (i.e., exactly one
+         top-level element, with only comments and processing instructions
+         outside of it) or content form (with those constraints
+         relaxed). Its equivalent in XPath 1.0, the
+         <firstterm>root node</firstterm>, can only be in document form.
+         This is part of the reason an <type>xml</type> value passed as the
+         context item to any <productname>PostgreSQL</productname>
+         XPath-based function must be in document form.
+        </para>
+       </listitem>
+      </itemizedlist>
+     </para>
+
+     <para>
+      The differences highlighted here are not all of them. In XQuery and
+      the 2.0 and later versions of XPath, there is an XPath 1.0 compatibility
+      mode, and the W3C lists of
+      <ulink url='https://www.w3.org/TR/2010/REC-xpath-functions-20101214/#xpath1-compatibility'>function library changes</ulink>
+      and
+      <ulink url='https://www.w3.org/TR/xpath20/#id-backwards-compatibility'>language changes</ulink>
+      applied in that mode offer a more complete (but still not exhaustive)
+      account of the differences.  The compatibility mode cannot make the
+      later languages exactly equivalent to XPath 1.0.
+     </para>
+    </sect3>
+
+    <sect3 id="functions-xml-limits-casts">
+     <title>Mappings between SQL and XML data types and values</title>
+
+     <para>
+      In SQL:2006 and later, both directions of conversion between standard SQL
+      data types and the XML Schema types are specified precisely. However, the
+      rules are expressed using the types and semantics of XQuery/XPath, and
+      have no direct application to the different data model of XPath 1.0.
+     </para>
+
+     <para>
+      When <productname>PostgreSQL</productname> maps SQL data values to XML
+      (as in <function>xmlelement</function>), or XML to SQL (as in the output
+      columns of <function>xmltable</function>), except for a few cases
+      treated specially, <productname>PostgreSQL</productname> simply assumes
+      that the XML data type's XPath 1.0 string form will be valid as the
+      text-input form of the SQL datatype, and conversely. This rule has the
+      virtue of simplicity while producing, for many data types, results similar
+      to the mappings specified in the standard. In this release,
+      an explicit cast is needed if an <function>xmltable</function> column
+      expression produces a boolean or double value; see
+      <xref linkend="functions-xml-limits-postgresql"/>.
+     </para>
+
+     <para>
+      Where interoperability with other systems is a concern, for some data
+      types, it may be necessary to use data type formatting functions (such
+      as those in <xref linkend="functions-formatting"/>) explicitly to
+      produce the standard mappings.
+     </para>
+    </sect3>
+   </sect2>
+
+   <sect2 id="functions-xml-limits-postgresql">
+    <title>
+     Incidental limits of the implementation
+    </title>
+
+    <para>
+     This section concerns limits that are not inherent in the
+     <application>libxml2</application> library, but apply to the current
+     implementation in <productname>PostgreSQL</productname>.
+    </para>
+
+    <sect3>
+     <title>
+      Cast needed for <function>xmltable</function> column
+      of boolean or double type
+     </title>
+
+     <para>
+      An <function>xmltable</function> column expression evaluating to an XPath
+      boolean or number result will produce an <quote>unexpected XPath object
+      type</quote> error. The workaround is to rewrite the column expression to
+      be inside the XPath <function>string</function> function;
+      <productname>PostgreSQL</productname> will then assign the string value
+      successfully to an SQL output column of boolean or double type.
+     </para>
+    </sect3>
+
+    <sect3>
+     <title>
+      Column path result or SQL result column of XML type
+     </title>
+
+     <para>
+      In this release, a <function>xmltable</function> column expression
+      that evaluates to an XML node-set can be assigned to an SQL result
+      column of XML type, producing a concatenation of: for most types of
+      node in the node-set, a text node containing the XPath 1.0
+      <firstterm>string-value</firstterm> of the node, but for an element node,
+      a copy of the node itself. Such a node-set may be assigned to an SQL
+      column of non-XML type only if the node-set has a single node, with the
+      string-value of most node types replaced with an empty string, the
+      string-value of an element node replaced with a concatenation of only its
+      direct text-node children (excluding those of descendants), and the
+      string-value of a text or attribute node being as defined in XPath 1.0.
+      An XPath string value assigned to a result column of XML type must be
+      parsable as XML.
+     </para>
+
+     <para>
+      It is best not to develop code that relies on these behaviors, which have
+      little resemblance to the spec, and are changed in
+      <productname>PostgreSQL 12</productname>.
+     </para>
+    </sect3>
+
+    <sect3>
+     <title>Only <literal>BY VALUE</literal> passing mechanism is supported</title>
+
+     <para>
+      The SQL standard defines two <firstterm>passing mechanisms</firstterm>
+      that apply when passing an XML argument from SQL to an XML function or
+      receiving a result: <literal>BY REF</literal>, in which a particular XML
+      value retains its node identity, and <literal>BY VALUE</literal>, in which
+      the content of the XML is passed but node identity is not preserved. A
+      mechanism can be specified before a list of parameters, as the default
+      mechanism for all of them, or after any parameter, to override the
+      default.
+     </para>
+
+     <para>
+      To illustrate the difference, if
+      <replaceable>x</replaceable> is an XML value, these two queries in
+      an SQL:2006 environment would produce true and false, respectively:
+
+<programlisting>
+SELECT XMLQUERY('$a is $b' PASSING BY REF <replaceable>x</replaceable> AS a, <replaceable>x</replaceable> AS b NULL ON EMPTY);
+SELECT XMLQUERY('$a is $b' PASSING BY VALUE <replaceable>x</replaceable> AS a, <replaceable>x</replaceable> AS b NULL ON EMPTY);
+</programlisting>
+     </para>
+
+     <para>
+      In this release, <productname>PostgreSQL</productname> will accept
+      <literal>BY REF</literal> in an
+      <function>XMLEXISTS</function> or <function>XMLTABLE</function>
+      construct, but will ignore it.  The <type>xml</type> data type holds
+      a character-string serialized representation, so there is no node
+      identity to preserve, and passing is always effectively <literal>BY
+      VALUE</literal>.
+     </para>
+    </sect3>
+
+    <sect3>
+     <title>Cannot pass named parameters to queries</title>
+
+     <para>
+      The XPath-based functions support passing one parameter to serve as the
+      XPath expression's context item, but do not support passing additional
+      values to be available to the expression as named parameters.
+     </para>
+    </sect3>
+
+    <sect3>
+     <title>No <type>XML(SEQUENCE)</type> type</title>
+
+     <para>
+      The <productname>PostgreSQL</productname> <type>xml</type> data type
+      can only hold a value in <literal>DOCUMENT</literal>
+      or <literal>CONTENT</literal> form.  An XQuery/XPath expression
+      context item must be a single XML node or atomic value, but XPath 1.0
+      further restricts it to be only an XML node, and has no node type
+      allowing <literal>CONTENT</literal>.  The upshot is that a
+      well-formed <literal>DOCUMENT</literal> is the only form of XML value
+      that <productname>PostgreSQL</productname> can supply as an XPath
+      context item.
+     </para>
+    </sect3>
+   </sect2>
+  </sect1>
+
  </appendix>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 198f9c2..a7514c0 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -9903,17 +9903,26 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
 
 
  <sect1 id="functions-xml">
+
   <title>XML Functions</title>
 
+  <indexterm>
+   <primary>XML Functions</primary>
+  </indexterm>
+
   <para>
    The functions and function-like expressions described in this
-   section operate on values of type <type>xml</type>.  Check <xref
-   linkend="datatype-xml"> for information about the <type>xml</type>
+   section operate on values of type <type>xml</type>.  See <xref
+   linkend="datatype-xml"/> for information about the <type>xml</type>
    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 most of these
-   functions requires the installation to have been built
-   with <command>configure --with-libxml</>.
+   type <type>xml</type> are documented there, not in this section.
+  </para>
+
+  <para>
+   Use of most of these functions
+   requires <productname>PostgreSQL</productname> to have been built
+   with <command>configure --with-libxml</command>.
   </para>
 
   <sect2 id="functions-producing-xml">
@@ -10107,8 +10116,8 @@ SELECT xmlelement(name foo, xmlattributes('xyz' as bar),
      encoding, depending on the setting of the configuration parameter
      <xref linkend="guc-xmlbinary">.  The particular behavior for
      individual data types is expected to evolve in order to align the
-     SQL and PostgreSQL data types with the XML Schema specification,
-     at which point a more precise description will appear.
+     PostgreSQL mappings with those specified in SQL:2006 and later,
+     as discussed in <xref linkend="functions-xml-limits-casts"/>.
     </para>
    </sect3>
 
@@ -10350,10 +10359,13 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
 </synopsis>
 
     <para>
-     The function <function>xmlexists</function> returns true if the
-     XPath expression in the first argument returns any nodes, and
-     false otherwise.  (If either argument is null, the result is
-     null.)
+     The function <function>xmlexists</function> evaluates an XPath 1.0
+     expression (the first argument), with the passed XML value as its context
+     item.  The function returns false if the result of that evaluation
+     yields an empty node-set, true if it yields any other value.  The
+     function returns null if any argument is null.  A nonnull value
+     passed as the context item must be an XML document, not a content
+     fragment or any non-XML value.
     </para>
 
     <para>
@@ -10369,14 +10381,14 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Tor
     </para>
 
     <para>
-     The <literal>BY REF</literal> clauses have no effect in
-     PostgreSQL, but are allowed for SQL conformance and compatibility
-     with other implementations.  Per SQL standard, the
-     first <literal>BY REF</literal> is required, the second is
-     optional.  Also note that the SQL standard specifies
-     the <function>xmlexists</function> construct to take an XQuery
-     expression as first argument, but PostgreSQL currently only
-     supports XPath, which is a subset of XQuery.
+     The <literal>BY REF</literal> clauses
+     are accepted in <productname>PostgreSQL</productname>, but are ignored,
+     as discussed in <xref linkend="functions-xml-limits-postgresql"/>.
+     In the SQL standard, the <function>xmlexists</function> function
+     evaluates an expression in the XML Query language,
+     but <productname>PostgreSQL</productname> allows only an XPath 1.0
+     expression, as discussed in
+     <xref linkend="functions-xml-limits-xpath1"/>.
     </para>
    </sect3>
 
@@ -10482,12 +10494,12 @@ SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuf
 </synopsis>
 
     <para>
-     The function <function>xpath</function> evaluates the XPath
-     expression <replaceable>xpath</replaceable> (a <type>text</> value)
+     The function <function>xpath</function> evaluates the XPath 1.0
+     expression <replaceable>xpath</replaceable> (a <type>text</type> value)
      against the XML value
      <replaceable>xml</replaceable>.  It returns an array of XML values
-     corresponding to the node set produced by the XPath expression.
-     If the XPath expression returns a scalar value rather than a node set,
+     corresponding to the node-set produced by the XPath expression.
+     If the XPath expression returns a scalar value rather than a node-set,
      a single-element array is returned.
     </para>
 
@@ -10549,9 +10561,10 @@ SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com";><b>test</b></a
     <para>
      The function <function>xpath_exists</function> is a specialized form
      of the <function>xpath</function> function.  Instead of returning the
-     individual XML values that satisfy the XPath, this function returns a
-     Boolean indicating whether the query was satisfied or not.  This
-     function is equivalent to the standard <literal>XMLEXISTS</> predicate,
+     individual XML values that satisfy the XPath 1.0 expression, this function
+     returns a Boolean indicating whether the query was satisfied or not
+     (specifically, whether it produced any value other than an empty node-set).
+     This function is equivalent to the <literal>XMLEXISTS</literal> predicate,
      except that it also offers support for a namespace mapping argument.
     </para>
 
@@ -10592,8 +10605,8 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com";>test</m
 
     <para>
      The <function>xmltable</function> function produces a table based
-     on the given XML value, an XPath filter to extract rows, and an
-     optional set of column definitions.
+     on the given XML value, an XPath filter to extract rows, and a
+     set of column definitions.
     </para>
 
     <para>
@@ -10604,30 +10617,34 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com";>test</m
     </para>
 
     <para>
-     The required <replaceable>row_expression</> argument is an XPath
-     expression that is evaluated against the supplied XML document to
-     obtain an ordered sequence of XML nodes. This sequence is what
-     <function>xmltable</> transforms into output rows.
+     The required <replaceable>row_expression</replaceable> argument is
+     an XPath 1.0 expression that is evaluated, passing the
+     <replaceable>document_expression</replaceable> as its context item, to
+     obtain a set of XML nodes. These nodes are what
+     <function>xmltable</function> transforms into output rows. No rows
+     will be produced if the <replaceable>document_expression</replaceable>
+     is null, nor if the <replaceable>row_expression</replaceable> produces
+     an empty node-set or any value other than a node-set.
     </para>
 
     <para>
-     <replaceable>document_expression</> provides the XML document to
-     operate on.
-     The <literal>BY REF</literal> clauses have no effect in PostgreSQL,
-     but are allowed for SQL conformance and compatibility with other
-     implementations.
-     The argument must be a well-formed XML document; fragments/forests
-     are not accepted.
+     <replaceable>document_expression</replaceable> provides the context
+     item for the <replaceable>row_expression</replaceable>. It must be a
+     well-formed XML document; fragments/forests are not accepted.
+     The <literal>BY REF</literal> clauses
+     are accepted but ignored, as discussed in
+     <xref linkend="functions-xml-limits-postgresql"/>.
+     In the SQL standard, the <function>xmltable</function> function
+     evaluates expressions in the XML Query language,
+     but <productname>PostgreSQL</productname> allows only XPath 1.0
+     expressions, as discussed in
+     <xref linkend="functions-xml-limits-xpath1"/>.
     </para>
 
     <para>
      The mandatory <literal>COLUMNS</literal> clause specifies the list
      of columns in the output table.
-     If the <literal>COLUMNS</> clause is omitted, the rows in the result
-     set contain a single column of type <literal>xml</> containing the
-     data matched by <replaceable>row_expression</>.
-     If <literal>COLUMNS</literal> is specified, each entry describes a
-     single column.
+     Each entry describes a single column.
      See the syntax summary above for the format.
      The column name and type are required; the path, default and
      nullability clauses are optional.
@@ -10635,48 +10652,57 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com";>test</m
 
     <para>
      A column marked <literal>FOR ORDINALITY</literal> will be populated
-     with row numbers matching the order in which the
-     output rows appeared in the original input XML document.
+     with row numbers, starting with 1, in the order of nodes retrieved from
+     the <replaceable>row_expression</replaceable>'s result node-set.
      At most one column may be marked <literal>FOR ORDINALITY</literal>.
     </para>
 
+    <note>
+     <para>
+      XPath 1.0 does not specify an order for nodes in a node-set, so code
+      that relies on a particular order of the results will be
+      implementation-dependent.  Details can be found in
+      <xref linkend="xml-xpath-1-specifics"/>.
+     </para>
+    </note>
+
     <para>
-     The <literal>column_expression</> for a column is an XPath expression
-     that is evaluated for each row, relative to the result of the
-     <replaceable>row_expression</>, to find the value of the column.
-     If no <literal>column_expression</> is given, then the column name
-     is used as an implicit path.
+     The <replaceable>column_expression</replaceable> for a column is an
+     XPath 1.0 expression that is evaluated for each row, with the current
+     node from the <replaceable>row_expression</replaceable> result as its
+     context item, to find the value of the column.  If
+     no <replaceable>column_expression</replaceable> is given, then the
+     column name is used as an implicit path.
     </para>
 
     <para>
-     If a column's XPath expression returns multiple elements, an error
-     is raised.
-     If the expression matches an empty tag, the result is an
-     empty string (not <literal>NULL</>).
-     Any <literal>xsi:nil</> attributes are ignored.
+     If a column's XPath expression returns a non-XML value (limited to
+     string, boolean, or double in XPath 1.0) and the column has a
+     PostgreSQL type other than <type>xml</type>, the column will be set
+     as if by assigning the value's string representation to the PostgreSQL
+     type. In this release, an XPath boolean or double result must be explicitly
+     cast to string (that is, the XPath 1.0 <function>string</function> function
+     wrapped around the original column expression);
+     <productname>PostgreSQL</productname> can then successfully assign the
+     string to an SQL result column of boolean or double type.
+     These conversion rules differ from those of the SQL
+     standard, as discussed in <xref linkend="functions-xml-limits-casts"/>.
     </para>
 
     <para>
-     The text body of the XML matched by the <replaceable>column_expression</>
-     is used as the column value. Multiple <literal>text()</literal> nodes
-     within an element are concatenated in order. Any child elements,
-     processing instructions, and comments are ignored, but the text contents
-     of child elements are concatenated to the result.
-     Note that the whitespace-only <literal>text()</> node between two non-text
-     elements is preserved, and that leading whitespace on a <literal>text()</>
-     node is not flattened.
+     In this release, SQL result columns of <type>xml</type> type, or
+     column XPath expressions evaluating to an XML type, regardless of the
+     output column SQL type, are handled as described in
+     <xref linkend="functions-xml-limits-postgresql"/>; the behavior
+     changes significantly in <productname>PostgreSQL 12</productname>.
     </para>
 
     <para>
-     If the path expression does not match for a given row but
-     <replaceable>default_expression</> is specified, the value resulting
-     from evaluating that expression is used.
-     If no <literal>DEFAULT</> clause is given for the column,
-     the field will be set to <literal>NULL</>.
-     It is possible for a <replaceable>default_expression</> to reference
-     the value of output columns that appear prior to it in the column list,
-     so the default of one column may be based on the value of another
-     column.
+     If the path expression returns an empty node-set
+     (typically, when it does not match)
+     for a given row, the column will be set to <literal>NULL</literal>, unless
+     a <replaceable>default_expression</replaceable> is specified; then the
+     value resulting from evaluating that expression is used.
     </para>
 
     <para>
@@ -10688,20 +10714,14 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com";>test</m
     </para>
 
     <para>
-     Unlike regular PostgreSQL functions, <replaceable>column_expression</>
-     and <replaceable>default_expression</> are not evaluated to a simple
-     value before calling the function.
-     <replaceable>column_expression</> is normally evaluated
-     exactly once per input row, and <replaceable>default_expression</>
-     is evaluated each time a default is needed for a field.
-     If the expression qualifies as stable or immutable the repeat
+     A <replaceable>default_expression</replaceable>, rather than being
+     evaluated immediately when <function>xmltable</function> is called,
+     is evaluated each time a default is needed for the column.
+     If the expression qualifies as stable or immutable, the repeat
      evaluation may be skipped.
-     Effectively <function>xmltable</> behaves more like a subquery than a
-     function call.
      This means that you can usefully use volatile functions like
-     <function>nextval</> in <replaceable>default_expression</>, and
-     <replaceable>column_expression</> may depend on other parts of the
-     XML document.
+     <function>nextval</function> in
+     <replaceable>default_expression</replaceable>.
     </para>
 
     <para>
diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt
index 8e746f3..ccd3450 100644
--- a/src/backend/catalog/sql_features.txt
+++ b/src/backend/catalog/sql_features.txt
@@ -593,7 +593,7 @@ X085	Predefined namespace prefixes			NO
 X086	XML namespace declarations in XMLTable			NO	
 X090	XML document predicate			YES	
 X091	XML content predicate			NO	
-X096	XMLExists			NO	XPath only
+X096	XMLExists			NO	XPath 1.0 only
 X100	Host language support for XML: CONTENT option			NO	
 X101	Host language support for XML: DOCUMENT option			NO	
 X110	Host language support for XML: VARCHAR mapping			NO	
@@ -661,11 +661,11 @@ X282	XMLValidate with CONTENT option			NO
 X283	XMLValidate with SEQUENCE option			NO	
 X284	XMLValidate: NAMESPACE without ELEMENT clause			NO	
 X286	XMLValidate: NO NAMESPACE with ELEMENT clause			NO	
-X300	XMLTable			NO	XPath only
+X300	XMLTable			NO	XPath 1.0 only
 X301	XMLTable: derived column list option			YES	
 X302	XMLTable: ordinality column option			YES	
 X303	XMLTable: column default option			YES	
-X304	XMLTable: passing a context item			YES	
+X304	XMLTable: passing a context item			YES	must be XML DOCUMENT
 X305	XMLTable: initializing an XQuery variable			NO	
 X400	Name and identifier mapping			YES	
 X410	Alter column data type: XML type			YES	
-- 
2.7.3

Reply via email to