Skip to content

[fix] Preceding/following axes miss nodes when predicates add context tracking#4

Closed
joewiz wants to merge 1 commit intodevelopfrom
claude/analyze-issue-4109-KY2bt
Closed

[fix] Preceding/following axes miss nodes when predicates add context tracking#4
joewiz wants to merge 1 commit intodevelopfrom
claude/analyze-issue-4109-KY2bt

Conversation

@joewiz
Copy link
Copy Markdown
Owner

@joewiz joewiz commented Mar 2, 2026

Closes eXist-db#4109.

Problem

The preceding:: and following:: axes skip nodes when the input node set was produced by an expression with a context-dependent predicate. For example:

(: Expected: w1:pb1, w2:pb1, w3:pb1, w4:pb2, w5:pb2 :)
(: Actual:   w1:pb1, w2:PRECEDING_PB_NOT_FOUND, w3:PRECEDING_PB_NOT_FOUND, w4:pb2, w5:PRECEDING_PB_NOT_FOUND :)
for $w in doc("/db/test/test.xml")//w[exists(.)]
let $preceding-page := $w/preceding::pb[1]
return $w/@id || ":" || ($preceding-page/@id, "PRECEDING_PB_NOT_FOUND")[1]

The predicate [exists(.)] is a no-op logically, but it triggers context tracking: the self:: axis evaluation inside the predicate attaches a context entry to each NodeProxy in the result set. When these nodes are later used as input to preceding:: or following::, the context entries leak through copyContext() into the axis result nodes. The context ID deduplication check in NewArrayNodeSet.selectPreceding() / selectFollowing() then sees a matching context ID and incorrectly skips valid result nodes, treating them as duplicates.

Approach

The fix adds a NO_CONTEXT_ID guard to the existing IGNORE_CONTEXT check in both selectFollowing() and selectPreceding() of NewArrayNodeSet. When contextId is NO_CONTEXT_ID (meaning the axis step is not inside a predicate context tracking scope), the context-based deduplication check is skipped — the same behavior as IGNORE_CONTEXT.

The change is two lines (one per method), following the same pattern already used elsewhere in the codebase where IGNORE_CONTEXT and NO_CONTEXT_ID are treated as equivalent for dedup purposes.

XQTS results

Test set Before (develop) After (this PR) Notes
prod-AxisStep 46 failures 46 failures No change — all pre-existing
prod-AxisStep.following 2 failures 2 failures No change — all pre-existing
prod-AxisStep.preceding 2 failures 2 failures No change — all pre-existing

No regressions introduced.

Note: The XQTS axis tests do not cover the specific scenario of context tracking leaking through predicates on the input expression, which is why there is no XQTS improvement. The issue manifests specifically with persistent (database-stored) nodes and context-dependent predicates on the input node set — a scenario tested by the new XQSuite tests below.

Test plan

  • 4 new XQSuite tests in axes-persistent-nodes.xqm covering both preceding:: and following:: axes with context predicates, in both FLWOR and simple map forms
  • Full eXist test suite: 6,476 tests, 0 failures, 129 skipped
  • XQTS prod-AxisStep, prod-AxisStep.following, prod-AxisStep.preceding: no regressions

🤖 Generated with Claude Code

@joewiz joewiz marked this pull request as draft March 2, 2026 04:19
… tracking

Closes eXist-db#4109.

When a context-dependent predicate like [exists(.)] is applied to the
input expression of a FLWOR for clause or simple map operator, the self
axis evaluation inside the predicate adds context tracking entries to
each NodeProxy. These context entries then leak into the cached result
nodes of subsequent selectPreceding/selectFollowing calls via
copyContext(), causing a false-positive match in the context ID
deduplication check. This makes the axis skip valid result nodes after
the first match per group.

The fix adds a NO_CONTEXT_ID guard to the context deduplication check
in both selectFollowing and selectPreceding of NewArrayNodeSet. When
contextId is NO_CONTEXT_ID, the step is not inside a predicate context
tracking scope, so the deduplication check should not be applied.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@joewiz joewiz changed the title [fix] Preceding/following axes miss nodes when predicates add context… [fix] Preceding/following axes miss nodes when predicates add context tracking Mar 3, 2026
@joewiz joewiz force-pushed the claude/analyze-issue-4109-KY2bt branch from 4d3da04 to 4d294f1 Compare March 3, 2026 00:55
@joewiz
Copy link
Copy Markdown
Owner Author

joewiz commented Mar 3, 2026

migrated to eXist-db#6076

@joewiz joewiz closed this Mar 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Additional bug affecting predicates on preceding and following steps

2 participants