Skip to content

docs: add sparql-quirks.md with the GRAPH/OPTIONAL gotcha#107

Merged
tkuhn merged 2 commits into
mainfrom
docs/sparql-quirks
May 22, 2026
Merged

docs: add sparql-quirks.md with the GRAPH/OPTIONAL gotcha#107
tkuhn merged 2 commits into
mainfrom
docs/sparql-quirks

Conversation

@tkuhn
Copy link
Copy Markdown
Contributor

@tkuhn tkuhn commented May 22, 2026

Summary

Adds doc/sparql-quirks.md with two RDF4J/SPARQL traps encountered while building consumer queries against /repo/spaces for nanodash (knowledgepixels/nanodash#468):

  1. GRAPH ?x { OPTIONAL { ... } } drops the row when the inner pattern is unmatched — pull the OPTIONAL outside. Bit nanodash twice.
  2. The npa:hasCurrentSpaceState pointer pattern can blow up the planner when the pattern under GRAPH ?g has multiple cross-graph joins + a UNION — same query with a hardcoded state-graph IRI runs in well under a second; the variable-?g form 504s after 60s. Materialiser code isn't affected (it formats the IRI as a Java string), but consumers that follow the documented pattern verbatim can hit it.

Happy to move the file or restructure if there's a better spot — CONTRIBUTING.md? A "Consumer notes" section in design-space-repositories.md?

Test plan

  • Doc-only change.

🤖 Generated with Claude Code

tkuhn and others added 2 commits May 22, 2026 13:49
Captures the RDF4J semantics for `GRAPH ?x { OPTIONAL { ... } }` —
it returns zero solutions when the inner pattern is unmatched, so the
surrounding row is filtered out even though the inner pattern is
optional. Workaround: `OPTIONAL { GRAPH ?x { ... } }`.

Bit a nanodash spaces-repo consumer twice
(see knowledgepixels/nanodash#468). Putting the note here so the next
person doesn't lose an afternoon to the same trap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
For complex consumer queries (multiple cross-graph joins + a UNION
inside GRAPH ?g), resolving the npa:hasCurrentSpaceState pointer with
a variable ?g can trigger an RDF4J planner blow-up that 504s — where
the same query with a hardcoded state-graph IRI runs in under a second.
The materialiser doesn't hit this because it formats the IRI as a Java
string, not a SPARQL variable; the trap is specific to consumers that
follow the documented pointer-resolution pattern verbatim.

Documents the workaround (resolve once, inline the constant) without
proposing a server-side fix — the planner behaviour is what it is, and
the recommended pattern still works for the simple cases that dominate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tkuhn tkuhn merged commit ed0f1d7 into main May 22, 2026
8 checks passed
@github-actions
Copy link
Copy Markdown

🎉 This PR is included in version 1.14.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant