diff --git a/pkg/database/contracts.go b/pkg/database/contracts.go index 4a3301ea1..bf55d3207 100644 --- a/pkg/database/contracts.go +++ b/pkg/database/contracts.go @@ -47,3 +47,10 @@ type TableNamer interface { type Scoper interface { Scope() any } + +// PgsqlOnConflictConstrainter implements the PgsqlOnConflictConstraint method, +// which returns the primary or unique key constraint name of the PostgreSQL table. +type PgsqlOnConflictConstrainter interface { + // PgsqlOnConflictConstraint returns the primary or unique key constraint name of the PostgreSQL table. + PgsqlOnConflictConstraint() string +} diff --git a/pkg/database/db.go b/pkg/database/db.go index 3dc871f6b..d67af53a3 100644 --- a/pkg/database/db.go +++ b/pkg/database/db.go @@ -259,7 +259,14 @@ func (db *DB) BuildInsertIgnoreStmt(into interface{}) (string, int) { // MySQL treats UPDATE id = id as a no-op. clause = fmt.Sprintf(`ON DUPLICATE KEY UPDATE "%s" = "%s"`, columns[0], columns[0]) case PostgreSQL: - clause = fmt.Sprintf("ON CONFLICT ON CONSTRAINT pk_%s DO NOTHING", table) + var constraint string + if constrainter, ok := into.(PgsqlOnConflictConstrainter); ok { + constraint = constrainter.PgsqlOnConflictConstraint() + } else { + constraint = "pk_" + table + } + + clause = fmt.Sprintf("ON CONFLICT ON CONSTRAINT %s DO NOTHING", constraint) } return fmt.Sprintf( @@ -322,7 +329,14 @@ func (db *DB) BuildUpsertStmt(subject interface{}) (stmt string, placeholders in clause = "ON DUPLICATE KEY UPDATE" setFormat = `"%[1]s" = VALUES("%[1]s")` case PostgreSQL: - clause = fmt.Sprintf("ON CONFLICT ON CONSTRAINT pk_%s DO UPDATE SET", table) + var constraint string + if constrainter, ok := subject.(PgsqlOnConflictConstrainter); ok { + constraint = constrainter.PgsqlOnConflictConstraint() + } else { + constraint = "pk_" + table + } + + clause = fmt.Sprintf("ON CONFLICT ON CONSTRAINT %s DO UPDATE SET", constraint) setFormat = `"%[1]s" = EXCLUDED."%[1]s"` }