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:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user