feat(querybuilder): add typed composition and dialect-safe functions - #17
Merged
Conversation
Add typed SQL fragments, numeric operators, runtime predicate composition, portable analytic windows, and forward keyset pagination through the shared AST and renderers.
Expose cardinality helpers and mutation metadata, cache rendered plans for reusable handles, and execute dialect-aware EXPLAIN statements without taking ownership from the underlying SQL driver.
Exercise the public types and rendered SQL, then prove result metadata, reusable execution, EXPLAIN, analytics, and keyset pagination against the supported database engines.
Document typed fragments, dynamic filters, analytics, keyset pagination, result contracts, prepared reuse, and EXPLAIN, with regenerated README type checks.
Replace executor cardinality methods with pipeable transforms, remove the compound keyset modifier, and keep dialect-specific functions and frames out of the standard namespace.\n\nBREAKING CHANGE: use execute(...).pipe(Executor.atMostOne/exactlyOne/nonEmpty); Query.keyset and non-portable standard function exports are removed.
Type PostgreSQL numeric bind literals, preserve textual bind ordering in window expressions, and emit MySQL lag/lead offsets as validated integer literals. Verify one standard function matrix live on all three dialects.
Document pipeable result helpers, explicit pagination composition, portable window behavior, and dialect-owned arbitrary calls. Record the durable API rules and regenerate README type checks.
Expose portable database type constructors through Type and remove the nested Query.type namespace. BREAKING CHANGE: use Type.<kind>() instead of Query.type.<kind>() for portable type witnesses.
Add PostgreSQL, MySQL, and SQLite round and modulo APIs with dialect-owned input, result, nullability, and runtime semantics. Update portable type witness call sites to the root Type module.
Move dialect-dependent aggregate, case conversion, clock, and explicit-frame behavior behind dialect modules. Tighten the remaining standard function types and runtime result contracts. BREAKING CHANGE: Root Function no longer exports sum, avg, lower, upper, or clock helpers; explicit frames must use dialect Function helpers; count and ranking functions now decode as BigIntString.
Merged
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.
This lands the querybuilder capability work, including production wiring, documentation, and live PostgreSQL/MySQL/SQLite coverage.
Why
The builder was missing a composable path for dynamic queries, typed SQL fragments, reusable execution, and richer result contracts.
The original function surface also treated several dialect-dependent behaviors as portable. That made result types and runtime semantics look more consistent than the databases actually are.
New Features
Composition and execution:
Functions and types:
BigIntStringQuery.typetoTypeBreaking Changes
execute(...).pipe(Executor.atMostOne/exactlyOne/nonEmpty)instead of executor cardinality methodsQuery.keysetis removed pending a reviewed pagination contractType.<kind>()instead ofQuery.type.<kind>()Functionno longer exports nativesum,avg, case-conversion, clock, modulo, or round helpersFunctionmodulesRisks & Testing Needed
Risk: consumer compile failures from the intentional API removals
→ the changelog and README show the replacement imports and pipeable calls
Risk: numeric result mismatches across drivers
→ live tests assert exact, approximate, integer, zero-divisor, aggregate, and rounding behavior on all three engines
Reversed/removed features:
Build status: pass locally
Test Plan
bun run test:types bun test bun run test:integrationResults:
Rollback
This restores the previous public surface; consumers should not adopt the new APIs until the release is confirmed.