Project

Profile

Help

Bug #4610

closed

Bug in XPath optimizer with positional filter

Added by Clément Fournier over 2 years ago. Updated almost 2 years ago.

Status:
Closed
Priority:
Low
Assignee:
Category:
Internals
Sprint/Milestone:
-
Start date:
2020-06-23
Due date:
% Done:

100%

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

Description

Hello,

I'm using the XPath engine of Saxon HE 9.8 (JRE). The optimizer fails to optimize the following form of expression

//A[true() = false()]/*[2]

with this exception

net.sf.saxon.trans.XPathException: Axis step child::element() cannot be used here: the context item is absent
	at net.sf.saxon.expr.AxisExpression.typeCheck(AxisExpression.java:115)
	at net.sf.saxon.expr.Operand.typeCheck(Operand.java:185)
	at net.sf.saxon.expr.Expression.typeCheckChildren(Expression.java:554)
	at net.sf.saxon.expr.SubscriptExpression.typeCheck(SubscriptExpression.java:58)
	at net.sf.saxon.expr.FilterExpression.optimize(FilterExpression.java:446)
	at net.sf.saxon.expr.Operand.optimize(Operand.java:200)
	at net.sf.saxon.expr.SlashExpression.optimize(SlashExpression.java:345)
	at net.sf.saxon.expr.Operand.optimize(Operand.java:200)
	at net.sf.saxon.expr.sort.DocumentSorter.optimize(DocumentSorter.java:95)
	at net.sf.saxon.sxpath.XPathEvaluator.createExpression(XPathEvaluator.java:141)

Here is the optimizer trace:

OPT : At line 1 of 
OPT : Replaced general comparison by value comparison
OPT : Expression after rewrite: true() eq false()
OPT : At line 1 of 
OPT : Filter expression eliminated because predicate is always false
OPT : Expression after rewrite: ()
OPT : At line 1 of 
OPT : Rewriting numeric filter expression with constant subscript
OPT : Expression after rewrite: child::element()[2]
OPT : At line 1 of 
OPT : Rewrote Filter Expression as:
OPT : Expression after rewrite: child::element()[2]

The following all work and are reduced to the empty sequence:

//A[true() = false()]/*[1]


//A[false()]/*[2]
()/*[2]

The latter two being the reduction steps that the optimization of the offending query is supposed to take.

The reason is not that I'm writing literally true() = false(), but I'm inlining some statically known variables.

On Saxon HE 9, this doesn't cause an exception but the following warning:

Warning on line 1 column 5 
  Evaluation will always throw a dynamic error: Axis step child::element() cannot be used here:
  the context item is absent

and the evaluation does not throw a dynamic error.

I didn't test on previous versions of Saxon.

For reference, context around line 115 is the following:

    public Expression typeCheck(ExpressionVisitor visitor, ContextItemStaticInfo contextInfo) throws XPathException {
        boolean noWarnings = ...;
        doneTypeCheck = true;
        if (contextInfo.getItemType() == ErrorType.getInstance()) {
            XPathException err = new XPathException("Axis step " + toString() +
                                                            " cannot be used here: the context item is absent");
            // ...
            throw err;
       }
    ...

This should probably have another check for whether the contextInfo is the empty sequence.


Related issues

Copied to Saxon - Bug #5361: Bug in XPath optimizer with positional filter, when LHS of filter is empty sequenceClosedMichael Kay2020-06-23

Actions

Please register to edit this issue

Also available in: Atom PDF