Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite474c2b

Browse files
committed
Set correct context for XPath evaluation
According to the SQL standard, the context of XMLTABLE's XPathrow_expression is the document node of the XML input document, not theroot node. This becomes visible when a relative path rather thanabsolute is used as row expression. Absolute paths is what was used inoriginal tests and docs (and the most common form used in examplesthroughout the interwebs), which explains why this wasn't noticedbefore.Other functions such as xpath() and xpath_exists() also have thisproblem. While not specified by the SQL standard, it would be prettyodd to leave those functions to behave differently than XMLTABLE, sochange them too. However, this is a backwards-incompatible change.No backpatch, out of fear of breaking code depending on the originalbroken behavior.Author: Markus WinandReported-By: Markus WinandReviewed-by: Álvaro HerreraDiscussion:https://postgr.es/m/0684A598-002C-42A2-AE12-F024A324EAE4@winand.at
1 parent425b4c0 commite474c2b

File tree

5 files changed

+27
-14
lines changed

5 files changed

+27
-14
lines changed

‎src/backend/utils/adt/xml.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3934,10 +3934,7 @@ xpath_internal(text *xpath_expr_text, xmltype *data, ArrayType *namespaces,
39343934
if (xpathctx==NULL||xmlerrcxt->err_occurred)
39353935
xml_ereport(xmlerrcxt,ERROR,ERRCODE_OUT_OF_MEMORY,
39363936
"could not allocate XPath context");
3937-
xpathctx->node=xmlDocGetRootElement(doc);
3938-
if (xpathctx->node==NULL||xmlerrcxt->err_occurred)
3939-
xml_ereport(xmlerrcxt,ERROR,ERRCODE_INTERNAL_ERROR,
3940-
"could not find root XML element");
3937+
xpathctx->node= (xmlNodePtr)doc;
39413938

39423939
/* register namespaces, if any */
39433940
if (ns_count>0)
@@ -4276,10 +4273,7 @@ XmlTableSetDocument(TableFuncScanState *state, Datum value)
42764273
if (xpathcxt==NULL||xtCxt->xmlerrcxt->err_occurred)
42774274
xml_ereport(xtCxt->xmlerrcxt,ERROR,ERRCODE_OUT_OF_MEMORY,
42784275
"could not allocate XPath context");
4279-
xpathcxt->node=xmlDocGetRootElement(doc);
4280-
if (xpathcxt->node==NULL||xtCxt->xmlerrcxt->err_occurred)
4281-
xml_ereport(xtCxt->xmlerrcxt,ERROR,ERRCODE_INTERNAL_ERROR,
4282-
"could not find root XML element");
4276+
xpathcxt->node= (xmlNodePtr)doc;
42834277
}
42844278
PG_CATCH();
42854279
{

‎src/test/regress/expected/xml.out

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,12 @@ SELECT xpath('/nosuchtag', '<root/>');
670670
{}
671671
(1 row)
672672

673+
SELECT xpath('root', '<root/>');
674+
xpath
675+
-----------
676+
{<root/>}
677+
(1 row)
678+
673679
-- Round-trip non-ASCII data through xpath().
674680
DO $$
675681
DECLARE
@@ -1212,7 +1218,7 @@ SELECT * FROM xmltable('/root' passing '<root><element>a1a<!-- aaaa -->a2a<?aaaa
12121218
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
12131219
ERROR: more than one value returned by column XPath expression
12141220
-- CDATA test
1215-
select * from xmltable('r' passing '<d><r><c><![CDATA[<hello> &"<>!<a>foo</a>]]></c></r><r><c>2</c></r></d>' columns c text);
1221+
select * from xmltable('d/r' passing '<d><r><c><![CDATA[<hello> &"<>!<a>foo</a>]]></c></r><r><c>2</c></r></d>' columns c text);
12161222
c
12171223
-------------------------
12181224
<hello> &"<>!<a>foo</a>

‎src/test/regress/expected/xml_1.out

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,12 @@ LINE 1: SELECT xpath('/nosuchtag', '<root/>');
576576
^
577577
DETAIL: This functionality requires the server to be built with libxml support.
578578
HINT: You need to rebuild PostgreSQL using --with-libxml.
579+
SELECT xpath('root', '<root/>');
580+
ERROR: unsupported XML feature
581+
LINE 1: SELECT xpath('root', '<root/>');
582+
^
583+
DETAIL: This functionality requires the server to be built with libxml support.
584+
HINT: You need to rebuild PostgreSQL using --with-libxml.
579585
-- Round-trip non-ASCII data through xpath().
580586
DO $$
581587
DECLARE
@@ -1067,10 +1073,10 @@ LINE 1: SELECT * FROM xmltable('/root' passing '<root><element>a1a<!...
10671073
DETAIL: This functionality requires the server to be built with libxml support.
10681074
HINT: You need to rebuild PostgreSQL using --with-libxml.
10691075
-- CDATA test
1070-
select * from xmltable('r' passing '<d><r><c><![CDATA[<hello> &"<>!<a>foo</a>]]></c></r><r><c>2</c></r></d>' columns c text);
1076+
select * from xmltable('d/r' passing '<d><r><c><![CDATA[<hello> &"<>!<a>foo</a>]]></c></r><r><c>2</c></r></d>' columns c text);
10711077
ERROR: unsupported XML feature
1072-
LINE 1: select * from xmltable('r' passing '<d><r><c><![CDATA[<hello...
1073-
^
1078+
LINE 1: select * from xmltable('d/r' passing '<d><r><c><![CDATA[<hel...
1079+
^
10741080
DETAIL: This functionality requires the server to be built with libxml support.
10751081
HINT: You need to rebuild PostgreSQL using --with-libxml.
10761082
-- XML builtin entities

‎src/test/regress/expected/xml_2.out

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,12 @@ SELECT xpath('/nosuchtag', '<root/>');
650650
{}
651651
(1 row)
652652

653+
SELECT xpath('root', '<root/>');
654+
xpath
655+
-----------
656+
{<root/>}
657+
(1 row)
658+
653659
-- Round-trip non-ASCII data through xpath().
654660
DO $$
655661
DECLARE
@@ -1192,7 +1198,7 @@ SELECT * FROM xmltable('/root' passing '<root><element>a1a<!-- aaaa -->a2a<?aaaa
11921198
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
11931199
ERROR: more than one value returned by column XPath expression
11941200
-- CDATA test
1195-
select * from xmltable('r' passing '<d><r><c><![CDATA[<hello> &"<>!<a>foo</a>]]></c></r><r><c>2</c></r></d>' columns c text);
1201+
select * from xmltable('d/r' passing '<d><r><c><![CDATA[<hello> &"<>!<a>foo</a>]]></c></r><r><c>2</c></r></d>' columns c text);
11961202
c
11971203
-------------------------
11981204
<hello> &"<>!<a>foo</a>

‎src/test/regress/sql/xml.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ SELECT xpath('count(//*)=0', '<root><sub/><sub/></root>');
188188
SELECT xpath('count(//*)=3','<root><sub/><sub/></root>');
189189
SELECT xpath('name(/*)','<root><sub/><sub/></root>');
190190
SELECT xpath('/nosuchtag','<root/>');
191+
SELECT xpath('root','<root/>');
191192

192193
-- Round-trip non-ASCII data through xpath().
193194
DO $$
@@ -423,7 +424,7 @@ SELECT * FROM xmltable('/root' passing '<root><element>a1a<!-- aaaa -->a2a<?aaaa
423424
SELECT*FROM xmltable('/root' passing'<root><element>a1a<!-- aaaa -->a2a<?aaaaa?> <!--z--> bbbb<x>xxx</x>cccc</element></root>' COLUMNS elementtextPATH'element/text()');-- should fail
424425

425426
-- CDATA test
426-
select*from xmltable('r' passing'<d><r><c><![CDATA[<hello> &"<>!<a>foo</a>]]></c></r><r><c>2</c></r></d>' columns ctext);
427+
select*from xmltable('d/r' passing'<d><r><c><![CDATA[<hello> &"<>!<a>foo</a>]]></c></r><r><c>2</c></r></d>' columns ctext);
427428

428429
-- XML builtin entities
429430
SELECT*FROM xmltable('/x/a' PASSING'<x><a><ent>&apos;</ent></a><a><ent>&quot;</ent></a><a><ent>&amp;</ent></a><a><ent>&lt;</ent></a><a><ent>&gt;</ent></a></x>' COLUMNS enttext);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp