[Bug 29120] [xslt 3.0] last() in a streamable xsl:merge

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

--- Comment #5 from Abel Braaksma <abel.braaksma@xs4all.nl> ---
> <xsl:merge-source for-each-stream="doc.xml" select="/*/*">
>    <xsl:merge-key select="last() - 825"/>

This is interesting. My instinct says this should be forbidden. Checking out
the rules once more, I see that for streamability we do not prohibit anything
in xsl:merge-key. That means that:

<xsl:merge-key select="../foo" />

is allowed. Considering that we take a snapshot, one could argue that this is
essentially a grounded expression that will always select the empty sequence,
but that hardly constitutes the principle of least surprise, and is isn't
helping any useful case I can think of.

My proposal would be to add an extra rule to guaranteed-streamable rules for
xsl:merge-source, something like:

    5. Every select expression of child xsl:merge-keys has a striding or 
       grounded posture and a motionless or consuming sweep when assessed 
       with the context item type and posture of the select expression of 
       the parent xsl:merge-source.

This rule will also take care of erroneous use of the fn:last() function, which
is not allowed in a striding posture.

As presently written it does not take care of a context item type other than
nodes (i.e. atomic types or function items), which, if we are keeping this
disallowed because of fn:snapshot, is better if we statically prohibit it to
make the streaming rules apply to all allowed cases (if not, then the fn:last()
function would be allowed if xsl:merge-source selects non-nodes, only to hit a
dynamic error later with fn:snapshot).

-----

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

While this exact construct is not problematic, it becomes problematic with
/*/transaction/copy-of(). I have reported that separately: bug 29153, comment
0.

> I'm not sure whether comment #2 is suggesting that we make use of last() 
> in these situations a dynamic error. That would be very different from our 
> usual approach where streamability violations are detected statically.

No, I think we can statically determine whether or not the context-size is
requested. In the case of binding a variable to the last() function, don't we
already have a restriction on this (in the sense that binding to
focus-dependent functions is disallowed)? But since this then becomes a
*dynamic* function call, a dynamic error when invoking such a dynamic function
call seems appropriate.

The alternative is to:
- ban fn:last()
- ban function-lookup
- ban all and any dynamic function calls
- ban inline functions (they can contain fn:last)

this seems a bit too much killing a mosquito with a bazooka ;).

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

Received on Monday, 28 September 2015 13:40:52 UTC