OXY-166: Add scalar aggregate functions (SUM / AVG / MIN / MAX) to oxygen-sql - #307
Open
Kalin-Rudnicki wants to merge 1 commit into
Open
OXY-166: Add scalar aggregate functions (SUM / AVG / MIN / MAX) to oxygen-sql#307Kalin-Rudnicki wants to merge 1 commit into
Kalin-Rudnicki wants to merge 1 commit into
Conversation
Mirrors the existing COUNT path (DSL -> parse -> fragment -> decode) to add scalar aggregation over the whole result set (no GROUP BY; that's OXY-100). - DSL: `Q.sum` / `Q.avg` / `Q.min` / `Q.max` in `Q`. - Nullability: SUM/AVG/MIN/MAX are SQL NULL over an empty set, so all four decode to `Option[_]` (unlike COUNT which is never null). - Widening follows Postgres: SUM(int)->Long, SUM(bigint/numeric)->BigDecimal, AVG(exact)->BigDecimal, AVG(float)->Double; MIN/MAX keep the column type. The `sum`/`avg` result type is encoded by the new `SumType`/`AvgType` type-classes so the query's static type reflects the widened result. - Added a decode-only `ResultDecoder.bigDecimal` (Postgres `numeric` -> `java.math.BigDecimal`); intentionally no `RowRepr[BigDecimal]` / `Column.Type.Numeric` to avoid touching migration codecs. - Tests: real-Postgres integration test over non-empty AND empty result sets (NULL -> None) plus SUM/AVG type correctness. - Docs: docs/sql/queries.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011YxWKdsz97QT9BD7AdpSq6
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.
OXY-166 — Scalar aggregate functions (SUM / AVG / MIN / MAX)
Adds
SUM/AVG/MIN/MAXscalar aggregate support to theoxygen-sqlquery DSL, mirroring the existingCOUNTpath end-to-end (DSL → parse → fragment → decode). Scalar aggregation over the whole result set — noGROUP BY(that's OXY-100).DSL
Nullability
SUM/AVG/MIN/MAXreturn SQLNULLover an empty result set, so all four decode toOption[_](unlikeCOUNT, which is never null).Type choices (documented in
docs/sql/queries.md)Follows Postgres' own widening:
sumOption[Long]sumOption[BigDecimal]sumOption[Float]sumOption[Double]avgOption[BigDecimal]avgOption[Double]min/maxAAOption[A]The
sum/avgwidening is encoded by newSumType/AvgTypetype-classes, so the query's static type already reflects the widened result. The macro reads the widenedOuttype off the term and picks the matching optional decoder — the primitiveintdecoder matches on JDBC runtime class (java.lang.Integer), so decodingSUM(int)(abigint/Long) without widening would fail; widening is required for correctness, not cosmetic.Added a decode-only
ResultDecoder.bigDecimal(Postgresnumeric→java.math.BigDecimal). Intentionally noRowRepr[BigDecimal]/Column.Type.Numeric— that would ripple into the migration codecs; aBigDecimaltable column is therefore still unsupported, but aggregate results decode toBigDecimalcorrectly.Tests
CustomQuerySpec"scalar aggregates" test (real Postgres via TestContainers): SUM/AVG/MIN/MAX over a non-empty group and an empty group (NULL →None), plus SUM widening (→Long) and AVG type (→BigDecimal).sql-itsuite: 55 passed / 0 failed.See
report/OXY-166.mdfor the full decision log and confidence score (9/10).🤖 Generated with Claude Code
https://claude.ai/code/session_011YxWKdsz97QT9BD7AdpSq6