Repository: go-gorm/gorm
Pull request #4735 (2021-09-29 04:54:20)

fix: QuoteTo not fully support raw mode
<!--
Make sure these boxes checked before submitting your pull request.

For significant changes, please open an issue to make an agreement on an implementation design/plan first before starting it.
-->

- [x] Do only one thing
- [x] Non breaking API changes
- [x] Tested

### What did this pull request do?

- fix quote bug
<!--
provide a general description of the code changes in your pull request
-->

### User Case Description

<!-- Your use case -->



Patch:
diff --git a/statement.go b/statement.go
index 3836344..347f88f 100644
--- a/statement.go
+++ b/statement.go
@@ -75,30 +75,36 @@ func (stmt *Statement) WriteQuoted(value interface{}) {
 
 // QuoteTo write quoted value to writer
 func (stmt *Statement) QuoteTo(writer clause.Writer, field interface{}) {
+	write := func(raw bool, str string) {
+		if raw {
+			writer.WriteString(str)
+		} else {
+			stmt.DB.Dialector.QuoteTo(writer, str)
+		}
+	}
+
 	switch v := field.(type) {
 	case clause.Table:
 		if v.Name == clause.CurrentTable {
 			if stmt.TableExpr != nil {
 				stmt.TableExpr.Build(stmt)
 			} else {
-				stmt.DB.Dialector.QuoteTo(writer, stmt.Table)
+				write(v.Raw, stmt.Table)
 			}
-		} else if v.Raw {
-			writer.WriteString(v.Name)
 		} else {
-			stmt.DB.Dialector.QuoteTo(writer, v.Name)
+			write(v.Raw, v.Name)
 		}
 
 		if v.Alias != "" {
 			writer.WriteByte(' ')
-			stmt.DB.Dialector.QuoteTo(writer, v.Alias)
+			write(v.Raw, v.Alias)
 		}
 	case clause.Column:
 		if v.Table != "" {
 			if v.Table == clause.CurrentTable {
-				stmt.DB.Dialector.QuoteTo(writer, stmt.Table)
+				write(v.Raw, stmt.Table)
 			} else {
-				stmt.DB.Dialector.QuoteTo(writer, v.Table)
+				write(v.Raw, v.Table)
 			}
 			writer.WriteByte('.')
 		}
@@ -107,19 +113,17 @@ func (stmt *Statement) QuoteTo(writer clause.Writer, field interface{}) {
 			if stmt.Schema == nil {
 				stmt.DB.AddError(ErrModelValueRequired)
 			} else if stmt.Schema.PrioritizedPrimaryField != nil {
-				stmt.DB.Dialector.QuoteTo(writer, stmt.Schema.PrioritizedPrimaryField.DBName)
+				write(v.Raw, stmt.Schema.PrioritizedPrimaryField.DBName)
 			} else if len(stmt.Schema.DBNames) > 0 {
-				stmt.DB.Dialector.QuoteTo(writer, stmt.Schema.DBNames[0])
+				write(v.Raw, stmt.Schema.DBNames[0])
 			}
-		} else if v.Raw {
-			writer.WriteString(v.Name)
 		} else {
-			stmt.DB.Dialector.QuoteTo(writer, v.Name)
+			write(v.Raw, v.Name)
 		}
 
 		if v.Alias != "" {
 			writer.WriteString(" AS ")
-			stmt.DB.Dialector.QuoteTo(writer, v.Alias)
+			write(v.Raw, v.Alias)
 		}
 	case []clause.Column:
 		writer.WriteByte('(')


Test patch:
diff --git a/clause/expression_test.go b/clause/expression_test.go
index eadd96e..4826db3 100644
--- a/clause/expression_test.go
+++ b/clause/expression_test.go
@@ -94,6 +94,34 @@ func TestNamedExpr(t *testing.T) {
 		Vars:         []interface{}{sql.Named("name", "jinzhu")},
 		Result:       "name1 = ? AND name2 = ?;",
 		ExpectedVars: []interface{}{"jinzhu", "jinzhu"},
+	}, {
+		SQL:    "?",
+		Vars:   []interface{}{clause.Column{Table: "table", Name: "col"}},
+		Result: "`table`.`col`",
+	}, {
+		SQL:    "?",
+		Vars:   []interface{}{clause.Column{Table: "table", Name: "col", Raw: true}},
+		Result: "table.col",
+	}, {
+		SQL:    "?",
+		Vars:   []interface{}{clause.Column{Table: "table", Name: clause.PrimaryKey, Raw: true}},
+		Result: "table.id",
+	}, {
+		SQL:    "?",
+		Vars:   []interface{}{clause.Column{Table: "table", Name: "col", Alias: "alias"}},
+		Result: "`table`.`col` AS `alias`",
+	}, {
+		SQL:    "?",
+		Vars:   []interface{}{clause.Column{Table: "table", Name: "col", Alias: "alias", Raw: true}},
+		Result: "table.col AS alias",
+	}, {
+		SQL:    "?",
+		Vars:   []interface{}{clause.Table{Name: "table", Alias: "alias"}},
+		Result: "`table` `alias`",
+	}, {
+		SQL:    "?",
+		Vars:   []interface{}{clause.Table{Name: "table", Alias: "alias", Raw: true}},
+		Result: "table alias",
 	}}
 
 	for idx, result := range results {