Skip to content

Commit 6c3f4e9

Browse files
author
Radu Sora
committed
feat: add support for databases enforcing strict data integrity through PKs. Fixes argoproj#13611
Signed-off-by: Radu Sora <[email protected]>
1 parent 89d75a6 commit 6c3f4e9

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

persist/sqldb/migrate.go

+32-2
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,43 @@ func ternary(condition bool, left, right change) change {
4040
}
4141

4242
func (m migrate) Exec(ctx context.Context) (err error) {
43+
44+
dbType := dbTypeFor(m.session)
45+
4346
{
4447
// poor mans SQL migration
45-
_, err = m.session.SQL().Exec("create table if not exists schema_history(schema_version int not null)")
48+
_, err = m.session.SQL().Exec("create table if not exists schema_history(schema_version int not null, primary key(schema_version))")
49+
if err != nil {
50+
return err
51+
}
52+
53+
// Ensure the schema_history table has a primary key, creating it if necessary
54+
// This logic is implemented separately from regular migrations to improve compatibility with databases running in strict or HA modes
55+
dbIdentifierColumn := "table_schema"
56+
if dbType == Postgres {
57+
dbIdentifierColumn = "table_catalog"
58+
}
59+
rows, err := m.session.SQL().Query(
60+
"select 1 from information_schema.table_constraints where constraint_type = 'PRIMARY KEY' and table_name = 'schema_history' and "+dbIdentifierColumn+" = ?",
61+
m.session.Name())
4662
if err != nil {
4763
return err
4864
}
65+
defer func() {
66+
tmpErr := rows.Close()
67+
if err == nil {
68+
err = tmpErr
69+
}
70+
}()
71+
if !rows.Next() {
72+
_, err := m.session.SQL().Exec("alter table schema_history add primary key(schema_version)")
73+
if err != nil {
74+
return err
75+
}
76+
} else if err := rows.Err(); err != nil {
77+
return err
78+
}
79+
4980
rs, err := m.session.SQL().Query("select schema_version from schema_history")
5081
if err != nil {
5182
return err
@@ -65,7 +96,6 @@ func (m migrate) Exec(ctx context.Context) (err error) {
6596
return err
6697
}
6798
}
68-
dbType := dbTypeFor(m.session)
6999

70100
log.WithFields(log.Fields{"clusterName": m.clusterName, "dbType": dbType}).Info("Migrating database schema")
71101

0 commit comments

Comments
 (0)