Fix alias keyword with Table, close #3104

This commit is contained in:
Jinzhu 2020-07-10 21:11:28 +08:00
parent 33c48611b6
commit d4b462a351
3 changed files with 34 additions and 1 deletions

View File

@ -2,6 +2,7 @@ package gorm
import ( import (
"fmt" "fmt"
"regexp"
"strings" "strings"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
@ -40,9 +41,19 @@ func (db *DB) Clauses(conds ...clause.Expression) (tx *DB) {
return return
} }
var tableRegexp = regexp.MustCompile("(?i).+ AS (\\w+)\\s*$")
// Table specify the table you would like to run db operations // Table specify the table you would like to run db operations
func (db *DB) Table(name string) (tx *DB) { func (db *DB) Table(name string) (tx *DB) {
tx = db.getInstance() tx = db.getInstance()
if strings.Contains(name, " ") {
tx.Statement.FullTable = name
if results := tableRegexp.FindStringSubmatch(name); len(results) == 2 {
tx.Statement.Table = results[1]
return
}
}
tx.Statement.Table = name tx.Statement.Table = name
return return
} }

View File

@ -19,6 +19,7 @@ import (
// Statement statement // Statement statement
type Statement struct { type Statement struct {
*DB *DB
FullTable string
Table string Table string
Model interface{} Model interface{}
Unscoped bool Unscoped bool
@ -69,7 +70,11 @@ func (stmt *Statement) QuoteTo(writer clause.Writer, field interface{}) {
switch v := field.(type) { switch v := field.(type) {
case clause.Table: case clause.Table:
if v.Name == clause.CurrentTable { if v.Name == clause.CurrentTable {
stmt.DB.Dialector.QuoteTo(writer, stmt.Table) if stmt.FullTable != "" {
writer.WriteString(stmt.FullTable)
} else {
stmt.DB.Dialector.QuoteTo(writer, stmt.Table)
}
} else if v.Raw { } else if v.Raw {
writer.WriteString(v.Name) writer.WriteString(v.Name)
} else { } else {
@ -374,6 +379,7 @@ func (stmt *Statement) Build(clauses ...string) {
func (stmt *Statement) Parse(value interface{}) (err error) { func (stmt *Statement) Parse(value interface{}) (err error) {
if stmt.Schema, err = schema.Parse(value, stmt.DB.cacheStore, stmt.DB.NamingStrategy); err == nil && stmt.Table == "" { if stmt.Schema, err = schema.Parse(value, stmt.DB.cacheStore, stmt.DB.NamingStrategy); err == nil && stmt.Table == "" {
stmt.Table = stmt.Schema.Table stmt.Table = stmt.Schema.Table
stmt.FullTable = stmt.Schema.Table
} }
return err return err
} }

View File

@ -24,6 +24,22 @@ func TestRow(t *testing.T) {
if age != 10 { if age != 10 {
t.Errorf("Scan with Row, age expects: %v, got %v", user2.Age, age) t.Errorf("Scan with Row, age expects: %v, got %v", user2.Age, age)
} }
table := "gorm.users"
if DB.Dialector.Name() != "mysql" {
table = "users" // other databases doesn't support select with `database.table`
}
DB.Table(table).Where(map[string]interface{}{"name": user2.Name}).Update("age", 20)
row = DB.Table(table+" as u").Where("u.name = ?", user2.Name).Select("age").Row()
if err := row.Scan(&age); err != nil {
t.Fatalf("Failed to scan age, got %v", err)
}
if age != 20 {
t.Errorf("Scan with Row, age expects: %v, got %v", user2.Age, age)
}
} }
func TestRows(t *testing.T) { func TestRows(t *testing.T) {