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 29571 - [XQ31] [FO31] 3.18.3 Cast
Summary: [XQ31] [FO31] 3.18.3 Cast
Status: RESOLVED FIXED
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XQuery 3.1 (show other bugs)
Version: Candidate Recommendation
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Jonathan Robie
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-04-12 09:11 UTC by Tim Mills
Modified: 2016-05-05 13:38 UTC (History)
2 users (show)

See Also:


Attachments

Description Tim Mills 2016-04-12 09:11:12 UTC
In XQ31 3.18.3 Cast it is written

"If the result of atomization is an empty sequence:

    If ? is specified after the target type, the result of the cast expression is an empty sequence.

    If ? is not specified after the target type, a type error is raised [err:XPTY0004]."

Suppose the target type is my:list which is a simple list type whose minLength is zero, and we have the query:

() cast as my:list

Following the rules above:

1. the result of atomization is the empty sequence.
2. ? is not specified.  Therefore a type error is raised.


FO31 says "If the target type of a cast expression (or a constructor function) is a type with variety list, the supplied value must be of type xs:string or xs:untypedAtomic.".  So perhaps a type error is correct behaviour.

However in FO31 18.3 Constructor functions for XML Schema built-in list types,

"The return type, however, allows for the fact that when the argument to the function is an empty sequence, the result is an empty sequence."

which makes it clear that

() cast as xs:NMTOKENS 

is not a type error.

In "18.5 Constructor functions for user-defined types", it is stated that

"For every user-defined simple type in the static context (See Section 2.1.1 Static Context XP31), there is a constructor function whose name is the same as the name of the type and whose effect is to create a value of that type from the supplied argument". 

The text goes on to state that

"In the case of an atomic type A, the return type of the function is A?, reflecting the fact that the result will be an empty sequence if the input is an empty sequence. For a union or list type, the return type of the function is specified only as xs:anyAtomicType*. Implementations performing static type checking will often be able to compute a more specific result type. For example, if the target type is a list type whose item type is the atomic type A, the result will always be an instance of A*; if the target type is a pure union type U then the result will always be an instance of U?. In general, however, applications needing interoperable behavior on implementations that do strict static type checking will need to use a treat as expression to assert the specific type of the result."

I can't find the text that states that the argument to the constructor function is xs:anyAtomicType?.

It might be worth noting that a query such as

xs:NMTOKENS("a b c") cast as NMTOKENS is a type error, which seems odd.
Comment 1 Michael Kay 2016-04-21 09:41:32 UTC
I agree that it seems rather odd that casting to a list type isn't idempotent; we would normally expect that if (A instance of T) is true, then (A castable as T) is also true. But I think fixing that would be feature creep. It's also potentially non-trivial to define.

I think the intent of the spec as written is that the only thing you can cast to a list type is a string (or untypedAtomic); except that if you write "V cast as L?" then if V is (), the result is ().

If there are statements in the spec that don't reflect that intent then we should fix them.
Comment 2 Jonathan Robie 2016-04-26 16:44:12 UTC
In today's call, we agreed to add a NOTE to call this out, but not to fix it now.  Getting that NOTE right may be tricky.
Comment 3 Andrew Coleman 2016-04-29 12:43:27 UTC
At the meeting on 2016-04-26, the WG agreed to resolve this bug by adding a note to the spec to make it clear to readers that when T is a list type, T(x) cast as T will typically fail.  Action A-641-13 was raised to track this change
Comment 4 Tim Mills 2016-05-05 10:15:34 UTC
I suggest the following note be added.



NOTE: 

As a consequence of these rules, for an expression E and type L, where

1. L is a list type, or L is a union type of which a list type is in its transitive membership, and

2. (E instance of L) eq true

then 

E castable as L

is false.  For example xs:NMTOKENS("a b c") castable as XS:NMTOKENS is false.  

Furthermore, if L is a list type with a mininum length facet of zero, () castable as L is false.
Comment 5 Tim Mills 2016-05-05 13:38:25 UTC
Correction....

NOTE: 

As a consequence of these rules, for an expression E and type L, where

1. L is a list type, or L is a union type of which a list type is in its transitive membership, and

2. (E instance of L) eq true

then 

E castable as L

is not generally true.  For example, xs:NMTOKENS("a b c") castable as XS:NMTOKENS is false.  

Furthermore, if L is a list type with a mininum length facet of zero, () castable as L is false.