Commit eaaa5986 authored by Alvaro Herrera's avatar Alvaro Herrera

Fix the BY {REF,VALUE} clause of XMLEXISTS/XMLTABLE

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
parent cb706ec4
...@@ -10583,7 +10583,7 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab; ...@@ -10583,7 +10583,7 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
</indexterm> </indexterm>
<synopsis> <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> </synopsis>
<para> <para>
...@@ -10596,7 +10596,7 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab; ...@@ -10596,7 +10596,7 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
<para> <para>
Example: Example:
<screen><![CDATA[ <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 xmlexists
------------ ------------
...@@ -10606,14 +10606,25 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Tor ...@@ -10606,14 +10606,25 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Tor
</para> </para>
<para> <para>
The <literal>BY REF</literal> clauses have no effect in The <literal>BY REF</literal> or <literal>BY VALUE</literal> clauses
PostgreSQL, but are allowed for SQL conformance and compatibility have no effect in <productname>PostgreSQL<productname>, but are allowed
with other implementations. Per SQL standard, the for compatibility with other implementations. Per the <acronym>SQL</acronym>
first <literal>BY REF</literal> is required, the second is standard, the one that precedes any argument is required, and indicates
optional. Also note that the SQL standard specifies the default for arguments that follow, and one may follow any argument to
the <function>xmlexists</function> construct to take an XQuery override the default.
expression as first argument, but PostgreSQL currently only <productname>PostgreSQL</productname> ignores <literal>BY REF</literal>
supports XPath, which is a subset of XQuery. 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> </para>
</sect3> </sect3>
...@@ -10820,7 +10831,7 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</m ...@@ -10820,7 +10831,7 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</m
<synopsis> <synopsis>
<function>xmltable</function>( <optional>XMLNAMESPACES(<replaceable>namespace uri</replaceable> AS <replaceable>namespace name</replaceable><optional>, ...</optional>), </optional> <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> 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 } | FOR ORDINALITY }
<optional>, ...</optional> <optional>, ...</optional>
...@@ -10850,11 +10861,11 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</m ...@@ -10850,11 +10861,11 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</m
<para> <para>
<replaceable>document_expression</replaceable> provides the XML document to <replaceable>document_expression</replaceable> provides the XML document to
operate on. 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 The argument must be a well-formed XML document; fragments/forests
are not accepted. 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>
<para> <para>
......
...@@ -635,8 +635,8 @@ X204 XMLQuery: initializing an XQuery variable NO ...@@ -635,8 +635,8 @@ X204 XMLQuery: initializing an XQuery variable NO
X205 XMLQuery: EMPTY ON EMPTY option NO X205 XMLQuery: EMPTY ON EMPTY option NO
X206 XMLQuery: NULL ON EMPTY option NO X206 XMLQuery: NULL ON EMPTY option NO
X211 XML 1.1 support NO X211 XML 1.1 support NO
X221 XML passing mechanism BY VALUE NO X221 XML passing mechanism BY VALUE YES
X222 XML passing mechanism BY REF 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 X231 XML(CONTENT(UNTYPED)) type NO
X232 XML(CONTENT(ANY)) type NO X232 XML(CONTENT(ANY)) type NO
X241 RETURNING CONTENT in XML publishing NO X241 RETURNING CONTENT in XML publishing NO
......
...@@ -13951,20 +13951,25 @@ xmlexists_argument: ...@@ -13951,20 +13951,25 @@ xmlexists_argument:
{ {
$$ = $2; $$ = $2;
} }
| PASSING c_expr BY REF | PASSING c_expr xml_passing_mech
{ {
$$ = $2; $$ = $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 * Aggregate decoration clauses
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment