Bug #3713
closedIncorrect type inference that element(foo) is a subtype of element(*:bar)
100%
Description
The static type inferencing logic incorrectly deduces that element(foo) is a subtype of element(*:bar)
The reason for this is that we look at the set of names that can be matched. The set of names that element(*:bar) can match is infinite, and therefore we assume that it includes "foo". But of course, it doesn't.
This emerged from a new optimization that rewrites child::foo/self:::bar as child::foo, on the basis that self:::bar does not further restrict the set of nodes selected. But although the optimisation is new (and is correct), the type inferencing code that it relies on has been in the product "for ever", and is flawed.
Updated by Michael Kay over 6 years ago
A comment in the code effectively anticipates this bug:
// Note that although
// NamespaceTest and LocalNameTest are NodeTests, they do not occur in SequenceTypes,
// so we don't need to consider them.
But this assumes that the type inferencing code will only be applied to SequenceTypes that can be expressed using the SequenceType syntax, not to inferred types.
Updated by Michael Kay over 6 years ago
- Status changed from New to In Progress
The simplest fix appears to be: if either of the nodetests is *:x
or @x:*@, then treat the sets of names as overlapping, unless they are actually the same nodetest. We can be smarter than this, but this should be adequate.
The underlying problem, though, is that for NamespaceTest and LocalNameTest, the method getRequiredNodeNames() returns IntUniversalSet.getInstance(). This is incorrect: the set of names accepted by these tests is infinite, but it is not universal (there are names that are not accepted).
Updated by Michael Kay over 6 years ago
There is in fact another problem which is that the code in TypeHierarchy.relationship() assumes that NodeTest.getRequiredNodeNames() will return null to indicate that all names are accepted, whereas it actually returns IntUniversalSet.getInstance().
Updated by Michael Kay over 6 years ago
- Status changed from In Progress to Resolved
- Applies to branch 9.8, trunk added
- Fix Committed on Branch 9.8, trunk added
Resolved on the 9.8 and trunk branches.
On the 9.8 branch, the main change is to the logic of TypeHierarchy.computeRelationship() when comparing the set of node names that two node tests can match.
On the trunk, the changes are more extensive: NodeTests for local name and namespace tests now return "absent" for the set of names matched (using Java 8 Optional<IntSet>
rather than null), and there is new logic which determines that, for example, *
subsumes *:x
and *:x
subsumes @p:x@.
Updated by O'Neil Delpratt over 6 years ago
- Status changed from Resolved to Closed
- % Done changed from 0 to 100
- Fixed in Maintenance Release 9.8.0.10 added
Bug fix applied in the Saxon 9.8.0.10 maintenance release.
Please register to edit this issue