Merge pull request #935 from pingcap/zimuxia/move-test

*: Move statement tests to executor package
This commit is contained in:
zimulala
2016-03-02 10:08:24 +08:00
10 changed files with 585 additions and 1007 deletions

View File

@ -14,6 +14,7 @@
package executor_test
import (
"fmt"
"strings"
"testing"
"time"
@ -161,6 +162,584 @@ func (s *testSuite) TestPrepared(c *C) {
exec.Close()
}
func (s *testSuite) fillData(tk *testkit.TestKit, table string) {
tk.MustExec("use test")
tk.MustExec(fmt.Sprintf("create table %s(id int not null default 1, name varchar(255), PRIMARY KEY(id));", table))
// insert data
tk.MustExec(fmt.Sprintf("insert INTO %s VALUES (1, \"hello\");", table))
tk.CheckExecResult(1, 0)
tk.MustExec(fmt.Sprintf("insert into %s values (2, \"hello\");", table))
tk.CheckExecResult(1, 0)
}
func (s *testSuite) TestDelete(c *C) {
tk := testkit.NewTestKit(c, s.store)
s.fillData(tk, "delete_test")
tk.MustExec(`update delete_test set name = "abc" where id = 2;`)
tk.CheckExecResult(1, 0)
tk.MustExec(`delete from delete_test where id = 2 limit 1;`)
tk.CheckExecResult(1, 0)
// Test delete with false condition
tk.MustExec(`delete from delete_test where 0;`)
tk.CheckExecResult(0, 0)
tk.MustExec("insert into delete_test values (2, 'abc')")
tk.MustExec(`delete from delete_test where delete_test.id = 2 limit 1`)
tk.CheckExecResult(1, 0)
// Select data
tk.MustExec("begin")
rows := tk.MustQuery(`SELECT * from delete_test limit 2;`)
rowStr := fmt.Sprintf("%v %v", "1", []byte("hello"))
rows.Check(testkit.Rows(rowStr))
tk.MustExec("commit")
tk.MustExec(`delete from delete_test ;`)
tk.CheckExecResult(1, 0)
}
func (s *testSuite) fillDataMultiTable(tk *testkit.TestKit) {
tk.MustExec("use test")
tk.MustExec("drop table if exists t1, t2, t3")
// Create and fill table t1
tk.MustExec("create table t1 (id int, data int);")
tk.MustExec("insert into t1 values (11, 121), (12, 122), (13, 123);")
tk.CheckExecResult(3, 0)
// Create and fill table t2
tk.MustExec("create table t2 (id int, data int);")
tk.MustExec("insert into t2 values (11, 221), (22, 222), (23, 223);")
tk.CheckExecResult(3, 0)
// Create and fill table t3
tk.MustExec("create table t3 (id int, data int);")
tk.MustExec("insert into t3 values (11, 321), (22, 322), (23, 323);")
tk.CheckExecResult(3, 0)
}
func (s *testSuite) TestMultiTableDelete(c *C) {
tk := testkit.NewTestKit(c, s.store)
s.fillDataMultiTable(tk)
tk.MustExec(`delete t1, t2 from t1 inner join t2 inner join t3 where t1.id=t2.id and t2.id=t3.id;`)
tk.CheckExecResult(2, 0)
// Select data
r := tk.MustQuery("select * from t3")
c.Assert(r.Rows(), HasLen, 3)
}
func (s *testSuite) TestQualifedDelete(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1")
tk.MustExec("drop table if exists t2")
tk.MustExec("create table t1 (c1 int, c2 int, index (c1))")
tk.MustExec("create table t2 (c1 int, c2 int)")
tk.MustExec("insert into t1 values (1, 1), (2, 2)")
// delete with index
tk.MustExec("delete from t1 where t1.c1 = 1")
tk.CheckExecResult(1, 0)
// delete with no index
tk.MustExec("delete from t1 where t1.c2 = 2")
tk.CheckExecResult(1, 0)
r := tk.MustQuery("select * from t1")
c.Assert(r.Rows(), HasLen, 0)
_, err := tk.Exec("delete from t1 as a where a.c1 = 1")
c.Assert(err, NotNil)
tk.MustExec("insert into t1 values (1, 1), (2, 2)")
tk.MustExec("insert into t2 values (2, 1), (3,1)")
tk.MustExec("delete t1, t2 from t1 join t2 where t1.c1 = t2.c2")
tk.CheckExecResult(3, 0)
tk.MustExec("insert into t2 values (2, 1), (3,1)")
tk.MustExec("delete a, b from t1 as a join t2 as b where a.c2 = b.c1")
tk.CheckExecResult(2, 0)
_, err = tk.Exec("delete t1, t2 from t1 as a join t2 as b where a.c2 = b.c1")
c.Assert(err, NotNil)
tk.MustExec("drop table t1, t2")
}
func (s *testSuite) TestInsert(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
testSQL := `drop table if exists insert_test;create table insert_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 int, c3 int default 1);`
tk.MustExec(testSQL)
testSQL = `insert insert_test (c1) values (1),(2),(NULL);`
tk.MustExec(testSQL)
errInsertSelectSQL := `insert insert_test (c1) values ();`
tk.MustExec("begin")
_, err := tk.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
errInsertSelectSQL = `insert insert_test (c1, c2) values (1,2),(1);`
tk.MustExec("begin")
_, err = tk.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
errInsertSelectSQL = `insert insert_test (xxx) values (3);`
tk.MustExec("begin")
_, err = tk.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
errInsertSelectSQL = `insert insert_test_xxx (c1) values ();`
tk.MustExec("begin")
_, err = tk.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
insertSetSQL := `insert insert_test set c1 = 3;`
tk.MustExec(insertSetSQL)
errInsertSelectSQL = `insert insert_test set c1 = 4, c1 = 5;`
tk.MustExec("begin")
_, err = tk.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
errInsertSelectSQL = `insert insert_test set xxx = 6;`
tk.MustExec("begin")
_, err = tk.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
insertSelectSQL := `create table insert_test_1 (id int, c1 int);`
tk.MustExec(insertSelectSQL)
insertSelectSQL = `insert insert_test_1 select id, c1 from insert_test;`
tk.MustExec(insertSelectSQL)
insertSelectSQL = `create table insert_test_2 (id int, c1 int);`
tk.MustExec(insertSelectSQL)
insertSelectSQL = `insert insert_test_1 select id, c1 from insert_test union select id * 10, c1 * 10 from insert_test;`
tk.MustExec(insertSelectSQL)
errInsertSelectSQL = `insert insert_test_1 select c1 from insert_test;`
tk.MustExec("begin")
_, err = tk.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
insertSQL := `insert into insert_test (id, c2) values (1, 1) on duplicate key update c2=10;`
tk.MustExec(insertSQL)
insertSQL = `insert into insert_test (id, c2) values (1, 1) on duplicate key update insert_test.c2=10;`
tk.MustExec(insertSQL)
_, err = tk.Exec(`insert into insert_test (id, c2) values(1, 1) on duplicate key update t.c2 = 10`)
c.Assert(err, NotNil)
}
func (s *testSuite) TestInsertAutoInc(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
createSQL := `drop table if exists insert_autoinc_test; create table insert_autoinc_test (id int primary key auto_increment, c1 int);`
tk.MustExec(createSQL)
insertSQL := `insert into insert_autoinc_test(c1) values (1), (2)`
tk.MustExec(insertSQL)
tk.MustExec("begin")
r := tk.MustQuery("select * from insert_autoinc_test;")
rowStr1 := fmt.Sprintf("%v %v", "1", "1")
rowStr2 := fmt.Sprintf("%v %v", "2", "2")
r.Check(testkit.Rows(rowStr1, rowStr2))
tk.MustExec("commit")
}
func (s *testSuite) TestReplace(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
testSQL := `drop table if exists replace_test;
create table replace_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 int, c3 int default 1);`
tk.MustExec(testSQL)
testSQL = `replace replace_test (c1) values (1),(2),(NULL);`
tk.MustExec(testSQL)
errReplaceSQL := `replace replace_test (c1) values ();`
tk.MustExec("begin")
_, err := tk.Exec(errReplaceSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
errReplaceSQL = `replace replace_test (c1, c2) values (1,2),(1);`
tk.MustExec("begin")
_, err = tk.Exec(errReplaceSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
errReplaceSQL = `replace replace_test (xxx) values (3);`
tk.MustExec("begin")
_, err = tk.Exec(errReplaceSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
errReplaceSQL = `replace replace_test_xxx (c1) values ();`
tk.MustExec("begin")
_, err = tk.Exec(errReplaceSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
replaceSetSQL := `replace replace_test set c1 = 3;`
tk.MustExec(replaceSetSQL)
errReplaceSetSQL := `replace replace_test set c1 = 4, c1 = 5;`
tk.MustExec("begin")
_, err = tk.Exec(errReplaceSetSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
errReplaceSetSQL = `replace replace_test set xxx = 6;`
tk.MustExec("begin")
_, err = tk.Exec(errReplaceSetSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
replaceSelectSQL := `create table replace_test_1 (id int, c1 int);`
tk.MustExec(replaceSelectSQL)
replaceSelectSQL = `replace replace_test_1 select id, c1 from replace_test;`
tk.MustExec(replaceSelectSQL)
replaceSelectSQL = `create table replace_test_2 (id int, c1 int);`
tk.MustExec(replaceSelectSQL)
replaceSelectSQL = `replace replace_test_1 select id, c1 from replace_test union select id * 10, c1 * 10 from replace_test;`
tk.MustExec(replaceSelectSQL)
errReplaceSelectSQL := `replace replace_test_1 select c1 from replace_test;`
tk.MustExec("begin")
_, err = tk.Exec(errReplaceSelectSQL)
c.Assert(err, NotNil)
tk.MustExec("rollback")
replaceUniqueIndexSQL := `create table replace_test_3 (c1 int, c2 int, UNIQUE INDEX (c2));`
tk.MustExec(replaceUniqueIndexSQL)
replaceUniqueIndexSQL = `replace into replace_test_3 set c2=1;`
tk.MustExec(replaceUniqueIndexSQL)
replaceUniqueIndexSQL = `replace into replace_test_3 set c2=1;`
tk.MustExec(replaceUniqueIndexSQL)
c.Assert(int64(tk.Se.AffectedRows()), Equals, int64(1))
replaceUniqueIndexSQL = `replace into replace_test_3 set c1=1, c2=1;`
tk.MustExec(replaceUniqueIndexSQL)
c.Assert(int64(tk.Se.AffectedRows()), Equals, int64(2))
replaceUniqueIndexSQL = `replace into replace_test_3 set c2=NULL;`
tk.MustExec(replaceUniqueIndexSQL)
replaceUniqueIndexSQL = `replace into replace_test_3 set c2=NULL;`
tk.MustExec(replaceUniqueIndexSQL)
c.Assert(int64(tk.Se.AffectedRows()), Equals, int64(1))
replaceUniqueIndexSQL = `create table replace_test_4 (c1 int, c2 int, c3 int, UNIQUE INDEX (c1, c2));`
tk.MustExec(replaceUniqueIndexSQL)
replaceUniqueIndexSQL = `replace into replace_test_4 set c2=NULL;`
tk.MustExec(replaceUniqueIndexSQL)
replaceUniqueIndexSQL = `replace into replace_test_4 set c2=NULL;`
tk.MustExec(replaceUniqueIndexSQL)
c.Assert(int64(tk.Se.AffectedRows()), Equals, int64(1))
replacePrimaryKeySQL := `create table replace_test_5 (c1 int, c2 int, c3 int, PRIMARY KEY (c1, c2));`
tk.MustExec(replacePrimaryKeySQL)
replacePrimaryKeySQL = `replace into replace_test_5 set c1=1, c2=2;`
tk.MustExec(replacePrimaryKeySQL)
replacePrimaryKeySQL = `replace into replace_test_5 set c1=1, c2=2;`
tk.MustExec(replacePrimaryKeySQL)
c.Assert(int64(tk.Se.AffectedRows()), Equals, int64(1))
}
func (s *testSuite) TestSelectWithoutFrom(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("begin")
r := tk.MustQuery("select 1 + 2*3")
r.Check(testkit.Rows("7"))
tk.MustExec("commit")
tk.MustExec("begin")
r = tk.MustQuery(`select _utf8"string";`)
r.Check(testkit.Rows("string"))
tk.MustExec("commit")
}
func (s *testSuite) TestSelectOrderBy(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
s.fillData(tk, "select_order_test")
tk.MustExec("begin")
// Test star field
r := tk.MustQuery("select * from select_order_test where id = 1 order by id limit 1 offset 0;")
rowStr := fmt.Sprintf("%v %v", 1, []byte("hello"))
r.Check(testkit.Rows(rowStr))
tk.MustExec("commit")
tk.MustExec("begin")
// Test multiple field
r = tk.MustQuery("select id, name from select_order_test where id = 1 group by id, name limit 1 offset 0;")
rowStr = fmt.Sprintf("%v %v", 1, []byte("hello"))
r.Check(testkit.Rows(rowStr))
tk.MustExec("commit")
tk.MustExec("drop table select_order_test")
}
func (s *testSuite) TestSelectDistinct(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
s.fillData(tk, "select_distinct_test")
tk.MustExec("begin")
r := tk.MustQuery("select distinct name from select_distinct_test;")
rowStr := fmt.Sprintf("%v", []byte("hello"))
r.Check(testkit.Rows(rowStr))
tk.MustExec("commit")
tk.MustExec("drop table select_distinct_test")
}
func (s *testSuite) TestSelectHaving(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
s.fillData(tk, "select_having_test")
tk.MustExec("begin")
r := tk.MustQuery("select id, name from select_having_test where id in (1,3) having name like 'he%';")
rowStr := fmt.Sprintf("%v %v", 1, []byte("hello"))
r.Check(testkit.Rows(rowStr))
tk.MustExec("commit")
tk.MustExec("drop table select_having_test")
}
func (s *testSuite) TestSelectErrorRow(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("begin")
_, err := tk.Exec("select row(1, 1) from test")
c.Assert(err, NotNil)
_, err = tk.Exec("select * from test group by row(1, 1);")
c.Assert(err, NotNil)
_, err = tk.Exec("select * from test order by row(1, 1);")
c.Assert(err, NotNil)
_, err = tk.Exec("select * from test having row(1, 1);")
c.Assert(err, NotNil)
_, err = tk.Exec("select (select 1, 1) from test;")
c.Assert(err, NotNil)
_, err = tk.Exec("select * from test group by (select 1, 1);")
c.Assert(err, NotNil)
_, err = tk.Exec("select * from test order by (select 1, 1);")
c.Assert(err, NotNil)
_, err = tk.Exec("select * from test having (select 1, 1);")
c.Assert(err, NotNil)
tk.MustExec("commit")
}
func (s *testSuite) TestUpdate(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
s.fillData(tk, "update_test")
updateStr := `UPDATE update_test SET name = "abc" where id > 0;`
tk.MustExec(updateStr)
tk.CheckExecResult(2, 0)
// select data
tk.MustExec("begin")
r := tk.MustQuery(`SELECT * from update_test limit 2;`)
rowStr1 := fmt.Sprintf("%v %v", 1, []byte("abc"))
rowStr2 := fmt.Sprintf("%v %v", 2, []byte("abc"))
r.Check(testkit.Rows(rowStr1, rowStr2))
tk.MustExec("commit")
tk.MustExec(`UPDATE update_test SET name = "foo"`)
tk.CheckExecResult(2, 0)
tk.MustExec("drop table update_test")
}
func (s *testSuite) fillMultiTableForUpdate(tk *testkit.TestKit) {
// Create and fill table items
tk.MustExec("CREATE TABLE items (id int, price TEXT);")
tk.MustExec(`insert into items values (11, "items_price_11"), (12, "items_price_12"), (13, "items_price_13");`)
tk.CheckExecResult(3, 0)
// Create and fill table month
tk.MustExec("CREATE TABLE month (mid int, mprice TEXT);")
tk.MustExec(`insert into month values (11, "month_price_11"), (22, "month_price_22"), (13, "month_price_13");`)
tk.CheckExecResult(3, 0)
}
func (s *testSuite) TestMultipleTableUpdate(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
s.fillMultiTableForUpdate(tk)
tk.MustExec(`UPDATE items, month SET items.price=month.mprice WHERE items.id=month.mid;`)
tk.MustExec("begin")
r := tk.MustQuery("SELECT * FROM items")
rowStr1 := fmt.Sprintf("%v %v", 11, []byte("month_price_11"))
rowStr2 := fmt.Sprintf("%v %v", 12, []byte("items_price_12"))
rowStr3 := fmt.Sprintf("%v %v", 13, []byte("month_price_13"))
r.Check(testkit.Rows(rowStr1, rowStr2, rowStr3))
tk.MustExec("commit")
// Single-table syntax but with multiple tables
tk.MustExec(`UPDATE items join month on items.id=month.mid SET items.price=month.mid;`)
tk.MustExec("begin")
r = tk.MustQuery("SELECT * FROM items")
rowStr1 = fmt.Sprintf("%v %v", 11, []byte("11"))
rowStr2 = fmt.Sprintf("%v %v", 12, []byte("items_price_12"))
rowStr3 = fmt.Sprintf("%v %v", 13, []byte("13"))
r.Check(testkit.Rows(rowStr1, rowStr2, rowStr3))
tk.MustExec("commit")
// JoinTable with alias table name.
tk.MustExec(`UPDATE items T0 join month T1 on T0.id=T1.mid SET T0.price=T1.mprice;`)
tk.MustExec("begin")
r = tk.MustQuery("SELECT * FROM items")
rowStr1 = fmt.Sprintf("%v %v", 11, []byte("month_price_11"))
rowStr2 = fmt.Sprintf("%v %v", 12, []byte("items_price_12"))
rowStr3 = fmt.Sprintf("%v %v", 13, []byte("month_price_13"))
r.Check(testkit.Rows(rowStr1, rowStr2, rowStr3))
tk.MustExec("commit")
}
// For https://github.com/pingcap/tidb/issues/345
func (s *testSuite) TestIssue345(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec(`drop table if exists t1, t2`)
tk.MustExec(`create table t1 (c1 int);`)
tk.MustExec(`create table t2 (c2 int);`)
tk.MustExec(`insert into t1 values (1);`)
tk.MustExec(`insert into t2 values (2);`)
tk.MustExec(`update t1, t2 set t1.c1 = 2, t2.c2 = 1;`)
tk.MustExec(`update t1, t2 set c1 = 2, c2 = 1;`)
tk.MustExec(`update t1 as a, t2 as b set a.c1 = 2, b.c2 = 1;`)
// Check t1 content
tk.MustExec("begin")
r := tk.MustQuery("SELECT * FROM t1;")
r.Check(testkit.Rows("2"))
tk.MustExec("commit")
// Check t2 content
tk.MustExec("begin")
r = tk.MustQuery("SELECT * FROM t2;")
r.Check(testkit.Rows("1"))
tk.MustExec("commit")
tk.MustExec(`update t1 as a, t2 as t1 set a.c1 = 1, t1.c2 = 2;`)
// Check t1 content
tk.MustExec("begin")
r = tk.MustQuery("SELECT * FROM t1;")
r.Check(testkit.Rows("1"))
tk.MustExec("commit")
// Check t2 content
tk.MustExec("begin")
r = tk.MustQuery("SELECT * FROM t2;")
r.Check(testkit.Rows("2"))
_, err := tk.Exec(`update t1 as a, t2 set t1.c1 = 10;`)
c.Assert(err, NotNil)
tk.MustExec("commit")
}
func (s *testSuite) TestMultiUpdate(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
// fix https://github.com/pingcap/tidb/issues/369
testSQL := `
DROP TABLE IF EXISTS t1, t2;
create table t1 (c int);
create table t2 (c varchar(256));
insert into t1 values (1), (2);
insert into t2 values ("a"), ("b");
update t1, t2 set t1.c = 10, t2.c = "abc";`
tk.MustExec(testSQL)
// fix https://github.com/pingcap/tidb/issues/376
testSQL = `DROP TABLE IF EXISTS t1, t2;
create table t1 (c1 int);
create table t2 (c2 int);
insert into t1 values (1), (2);
insert into t2 values (1), (2);
update t1, t2 set t1.c1 = 10, t2.c2 = 2 where t2.c2 = 1;`
tk.MustExec(testSQL)
r := tk.MustQuery("select * from t1")
r.Check(testkit.Rows("10", "10"))
}
func (s *testSuite) TestUnion(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
testSQL := `select 1 union select 0;`
tk.MustExec(testSQL)
testSQL = `drop table if exists union_test; create table union_test(id int);`
tk.MustExec(testSQL)
testSQL = `drop table if exists union_test;`
tk.MustExec(testSQL)
testSQL = `create table union_test(id int);`
tk.MustExec(testSQL)
testSQL = `insert union_test values (1),(2); select id from union_test union select 1;`
tk.MustExec(testSQL)
testSQL = `select id from union_test union select id from union_test;`
tk.MustExec("begin")
r := tk.MustQuery(testSQL)
r.Check(testkit.Rows("1", "2"))
r = tk.MustQuery("select 1 union all select 1")
r.Check(testkit.Rows("1", "1"))
r = tk.MustQuery("select 1 union all select 1 union select 1")
r.Check(testkit.Rows("1"))
r = tk.MustQuery("select 1 union (select 2) limit 1")
r.Check(testkit.Rows("1"))
r = tk.MustQuery("select 1 union (select 2) limit 1, 1")
r.Check(testkit.Rows("2"))
r = tk.MustQuery("select id from union_test union all (select 1) order by id desc")
r.Check(testkit.Rows("2", "1", "1"))
r = tk.MustQuery("select id as a from union_test union (select 1) order by a desc")
r.Check(testkit.Rows("2", "1"))
r = tk.MustQuery(`select null union select "abc"`)
rowStr1 := fmt.Sprintf("%v", nil)
r.Check(testkit.Rows(rowStr1, "abc"))
r = tk.MustQuery(`select "abc" union select 1`)
r.Check(testkit.Rows("abc", "1"))
tk.MustExec("commit")
}
func (s *testSuite) TestTablePKisHandleScan(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")

View File

@ -367,11 +367,6 @@ func (s *testParserSuite) TestBuiltin(c *C) {
{`SELECT LOCATE('bar', 'foobarbar');`, true},
{`SELECT LOCATE('bar', 'foobarbar', 5);`, true},
// For delete statement
{"DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;", true},
{"DELETE FROM t1, t2 USING t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;", true},
{"DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id limit 10;", false},
// For time fsp
{"CREATE TABLE t( c1 TIME(2), c2 DATETIME(2), c3 TIMESTAMP(2) );", true},

View File

@ -1,127 +0,0 @@
// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package stmts_test
import (
"database/sql"
"fmt"
"testing"
"github.com/ngaut/log"
. "github.com/pingcap/check"
"github.com/pingcap/tidb"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/util/mock"
)
func TestT(t *testing.T) {
TestingT(t)
}
var _ = Suite(&testStmtSuite{})
type testStmtSuite struct {
dbName string
testDB *sql.DB
createDBSql string
dropDBSql string
useDBSql string
createTableSql string
insertSql string
selectSql string
createSystemDBSQL string
createUserTableSQL string
createDBPrivTableSQL string
createTablePrivTableSQL string
createColumnPrivTableSQL string
ctx context.Context
}
func (s *testStmtSuite) SetUpTest(c *C) {
log.SetLevelByString("error")
s.dbName = "teststmts"
var err error
s.testDB, err = sql.Open(tidb.DriverName, tidb.EngineGoLevelDBMemory+"/"+s.dbName+"/"+s.dbName)
c.Assert(err, IsNil)
// create db
s.createDBSql = fmt.Sprintf("create database if not exists %s;", s.dbName)
s.dropDBSql = fmt.Sprintf("drop database if exists %s;", s.dbName)
s.useDBSql = fmt.Sprintf("use %s;", s.dbName)
s.createTableSql = `
CREATE TABLE test(id INT NOT NULL DEFAULT 1, name varchar(255), PRIMARY KEY(id));
CREATE TABLE test1(id INT NOT NULL DEFAULT 2, name varchar(255), PRIMARY KEY(id), INDEX name(name));
CREATE TABLE test2(id INT NOT NULL DEFAULT 3, name varchar(255), PRIMARY KEY(id));`
s.selectSql = `SELECT * from test limit 2;`
mustExec(c, s.testDB, s.createDBSql)
mustExec(c, s.testDB, s.useDBSql)
s.createSystemDBSQL = fmt.Sprintf("create database if not exists %s;", mysql.SystemDB)
s.createUserTableSQL = tidb.CreateUserTable
s.createDBPrivTableSQL = tidb.CreateDBPrivTable
s.createTablePrivTableSQL = tidb.CreateTablePrivTable
s.createColumnPrivTableSQL = tidb.CreateColumnPrivTable
mustExec(c, s.testDB, s.createSystemDBSQL)
mustExec(c, s.testDB, s.createUserTableSQL)
mustExec(c, s.testDB, s.createDBPrivTableSQL)
mustExec(c, s.testDB, s.createTablePrivTableSQL)
mustExec(c, s.testDB, s.createColumnPrivTableSQL)
s.ctx = mock.NewContext()
variable.BindSessionVars(s.ctx)
}
func (s *testStmtSuite) TearDownTest(c *C) {
// drop db
mustExec(c, s.testDB, s.dropDBSql)
}
func mustBegin(c *C, currDB *sql.DB) *sql.Tx {
tx, err := currDB.Begin()
c.Assert(err, IsNil)
return tx
}
func mustCommit(c *C, tx *sql.Tx) {
err := tx.Commit()
c.Assert(err, IsNil)
}
func mustExecuteSql(c *C, tx *sql.Tx, sql string) sql.Result {
r, err := tx.Exec(sql)
c.Assert(err, IsNil, Commentf(sql))
return r
}
func mustExec(c *C, currDB *sql.DB, sql string) sql.Result {
tx := mustBegin(c, currDB)
r := mustExecuteSql(c, tx, sql)
mustCommit(c, tx)
return r
}
func checkResult(c *C, r sql.Result, affectedRows int64, insertID int64) {
gotRows, err := r.RowsAffected()
c.Assert(err, IsNil)
c.Assert(gotRows, Equals, affectedRows)
gotID, err := r.LastInsertId()
c.Assert(err, IsNil)
c.Assert(gotID, Equals, insertID)
}

View File

@ -1,165 +0,0 @@
// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package stmts_test
import (
"database/sql"
. "github.com/pingcap/check"
)
func (s *testStmtSuite) fillData(currDB *sql.DB, c *C) {
mustExec(c, currDB, s.createDBSql)
mustExec(c, currDB, s.useDBSql)
mustExec(c, currDB, s.createTableSql)
// insert data
r := mustExec(c, currDB, `INSERT INTO test VALUES (1, "hello");`)
checkResult(c, r, 1, 0)
r = mustExec(c, currDB, `INSERT INTO test VALUES (2, "hello");`)
checkResult(c, r, 1, 0)
}
func (s *testStmtSuite) fillDataMultiTable(currDB *sql.DB, c *C) {
// Create db
mustExec(c, currDB, s.createDBSql)
// Use db
mustExec(c, currDB, s.useDBSql)
// Create and fill table t1
mustExec(c, currDB, "CREATE TABLE t1 (id int, data int);")
r := mustExec(c, currDB, "insert into t1 values (11, 121), (12, 122), (13, 123);")
checkResult(c, r, 3, 0)
// Create and fill table t2
mustExec(c, currDB, "CREATE TABLE t2 (id int, data int);")
r = mustExec(c, currDB, "insert into t2 values (11, 221), (22, 222), (23, 223);")
checkResult(c, r, 3, 0)
// Create and fill table t3
mustExec(c, currDB, "CREATE TABLE t3 (id int, data int);")
r = mustExec(c, currDB, "insert into t3 values (11, 321), (22, 322), (23, 323);")
checkResult(c, r, 3, 0)
}
func (s *testStmtSuite) queryStrings(currDB *sql.DB, sql string, c *C) []string {
tx := mustBegin(c, currDB)
rows, err := tx.Query(sql)
c.Assert(err, IsNil)
defer rows.Close()
var strs []string
for rows.Next() {
var str string
rows.Scan(&str)
strs = append(strs, str)
}
return strs
}
func (s *testStmtSuite) TestDelete(c *C) {
s.fillData(s.testDB, c)
r := mustExec(c, s.testDB, `UPDATE test SET name = "abc" where id = 2;`)
checkResult(c, r, 1, 0)
r = mustExec(c, s.testDB, `DELETE from test where id = 2 limit 1;`)
checkResult(c, r, 1, 0)
// Test delete with false condition
r = mustExec(c, s.testDB, `DELETE from test where 0;`)
checkResult(c, r, 0, 0)
mustExec(c, s.testDB, "insert into test values (2, 'abc')")
r = mustExec(c, s.testDB, `delete from test where test.id = 2 limit 1`)
checkResult(c, r, 1, 0)
// Select data
tx := mustBegin(c, s.testDB)
rows, err := tx.Query(s.selectSql)
c.Assert(err, IsNil)
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
c.Assert(id, Equals, 1)
c.Assert(name, Equals, "hello")
}
rows.Close()
mustCommit(c, tx)
r = mustExec(c, s.testDB, `DELETE from test;`)
checkResult(c, r, 1, 0)
}
func (s *testStmtSuite) TestMultiTableDelete(c *C) {
s.fillDataMultiTable(s.testDB, c)
r := mustExec(c, s.testDB, `DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;`)
checkResult(c, r, 2, 0)
// Select data
tx := mustBegin(c, s.testDB)
rows, err := tx.Query("select * from t3")
c.Assert(err, IsNil)
cnt := 0
for rows.Next() {
cnt++
}
c.Assert(cnt, Equals, 3)
rows.Close()
}
func (s *testStmtSuite) TestQualifedDelete(c *C) {
mustExec(c, s.testDB, "drop table if exists t1")
mustExec(c, s.testDB, "drop table if exists t2")
mustExec(c, s.testDB, "create table t1 (c1 int, c2 int, index (c1))")
mustExec(c, s.testDB, "create table t2 (c1 int, c2 int)")
mustExec(c, s.testDB, "insert into t1 values (1, 1), (2, 2)")
// delete with index
r := mustExec(c, s.testDB, "delete from t1 where t1.c1 = 1")
checkResult(c, r, 1, 0)
// delete with no index
r = mustExec(c, s.testDB, "delete from t1 where t1.c2 = 2")
checkResult(c, r, 1, 0)
rows, err := s.testDB.Query("select * from t1")
c.Assert(err, IsNil)
cnt := 0
for rows.Next() {
cnt++
}
rows.Close()
c.Assert(cnt, Equals, 0)
_, err = s.testDB.Exec("delete from t1 as a where a.c1 = 1")
c.Assert(err, NotNil)
mustExec(c, s.testDB, "insert into t1 values (1, 1), (2, 2)")
mustExec(c, s.testDB, "insert into t2 values (2, 1), (3,1)")
r = mustExec(c, s.testDB, "delete t1, t2 from t1 join t2 where t1.c1 = t2.c2")
checkResult(c, r, 3, 0)
mustExec(c, s.testDB, "insert into t2 values (2, 1), (3,1)")
r = mustExec(c, s.testDB, "delete a, b from t1 as a join t2 as b where a.c2 = b.c1")
checkResult(c, r, 2, 0)
_, err = s.testDB.Exec("delete t1, t2 from t1 as a join t2 as b where a.c2 = b.c1")
c.Assert(err, NotNil)
mustExec(c, s.testDB, "drop table t1, t2")
}

View File

@ -1,116 +0,0 @@
// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package stmts_test
import (
. "github.com/pingcap/check"
)
func (s *testStmtSuite) TestInsert(c *C) {
testSQL := `drop table if exists insert_test;create table insert_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 int, c3 int default 1);`
mustExec(c, s.testDB, testSQL)
testSQL = `insert insert_test (c1) values (1),(2),(NULL);`
mustExec(c, s.testDB, testSQL)
errInsertSelectSQL := `insert insert_test (c1) values ();`
tx := mustBegin(c, s.testDB)
_, err := tx.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tx.Rollback()
errInsertSelectSQL = `insert insert_test (c1, c2) values (1,2),(1);`
tx = mustBegin(c, s.testDB)
_, err = tx.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tx.Rollback()
errInsertSelectSQL = `insert insert_test (xxx) values (3);`
tx = mustBegin(c, s.testDB)
_, err = tx.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tx.Rollback()
errInsertSelectSQL = `insert insert_test_xxx (c1) values ();`
tx = mustBegin(c, s.testDB)
_, err = tx.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tx.Rollback()
insertSetSQL := `insert insert_test set c1 = 3;`
mustExec(c, s.testDB, insertSetSQL)
errInsertSelectSQL = `insert insert_test set c1 = 4, c1 = 5;`
tx = mustBegin(c, s.testDB)
_, err = tx.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tx.Rollback()
errInsertSelectSQL = `insert insert_test set xxx = 6;`
tx = mustBegin(c, s.testDB)
_, err = tx.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tx.Rollback()
insertSelectSQL := `create table insert_test_1 (id int, c1 int);`
mustExec(c, s.testDB, insertSelectSQL)
insertSelectSQL = `insert insert_test_1 select id, c1 from insert_test;`
mustExec(c, s.testDB, insertSelectSQL)
insertSelectSQL = `create table insert_test_2 (id int, c1 int);`
mustExec(c, s.testDB, insertSelectSQL)
insertSelectSQL = `insert insert_test_1 select id, c1 from insert_test union select id * 10, c1 * 10 from insert_test;`
mustExec(c, s.testDB, insertSelectSQL)
errInsertSelectSQL = `insert insert_test_1 select c1 from insert_test;`
tx = mustBegin(c, s.testDB)
_, err = tx.Exec(errInsertSelectSQL)
c.Assert(err, NotNil)
tx.Rollback()
insertSQL := `insert into insert_test (id, c2) values (1, 1) on duplicate key update c2=10;`
mustExec(c, s.testDB, insertSQL)
insertSQL = `insert into insert_test (id, c2) values (1, 1) on duplicate key update insert_test.c2=10;`
mustExec(c, s.testDB, insertSQL)
_, err = s.testDB.Exec(`insert into insert_test (id, c2) values(1, 1) on duplicate key update t.c2 = 10`)
c.Assert(err, NotNil)
}
func (s *testStmtSuite) TestInsertAutoInc(c *C) {
createSQL := `drop table if exists insert_autoinc_test; create table insert_autoinc_test (id int primary key auto_increment, c1 int);`
mustExec(c, s.testDB, createSQL)
insertSQL := `insert into insert_autoinc_test(c1) values (1), (2)`
mustExec(c, s.testDB, insertSQL)
tx := mustBegin(c, s.testDB)
rows, err := tx.Query("select * from insert_autoinc_test;")
c.Assert(err, IsNil)
c.Assert(rows.Next(), IsTrue)
var id, c1 int
rows.Scan(&id, &c1)
c.Assert(id, Equals, 1)
c.Assert(c1, Equals, 1)
c.Assert(rows.Next(), IsTrue)
rows.Scan(&id, &c1)
c.Assert(id, Equals, 2)
c.Assert(c1, Equals, 2)
c.Assert(rows.Next(), IsFalse)
rows.Close()
mustCommit(c, tx)
}

View File

@ -1,124 +0,0 @@
// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package stmts_test
import (
. "github.com/pingcap/check"
)
func (s *testStmtSuite) TestReplace(c *C) {
testSQL := `drop table if exists replace_test;
create table replace_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 int, c3 int default 1);`
mustExec(c, s.testDB, testSQL)
testSQL = `replace replace_test (c1) values (1),(2),(NULL);`
mustExec(c, s.testDB, testSQL)
errReplaceSQL := `replace replace_test (c1) values ();`
tx := mustBegin(c, s.testDB)
_, err := tx.Exec(errReplaceSQL)
c.Assert(err, NotNil)
tx.Rollback()
errReplaceSQL = `replace replace_test (c1, c2) values (1,2),(1);`
tx = mustBegin(c, s.testDB)
_, err = tx.Exec(errReplaceSQL)
c.Assert(err, NotNil)
tx.Rollback()
errReplaceSQL = `replace replace_test (xxx) values (3);`
tx = mustBegin(c, s.testDB)
_, err = tx.Exec(errReplaceSQL)
c.Assert(err, NotNil)
tx.Rollback()
errReplaceSQL = `replace replace_test_xxx (c1) values ();`
tx = mustBegin(c, s.testDB)
_, err = tx.Exec(errReplaceSQL)
c.Assert(err, NotNil)
tx.Rollback()
replaceSetSQL := `replace replace_test set c1 = 3;`
mustExec(c, s.testDB, replaceSetSQL)
errReplaceSetSQL := `replace replace_test set c1 = 4, c1 = 5;`
tx = mustBegin(c, s.testDB)
_, err = tx.Exec(errReplaceSetSQL)
c.Assert(err, NotNil)
tx.Rollback()
errReplaceSetSQL = `replace replace_test set xxx = 6;`
tx = mustBegin(c, s.testDB)
_, err = tx.Exec(errReplaceSetSQL)
c.Assert(err, NotNil)
tx.Rollback()
replaceSelectSQL := `create table replace_test_1 (id int, c1 int);`
mustExec(c, s.testDB, replaceSelectSQL)
replaceSelectSQL = `replace replace_test_1 select id, c1 from replace_test;`
mustExec(c, s.testDB, replaceSelectSQL)
replaceSelectSQL = `create table replace_test_2 (id int, c1 int);`
mustExec(c, s.testDB, replaceSelectSQL)
replaceSelectSQL = `replace replace_test_1 select id, c1 from replace_test union select id * 10, c1 * 10 from replace_test;`
mustExec(c, s.testDB, replaceSelectSQL)
errReplaceSelectSQL := `replace replace_test_1 select c1 from replace_test;`
tx = mustBegin(c, s.testDB)
_, err = tx.Exec(errReplaceSelectSQL)
c.Assert(err, NotNil)
tx.Rollback()
replaceUniqueIndexSQL := `create table replace_test_3 (c1 int, c2 int, UNIQUE INDEX (c2));`
mustExec(c, s.testDB, replaceUniqueIndexSQL)
replaceUniqueIndexSQL = `replace into replace_test_3 set c2=1;`
mustExec(c, s.testDB, replaceUniqueIndexSQL)
replaceUniqueIndexSQL = `replace into replace_test_3 set c2=1;`
ret := mustExec(c, s.testDB, replaceUniqueIndexSQL)
rows, err := ret.RowsAffected()
c.Assert(err, IsNil)
c.Assert(rows, Equals, int64(1))
replaceUniqueIndexSQL = `replace into replace_test_3 set c1=1, c2=1;`
ret = mustExec(c, s.testDB, replaceUniqueIndexSQL)
rows, err = ret.RowsAffected()
c.Assert(err, IsNil)
c.Assert(rows, Equals, int64(2))
replaceUniqueIndexSQL = `replace into replace_test_3 set c2=NULL;`
mustExec(c, s.testDB, replaceUniqueIndexSQL)
replaceUniqueIndexSQL = `replace into replace_test_3 set c2=NULL;`
ret = mustExec(c, s.testDB, replaceUniqueIndexSQL)
rows, err = ret.RowsAffected()
c.Assert(err, IsNil)
c.Assert(rows, Equals, int64(1))
replaceUniqueIndexSQL = `create table replace_test_4 (c1 int, c2 int, c3 int, UNIQUE INDEX (c1, c2));`
mustExec(c, s.testDB, replaceUniqueIndexSQL)
replaceUniqueIndexSQL = `replace into replace_test_4 set c2=NULL;`
mustExec(c, s.testDB, replaceUniqueIndexSQL)
replaceUniqueIndexSQL = `replace into replace_test_4 set c2=NULL;`
ret = mustExec(c, s.testDB, replaceUniqueIndexSQL)
rows, err = ret.RowsAffected()
c.Assert(err, IsNil)
c.Assert(rows, Equals, int64(1))
replacePrimaryKeySQL := `create table replace_test_5 (c1 int, c2 int, c3 int, PRIMARY KEY (c1, c2));`
mustExec(c, s.testDB, replacePrimaryKeySQL)
replacePrimaryKeySQL = `replace into replace_test_5 set c1=1, c2=2;`
mustExec(c, s.testDB, replacePrimaryKeySQL)
replacePrimaryKeySQL = `replace into replace_test_5 set c1=1, c2=2;`
ret = mustExec(c, s.testDB, replacePrimaryKeySQL)
rows, err = ret.RowsAffected()
c.Assert(err, IsNil)
c.Assert(rows, Equals, int64(1))
}

View File

@ -1,142 +0,0 @@
// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package stmts_test
import (
. "github.com/pingcap/check"
)
func (s *testStmtSuite) TestSelectWithoutFrom(c *C) {
tx := mustBegin(c, s.testDB)
rows, err := tx.Query("select 1 + 2*3")
c.Assert(err, IsNil)
var result int
for rows.Next() {
rows.Scan(&result)
c.Assert(result, Equals, 7)
}
rows.Close()
mustCommit(c, tx)
tx = mustBegin(c, s.testDB)
rows, err = tx.Query(`select _utf8"string";`)
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{"string"}})
rows.Close()
mustCommit(c, tx)
}
func (s *testStmtSuite) TestSelectOrderBy(c *C) {
s.fillData(s.testDB, c)
tx := mustBegin(c, s.testDB)
// Test star field
rows, err := tx.Query("select * from test where id = 1 order by id limit 1 offset 0;")
c.Assert(err, IsNil)
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
c.Assert(id, Equals, 1)
c.Assert(name, Equals, "hello")
}
rows.Close()
mustCommit(c, tx)
tx = mustBegin(c, s.testDB)
// Test multiple field
rows, err = tx.Query("select id, name from test where id = 1 group by id, name limit 1 offset 0;")
c.Assert(err, IsNil)
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
c.Assert(id, Equals, 1)
c.Assert(name, Equals, "hello")
}
rows.Close()
mustCommit(c, tx)
}
func (s *testStmtSuite) TestSelectDistinct(c *C) {
s.fillData(s.testDB, c)
tx := mustBegin(c, s.testDB)
rows, err := tx.Query("select distinct name from test;")
c.Assert(err, IsNil)
var cnt int
for rows.Next() {
var name string
rows.Scan(&name)
c.Assert(name, Equals, "hello")
cnt++
}
c.Assert(cnt, Equals, 1)
rows.Close()
mustCommit(c, tx)
}
func (s *testStmtSuite) TestSelectHaving(c *C) {
s.fillData(s.testDB, c)
tx := mustBegin(c, s.testDB)
rows, err := tx.Query("select id, name from test where id in (1,3) having name like 'he%';")
c.Assert(err, IsNil)
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
c.Assert(id, Equals, 1)
c.Assert(name, Equals, "hello")
}
rows.Close()
mustCommit(c, tx)
}
func (s *testStmtSuite) TestSelectErrorRow(c *C) {
tx := mustBegin(c, s.testDB)
_, err := tx.Query("select row(1, 1) from test")
c.Assert(err, NotNil)
_, err = tx.Query("select * from test group by row(1, 1);")
c.Assert(err, NotNil)
_, err = tx.Query("select * from test order by row(1, 1);")
c.Assert(err, NotNil)
_, err = tx.Query("select * from test having row(1, 1);")
c.Assert(err, NotNil)
_, err = tx.Query("select (select 1, 1) from test;")
c.Assert(err, NotNil)
_, err = tx.Query("select * from test group by (select 1, 1);")
c.Assert(err, NotNil)
_, err = tx.Query("select * from test order by (select 1, 1);")
c.Assert(err, NotNil)
_, err = tx.Query("select * from test having (select 1, 1);")
c.Assert(err, NotNil)
mustCommit(c, tx)
}

View File

@ -1,116 +0,0 @@
// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package stmts_test
import (
"database/sql"
"fmt"
. "github.com/pingcap/check"
)
func (s *testStmtSuite) TestUnion(c *C) {
testSQL := `select 1 union select 0;`
mustExec(c, s.testDB, testSQL)
testSQL = `drop table if exists union_test; create table union_test(id int);`
mustExec(c, s.testDB, testSQL)
testSQL = `drop table if exists union_test;`
mustExec(c, s.testDB, testSQL)
testSQL = `create table union_test(id int);`
mustExec(c, s.testDB, testSQL)
testSQL = `insert union_test values (1),(2); select id from union_test union select 1;`
mustExec(c, s.testDB, testSQL)
testSQL = `select id from union_test union select id from union_test;`
tx := mustBegin(c, s.testDB)
rows, err := tx.Query(testSQL)
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{1}, {2}})
rows, err = tx.Query("select 1 union all select 1")
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{1}, {1}})
rows, err = tx.Query("select 1 union all select 1 union select 1")
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{1}})
rows, err = tx.Query("select 1 union (select 2) limit 1")
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{1}})
rows, err = tx.Query("select 1 union (select 2) limit 1, 1")
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{2}})
rows, err = tx.Query("select id from union_test union all (select 1) order by id desc")
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{2}, {1}, {1}})
rows, err = tx.Query("select id as a from union_test union (select 1) order by a desc")
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{2}, {1}})
rows, err = tx.Query(`select null union select "abc"`)
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{nil}, {"abc"}})
rows, err = tx.Query(`select "abc" union select 1`)
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{"abc"}, {"1"}})
mustCommit(c, tx)
}
func dumpRows(c *C, rows *sql.Rows) [][]interface{} {
cols, err := rows.Columns()
c.Assert(err, IsNil)
ay := make([][]interface{}, 0)
for rows.Next() {
v := make([]interface{}, len(cols))
for i := range v {
v[i] = new(interface{})
}
err = rows.Scan(v...)
c.Assert(err, IsNil)
for i := range v {
v[i] = *(v[i].(*interface{}))
}
ay = append(ay, v)
}
rows.Close()
c.Assert(rows.Err(), IsNil)
return ay
}
func matchRows(c *C, rows *sql.Rows, expected [][]interface{}) {
ay := dumpRows(c, rows)
c.Assert(len(ay), Equals, len(expected))
for i := range ay {
match(c, ay[i], expected[i]...)
}
}
func match(c *C, row []interface{}, expected ...interface{}) {
c.Assert(len(row), Equals, len(expected))
for i := range row {
got := fmt.Sprintf("%v", row[i])
need := fmt.Sprintf("%v", expected[i])
c.Assert(got, Equals, need)
}
}

