Latest Results
fix(sparql): project OneOrMore path branches to endpoints for transitive closure
SPARQL `path+` (OneOrMore) returned no transitive closure for variable
endpoints: it yielded only the direct neighbours, with the true multi-hop
endpoint replaced by the first intermediate hop and duplicate rows that
DISTINCT failed to collapse. The sibling operators `/ | ^ * ?` were all
correct.
`translate_one_or_more_path` pushed each fixed-depth branch raw into the
Union, whereas `translate_zero_or_more_path` and `translate_zero_or_one_path`
wrap every depth branch in `project_path_endpoints` first. Without that
projection the depth-N branches keep their per-hop intermediate columns, the
Union output schema is seeded from the narrow depth-1 branch, and Distinct
copies the leading (intermediate) columns into the endpoint slot while keying
on each chunk's own width. Wrap each depth branch in `project_path_endpoints`,
exactly as the sibling operators do. No reflexive 0-hop branch is added:
`path+` excludes the zero-length path (SPARQL 1.1 sec 9.1).
Add result-level closure oracles to property_paths.gtest over a->b->c->d->e
plus c->x (open-ended `?s :p+ ?o`, bound-subject, a cycle, nested `^(:p+)` and
`(:p+)/:q`, and `?` `/` `^` regression guards), and strengthen two existing
count-only `+` tests to assert values rather than only cardinality. The
bounded MAX_DEPTH=50 expansion is unchanged (also fixes a stale test comment).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>teipsum:fix-path-one-or-more fix(query): widen UNION output schema to the union of all branches
UNION built its result schema from the first branch alone, so a variable or
column that appears only in a later branch was dropped instead of present
with an unbound value. On the SPARQL leg this surfaced three ways: a
projection / ORDER BY / aggregate above the UNION that referenced such a
variable raised GRAFEO-X001 ("Variable not found") at plan time; a narrower
later branch indexed against the wider first-branch width raised GRAFEO-V001
("Column not found") at run time; and, most dangerously, SELECT * returned a
later branch's values under the first branch's variable names with no error
(the Wildcard projection skips the by-name guard). The Cypher/GQL leg
silently truncated a UNION whose later branch is wider, dropping the extra
columns.
Per SPARQL 1.1 the result variable domain is the union of the branches'
in-scope variables (sec 18.2.1) and the result is the multiset union of the
partial solution mappings (sec 18.5): a variable unbound in a branch is
unbound there, never removed.
RDF/SPARQL planner (rdf/mod.rs plan_union): advertise the union of every
branch's variable set and wrap each branch in a projection that null-pads it
to the unified width. The padding is a genuine per-chunk-width copy rather
than a merely-wider declared schema, because DISTINCT and ORDER BY copy at
each chunk's own column count against a fixed-width builder. RdfUnionOperator
now debug-asserts the uniform width, and its stale "UNION of INSERT" docstring
is refreshed. The single-branch fast path is preserved.
LPG (Cypher/GQL) planner (lpg/join.rs plan_union): Cypher/GQL UNION aligns
columns by position with names from the first branch, so widen to the maximum
branch arity and null-pad the trailing columns of narrower branches. The two
legs reconcile differently (by variable name for SPARQL, positionally for
Cypher/GQL) and fail differently, so each keeps its own regression oracle.
Column-name compatibility validation is left out of scope.
Tests: the existing UNION spec cases were all same-arity, so heterogeneous
coverage is added -- the X001 and V001 repros, a SELECT-* anti-corruption
guard asserting the widened schema and null padding, DISTINCT-over-unbound
and ORDER-BY-nulls-last, a white-box planner test, and positive-correctness
Cypher oracles for the wider-first and wider-second branch cases.
Co-Authored-By: Claude <noreply@anthropic.com>teipsum:fix-union-output-arity Latest Branches
0%
dependabot/cargo/rust-dependencies-ff17ce92f5 0%
teipsum:fix-duplicate-column-names 0%
teipsum:fix-path-one-or-more © 2026 CodSpeed Technology