Bug #5281
closedIncorrect results from $var[last() on Saxon 11.1
100%
Description
After updating one of my projects to Saxon 11.1, I see incorrect resuls from a recursive XQuery function. I have boiled this down to a small reproduction in the attached repro.xq, which can be run from command line by
java net.sf.saxon.Query repro.xq
The code contains a recursive function that joins a sequence of string fragments to a multiline string, obeying some interspersed tab directives. The problem is that some fragments just don't appear in the result. The result is correct when running the code on 10.6.
In this particular case, the result will also be correct, when doing one replacement:
(: result will be correct when replacing '$done[last()]' :)
(: in the following line by '$last' :)
string-join(($done[last()], string($item)), " ")
Unfortunately this finding did not yet help creating a workaround in the original code.
Files
Updated by Michael Kay almost 3 years ago
Thanks for reporting it. I've reproduced the results (different in 11.1 and 10.6). The problem will be in the new ZenoString library which is very much designed to give better performance and memory usage in applications that construct strings incrementally and recursively. I'm slightly surprised that there should be a problem with all-ASCII strings since most of the complications are in handling wide characters. Working on it!
Updated by Michael Kay almost 3 years ago
I've got as far as establishing that if you insert the line
if (not($last eq $done[last()])) then trace((), "****BAD****") else (),
before the relevant call on string-join()
then it triggers, and that $done[last()]
is being returned as an empty sequence. $done
holds a MemoClosure
, which has been fully evaluated (as expected, because there has been a previous call to read it to the end). No indication that it has anything to do with ZenoStrings after all.
Updated by Michael Kay almost 3 years ago
It's implementing last()
by getting an iterator, finding it's reversible, then doing getReverseIterator().next()
. The reversible iterator is an array iterator, but getReverseIterator()
is incorrect because it isn't taking account of the fact that the array iterator is only iterating over a portion of the underlying array.
Updated by Michael Kay almost 3 years ago
Fixed in ArrayIterator.getReverseiterator()
.
Note, in 10.x, there was no such method, so $x[last()]
in this situation would have involved reading the whole array to the end.
Updated by Michael Kay almost 3 years ago
- Subject changed from Strange results from XQuery on Saxon 11.1 to Incorrect results from $var[last() on Saxon 11.1
- Category set to XPath conformance
- Status changed from New to Resolved
- Assignee set to Michael Kay
- Priority changed from Low to Normal
- Applies to branch trunk added
- Fix Committed on Branch 11, trunk added
Updated by Gunther Rademacher almost 3 years ago
Thanks for fixing this! Would you mind sharing the fix? I can't find a repository containing fixes, or even current code branches.
Updated by Debbie Lockett almost 3 years ago
- Status changed from Resolved to Closed
- % Done changed from 0 to 100
- Fixed in Maintenance Release 11.2 added
Bug fix applied in the Saxon 11.2 maintenance release.
Please register to edit this issue