View File

@ -1,212 +0,0 @@
// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package stmts_test
import (
"database/sql"
. "github.com/pingcap/check"
"github.com/pingcap/tidb"
)
func (s *testStmtSuite) TestUpdate(c *C) {
testDB, err := sql.Open(tidb.DriverName, tidb.EngineGoLevelDBMemory+"tmp/"+s.dbName)
c.Assert(err, IsNil)
s.fillData(testDB, c)
updateStr := `UPDATE test SET name = "abc" where id > 0;`
r := mustExec(c, testDB, updateStr)
checkResult(c, r, 2, 0)
// select data
tx := mustBegin(c, testDB)
rows, err := tx.Query(s.selectSql)
c.Assert(err, IsNil)
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
c.Assert(name, Equals, "abc")
}
rows.Close()
mustCommit(c, tx)
r = mustExec(c, testDB, `UPDATE test SET name = "foo"`)
checkResult(c, r, 2, 0)
}
func (s *testStmtSuite) fillMultiTableForUpdate(currDB *sql.DB, c *C) {
// Create db
mustExec(c, currDB, s.createDBSql)
// Use db
mustExec(c, currDB, s.useDBSql)
// Create and fill table items
mustExec(c, currDB, "CREATE TABLE items (id int, price TEXT);")
r := mustExec(c, currDB, `insert into items values (11, "items_price_11"), (12, "items_price_12"), (13, "items_price_13");`)
checkResult(c, r, 3, 0)
// Create and fill table month
mustExec(c, currDB, "CREATE TABLE month (mid int, mprice TEXT);")
r = mustExec(c, currDB, `insert into month values (11, "month_price_11"), (22, "month_price_22"), (13, "month_price_13");`)
checkResult(c, r, 3, 0)
}
func (s *testStmtSuite) TestMultipleTableUpdate(c *C) {
testDB, err := sql.Open(tidb.DriverName, tidb.EngineGoLevelDBMemory+"tmp/"+s.dbName)
c.Assert(err, IsNil)
s.fillMultiTableForUpdate(testDB, c)
r := mustExec(c, testDB, `UPDATE items, month SET items.price=month.mprice WHERE items.id=month.mid;`)
c.Assert(r, NotNil)
tx := mustBegin(c, testDB)
rows, err := tx.Query("SELECT * FROM items")
c.Assert(err, IsNil)
expectedResult := map[int]string{
11: "month_price_11",
12: "items_price_12",
13: "month_price_13",
}
for rows.Next() {
var (
id int
price string
)
rows.Scan(&id, &price)
c.Assert(price, Equals, expectedResult[id])
}
rows.Close()
mustCommit(c, tx)
// Single-table syntax but with multiple tables
r = mustExec(c, testDB, `UPDATE items join month on items.id=month.mid SET items.price=month.mid;`)
c.Assert(r, NotNil)
tx = mustBegin(c, testDB)
rows, err = tx.Query("SELECT * FROM items")
c.Assert(err, IsNil)
expectedResult = map[int]string{
11: "11",
12: "items_price_12",
13: "13",
}
for rows.Next() {
var (
id int
price string
)
rows.Scan(&id, &price)
c.Assert(price, Equals, expectedResult[id])
}
rows.Close()
mustCommit(c, tx)
// JoinTable with alias table name.
r = mustExec(c, testDB, `UPDATE items T0 join month T1 on T0.id=T1.mid SET T0.price=T1.mprice;`)
c.Assert(r, NotNil)
tx = mustBegin(c, testDB)
rows, err = tx.Query("SELECT * FROM items")
c.Assert(err, IsNil)
expectedResult = map[int]string{
11: "month_price_11",
12: "items_price_12",
13: "month_price_13",
}
for rows.Next() {
var (
id int
price string
)
rows.Scan(&id, &price)
c.Assert(price, Equals, expectedResult[id])
}
rows.Close()
mustCommit(c, tx)
}
// For https://github.com/pingcap/tidb/issues/345
func (s *testStmtSuite) TestIssue345(c *C) {
testDB, err := sql.Open(tidb.DriverName, tidb.EngineGoLevelDBMemory+"tmp-issue345/"+s.dbName)
c.Assert(err, IsNil)
mustExec(c, testDB, `drop table if exists t1, t2`)
mustExec(c, testDB, `create table t1 (c1 int);`)
mustExec(c, testDB, `create table t2 (c2 int);`)
mustExec(c, testDB, `insert into t1 values (1);`)
mustExec(c, testDB, `insert into t2 values (2);`)
mustExec(c, testDB, `update t1, t2 set t1.c1 = 2, t2.c2 = 1;`)
mustExec(c, testDB, `update t1, t2 set c1 = 2, c2 = 1;`)
mustExec(c, testDB, `update t1 as a, t2 as b set a.c1 = 2, b.c2 = 1;`)
// Check t1 content
tx := mustBegin(c, testDB)
rows, err := tx.Query("SELECT * FROM t1;")
matchRows(c, rows, [][]interface{}{{2}})
rows.Close()
mustCommit(c, tx)
// Check t2 content
tx = mustBegin(c, testDB)
rows, err = tx.Query("SELECT * FROM t2;")
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{1}})
rows.Close()
mustCommit(c, tx)
mustExec(c, testDB, `update t1 as a, t2 as t1 set a.c1 = 1, t1.c2 = 2;`)
// Check t1 content
tx = mustBegin(c, testDB)
rows, err = tx.Query("SELECT * FROM t1;")
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{1}})
rows.Close()
mustCommit(c, tx)
// Check t2 content
tx = mustBegin(c, testDB)
rows, err = tx.Query("SELECT * FROM t2;")
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{2}})
rows.Close()
_, err = testDB.Exec(`update t1 as a, t2 set t1.c1 = 10;`)
c.Assert(err, NotNil)
mustCommit(c, tx)
}
func (s *testStmtSuite) TestMultiUpdate(c *C) {
// fix https://github.com/pingcap/tidb/issues/369
testSQL := `
DROP TABLE IF EXISTS t1, t2;
create table t1 (c int);
create table t2 (c varchar(256));
insert into t1 values (1), (2);
insert into t2 values ("a"), ("b");
update t1, t2 set t1.c = 10, t2.c = "abc";`
mustExec(c, s.testDB, testSQL)
// fix https://github.com/pingcap/tidb/issues/376
testSQL = `DROP TABLE IF EXISTS t1, t2;
create table t1 (c1 int);
create table t2 (c2 int);
insert into t1 values (1), (2);
insert into t2 values (1), (2);
update t1, t2 set t1.c1 = 10, t2.c2 = 2 where t2.c2 = 1;`
mustExec(c, s.testDB, testSQL)
rows, err := s.testDB.Query("select * from t1")
c.Assert(err, IsNil)
matchRows(c, rows, [][]interface{}{{10}, {10}})
}

View File

@ -87,6 +87,12 @@ func (tk *TestKit) Exec(sql string, args ...interface{}) (ast.RecordSet, error)
return rs, nil
}
// CheckExecResult checks the affected rows and the insert id after executing MustExec.
func (tk *TestKit) CheckExecResult(affectedRows, insertID int64) {
tk.c.Assert(affectedRows, check.Equals, int64(tk.Se.AffectedRows()))
tk.c.Assert(insertID, check.Equals, int64(tk.Se.LastInsertID()))
}
// MustExec executes a sql statement and asserts nil error.
func (tk *TestKit) MustExec(sql string, args ...interface{}) {
_, err := tk.Exec(sql, args...)