Skip to content

fix(cli): rewrite ALTER COLUMN to EQL v3 domains, not just eql_v2_encrypted#728

Open
tobyhede wants to merge 6 commits into
mainfrom
fix/drizzle-v3-alter-column
Open

fix(cli): rewrite ALTER COLUMN to EQL v3 domains, not just eql_v2_encrypted#728
tobyhede wants to merge 6 commits into
mainfrom
fix/drizzle-v3-alter-column

Conversation

@tobyhede

@tobyhede tobyhede commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

What

drizzle-kit generate emits an in-place ALTER TABLE … ALTER COLUMN … SET DATA TYPE when a plaintext column is changed to an encrypted one. Postgres rejects it — there is no cast from text/numeric to an EQL domain — and on drizzle-kit 0.31.0+ the type name is additionally mangled to "undefined"."<type>" because a customType has no typeSchema.

rewriteEncryptedAlterColumns repaired this only for the v2 type eql_v2_encrypted. An EQL v3 user who changed a column's type got an un-runnable migration with nothing to fix it. Closes #693.

Fix

  • Match the whole eql_v3_* domain family alongside eql_v2_encrypted, by shape (eql_v3_[a-z0-9_]+) rather than an enumerated list, so a newly added domain needs no edit here.
  • Capture the mangled type blob and thread the extracted domain through renderSafeAlter, which previously hardcoded the v2 type in its comment and its ADD COLUMN.
  • Run the sweep from stash eql migration --drizzle too. This is the v3 migration-first path and it never called the rewriter — the regex fix alone would not have reached a single v3 user.

Version-dependence (issue and #688 had it backwards)

Reproduced against six drizzle-kit versions via drizzle-kit/api's generateMigration:

dataType() returns ≤ 0.30.6 ≥ 0.31.0
eql_v3_text_search eql_v3_text_search "undefined"."eql_v3_text_search"
public.eql_v3_text_search public.eql_v3_text_search "undefined"."public.eql_v3_text_search"
"public"."eql_v3_text_search" "public"."eql_v3_text_search" "undefined".""public"."eql_v3_text_search""

The "undefined". prefix is a 0.31.0-and-later behaviour, not an older-drizzle-kit artifact as #693 and #688 both state. That yields six mangled forms, all matched. Two of them (public.eql_vN_… and "undefined"."public.eql_vN_…") were unmatched for v2 as well; the latter is exactly what stack emitted for v3 before #688, so pre-#688 RC users have those files on disk today.

Backfill guidance

Kept as a comment on both surfaces. v3 stores the ZeroKMS-produced EQL jsonb envelope rather than v2's composite, but it is still not expressible in SQL, so the UPDATE cannot become real SQL. What is worth adding — and now is — is that this sequence drops the plaintext column in the same migration, whereas the staged stash encrypt lifecycle (add → backfill → cutover → drop) keeps both alive across deploys; the comment now points there for populated tables.

Not in scope (filed as #710)

The sweep is bolted onto eql migration, which runs before the broken migration exists in the intended flow, so it only helps the user who re-runs the command as a recovery step. The complete fix is a standalone repair command (stash eql repair --drizzle, or a check in stash encrypt plan) that can also consult the drizzle journal to avoid rewriting an already-applied jsonb→v3 migration. Filed as #710 rather than expanding this PR's surface.

Tests

  • All 40 v3 domains, seven mangled forms, the two newly-matched v2 forms, mixed v2+v3 in one file, the guidance comment naming the right domain, and negative cases (text, jsonb, eql_v4_*, not_eql_v3_*).
  • New eql migration --drizzle tests: sweeps a broken sibling; does not rewrite the install migration it just generated (the skip is verified load-bearing — the test fails if skip is dropped).
  • Non-vacuousness verified: reverting only the two source files leaves 52 tests failing; restoring makes them pass.
  • pnpm --filter stash test → 640 passed / 51 files. pnpm --filter @cipherstash/wizard test → 145 passed. pnpm run code:check → exit 0.

Skills / changeset

skills/stash-cli and skills/stash-drizzle document the new sweep behaviour and the plaintext→encrypted column-change hazard. The wizard's copy of the rewriter stays v2-only (it only scaffolds v2 columns); its cross-reference comment records the divergence. Changeset: stash patch.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Fixed migration rewriting for ALTER COLUMN ... SET DATA TYPE when switching from plaintext to CipherStash EQL encrypted domains (EQL v2 and full EQL v3 family, including schema-qualified and version-mangled forms).
    • Prevents invalid in-place SET DATA TYPE migrations by rewriting eligible statements into a safe multi-step ADD/DROP/RENAME flow.
    • Improves reporting for near-miss statements and warns when the sweep is incomplete so sibling migrations can be reviewed.
  • Documentation

    • Added clearer warnings about data loss and guidance to use the staged encrypt/cutover path for populated tables.

tobyhede added 2 commits July 20, 2026 15:39
…rypted

drizzle-kit emits an in-place `ALTER TABLE ... ALTER COLUMN ... SET DATA
TYPE` when a plaintext column is changed to an encrypted one. Postgres
rejects it (no cast from text/numeric to an EQL type), and on drizzle-kit
0.31.0+ the type name is additionally mangled to `"undefined"."<type>"`
because a customType has no `typeSchema`.

`rewriteEncryptedAlterColumns` repaired this only for the v2 type, so an
EQL v3 user got an un-runnable migration with nothing to fix it (#693).

- Match the whole `eql_v3_*` domain family alongside `eql_v2_encrypted`,
  by shape rather than an enumerated list, so a new domain needs no edit
  here.
- Capture the mangled type blob and thread the extracted domain through
  `renderSafeAlter`, which no longer hardcodes the v2 type.
- Cover all six mangled forms, verified empirically against drizzle-kit
  0.24.2 / 0.28.1 / 0.30.6 / 0.31.0 / 0.31.1 / 0.31.10 via
  `drizzle-kit/api`. The `"undefined".` prefix is a 0.31.0-AND-LATER
  behaviour; #693 and #688 both describe it as an older-drizzle-kit
  artifact, which is backwards. Two forms this adds
  (`public.eql_vN_...` and `"undefined"."public.eql_vN_..."`) were
  unmatched for v2 as well, and the latter is what stack emitted for v3
  before #688.
- Run the sweep from `stash eql migration --drizzle` too. That is the
  v3 migration-first path and it never called the rewriter, so the
  regex fix alone would not have reached a single v3 user.

Backfill guidance: v3 stores the ZeroKMS-produced EQL jsonb envelope
rather than v2's composite, but it is still not expressible in SQL, so
the UPDATE stays a guidance comment on both surfaces. What is worth
adding is that this sequence DROPS the plaintext column in the same
migration, whereas the staged `stash encrypt` lifecycle keeps both alive
across deploys — so the comment now points there for populated tables.

The wizard's copy of the rewriter stays v2-only (it only scaffolds v2
columns); its cross-reference comment records the divergence.

Closes #693
The test asserted only that the generated migration still contained the
EQL bundle. The bundle carries no ALTER COLUMN of its own, so the sweep
would never have rewritten it and the test passed with `skip` removed.

Append an unsafe ALTER to what the command writes, and put the identical
statement in a sibling file: the generated migration must keep it
verbatim while the sibling gets rewritten. Verified it fails when `skip`
is dropped.

Found by CodeRabbit.
@tobyhede
tobyhede requested a review from a team as a code owner July 21, 2026 00:06
@changeset-bot

changeset-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8dcbf05

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
stash Patch
@cipherstash/basic-example Patch
@cipherstash/e2e Patch
@cipherstash/stack Patch
@cipherstash/stack-drizzle Patch
@cipherstash/stack-supabase Patch
@cipherstash/prisma-next Patch
@cipherstash/wizard Patch
@cipherstash/bench Patch
@cipherstash/test-kit Patch
@cipherstash/prisma-next-example Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f107392d-67dd-4de4-a2f9-61a45c087900

📥 Commits

Reviewing files that changed from the base of the PR and between 17a5dfe and 8dcbf05.

📒 Files selected for processing (1)
  • packages/cli/src/commands/db/install.ts

📝 Walkthrough

Walkthrough

The migration rewriter now recognizes EQL v2 and v3 encrypted domains, rewrites eligible Drizzle ALTER statements, reports skipped near-misses, and preserves schema qualifiers. Both migration workflows invoke the sweep, with tests and documentation covering its behavior and data-handling guidance.

Changes

EQL migration rewrite

Layer / File(s) Summary
Domain-aware rewrite engine
packages/cli/src/commands/db/rewrite-migrations.ts, packages/cli/src/__tests__/rewrite-migrations.test.ts
The rewriter supports EQL v2/v3 domains and mangled Drizzle forms, returns rewritten and skipped results, preserves schemas, and emits domain-specific ADD/DROP/RENAME SQL with expanded tests.
Migration workflow integration
packages/cli/src/commands/eql/migration.ts, packages/cli/src/commands/db/install.ts, packages/cli/src/commands/eql/__tests__/migration.test.ts
The EQL migration-first and install flows sweep migrations, skip the generated install migration, log results, and warn when statements remain unresolved.
Guidance and release documentation
.changeset/wild-donkeys-shave.md, skills/stash-cli/SKILL.md, skills/stash-drizzle/SKILL.md, packages/wizard/src/lib/rewrite-migrations.ts
Documentation describes EQL v3 handling, data-dropping rewrites, staged migration guidance, and the wizard/stash implementation divergence.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant eqlMigrationCommand
  participant rewriteEncryptedAlterColumns
  participant SiblingMigrations
  participant MigrationLogger
  eqlMigrationCommand->>rewriteEncryptedAlterColumns: sweep output directory and skip generated migration
  rewriteEncryptedAlterColumns->>SiblingMigrations: rewrite eligible sibling ALTER statements
  rewriteEncryptedAlterColumns->>eqlMigrationCommand: return rewritten and skipped results
  eqlMigrationCommand->>MigrationLogger: log rewrites and incomplete-sweep warnings
Loading

Possibly related issues

  • cipherstash/stack issue 707 — Covers the prerequisite generalization from EQL v2 to the EQL v3 domain family.
  • cipherstash/stack issue 710 — Relates to the migration-rewrite sweep and its potential standalone repair command.
  • cipherstash/stack issue 534 — Covers complementary EQL v3 schema-builder changes.

Possibly related PRs

  • cipherstash/stack#353 — Modifies the same rewriter logic for mangled Drizzle ALTER statements and ADD/DROP/RENAME output.
  • cipherstash/stack#691 — Introduces the migration-first Drizzle flow extended by this sweep.

Suggested reviewers: freshtonic

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly names the main change: rewriting ALTER COLUMN handling for EQL v3 domains instead of only the v2 encrypted type.
Linked Issues check ✅ Passed The code and tests cover the v2/v3 rewrite path, mangled forms, skipped statements, and unsafe backfill guidance required by #693.
Out of Scope Changes check ✅ Passed The docs, tests, and wizard comment updates all support the migration-rewriter work and stay within the PR's stated scope.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/drizzle-v3-alter-column

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@tobyhede
tobyhede requested a review from freshtonic July 21, 2026 00:18
tobyhede added 2 commits July 21, 2026 10:27
Two review findings on the rewrite:

- The guidance comment told the user to "backfill the new column BEFORE
  running this migration" — impossible, since the temp column is created
  BY this migration's ADD COLUMN and the original is dropped in the same
  run. The sequence is equivalent to DROP+ADD: it fixes the type but does
  not preserve data, so it is safe ONLY on an empty table. Reworded the
  comment (and the two skills) to say exactly that and to point a
  populated table at the staged `stash encrypt` path instead.

- Narrow the match tail from `[^;]*;` to `\s*;` so a hand-authored
  `SET DATA TYPE <type> USING <expr>;` — a runnable statement the user
  wrote deliberately — is left untouched rather than silently rewritten
  with its USING clause discarded. drizzle-kit's own output has no
  trailing clause, so this changes nothing for the real broken forms.
  Added a regression test (fails under the old `[^;]*;`).

Found by CodeRabbit.
The Step 4/5 comment and `p.log.info` on both sweep call sites
(`eql migration --drizzle` and `eql install --drizzle`) still said the
rewrite "works on empty and populated tables alike" / was a "safe
ADD+migrate+DROP" — the same overclaim just corrected in the rewriter
and skills. The sequence is equivalent to DROP+ADD: runnable, safe on an
empty table, data-destroying on a populated one. Reword both to say so
and to point at each file's header comment (which steers populated
tables to the staged `stash encrypt` path).

Found by CodeRabbit. Two further findings on the same review — the
rewrite not preserving column constraints, and the regex not being
SQL-context-aware — are limitations of the shared v2 rewriter this
change inherits rather than defects in it; deferred to the standalone
repair-command follow-up (#710) rather than redesigning shipped v2
behaviour inside a v3 bugfix.
Comment thread packages/cli/src/__tests__/rewrite-migrations.test.ts

@coderdan coderdan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — stash migration rewriter (v3 domain support)

Deep pass over the rewriter. The core change is right: matching the eql_v3_* family by shape, carrying the matched domain into the replacement, and wiring the sweep into eql migration --drizzle all check out, and the 42-domain list in the test matches packages/stack/src/eql/v3/ exactly. 80/80 tests pass locally.

I verified the regex empirically against realistic drizzle-kit output rather than by reading. Results: --> statement-breakpoint, lowercase SQL, a newline before the ;, and mixed v2/v3 in one file all match correctly. Two inputs do not match — details below and inline.

Nine findings; six are inline. The three below sit outside the diff hunks, so GitHub won't anchor them.


1. The exported function's docblock still claims populated-table safety — rewrite-migrations.ts:78-90

This is the same falsehood a71b9a8 removed from the user-facing messages, surviving in the API documentation:

"The fix that works on both empty and non-empty tables is to add a new encrypted column, backfill it, drop the original..."
"Running this migration against a populated table leaves the new column NULL until the app backfills it."

That reads as recoverable — as though the plaintext is still there to backfill from. It isn't: renderSafeAlter emits DROP COLUMN in the same migration, and its own docblock at line 131 now says the sequence DESTROYS the data. The two docblocks in this one file directly contradict each other, and the wrong one is on the exported symbol.

Worth fixing in this PR precisely because it's the class of drift the PR set out to correct. (It also still describes only eql_v2_encrypted.)

2. No diagnostic when an encrypted ALTER is detected but not rewritten — rewrite-migrations.ts:105

The sweep returns only files it changed; callers log Rewrote N file(s) or stay silent. Anything recognisably an ALTER-to-encrypted that falls outside the pattern — a schema-qualified table (see inline on line 70), any trailing clause now that the tail is \s*;, a form a future drizzle-kit adds — is passed over with zero output. The user believes the sweep ran and ships a migration that dies at drizzle-kit migrate.

Given the tail was deliberately tightened this PR, the silent-miss surface grew. A cheap second pass — match SET DATA TYPE near an eql_v[23] token, warn on anything the strict regex didn't rewrite — turns every one of these into an actionable message and costs one extra scan.

3. Four statements share one --> statement-breakpoint chunk — rewrite-migrations.ts:165

drizzle-kit splits on --> statement-breakpoint and sends each chunk as one query. The rewrite replaces one statement with four joined by \n and inserts no breakpoints, so all four arrive as a single multi-statement string. node-postgres tolerates that in simple-query mode; the Neon HTTP driver and postgres.js in prepared mode reject multiple commands per statement — failing exactly the projects this unblocks. Pre-existing, but this PR extends it to every v3 user.

Comment thread packages/cli/src/commands/db/rewrite-migrations.ts Outdated
Comment thread packages/cli/src/commands/db/rewrite-migrations.ts Outdated
Comment thread packages/cli/src/commands/db/rewrite-migrations.ts Outdated
Comment thread packages/cli/src/commands/db/rewrite-migrations.ts Outdated
Comment thread packages/cli/src/commands/eql/migration.ts
Comment thread skills/stash-drizzle/SKILL.md Outdated
Respond to review feedback on the migration rewriter:

- Match schema-qualified tables (app.users from pgSchema()); thread the
  schema through renderSafeAlter so every emitted statement stays qualified.
- Derive DOMAIN_RE from ENCRYPTED_DOMAIN so the domain alternation has one
  source of truth (silent-miss if they drift).
- Warn in the emitted guidance that NOT NULL, DEFAULT, UNIQUE, and indexes are
  not carried over by the ADD/DROP/RENAME.
- Drop the trailing ; from the commented UPDATE placeholder so naive
  semicolon-splitting runners can't cut mid-comment.
- Rewrite the exported docblock: the sequence destroys data and is empty-table
  only, matching renderSafeAlter; covers both v2 and the v3 domain family.
- Report near-miss encrypted ALTERs the strict regex didn't rewrite (skipped)
  instead of passing them over silently; return { rewritten, skipped }.
- Insert --> statement-breakpoint between emitted statements so Neon HTTP /
  postgres.js prepared-mode drivers don't reject multi-command chunks.
- Surface an incomplete sweep in the closing next-steps note, not just an
  inline warning sandwiched between success messages.
- Reduce the duplicated plaintext->encrypted warning in stash-drizzle to the
  drizzle-specific detail plus a cross-reference; stash-cli owns the full
  safety explanation.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/cli/src/commands/db/install.ts (1)

616-630: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Skipped near-misses aren't re-surfaced at the closing note (inconsistent with migration.ts).

When skipped.length > 0, the warning is logged inline at Line 617, but execution then falls through to p.log.success('Migration created') and the "run drizzle-kit migrate" note. The warning scrolls past between success output, and the user is steered to migrate against sibling SQL that still holds un-runnable ALTER COLUMN statements.

generateDrizzleEqlMigration in packages/cli/src/commands/eql/migration.ts already solved this by tracking sweepIncomplete and re-warning at the closing note. This v2 install path — the one that "has always done this" — should get the same treatment for parity.

♻️ Mirror the sweepIncomplete closing-note warning
+  let sweepIncomplete = false
   try {
     const { rewritten, skipped } = await rewriteEncryptedAlterColumns(outDir, {
       skip: generatedMigrationPath,
     })
     if (rewritten.length > 0) {
       p.log.info(
         `Rewrote ${rewritten.length} migration file(s) into a runnable ADD+DROP+RENAME for encrypted columns (safe on empty tables; see each file's header before running against populated data):`,
       )
       for (const file of rewritten) p.log.step(`  - ${file}`)
     }
     if (skipped.length > 0) {
+      sweepIncomplete = true
       p.log.warn(
         `Found ${skipped.length} ALTER-to-encrypted statement(s) the sweep could not rewrite automatically. Review and fix them before running your migrations:`,
       )
       for (const { file, statement } of skipped) {
         p.log.step(`  - ${file}: ${statement}`)
       }
     }
   } catch (error) {
+    sweepIncomplete = true
     p.log.warn(
       `Could not rewrite ALTER COLUMN migrations: ${error instanceof Error ? error.message : String(error)}`,
     )
   }
 
   p.log.success(`Migration created: ${generatedMigrationPath}`)
+  if (sweepIncomplete) {
+    p.log.warn(
+      `The ALTER COLUMN sweep did not fully complete — review the sibling migrations in ${outDir} before running drizzle-kit migrate, or you may apply broken/unsafe SQL.`,
+    )
+  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/commands/db/install.ts` around lines 616 - 630, Track
whether the ALTER-to-encrypted sweep was incomplete when skipped statements are
found, using the existing skipped handling in the install migration flow. At the
closing output near p.log.success, re-emit the warning and migration guidance
when that flag is set, matching generateDrizzleEqlMigration’s sweepIncomplete
behavior so users are not directed to run migrations containing unrewriteable
statements.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/cli/src/commands/db/install.ts`:
- Around line 616-630: Track whether the ALTER-to-encrypted sweep was incomplete
when skipped statements are found, using the existing skipped handling in the
install migration flow. At the closing output near p.log.success, re-emit the
warning and migration guidance when that flag is set, matching
generateDrizzleEqlMigration’s sweepIncomplete behavior so users are not directed
to run migrations containing unrewriteable statements.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b29e3fda-4b0f-441c-b591-22156d9756c7

📥 Commits

Reviewing files that changed from the base of the PR and between 4888995 and 17a5dfe.

📒 Files selected for processing (9)
  • .changeset/wild-donkeys-shave.md
  • packages/cli/src/__tests__/rewrite-migrations.test.ts
  • packages/cli/src/commands/db/install.ts
  • packages/cli/src/commands/db/rewrite-migrations.ts
  • packages/cli/src/commands/eql/__tests__/migration.test.ts
  • packages/cli/src/commands/eql/migration.ts
  • packages/wizard/src/lib/rewrite-migrations.ts
  • skills/stash-cli/SKILL.md
  • skills/stash-drizzle/SKILL.md

The v2 install path (generateDrizzleMigration) warned inline on a skipped
statement or a thrown sweep, then fell through to the 'Migration created'
success line and the 'run drizzle-kit migrate' note with no re-surfacing —
so the warning scrolled past and the user was steered to migrate against
un-swept, broken sibling SQL.

Mirror the sweepIncomplete flag + closing-note warning already used in the
v3 stash eql migration --drizzle path (migration.ts), giving the two
migration surfaces parity. Addresses the CodeRabbit parity nitpick on #728.
@tobyhede

Copy link
Copy Markdown
Contributor Author

@coderabbitai Applied in 8dcbf05.

generateDrizzleMigration (the v2 install path) now mirrors the v3 stash eql migration --drizzle path: a sweepIncomplete flag is set both when skipped.length > 0 and in the catch, and re-surfaced as a warning at the closing note after Migration created:, immediately before the drizzle-kit migrate next-step. The two migration surfaces are now at parity, so a user is no longer steered to migrate against un-swept sibling SQL with the only warning scrolled past.

No test added: generateDrizzleMigration has no unit-test harness in this repo, and the change is a line-for-line mirror of the v3 logic already covered by migration.test.ts ("warns at the closing note when the sweep leaves skipped statements"). Standing up a new spawn/clack/fs mock harness for the install path is out of proportion to the nit; the untested-install-path gap predates this PR.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@tobyhede Thanks—this addresses the concern. Mirroring the v3 sweepIncomplete handling and surfacing it immediately before the drizzle-kit migrate instruction keeps both migration flows consistent. The test rationale is reasonable for this small, line-for-line parity change.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

@tobyhede
tobyhede requested a review from coderdan July 21, 2026 08:08
@coderdan

Copy link
Copy Markdown
Contributor

I thought the plan was to remove V2 entirely but I'm okay leaving it, so we get this one out of the line, if that is removed as a follow-up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

drizzle-kit v3: ALTER COLUMN to an eql_v3 domain emits invalid DDL (no v3 rewriter)

2 participants