feat: SPARQL conversion layer with SparqlStore base class#14
Merged
Conversation
Complete design workflow for IR-to-SPARQL conversion: - Ideation docs exploring package placement, architecture, result mapping, and layered conversion with SPARQL 1.2 algebra intermediate - Architecture plan with full type definitions, translation rules, and inter-component contracts for parallel implementation - Task breakdown with 7 phases (1 → 2a-2d parallel → 3 → 4), each with detailed test specifications and explicit assertions - Updated workflow skill to auto-enter ideation mode - Updated plan skill with inter-component contracts requirement - Updated tasks skill with parallel execution and test specification sections Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 1 of SPARQL conversion layer: - SparqlAlgebra.ts: full type definitions for algebra nodes, plans, expressions, terms, triples, projection items, and order conditions - sparqlUtils.ts: formatUri, formatLiteral, collectPrefixes, generateEntityUri with ULID-based URI generation - Barrel exports via src/sparql/index.ts and src/index.ts - 15 unit tests covering all utility functions - Added ulid dependency - Removed originating ideation doc (implementation started) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Renamed "Test specification" to "Validation specification" to clarify that phase acceptance criteria can include compilation checks, runtime checks, HTTP checks, and structural checks — not only coded tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 2a: IR→algebra for SELECT queries (27 tests) Phase 2b: algebra→SPARQL string serialization (61 tests) Phase 2c: SPARQL JSON result mapping (25 tests) Phase 2d: IR→algebra for mutations (16 tests) All 291 tests pass, compilation clean, no regressions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wire selectToSparql, createToSparql, updateToSparql, deleteToSparql to call through the full IR→algebra→string pipeline. Add 55 select golden tests and 19 mutation golden tests covering all query-fixtures factories end-to-end. 365/365 tests pass, compilation clean. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add test helper for Fuseki dataset management (create, load, query, cleanup) and 19 integration tests covering the full SPARQL pipeline (16 select + 3 mutation). Tests skip gracefully when Fuseki is unavailable. 384/384 tests pass, compilation clean. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…phase) and add Phase 5-6 - implementation skill: add parallel execution section for sub-agent spawning - tasks skill: strengthen integration phase requirement after parallel work - review skill: require follow-up questions before mode switch, enforce tasks-first flow - plan: add Phase 5 (Fuseki Docker) and Phase 6 (negative tests) - ideation: defer SPARQL CONSTRUCT support to 004 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ation test assertions Phase 5: Added docker-compose.test.yml for ephemeral Fuseki, test:fuseki npm script, fixed 6 test assertion issues (singleResult handling, test data gaps). Documented two known limitations: nested result grouping needs traversal aliases in SELECT projection; FILTER uses string literals for URI entity references. Phase 6: Added 12 negative/error-path tests, fixed silent failure in convertExistsPattern(), updated outdated "stubs" comments. All 396 tests pass, 19 Fuseki integration tests pass against live Fuseki. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…coverage to 75 fixtures Phase 7: Add IRReferenceExpression type to distinguish URI references from string literals in FILTER comparisons. Entity refs now emit <IRI> instead of "literal" in generated SPARQL. Phase 8: Add collectTraversalAliases() and inject traversal alias variables into SELECT projection so mapNestedRows() can group nested results by traversed entity. Phase 9: Expand sparql-fuseki.test.ts from 19 to 75 tests covering all query factories (56 SELECT + 19 mutation). Add Employee test data, categorize tests by SPARQL validity, use try/finally for mutation cleanup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 10: Recursive nesting in result mapping Phase 11: Tighten Fuseki assertions to OLD test depth Phase 12: Inline where filter lowering (IR pipeline) Phase 13: Fix invalid SPARQL generation (3 fixtures) Phase 14: Fix edge cases (eval projection, context path) Each phase includes root cause analysis, approach options, files changed, and open questions for user decision. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each phase now includes: - Exact code locations and line numbers for changes - Before/after code examples with concrete implementations - Expected SPARQL output after fixes - Precise root cause analysis with code path traces - Architectural considerations and edge cases Key findings from deep dive: - Phase 13b: root cause is line 158 of IRCanonicalize.ts calling toComparison() instead of checking for SOME/EVERY on the `first` element of a where_boolean compound - Phase 13c: SparqlSelectPlan already has `having` field and algebraToString.ts already serializes it — only irToAlgebra.ts needs changes - Phase 14b: arg_path.subject already carries context entity IRI — fix is to use it as a fixed triple subject instead of using the query's root alias Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tasks mode: defines concrete tasks, dependency graph, parallel execution strategy, stub boundaries, and detailed validation specifications with test data assertions for each phase. Key structure: - Phases 10, 12, 13, 14 run in parallel (different files) - Phase 11 runs last (assertion tightening after fixes land) - Shared file risk in irToAlgebra.ts documented with section ranges - Integration verification checklist after all phases merge Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrites resultMapping.ts to support arbitrary nesting depth in SPARQL result grouping. Introduces buildAliasChain() to walk the traversal map, insertIntoTree() for recursive NestedGroup construction, and collectNestedGroup() for recursive binding collection. All 452 tests pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
13a: Wrap NOT expressions in parentheses in algebraToString.ts to
fix precedence (!(expr) instead of !expr).
13b: Add canonicalizeComparison() in IRCanonicalize.ts to detect
SOME/EVERY quantifiers in the first element of boolean compounds.
13c: Route aggregate-containing WHERE filters to HAVING in
irToAlgebra.ts via containsAggregate() detection.
All 452 tests pass with updated golden expectations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
14a: Add 'expression' variant to SparqlProjectionItem for computed
projections like (expr AS ?alias). Fixes customResultEqualsBoolean
which now correctly projects the boolean comparison.
14b: Add context_property_expr IR expression type to resolve context
entity property paths via separate triples instead of reusing
the same variable. Fixes whereWithContextPath tautology.
All 452 tests pass with updated golden expectations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Process DesugaredPropertyStep.where predicates that were silently dropped during IR lowering. When a property step has .where(), force a traversal creation, canonicalize and lower the where predicate, and attach the resulting filter to the traverse pattern. In irToAlgebra, filtered traversals produce OPTIONAL blocks with the traverse triple, filter property triples, and FILTER co-located inside. Fixes 6 fixtures: whereFriendsNameEquals, whereHobbyEquals, whereAnd, whereOr, whereAndOrAnd, whereAndOrAndNested. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 3-level nesting and alias_expr tests to sparql-result-mapping.test.ts. Tighten Fuseki test assertions from defensive patterns (>=1, toBeDefined) to precise values matching test data. Update inline where section (now lowered via Phase 12) and invalid SPARQL section (now valid via Phase 13). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ested create with predefined ID (Phases 15-17) - Fix DELETE variable reuse via SparqlDeleteInsertPlan refactor - Fix context variable naming with sanitizeVarName() - Fix aggregate alias collision in irToAlgebra - Fix UPDATE OPTIONAL wrapping for safe WHERE clause - Add operator parenthesization for OR inside AND expressions - Fix literal property inline where result mapping with detectLiteralTraversals() - Fix isNodeReference() to distinguish references from nested creates - Handle predefined ID in convertNodeDescription() - All 456 tests pass, 75/75 Fuseki end-to-end Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add comprehensive review section to plan doc with remaining gaps categorized by priority - Create documentation/sparql-algebra.md covering the full SPARQL pipeline: algebra types, IR→algebra conversion, string serialization, result mapping, public API, store implementation guide, and known limitations Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…sion detection (Phases 18-20) Phase 18: Add escapeSparqlString() for SPARQL literal escaping (quotes, backslashes, newlines, tabs, CRs). Fix language-tagged literal bypass in serializeTerm(). Remove unused varCounter in updateToAlgebra(). Phase 19: Rewrite convertExistsPattern() with full recursive support for optional (→ left_join), union (→ union), and nested exists patterns. Fix join case to handle mixed sub-pattern types instead of only traverse. Phase 20: Improve detectLiteralTraversals() to scan all bindings and handle mixed types safely. Add duplicate result key detection in buildNestingDescriptor(). Fix context property collision by using raw IRI as registry key + variable name deduplication with counter. All 471 tests pass, 75/75 Fuseki, TypeScript clean. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove string literal escaping and EXISTS limitations (now fixed). Add escapeSparqlString to utilities table. Update known limitations to reflect current state. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…pe casts - Add SparqlStore abstract base class (IR → SPARQL → execute → map pipeline) - Add FusekiStore concrete implementation with 5 integration tests (80/80 Fuseki) - Replace hardcoded XSD/RDF URI strings with ontology module imports - Fix `as any` casts: use `as never` for exhaustive switches, explicit ResultRow[] for arrays - Remove dead commented code in MutationQuery.ts - Update plan review section with resolved nice-to-have items Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dvanced patterns - 005: Named graph support (.from()/.into() for GRAPH clauses) - 006: Computed expressions & update functions (L.times, L.concat, etc.) - 007: Advanced query patterns (MINUS set difference + DELETE WHERE bulk delete) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Walks through Shape → DSL → IR → SPARQL Algebra → SPARQL String → Result with abbreviated examples at each stage. Links to IR and SPARQL algebra docs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…type inference - README: highlight fully inferred result types as top feature, add AST optimization mention, remove stray code block, update store packages list - sparql-algebra.md: fix "no base classes" statement, add SparqlStore.ts to file structure, rewrite store implementation section to use SparqlStore base class, add SparqlStore to public API section - intermediate-representation.md: update reference implementations to describe built-in SparqlStore instead of "coming soon" Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Contributor
|
If this change doesn't need a release (docs, CI config, etc.), you can ignore this message. |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Contributor
|
If this change doesn't need a release (docs, CI config, etc.), you can ignore this message. |
- Rewrote report with full architecture, design decisions, API surface, conversion rules, resolved gaps, and test coverage - Added changeset (minor) with detailed user-facing changelog - Updated wrapup skill with report quality and changeset guidelines Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a complete SPARQL conversion pipeline to
@_linked/core— compiles the canonical IR into executable SPARQL and maps results back to fully typed DSL objects.What's new
SparqlStoreabstract base class: Concrete stores only implementexecuteSparqlSelect()andexecuteSparqlUpdate()— the base class handles everything elseTest coverage
Documentation
documentation/sparql-algebra.md— full layer referencedocumentation/intermediate-representation.md— SparqlStore as reference implementationREADME.md— pipeline walkthrough, type inference highlight, SparqlStore sectionFuture work (ideation docs)
docs/ideas/005)docs/ideas/006)docs/ideas/007)Test plan
npx tsc --noEmit)@_linked/core🤖 Generated with Claude Code