#152 Stack overflow compiling *[.+current()=1]

v7.6.5
closed
Michael Kay
5
2012-10-08
2003-08-14
Michael Kay
No

When compiling the expression

*[.+current()=1]

infinite recursion occurs in the compiler. The stack
trace indicates mutual recursion between the following
two calls:

net.sf.saxon.expr.Assignation.analyze(Assignation.java:131)
net.sf.saxon.expr.FilterExpression.analyze(FilterExpression.java:192)

Explanation:

In the first phase of optimization, the expression

*[. + current()=1]

is rewritten as

let $x := .
return *[.+$x = 1]

Unfortunately the static type of $x isn't being
calculated accurately enough, so the next phase
rewrites this as:

let $x := .
return *[.+$x[1] = 1]

Which then becomes:

let $x := .
let $y := $x[1]
return *[.+$y = 1]

and then

let $x := .
let $y := $x[1]
let $z := $y[1]
return *[.+$z = 1]

and so ad infinitum

The fix is to replace line 151 in PromotionOffer.java, viz:

decl.setRequiredType(SequenceType.ANY_SEQUENCE);

with:

SequenceType type =
new SequenceType(child.getItemType(), Type.ITEM,
child.getCardinality());
decl.setRequiredType(type);

The only circumvention that comes to mind is to rewrite

.+current() = 1

as

current() = 1-.

Occurs in 7.6.5 only, as far as I know.

Test case added, bug96

Discussion