exist
exist copied to clipboard
[BUG] XQuery simple node selection return duplicate nodes
Describe the bug
Given XML document:
<A1 id="1">
<B2 id="2">1</B2>
<C1 id="3">
<B2 id="4">1</B2>
</C1>
</A1>
and XPath query:
//*//B2
Exist db returns
<B2 id="2">1</B2>
<B2 id="4">1</B2>
<B2 id="4">1</B2>
Expected behavior
Should return
<B2 id="2">1</B2>
<B2 id="4">1</B2>
as BaseX and Saxon
To Reproduce
- Go to Java admin client
- Add XML document to collection
- Use find command to execute XPath Query
- See error (shows there are three hits)
Context (please always complete the following information)
- Build: latest development version built from source, commit b700a92
- Java: 17
- OS: [Windows]
Additional context
- How is eXist-db installed? Jar installer
- Any custom changes in e.g.
conf.xml? No
Are there any indexes defined?
I can reproduce this in eXist 6.2.0:
xquery version "3.1";
module namespace t="http://exist-db.org/xquery/test";
declare namespace test="http://exist-db.org/xquery/xqsuite";
declare variable $t:XML := document {
<A1 id="1">
<B2 id="2">1</B2>
<C1 id="3">
<B2 id="4">1</B2>
</C1>
</A1>
};
declare
%test:setUp
function t:setup() {
let $testCol := xmldb:create-collection("/db", "test")
return
xmldb:store("/db/test", "test.xml", $t:XML)
};
declare
%test:tearDown
function t:tearDown() {
xmldb:remove("/db/test")
};
declare
%test:assertEquals("2")
function t:test() {
doc("/db/test/test.xml")//*//B2
=> count()
};
The test result showing the failure:
<testsuite errors="0" failures="1" package="http://exist-db.org/xquery/test" pending="0" tests="1"
time="PT0.002S" timestamp="2023-03-20T16:39:05.398-04:00">
<testcase class="t:test" name="test">
<failure message="assertEquals failed." type="failure-error-code-1">2</failure>
<output>3</output>
</testcase>
</testsuite>
@joewiz Thanks for the test case :-)
One request - If you wouldn't mind... Could you avoid arrow operators in your XQSuite tests unless they are absolutely necessary please, as it makes it much easier for me to debug with the Java debugger. Additional things to avoid unless necessary are: maps, arrays, partial functions, higher-order-functions, simple mapping operator, arrow operator, string constructors. Basically the simpler the query (e.g. as close to XQuery 1.0 as possible) the easier it is for me to debug (with the Java debugger).
Are there any indexes defined?
There is no index defined :)
@adamretter Good to know! With that in mind, here's a new revision. Besides eliminating the arrow operator, I trimmed the test XML file, and added an in-memory test, which passes.
xquery version "3.1";
module namespace t="http://exist-db.org/xquery/test";
declare namespace test="http://exist-db.org/xquery/xqsuite";
declare variable $t:XML := document {
<A>
<B/>
<C>
<B/>
</C>
</A>
};
declare
%test:setUp
function t:setup() {
xmldb:create-collection("/db", "test"),
xmldb:store("/db/test", "test.xml", $t:XML)
};
declare
%test:tearDown
function t:tearDown() {
xmldb:remove("/db/test")
};
declare
%test:assertEquals("2")
function t:test-db() {
count(
doc("/db/test/test.xml")//*//B
)
};
declare
%test:assertEquals("2")
function t:test-mem() {
count(
$t:XML//*//B
)
};
The results:
<testsuite errors="0" failures="1" package="http://exist-db.org/xquery/test" pending="0" tests="2"
time="PT0.002S" timestamp="2023-03-20T23:24:56.365-04:00">
<testcase class="t:test-db" name="test-db">
<failure message="assertEquals failed." type="failure-error-code-1">2</failure>
<output>3</output>
</testcase>
<testcase class="t:test-mem" name="test-mem"/>
</testsuite>
@adamretter are you actively working on this issue?