Project

Profile

Help

Bug #5361

closed

Bug in XPath optimizer with positional filter, when LHS of filter is empty sequence

Added by Clément Fournier about 2 years ago. Updated about 2 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
XPath conformance
Sprint/Milestone:
-
Start date:
2020-06-23
Due date:
% Done:

100%

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

Description

Hello,

This is a similar issue and context to #4610.

I'm using the XPath engine of Saxon HE 10.6 (JRE) and inlining statically known variables. The optimizer fails to reduce the following expression to () when $foo is replaced with false():

//A[$foo][child::*[2]]

with 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

Note that if you write //A[false()][child::*[2]], the parser does some early optimization, prunes the branch, and the optimizer isn't run at all. Only if you use a variable and set its static value to false() in IndependentContext::bindVariable, you get the bug. You can find a MWE attached.

Also note that the following work fine:

//A[$foo]/*[2]
//A[$foo=true()][child::*[2]]

I reproduced the issue on Saxon HE 10.2 and 10.6.

While debugging I found that the offending expression is represented like so:

(/)/((descendant::element(Q{}A)[false()])[child::element()[2]])
     ------------------------------------    

Then, the LHS of the FilterExpression (underlined part above) is reduced to (). At this point the entire FilterExpression could already be folded to (), but optimization of the FilterExpression continues by optimizing the filter child::element()[2]. This is initially a FilterExpression and is replaced by a SubscriptExpression. Type checking the SubscriptExpression fails with "the context item is absent" (the warning is reported at this point) and the SubscriptExpression becomes error("Axis step child::element() cannot be used here: the context item is absent")[2]. This shouldn't have to happen as the LHS of the filter is ().

A possible fix would be to end the optimization of a FilterExpression as soon as the LHS has been optimized to (), without considering the predicate.


Files

SaxonMwe.java (1.55 KB) SaxonMwe.java MWE java class Clément Fournier, 2022-02-27 17:17

Related issues

Copied from Saxon - Bug #4610: Bug in XPath optimizer with positional filterClosedMichael Kay2020-06-23

Actions
Actions #1

Updated by Clément Fournier about 2 years ago

  • Copied from Bug #4610: Bug in XPath optimizer with positional filter added
Actions #2

Updated by Michael Kay about 2 years ago

Thanks for reporting it. I've reproduced it.

Note that the problem doesn't occur when using the s9api API:

            Processor proc = new Processor(false);
            XPathCompiler compiler = proc.newXPathCompiler();
            compiler.declareVariable(new QName("", "falseVar"), ItemType.BOOLEAN, OccurrenceIndicator.ONE);
            XPathSelector exp = compiler.compile("//A[$falseVar=true()][child::*[2]]").load();

The API you are using is a Saxon internal API that's really only retained for legacy reasons. But I'll investigate to see why there's a difference.

Actions #3

Updated by Michael Kay about 2 years ago

The reason for the difference is that the s9api API gives you no way to bind a value to the variable at compile time, it can only be bound at run-time.

Actions #4

Updated by Michael Kay about 2 years ago

In FilterExpression.optimize(), changing

        getLhs().optimize(visitor, contextItemType);

to

        getLhs().optimize(visitor, contextItemType);
        if (Literal.isEmptySequence(getSelectExpression())) {
            return getSelectExpression();
        }
Actions #5

Updated by Michael Kay about 2 years ago

  • Category changed from Internals to XPath conformance
  • Status changed from New to Resolved
  • Priority changed from Low to Normal
  • Applies to branch 11, 9.9, trunk added
  • Fix Committed on Branch 10, 11, trunk added
  • Fix Committed on Branch deleted (9.9)
  • Platforms .NET, Java added

Patch committed on 10.x, 11.x, and 12.x branches.

Actions #6

Updated by Michael Kay about 2 years ago

Note: I think bug #4610 fixed the problem for the case where the reduction of the predicate to false() happened during the typecheck phase, but not when it happened during the optimize() phase.

Actions #7

Updated by Debbie Lockett about 2 years ago

  • Fixed in Maintenance Release deleted (10.0)
Actions #8

Updated by Debbie Lockett about 2 years ago

  • Fixed in Maintenance Release 10.7 added

Bug fix applied in the Saxon 10.7 maintenance release. (Leaving open awaiting Saxon 11 maintenance release.)

Actions #9

Updated by Clément Fournier about 2 years ago

Thanks for the quick reaction! I understand I should probably use the s9api instead of this legacy API... For optimization purposes though it's really nice to be able to bind variables at compile-time. Are there any plans to add support for that?

Actions #10

Updated by O'Neil Delpratt about 2 years ago

  • Status changed from Resolved to Closed
  • Fixed in Maintenance Release 11.3 added
  • Fixed in Maintenance Release deleted (10.7)

Bug fix applied in the Saxon 11.3 maintenance release.

Actions #11

Updated by O'Neil Delpratt about 2 years ago

  • Fixed in Maintenance Release 10.7 added

Please register to edit this issue

Also available in: Atom PDF