Fix #2205: context problem with map:get() in xpath predicate#6088
Open
joewiz wants to merge 1 commit intoeXist-db:developfrom
Open
Fix #2205: context problem with map:get() in xpath predicate#6088joewiz wants to merge 1 commit intoeXist-db:developfrom
joewiz wants to merge 1 commit intoeXist-db:developfrom
Conversation
0aabb46 to
a122438
Compare
Member
Author
|
cc/ @djbpitt |
Fix eXist-db#2205: When a predicate like [@K2 = map:get($map, @k1)] is evaluated against stored nodes, the nodeSetCompare() else branch in GeneralComparison evaluated the right operand with contextSequence (the entire node set) rather than per-node. This caused @k1 to resolve against all nodes at once, producing XPTY0004 errors. Fix the else branch to use the context chain (item.getContext()) when available, mirroring the if-branch's per-node evaluation via context.getNode().toSequence(). Falls back to contextSequence only when no context chain exists. Add regression tests for the = (general comparison) and eq (value comparison) variants, plus a performance benchmark for predicate evaluation with context-dependent right operands. Closes eXist-db#2205 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
a122438 to
eea8395
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
GeneralComparison.nodeSetCompare()else branch to evaluate the right operand per-node using the context chain (item.getContext().getNode()) instead of the entirecontextSequence. This resolvesXPTY0004errors when predicates like[@k2 = map:get($map, @k1)]are evaluated against stored (on-disk) nodes.=(general comparison) andeq(value comparison) variants of the bug.GeneralComparisonBenchmarkfor measuring predicate evaluation performance (guarded by-Dexist.run.benchmarks=true).Root cause
In
nodeSetCompare(), the else branch (used when the context documents contain the node documents) evaluated the right operand withcontextSequence(the whole node set) andnullcontextItem. Formap:get($map, @k1), this caused@k1to resolve against all nodes at once instead of per-node, producing multiple values where a single one was expected.The fix mirrors the if-branch's approach: use
context.getNode().toSequence()to evaluate the right operand against the correct parent element for each node.Performance benchmark
GeneralComparisonBenchmarkis excluded from the normal test suite (the class name does not match Surefire's*Testdiscovery pattern, and anAssumeguard requires-Dexist.run.benchmarks=true). To run it:mvn test -pl exist-core -Dtest=GeneralComparisonBenchmark \ -Dexist.run.benchmarks=true -Ddependency-check.skip=trueBenchmarked with an embedded eXist instance, 3 warmup + 5 measured iterations per query. Two query types exercise the unchanged code path (no context chain needed); two exercise the changed code path (context-dependent right operand).
@v = 'v0'(literal)@v = $x(variable)@v = map:get($map, @k)@v = local:get(@k)Key takeaways:
map:get,local:get) crashed on develop withXPTY0004and now work correctly at reasonable latency on the fix branch.if (ctxItem != null)branch check per node — negligible overhead.Test plan
xquery.optimizer.OptimizerTests— 60/60 passed (includes 2 new regression tests)xquery.dates.DateTests— 121/121 passed (no regressions)xquery.maps.MapTests— 124/124 passed (no regressions)exist-coretest suite — 6496 tests, 0 failures, 0 errorsGeneralComparisonBenchmark— all 4 query variants pass at 3 data sizes🤖 Generated with Claude Code