Skip to content

Support ALTER COLUMN on SQLite via table rebuild#512

Merged
christianparpart merged 2 commits into
masterfrom
feature/sqlite-alter-column
Jun 25, 2026
Merged

Support ALTER COLUMN on SQLite via table rebuild#512
christianparpart merged 2 commits into
masterfrom
feature/sqlite-alter-column

Conversation

@christianparpart

Copy link
Copy Markdown
Member

SQLite has no ALTER TABLE … ALTER COLUMN, yet the SQLite query formatter emitted the SQL-Server form verbatim. Any AlterColumn migration therefore failed at runtime with near "ALTER": syntax error — for example a downstream lup2dbtool-generated migration that widens a column to long varchar, which translates to plan.AlterTable(...).AlterColumn(...) and runs through this library.

This routes SQLite AlterColumn through the same sentinel + table-rebuild path already used for foreign-key changes, so SQLite reaches real parity with MS SQL Server and PostgreSQL. Those two dialects continue to ALTER the column in place; their formatter branches are untouched.

Changes

  • SQLiteFormatter: emit a -- LIGHTWEIGHT_SQLITE_GUARD: ALTER_COLUMN sentinel carrying the new column type and nullability instead of an unsupported ALTER COLUMN statement.
  • Migration executor: recognise the sentinel and rebuild the table from its stored CREATE TABLE, rewriting only the target column's type and nullability while preserving the other columns, the primary key, and inline constraints (RewriteSqliteColumnDefinition + StripNullabilityKeywords), then copy the data across via the shared RebuildSqliteTable helper.
  • Tests: formatter-output coverage for SQLite (sentinel), PostgreSQL, and SQL Server across both nullability values and a parameterized type; plus end-to-end SQLite rebuild tests driven through MigrationManager (so the guard executor actually fires and the --test-env=sqlite3 CI leg verifies it) covering type widening with data/PK/other-column preservation, NOT NULLNULL in both directions, two folded AlterColumn calls, and a missing-column error path that leaves the table intact.

@christianparpart christianparpart requested a review from a team as a code owner June 24, 2026 16:20
@github-actions github-actions Bot added tests Core API Query Formatter SQL dialect implementations labels Jun 24, 2026
@christianparpart christianparpart force-pushed the feature/sqlite-alter-column branch 2 times, most recently from 65f16f1 to 07efcab Compare June 24, 2026 21:33
@github-actions github-actions Bot added documentation Improvements or additions to documentation Query Builder labels Jun 24, 2026
@christianparpart christianparpart force-pushed the feature/sqlite-alter-column branch from 07efcab to 9122cfe Compare June 25, 2026 08:47
Christian Parpart added 2 commits June 25, 2026 11:35
SQLite has no `ALTER TABLE … ALTER COLUMN`, yet the SQLite formatter emitted
the SQL-Server form verbatim, so an AlterColumn migration failed at runtime with
`near "ALTER": syntax error`. This surfaced in downstream lup2dbtool-generated
migrations (e.g. widening a column to `long varchar`), which translate to
`plan.AlterTable(...).AlterColumn(...)` and run through this library.

Route SQLite AlterColumn through the existing sentinel + table-rebuild path used
for foreign-key changes:

- SQLiteFormatter emits `-- LIGHTWEIGHT_SQLITE_GUARD: ALTER_COLUMN` carrying the
  new column type and nullability.
- The migration executor recognises the sentinel and rebuilds the table from its
  stored CREATE TABLE, rewriting only the target column's type and nullability
  while preserving other columns, the primary key, and inline constraints
  (RewriteSqliteColumnDefinition + StripNullabilityKeywords), then copies the
  data across via the shared RebuildSqliteTable helper.

MS SQL Server and PostgreSQL continue to ALTER the column in place — those
formatter branches are untouched.

Tests:
- QueryBuilderTests: formatter output for SQLite (sentinel), PostgreSQL, and
  SQL Server, for both nullability values and a parameterized type.
- MigrationTests: CI-verified end-to-end SQLite rebuild (run through
  MigrationManager so the guard executor fires) — type widen with data/PK/other
  columns preserved, NOT NULL↔NULL both directions, two folded AlterColumn calls,
  and the missing-column error path leaving the table intact.

Signed-off-by: Christian Parpart <c.parpart@lastrada.net>
The previous commit's local clang-format run used v20; CI enforces v22, which
formats two pre-existing blocks (an SqlInsertDataPlan initializer and the
`m3 "drop temp"` FoldStub) differently. Restore them to master's v22 form so the
"Check C++ style" job passes. No behavioural change.

Signed-off-by: Christian Parpart <c.parpart@lastrada.net>
@christianparpart christianparpart force-pushed the feature/sqlite-alter-column branch from 9122cfe to 9ecf63e Compare June 25, 2026 09:36
@christianparpart christianparpart merged commit 8cd0795 into master Jun 25, 2026
28 checks passed
@christianparpart christianparpart deleted the feature/sqlite-alter-column branch June 25, 2026 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Core API documentation Improvements or additions to documentation Query Builder Query Formatter SQL dialect implementations tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant