The issue is JAVA Bindings for BAseX version <= 7.7, illustrated by the following XQUERY code
import module namespace set = "java.util.HashSet";{
let $loop :=
for $i in 1 to 128
return set:add($i)
let $loop :=
for $i in 1 to 128
return set:add($i)
return
set:size()
}
returning .. 129 (expected 128)
Explanation : (courtesy by Christian Gruen)
set:add
function is no integer-specific function, so it allows all types of objects as argument.xs:integer
and in the range of 0-127 are cached. This means that if an integer like 84
is requested twice, the returned item will have the same reference in memory.127
: in this case, new references will be created. As XQuery items have nohashCode()
function, their memory reference will be used when calculating the hash code.
WorkAround :
preferred : Last Stable Release 7.8 solves the issue.
Other workaround :
- Use the map:module to simulate HashSet (well, I do confess that I do not know how to achieve this)
- wrap the JAVA Class in order to manage directly this issue (by forcing cast operation in your wrapper), then import your wrapper as a module in BAseX