From eaaa5986ad03f7871fa95878460e1132cb7e8963 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Thu, 7 Mar 2019 11:17:09 -0300 Subject: [PATCH] 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 --- doc/src/sgml/func.sgml | 39 ++++++++++++++++++---------- src/backend/catalog/sql_features.txt | 4 +-- src/backend/parser/gram.y | 15 +++++++---- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 6765b0d584c..774d5b3fce1 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -10583,7 +10583,7 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab; -XMLEXISTS(text PASSING BY REF xml BY REF) +XMLEXISTS(text PASSING BY { REF | VALUE } xml BY { REF | VALUE }) @@ -10596,7 +10596,7 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab; Example: TorontoOttawa'); +SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE 'TorontoOttawa'); xmlexists ------------ @@ -10606,14 +10606,25 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF 'Tor - The BY REF clauses have no effect in - PostgreSQL, but are allowed for SQL conformance and compatibility - with other implementations. Per SQL standard, the - first BY REF is required, the second is - optional. Also note that the SQL standard specifies - the xmlexists construct to take an XQuery - expression as first argument, but PostgreSQL currently only - supports XPath, which is a subset of XQuery. + The BY REF or BY VALUE clauses + have no effect in PostgreSQL, but are allowed + for compatibility with other implementations. Per the SQL + 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. + PostgreSQL ignores BY REF + and passes by value always. + + + + In the SQL standard, an xmlexists + 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 PostgreSQL, 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. @@ -10820,7 +10831,7 @@ SELECT xpath_exists('/my:a/text()', 'test xmltable( XMLNAMESPACES(namespace uri AS namespace name, ...), - row_expression PASSING BY REF document_expression BY REF + row_expression PASSING BY { REF | VALUE } document_expression BY { REF | VALUE } COLUMNS name { type PATH column_expression DEFAULT default_expression NOT NULL | NULL | FOR ORDINALITY } , ... @@ -10850,11 +10861,11 @@ SELECT xpath_exists('/my:a/text()', 'test document_expression provides the XML document to operate on. - The BY REF 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 BY REF or BY VALUE clauses are + accepted, as described for the xmlexists predicate, + but ignored; PostgreSQL currently passes XML by value always. diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt index aeb262a5b0e..bade0fe9aeb 100644 --- a/src/backend/catalog/sql_features.txt +++ b/src/backend/catalog/sql_features.txt @@ -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 diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 753af6073f3..e23e68fdb33 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -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 -- 2.39.5