Project

Profile

Help

Bug #5281

closed

Incorrect results from $var[last() on Saxon 11.1

Added by Gunther Rademacher about 2 years ago. Updated about 2 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
XPath conformance
Sprint/Milestone:
-
Start date:
2022-02-04
Due date:
% Done:

100%

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

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

repro.xq (5.23 KB) repro.xq Gunther Rademacher, 2022-02-04 17:42
Actions #1

Updated by Michael Kay about 2 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!

Actions #2

Updated by Michael Kay about 2 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.

Actions #3

Updated by Michael Kay about 2 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.

Actions #4

Updated by Michael Kay about 2 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.

Actions #5

Updated by Michael Kay about 2 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
Actions #6

Updated by Gunther Rademacher about 2 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.

Actions #7

Updated by Debbie Lockett about 2 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

Also available in: Atom PDF