Skip to content

Commit

Permalink
stmts: lazy update, cache all select then do update.
Browse files Browse the repository at this point in the history
Fix issue pingcap#376
  • Loading branch information
siddontang committed Oct 14, 2015
1 parent 65c1710 commit 249fae3
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 3 deletions.
10 changes: 8 additions & 2 deletions stmt/stmts/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ func (s *UpdateStmt) Exec(ctx context.Context) (_ rset.Recordset, err error) {
}

m := map[interface{}]interface{}{}
var records []*plan.Row
for {
row, err1 := p.Next(ctx)
if err1 != nil {
Expand All @@ -263,11 +264,16 @@ func (s *UpdateStmt) Exec(ctx context.Context) (_ rset.Recordset, err error) {
if row == nil {
break
}
rowData := row.Data
if len(row.RowKeys) == 0 {
// Nothing to update
return nil, nil
continue
}
records = append(records, row)
}

for _, row := range records {
rowData := row.Data

// Set EvalIdentFunc
m[expression.ExprEvalIdentFunc] = func(name string) (interface{}, error) {
return plans.GetIdentValue(name, p.GetFields(), rowData, field.DefaultFieldFlag)
Expand Down
57 changes: 56 additions & 1 deletion stmt/stmts/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ func (s *testStmtSuite) TestIssue345(c *C) {

// See https://github.com/pingcap/tidb/issues/369
func (s *testStmtSuite) TestIssue369(c *C) {
testSQL := `drop table if exists users, foobar;`
testSQL := `DROP TABLE IF EXISTS users, foobar;`
mustExec(c, s.testDB, testSQL)

testSQL = `CREATE TABLE users (
Expand Down Expand Up @@ -261,3 +261,58 @@ func (s *testStmtSuite) TestIssue369(c *C) {
r := mustExec(c, s.testDB, testSQL)
checkResult(c, r, 3, 0)
}

// See https://github.com/pingcap/tidb/issues/376
func (s *testStmtSuite) TestIssue376(c *C) {
testSQL := `
DROP TABLE IF EXISTS users, foobar, addresses;
CREATE TABLE users (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(30) NOT NULL,
some_update VARCHAR(30),
PRIMARY KEY (id)
)ENGINE=MyISAM;
CREATE TABLE foobar (
id INTEGER NOT NULL AUTO_INCREMENT,
user_id INTEGER,
data VARCHAR(30),
some_update VARCHAR(30),
PRIMARY KEY (id),
FOREIGN KEY(user_id) REFERENCES users (id)
)ENGINE=MyISAM;
CREATE TABLE addresses (
id INTEGER NOT NULL AUTO_INCREMENT,
user_id INTEGER,
email_address VARCHAR(50) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY(user_id) REFERENCES users (id)
)ENGINE=MyISAM;
INSERT INTO users (id, name, some_update) VALUES
(8, 'ed', 'value'),
(9, 'fred', 'value');
INSERT INTO addresses (id, user_id, email_address) VALUES
(2, 8, 'ed@wood.com'),
(3, 8, 'ed@bettyboop.com'),
(4, 9, 'fred@fred.com');
INSERT INTO foobar (id, user_id, data) VALUES
(2, 8, 'd1'),
(3, 8, 'd2'),
(4, 9, 'd3');`

mustExec(c, s.testDB, testSQL)
testSQL = `
UPDATE addresses, users SET users.name='ed2', users.some_update='im the update',
addresses.email_address=users.name WHERE users.id = addresses.user_id AND users.name = 'ed';`
r := mustExec(c, s.testDB, testSQL)
checkResult(c, r, 3, 0)

testSQL = `SELECT addresses.id, addresses.user_id, addresses.email_address FROM addresses ORDER BY addresses.id;`
rows, err := s.testDB.Query(testSQL)
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{2, 8, "ed"}, {3, 8, "ed"}, {4, 9, "fred@fred.com"}})
}

0 comments on commit 249fae3

Please sign in to comment.