From 841ea1bde530b7d046262861cc39a041f42bdce3 Mon Sep 17 00:00:00 2001 From: matematik7 Date: Mon, 14 Aug 2017 20:46:39 +0200 Subject: [PATCH 1/3] Do not always override select on pluck --- scope.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/scope.go b/scope.go index 0dcea855..db797dcc 100644 --- a/scope.go +++ b/scope.go @@ -938,14 +938,30 @@ func (scope *Scope) initialize() *Scope { return scope } +func (scope *Scope) isQueryForColumn(query interface{}, column string) bool { + queryStr := fmt.Sprint(query) + if queryStr == column { + return true + } + + if strings.HasSuffix(strings.ToLower(queryStr), "as "+column) { + return true + } + + return false +} + func (scope *Scope) pluck(column string, value interface{}) *Scope { dest := reflect.Indirect(reflect.ValueOf(value)) - scope.Search.Select(column) if dest.Kind() != reflect.Slice { scope.Err(fmt.Errorf("results should be a slice, not %s", dest.Kind())) return scope } + if query, ok := scope.Search.selects["query"]; !ok || !scope.isQueryForColumn(query, column) { + scope.Search.Select(column) + } + rows, err := scope.rows() if scope.Err(err) == nil { defer rows.Close() From 36043ad905ae3c19feaebd68327b1bf6b291ec29 Mon Sep 17 00:00:00 2001 From: matematik7 Date: Mon, 4 Sep 2017 18:12:20 +0200 Subject: [PATCH 2/3] Fix for quoted column names and add test --- query_test.go | 24 ++++++++++++++++++++++++ scope.go | 8 ++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/query_test.go b/query_test.go index 882fd611..df8893fd 100644 --- a/query_test.go +++ b/query_test.go @@ -674,3 +674,27 @@ func TestSelectWithArrayInput(t *testing.T) { t.Errorf("Should have selected both age and name") } } + +func TestPluckWithSelect(t *testing.T) { + DB.Save(&User{Name: "matematik7", Age: 25}) + + var userAges []string + err := DB.Model(&User{}).Where("age = ?", 25).Select("name || ' - ' || age as user_age").Pluck("user_age", &userAges).Error + if err != nil { + t.Error(err) + } + + if len(userAges) != 1 || userAges[0] != "matematik7 - 25" { + t.Errorf("Should correctly pluck with select, got: %s", userAges) + } + + userAges = userAges[:0] + err = DB.Model(&User{}).Where("age = ?", 25).Select("name || ' - ' || age as \"user_age\"").Pluck("user_age", &userAges).Error + if err != nil { + t.Error(err) + } + + if len(userAges) != 1 || userAges[0] != "matematik7 - 25" { + t.Errorf("Should correctly pluck with select, got: %s", userAges) + } +} diff --git a/scope.go b/scope.go index db797dcc..65ac62d9 100644 --- a/scope.go +++ b/scope.go @@ -939,12 +939,16 @@ func (scope *Scope) initialize() *Scope { } func (scope *Scope) isQueryForColumn(query interface{}, column string) bool { - queryStr := fmt.Sprint(query) + queryStr := strings.ToLower(fmt.Sprint(query)) if queryStr == column { return true } - if strings.HasSuffix(strings.ToLower(queryStr), "as "+column) { + if strings.HasSuffix(queryStr, "as "+column) { + return true + } + + if strings.HasSuffix(queryStr, "as \""+column+"\"") { return true } From 46269198a4e50bbffb5682321fe5865836dd17b9 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Sun, 11 Feb 2018 13:41:46 +0800 Subject: [PATCH 3/3] Refactor PR #1569 --- query_test.go | 23 ++++++++++++++++++----- scope.go | 2 +- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/query_test.go b/query_test.go index df8893fd..135805a7 100644 --- a/query_test.go +++ b/query_test.go @@ -2,6 +2,7 @@ package gorm_test import ( "fmt" + "os" "reflect" "github.com/jinzhu/gorm" @@ -676,25 +677,37 @@ func TestSelectWithArrayInput(t *testing.T) { } func TestPluckWithSelect(t *testing.T) { - DB.Save(&User{Name: "matematik7", Age: 25}) + var ( + user = User{Name: "matematik7_pluck_with_select", Age: 25} + combinedName = fmt.Sprintf("%v%v", user.Name, user.Age) + combineUserAgeSQL = fmt.Sprintf("concat(%v, %v)", DB.Dialect().Quote("name"), DB.Dialect().Quote("age")) + ) + if dialect := os.Getenv("GORM_DIALECT"); dialect == "sqlite" { + combineUserAgeSQL = fmt.Sprintf("(%v || %v)", DB.Dialect().Quote("name"), DB.Dialect().Quote("age")) + } + + DB.Save(&user) + + selectStr := combineUserAgeSQL + " as user_age" var userAges []string - err := DB.Model(&User{}).Where("age = ?", 25).Select("name || ' - ' || age as user_age").Pluck("user_age", &userAges).Error + err := DB.Model(&User{}).Where("age = ?", 25).Select(selectStr).Pluck("user_age", &userAges).Error if err != nil { t.Error(err) } - if len(userAges) != 1 || userAges[0] != "matematik7 - 25" { + if len(userAges) != 1 || userAges[0] != combinedName { t.Errorf("Should correctly pluck with select, got: %s", userAges) } + selectStr = combineUserAgeSQL + fmt.Sprintf(" as %v", DB.Dialect().Quote("user_age")) userAges = userAges[:0] - err = DB.Model(&User{}).Where("age = ?", 25).Select("name || ' - ' || age as \"user_age\"").Pluck("user_age", &userAges).Error + err = DB.Model(&User{}).Where("age = ?", 25).Select(selectStr).Pluck("user_age", &userAges).Error if err != nil { t.Error(err) } - if len(userAges) != 1 || userAges[0] != "matematik7 - 25" { + if len(userAges) != 1 || userAges[0] != combinedName { t.Errorf("Should correctly pluck with select, got: %s", userAges) } } diff --git a/scope.go b/scope.go index 65ac62d9..29508d8d 100644 --- a/scope.go +++ b/scope.go @@ -948,7 +948,7 @@ func (scope *Scope) isQueryForColumn(query interface{}, column string) bool { return true } - if strings.HasSuffix(queryStr, "as \""+column+"\"") { + if strings.HasSuffix(queryStr, "as "+scope.Quote(column)) { return true }