Skip to content

Sub-SELECT correlation var produced by an inner aggregate is not join-enforced #1388

Description

@bplatz

Problem

When a sub-SELECT exposes a correlation variable that it produces via an aggregate (or BIND/OPTIONAL) rather than a top-level triple, the natural join with the enclosing pattern is not enforced on that variable. Rows that should be filtered out by the join survive with the parent's binding.

Repro

SELECT ?s
WHERE {
  ?s :p ?c .
  {
    SELECT ?s (COUNT(?x) AS ?c)
    WHERE { ?s :r ?x }
    GROUP BY ?s
  }
}

Data: ex:a :p 2 ; :r ex:x1, ex:x2 (COUNT=2, matches :p) and ex:b :p 5 ; :r ex:y1 (COUNT=1, does NOT match :p=5).

Expected: only ex:a (the :p ?c == COUNT equality must hold).
Actual: both ex:a and ex:b returned — the ?c equality is never checked.

Root cause

In fluree-db-query/src/subquery.rs, the materialize-once hash join keys only on join_keys (correlation vars the subquery produces via a top-level required triple). A correlation var produced by an aggregate is excluded from join_keys, and the non-clobbering merge (subquery.rs:~420-430) keeps the parent's value without an equality check. So the join degenerates to the other keys (here ?s) only.

Scope / status

Suggested fix direction

Either include aggregate/BIND-produced correlation vars in the post-join equality check (filter merged rows where the parent binding ≠ the subquery binding for such vars), or extend the hash key to cover them. Needs care for the unbound-compatible case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions