fix: implement ColumnCheckSQL to make AddColumn idempotent (#112227)

SQLite dialect now checks column existence via PRAGMA table_info, enabling
IfColumnNotExistsCondition to work correctly. Previously, BaseDialect returned
empty SQL, so AddColumn ran unconditionally and could fail with
“duplicate column name” under parallel CI runs.

- Prevents duplicate-column errors in SQLite migrations (e.g. unified storage
  adding previous_resource_version) when migration locking/logging don’t serialize
  execution.
- No change for other dialects.
This commit is contained in:
Jean-Philippe Quéméner
2025-10-09 22:17:50 +03:00
committed by GitHub
parent d291671ed1
commit e6e58c3a56
@@ -87,6 +87,17 @@ func (db *SQLite3) IndexCheckSQL(tableName, indexName string) (string, []any) {
return sql, args
}
func (db *SQLite3) ColumnCheckSQL(tableName, columnName string) (string, []any) {
// Use PRAGMA table_info to check if a column exists on a table. In SQLite, quoting with backticks inside
// pragma_table_info(<expr>) can be interpreted as an identifier/column. Instead, pass the table name as a
// string literal to avoid ambiguity. We cannot parameterize identifiers, but pragma_table_info accepts string
// literals, so we embed a single-quoted literal safely by replacing single quotes if any.
// Note: tableName is expected to be a trusted identifier from migrations.
safeTable := strings.ReplaceAll(tableName, "'", "''")
sql := "SELECT 1 FROM pragma_table_info('" + safeTable + "') WHERE name = ?"
return sql, []any{columnName}
}
func (db *SQLite3) DropIndexSQL(tableName string, index *Index) string {
quote := db.Quote
// var unique string