Project

Profile

Help

Bug #5110

XPDY0002 The context item is absent, so position() is undefined for use of position() inside predicate

Added by Martin Honnen 18 days ago. Updated 12 days ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
XQuery conformance
Sprint/Milestone:
Start date:
2021-09-30
Due date:
% Done:

0%

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

Description

I get the error

Error on line 8 column 29 of powerset1.xq:
  XPDY0002  The context item is absent, so position() is undefined
     Focus: absent
     Local variables
        $counter = 0
        $input =  ("A", "B", "C", ... [4])
        $counter-bin = xs:base64Binary("AA==")
     invoked by unknown caller (class net.sf.saxon.value.MemoClosure)
     Focus: absent
     Local variables
        $counter = 0
        $input =  ("A", "B", "C", ... [4])
     invoked by function call at file:/C:/Users/Martin%20Honnen/OneDrive/Documents/XQuery/powerset/./powerset1.xq#17
     Focus: absent
     Local variables
        $a = []
        $i = 0
        $input =  ("A", "B", "C", ... [4])
     invoked by unknown caller (class net.sf.saxon.functions.hof.UserFunctionReference$BoundUserFunction)

running Saxon 10.6 EE Java against the XQuery

declare namespace math = 'http://www.w3.org/2005/xpath-functions/math';
declare namespace bin = 'http://expath.org/ns/binary';
declare namespace array = 'http://www.w3.org/2005/xpath-functions/array';

declare function local:combination($counter as xs:integer, $input as item()*) as item()* {
   let $counter-bin := bin:from-octets($counter)
   return $input[
     let $j:= position() - 1,
     $bin := bin:and($counter-bin, bin:shift(bin:hex('1'), $j)) 
     return bin:to-octets($bin) > 0]
 };
 
declare function local:powerset($input as item()*) as array(item()*) {
  fold-left(
    0 to (xs:integer(math:pow(2, count($input))) - 1),
    [],
    function($a, $i) { array:append($a, local:combination($i, $input)) }
   )
 };
 
local:powerset(('A', 'B', 'C', 'D'))

The code runs fine with BaseX, outputting [(), "A", "B", ("A", "B"), "C", ("A", "C"), ("B", "C"), ("A", "B", "C"), "D", ("A", "D"), ("B", "D"), ("A", "B", "D"), ("C", "D"), ("A", "C", "D"), ("B", "C", "D"), ("A", "B", "C", "D")].

History

#1 Updated by Martin Honnen 17 days ago

If I turn off any optimization with e.g. -opt:0 (and add declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; declare option output:method 'adaptive';) to code gives the wanted result.

#2 Updated by Michael Kay 12 days ago

Added as a test case to EXPath-binary-extra/EXPath-binary-powerset.

Problem reproduced.

#3 Updated by Michael Kay 12 days ago

In FilterExpression.java, evaluating $input[....], it has wrongly decided that the value of the predicate is independent of the focus.

When first calculated in FilterExpression.typeCheck(), the value of filterIsIndependent' is correctly set to false(andfilterIsPositionalis correctly set totrue`).

But in the optimize() phase, the re-calculation of filterIsPositional at line 389 wrongly sets it to false. Though on exit from optimize(), filterIsIndependent' is still correctly set to false`.

But then we attempt to rewrite the FLWOR expression as a "for" or "let" expression, which re-does the typeCheck() on the FilterExpression, and this time filterIsIndependent becomes true.

#4 Updated by Michael Kay 12 days ago

Note that the test runs correctly on the 11 branch.

I suspect (with no evidence) that the difference might be that the calls on bin:xx() functions are now implemented as integrated extension functions rather than reflexive extension functions, which may mean that they are handling context-dependent subexpressions better.

#5 Updated by Michael Kay 12 days ago

Correction: it doesn't work on the 11 branch. It no longer crashes, but it produces wrong output. The result on SaxonJ is

AA BB AA BB CC AA CC BB CC AA BB CC DD AA DD BB DD AA BB DD CC DD AA CC DD BB CC DD AA BB CC DD

and on SaxonCS we get

A B A B C A C B C A B C D A D B D A B D C D A C D B C D A B C D

(which is the same sequence without the doubling)

#6 Updated by Michael Kay 12 days ago

If I run under SaxonCS with !method=adaptive, the output is

[(),"A","B",("A","B"),"C",("A","C"),("B","C"),("A","B","C"),"D",("A","D"),("B","D"),("A","B","D"),("C","D"),("A","C","D"),("B","C","D"),("A","B","C","D")]

which is the same as BaseX. Phew!!!

#7 Updated by Michael Kay 12 days ago

The difference between the J and CS behaviour on the 11 branch is purely by chance. There is a bug in UTF8Writer.write(UnicodeString) whereby if the UnicodeString is a UnicodeChar, then the character is written twice. This bug doesn't affect the query as I was running it in SaxonCS because the output is being sent to a writer, not a stream, so the UTF8Writer is not used. But the UTF8Writer is present in SaxonCS and the bug could manifest itself under different circumstances.

Please register to edit this issue

Also available in: Atom PDF