fix(pgsql): handle default values for array types in migrations

* update default value quoting logic for PostgreSQL
* add tests for array default value handling
This commit is contained in:
Hein
2026-04-30 18:16:21 +02:00
parent d30fc24f55
commit 0a3966e6fc
6 changed files with 152 additions and 14 deletions

View File

@@ -110,8 +110,12 @@ func SanitizeFilename(name string) string {
// Examples (bigint): "0" → "0"
// Examples (timestamp): "now()" → "now()" (function call never quoted)
func QuoteDefaultValue(value, sqlType string) string {
value = strings.TrimSpace(value)
// Function calls are never quoted regardless of column type.
if strings.Contains(value, "(") || strings.Contains(value, ")") {
if strings.Contains(value, "(") || strings.Contains(value, ")") ||
strings.Contains(value, "::") ||
strings.HasPrefix(strings.ToUpper(value), "ARRAY[") {
return value
}
@@ -121,6 +125,16 @@ func QuoteDefaultValue(value, sqlType string) string {
baseType = baseType[:idx]
}
if isArraySQLType(baseType) {
if arrayLiteral, ok := normalizeArrayDefaultLiteral(value); ok {
return quoteSQLLiteral(arrayLiteral)
}
}
if isQuotedSQLLiteral(value) {
return value
}
// Types whose default values must NOT be quoted.
unquotedTypes := map[string]bool{
// Integer types
@@ -154,7 +168,32 @@ func QuoteDefaultValue(value, sqlType string) string {
// Everything else (text, varchar, char, uuid, date, time, timestamp, json, …)
// is treated as a quoted literal.
return "'" + value + "'"
return quoteSQLLiteral(value)
}
func isArraySQLType(sqlType string) bool {
return strings.HasSuffix(sqlType, "[]")
}
func normalizeArrayDefaultLiteral(value string) (string, bool) {
switch {
case strings.HasPrefix(value, "''{") && strings.HasSuffix(value, "}''"):
return value[2 : len(value)-2], true
case strings.HasPrefix(value, "'{") && strings.HasSuffix(value, "}'"):
return value[1 : len(value)-1], true
case strings.HasPrefix(value, "{") && strings.HasSuffix(value, "}"):
return value, true
default:
return "", false
}
}
func isQuotedSQLLiteral(value string) bool {
return len(value) >= 2 && strings.HasPrefix(value, "'") && strings.HasSuffix(value, "'")
}
func quoteSQLLiteral(value string) string {
return "'" + strings.ReplaceAll(value, "'", "''") + "'"
}
// SanitizeStructTagValue sanitizes a value to be safely used inside Go struct tags.