FIX:Optimistic Lock in BeforeUpdate: PK Condition Placement Affecting DB Plan Efficiency

This commit is contained in:
sirius 2025-04-17 11:43:14 +08:00
parent 0daaf1747c
commit dc3f2394b7

View File

@ -259,6 +259,7 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) {
switch updatingValue.Kind() {
case reflect.Struct:
set = make([]clause.Assignment, 0, len(stmt.Schema.FieldsByDBName))
priExpr := make([]clause.Expression, 0)
for _, dbName := range stmt.Schema.DBNames {
if field := updatingSchema.LookUpField(dbName); field != nil {
if !field.PrimaryKey || !updatingValue.CanAddr() || stmt.Dest != stmt.Model {
@ -290,11 +291,26 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) {
}
} else {
if value, isZero := field.ValueOf(stmt.Context, updatingValue); !isZero {
stmt.AddClause(clause.Where{Exprs: []clause.Expression{clause.Eq{Column: field.DBName, Value: value}}})
// stmt.AddClause(clause.Where{Exprs: []clause.Expression{clause.Eq{Column: field.DBName, Value: value}}})
priExpr = append(priExpr, clause.Eq{Column: field.DBName, Value: value})
}
}
}
}
if len(priExpr) > 0 {
where := clause.Where{Exprs: priExpr}
wname := where.Name()
existWc := stmt.Clauses[wname]
existWc.Name = wname
if existingWhere, ok := existWc.Expression.(clause.Where); ok {
where.Exprs = append(priExpr, existingWhere.Exprs...)
existWc.Expression = where
stmt.Clauses[wname] = existWc
}
existWc.Expression = where
stmt.Clauses[wname] = existWc
}
default:
stmt.AddError(gorm.ErrInvalidData)
}