From 397b583b8ecc5a31c838db5822fe1003b53a91ef Mon Sep 17 00:00:00 2001 From: chenrui Date: Fri, 25 Feb 2022 22:38:48 +0800 Subject: [PATCH] fix: query scanner in single column --- scan.go | 12 +++++++++++- tests/query_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/scan.go b/scan.go index 0da12daf..a1cb582e 100644 --- a/scan.go +++ b/scan.go @@ -272,7 +272,17 @@ func Scan(rows *sql.Rows, db *DB, mode ScanMode) { } case reflect.Struct, reflect.Ptr: if initialized || rows.Next() { - db.scanIntoStruct(sch, rows, reflectValue, values, columns, fields, joinFields) + if update { + db.scanIntoStruct(sch, rows, reflectValue, values, columns, fields, joinFields) + } else { + elem := reflect.New(reflectValueType) + db.scanIntoStruct(sch, rows, elem, values, columns, fields, joinFields) + if isPtr { + db.Statement.ReflectValue.Set(elem) + } else { + db.Statement.ReflectValue.Set(elem.Elem()) + } + } } default: db.AddError(rows.Scan(dest)) diff --git a/tests/query_test.go b/tests/query_test.go index d10df180..6542774a 100644 --- a/tests/query_test.go +++ b/tests/query_test.go @@ -1158,3 +1158,39 @@ func TestQueryWithTableAndConditionsAndAllFields(t *testing.T) { t.Errorf("invalid query SQL, got %v", result.Statement.SQL.String()) } } + +type DoubleInt64 struct { + data int64 +} + +func (t *DoubleInt64) Scan(val interface{}) error { + switch v := val.(type) { + case int64: + t.data = v * 2 + return nil + default: + return fmt.Errorf("DoubleInt64 cant not scan with:%v", v) + } +} + +// https://github.com/go-gorm/gorm/issues/5091 +func TestQueryScannerWithSingleColumn(t *testing.T) { + user := User{Name: "scanner_raw_1", Age: 10} + DB.Create(&user) + + var result1 DoubleInt64 + if err := DB.Model(&User{}).Where("name LIKE ?", "scanner_raw_%").Limit(1).Pluck( + "age", &result1).Error; err != nil { + t.Errorf("Failed, got error: %v", err) + } + + AssertEqual(t, result1.data, 20) + + var result2 DoubleInt64 + if err := DB.Model(&User{}).Where("name LIKE ?", "scanner_raw_%").Limit(1).Select( + "age").Scan(&result2).Error; err != nil { + t.Errorf("Failed, got error: %v", err) + } + + AssertEqual(t, result2.data, 20) +}