Simplify v332 migration and add cross-DB test

Tested against the CI image versions (postgres:14, bitnamilegacy/mysql:8.0,
mcr.microsoft.com/mssql/server:2019-latest) plus SQLite. Both the original
implementation (per-dialect SQL) and a naive `base.ModifyColumn` with
`DefaultIsEmpty: false` were tried. Findings:

- DefaultIsEmpty: false fails on MSSQL with "Incorrect syntax near the
  keyword 'DEFAULT'" because MSSQL's ALTER COLUMN does not accept inline
  DEFAULT (it lives in a separate constraint object).
- DefaultIsEmpty: true succeeds on MSSQL (existing default constraint
  unaffected) and Postgres (DEFAULT constraint is independent of TYPE)
  but drops the DEFAULT on MySQL because MODIFY COLUMN rewrites all
  column attributes.

Settled on the minimal cross-DB form: base.ModifyColumn with
DefaultIsEmpty: true to widen the type, then a MySQL-only follow-up
`ALTER ... SET DEFAULT 0` to restore the default that MODIFY COLUMN drops.

The new test seeds rows at the int8 boundary (0 and 127), runs the
migration, asserts the column type widened, the rows preserved, and that
inserting a value > 127 succeeds afterward.

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
This commit is contained in:
silverwind
2026-04-27 12:55:08 +02:00
committed by beardev-in
parent efe43882d5
commit d6ae7c1c50
2 changed files with 107 additions and 6 deletions

View File

@@ -10,17 +10,32 @@ import (
"xorm.io/xorm/schemas"
)
// WidenProjectBoardSorting changes project_board.sorting from int8 (TINYINT) to int (INTEGER)
// so the public API can expose a regular int and lift the 127 column upper bound.
// WidenProjectBoardSorting changes project_board.sorting from int8 (TINYINT/SMALLINT)
// to int. The previous int8 type capped projects at 127 columns and forced the API
// to truncate user-supplied sort values. SQLite uses dynamic typing so the schema
// type is cosmetic; existing rows already store the wider value.
//
// `base.ModifyColumn` is called with DefaultIsEmpty: true because MSSQL's ALTER
// COLUMN syntax does not accept inline DEFAULT (it would error on the keyword).
// On MySQL, MODIFY COLUMN without an explicit DEFAULT drops the existing default,
// so it has to be reapplied. On Postgres and MSSQL the DEFAULT constraint is
// maintained separately from the column type and is preserved automatically.
func WidenProjectBoardSorting(x *xorm.Engine) error {
if x.Dialect().URI().DBType == schemas.SQLITE {
return nil
}
return base.ModifyColumn(x, "project_board", &schemas.Column{
if err := base.ModifyColumn(x, "project_board", &schemas.Column{
Name: "sorting",
SQLType: schemas.SQLType{Name: "INT"},
Nullable: false,
Default: "0",
DefaultIsEmpty: false,
})
DefaultIsEmpty: true,
}); err != nil {
return err
}
if x.Dialect().URI().DBType == schemas.MYSQL {
if _, err := x.Exec("ALTER TABLE `project_board` ALTER `sorting` SET DEFAULT 0"); err != nil {
return err
}
}
return nil
}