Skip to content

[bugfix] Preserve in-scope namespaces when copying XQueryContext#6329

Open
joewiz wants to merge 2 commits into
eXist-db:developfrom
joewiz:bugfix/xq31-set-ops-namespace-context
Open

[bugfix] Preserve in-scope namespaces when copying XQueryContext#6329
joewiz wants to merge 2 commits into
eXist-db:developfrom
joewiz:bugfix/xq31-set-ops-namespace-context

Conversation

@joewiz
Copy link
Copy Markdown
Member

@joewiz joewiz commented May 10, 2026

Summary

  • Fixes XQuery's XQueryContext copy constructor to also copy inScopeNamespaces, not just staticNamespaces.
  • Closes 23 spurious XPST0081 failures in the XQ 3.1 XQTS conformance suite (op-intersect, op-union, op-except).

Why

The tree parser uses a copy of the supplied XQueryContext as its lookup staticContext (see XQueryTree.g:94). When a host application registers prefixes via declareInScopeNamespace(prefix, uri) before compilation -- the API the exist-xqts-runner uses to apply each test's <environment><namespace prefix="..." uri="..."/> declaration -- the copy dropped them. Path-step QName.parse(staticContext, ...) then could not resolve the prefix and threw XPST0081 with the misleading message No namespace defined for prefix <eqname> (where <eqname> is the entire prefix:local token because that is what eq.getText() returns at the catch site in the tree parser).

The copy constructor previously preserved every other piece of static-context state -- decimal formats, default namespaces, declared functions, modules, etc. -- but inScopeNamespaces was overlooked. The fix adds the same kind of straightforward map copy.

What changed

  • exist-core/src/main/java/org/exist/xquery/XQueryContext.java: in the XQueryContext(XQueryContext copyFrom) constructor, after copying staticNamespaces, also copy inScopeNamespaces and inScopePrefixes.
  • exist-core/src/test/java/org/exist/xquery/InScopeNamespaceCompileTest.java: new regression test mirroring the failing XQTS scenarios. Compiles (/atomic:root/atomic:integer) intersect/union/except (/atomic:root/atomic:integer) (plus a plain path baseline) after registering the atomic prefix via declareInScopeNamespace. Each test fails on develop and passes with the fix.

Spec references

  • W3C XQuery 3.1 2.1.1 Static Context -- "statically known namespaces" includes both prolog declarations and host-supplied bindings.
  • W3C XQTS catalog: <environment><namespace> (source) is the standard mechanism for an XQTS test environment to declare statically-known namespaces.

XQTS before/after (XQ 3.1 develop, op-intersect/union/except, same runner JAR)

Test set XPST0081 before XPST0081 after
op-intersect 8 0
op-union 8 0
op-except 7 0
Total 23 0

(Other failures in these test sets -- mostly XQST0031 from XQ10+ tests being forced to xquery version "4.0" by a runner-side change -- are unrelated to this fix and unchanged.)

Test plan

  • Targeted reproducer (InScopeNamespaceCompileTest) fails on develop, passes with fix
  • mvn test -pl exist-core (6,703 tests, 0 failures, 105 skipped) -- the one pre-existing parallel-test classloader flake (DeepEmbeddedBackupRestoreTest / NoClassDefFound) passes in isolation
  • XQTS 3.1 op-intersect, op-union, op-except: 23 XPST0081 failures eliminated, no other regressions in those sets
  • PMD/Codacy: no new warnings on XQueryContext.java

[This response was co-authored with Claude Code. -Joe]

Note on test isolation

mvn test -pl exist-core showed one parallel-suite flake that passes when re-run in isolation. Per feedback_distinguish_ci_failure_shapes.md this is a classloader-isolation symptom, not a fix-introduced regression — the fix only touches XQueryContext's copy constructor (10 lines, additive — copies two existing fields that were silently dropped) and the new InScopeNamespaceCompileTest runs cleanly in isolation. Calling it out here so reviewers don't have to re-verify.

The XQueryContext copy constructor copied staticNamespaces (prolog
"declare namespace" entries) but dropped inScopeNamespaces. The tree
parser uses the copy as its lookup context (XQueryTree.g:94), so any
prefix a host application registered via declareInScopeNamespace
before compilation -- the API the XQTS runner uses to apply each
test's <environment><namespace>... declarations -- was invisible to
QName.parse() during tree-walk and produced spurious XPST0081 errors.

Closes 23 XQ 3.1 XQTS failures across op-intersect, op-union, and
op-except (the fn-{intersect,union,except}-node-args tests using the
"atomic" environment), plus partial relief for prod-* tests that go
through the same code path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@joewiz joewiz requested a review from a team as a code owner May 10, 2026 04:09
}
}

// Copy in-scope namespaces too. Hosts (e.g. the XQTS runner) register
Copy link
Copy Markdown
Member

@line-o line-o May 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would shorten this comment to

Copy in-scope namespaces registered via declareInScopeNamespace. Otherwise QName.parse()
will raise error XPST0081 when resolving path-step names in any of those

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[This response was co-authored with Claude Code. -Joe]

Done in 5a91572f5d — applied your exact suggested wording.

…r line-o

Apply line-o's exact suggested wording from the PR eXist-db#6329 review thread.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@line-o line-o added the xquery issue is related to xquery implementation label May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

xquery issue is related to xquery implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants