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 30313 - [xslt30] Overriding variables must have "identical declared type"; what if they have no declared type?
Summary: [xslt30] Overriding variables must have "identical declared type"; what if th...
Status: REOPENED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 3.0 (show other bugs)
Version: Recommendation
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: 2018-11-03 23:07 UTC by Michael Kay
Modified: 2019-02-28 15:31 UTC (History)
1 user (show)

See Also:


Attachments

Description Michael Kay 2018-11-03 23:07:56 UTC
In ยง3.5.3.3 it is stated that an when one global variables overrides another, "Their declared types [must be] identical."

It's not clear what this means when there is no explicit declared type.

The difficulty exists particularly because the "as" attribute does not have a simple lexical default.

Consider

<xsl:variable name="x" select="23"/>

versus

<xsl;variable name="x">23</xsl:variable>

I suggest the interpretation:

Their declared types [must be] identical. The declared type of a variable for this purpose is the "SequenceType" appearing in the "as" attribute, or "item()*" in the absence of the "as" attribute.
Comment 1 Abel Braaksma 2018-11-16 15:46:14 UTC
We currently allow overriding a variable if their types, implicitly or explicitly, are identical. 

I think that if we default it to item()*, this can be problematic for implicit defaults like document() or xs:string. In your example it is statically known that the type of the second $x is document() and the type of the first $x is xs:integer.

However, the static type may not be definitively known. The select-expression could call fn:collection, which can return any type and I'm sure there are other possibilities. Though statically, these would simply default to item()*.

I'm not sure what the best cause of action is. One alternative way of reading "the declared types must be identical" is that it seems to implicitly require a declared type on variables. In the absence thereof (i.e., no as-clause), you cannot override the xsl:variable. The logic being: "when the type is not declared, its type is unknown and cannot always be assessed statically to be equal".
Comment 2 Abel Braaksma 2018-11-16 15:59:32 UTC
Hmm, one complicating factor is that the large example on binding components (3.5.3.5 Binding References to Components) exclusively uses variables that have no as-clause. Having that example suggests that overriding without as-clause is valid, but the prose in that section do not mention the type-identicality.
Comment 3 Michael Kay 2019-02-15 10:50:14 UTC
I propose that after "Their declared types are identical." we add "The declared type is the type appearing in the 'as' attribute if present; in the absence of an 'as' attribute, the declared type is 'item()*' if a 'select' attribute is present, or 'document-node()' otherwise.
Comment 4 Michael Kay 2019-02-15 11:00:35 UTC
Or more precisely:

For this purpose, the declared type is the first of the following that applies:
				
* If there is an <code>as</code> attribute, then the type defined by that attribute.

* If there is a <code>select</code> attribute, then <code>item()*</code>.

* If there is a non-empty sequence constructor, then <code>document-node()</code>.

* Otherwise, <code>xs:string</code>.
Comment 5 Abel Braaksma 2019-02-19 20:39:21 UTC
Since this only pertains to xsl:variable and not xsl:param (which tends to be more malleable), I think it is a fair solution while still allowing processors to optimize for the (rather complex) default variable types.

For reference, a draft proposal erratum was published on 13 Feb 2019, E35, see:
https://htmlpreview.github.io/?https://github.com/w3c/qtspecs/blob/master/errata/xslt-30/html/xslt-30-errata.html#E35
Comment 6 Abel Braaksma 2019-02-28 15:31:44 UTC
Reopening as I think we forgot one tiny little bit: existing examples in the spec.

I propose we change the existing examples where it is applicable. They are not necessarily wrong but as written they can lead to confusion, esp. in light of overriding. I think we only need to address the examples overriding is an option.

Luckily there's only a handful:

B.2 Stylesheet JSON
- variable $quot is private, leave as is

3.5.3.5 Binding References to Components
- variable $C has implicit type xs:integer, would benefit from as="xs:integer" for clarity
- example with xsl:override on $C, same, should have as="xs:integer" for clarity
- others are private/final, cannot be overridden

3.5.3.6 Dynamic References to Components
- in the Note, variable $get-order. Should have an as-clause as otherwise the type is item()* and that is not the intend here and can lead to errors.

3.5.7 Worked Example of a Library Package
- nothing to do, all xsl:variable have a type



Other variables do not appear under xsl:package and are therefore not open to misinterpretation.