Add lateral and grouped aggregate strategies - #3
Draft
wtsnz wants to merge 6 commits into
Draft
Conversation
Move the loaded-aggregate implementation into `AshSql.Aggregate.Lateral` and leave `AshSql.Aggregate` as the compatibility facade. Implementation notes: - preserve the existing public function signatures; - delegate directly to the extracted lateral module; - retain the upstream aggregate read-action correction; - avoid the temporary context wrapper from the earlier history. This is a structural extraction with no intended behavior change.
Move root aggregate-query execution into `AshSql.Aggregate.Lateral.Query` and keep `AshSql.AggregateQuery` as the public entry point. Implementation notes: - preserve the existing aggregate-query API; - normalize bindings once in the facade; - pass the prepared query to the lateral implementation; - remove the duplicate binding initialization from the extracted module. This is a structural extraction with no intended query behavior change.
Introduce the adapter callbacks that select an aggregate planner and provide dialect-specific grouped list expressions. Implementation notes: - `aggregate_strategy/1` defaults to `:lateral`; - adapters can opt into the new `:grouped` strategy; - `grouped_list_aggregate/2` keeps list SQL and result representation in the adapter; - both callbacks remain overridable through `AshSql.Implementation`. Existing adapters continue to use lateral aggregates without any required changes.
Add the grouped and windowed planner used by adapters that cannot load related aggregates through lateral joins. Implementation notes: - apply relationship limits and offsets per parent before aggregation; - resolve attributes, calculations, and aggregate fields through AshSQL expressions; - reuse the existing relationship and sort planners; - preserve aggregate type constraints; - delegate grouped list expressions to the selected adapter. The companion AshSQLite suite covers the supported aggregate kinds, relationship shapes, rich fields, defaults, and bounds.
Route root aggregate queries through the selected strategy and add the grouped implementation for SQLite-style adapters. Implementation notes: - support count, sum, average, minimum, maximum, first, and exists; - apply filters, limits, offsets, and required ordering before aggregation; - preserve `first` nil handling, defaults, and Ash sort semantics; - resolve calculation and aggregate fields through shared expression handling; - derive fieldless distinct counts from single primary-key metadata and reject unsupported key shapes clearly. The companion AshSQLite regressions cover each of these query semantics end to end.
Explain how SQL adapters select between lateral and grouped aggregate planning. Documentation includes: - the default `:lateral` behavior; - the adapter opt-in for `:grouped`; - the adapter-owned grouped list callback; - the new strategy support in the changelog. The guide describes the final contract after both loaded and root aggregate paths are in place.
wtsnz
force-pushed
the
agent/aggregate-strategies-clear-history
branch
from
July 22, 2026 06:04
56ae4b0 to
c8283dd
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 adapter-selectable aggregate strategies to AshSQL.
The existing lateral implementation is extracted behind stable facades, and a grouped/windowed implementation is added for adapters such as SQLite that cannot use lateral joins. Existing adapters remain on the default
:lateralstrategy.Why
AshSQLite needs grouped aggregate planning, but the planner, expression handling, relationship semantics, and strategy dispatch belong in AshSQL. Dialect-specific list SQL remains owned by the selected adapter.
Commit story
Each non-trivial commit explains its problem, change, reason, behavior, and validation.
Correctness included
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 #1. The old PR and branch remain unchanged as a backup.
The companion adapter and acceptance coverage is in wtsnz/ash_sqlite#6.