Bug #6239
closedFunction conversion rules: xs:anyURI to xs:string conversion
100%
Description
The XPath 3.1 function conversion rules say that it should be possible to supply an item of type xs:anyURI where the required type is xs:string. This is only working in the case where the static type of the function argument is known to be xs:anyURI; it fails with a type error if the type is only discovered to be xs:anyURI at evaluation time.
Updated by Michael Kay about 1 year ago
Demonstrated by QT4 test case function-call-promotion-405 run with -lang:XQ31.
Updated by Michael Kay about 1 year ago
The test turned out to be incorrect. There is a problem, but it's quite hard to find a test case that reveals it.
The ItemChecker is letting an xs:anyURI through where an xs:string is expected, which means that a call that supplies an xs:anyURI
to a function expecting an xs:string
actually succeeds -- but it arrives as an xs:anyURI
, not as an xs:string
. How do we detect the difference? The obvious way is by using an "instance of" test, but this will be optimized away because we think we know the type of the value statically. Perhaps we should mix the supplied value into a sequence with other values and then do an instance-of test on a selected item from that sequence...?
I have revised the test function-call-promotion-405 so it now demonstrates the failure.
Updated by Michael Kay about 1 year ago
Because the "treat as" expression is implemented using the ItemChecker
class, and ItemChecker
treats an xs:anyURI
as an xs:string
, the expression $x treat as xs:string*
can succeed (incorrectly) when the sequence $x contains an xs:anyURI
.
I have added QT3 test treat-as-26
to demonstrate this.
Updated by Michael Kay about 1 year ago
- Status changed from New to Resolved
- Applies to branch deleted (
11) - Fix Committed on Branch 12, trunk added
Fixed on the 12.x and main branches.
Although the bug is present in earlier releases, it has caused no trouble, so I shall refrain from fixing it unless it proves necessary. (The main changes needed are in ItemChecker and TypeChecker).
Updated by Michael Kay about 1 year ago
- Status changed from Resolved to In Progress
Reopening because there is a need to test that the new way of handling these promotions generates SEF files that existing SaxonJS releases will accept.
Updated by Michael Kay about 1 year ago
I'm now looking at the SEF file output to ensure backwards compatibility in SaxonJS.
For this function (in test as-0152):
<xsl:function name="f:promote" as="xs:double">
<xsl:param name="p"/>
<xsl:sequence select="$p"/>
</xsl:function>
we are now generating:
<function name='Q{f}promote' line='10' module='file:/Users/mike/GitHub/xslt30-test/tests/attr/as/as-0152.xsl' flags='pU' as='1AO' slots='1'>
<arg name='Q{}p' as='*'/>
<check role='body' baseUri='file:/Users/mike/GitHub/xslt30-test/tests/attr/as/as-0152.xsl' ns='f=f xs=~ xsl=~' line='12' card='1' diag='5|0|XTTE0780|f:promote#1'>
<convert from='A' to='AO' flags='p' diag='5|0|XTTE0780|f:promote#1'>
<data diag='5|0|XTTE0780|f:promote#1'>
<varRef name='Q{}p' slot='0'/>
</data>
</convert>
</check>
</function>
Specifcally, the varRef
is wrapped in data
(to do atomisation) then convert
which now does both numeric type promotion and conversion from untyped atomic, and then check
for a cardinality check.
Saxon 11 generated:
<function name='Q{f}promote' line='10' module='file:/Users/mike/GitHub/xslt30-test/tests/attr/as/as-0152.xsl' eval='16' flags='pU' as='1AO' slots='1'>
<arg name='Q{}p' as='*'/>
<check role='body' baseUri='file:/Users/mike/GitHub/xslt30-test/tests/attr/as/as-0152.xsl' ns='f=f xs=~ xsl=~' line='12' card='1' diag='5|0|XTTE0780|f:promote#1'>
<convert from='A' to='AO' flags='p' diag='5|0|XTTE0780|f:promote#1'>
<cvUntyped to='AO' diag='5|0|XTTE0780|f:promote#1'>
<data diag='5|0|XTTE0780|f:promote#1'>
<varRef name='Q{}p' slot='0'/>
</data>
</cvUntyped>
</convert>
</check>
</function>
So the conversion was done in two steps: cvUntyped
to convert untypedAtomic to double, and then convert
to do promotion from decimal/float to double.
Attempting to run the SEF file from Saxon 12.x using SaxonJS 2.6 results in "Incompatible operands: xs:untypedAtomic (01.123) and xs:double". So we're going to need to adapt the SEF output from 12.x when target=JS.
Updated by Michael Kay about 1 year ago
- Status changed from In Progress to Resolved
This has been done. Marking as resolved.
Updated by O'Neil Delpratt about 1 year ago
- Status changed from Resolved to Closed
- % Done changed from 0 to 100
- Fixed in Maintenance Release 12.4 added
Bug fix applied in the Saxon 12.4 maintenance release
Please register to edit this issue