Project

Profile

Help

Bug #3713

closed

Incorrect type inference that element(foo) is a subtype of element(*:bar)

Added by Michael Kay about 6 years ago. Updated over 1 year ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
XPath conformance
Sprint/Milestone:
-
Start date:
2018-03-07
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
9.8, trunk
Fix Committed on Branch:
9.8, trunk
Fixed in Maintenance Release:
Platforms:

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.

Actions #1

Updated by Michael Kay about 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.

Actions #2

Updated by Michael Kay about 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).

Actions #3

Updated by Michael Kay about 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().

Actions #4

Updated by Michael Kay about 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@.

Actions #5

Updated by O'Neil Delpratt about 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.

Actions #6

Updated by Anonymous over 1 year ago

(Spam deleted)

Please register to edit this issue

Also available in: Atom PDF