diff --git a/statement.go b/statement.go index 355a5f0b..707e4aef 100644 --- a/statement.go +++ b/statement.go @@ -165,16 +165,7 @@ func (stmt *Statement) AddVar(writer clause.Writer, vars ...interface{}) { case Valuer: stmt.AddVar(writer, v.GormValue(stmt.Context, stmt.DB)) case clause.Expr: - var varStr strings.Builder - var sql = v.SQL - for _, arg := range v.Vars { - stmt.Vars = append(stmt.Vars, arg) - stmt.DB.Dialector.BindVarTo(&varStr, stmt, arg) - sql = strings.Replace(sql, "?", varStr.String(), 1) - varStr.Reset() - } - - writer.WriteString(sql) + v.Build(stmt) case driver.Valuer: stmt.Vars = append(stmt.Vars, v) stmt.DB.Dialector.BindVarTo(writer, stmt, v) diff --git a/tests/create_test.go b/tests/create_test.go index 170c8546..bd968ea8 100644 --- a/tests/create_test.go +++ b/tests/create_test.go @@ -2,6 +2,7 @@ package tests_test import ( "errors" + "regexp" "testing" "time" @@ -493,3 +494,26 @@ func TestFirstOrCreateWithPrimaryKey(t *testing.T) { t.Errorf("invalid primary key after creating, got %v, %v", companies[0].ID, companies[1].ID) } } + +func TestCreateFromSubQuery(t *testing.T) { + user := User{Name: "jinzhu"} + + DB.Create(&user) + + subQuery := DB.Table("users").Where("name=?", user.Name).Select("id") + + result := DB.Session(&gorm.Session{DryRun: true}).Model(&Pet{}).Create([]map[string]interface{}{ + { + "name": "cat", + "user_id": gorm.Expr("(?)", DB.Table("(?) as tmp", subQuery).Select("@uid:=id")), + }, + { + "name": "dog", + "user_id": gorm.Expr("@uid"), + }, + }) + + if !regexp.MustCompile(`INSERT INTO .pets. \(.name.,.user_id.\) .*VALUES \(.+,\(SELECT @uid:=id FROM \(SELECT id FROM .users. WHERE name=.+\) as tmp\)\),\(.+,@uid\)`).MatchString(result.Statement.SQL.String()) { + t.Errorf("invalid insert SQL, got %v", result.Statement.SQL.String()) + } +}