Bug #4091
closedFunction with declared argument type of xs:error can be successfully called
100%
Description
Adam Retter reported on xquery-talk:
On 12 Jan 2019, at 09:22, Adam Retter adam.retter@googlemail.com wrote:
Whilst looking for a type which is declarable in XQuery but that cannot be constructed, I wrote a strange query, well to me anyway, which evaluates on Saxon 9.8.0.12 PE, and returns .
declare function local:test1($x as xs:error) {
<hello/>
};
local:test1(())
xs:error is defined in XSD 1.1 part 1:
[Definition:] A special simple type definition, whose name is error in the XSD namespace, is also present in each ·XSD schema·. The XSD error type has no valid instances. It can be used in any place where other types are normally used; in particular, it can be used in conditional type assignment to cause elements which satisfy certain conditions to be invalid.
In §3.16.7.3 it is defined as a union type with no member types.
I think that this call should fail on the grounds that () is not a valid instance of xs:error.
What's happening is apparently that when xs:error
is used as a SequenceType, it is given a required cardinality of 0, and the type matching, when it sees a required cardinality of 0, allows an empty sequence to appear. I think the correct handling would be to have a required cardinality of 1.
Updated by Michael Kay almost 6 years ago
The constructor for SequenceType has this logic explicitly:
public SequenceType(ItemType primaryType, int cardinality) {
this.primaryType = primaryType;
if (primaryType instanceof ErrorType) {
this.cardinality = StaticProperty.EMPTY;
} else {
this.cardinality = cardinality;
}
}
It feels wrong, but we need to see if anything breaks when we change it.
It also feels wrong that ErrorType extends NodeTest. Perhaps this is because at one time we implemented empty-sequence() as having an item type of ErrorType? We need to think carefully about the consequences of making changes here.
Updated by Adam Retter almost 6 years ago
Maybe also worth adding that:
You can also modify the query so the parameter has one-or-mode cardinality e.g. "$x as xs:error+", and it will still evaluate with an empty sequence as the argument.
e.g. the following still evaluates (note the +
):
declare function local:test1($x as xs:error+) { }; local:test1(())
Updated by Michael Kay almost 6 years ago
QT3 actually contains quite a number of similar tests cases, but it doesn't include the case of supplying an empty sequence to a function that expects xs:error. I've added this as test xs-error-054.
Updated by Michael Kay almost 6 years ago
Changing the constructor described in comment #1 leads to a test failure in xs-error-007. This test does
xs:error#1 instance of function(xs:anyAtomicType?) as empty-sequence()
and expects "true".
The F+O spec says the signature of xs:error#1 is xs:error($arg as xs:anyAtomicType?) as xs:error?
Now, §2.5.6.1 in the XPath book says that xs:error?
is "treated in the same way" as empty-sequence()
as regards the subtype relationship, and I guess it's the subtype relationship that matters here.
I get the correct results on all the xs:error tests (including the new one) if I change the SequenceType constructor to
public SequenceType(ItemType primaryType, int cardinality) {
this.primaryType = primaryType;
if (primaryType instanceof ErrorType && Cardinality.allowsZero(cardinality)) {
this.cardinality = StaticProperty.EMPTY;
} else {
this.cardinality = cardinality;
}
}
which is basically as it was before except that it doesn't permit an empty sequence as an instance of xs:error
or xs:error+
.
This is passing all tests so I'll run with it.
Updated by Michael Kay almost 6 years ago
- Status changed from New to Resolved
- Applies to branch trunk added
- Fix Committed on Branch 9.9, trunk added
Fixed on 9.9 branch and trunk.
Updated by O'Neil Delpratt almost 6 years ago
- Status changed from Resolved to Closed
- % Done changed from 0 to 100
- Fixed in Maintenance Release 9.9.1.2 added
Bug issue fixed in the Saxon 9.9.1.2 maintenance release.
Please register to edit this issue