Project

Profile

Help

Bug #3634

closed

Compile-time stack overflow while optimizing FLWOR expression in XQuery

Added by Michael Kay about 6 years ago. Updated about 6 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Internals
Sprint/Milestone:
-
Start date:
2018-01-19
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

A stack overflow occurs while compiling the following query:

for $x in doc("mondial.xml")//country/name

where some $l in /PLAY//LINE satisfies contains($l,$x)

return $x

The key characteristic is that the where clause has a dependency on the context item which means that naive rewriting of the where clause as a filter predicate is not possible.

Actions #1

Updated by Michael Kay about 6 years ago

It's not a tree corruption as initially suspected: it's a looping rewrite sequence. We're first extracting the context item from the where clause to produce something like

let $dot := . return for $x in AAA where f($dot) return $x

and then we're inlining the variable $dot (because there's only one reference to it), which takes us back to the original expression; and so ad infinitum.

The variable inlining should not happen, because the "where" operand is higher-order (it's evaluated more than once in the course of evaluating its parent expression).

Actions #2

Updated by Michael Kay about 6 years ago

In LetExpression.optimize(), the function verifyReferences() successfully builds a reference list of length one, in which the local variable reference is flagged as "inLoop"; but the call on verifyReferences() does not reset the field "hasLoopingReference" - and indeed this field is not re-examined. The subsequent logic only considers the length of the reference list (1) regardless of whether the references are looping references.

Actions #3

Updated by Michael Kay about 6 years ago

  • Applies to branch 9.8, trunk added
  • Fix Committed on Branch 9.8, trunk added

Solved by adding to LetExpression.optimize the condition

if (references.get(0).isInLoop()) {
     considerRemoval = false;
}
Actions #4

Updated by Michael Kay about 6 years ago

  • Status changed from New to Resolved
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.8 added

Bug fix applied in the Saxon 9.8.0.8 maintenance release.

Please register to edit this issue

Also available in: Atom PDF