Skip to content

SPARQL: implement FILTER (NOT) EXISTS — lower onto the existing MINUS anti-join machinery #111

Description

@styk-tv

Observed (v0.6.27, source + live)

FILTER EXISTS / FILTER NOT EXISTS are not translatable in any form — plain BGP or GRAPH-wrapped both refuse:

sparql: FILTER expression not translatable: Not(Exists(Bgp { … }))
sparql: FILTER expression not translatable: Not(Exists(Graph { … }))

Source-confirmed: the FILTER→SQL translator has no Expression::Exists arm (src/query/executor.rsExists appears only in the substitution pass, the walker no-op, and the contains-aggregate check). The refusal is honest and stable — never a wrong answer.

Why this matters

Downstream consumers are starting to route around SPARQL entirely for absence checks ("integrity as compiled SQL because SPARQL can't express it"). That belief is half wrong todayMINUS (graph-scoped) and OPTIONAL + FILTER(!BOUND(?x)) both translate and answer correctly, measured live:

# organs with no dependsOn — works on 0.6.27
SELECT ?o WHERE { GRAPH <urn:g> {
  ?o a ckp:Organ MINUS { ?o ckp:dependsOn ?x } } }

# same, negation-by-failure — also works
SELECT ?o WHERE { GRAPH <urn:g> {
  ?o a ckp:Organ . OPTIONAL { ?o ckp:dependsOn ?d } FILTER(!BOUND(?d)) } }

But NOT EXISTS is the form people write first, and the W3C-semantics differences (MINUS ignores disjoint-variable patterns; NOT EXISTS is a correlated anti-join) mean MINUS is not a universal substitute.

Proposal

Lower FILTER (NOT) EXISTS over a BGP onto the existing anti-join machinery: the SQL builder already implements graph-scoped anti-joins for MinusBlock; NOT EXISTS is the correlated variant (join on all shared in-scope variables), EXISTS the semi-join twin. GRAPH-wrapped inner patterns should reuse the same GraphScope plumbing MinusBlock.scope already has. Nested/complex inner patterns (OPTIONAL/UNION inside EXISTS) can stay a named refusal — scope this to the BGP-inner case that covers the integrity-check family.

v0.6.29+ candidate; not for the current release train.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementImprovement to existing behaviour

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions