From ba269cb8167e2bd9fa811ccf2008b89d9e131174 Mon Sep 17 00:00:00 2001 From: Robin6939 Date: Mon, 7 Jul 2025 11:32:22 +0530 Subject: [PATCH 1/3] [bugfix] #4958 return false() from empty nodeSetCompare --- .../org/exist/xquery/GeneralComparison.java | 3 ++ exist-core/src/test/xquery/emptySeq.xq | 38 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 exist-core/src/test/xquery/emptySeq.xq diff --git a/exist-core/src/main/java/org/exist/xquery/GeneralComparison.java b/exist-core/src/main/java/org/exist/xquery/GeneralComparison.java index d277e81f75..30037df7e5 100644 --- a/exist-core/src/main/java/org/exist/xquery/GeneralComparison.java +++ b/exist-core/src/main/java/org/exist/xquery/GeneralComparison.java @@ -648,6 +648,9 @@ protected Sequence nodeSetCompare( NodeSet nodes, Sequence contextSequence ) thr } } } + if (result.isEmpty()) { + return BooleanValue.FALSE; + } } if( context.getProfiler().traceFunctions() ) { diff --git a/exist-core/src/test/xquery/emptySeq.xq b/exist-core/src/test/xquery/emptySeq.xq new file mode 100644 index 0000000000..a3be9ea756 --- /dev/null +++ b/exist-core/src/test/xquery/emptySeq.xq @@ -0,0 +1,38 @@ +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 { + +}; + +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:assertTrue +function t:test-db() { + exists( + doc("/db/test/test.xml")//F[boolean(count(@id >= 2))] + ) +}; + +declare + %test:assertTrue +function t:test-mem() { + exists( + $t:XML//F[boolean(count(@id >= 2))] + ) +}; \ No newline at end of file From 76d220f78f5daa9c61518f8d3e2e167b733a649c Mon Sep 17 00:00:00 2001 From: Robin6939 Date: Mon, 7 Jul 2025 22:45:03 +0530 Subject: [PATCH 2/3] [bugfix] 4810-Fixed comparison and predicate execution --- .../main/java/org/exist/xquery/Predicate.java | 6 +++- exist-core/src/test/xquery/startWithComp.xq | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 exist-core/src/test/xquery/startWithComp.xq diff --git a/exist-core/src/main/java/org/exist/xquery/Predicate.java b/exist-core/src/main/java/org/exist/xquery/Predicate.java index 986de11bb8..2e6719d3a5 100644 --- a/exist-core/src/main/java/org/exist/xquery/Predicate.java +++ b/exist-core/src/main/java/org/exist/xquery/Predicate.java @@ -377,7 +377,11 @@ private Sequence selectByNodeSet(final Sequence contextSequence) throws XPathExc final NodeSet contextSet = contextSequence.toNodeSet(); final boolean contextIsVirtual = contextSet instanceof VirtualNodeSet; contextSet.setTrackMatches(false); - final NodeSet nodes = super.eval(contextSet, null).toNodeSet(); + final Sequence x = super.eval(contextSet, null); + if(!(x instanceof NodeSet)) + return x; + final NodeSet nodes = result.toNodeSet(); + /* * if the predicate expression returns results from the cache we can * also return the cached result. diff --git a/exist-core/src/test/xquery/startWithComp.xq b/exist-core/src/test/xquery/startWithComp.xq new file mode 100644 index 0000000000..78c2ada88a --- /dev/null +++ b/exist-core/src/test/xquery/startWithComp.xq @@ -0,0 +1,32 @@ +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 { + +

true

+
+}; + +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:assertTrue +function t:test() { + doc("/db/test/test.xml")//*[starts-with(@a2, "1") = false()] + => exists() +}; \ No newline at end of file From e100903d9a1bbe5ad02c3abaa95a47e35d862f60 Mon Sep 17 00:00:00 2001 From: Robin6939 Date: Tue, 8 Jul 2025 20:49:53 +0530 Subject: [PATCH 3/3] [Fix] Predicate nodeset to boolean --- .../src/main/java/org/exist/xquery/Predicate.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/exist-core/src/main/java/org/exist/xquery/Predicate.java b/exist-core/src/main/java/org/exist/xquery/Predicate.java index 2e6719d3a5..efe44f256b 100644 --- a/exist-core/src/main/java/org/exist/xquery/Predicate.java +++ b/exist-core/src/main/java/org/exist/xquery/Predicate.java @@ -36,6 +36,7 @@ import org.exist.xquery.value.SequenceIterator; import org.exist.xquery.value.Type; import org.exist.xquery.value.ValueSequence; +import org.exist.xquery.value.BooleanValue; import javax.annotation.Nullable; import java.util.Set; @@ -377,10 +378,13 @@ private Sequence selectByNodeSet(final Sequence contextSequence) throws XPathExc final NodeSet contextSet = contextSequence.toNodeSet(); final boolean contextIsVirtual = contextSet instanceof VirtualNodeSet; contextSet.setTrackMatches(false); - final Sequence x = super.eval(contextSet, null); - if(!(x instanceof NodeSet)) - return x; - final NodeSet nodes = result.toNodeSet(); + final Sequence res = super.eval(contextSet, null); + if(!(res instanceof NodeSet)) { + if(res == BooleanValue.FALSE) + return NodeSet.EMPTY_SET; + return res; + } + final NodeSet nodes = res.toNodeSet(); /* * if the predicate expression returns results from the cache we can