From 0a95f53d613a142fde665c4d164db9dafffb1d13 Mon Sep 17 00:00:00 2001 From: Hassan Abedi Date: Fri, 10 Apr 2026 10:25:45 +0200 Subject: [PATCH] Update docs and add runnable SQL example scripts --- AGENTS.md | 8 +++++++- README.md | 12 ++++++++++-- ROADMAP.md | 2 +- examples/scripts/README.md | 4 ++++ examples/scripts/sql_basic.chase | 8 ++++++++ examples/scripts/sql_join.chase | 10 ++++++++++ examples/scripts/sql_order_by.chase | 7 +++++++ examples/scripts/sql_self_join.chase | 8 ++++++++ 8 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 examples/scripts/sql_basic.chase create mode 100644 examples/scripts/sql_join.chase create mode 100644 examples/scripts/sql_order_by.chase create mode 100644 examples/scripts/sql_self_join.chase diff --git a/AGENTS.md b/AGENTS.md index f95029d..6bc4a62 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -60,6 +60,7 @@ Quick examples: - `src/sql/`: narrow SQL AST and parser support. - `src/planner/`: logical plan structures and SQL-to-plan translation. - `src/execution/`: execution of the current logical plan subset. +- `examples/scripts/`: runnable script examples for supported workflows. - `tests/`: integration, regression, and property-based tests. ## Architecture Constraints @@ -70,7 +71,9 @@ Quick examples: - The chase engine should remain largely stateless; pass execution state explicitly. - New chase variants should be composable with existing infrastructure. - Existential variables generate labeled nulls (`Term::Null`). -- The current SQL support is intentionally narrow: single-table `SELECT-FROM-WHERE` with positional column names such as `c0` and `c1`. +- The current SQL support is intentionally narrow: `SELECT-FROM-WHERE-ORDER BY` over predicate-backed tables, equality predicates combined with `AND`, comma-join style multi-table queries, table aliases, and ordering by output-column names. +- Stable SQL column names come from explicit catalog registration or the frontend `schema ...` command; otherwise the default names are positional such as `c0` and `c1`. +- Do not describe unsupported SQL features such as aggregates, grouping, or arbitrary expressions as implemented. - Relational and SQL modules should build on explicit schemas and logical plans, not call frontend helpers directly. - If you add parser, planner, or executor layers, keep their responsibilities separate. - Public docs and interfaces should reflect the implemented state of the repository accurately. @@ -114,6 +117,7 @@ Example scopes that are good first tasks: - Tighten frontend wording so it matches actual behavior. - Introduce a small planning-oriented type without changing execution semantics. - Extend the SQL slice with a narrow, well-tested feature such as aliases or named columns. +- Add a runnable example script that demonstrates a supported workflow. ## Testing Expectations @@ -123,6 +127,7 @@ Example scopes that are good first tasks: - Regression tests for bug fixes go in `tests/regression_tests.rs`. - Property-based tests go in `tests/property_tests.rs`. - SQL/planner/execution flow tests go in `tests/sql_pipeline_tests.rs`. +- Runnable documentation examples belong in `examples/scripts/` when they clarify supported behavior. - Do not merge code that breaks existing tests. Minimal unit-test checklist for chase-related behavior: @@ -199,6 +204,7 @@ Use this review format: - When adding non-chase engine pieces, define clean interfaces before broadening functionality. - Keep `frontend` presentation-only when possible; shared reasoning logic belongs in `chase`, relational logic in `relational`/`planner`/`execution`. - Keep user-facing naming consistent with the repository name: `query-engine` / `query_engine`. +- If you change the SQL subset, update `README.md`, `ROADMAP.md`, and relevant example scripts in the same change. ## Commit and PR Hygiene diff --git a/README.md b/README.md index bbf5d68..09a6d36 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ execution boundaries. - Provenance-oriented explanations for derived answers - Script, REPL, and local web UI for experimentation - Relational schema, catalog, logical-plan, and execution scaffolding -- A minimal SQL slice for `SELECT-FROM-WHERE` queries over predicate-backed tables +- A minimal SQL slice for `SELECT-FROM-WHERE-ORDER BY` queries over predicate-backed tables ### Architecture @@ -84,6 +84,7 @@ assert_eq!(result.instance.facts_for_predicate("Ancestor").len(), 3); cargo run -- repl cargo run -- gui cargo run -- script examples/scripts/ancestor.chase +cargo run -- script examples/scripts/sql_join.chase ``` #### REPL language @@ -110,7 +111,7 @@ The repository now has a narrow SQL pipeline with: - relational schemas, rows, and values - SQL parsing for a small subset - logical planning -- execution for single-table queries and basic multi-table joins +- execution for filtering, ordering, and basic multi-table joins Currently supported examples: @@ -171,6 +172,13 @@ Current limits: - no aggregates - projection aliases only via `AS` +Runnable SQL examples: + +- `examples/scripts/sql_basic.chase` +- `examples/scripts/sql_join.chase` +- `examples/scripts/sql_self_join.chase` +- `examples/scripts/sql_order_by.chase` + ### Development For non-trivial changes, run: diff --git a/ROADMAP.md b/ROADMAP.md index e211f0a..675d265 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -37,7 +37,7 @@ This document tracks the current state and next steps for the repository. - [ ] Keep all public docs aligned with actual implemented behavior - [ ] Remove remaining stale terminology in comments and help text -- [ ] Expand examples for the current rule-engine workflow +- [x] Expand examples for the current rule-engine and SQL workflows - [ ] Add rustdoc coverage for the main public types - [x] Document the current SQL subset and its limits diff --git a/examples/scripts/README.md b/examples/scripts/README.md index 783fcf4..5015141 100644 --- a/examples/scripts/README.md +++ b/examples/scripts/README.md @@ -12,3 +12,7 @@ Available examples: - `ancestor.chase`: transitive closure over `Parent/2` - `employee_departments.chase`: existential rule that creates labeled nulls - `same_team.chase`: conjunctive query with a self-join +- `sql_basic.chase`: named-column filtering in the SQL frontend +- `sql_join.chase`: multi-table SQL join over predicate-backed tables +- `sql_self_join.chase`: self-join with SQL table aliases +- `sql_order_by.chase`: ordered SQL output with `ORDER BY` diff --git a/examples/scripts/sql_basic.chase b/examples/scripts/sql_basic.chase new file mode 100644 index 0000000..16f38c8 --- /dev/null +++ b/examples/scripts/sql_basic.chase @@ -0,0 +1,8 @@ +# Filter rows through the SQL frontend with named columns. + +fact Parent(alice, bob). +fact Parent(bob, carol). +fact Parent(carol, dave). + +schema Parent(parent, child). +sql SELECT parent FROM Parent WHERE child = 'bob'; diff --git a/examples/scripts/sql_join.chase b/examples/scripts/sql_join.chase new file mode 100644 index 0000000..b5388be --- /dev/null +++ b/examples/scripts/sql_join.chase @@ -0,0 +1,10 @@ +# Join two predicate-backed tables through the SQL frontend. + +fact Parent(alice, bob). +fact Parent(bob, carol). +fact Ancestor(bob, carol). +fact Ancestor(carol, dave). + +schema Parent(parent, child). +schema Ancestor(parent, child). +sql SELECT Parent.parent, Ancestor.child FROM Parent, Ancestor WHERE Parent.child = Ancestor.parent; diff --git a/examples/scripts/sql_order_by.chase b/examples/scripts/sql_order_by.chase new file mode 100644 index 0000000..453bdc8 --- /dev/null +++ b/examples/scripts/sql_order_by.chase @@ -0,0 +1,7 @@ +# Sort SQL output through ORDER BY. + +fact Parent(alice, bob). +fact Parent(bob, carol). +fact Parent(carol, dave). + +sql SELECT c0 FROM Parent ORDER BY c0 DESC; diff --git a/examples/scripts/sql_self_join.chase b/examples/scripts/sql_self_join.chase new file mode 100644 index 0000000..1a971c9 --- /dev/null +++ b/examples/scripts/sql_self_join.chase @@ -0,0 +1,8 @@ +# Run a self-join with SQL table aliases. + +fact Parent(alice, bob). +fact Parent(bob, carol). +fact Parent(carol, dave). + +schema Parent(parent, child). +sql SELECT p.parent, q.child FROM Parent AS p, Parent AS q WHERE p.child = q.parent;