Skip to content

Commit eaaa598

Browse files
committed
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
1 parent cb706ec commit eaaa598

File tree

3 files changed

+37
-21
lines changed

3 files changed

+37
-21
lines changed

doc/src/sgml/func.sgml

+25-14
Original file line numberDiff line numberDiff line change
@@ -10583,7 +10583,7 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
1058310583
</indexterm>
1058410584

1058510585
<synopsis>
10586-
<function>XMLEXISTS</function>(<replaceable>text</replaceable> PASSING <optional>BY REF</optional> <replaceable>xml</replaceable> <optional>BY REF</optional>)
10586+
<function>XMLEXISTS</function>(<replaceable>text</replaceable> PASSING <optional>BY { REF | VALUE }</optional> <replaceable>xml</replaceable> <optional>BY { REF | VALUE }</optional>)
1058710587
</synopsis>
1058810588

1058910589
<para>
@@ -10596,7 +10596,7 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
1059610596
<para>
1059710597
Example:
1059810598
<screen><![CDATA[
10599-
SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Toronto</town><town>Ottawa</town></towns>');
10599+
SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE '<towns><town>Toronto</town><town>Ottawa</town></towns>');
1060010600

1060110601
xmlexists
1060210602
------------
@@ -10606,14 +10606,25 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Tor
1060610606
</para>
1060710607

1060810608
<para>
10609-
The <literal>BY REF</literal> clauses have no effect in
10610-
PostgreSQL, but are allowed for SQL conformance and compatibility
10611-
with other implementations. Per SQL standard, the
10612-
first <literal>BY REF</literal> is required, the second is
10613-
optional. Also note that the SQL standard specifies
10614-
the <function>xmlexists</function> construct to take an XQuery
10615-
expression as first argument, but PostgreSQL currently only
10616-
supports XPath, which is a subset of XQuery.
10609+
The <literal>BY REF</literal> or <literal>BY VALUE</literal> clauses
10610+
have no effect in <productname>PostgreSQL<productname>, but are allowed
10611+
for compatibility with other implementations. Per the <acronym>SQL</acronym>
10612+
standard, the one that precedes any argument is required, and indicates
10613+
the default for arguments that follow, and one may follow any argument to
10614+
override the default.
10615+
<productname>PostgreSQL</productname> ignores <literal>BY REF</literal>
10616+
and passes by value always.
10617+
</para>
10618+
10619+
<para>
10620+
In the <acronym>SQL</acronym> standard, an <function>xmlexists</function>
10621+
construct evaluates an expression in the XQuery language, allows passing
10622+
values for named parameters in the expression as well as for the context
10623+
item, and does not require the passed values to be documents, or even of
10624+
XML type.
10625+
In <productname>PostgreSQL</productname>, this construct currently only
10626+
evaluates an XPath 1.0 expression, and allows passing only one value,
10627+
which must be an XML document, to be the context item.
1061710628
</para>
1061810629
</sect3>
1061910630

@@ -10820,7 +10831,7 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</m
1082010831

1082110832
<synopsis>
1082210833
<function>xmltable</function>( <optional>XMLNAMESPACES(<replaceable>namespace uri</replaceable> AS <replaceable>namespace name</replaceable><optional>, ...</optional>), </optional>
10823-
<replaceable>row_expression</replaceable> PASSING <optional>BY REF</optional> <replaceable>document_expression</replaceable> <optional>BY REF</optional>
10834+
<replaceable>row_expression</replaceable> PASSING <optional>BY { REF | VALUE }</optional> <replaceable>document_expression</replaceable> <optional>BY { REF | VALUE }</optional>
1082410835
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>
1082510836
| FOR ORDINALITY }
1082610837
<optional>, ...</optional>
@@ -10850,11 +10861,11 @@ SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</m
1085010861
<para>
1085110862
<replaceable>document_expression</replaceable> provides the XML document to
1085210863
operate on.
10853-
The <literal>BY REF</literal> clauses have no effect in PostgreSQL,
10854-
but are allowed for SQL conformance and compatibility with other
10855-
implementations.
1085610864
The argument must be a well-formed XML document; fragments/forests
1085710865
are not accepted.
10866+
The <literal>BY REF</literal> or <literal>BY VALUE</literal> clauses are
10867+
accepted, as described for the <function>xmlexists</function> predicate,
10868+
but ignored; PostgreSQL currently passes XML by value always.
1085810869
</para>
1085910870

1086010871
<para>

src/backend/catalog/sql_features.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -635,8 +635,8 @@ X204 XMLQuery: initializing an XQuery variable NO
635635
X205 XMLQuery: EMPTY ON EMPTY option NO
636636
X206 XMLQuery: NULL ON EMPTY option NO
637637
X211 XML 1.1 support NO
638-
X221 XML passing mechanism BY VALUE NO
639-
X222 XML passing mechanism BY REF YES
638+
X221 XML passing mechanism BY VALUE YES
639+
X222 XML passing mechanism BY REF NO parser accepts BY REF but ignores it; passing is always BY VALUE
640640
X231 XML(CONTENT(UNTYPED)) type NO
641641
X232 XML(CONTENT(ANY)) type NO
642642
X241 RETURNING CONTENT in XML publishing NO

src/backend/parser/gram.y

+10-5
Original file line numberDiff line numberDiff line change
@@ -13951,20 +13951,25 @@ xmlexists_argument:
1395113951
{
1395213952
$$ = $2;
1395313953
}
13954-
| PASSING c_expr BY REF
13954+
| PASSING c_expr xml_passing_mech
1395513955
{
1395613956
$$ = $2;
1395713957
}
13958-
| PASSING BY REF c_expr
13958+
| PASSING xml_passing_mech c_expr
1395913959
{
13960-
$$ = $4;
13960+
$$ = $3;
1396113961
}
13962-
| PASSING BY REF c_expr BY REF
13962+
| PASSING xml_passing_mech c_expr xml_passing_mech
1396313963
{
13964-
$$ = $4;
13964+
$$ = $3;
1396513965
}
1396613966
;
1396713967

13968+
xml_passing_mech:
13969+
BY REF
13970+
| BY VALUE_P
13971+
;
13972+
1396813973

1396913974
/*
1397013975
* Aggregate decoration clauses

0 commit comments

Comments
 (0)