Project

Profile

Help

Bug #6253

closed

Atomized item type for an array (test CastableAs667)

Added by Michael Kay 6 months ago. Updated 5 months ago.

Status:
Closed
Priority:
Low
Assignee:
Category:
Internals
Sprint/Milestone:
-
Start date:
2023-11-15
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
12, trunk
Fix Committed on Branch:
12, trunk
Fixed in Maintenance Release:
Platforms:
.NET, Java

Description

We're seeing a test failure on the 12.4 branch in QT3 test case CastableAs667; although the test passed in earlier releases, the underlying problem in the code seems to have been present for some time (and it could have other symptoms).

The code in Atomizer.getAtomizedItemType() is supposed to return the item type of the items that will result from atomizing a given expression. The expression in this case is [[], (), [[3, ()]]] and the atomised item type should be xs:integer. However the method (both on the 12.4 branch and earlier) is incorrectly returning xs:error. This causes the candidate 12.4 code to fall over saying xs:error cannot be converted to the required type.

Actions #1

Updated by Michael Kay 6 months ago

The type inferencing here is highly questionable. We're trying to derive the most specific type possible for the (constant) expression [[], (), [[3, ()]]].

First question should perhaps be: why are we bothering? This is all happening during CastableExpression.typeCheck(). Since the expression is a literal, why don't we just evaluate the result at this point, rather than doing all the complex type analysis?

We're deriving an item type for [] of array(xs:error), which is sort of reasonable; and an item type for () of xs:error, and calculating the least common supertype of these two as array(xs:error) which again is reasonable. The type of [[3. ()]] comes out as array(array(xs:integer)) which again is OK. The problem comes when we try to find the least common supertype of array(xs:error) and array(array(xs:integer)), which Type.getCommonSuperType() computes as function(*), and the problem is that function(*) isn't atomizable.

We could do better in computing the least common supertype here. But even if we compute it as function(*), it's wrong to assume that atomisation will fail, because some instances of function(*) (such as arrays of integers) can indeed be atomized.

Actions #2

Updated by Michael Kay 6 months ago

  • Applies to branch 12, trunk added
  • Fix Committed on Branch 12, trunk added
  • Platforms .NET, Java added

A sufficient solution to make this test pass is to make AnyFunctionType.getAtomizedItemType() return xs:anyAtomic rather than null, since null indicates that atomization will always fail, and this is not the case for arrays.

Another sufficient solution is for Type.getCommonSuperType() to return array(*) when both item types are array types.

The other option, of doing early evaluation of the "castable" expression, isn't so easy to implement, and in any case is unrealistic because it's only in test cases that you're likely to find the operand is constant.

I have applied both the previous changes.

Actions #3

Updated by Michael Kay 6 months ago

  • Status changed from New to Resolved
Actions #4

Updated by O'Neil Delpratt 5 months 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

Also available in: Atom PDF