Re: PostgreSQL vs SQL/XML Standards

From: Chapman Flack <chap(at)anastigmatix(dot)net>
To: Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>
Cc: Markus Winand <markus(dot)winand(at)winand(dot)at>, Alvaro Herrera <alvherre(at)2ndquadrant(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: PostgreSQL vs SQL/XML Standards
Date: 2019-01-21 23:48:53
Message-ID: 5C465A65.4030305@anastigmatix.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

In two places in the XMLTABLE implementation (XmlTableFetchRow, iterating
through a nodeset returned by the row_expression, and XmlTableGetValue,
going through a nodeset returned by the column_expression), the iteration
proceeds in index order through xpathobj->nodesetval->nodeTab.

The same happens in the older xml_xpathobjtoxmlarray, producing the array
result of the xpath() function.

In <libxml/xpath.h> one finds this unsettling comment:

xmlNodePtr *nodeTab; /* array of nodes in no particular order */

So far, no matter what oddball XPath expressions I think up, nodeTab
does seem to end up in document order. It would be comforting to document
that, but the comment suggests it might not be guaranteed.

Are you aware of any statement I might have missed in the libxml docs,
where they commit to XPath evaluation returning a nodeset where nodeTab
has a predictable order? If there is a statement to that effect somewhere,
it might be worth citing in a comment in xml.c.

Regards,
-Chap

Here is a fairly oddball query, generating an XML document with about
3k names in descending order, partitioning those elements into subsets
having the same second character of the name, and unioning those back
together. You'd sort of expect that to produce a result nodeTab in goofy
order if anything could, but no, the results seem verifiably in descending
order every time, suggesting the result nodeTab is indeed being put
in document order before the XPath evaluator returns. If only they would
document that.

WITH nodeset_order_check(name, prev_name) AS (
SELECT
x, lag(x) OVER (ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
FROM
(SELECT
string_agg(DISTINCT
'x/n[substring(.,2,1) = "' || substring(proname from 2 for 1) || '"]',
'|')
FROM pg_proc) AS rowx(rowx),
(SELECT
XMLELEMENT(NAME x,
XMLAGG(XMLELEMENT(NAME n, proname) ORDER BY proname DESC))
FROM pg_proc) AS src(src),
XMLTABLE(rowx PASSING src COLUMNS x text PATH '.')
)
SELECT every(prev_name >= name IS NOT FALSE) FROM nodeset_order_check;
every
-------
t
(1 row)

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message David Rowley 2019-01-21 23:51:47 Re: RelationGetIndexAttrBitmap() small deviation between comment and code
Previous Message Andres Freund 2019-01-21 23:42:49 Re: should ConstraintRelationId ins/upd cause relcache invals?