[Bug 29153] New: [XSLT30] have we created a loop-hole with windowed streaming and copy-of or snapshot?

https://www.w3.org/Bugs/Public/show_bug.cgi?id=29153

            Bug ID: 29153
           Summary: [XSLT30] have we created a loop-hole with windowed
                    streaming and copy-of or snapshot?
           Product: XPath / XQuery / XSLT
           Version: Last Call drafts
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: normal
          Priority: P2
         Component: XSLT 3.0
          Assignee: mike@saxonica.com
          Reporter: abel.braaksma@xs4all.nl
        QA Contact: public-qt-comments@w3.org
  Target Milestone: ---

This follows from the discussion in bug 29120, comment 4, where Michael wrote:

> <xsl:for-each select="copy-of(/*/transaction)">
>   <xsl:value-of select="last()"/>
> </xsl:for-each>

> Here last() is allowed because the context posture is grounded. But we have 
> the same problem, that in effect we have to materialize the entire result of 
> copy-of(), rather than pipelining it one item at a time. 

This does not pose a problem, because the whole argument will be consumed by
copy-of(), but what if you rewrite this as the following, where the
"consumation" should happen one element at a time?

<xsl:for-each select="/*/transaction/copy-of(.)">
  <xsl:value-of select="last()"/>
</xsl:for-each>

This is the "suggested" way of writing windowed streaming. Since we take a copy
each time, the xsl:for-each gets a grounded posture. But the problem is not
just with copy-of:

<xsl:for-each select="for $x in */* return string(*)">
  <xsl:value-of select="last()"/>
</xsl:for-each>

Which, imo, also suggests that the user intends to stream it, but the only way
to know the value of fn:last() is by evaluating the whole tree.

I checked the general streamability rules, and while we have exception rules
for higher-order operands like xsl:for-each, they have no effect when the
select expression selects a grounded result.

I think that the only problem is with fn:last(), therefore I suggest we add a
rule in section 19.8.9.14 Streamability of the last function along those lines
(probably with a Note explaining why so):

    x) if the fn:last function appears at any depth inside a higher-order 
       operand, then roaming and free-ranging.

This has a few nasty side-effects, so perhaps we can do better. I.e., consider:

a) a/b[last()] (should be prohibited)
b) (1 to 10)[last()] (should be allowed)
c) xsl:for-each/@select="copy-of(x)", the last() in seqtor (should be allowed?)
d) same with xsl:iterate
e) same with xsl:for-each-group
f) (for $e in a/b return copy-of($e))[last()]  (maybe allowed?)
g) a/b/copy-of(x)[last()] (should be prohibited, though can be made streamable)

Perhaps there are other scenarios to consider? In the event that we prohibit
too much, someone can always create a copy of a node-set as a workaround and
use count($x).

-- 
You are receiving this mail because:
You are the QA Contact for the bug.

Received on Monday, 28 September 2015 13:35:26 UTC