Support #4932

EE Optimisations introduce bug when dealing with multiple predicates

Added by Tomos Hillman 3 months ago. Updated 2 months ago.

Start date:
Due date:
% Done:


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


Optimisations where the order of predicates are significant are introducing bugs for one of my clients between their development environment (Saxon 9.9 PE) and their production server (Saxon 9.9EE).

The example included in the XSL file (attached) is a good example: one predicate restricts to map entries within a map, the second filters by the presence of a map key within the child map. In PE, this works as expected. In EE, parentheses need to be added.

The problem is exacerbated by the way this is reported: unfortunately I can't yet replicate this part in the simplified code attached, but the error is reported as "E [Saxon-EE 10.3] (External): Internal error: no value for variable $vv:v0 at line 30 of file:/....xsl" - worryingly, in 10.3, this error is thrown even with the parentheses in place, even though the parentheses bypass the problem in 9.9 and 10.

The code where this error is thrown occurs in an xsl:iterate statement within another xsl:iterate statement, if that helps.

bug-report.xsl (1.02 KB) bug-report.xsl Tomos Hillman, 2021-03-10 11:37


#1 Updated by Tomos Hillman 3 months ago

Ignore the bit about 10.3 - further testing leads me to believe that this is a separate issue.

#2 Updated by Michael Kay 3 months ago

I see the error reported in 10.3 as

Type error at char 58 in expression in xsl:variable/@select on line 25 column 110 of bug-report.xsl:
  XPTY0004  The items on the LHS of the '?' operator must be maps or arrays; but value (110)
  was supplied

I think it's perhaps unfortunate that the specification allows predicates to be reordered; it's certainly a reasonable user expectation that the first predicate can be used as a "guard" for the second in this way. But the language spec is explicit that it is allowed: see ยง2.3.4:

The expression in the following example cannot raise a casting error if it is evaluated exactly as written (i.e., left to right). Since neither predicate depends on the context position, an implementation might choose to reorder the predicates to achieve better performance (for example, by taking advantage of an index). This reordering could cause the expression to raise an error.

$N[@x castable as xs:date][xs:date(@x) gt xs:date("2000-01-01")]

To avoid unexpected errors caused by expression rewrite, tests that are designed to prevent dynamic errors should be expressed using conditional expressions. For example, the above expression can be written as follows:

$N[if (@x castable as xs:date) then xs:date(@x) gt xs:date("2000-01-01") else false()]

Saxon has an experimental extension to help with this use case: in the expression A andThen B, it's guaranteed that B won't be evaluated unless A is true.

#3 Updated by Michael Kay 3 months ago

  • Status changed from New to In Progress
  • Assignee set to Michael Kay

#4 Updated by Michael Kay 2 months ago

  • Tracker changed from Bug to Support
  • Status changed from In Progress to Closed

Closing this (feel free to reopen if there is further information). I know the behaviour is not intuitive, but it is explicitly in line with the spec.

Please register to edit this issue

Also available in: Atom PDF