Skip to content

[SQLite-kit] Fix column rename breaking INSERT INTO...SELECT during table recreate#5597

Open
funsaized wants to merge 1 commit intodrizzle-team:mainfrom
funsaized:fix/sqlite-column-rename-recreate-table
Open

[SQLite-kit] Fix column rename breaking INSERT INTO...SELECT during table recreate#5597
funsaized wants to merge 1 commit intodrizzle-team:mainfrom
funsaized:fix/sqlite-column-rename-recreate-table

Conversation

@funsaized
Copy link
Copy Markdown

@funsaized funsaized commented Apr 6, 2026

Summary

Fixes #5587

When a SQLite column rename coincides with a table recreation (e.g., renaming a column while also changing its type or default value), the generated INSERT INTO...SELECT migration SQL uses the new column name in the SELECT clause. Since the old table still has the old column name, the migration fails.

Before (broken):

INSERT INTO `__new_task`("is_visible") SELECT "is_visible" FROM `task`;
-- ERROR: "is_visible" doesn't exist in old table (it's still "is_invisible")

After (fixed):

INSERT INTO `__new_task`("is_visible") SELECT "is_invisible" FROM `task`;
-- Correctly reads from old column name, writes to new column name

Root Cause

When sqliteCombineStatements / libSQLCombineStatements combine an alter_table_rename_column with other statements that trigger table recreation, the column rename info is lost — the rename statement is dropped when recreate_table replaces existing statements, so the SQL generator uses new column names on both sides of the INSERT INTO...SELECT.

Changes

  • jsonStatements.ts: Added optional columnRenames field to JsonRecreateTableStatement
  • statementCombiner.ts: Track column renames per table during statement combination, inject them into any recreate_table for that table. When columnRenames is injected, also strip retained alter_table_rename_column statements from the output — prevents double-rename when rename_table causes the combiner to preserve (push) rather than replace statements.
  • sqlgenerator.ts: SQLiteRecreateTableConvertor and LibSQLRecreateTableConvertor build a rename map and use old column names in SELECT while keeping new names in INSERT
  • Tests: Updated existing combiner test expectation; added test for rename_table + rename_column + type change on same table (verifies rename is absorbed into recreate, not retained as separate statement)

Testing

  • All 88 existing SQLite/LibSQL tests pass
  • All 25 statement combiner tests pass (SQLite + LibSQL + SingleStore), including new test

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 03ebf69ee1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (stmts) {
const recreate = stmts.find((s) => s.type === 'recreate_table') as JsonRecreateTableStatement | undefined;
if (recreate) {
recreate.columnRenames = renames;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Skip columnRenames when rename_column statement is retained

This assignment copies every alter_table_rename_column into recreate_table, even in flows where the rename statement is still executed (for example when rename_table is present and the combiner keeps prior statements). In that case migration order becomes RENAME COLUMN ... followed by recreate SQL that now selects the old name from the already-renamed table, so INSERT INTO ... SELECT fails with a missing-column error. columnRenames should only include renames that were removed from the final statement list, not renames that will run explicitly.

Useful? React with 👍 / 👎.

…olumn rename

When rename_column coincides with table recreation, the generated INSERT INTO...SELECT
now correctly uses old column names in SELECT while using new names in INSERT.

Also strips retained rename_column statements when a recreate_table absorbs
them via columnRenames, preventing double-rename when rename_table is present.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@funsaized funsaized force-pushed the fix/sqlite-column-rename-recreate-table branch from 03ebf69 to 22c20fc Compare April 6, 2026 11:01
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.

[BUG]: SQLite column name change error

1 participant