From: Chapman Flack <chap@anastigmatix.net>
To: Pavel Stehule <pavel.stehule@gmail.com>
Cc: Markus Winand <markus.winand@winand.at>
Cc: Alvaro Herrera <alvherre@2ndquadrant.com>
Cc: Tom Lane <tgl@sss.pgh.pa.us>
Cc: PostgreSQL Hackers <pgsql-hackers@postgresql.org>
Subject: Re: PostgreSQL vs SQL/XML Standards
Date: Sat, 12 Jan 2019 18:38:56 -0500
Message-ID: <5C3A7A90.3070207@anastigmatix.net> (raw)
In-Reply-To: <CAFj8pRCN=0k507nTfvNQuruHvomA4SiC6uGUXY5Gz0crxf-JAQ@mail.gmail.com>
References: <CAFj8pRDFQJMoKf-X+3p1ASwU02nnXfAXrg83Z3fHUBd-Gwuuxw@mail.gmail.com>
<20181025194720.ylmw64xqlnjr5wja@alvherre.pgsql>
<CAFj8pRB10LxRcYYKWb5omjtAQq_bEVWiQ9B6V=kRZYMvM0B-_w@mail.gmail.com>
<CAFj8pRBr5tY5b=8gKptwOyuPf8f3fvyHbXNbSCU03guNh-johw@mail.gmail.com>
<CAFj8pRA6J25CtAZ2TuRvxK3gat7-bBUYh0rfE2yM7Hj9GD14Dg@mail.gmail.com>
<FB592C2F-E2F3-42FD-A342-EE41BECD3771@winand.at>
<CAFj8pRC_bi4uzE3Z-XXuGnLFPP-7cZ-zr2JhGauWm3E8K2MqEg@mail.gmail.com>
<45C74339-3531-46BD-A595-37183C6730A1@winand.at>
<CAFj8pRB4NHismecE-SnezKz9OektP2H8t_684TbqQ4Ax3swZwQ@mail.gmail.com>
<5C283168.8060001@anastigmatix.net>
<CAFj8pRDRrxyr8=2PEFxP_eZCRqJMU4Jpj0whJM9pX0V4Q4EQvw@mail.gmail.com>
<5C291741.9060506@anastigmatix.net>
<CAFj8pRAmSUO1g1qnVgXmE=7bPULYjwDfyO5KDohsHMFesDenmA@mail.gmail.com>
<5C297BB7.9070509@anastigmatix.net>
<CAFj8pRCN=0k507nTfvNQuruHvomA4SiC6uGUXY5Gz0crxf-JAQ@mail.gmail.com>
On 12/30/18 03:23, Pavel Stehule wrote:
> Unfortunately, there is a different releases of libxml2 with different
> error reporting and it is hard (impossible) to prepare for all variants. :-/
>
> I prepare xml.out for my FC29 (fresh libxml2) and for no support xml.
> Other I prepare by patching - and this error (in context) is expected.
It turns out that the variant was already accounted for in the xml_2.out
variant result file, it just needed to have the new results added.
Done in xmltable-xpath-result-processing-bugfix-4.patch attached.
On 12/31/18 01:03, Pavel Stehule wrote:
> po 31. 12. 2018 v 3:15 odesÃlatel Chapman Flack <chap@anastigmatix.net>
> napsal:
>> But the PostgreSQL situation is a little more strange. PG uses BY VALUE
>> semantics as the default when no passing method is specified. PG also uses
>> BY VALUE semantics when BY REF is explicitly requested, which is rude,
>> just like Oracle. But why should an explicit specification of BY VALUE
>> (which is, after all, the semantics we're going to use anyway!) produce
>> this?
>>
>> ERROR: syntax error at or near "value"
>>
>> To me, that doesn't seem like least astonishment.
>>
>> I am not seeing what would be complicated about removing that astonishment
>> by simply allowing the grammar productions to also consume BY VALUE and
>> ignore it.
>
> ok - I am not against implementation of ignored BY VALUE. But I don't like
> a idea to disable BY REF.
Done in attached xmltable-xmlexists-passing-mechanisms-1.patch along with
some corresponding documentation adjustments.
I am still working on more extensive documentation, but it seemed best
to include the changes related to BY REF / BY VALUE in the same patch
with the grammar change.
-Chap
Attachments:
[text/x-patch] xmltable-xpath-result-processing-bugfix-4.patch (13.4K, ../5C3A7A90.3070207@anastigmatix.net/2-xmltable-xpath-result-processing-bugfix-4.patch)
download | inline diff:diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgmlindex 90d67f1..06f3f69 100644--- a/doc/src/sgml/func.sgml+++ b/doc/src/sgml/func.sgml@@ -10999,9 +10999,9 @@ $$ AS data;
SELECT xmltable.*
FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text);
- element ------------------------ Hello2a2 bbbCC + element +-------------------------+ Hello2a2 bbbxxxCC
]]></screen>
</para>
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.cindex 1cec168..df7f0cc 100644--- a/src/backend/utils/adt/xml.c+++ b/src/backend/utils/adt/xml.c@@ -3674,15 +3674,15 @@ SPI_sql_row_to_xmlelement(uint64 rownum, StringInfo result, char *tablename,
#ifdef USE_LIBXML
/*
- * Convert XML node to text (dump subtree in case of element,- * return value otherwise)+ * Convert XML node to text (dump subtree), for attribute and text+ * returns escaped text.
*/
static text *
xml_xmlnodetoxmltype(xmlNodePtr cur, PgXmlErrorContext *xmlerrcxt)
{
xmltype *result;
- if (cur->type == XML_ELEMENT_NODE)+ if (cur->type != XML_ATTRIBUTE_NODE && cur->type != XML_TEXT_NODE)
{
xmlBufferPtr buf;
xmlNodePtr cur_copy;
@@ -4427,6 +4427,37 @@ XmlTableFetchRow(TableFuncScanState *state)
#endif /* not USE_LIBXML */
}
+#ifdef USE_LIBXML+/*+ * Copy XmlChar string to PostgreSQL memory. Ensure releasing of+ * source xmllib string.+ */+static char *+copy_and_safe_free_xmlchar(xmlChar *str)+{+ char *result;++ if (str)+ {+ PG_TRY();+ {+ result = pstrdup((char *) str);+ }+ PG_CATCH();+ {+ xmlFree(str);+ PG_RE_THROW();+ }+ PG_END_TRY();+ xmlFree(str);+ }+ else+ result = NULL;++ return result;+}+#endif+
/*
* XmlTableGetValue
* Return the value for column number 'colnum' for the current row. If
@@ -4475,9 +4506,9 @@ XmlTableGetValue(TableFuncScanState *state, int colnum,
/*
* There are four possible cases, depending on the number of nodes
* returned by the XPath expression and the type of the target column:
- * a) XPath returns no nodes. b) One node is returned, and column is- * of type XML. c) One node, column type other than XML. d) Multiple- * nodes are returned.+ * a) XPath returns no nodes. b) The target type is XML (return all+ * as XML). For non-XML types: c) One node (return content).+ * d) Multiple nodes (error).
*/
if (xpathobj->type == XPATH_NODESET)
{
@@ -4490,85 +4521,72 @@ XmlTableGetValue(TableFuncScanState *state, int colnum,
{
*isnull = true;
}
- else if (count == 1 && typid == XMLOID)- {- text *textstr;-- /* simple case, result is one value */- textstr = xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[0],- xtCxt->xmlerrcxt);- cstr = text_to_cstring(textstr);- }- else if (count == 1)+ else
{
- xmlChar *str;- xmlNodePtr node;-- /*- * Most nodes (elements and even attributes) store their data- * in children nodes. If they don't have children nodes, it- * means that they are empty (e.g. <element/>). Text nodes and- * CDATA sections are an exception: they don't have children- * but have content in the Text/CDATA node itself.- */- node = xpathobj->nodesetval->nodeTab[0];- if (node->type != XML_CDATA_SECTION_NODE &&- node->type != XML_TEXT_NODE)- node = node->xmlChildrenNode;-- str = xmlNodeListGetString(xtCxt->doc, node, 1);- if (str != NULL)+ if (typid == XMLOID)
{
- PG_TRY();- {- cstr = pstrdup((char *) str);- }- PG_CATCH();+ text *textstr;+ StringInfoData str;+ int i;++ /* Concatenate serialized values */+ initStringInfo(&str);+ for (i = 0; i < count; i++)
{
- xmlFree(str);- PG_RE_THROW();+ textstr =+ xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i],+ xtCxt->xmlerrcxt);++ appendStringInfoText(&str, textstr);
}
- PG_END_TRY();- xmlFree(str);+ cstr = str.data;
}
else
{
- /* Ensure mapping of empty tags to PostgreSQL values. */- cstr = "";- }- }- else- {- StringInfoData str;- int i;-- Assert(count > 1);+ xmlChar *str;- /*- * When evaluating the XPath expression returns multiple- * nodes, the result is the concatenation of them all. The- * target type must be XML.- */- if (typid != XMLOID)- ereport(ERROR,- (errcode(ERRCODE_CARDINALITY_VIOLATION),- errmsg("more than one value returned by column XPath expression")));+ if (count > 1)+ ereport(ERROR,+ (errcode(ERRCODE_CARDINALITY_VIOLATION),+ errmsg("more than one value returned by column XPath expression")));- /* Concatenate serialized values */- initStringInfo(&str);- for (i = 0; i < count; i++)- {- appendStringInfoText(&str,- xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i],- xtCxt->xmlerrcxt));+ str = xmlXPathCastNodeSetToString(xpathobj->nodesetval);+ if (str)+ cstr = copy_and_safe_free_xmlchar(str);+ else+ /* empty element */+ cstr = "";
}
- cstr = str.data;
}
}
else if (xpathobj->type == XPATH_STRING)
{
cstr = (char *) xpathobj->stringval;
}
+ else if (xpathobj->type == XPATH_BOOLEAN)+ {+ char typcategory;+ bool typispreferred;+ xmlChar *str;++ /* Allow implicit casting from boolean to numbers */+ get_type_category_preferred(typid, &typcategory, &typispreferred);++ if (typcategory != TYPCATEGORY_NUMERIC)+ str = xmlXPathCastBooleanToString(xpathobj->boolval);+ else+ str = xmlXPathCastNumberToString(+ xmlXPathCastBooleanToNumber(xpathobj->boolval));++ cstr = copy_and_safe_free_xmlchar(str);+ }+ else if (xpathobj->type == XPATH_NUMBER)+ {+ xmlChar *str;++ str = xmlXPathCastNumberToString(xpathobj->floatval);+ cstr = copy_and_safe_free_xmlchar(str);+ }
else
elog(ERROR, "unexpected XPath object type %u", xpathobj->type);
diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.outindex 6e1f885..bfb98e3 100644--- a/src/test/regress/expected/xml.out+++ b/src/test/regress/expected/xml.out@@ -1210,9 +1210,9 @@ SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan"
(2 rows)
SELECT * FROM xmltable('/root' passing '<root><element>a1a<!-- aaaa -->a2a<?aaaaa?> <!--z--> bbbb<x>xxx</x>cccc</element></root>' COLUMNS element text);
- element --------------------- a1aa2a bbbbcccc+ element +----------------------+ a1aa2a bbbbxxxcccc
(1 row)
SELECT * FROM xmltable('/root' passing '<root><element>a1a<!-- aaaa -->a2a<?aaaaa?> <!--z--> bbbb<x>xxx</x>cccc</element></root>' COLUMNS element text PATH 'element/text()'); -- should fail
@@ -1493,3 +1493,29 @@ SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c
14
(4 rows)
+-- XPath result can be boolean or number too+SELECT * FROM XMLTABLE('*' PASSING '<a>a</a>' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d boolean PATH '. = "a"');+ a | b | c | d +----------+---+----+---+ <a>a</a> | a | hi | t+(1 row)++SELECT * FROM XMLTABLE('*' PASSING '<a>a</a>' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d integer PATH 'string-length(.)');+ a | b | c | d +----------+---+----+---+ <a>a</a> | a | hi | 1+(1 row)++SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>' COLUMNS x xml PATH 'node()');+ x +---------------------------------------------------------------+ pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post+(1 row)++SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>' COLUMNS x xml PATH '/');+ x +----------------------------------------------------------------------+ <e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>++ +(1 row)+diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.outindex 0eba424..62b83fb 100644--- a/src/test/regress/expected/xml_1.out+++ b/src/test/regress/expected/xml_1.out@@ -1343,3 +1343,28 @@ SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c
---
(0 rows)
+-- XPath result can be boolean or number too+SELECT * FROM XMLTABLE('*' PASSING '<a>a</a>' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d boolean PATH '. = "a"');+ERROR: unsupported XML feature+LINE 1: SELECT * FROM XMLTABLE('*' PASSING '<a>a</a>' COLUMNS a xml ...+ ^+DETAIL: This functionality requires the server to be built with libxml support.+HINT: You need to rebuild PostgreSQL using --with-libxml.+SELECT * FROM XMLTABLE('*' PASSING '<a>a</a>' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d integer PATH 'string-length(.)');+ERROR: unsupported XML feature+LINE 1: SELECT * FROM XMLTABLE('*' PASSING '<a>a</a>' COLUMNS a xml ...+ ^+DETAIL: This functionality requires the server to be built with libxml support.+HINT: You need to rebuild PostgreSQL using --with-libxml.+SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>' COLUMNS x xml PATH 'node()');+ERROR: unsupported XML feature+LINE 1: SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?...+ ^+DETAIL: This functionality requires the server to be built with libxml support.+HINT: You need to rebuild PostgreSQL using --with-libxml.+SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>' COLUMNS x xml PATH '/');+ERROR: unsupported XML feature+LINE 1: SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?...+ ^+DETAIL: This functionality requires the server to be built with libxml support.+HINT: You need to rebuild PostgreSQL using --with-libxml.diff --git a/src/test/regress/expected/xml_2.out b/src/test/regress/expected/xml_2.outindex 3ec56e4..91bdbb7 100644--- a/src/test/regress/expected/xml_2.out+++ b/src/test/regress/expected/xml_2.out@@ -1190,9 +1190,9 @@ SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan"
(2 rows)
SELECT * FROM xmltable('/root' passing '<root><element>a1a<!-- aaaa -->a2a<?aaaaa?> <!--z--> bbbb<x>xxx</x>cccc</element></root>' COLUMNS element text);
- element --------------------- a1aa2a bbbbcccc+ element +----------------------+ a1aa2a bbbbxxxcccc
(1 row)
SELECT * FROM xmltable('/root' passing '<root><element>a1a<!-- aaaa -->a2a<?aaaaa?> <!--z--> bbbb<x>xxx</x>cccc</element></root>' COLUMNS element text PATH 'element/text()'); -- should fail
@@ -1473,3 +1473,29 @@ SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c
14
(4 rows)
+-- XPath result can be boolean or number too+SELECT * FROM XMLTABLE('*' PASSING '<a>a</a>' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d boolean PATH '. = "a"');+ a | b | c | d +----------+---+----+---+ <a>a</a> | a | hi | t+(1 row)++SELECT * FROM XMLTABLE('*' PASSING '<a>a</a>' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d integer PATH 'string-length(.)');+ a | b | c | d +----------+---+----+---+ <a>a</a> | a | hi | 1+(1 row)++SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>' COLUMNS x xml PATH 'node()');+ x +---------------------------------------------------------------+ pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post+(1 row)++SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>' COLUMNS x xml PATH '/');+ x +----------------------------------------------------------------------+ <e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>++ +(1 row)+diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sqlindex 3b91b56..7089fad 100644--- a/src/test/regress/sql/xml.sql+++ b/src/test/regress/sql/xml.sql@@ -595,3 +595,10 @@ INSERT INTO xmltest2 VALUES('<d><r><dc>2</dc></r></d>', 'D');
SELECT xmltable.* FROM xmltest2, LATERAL xmltable('/d/r' PASSING x COLUMNS a int PATH '' || lower(_path) || 'c');
SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c') PASSING x COLUMNS a int PATH '.');
SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c') PASSING x COLUMNS a int PATH 'x' DEFAULT ascii(_path) - 54);
++-- XPath result can be boolean or number too+SELECT * FROM XMLTABLE('*' PASSING '<a>a</a>' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d boolean PATH '. = "a"');+SELECT * FROM XMLTABLE('*' PASSING '<a>a</a>' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d integer PATH 'string-length(.)');++SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>' COLUMNS x xml PATH 'node()');+SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>' COLUMNS x xml PATH '/');
[text/x-patch] xmltable-xmlexists-passing-mechanisms-1.patch (5.8K, ../5C3A7A90.3070207@anastigmatix.net/3-xmltable-xmlexists-passing-mechanisms-1.patch)
download | inline diff:diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgmlindex 06f3f69..df0fe4d 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;
</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,22 @@ 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 PostgreSQL, but are allowed for compatibility+ with other implementations. Per 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 <literal>BY REF</literal> and passes by value always.+ </para>++ <para>+ In the SQL standard, an <function>xmlexists</function> construct first+ appears in SQL:2006, evaluates an expression in the XML Query 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.
</para>
</sect3>
@@ -10820,7 +10828,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 +10858,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>
diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txtindex aeb262a..bade0fe 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.yindex c086235..1b303d7 100644--- a/src/backend/parser/gram.y+++ b/src/backend/parser/gram.y@@ -13942,20 +13942,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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: chap@anastigmatix.net, pavel.stehule@gmail.com, markus.winand@winand.at, alvherre@2ndquadrant.com, tgl@sss.pgh.pa.us
Subject: Re: PostgreSQL vs SQL/XML Standards
In-Reply-To: <5C3A7A90.3070207@anastigmatix.net>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox