This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 28791 - [xslt 3.0] Streamability of simple mapping operator
Summary: [xslt 3.0] Streamability of simple mapping operator
Status: CLOSED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Last Call drafts
Hardware: PC All
: P2 normal
Target Milestone: ---
Assignee: Michael Kay
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-06-11 14:09 UTC by Michael Kay
Modified: 2015-08-17 08:43 UTC (History)
1 user (show)

See Also:


Attachments

Description Michael Kay 2015-06-11 14:09:17 UTC
The semantics of A!B in XPath and <xsl:for-each select="A"/><xsl:sequence select="B"/></xsl:for-each> in XSLT are identical, so it is surprising to find that the streamability rules are very different.

For the bang operator we say:

<quote>
The posture and sweep of the expression are the posture and sweep of the right-hand operand, assessed with a context posture and type set to the posture and type of the left-hand operand.
</quote>

while for xsl:for-each, excluding things that aren't relevant e.g. xsl:sort, we say:

<quote>
1. If the select expression is grounded, then the posture and sweep of the xsl:for-each instruction follow the general streamability rules, with the operand roles and their usages as follows:
1a. The select expression (the operand usage is irrelevant, but can be taken as inspection)
1b. The contained sequence constructor (usage transmission). This is a higher-order operand; its context posture is grounded.

2. If the posture of the select expression is crawling and the sweep of the contained sequence constructor is consuming, then roaming and free-ranging.

3. Otherwise:
3a. The posture of the instruction is the posture of the contained sequence constructor, assessed with the context posture and context item type set to the posture and type of the select expression.
3b. The sweep of the instruction is the wider of the sweep of the select expression and the sweep of the contained sequence constructor.
</quote>

The differences are:

(a) rule 1, which handles the case where the LHS is grounded, is missing for the bang operator. It is potentially needed to handle cases where the RHS is not dependent on the focus, but is not motionless; but all examples I can see where this would come into play, like (1 to 5)!current-group() are covered by existing rules. We need to watch for (1 to 5)!$x where £x is a reference to a streaming parameter of a streamable stylesheet function. As far as I can see, if this rule is needed for xsl:for-each, then it is also needed for the bang operator, and indeed for "/".

(b) I can't see anything disallowed by rule 2 that isn't also disallowed by rule 3a.

(c) Rule 3b is blatantly different from the rule for the bang operator. I think the rule for bang is seriously wrong here. Consider "author!." or "author!name()" - the "wider sweep" rule would give us consuming, but the current rule gives us motionless.

I suggest that we fix all of this by saying for the bang operator: "The sweep and posture of the expression A!B (where A and B are arbitrary expressions) are the same as the sweep and posture of the construct <xsl:for-each select="A"/><xsl:sequence select="B"/></xsl:for-each>: see section a.b.c.d." Then at least we know they are consistent.
Comment 1 Michael Kay 2015-06-25 17:10:35 UTC
One difference between A!B and <xsl:for-each select="A"><xsl:sequence select="B"/></xsl:for-each> is that the semantics of a call to current() within B are different. This case is of course relevant.
Comment 2 Abel Braaksma 2015-06-27 23:25:00 UTC

> (a) rule 1, which handles the case where the LHS is grounded, is missing for 
> the bang operator. [...] As far as I can see, if this rule is needed for 
> xsl:for-each, then it is also needed for the bang operator, and indeed for "/".

This seems to only apply to fn:current, which is now covered in Bug 28833.

> (b) I can't see anything disallowed by rule 2 that isn't also disallowed by 
> rule 3a.

Rule 2 prevents overlapping nodes to be consumed in the body of the for-each (crawling context, then motionless for-each seqtor). Rule 3a covers "normal" cases with non-overlapping context posture, in which case the body is allowed to be consuming.

In the case of the mapping operator, a semantically similar expression is (a//b)!string(.). We allow this currently in the mapping operator, same way we allow string(a//b) (the "minimal buffer" rule). With for-each, this gives more problems, as the body could, for instance, do an apply-templates. I'm not sure we need to restrict this for map expressions.

> (c) Rule 3b is blatantly different from the rule for the bang operator. I 
> think the rule for bang is seriously wrong here. Consider "author!." or 
> "author!name()" - the "wider sweep" rule would give us consuming, but the 
> current rule gives us motionless.

Yes, I think it should work similar to path expressions, where the "wider sweep" rule actually exists. So this needs to be fixed for map expressions.

> One difference between A!B and <xsl:for-each select="A"><xsl:sequence 
> select="B"/></xsl:for-each> is that the semantics of a call to current() 
> within B are different. This case is of course relevant.

Yes, see Bug 28833. But also that a sequence constructor can have constructs like apply-templates and xsl:fork, which is not possible in a mapping expression. One might argue that you can create a streamable stylesheet function, but rules restrict overlapping nodes to be consumed by a streamable stylesheet function (by 19.8.5.5 and 19.8.5.6, rule 3).
Comment 3 Abel Braaksma 2015-07-08 23:29:01 UTC
This bug was discussed at the telcon of 2015-07-02 where the WG decided that:

    The streamability rules for the Simple Map Operator (!) only need to be 
    changed with respect to the wider sweep rule of the two operands, similar 
    to the wider sweep rule of the Path Operator.

See minutes of 2015-07-02 telcon: https://lists.w3.org/Archives/Member/w3c-xsl-wg/2015Jul/0003.html (member only).
Comment 4 Michael Kay 2015-07-09 22:28:25 UTC
The change was agreed and has been applied to the spec.