mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Fix minor deficiencies in XMLTABLE, xpath(), xmlexists()
Correctly process nodes of more types than previously. In some cases, nodes were being ignored (nothing was output); in other cases, trying to return them resulted in errors about unrecognized nodes. In yet other cases, necessary escaping (of XML special characters) was not being done. Fix all those (as far as the authors could find) and add regression tests cases verifying the new behavior. I (Álvaro) was of two minds about backpatching these changes. They do seem bugfixes that would benefit most users of the affected functions; but on the other hand it would change established behavior in minor releases, so it seems prudent not to. Authors: Pavel Stehule, Markus Winand, Chapman Flack Discussion: https://postgr.es/m/CAFj8pRA6J25CtAZ2TuRvxK3gat7-bBUYh0rfE2yM7Hj9GD14Dg@mail.gmail.com https://postgr.es/m/8BDB0627-2105-4564-AA76-7849F028B96E@winand.at The elephant in the room as pointed out by Chapman Flack, not fixed in this commit, is that we still have XMLTABLE operating on XPath 1.0 instead of the standard-mandated XQuery (or even its subset XPath 2.0). Fixing that is a major undertaking, however.
This commit is contained in:
@ -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,24 @@ 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"', e integer PATH 'string-length(.)');
|
||||
a | b | c | d | e
|
||||
----------+---+----+---+---
|
||||
<a>a</a> | a | hi | t | 1
|
||||
(1 row)
|
||||
|
||||
\x
|
||||
SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>' COLUMNS x xml PATH 'node()', y xml PATH '/');
|
||||
-[ RECORD 1 ]-----------------------------------------------------------
|
||||
x | pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post
|
||||
y | <e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>+
|
||||
|
|
||||
|
||||
\x
|
||||
SELECT * FROM XMLTABLE('.' PASSING XMLELEMENT(NAME a) columns a varchar(20) PATH '"<foo/>"', b xml PATH '"<foo/>"');
|
||||
a | b
|
||||
--------+--------------
|
||||
<foo/> | <foo/>
|
||||
(1 row)
|
||||
|
||||
|
@ -1343,3 +1343,22 @@ 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"', e 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.
|
||||
\x
|
||||
SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>' COLUMNS x xml PATH 'node()', y 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.
|
||||
\x
|
||||
SELECT * FROM XMLTABLE('.' PASSING XMLELEMENT(NAME a) columns a varchar(20) PATH '"<foo/>"', b xml PATH '"<foo/>"');
|
||||
ERROR: unsupported XML feature
|
||||
DETAIL: This functionality requires the server to be built with libxml support.
|
||||
HINT: You need to rebuild PostgreSQL using --with-libxml.
|
||||
|
@ -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,24 @@ 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"', e integer PATH 'string-length(.)');
|
||||
a | b | c | d | e
|
||||
----------+---+----+---+---
|
||||
<a>a</a> | a | hi | t | 1
|
||||
(1 row)
|
||||
|
||||
\x
|
||||
SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>' COLUMNS x xml PATH 'node()', y xml PATH '/');
|
||||
-[ RECORD 1 ]-----------------------------------------------------------
|
||||
x | pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post
|
||||
y | <e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>+
|
||||
|
|
||||
|
||||
\x
|
||||
SELECT * FROM XMLTABLE('.' PASSING XMLELEMENT(NAME a) columns a varchar(20) PATH '"<foo/>"', b xml PATH '"<foo/>"');
|
||||
a | b
|
||||
--------+--------------
|
||||
<foo/> | <foo/>
|
||||
(1 row)
|
||||
|
||||
|
@ -595,3 +595,11 @@ 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"', e integer PATH 'string-length(.)');
|
||||
\x
|
||||
SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n2>&deep</n2>post</e>' COLUMNS x xml PATH 'node()', y xml PATH '/');
|
||||
\x
|
||||
|
||||
SELECT * FROM XMLTABLE('.' PASSING XMLELEMENT(NAME a) columns a varchar(20) PATH '"<foo/>"', b xml PATH '"<foo/>"');
|
||||
|
Reference in New Issue
Block a user