TML-2761: Target-contributed DDL in query AST + marker bootstrap via adapter#672
TML-2761: Target-contributed DDL in query AST + marker bootstrap via adapter#672wmadden-electric wants to merge 7 commits into
Conversation
… DDL in the query AST Start the re-scoped project fresh off main after closing #661 (which built the rejected generic-core DDL approach). Carries the respec artifacts: design-notes/spec/plan reframed around "expand the SQL query AST to represent DDL as a target-contributed surface the adapter lowers" (target owns shape, adapter owns lowering), the foundational ddl-in-query-ast slice (spike folded into its first dispatch), and the sql-marker slice rebased onto it. Signed-off-by: Will Madden <madden@prisma.io>
Add a parallel DdlNode/DdlVisitor hierarchy beside DML query ASTs and route adapter.lower() through dialect-specific DDL visitors without touching the existing renderLoweredSql switch or AnyQueryAst membership. Signed-off-by: Will Madden <madden@prisma.io>
Trim the family DdlNode base (no accept/visitor), add DdlColumn.default from contract ColumnDefault, and move CreateTable/CreateSchema concretes into target-postgres and target-sqlite with adapter-owned lowering. Signed-off-by: Will Madden <madden@prisma.io>
Harden Postgres and SQLite DDL renderers so lowered CreateSchema/CreateTable ASTs match the existing ensure*Statement bootstrap constants exactly, add ifNotExists on CreateTable, and tighten lower() to accept target DDL nodes. Pin byte-equality in adapter migration tests; fixtures:check stays green. Signed-off-by: Will Madden <madden@prisma.io>
Record per-target visitor decision and slice plan corrections as the foundational dispatches land. Signed-off-by: Will Madden <madden@prisma.io>
Expose col/lit/fn helpers on sql-relational-core and per-target createTable/createSchema factories so bootstrap and planner callers can build DDL nodes without a contract; refactor byte-equality tests to use them. Signed-off-by: Will Madden <madden@prisma.io>
Control adapters now expose bootstrap AST builders and lower DDL nodes; migration runners and sign() execute lowered bootstrap SQL instead of raw ensure*Statement constants, closing the first consumer path for the target-contributed DDL surface. Signed-off-by: Will Madden <madden@prisma.io>
|
Warning Review limit reached
More reviews will be available in 8 minutes and 29 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (9)
📒 Files selected for processing (37)
✨ Finishing Touches🧪 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 |
Linked issue
Refs TML-2761 — foundational slice for marker/ledger via typed query AST commands (related: TML-2753, TML-2754, TML-2253).
At a glance
Before this PR, marker/ledger bootstrap executed pre-built SQL strings from
statement-builders/sql-marker. After it, each target builds frozen DDL nodes and the control adapter lowers them through the same visitor path as the runtime adapter.Decision
This PR ships a target-contributed DDL surface in the SQL query AST — separate from DML
AnyQueryAst— with per-target visitors in the Postgres and SQLite adapters, contract-free constructors, and marker/ledger bootstrap as the first real consumer.Deliverables:
DdlNodebase +isAnyDdlNodeguard; PostgresCreateTable/CreateSchema, SQLiteCreateTableonly.renderLoweredDdl+ per-target visitors); DML renderer switch untouched.col/lit/fn,createTable/createSchema) and per-target bootstrap AST factories.sign()route bootstrap throughfamily.lowerAst()— noensure*Statementin those paths.Reviewer notes
control-bootstrap.tscolumn shapes. Byte-equality againststatement-buildersconstants is the pin — seepackages/3-targets/6-adapters/*/test/migrations/ddl-lowering.test.ts.ensure*Statementoutput for idempotent bootstrap, not contract-derived DDL.ensure*Statementconstants remain instatement-builders.ts/sql-marker.tsfor tests and golden pins; only the execution paths were rerouted.ColumnType, sharedcontrol-tables.ts) is absent; grep gate included in verification.How it fits together
relational-core/src/ast/ddl-types.tsdefines the family DDL base; targets own concrete node classes in their packages.lower()toAnyQueryAst | TargetDdlNode, routing DDL throughrenderLoweredDdland DML through the existing renderer.@prisma-next/sql-relational-core/contract-freeplus@prisma-next/target-{postgres,sqlite}/contract-freebuild nodes without a contract.buildControlTableBootstrapAsts()/buildSignMarkerBootstrapAsts()on each target; exposed onSqlControlAdapterand the family instance.sign()lower bootstrap ASTs and execute the result.Behavior changes & evidence
packages/3-targets/6-adapters/postgres/src/core/ddl-renderer.ts,packages/3-targets/6-adapters/sqlite/src/core/ddl-renderer.ts. Evidence:packages/3-targets/6-adapters/postgres/test/migrations/ddl-lowering.test.ts, sqlite sibling.packages/2-sql/4-lanes/relational-core/src/contract-free/column.ts, targetcontract-free/ddl.ts. Evidence:test/contract-free/in relational-core and target packages.packages/3-targets/3-targets/postgres/src/core/migrations/runner.ts,packages/2-sql/9-family/src/core/control-instance.ts. Evidence: runner error integration tests, family-sql test suite.sign()is target-correct for SQLite — no longer calls PG-flavoredensureSchemaStatement/ensureTableStatementfromsql-marker.ts.Testing performed
pnpm --filter @prisma-next/target-postgres --filter @prisma-next/target-sqlite --filter @prisma-next/adapter-postgres --filter @prisma-next/adapter-sqlite --filter @prisma-next/family-sql typecheckpnpm fixtures:check(DML lowering byte-identical)ColumnType/CreateSchemaAstin relational-core; noensure*Statementin runner/sign bootstrap pathsFollow-ups
Alternatives considered
AnyQueryAst(PR TML-2253: SQL DDL query-AST + contract-free builder + control-table bootstrap through the adapter #661) — rejected; SQLite would stubCreateSchema, and a neutralColumnTypeenum obscures dialect-native types.family-sqlcontrol-tables surface — rejected; PG and SQLite marker DDL legitimately differ; each target owns its bootstrap shape.DdlVisitorwith SQLite no-ops — rejected; per-target visitor interfaces keep SQLite from stubbing schema operations it doesn't have.Skill update
n/a — internal only (framework/target adapter surface; no user-facing CLI or config change).
Checklist
git commit -s) per the DCO.TML-2761: …form.