OXY-6: array input + = ANY(?) - #298
Conversation
💬 Feedback from KalinThe primary intended use case for the array/unnest input — in my head — is using SELECT *
FROM UNNEST(?) a
JOIN other b ON b.id = aThis PR implemented Spinning up an agent to build the |
UNNEST(?) as an input join table source (the primary use case)Following the feedback that the main goal was using UNNEST as an input join table ( DSL
@compile
val notesByPersonIdUnnest: QueryIO[ArraySeq[UUID], Note] =
for {
ids <- input.array[UUID]
id <- select.unnest(ids) // FROM UNNEST(?::uuid[]) id(id)
n <- join[Note] if n.personId == id
} yield ngenerates: SELECT n.id, n.person_id, n.note
FROM UNNEST(?::uuid[]) id(id)
JOIN note n ON n.person_id = id.idThe whole collection still binds as a single Notes / decisions
Test coverageNew integration test "UNNEST(?) as an input join table" in
14/14 |
- `input.array[A]` now binds a `Seq[A]` (was `ArraySeq[A]`); callers pass their collection directly, since it is adapted to a JDBC array at bind time anyway. - add `input.set[A]` binding a `Set[A]` via the same `= ANY(?)` / `UNNEST(?)` path. - `VariableReference.ArrayFromInput` gains an `ArrayInputKind` (Seq | Set); `TypeclassExpr.RowRepr.collectionAsArray(kind)` wraps `RowRepr[A]` into `RowRepr[Seq[A]]` / `RowRepr[Set[A]]` via `ArrayRepr` + `transform`. - `Q.select.unnest` accepts `Iterable[A]` so both Seq and Set inputs unnest. - FromUnnest: move the `UNNEST(` closing paren into `GeneratedFragment.of`. - report/OXY-6.md moved to a comment on the OXY-6 Jira issue and removed. - tests: Seq/Set `= ANY(?)` + Set UNNEST cases; docs updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add first-class collection inputs to the sql query DSL, bound as a single `java.sql.Array` param instead of expanding to N placeholders (avoids the JDBC ~32767-param limit and plan-cache blowup). - `input.array[A]` (a `Seq[A]`) and `input.set[A]` (a `Set[A]`) + `arr.contains(col)` generate `col = ANY(?)`. - `select.unnest(arr)` uses the collection as a `FROM UNNEST(?::t[]) a(a)` table source (one row per element), aliased/qualified so it can be joined/filtered/selected. - `RowRepr.seqRepr` / `RowRepr.setRepr` wrap `RowRepr[A]` into `RowRepr[Seq[A]]` / `RowRepr[Set[A]]` (single Array column via `ArraySeqEncoder`); the runtime collection is adapted to a JDBC array at bind time, so callers pass their collection directly. - single-column element types only; array/set inputs are non-optional. - docs + it-test coverage (empty / single / large / NOT-found / composition / Set). Report captured on the OXY-6 Jira issue. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
OXY-6 — Add support for array input + unnest
Adds first-class support in
oxygen-sqlfor binding a collection as a single parameter and expanding it as Postgrescol = ANY(?), avoiding N-placeholderINlists (JDBC ~32767-param limit / plan-cache blowup).DSL
Q.input.array[A]binds anArraySeq[A]as onejava.sql.Arrayparam;ids.contains(col)generatescol = ANY(?). Encoding reuses the existingRowRepr.ArrayRepr/ArraySeqEncoder(no::type[]cast — the JDBC typed array already carries the element type).What changed
T.ArrayInput,Q.input.arrayVariableReference.ArrayFromInput,InputPart,RawQueryExpr/QueryExprArrayContains,DecoderBuilderexhaustivenessFragmentBuilderemits<col> = ANY(?);TypeclassExpr.RowRepr.arraySeqdocs/sql/queries.mdScope / decisions
= ANY(?)form only; UNNEST-as-a-table-source deferred (overlaps OXY-98 lateral join).INwith N placeholders).report/OXY-6.md.🤖 Generated with Claude Code