Repository navigation
Add a Postgres dialect - #2
Merged
Merged
Conversation
Column refs, qualifiers, tables, aliases, CTE names and group/order keys render as Ident fragments the dialect quotes. ClickHouse writes them bare, so its output is unchanged. Untyped boolean and DateTime literals go through the dialect too. Dialect.clauses records which clauses exist: FORMAT fails to compile where it has no meaning, and a wrapped union gets the derived-table alias some databases require. Dialect.paramCodecs lets a dialect re-encode a portable param kind.
New ./postgres entry point: postgresDialect (double-quoted identifiers, standard string literals, $n binding), Postgres column types whose codecs accept what common drivers send, a function catalog for what Postgres spells differently (count(*), FILTER (WHERE ...), percentile_cont, date_trunc in UTC, date_bin, array_agg, ->>), and a compile that defaults to Postgres. Core changes it needed: Dialect.paramCodecs now re-encodes portable param kinds (param.bool binds a boolean, param.dateTime an ISO instant), and Dialect.clauses.groupByAlias writes GROUP BY keys by position where a bare name would resolve to an input column first. Tests run every query on PGlite, so they pass only if Postgres accepts the SQL and the rows decode. ClickHouse output is unchanged.
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configuration
⛔ Files ignored due to path filters (1)
📒 Files selected for processing (24)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Stacked on #1. Finishes the dialect work: identifier quoting, clause differences, and a Postgres dialect that runs on real Postgres. The design notes, including where the plan changed, are in
design/dialects.md; the user-facing guide isdocs/postgres.md.Identifiers through the dialect
Column refs, qualifiers, tables, aliases, CTE names and group/order keys render as
Identfragments thatDialect.quoteIdentquotes. A column ref carries its qualifier separately (ident("Name", "e")), so a ClickHouseNestedcolumn likeEvents.Nameis never split, while adb.tablequalifier is quoted per segment. Untyped boolean and DateTime literals go through the dialect as well. ClickHouse writes names bare, so its output is byte-identical.Clause differences as capability flags
Dialect.clausesholds what differs between the two databases:format:.format()fails to compile whereFORMATdoes not exist, rather than being dropped silently.derivedTableAlias: a wrapped union getsAS "__union".groupByAlias: Postgres resolves a bare name inGROUP BYto an input column before a select alias, soselect({ Service: lower($.Service) }).groupBy("Service")would group by the raw column. Postgres keys are written by position (GROUP BY 1), which keeps ClickHouse's meaning. There is a test that fails without this.The plan was to move
compile.tsinto a ClickHouse dialect class. Three flags read in three places did the job without relocating ~1100 lines.The
./postgresentry pointpostgresDialect: double-quoted identifiers, standard string literals (anE'...'string only when a value spells the param marker, so the marker can be hex-escaped),$nbinding.Dialect.paramCodecsmakesparam.boolbind a boolean andparam.dateTimean ISO-8601 instant, which no session time zone can reinterpret.bigint; timestamptz as aDateor text; jsonb parsed.count(*),countIf/sumIfasFILTER (WHERE ...),percentile_cont,date_trunc(..., 'UTC'),date_bin,array_agg,->>,coalesce.compile/compileUnsafe/compileUnion/compileUnionUnsafethat default to Postgres.Testing
src/pg/postgres.test.tsruns every query on PGlite (Postgres 17 in WASM, new dev dependency), so a test passes only if Postgres accepts the SQL, binds the params, and the rows decode through the declared types. It covers aggregates withFILTER,dateBin/dateTruncbuckets withDateandDateTime.Utcparams, a join to a schema-qualified table over a subquery, a CTE, an ordered union, a value containing a quote, a backslash and the param marker (as a bound param, a literal, and a LIKE pattern), boolean binding, jsonb comparison, and the GROUP BY alias case.tscfor the library and the testsvitest run src/ch src/sql src/pg src/docs-examples.test.ts: 324 passedbun run build, the doc-citation and export-catalog checks, and the doc-example check, which now runs thedocs/postgres.mdexample on PGlite and asserts its rowstest:clickhouse(live ClickHouse via Docker)Not in this PR
quantile,toStartOfInterval, map subscripts) still write ClickHouse SQL under any dialect; they could refuse to compile under another one instead.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.