Streamability of fold-left function in Saxon
Added by Martin Honnen over 5 years ago
Reading the spec about the streamability of the fold-left
function at https://www.w3.org/TR/xslt-30/#streamability-fn-fold-left it suggests in my interpretation that the example given there (fold-left(/*/transaction, 0, function($x as xs:decimal, $y as xs:decimal) as xs:decimal {$x+$y})
should be streamable.
However, Saxon 9.8.0.12 EE and Saxon 9.9.1.1 EE do reject such an expression as not being streamable
Error on line 12 of sheet1-spec-example.xsl:
XTSE3430: Template rule is not streamable
* Operand {element()/transaction} of {fn:fold-left(...)} selects streamed nodes in a
context that allows arbitrary navigation (line 13)
Template rule is not streamable
* Operand {element()/transaction} of {fn:fold-left(...)} selects streamed nodes in a context that allows arbitrary navigation (line 13)
Looking at the test cases for streaming and fold-left in the test suite I find a comment in there (https://github.com/w3c/xslt30-test/blob/master/tests/strm/sf-fold-left/sf-fold-left-A.xsl)
TODO: fold-left is defined in the current XSLT 3.0 draft to have the operand usage N (Navigation) making it non-streamable. This should be fixed; it should have type-determined usage based on the type of the first argument of the function provided in the third argument, if this is known. In the meantime, we explicitly atomize the sequence to be processed
and test cases seem to use e.g. fold-left(/*/transaction/data(), 0, function($x as xs:decimal, $y as xs:decimal) as xs:decimal {$x+$y})
.
As the final spec seems to have been fixed according to the "TODO" note it looks like the test cases and Saxon's implementation have not been adjusted.
Minimal test case I used:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:mode streamable="yes"/>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:sequence select="fold-left(/*/transaction, 0, function($x as xs:decimal, $y as xs:decimal) as xs:decimal {$x+$y})"/>
</xsl:template>
</xsl:stylesheet>
Replies (3)
Please register to reply
RE: Streamability of fold-left function in Saxon - Added by Michael Kay over 5 years ago
The rule does indeed appear to have been "fixed":
19.8.9.8 Streamability of the fold-left Function
The function call fold-left($seq, $zero, $f), follows the general streamability rules,
with the first argument $seq having type-determined usage based on the type of
the second argument of the function supplied as $f.
but I have to say I find the fix a bit questionable, since in the general case the type of the function supplied as $f isn't statically known. (Having said that, it's certainly common to find that the argument is known statically, and in principle the analysis could take account of this.)
RE: Streamability of fold-left function in Saxon - Added by Martin Honnen over 5 years ago
https://www.w3.org/Bugs/Public/show_bug.cgi?id=26439#c5 seems to have accepted the "fix", unfortunately I can't access https://lists.w3.org/Archives/Member/w3c-xsl-wg/2014Sep/0002.html to read up on how the concern from the comment 4 "we need to allow user-defined functions (e.g. inline functions) and it's not clear how we can constrain them suitably" was resolved or why the problem of "the type of the function supplied as $f" not being statically know was not an issue in 2014.
RE: Streamability of fold-left function in Saxon - Added by Michael Kay over 5 years ago
Sadly, I've lost access to the mailing list archives myself. I've asked W3C if there's any way of reinstating this but it's a problem: WG members decided in the early days to use a member-only list, and unlike the XQuery WG, they never switched to a public list; and (understandably) there doesn't seem to be any mechanism for making it public retroactively.
I should have anticipated this and downloaded a copy before the WG closed.
Please register to reply