Compare commits

..
2 Commits
Author SHA1 Message Date
warkanum 19b592820c chore(release): update package version to 1.0.69
Release / test (push) Successful in 4m9s
Release / release (push) Successful in 2m11s
Release / pkg-deb (push) Failing after 1m46s
Release / pkg-aur (push) Successful in 2m5s
Release / pkg-rpm (push) Successful in 2m36s
2026-08-17 22:36:35 +02:00
warkanum b158a98acc fix(pgsql): strip backticks from column defaults in migration paths
Backtick-wrapped defaults (e.g. from GORM tags like `now()`) were only
stripped in the CREATE TABLE column-definition path, leaving raw
backticks in the ALTER COLUMN ... SET DEFAULT migration statement and
in the migration-generated CREATE TABLE template, producing invalid
SQL. Default-drift comparisons also compared raw values, so a
backtick-wrapped model default never matched the live DB default and
kept re-emitting redundant ALTER statements.
2026-08-17 22:36:14 +02:00
6 changed files with 54 additions and 6 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# Maintainer: Hein (Warky Devs) <hein@warky.dev>
pkgname=relspec
pkgver=1.0.68
pkgver=1.0.69
pkgrel=1
pkgdesc="RelSpec is a comprehensive database relations management tool that reads, transforms, and writes database table specifications across multiple formats and ORMs."
arch=('x86_64' 'aarch64')
+1 -1
View File
@@ -1,5 +1,5 @@
Name: relspec
Version: 1.0.68
Version: 1.0.69
Release: 1%{?dist}
Summary: RelSpec is a comprehensive database relations management tool that reads, transforms, and writes database table specifications across multiple formats and ORMs.
+19 -2
View File
@@ -460,7 +460,7 @@ func (w *MigrationWriter) generateAlterTableScripts(schema *models.Schema, model
}
// Check default value changes
if fmt.Sprintf("%v", modelCol.Default) != fmt.Sprintf("%v", currentCol.Default) {
if !columnDefaultsEqual(modelCol.Default, currentCol.Default) {
setDefault, defaultVal := formatColumnDefaultSQL(modelCol)
sql, err := w.executor.ExecuteAlterColumnDefaultWithCheck(AlterColumnDefaultWithCheckData{
@@ -956,7 +956,24 @@ func columnsEqual(col1, col2 *models.Column) bool {
}
return columnTypesEqual(col1, col2) &&
col1.NotNull == col2.NotNull &&
fmt.Sprintf("%v", col1.Default) == fmt.Sprintf("%v", col2.Default)
columnDefaultsEqual(col1.Default, col2.Default)
}
// columnDefaultsEqual compares column defaults for drift detection, stripping
// MySQL-style backticks (e.g. from GORM tags) so a model default of
// "`now()`" is recognised as equal to a live default of "now()".
func columnDefaultsEqual(default1, default2 interface{}) bool {
return normalizeDefaultForCompare(default1) == normalizeDefaultForCompare(default2)
}
func normalizeDefaultForCompare(value interface{}) string {
if value == nil {
return ""
}
if s, ok := value.(string); ok {
return strings.TrimSpace(stripBackticks(s))
}
return fmt.Sprintf("%v", value)
}
func columnTypesEqual(col1, col2 *models.Column) bool {
+1 -1
View File
@@ -530,7 +530,7 @@ func BuildCreateTableData(schemaName string, table *models.Table) CreateTableDat
}
if col.Default != nil {
if value, ok := col.Default.(string); ok {
colData.Default = writers.QuoteDefaultValue(value, col.Type)
colData.Default = writers.QuoteDefaultValue(stripBackticks(value), col.Type)
} else {
colData.Default = fmt.Sprintf("%v", col.Default)
}
+1 -1
View File
@@ -512,7 +512,7 @@ func formatColumnDefaultSQL(col *models.Column) (setDefault bool, defaultVal str
return false, ""
}
if value, ok := col.Default.(string); ok {
return true, writers.QuoteDefaultValue(value, col.Type)
return true, writers.QuoteDefaultValue(stripBackticks(value), col.Type)
}
return true, fmt.Sprintf("%v", col.Default)
}
+31
View File
@@ -1140,6 +1140,37 @@ func TestWriteSchema_EmitsGuardedAlterColumnDefaultStatements(t *testing.T) {
}
}
func TestWriteSchema_AlterColumnDefaultStripsBackticksFromFunctionExpression(t *testing.T) {
db := models.InitDatabase("testdb")
schema := models.InitSchema("public")
table := models.InitTable("agent_skills", "public")
updatedAtCol := models.InitColumn("updatedat", "agent_skills", "public")
updatedAtCol.Type = "timestamp"
updatedAtCol.Default = "`now()`"
table.Columns["updatedat"] = updatedAtCol
schema.Tables = append(schema.Tables, table)
db.Schemas = append(db.Schemas, schema)
var buf bytes.Buffer
writer := NewWriter(&writers.WriterOptions{})
writer.writer = &buf
if err := writer.WriteDatabase(db); err != nil {
t.Fatalf("WriteDatabase failed: %v", err)
}
output := buf.String()
if strings.Contains(output, "`") {
t.Fatalf("expected no backticks in generated SQL, got:\n%s", output)
}
if !strings.Contains(output, "ALTER COLUMN updatedat SET DEFAULT now()") {
t.Fatalf("expected guarded SET DEFAULT now() without backticks, got:\n%s", output)
}
}
func TestWriteSchema_GuardedAlterColumnTypeFallsBackOnConversionFailure(t *testing.T) {
db := models.InitDatabase("testdb")
schema := models.InitSchema("public")