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 29670 - [XSLT30] xsl:accumulator/@initial-value accessing the global context item and streamability
Summary: [XSLT30] xsl:accumulator/@initial-value accessing the global context item and...
Status: CLOSED WONTFIX
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Candidate Recommendation
Hardware: PC Windows NT
: 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: 2016-05-27 09:52 UTC by Abel Braaksma
Modified: 2016-10-06 18:42 UTC (History)
0 users

See Also:


Attachments

Description Abel Braaksma 2016-05-27 09:52:56 UTC
> ACTION 2016-05-26-001: ABr to raise an issue analogous to Bug 29499, addressing accumulators.

Similar to global variables, xsl:accumulator can access the global context item (GCI) through the @initial-value attribute. The rules that apply when the GCI is streamable are covered in 3.5.6:

Under 3.5.6 Declaring the Global Context Item we say:

   "If the streamable attribute is present with the value yes, then the select expression or contained sequence constructor of every global xsl:variable and xsl:param declaration in the containing package must be grounded and motionless, when assessed with a context posture of striding, and a context item type based on the declared type of the global context item. The consequences of violating this rule depend on the conformance level of the processor, as described in 19.10 Streamability Guarantees."


This section leaves out xsl:accumulator/@initial-value, which can also access the GCI. Furthermore, the resolution of Bug 29499 may also apply here, such that:

1) if import precedence overrules an accumulator, the overruled accumulator need not be analyzed.

2) if the accumulator is *not* used, it is still an error if the @initial-value expression is not motionless + grounded.

3) we should perhaps stress (in a Note?) that it does *not* matter whether the accumulator is declared streamable or not, this rule applies to the GCI, not to the (initial) match selection or other streamable trees a *streamable* accumulator can be applied to. The xsl:accumulator-rule declarations *cannot* access the GCI.
Comment 1 Michael Kay 2016-05-27 10:04:05 UTC
>Similar to global variables, xsl:accumulator can access the global context item (GCI) through the @initial-value attribute.

This is not quite accurate. 18.2.1 says:

The expression in the initial-value attribute is evaluated with a singleton focus based on the root node of the [streamed] input tree to which the accumulator is being applied.

(The word "streamed" is present in the text and should be removed)

So an accumulator can reference the GCI only in the case where it is being applied to the tree rooted at the GCI.

If the GCI is a streamed node, then an accumulator is applicable to the GCI only if it is declared streamable (§18.2.2), and in this case we require (§18.2.8) that the initial-value expression is grounded and motionless.

I don't think it's necessary to change the rules for accumulators that are eclipsed by virtue of import precedence. We allow you to override a non-streamable accumulator with a streamable one, and that meets the requirement we're trying to address.
Comment 2 Abel Braaksma 2016-05-27 17:21:03 UTC
Thanks, this does simplify matters.

> So an accumulator can reference the GCI only in the case where it is being 
> applied to the tree rooted at the GCI.
I don't think this is possible. Apparently, the GCI can only be accessed in xsl:variable/xsl:param. Even if GCI == IMS, then still, from the point of view of the spec, they are not the same.

This does create an edge-case scenario, though, which I am not sure we address properly:

<xsl:global-context-item streamable="yes" />

<xsl:variable name="X" select="accumulator-before('acc')" />

<xsl:accumulator 
   name="acc" 
   initial-value="has-children()"
   streamable="yes">
   <xsl:accumulator-rule select="$value" />
</xsl:accumulator>

<xsl:template match="/">
   <xsl:value-of select="$X" />
</xsl:template>

What happens here is that $X uses fn:accumulator-before, which results in the accumulator "acc" being applicable to the GCI (the real GCI, irrespective of the IMS).

I am not sure this is (un)fortunate. As in this case both the xsl:variable and the xsl:accumulator/@initial-value *MUST* be motionless/grounded. I don't think it serves any practical use-case, but I think it is the only way to force an accumulator on a streamed GCI, though this GCI cannot be consumed in any way.

In fact, that applies to any GCI that is a streamed node. It cannot be consumed. Yes, if the IMS is the same (but we don't enforce, nor disallow them to be node-identity equal) then you can argue that applying templates will consume the GCI, but that is not what happens here.

This begs the question: if we can never consume a streamed GCI, should we maintain all that machinery? I know that when we added it it seemed a good idea, but perhaps we would do better to suggest GCI to be absent when IMS is a streamed node.
Comment 3 Michael Kay 2016-05-27 17:35:15 UTC
>In fact, that applies to any GCI that is a streamed node. It cannot be consumed.

Fascinating insight.

Yes, let's just say that the global context item cannot be a streamed node.

Perhaps with a suggestion that when implementing a legacy API in which a single "setSource" method has provided both the GCI and the IMS, our recommendation is that when the supplied value is a streamed input source, and the initial mode is streamable, then the supplied value should be used to set the IMS, and the GCI should be absent.
Comment 4 Abel Braaksma 2016-05-27 18:24:53 UTC
(In reply to Michael Kay from comment #3)
> Yes, let's just say that the global context item cannot be a streamed node.
> 
> Perhaps with a suggestion that when implementing a legacy API in which a
> single "setSource" method has provided both the GCI and the IMS, our
> recommendation is that when the supplied value is a streamed input source,
> and the initial mode is streamable, then the supplied value should be used
> to set the IMS, and the GCI should be absent.
With the current rules for xsl:global-context-item this would work, as the default (if the declaration is absent) is type="item()" and use="optional".

This would then, of course, cause a dynamic (!) error if you would try to access the GCI within xsl:variable/param etc, but that may be clearer than requiring motionless expressions (and it does *not* remove the ability to have the GCI set to a non-streamed document node, different from the IMS).

The only use-case we subvert is where the programmer wants information on the input tree. But a workaround (which could go in a Note) is to use an accumulator that only operates on the document node of the input tree.

What would happen if you access the GCI with a streamed accumulator, as in comment 2? I think the answer should be: it doesn't matter, as a streamed accumulator is equally applicable to non-streamed trees (but the inverse is not true).

This would imply removing anything in the spec related to xsl:global-context-item/@streamable="yes". Considering the issues we have with "getting it right", I think that's a good thing ;). But is this an allowed change at this CR stage?
Comment 5 Abel Braaksma 2016-06-16 14:41:27 UTC
This bug is to be closed as WONTFIX, as the GCI cannot directly be accessed by accumulators. Indirect access will be disallowed, as GCI-as-a-stream is going to be dropped, see Bug 29696 and the DECISION in the minutes of 9 June 2016.