Add SQLite grouped aggregate support - #6
Draft
wtsnz wants to merge 11 commits into
Draft
Conversation
Enable AshSQLite to route supported aggregate operations through AshSQL's grouped planner. Implementation notes: - select `:grouped` in the SQL implementation; - advertise the supported aggregate kinds and relationship shapes; - delegate query return, filtering, calculations, and root aggregates to the shared AshSQL paths; - keep manual, parent-dependent, and no-attribute relationship shapes unsupported. The following commits add end-to-end coverage for each enabled path.
Provide the SQLite expression used by AshSQL's grouped list planner. Implementation notes: - build lists with windowed `json_group_array`; - filter nil values inside the SQL aggregate when `include_nil?` is false; - leave window planning and result typing in AshSQL; - keep SQLite syntax and JSON representation inside the adapter. The acceptance suite covers ordering, nil inclusion, defaults, constrained values, relationship bounds, and calculation fields.
Add a small adapter API for custom Ecto aggregate expressions. Implementation notes: - define callbacks for the aggregate expression and result type; - let custom modules use SQLite-specific functions; - leave relationships, filters, windows, and result loading in the shared planner. The acceptance suite exercises custom aggregates in root queries and related aggregate loads.
Add the main SQLite acceptance matrix for the grouped strategy. Coverage includes: - root and loaded scalar aggregates; - first, list, exists, and custom aggregates; - filtering, sorting, pagination, calculations, and join filters; - one-hop, unrelated, many-to-many, and multi-hop paths; - nil handling, defaults, distinct values, read actions, and stable unsupported errors. These tests verify the generated grouped and windowed SQL through the concrete SQLite adapter.
Add focused coverage for the parts of `first` that differ from a simple ordered `LIMIT 1` query. Coverage includes: - excluding or including nil values; - applying a fallback to an empty filtered result; - ascending and descending ordering; - all four Ash null-ordering variants. These tests protect behavior that was missing from the original grouped query implementation.
Exercise fieldless distinct counts against the primary-key shapes supported by Ash resources. Coverage includes: - a valid single primary key whose Ash name is not `:id`; - a composite primary key; - a resource without a primary key; - clear errors for the unsupported key shapes. These tests protect the grouped query path from assuming that every resource has an `:id` attribute.
Verify that grouped list and first expressions retain the aggregate item's type constraints. Implementation notes: - build the aggregate data-layer query directly; - inspect the generated Ecto type for the list value; - assert that `trim?` and `allow_empty?` survive query construction. This protects a constraint loss inherited from the earlier SQLite implementation rather than a defect introduced by the extraction.
Verify that an ordered root query with only an offset is bounded before aggregation. Implementation notes: - create three ordered records; - offset the first record without specifying a limit; - assert that the aggregate sees the remaining two records; - exercise SQLite's required `LIMIT -1` representation for a standalone offset. The missing offset condition came from existing AshSQL wrapping logic and was copied into the grouped path.
Add root-query regressions for bounded inputs and non-attribute aggregate fields. Coverage includes: - `first` and `exists` over a zero-limit query; - a sorted and limited query whose outer aggregate has its own sort; - an offset query with no remaining rows; - calculation fields and aggregate-on-aggregate fields. These tests protect grouped query behavior introduced by the aggregate extraction.
Add loaded-aggregate regressions for relationship bounds and rich related fields. Coverage includes: - per-parent relationship limits and offsets; - count and list results over each bounded relationship; - calculation fields on related records; - aggregate fields on related records; - sum, maximum, first, and list results. These tests protect grouped loading behavior introduced by the aggregate extraction.
Add a complete guide to the grouped aggregate behavior exposed by AshSQLite. Documentation includes: - supported root and loaded aggregate kinds; - calculations, filters, sorting, pagination, and relationship paths; - custom aggregates, limits, offsets, and unsupported shapes; - SQLite requirements for windows, `FILTER`, JSON, and null ordering; - navigation, tutorial, API grouping, and changelog updates. The guide reflects the behavior exercised by the preceding acceptance commits.
wtsnz
force-pushed
the
agent/sqlite-grouped-aggregates-clear-history
branch
from
July 22, 2026 06:04
727d1c6 to
d6ee81a
Compare
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
Add SQLite aggregate support through AshSQL's grouped aggregate strategy.
AshSQLite selects the grouped planner, declares its supported capability and relationship shapes, provides SQLite's JSON-backed list expression, and exposes a custom aggregate behaviour. The PR includes end-to-end acceptance coverage and a complete aggregate guide.
Dependency
Review and merge wtsnz/ash_sql#3 first. This PR is validated against that clean-history AshSQL branch.
Commit story
firstsemantics.The sequence contains no implementation-and-immediate-removal commits. Each focused regression commit explains the defect and its provenance.
Supported behavior
Validation
mix format --check-formatted1 passed210 passed851 passed, 21 excludedTests used
--no-deps-checkbecause the local checkouts have existing dependency-lock mismatches under the current toolchain. No dependency or lockfile was changed.Review context
This is the clean-history replacement for draft fork PR #5. The old PR and branch remain unchanged as a backup.