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 24173 - [xslt 3.0] Need more precise type information
Summary: [xslt 3.0] Need more precise type information
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: 2013-12-28 17:32 UTC by Michael Kay
Modified: 2014-02-17 08:14 UTC (History)
1 user (show)

See Also:


Attachments

Description Michael Kay 2013-12-28 17:32:13 UTC
John Lumley writes:

When working through the W3C test sets (fix one problem, open up another.....) I think I've discovered some cases where more precise type determination is required. This is typified in strm/sf-head/sf-head-A.xsl, test r-32 and the xsl:value-of/@select. The circumstances are:

The argument to fn:head() has type attribute()*, climbing posture and consuming sweep.

As the usage of that argument is transmission and it is the sole potential consumer, the call to fn:head() has climbing posture and consuming sweep.

The functional signature type of fn:head() is item()?

The (un-adjusted) usage of this call by xsl:value-of is absorption, which with a climbing posture gives the xsl:value-of a free-ranging sweep and thus a roaming posture.

The issue is that of the type of fn:head() - in this case any of the members of the argument sequence have type attribute() and would be classed as childless-nodes. If in this circumstance we classify the type of fn:head() to be attribute()?, then the usage is this call by xsl:value-of is adjusted to inspection by rule 1.b.iii.A.I, and thus the sweep remains as consuming, the call is a single potentially consuming operand with inspection usage, so the xsl:value-of becomes grounded and motionless.

So it appears that without a finer type determination, viz the type of fn:head() is effectively the (singular) type of its first argument, this example can't be guaranteed streamable.

I think similar conditions would also apply to  'remove','head','tail','subsequence','unordered', 'outermost','innermost','exactly-one','zero-or-more','one-or-more','trace' - the tests fail without such type determination.
Comment 1 Michael Kay 2014-01-13 20:42:11 UTC
I think there is a general rule that where a built-in function listed in 19.8.8 has a proforma that includes one or more operands with usage T (transmission), then the inferred type of the function call is the more specific of the declared return type of the function and the type of the operand having usage T; or if (as with insert-before) there is more than one operand having usage T, then the lowest common supertype of the types of these operands.
Comment 2 C. M. Sperberg-McQueen 2014-02-10 10:11:48 UTC
The WG discussed this during the ftf meeting in Prague and inclined to agree that formulating a general rule for these functions would be desirable.  (A general rule would also have the nice side effect that if in the future users were allowed to declare operand usage for user-defined functions, then user-defined functions would benefit from the general rule.) 

A special-case rule listing the built-in functions remains a fallback possibility if the general rule proves elusive.
Comment 3 Michael Kay 2014-02-11 18:16:17 UTC
Changed the entry for FunctionCall [59] in the table in 19.2 to:

In general: the declared result type of function <var>F</var>.  But if one or more of the arguments to the function have operand usage <termref def="dt-transmission"/>, then the least common supertype of the static types of these arguments, provided this is a subtype of the declared result type of <var>F</var>. (For example, the type of the function call <code>head(//text())</code> is <code>text()</code>.)