Bug #2571
closedXQuery group-by leads to "Local variable $x has not been allocated a stack frame slot"
100%
Description
Reported by Hans-Juergen Rennau in email to MHK. The query:
let $doc := doc('problem-input.xml')
let $targets :=
for $xincludeGroup in $doc//xi:include
group by $href := $xincludeGroup/@href
order by $href
return <target href="{$href}"/>
return
<targets>{$targets}</targets>
fails with:
java.lang.ArrayIndexOutOfBoundsException: Local variable $xincludeGroup has not been allocated a stack frame slot
at net.sf.saxon.expr.LocalVariableReference.evaluateVariable(LocalVariableReference.java:114)
at net.sf.saxon.expr.flwor.TupleExpression.evaluateItem(TupleExpression.java:122)
at net.sf.saxon.expr.flwor.OrderByClausePush.processTuple(OrderByClausePush.java:50)
at net.sf.saxon.expr.flwor.GroupByClausePush.close(GroupByClausePush.java:100)
at net.sf.saxon.expr.flwor.LetClausePush.close(LetClausePush.java:44)
at net.sf.saxon.expr.flwor.ForClausePush.close(ForClausePush.java:53)
The problem occurs in the latest 9.6 build but not in 9.7
Updated by Michael Kay almost 9 years ago
What seems to be happening is as follows. In theory, there should be both a pre-grouping value for $xincludeGroup (containing a single item, the value before the group-by processing) and a post-grouping value with the same variable name, holding the set of all the values for the group. Because there is no reference to the post-grouping variable of this name, it seems to have been optimized away (and therefore, not allocated a slot number). But the order by clause doesn't seem aware that the variable has been optimized away; its TupleExpression is expected to contain a binding for this variable.
Updated by Michael Kay almost 9 years ago
During optimization of the outer FLWOR expression, the variable $targets is inlined. As described in bug #2556, this results in an unnecessary (but not intrinsically incorrect) copy operation on the inner FLWOR expression. This copy operation has a bug: the LocalVariableBinding objects used to represent the synthetic post-grouping variables (specifically the post-grouping version of the $xincludeGroup variable) have their reference counts set to zero. The reference counts are not recomputed after the rewrite, and consequently in the next phase of optimization the variable binding is considered to be unreferenced and is therefore dropped (without, of course, removing the reference to the variable).
Fixing the copy() operation on LocalVariableReference to preserve the reference count appears to solve the problem (but not yet regression-tested).
On the 9.7 branch, the problem no longer surfaces because the fix to bug #2556 eliminates the unnecessary copy operation. However, the copy() operation on LocalVariableReference is still incorrect, it just doesn't get exercised by this test case. I think it is therefore prudent to apply the same patch.
Updated by Michael Kay almost 9 years ago
- Status changed from New to Resolved
- Applies to branch 9.7 added
- Fix Committed on Branch 9.6, 9.7 added
Patch committed to LocalVariableBinding.copy() on both 9.6 and 9.7 branches.
Updated by O'Neil Delpratt almost 9 years ago
- % Done changed from 0 to 100
- Fixed in Maintenance Release 9.7.0.2 added
Bug fix applied in the Saxon 9.7.0.2 maintenance release
Updated by O'Neil Delpratt almost 9 years ago
- Fixed in Maintenance Release 9.7.0.3 added
- Fixed in Maintenance Release deleted (
9.7.0.2)
Bug fix applied in the 9.7.0.3 maintenance release. Leave open until fix applied in the 9.6 branch
Updated by O'Neil Delpratt over 8 years ago
- Status changed from Resolved to Closed
- Fixed in Maintenance Release 9.6.0.9 added
- Fixed in Maintenance Release deleted (
9.7.0.3)
Bug fix applied in the Saxon 9.6.0.9 maintenance release.
Updated by O'Neil Delpratt over 8 years ago
- Fixed in Maintenance Release 9.7.0.3 added
Please register to edit this issue