fix: keep nil when dest is ptr & dest is nil[notfound]

This commit is contained in:
mr-chenguang lcgash 2024-04-15 03:08:37 +00:00
parent ad81206cc2
commit 8ce25a5dd1
4 changed files with 5 additions and 9 deletions

View File

@ -115,7 +115,8 @@ func (p *processor) Execute(db *DB) *DB {
if stmt.Dest != nil {
stmt.ReflectValue = reflect.ValueOf(stmt.Dest)
for stmt.ReflectValue.Kind() == reflect.Ptr {
if stmt.ReflectValue.IsNil() && stmt.ReflectValue.CanAddr() {
stmt.DestIsNil = stmt.ReflectValue.IsNil()
if stmt.DestIsNil && stmt.ReflectValue.CanAddr() {
stmt.ReflectValue.Set(reflect.New(stmt.ReflectValue.Type().Elem()))
}

View File

@ -342,7 +342,7 @@ func Scan(rows Rows, db *DB, mode ScanMode) {
if db.RowsAffected == 0 && db.Statement.RaiseErrorOnNotFound && db.Error == nil {
db.AddError(ErrRecordNotFound)
if db.NotFoundAsNilWhenPtr && db.Statement.Dest != nil && reflect.ValueOf(db.Statement.Dest).Kind() == reflect.Ptr {
if db.Statement.DestIsNil {
// reset dest to nil
reflect.ValueOf(db.Statement.Dest).Elem().Set(reflect.Zero(reflect.ValueOf(db.Statement.Dest).Elem().Type()))
}

View File

@ -26,6 +26,7 @@ type Statement struct {
Model interface{}
Unscoped bool
Dest interface{}
DestIsNil bool
ReflectValue reflect.Value
Clauses map[string]clause.Clause
BuildClauses []string

View File

@ -208,13 +208,7 @@ func TestFind(t *testing.T) {
t.Run("NotFoundAsNil", func(t *testing.T) {
var first *User
if err := DB.Where("name = ?", "find-not-found").First(&first).Error; err != nil {
AssertEqual(t, err, gorm.ErrRecordNotFound)
AssertEqual(t, first == nil, false)
}
DB.Config.NotFoundAsNilWhenPtr = true
if err := DB.Where("name = ?", "find-not-found").First(&first).Error; err != nil {
if err := DB.Where("name = ?", "find not found").First(&first).Error; err != nil {
AssertEqual(t, err, gorm.ErrRecordNotFound)
AssertEqual(t, first, nil)
}