feat(sql): GROUP BY, aggregates, DISTINCT, LIKE, IN (SQLR-3)#97
Merged
Conversation
Closes the analytical-SQL gap that was sitting under "Possible extras": - LIKE / NOT LIKE / ILIKE with %, _, \-escape; case-insensitive ASCII to match SQLite's default - IN (list) / NOT IN (list); subquery form rejected with NotImplemented - SELECT DISTINCT (single + multi-column; NULL == NULL for dedupe) - GROUP BY on bare columns (implicit DISTINCT when no aggregates) - Aggregates: COUNT(*), COUNT([DISTINCT] col), SUM, AVG, MIN, MAX - Column aliases (COUNT(*) AS n) and ORDER BY by alias or display form - Friendly error when an aggregate name lands in WHERE SUM stays Integer until a Real input or i64 overflow promotes it once to Real (SQLite-style); AVG always returns Real (NULL on empty). HAVING, LIKE...ESCAPE, IN (subquery), DISTINCT on SUM/AVG/MIN/MAX, and GROUP BY on expressions are explicit follow-ups. Co-Authored-By: Claude Opus 4.7 (1M context) <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
Closes the analytical-SQL gap that was sitting under "Possible extras":
LIKE/NOT LIKE/ILIKEwith%,_,\-escape; case-insensitive ASCII to match SQLite's defaultIN (list)/NOT IN (list); subquery form rejected withNotImplementedSELECT DISTINCT(single + multi-column;NULL == NULLfor dedupe)GROUP BYon bare columns (acts like implicitDISTINCTwhen no aggregates)COUNT(*),COUNT([DISTINCT] col),SUM,AVG,MIN,MAXCOUNT(*) AS n) andORDER BYby alias or aggregate display formWHERESUMstaysINTEGERuntil aREALinput ori64overflow promotes it once toREAL(SQLite-style).AVGalways returnsREAL(orNULLon empty / all-NULL groups).What's not in this PR (filed as follow-ups)
HAVINGLIKE … ESCAPE '<char>'IN (subquery)DISTINCTonSUM/AVG/MIN/MAXGROUP BYon expressionsBETWEEN,GROUP_CONCAT,GLOB/REGEXPImplementation map
src/sql/agg.rs—AggState,DistinctKey,like_match. Pure-functional; noDatabase/Tablecoupling.src/sql/parser/select.rs—ProjectionbecomesItems(Vec<ProjectionItem>), withProjectionKind::{Column, Aggregate}and an optional alias.SelectQuerygainsdistinct: boolandgroup_by: Vec<String>. Parser validates that bare projection columns appear inGROUP BY.src/sql/executor.rs— addsExpr::Like,Expr::ILike,Expr::InList,Expr::InSubqueryarms ineval_expr. New aggregation path inexecute_select_rowsthat bypasses the rowid-shape optimizers (HNSW / FTS / bounded-heap) when grouping. DISTINCT post-pass and aggregate-aware ORDER BY by alias / display form.Docs
README.mdfeature table updated; "Possible extras" pruned.docs/supported-sql.md— full SELECT semantics rewrite (DISTINCT / GROUP BY / aggregates / LIKE / IN sections, with semantics callouts).docs/sql-engine.md— new "Aggregation phase" section under the executor doc.Verification
cargo build --workspace --exclude sqlrite-desktop --exclude sqlrite-python --exclude sqlrite-nodejs --all-targets— cleancargo fmt --all -- --check— cleancargo clippy --workspace --exclude sqlrite-desktop --exclude sqlrite-python --exclude sqlrite-nodejs --all-targets— no new warnings (only pre-existing ones unrelated to this PR)cargo test --workspace --exclude sqlrite-desktop --exclude sqlrite-python --exclude sqlrite-nodejs— engine tests went from 411 → 434 (+22 SQLR-3 integration tests + 12 new agg.rs unit tests; some pre-existing tests collapsed into new helpers)CREATE,INSERT,LIKE,IN,DISTINCT,GROUP BYwith all 5 aggregates +COUNT(DISTINCT)+ORDER BY n DESC— all render correctly via prettytable.Test plan
main🤖 Generated with Claude Code