-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using an @
in a string passed to Select
results in incorrect query
#7235
Comments
@markhildreth-gravity I think the root cause is here: Line 141 in 52e3b35
If it finds a quick fix is change your codes to: // make query an slice of string, so that it won't go to the unexpected branch
DB.Table("users").Select([]string{"name = '[email protected]' as is_example", "age"}).Scan(&results).Error |
@ivila Thanks for the quick response. That makes sense why the code isn't working as epxected, although I will say it's not immediately as a developer that the code is wrong. I should point out this was a quick case to reproduce, but the issue originally occurred because I was using I'd like to recommend the following: 1.) Change the docs to always use the slice type when listing multiple items: Anywhere in the docs where
...could be changed to this...
2.) Ideally, the two use cases (list of strings vs string template w/ args) are split into different methods (e.g., a |
I happen to have been looking at exactly this code in gorm today, trying to figure out how I might be able to add some custom finishers. If you check out line 141 in @markhildreth-gravity my recommendation would actually just be to reverse the order of the parameters you pass to
That should allow the Code from case string:
if strings.Count(v, "?") >= len(args) && len(args) > 0 {
tx.Statement.AddClause(clause.Select{
Distinct: db.Statement.Distinct,
Expression: clause.Expr{SQL: v, Vars: args},
})
} else if strings.Count(v, "@") > 0 && len(args) > 0 {
tx.Statement.AddClause(clause.Select{
Distinct: db.Statement.Distinct,
Expression: clause.NamedExpr{SQL: v, Vars: args},
})
} else {
tx.Statement.Selects = []string{v}
for _, arg := range args {
switch arg := arg.(type) {
case string:
tx.Statement.Selects = append(tx.Statement.Selects, arg)
case []string:
tx.Statement.Selects = append(tx.Statement.Selects, arg...)
default:
tx.Statement.AddClause(clause.Select{
Distinct: db.Statement.Distinct,
Expression: clause.Expr{SQL: v, Vars: args},
})
return
}
}
if clause, ok := tx.Statement.Clauses["SELECT"]; ok {
clause.Expression = nil
tx.Statement.Clauses["SELECT"] = clause
}
} |
Thanks for looking into this. The problem I had was already solved by passing my values as a slice. And it seems like switching the argument ordering as you recommend would also solve the specific issue that I found myself in. However, I would still prefer using a string slice when the goal of the method is to give a list of columns to return, as it makes it less likely that a change to the arguments might errantly cause Gorm to switch to "template" mode. Put another way, if I write code like this...
...it's impossible to know which "mode" Gorm will use. It entirely depends on what the value of
... then I know for sure that Gorm will ALWAYS treat the strings as a list of columns, rather than templates. As I mentioned, changing the API so that the two modes occur using different methods would IMO be a better solution, but that's obvious a breaking change. |
GORM Playground Link
go-gorm/playground#764
Description
When using the
@
character in a string passed toSelect()
, the remaining strings passed to select are ignored.For example, these two queries...
... generates the following SQL, respectively...
Note how in the second,
age
is left off. This only seems to happen if the@
is included in the first string.The text was updated successfully, but these errors were encountered: