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 24040 - [XT3TS] result-document-1107, 1109, 1110
Summary: [XT3TS] result-document-1107, 1109, 1110
Status: RESOLVED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 Test Suite (show other bugs)
Version: Candidate Recommendation
Hardware: Other 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: 2013-12-09 21:38 UTC by Tim Mills
Modified: 2015-08-06 01:13 UTC (History)
1 user (show)

See Also:


Attachments

Description Tim Mills 2013-12-09 21:38:37 UTC
These tests offer the optimizer the possibility of

1. Eliminating the redundant sort
2. Eliminating an unused parameter

Thus the otherwise erroneous use of result-document can be side-stepped.
is this permitted?
Comment 1 Abel Braaksma 2015-05-15 16:34:00 UTC
My take on this:

> result-document-1107

You can only find the sort key specification by evaluating the xsl:call-template, which contains the xsl:result-document. Only after this evaluation you find that the sort key is redundant and can be ignored, but by this time you have already evaluated it.

I think that in this case the error cannot be side-stepped.

> result-document-1109

This is different. The param is not used, so the error is never raised (unless a processor detects the error statically). So yes, here I believe it can be side-stepped.

> result-document-1110

Same here, param is never used, no need to throw the error.
Comment 2 Tim Mills 2015-05-18 15:52:43 UTC
In result-document-1107, it is possible to avoid the error by avoiding use of the variable.

   <xsl:template name="a">
	  <xsl:variable name="v">
	     <xsl:call-template name="rrr"/>
	  </xsl:variable>
	  <xsl:sequence select="$v"/>
   </xsl:template>

since $v is only used once.  i.e. as if the transform had been written as:

   <xsl:template name="a">
	     <xsl:call-template name="rrr"/>
   </xsl:template>


Modifying the test to

   <xsl:template name="a">
	  <xsl:variable name="v">
	     <xsl:call-template name="rrr"/>
	  </xsl:variable>
	  <xsl:sequence select="$v, $v"/>
   </xsl:template>

should force out the error.
Comment 3 Abel Braaksma 2015-05-19 01:30:26 UTC
>    <xsl:template name="a">

That template is used by test result-document-1101, not 1107, the latter using the sort as mentioned in comment#0.

That is not to say that in 1101 the same issue applies. And I'm not certain whether using the variable twice really forces this error, it can still be rewritten by inlining if a processor chooses so, i.e. like:

<xsl:sequence>
    <xsl:call-template name="rrr" />
    <xsl:call-template name="rrr" />
</xsl:sequence>

Looking further into these tests, I see that more tests here are eligible for improvement: i.e., xsl:attribute no longer triggers temporary output state in XSLT 3.0 (test 1102), or specifically:

<quote>
The instructions in the initial named template are evaluated in final output state. An instruction is evaluated in the same output state as its calling instruction, except that xsl:variable, xsl:param, xsl:with-param, xsl:function, xsl:key, xsl:sort, xsl:accumulator-rule, and xsl:merge-key always evaluate the instructions in their contained sequence constructor in temporary output state.
</quote>

Looking at that quote, I am wondering whether or not we should improve the text in the spec,

1. saying that optimizing rewrites may remove this error from occurring
2. or: saying that optimizations must leave this error in place at all times (but I don't like this option)

With the variables, the indirectness is an issue. I.e., suppose a processor aggressively inlines variables, this error would only be detectable if it xsl:result-document is statically inside xsl:variable's scope.

But there's another problem here: aftger optimization, the xsl:result-document is positioned in a legal position and the result-document is created, possibly repeatedly (which yields a different error). This is a processor-dependent behavior that may not be what we want.

Perhaps we should lift this error entirely and change it such that in temporary output state, xsl:result-document is ignored, with a NOTE saying that as a result of optimizations, temporary output state may change into final output state, potentially leading to multiple invocations of the same xsl:result-document instruction, raising XTDE1490.
Comment 4 Tim Mills 2015-05-19 14:46:07 UTC
(In reply to Abel Braaksma from comment #3)
> >    <xsl:template name="a">
> 
> That template is used by test result-document-1101, not 1107, the latter
> using the sort as mentioned in comment#0.

My mistake.  I'll add a separate comment regarding 1107.

> That is not to say that in 1101 the same issue applies. And I'm not certain
> whether using the variable twice really forces this error, it can still be
> rewritten by inlining if a processor chooses so, i.e. like:
> 
> <xsl:sequence>
>     <xsl:call-template name="rrr" />
>     <xsl:call-template name="rrr" />
> </xsl:sequence>

This isn't a valid rewrite, because the template returns nodes with node identity.  The above rewrite returns two distinct node.  ($v, $v) would return two nodes with the same identity.
Comment 5 Tim Mills 2015-05-19 14:47:48 UTC
Regarding result-document-1107, the sort in:

   <xsl:perform-sort select="1 to 100">      
	    <xsl:sort>
	     <xsl:call-template name="rrr"/>
	    </xsl:sort>
  </xsl:perform-sort>  

can be eliminated, since the sort key would be a constant.  Hence the error can be avoided.
Comment 6 Abel Braaksma 2015-05-20 01:09:18 UTC
(In reply to Tim Mills from comment #4)
> > <xsl:sequence>
> >     <xsl:call-template name="rrr" />
> >     <xsl:call-template name="rrr" />
> > </xsl:sequence>
> 
> This isn't a valid rewrite, because the template returns nodes with node
> identity.  The above rewrite returns two distinct node.  ($v, $v) would
> return two nodes with the same identity.

Depends, if identity is not required for proper result, then a processor can cache and return equal results on equal function or template calls. But that was not the point I was trying to make. I was trying to say that the kinds of optimizations that a processor will apply is hard to determine.
Comment 7 Michael Kay 2015-07-01 13:30:44 UTC
Concerning 1101 (discussed in comment 2 but misspoken as 1107):

I think it's not clear that the XSLT spec gives you license to inline the variable, or at any rate, to skip setting temporary output state when you do so. It would be allowed in XPath under the "Errors and Optimization" rules, but XSLT does not reference these rules, nor does it provide any equivalent of its own. In the absence of such a rule, any rewrite you perform must preserve error semantics, which means that when inlining the variable you must still set temporary output state.

I have an open mind about whether XSLT should adopt the XPath rules and/or allow some other relaxation here. But I think the status quo is that it does not. I think the whole point is that xsl:result-document has a (limited kind of) side effect, and the rules on temporary output state are trying to ensure that calls on result-document are guaranteed to fail if they appear in places where execute-once semantics are not guaranteed; if we relax the rules, we lose interoperability.

(Saxon, I believe, inlines the variable but in such a way that temporary output state is still set.)

Concerning 1107, I have replaced the call on rrr with a call on a new template whose result depends on the context item, so that a processor cannot take advantage of the fact that the called template produces the same sort key each time. (Incidentally, the optimization wouldn't work in 3.0 anyway, as the called template can be overridden in a different package by one that uses the context item.)

Concerning 1109 and 1110, I have fixed the tests so that the parameter value is used, which I believe forces the error.
Comment 8 Michael Kay 2015-07-01 13:36:36 UTC
(Note for information: in current Saxon releases we use the 3.0 rules for temporary output state whether processor is running in 2.0 or 3.0 mode. For example we don't set temporary output state while evaluating xsl:attribute. So we have introduced a 2.0 non-conformance.)