Fix the BY {REF,VALUE} clause of XMLEXISTS/XMLTABLE
authorAlvaro Herrera <[email protected]>
Thu, 7 Mar 2019 14:17:09 +0000 (11:17 -0300)
committerAlvaro Herrera <[email protected]>
Thu, 7 Mar 2019 14:20:35 +0000 (11:20 -0300)
This clause is used to indicate the passing mode of a XML document, but
we were doing it wrong: we accepted BY REF and ignored it, and rejected
BY VALUE as a syntax error.  The reality, however, is that documents are
always passed BY VALUE, so rejecting that clause was silly.  Change
things so that we accept BY VALUE.

BY REF continues to be accepted, and continues to be ignored.

Author: Chapman Flack
Reviewed-by: Pavel Stehule
Discussion: https://postgr.es/m/5C297BB7.9070509@anastigmatix.net

doc/src/sgml/func.sgml
src/backend/catalog/sql_features.txt
src/backend/parser/gram.y

index 6765b0d584c8a76e51664bbe83fcf5bd3c3ba6e7..774d5b3fce19ece5ce5fe9fee97b5a94385b717b 100644 (file)
@@ -10583,7 +10583,7 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
     </indexterm>
 
 <synopsis>
-<function>XMLEXISTS</function>(<replaceable>text</replaceable> PASSING <optional>BY REF</optional> <replaceable>xml</replaceable> <optional>BY REF</optional>)
+<function>XMLEXISTS</function>(<replaceable>text</replaceable> PASSING <optional>BY { REF | VALUE }</optional> <replaceable>xml</replaceable> <optional>BY { REF | VALUE }</optional>)
 </synopsis>
 
     <para>
@@ -10596,7 +10596,7 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
     <para>
      Example:
      <screen><![CDATA[
-SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Toronto</town><town>Ottawa</town></towns>');
+SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE '<towns><town>Toronto</town><town>Ottawa</town></towns>');
 
  xmlexists
 ------------
@@ -10606,14 +10606,25 @@ 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> or <literal>BY VALUE</literal> clauses
+     have no effect in <productname>PostgreSQL<productname>, but are allowed
+     for compatibility with other implementations.  Per the <acronym>SQL</acronym>
+     standard, the one that precedes any argument is required, and indicates
+     the default for arguments that follow, and one may follow any argument to
+     override the default.
+     <productname>PostgreSQL</productname> ignores <literal>BY REF</literal>
+     and passes by value always.
+    </para>
+
+    <para>
+     In the <acronym>SQL</acronym> standard, an <function>xmlexists</function>
+     construct evaluates an expression in the XQuery language, allows passing
+     values for named parameters in the expression as well as for the context
+     item, and does not require the passed values to be documents, or even of
+     XML type.
+     In <productname>PostgreSQL</productname>, this construct currently only
+     evaluates an XPath 1.0 expression, and allows passing only one value,
+     which must be an XML document, to be the context item.
     </para>
    </sect3>
 
@@ -10820,7 +10831,7 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</m
 
 <synopsis>
 <function>xmltable</function>( <optional>XMLNAMESPACES(<replaceable>namespace uri</replaceable> AS <replaceable>namespace name</replaceable><optional>, ...</optional>), </optional>
-          <replaceable>row_expression</replaceable> PASSING <optional>BY REF</optional> <replaceable>document_expression</replaceable> <optional>BY REF</optional>
+          <replaceable>row_expression</replaceable> PASSING <optional>BY { REF | VALUE }</optional> <replaceable>document_expression</replaceable> <optional>BY { REF | VALUE }</optional>
           COLUMNS <replaceable>name</replaceable> { <replaceable>type</replaceable> <optional>PATH <replaceable>column_expression</replaceable></optional> <optional>DEFAULT <replaceable>default_expression</replaceable></optional> <optional>NOT NULL | NULL</optional>
                         | FOR ORDINALITY }
                    <optional>, ...</optional>
@@ -10850,11 +10861,11 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</m
     <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.
+     The <literal>BY REF</literal> or <literal>BY VALUE</literal> clauses are
+     accepted, as described for the <function>xmlexists</function> predicate,
+     but ignored; PostgreSQL currently passes XML by value always.
     </para>
 
     <para>
index aeb262a5b0e108796da2785084b4aebe1875545e..bade0fe9aebdd267af2ce3f3788986a97e015e78 100644 (file)
@@ -635,8 +635,8 @@ X204    XMLQuery: initializing an XQuery variable           NO
 X205   XMLQuery: EMPTY ON EMPTY option         NO  
 X206   XMLQuery: NULL ON EMPTY option          NO  
 X211   XML 1.1 support         NO  
-X221   XML passing mechanism BY VALUE          NO  
-X222   XML passing mechanism BY REF            YES 
+X221   XML passing mechanism BY VALUE          YES 
+X222   XML passing mechanism BY REF            NO  parser accepts BY REF but ignores it; passing is always BY VALUE
 X231   XML(CONTENT(UNTYPED)) type          NO  
 X232   XML(CONTENT(ANY)) type          NO  
 X241   RETURNING CONTENT in XML publishing         NO  
index 753af6073f35e5d37428314beaaf805e46d542a5..e23e68fdb332caa2b48c430a4242e871446a3f85 100644 (file)
@@ -13951,20 +13951,25 @@ xmlexists_argument:
                {
                    $$ = $2;
                }
-           | PASSING c_expr BY REF
+           | PASSING c_expr xml_passing_mech
                {
                    $$ = $2;
                }
-           | PASSING BY REF c_expr
+           | PASSING xml_passing_mech c_expr
                {
-                   $$ = $4;
+                   $$ = $3;
                }
-           | PASSING BY REF c_expr BY REF
+           | PASSING xml_passing_mech c_expr xml_passing_mech
                {
-                   $$ = $4;
+                   $$ = $3;
                }
        ;
 
+xml_passing_mech:
+           BY REF
+           | BY VALUE_P
+       ;
+
 
 /*
  * Aggregate decoration clauses