1903 lines
72 KiB
Go
1903 lines
72 KiB
Go
// 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 executor_test
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/ngaut/log"
|
|
. "github.com/pingcap/check"
|
|
"github.com/pingcap/tidb"
|
|
"github.com/pingcap/tidb/context"
|
|
"github.com/pingcap/tidb/domain"
|
|
"github.com/pingcap/tidb/executor"
|
|
"github.com/pingcap/tidb/inspectkv"
|
|
"github.com/pingcap/tidb/kv"
|
|
"github.com/pingcap/tidb/model"
|
|
"github.com/pingcap/tidb/parser"
|
|
"github.com/pingcap/tidb/store/tikv"
|
|
"github.com/pingcap/tidb/util/testkit"
|
|
"github.com/pingcap/tidb/util/testleak"
|
|
"github.com/pingcap/tidb/util/types"
|
|
)
|
|
|
|
func TestT(t *testing.T) {
|
|
TestingT(t)
|
|
}
|
|
|
|
var _ = Suite(&testSuite{})
|
|
|
|
type testSuite struct {
|
|
store kv.Storage
|
|
*parser.Parser
|
|
}
|
|
|
|
var mockTikv = flag.Bool("mockTikv", true, "use mock tikv store in executor test")
|
|
|
|
func (s *testSuite) SetUpSuite(c *C) {
|
|
s.Parser = parser.New()
|
|
flag.Lookup("mockTikv")
|
|
useMockTikv := *mockTikv
|
|
if useMockTikv {
|
|
store, err := tikv.NewMockTikvStore()
|
|
c.Assert(err, IsNil)
|
|
s.store = store
|
|
tidb.SetSchemaLease(0)
|
|
} else {
|
|
store, err := tidb.NewStore("memory://test/test")
|
|
c.Assert(err, IsNil)
|
|
s.store = store
|
|
}
|
|
log.SetLevelByString("warn")
|
|
executor.BaseLookupTableTaskSize = 2
|
|
}
|
|
|
|
func (s *testSuite) TearDownSuite(c *C) {
|
|
executor.BaseLookupTableTaskSize = 512
|
|
s.store.Close()
|
|
}
|
|
|
|
func (s *testSuite) TestAdmin(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists admin_test")
|
|
tk.MustExec("create table admin_test (c1 int, c2 int, c3 int default 1, index (c1))")
|
|
tk.MustExec("insert admin_test (c1) values (1),(2),(NULL)")
|
|
r, err := tk.Exec("admin show ddl")
|
|
c.Assert(err, IsNil)
|
|
row, err := r.Next()
|
|
c.Assert(err, IsNil)
|
|
c.Assert(row.Data, HasLen, 6)
|
|
txn, err := s.store.Begin()
|
|
c.Assert(err, IsNil)
|
|
ddlInfo, err := inspectkv.GetDDLInfo(txn)
|
|
c.Assert(err, IsNil)
|
|
c.Assert(row.Data[0].GetInt64(), Equals, ddlInfo.SchemaVer)
|
|
rowOwnerInfos := strings.Split(row.Data[1].GetString(), ",")
|
|
ownerInfos := strings.Split(ddlInfo.Owner.String(), ",")
|
|
c.Assert(rowOwnerInfos[0], Equals, ownerInfos[0])
|
|
c.Assert(row.Data[2].GetString(), Equals, "")
|
|
bgInfo, err := inspectkv.GetBgDDLInfo(txn)
|
|
c.Assert(err, IsNil)
|
|
c.Assert(row.Data[3].GetInt64(), Equals, bgInfo.SchemaVer)
|
|
rowOwnerInfos = strings.Split(row.Data[4].GetString(), ",")
|
|
ownerInfos = strings.Split(bgInfo.Owner.String(), ",")
|
|
c.Assert(rowOwnerInfos[0], Equals, ownerInfos[0])
|
|
c.Assert(row.Data[5].GetString(), Equals, "")
|
|
row, err = r.Next()
|
|
c.Assert(err, IsNil)
|
|
c.Assert(row, IsNil)
|
|
|
|
// check table test
|
|
tk.MustExec("create table admin_test1 (c1 int, c2 int default 1, index (c1))")
|
|
tk.MustExec("insert admin_test1 (c1) values (21),(22)")
|
|
r, err = tk.Exec("admin check table admin_test, admin_test1")
|
|
c.Assert(err, IsNil)
|
|
c.Assert(r, IsNil)
|
|
// error table name
|
|
r, err = tk.Exec("admin check table admin_test_error")
|
|
c.Assert(err, NotNil)
|
|
// different index values
|
|
domain, err := domain.NewDomain(s.store, 1*time.Second)
|
|
c.Assert(err, IsNil)
|
|
is := domain.InfoSchema()
|
|
c.Assert(is, NotNil)
|
|
tb, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("admin_test"))
|
|
c.Assert(err, IsNil)
|
|
c.Assert(tb.Indices(), HasLen, 1)
|
|
_, err = tb.Indices()[0].Create(txn, types.MakeDatums(int64(10)), 1)
|
|
c.Assert(err, IsNil)
|
|
err = txn.Commit()
|
|
c.Assert(err, IsNil)
|
|
r, err = tk.Exec("admin check table admin_test")
|
|
c.Assert(err, NotNil)
|
|
}
|
|
|
|
func (s *testSuite) TestPrepared(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists prepare_test")
|
|
tk.MustExec("create table prepare_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 int, c3 int default 1)")
|
|
tk.MustExec("insert prepare_test (c1) values (1),(2),(NULL)")
|
|
|
|
tk.MustExec(`prepare stmt_test_1 from 'select id from prepare_test where id > ?'; set @a = 1; execute stmt_test_1 using @a;`)
|
|
tk.MustExec(`prepare stmt_test_2 from 'select 1'`)
|
|
// Prepare multiple statement is not allowed.
|
|
_, err := tk.Exec(`prepare stmt_test_3 from 'select id from prepare_test where id > ?;select id from prepare_test where id > ?;'`)
|
|
c.Assert(executor.ErrPrepareMulti.Equal(err), IsTrue)
|
|
// The variable count does not match.
|
|
_, err = tk.Exec(`prepare stmt_test_4 from 'select id from prepare_test where id > ? and id < ?'; set @a = 1; execute stmt_test_4 using @a;`)
|
|
c.Assert(executor.ErrWrongParamCount.Equal(err), IsTrue)
|
|
// Prepare and deallocate prepared statement immediately.
|
|
tk.MustExec(`prepare stmt_test_5 from 'select id from prepare_test where id > ?'; deallocate prepare stmt_test_5;`)
|
|
|
|
// Statement not found.
|
|
_, err = tk.Exec("deallocate prepare stmt_test_5")
|
|
c.Assert(executor.ErrStmtNotFound.Equal(err), IsTrue)
|
|
|
|
// The `stmt_test5` should not be found.
|
|
_, err = tk.Exec(`set @a = 1; execute stmt_test_5 using @a;`)
|
|
c.Assert(executor.ErrStmtNotFound.Equal(err), IsTrue)
|
|
|
|
// Use parameter marker with argument will run prepared statement.
|
|
result := tk.MustQuery("select distinct c1, c2 from prepare_test where c1 = ?", 1)
|
|
result.Check([][]interface{}{{1, nil}})
|
|
|
|
// Call Session PrepareStmt directly to get stmtId.
|
|
stmtId, _, _, err := tk.Se.PrepareStmt("select c1, c2 from prepare_test where c1 = ?")
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Se.ExecutePreparedStmt(stmtId, 1)
|
|
c.Assert(err, IsNil)
|
|
|
|
// Make schema change.
|
|
tk.Exec("create table prepare2 (a int)")
|
|
|
|
// Should success as the changed schema do not affect the prepared statement.
|
|
_, err = tk.Se.ExecutePreparedStmt(stmtId, 1)
|
|
c.Assert(err, IsNil)
|
|
|
|
// Drop a column so the prepared statement become invalid.
|
|
tk.MustExec("alter table prepare_test drop column c2")
|
|
|
|
// There should be schema changed error.
|
|
_, err = tk.Se.ExecutePreparedStmt(stmtId, 1)
|
|
c.Assert(executor.ErrSchemaChanged.Equal(err), IsTrue)
|
|
|
|
// Coverage.
|
|
exec := &executor.ExecuteExec{}
|
|
exec.Fields()
|
|
exec.Next()
|
|
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) {
|
|
defer testleak.AfterTest(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) {
|
|
defer testleak.AfterTest(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) {
|
|
defer testleak.AfterTest(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) {
|
|
defer testleak.AfterTest(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) {
|
|
defer testleak.AfterTest(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")
|
|
|
|
tk.MustExec("begin")
|
|
insertSQL = `insert into insert_autoinc_test(id, c1) values (5,5)`
|
|
tk.MustExec(insertSQL)
|
|
insertSQL = `insert into insert_autoinc_test(c1) values (6)`
|
|
tk.MustExec(insertSQL)
|
|
tk.MustExec("commit")
|
|
tk.MustExec("begin")
|
|
r = tk.MustQuery("select * from insert_autoinc_test;")
|
|
rowStr3 := fmt.Sprintf("%v %v", "5", "5")
|
|
rowStr4 := fmt.Sprintf("%v %v", "6", "6")
|
|
r.Check(testkit.Rows(rowStr1, rowStr2, rowStr3, rowStr4))
|
|
tk.MustExec("commit")
|
|
|
|
tk.MustExec("begin")
|
|
insertSQL = `insert into insert_autoinc_test(id, c1) values (3,3)`
|
|
tk.MustExec(insertSQL)
|
|
tk.MustExec("commit")
|
|
tk.MustExec("begin")
|
|
r = tk.MustQuery("select * from insert_autoinc_test;")
|
|
rowStr5 := fmt.Sprintf("%v %v", "3", "3")
|
|
r.Check(testkit.Rows(rowStr1, rowStr2, rowStr5, rowStr3, rowStr4))
|
|
tk.MustExec("commit")
|
|
|
|
tk.MustExec("begin")
|
|
insertSQL = `insert into insert_autoinc_test(c1) values (7)`
|
|
tk.MustExec(insertSQL)
|
|
tk.MustExec("commit")
|
|
tk.MustExec("begin")
|
|
r = tk.MustQuery("select * from insert_autoinc_test;")
|
|
rowStr6 := fmt.Sprintf("%v %v", "7", "7")
|
|
r.Check(testkit.Rows(rowStr1, rowStr2, rowStr5, rowStr3, rowStr4, rowStr6))
|
|
tk.MustExec("commit")
|
|
|
|
// issue-962
|
|
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(id, c1) values (0.3, 1)`
|
|
tk.MustExec(insertSQL)
|
|
r = tk.MustQuery("select * from insert_autoinc_test;")
|
|
rowStr1 = fmt.Sprintf("%v %v", "1", "1")
|
|
r.Check(testkit.Rows(rowStr1))
|
|
insertSQL = `insert into insert_autoinc_test(id, c1) values (-0.3, 2)`
|
|
tk.MustExec(insertSQL)
|
|
r = tk.MustQuery("select * from insert_autoinc_test;")
|
|
rowStr2 = fmt.Sprintf("%v %v", "2", "2")
|
|
r.Check(testkit.Rows(rowStr1, rowStr2))
|
|
insertSQL = `insert into insert_autoinc_test(id, c1) values (-3.3, 3)`
|
|
tk.MustExec(insertSQL)
|
|
r = tk.MustQuery("select * from insert_autoinc_test;")
|
|
rowStr3 = fmt.Sprintf("%v %v", "-3", "3")
|
|
r.Check(testkit.Rows(rowStr3, rowStr1, rowStr2))
|
|
insertSQL = `insert into insert_autoinc_test(id, c1) values (4.3, 4)`
|
|
tk.MustExec(insertSQL)
|
|
r = tk.MustQuery("select * from insert_autoinc_test;")
|
|
rowStr4 = fmt.Sprintf("%v %v", "4", "4")
|
|
r.Check(testkit.Rows(rowStr3, rowStr1, rowStr2, rowStr4))
|
|
insertSQL = `insert into insert_autoinc_test(c1) values (5)`
|
|
tk.MustExec(insertSQL)
|
|
r = tk.MustQuery("select * from insert_autoinc_test;")
|
|
rowStr5 = fmt.Sprintf("%v %v", "5", "5")
|
|
r.Check(testkit.Rows(rowStr3, rowStr1, rowStr2, rowStr4, rowStr5))
|
|
insertSQL = `insert into insert_autoinc_test(id, c1) values (null, 6)`
|
|
tk.MustExec(insertSQL)
|
|
r = tk.MustQuery("select * from insert_autoinc_test;")
|
|
rowStr6 = fmt.Sprintf("%v %v", "6", "6")
|
|
r.Check(testkit.Rows(rowStr3, rowStr1, rowStr2, rowStr4, rowStr5, rowStr6))
|
|
}
|
|
|
|
func (s *testSuite) TestInsertIgnore(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
testSQL := `drop table if exists t;
|
|
create table t (id int PRIMARY KEY AUTO_INCREMENT, c1 int);`
|
|
tk.MustExec(testSQL)
|
|
testSQL = `insert into t values (1, 2);`
|
|
tk.MustExec(testSQL)
|
|
|
|
r := tk.MustQuery("select * from t;")
|
|
rowStr := fmt.Sprintf("%v %v", "1", "2")
|
|
r.Check(testkit.Rows(rowStr))
|
|
|
|
tk.MustExec("insert ignore into t values (1, 3), (2, 3)")
|
|
|
|
r = tk.MustQuery("select * from t;")
|
|
rowStr = fmt.Sprintf("%v %v", "1", "2")
|
|
rowStr1 := fmt.Sprintf("%v %v", "2", "3")
|
|
r.Check(testkit.Rows(rowStr, rowStr1))
|
|
}
|
|
|
|
func (s *testSuite) TestReplace(c *C) {
|
|
defer testleak.AfterTest(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))
|
|
|
|
// For Issue989
|
|
issue989SQL := `CREATE TABLE tIssue989 (a int, b int, PRIMARY KEY(a), UNIQUE KEY(b));`
|
|
tk.MustExec(issue989SQL)
|
|
issue989SQL = `insert into tIssue989 (a, b) values (1, 2);`
|
|
tk.MustExec(issue989SQL)
|
|
issue989SQL = `replace into tIssue989(a, b) values (111, 2);`
|
|
tk.MustExec(issue989SQL)
|
|
r := tk.MustQuery("select * from tIssue989;")
|
|
r.Check(testkit.Rows("111 2"))
|
|
|
|
// For Issue1012
|
|
issue1012SQL := `CREATE TABLE tIssue1012 (a int, b int, PRIMARY KEY(a), UNIQUE KEY(b));`
|
|
tk.MustExec(issue1012SQL)
|
|
issue1012SQL = `insert into tIssue1012 (a, b) values (1, 2);`
|
|
tk.MustExec(issue1012SQL)
|
|
issue1012SQL = `insert into tIssue1012 (a, b) values (2, 1);`
|
|
tk.MustExec(issue1012SQL)
|
|
issue1012SQL = `replace into tIssue1012(a, b) values (1, 1);`
|
|
tk.MustExec(issue1012SQL)
|
|
c.Assert(int64(tk.Se.AffectedRows()), Equals, int64(3))
|
|
r = tk.MustQuery("select * from tIssue1012;")
|
|
r.Check(testkit.Rows("1 1"))
|
|
}
|
|
|
|
func (s *testSuite) TestSelectWithoutFrom(c *C) {
|
|
defer testleak.AfterTest(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) TestSelectLimit(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
s.fillData(tk, "select_limit")
|
|
|
|
tk.MustExec("insert INTO select_limit VALUES (3, \"hello\");")
|
|
tk.CheckExecResult(1, 0)
|
|
tk.MustExec("insert INTO select_limit VALUES (4, \"hello\");")
|
|
tk.CheckExecResult(1, 0)
|
|
|
|
tk.MustExec("begin")
|
|
r := tk.MustQuery("select * from select_limit limit 1;")
|
|
rowStr1 := fmt.Sprintf("%v %v", 1, []byte("hello"))
|
|
r.Check(testkit.Rows(rowStr1))
|
|
tk.MustExec("commit")
|
|
|
|
r = tk.MustQuery("select id from (select * from select_limit limit 1) k where id != 1;")
|
|
r.Check(testkit.Rows())
|
|
|
|
tk.MustExec("begin")
|
|
r = tk.MustQuery("select * from select_limit limit 18446744073709551615 offset 0;")
|
|
rowStr2 := fmt.Sprintf("%v %v", 2, []byte("hello"))
|
|
rowStr3 := fmt.Sprintf("%v %v", 3, []byte("hello"))
|
|
rowStr4 := fmt.Sprintf("%v %v", 4, []byte("hello"))
|
|
r.Check(testkit.Rows(rowStr1, rowStr2, rowStr3, rowStr4))
|
|
tk.MustExec("commit")
|
|
|
|
tk.MustExec("begin")
|
|
r = tk.MustQuery("select * from select_limit limit 18446744073709551615 offset 1;")
|
|
r.Check(testkit.Rows(rowStr2, rowStr3, rowStr4))
|
|
tk.MustExec("commit")
|
|
|
|
tk.MustExec("begin")
|
|
r = tk.MustQuery("select * from select_limit limit 18446744073709551615 offset 3;")
|
|
r.Check(testkit.Rows(rowStr4))
|
|
tk.MustExec("commit")
|
|
|
|
tk.MustExec("begin")
|
|
_, err := tk.Exec("select * from select_limit limit 18446744073709551616 offset 3;")
|
|
c.Assert(err, NotNil)
|
|
tk.MustExec("rollback")
|
|
}
|
|
|
|
func (s *testSuite) TestSelectOrderBy(c *C) {
|
|
defer testleak.AfterTest(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 limit
|
|
r = tk.MustQuery("select * from select_order_test order by name, 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 limit
|
|
r = tk.MustQuery("select id as c1, name from select_order_test order by 2, 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 limit overflow
|
|
r = tk.MustQuery("select * from select_order_test order by name, id limit 100 offset 0;")
|
|
rowStr1 := fmt.Sprintf("%v %v", 1, []byte("hello"))
|
|
rowStr2 := fmt.Sprintf("%v %v", 2, []byte("hello"))
|
|
r.Check(testkit.Rows(rowStr1, rowStr2))
|
|
tk.MustExec("commit")
|
|
|
|
tk.MustExec("begin")
|
|
// Test offset overflow
|
|
r = tk.MustQuery("select * from select_order_test order by name, id limit 1 offset 100;")
|
|
r.Check(testkit.Rows())
|
|
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")
|
|
|
|
// Test limit + order by
|
|
tk.MustExec("begin")
|
|
executor.SortBufferSize = 10
|
|
for i := 3; i <= 10; i += 1 {
|
|
tk.MustExec(fmt.Sprintf("insert INTO select_order_test VALUES (%d, \"zz\");", i))
|
|
}
|
|
tk.MustExec("insert INTO select_order_test VALUES (10086, \"hi\");")
|
|
for i := 11; i <= 20; i += 1 {
|
|
tk.MustExec(fmt.Sprintf("insert INTO select_order_test VALUES (%d, \"hh\");", i))
|
|
}
|
|
for i := 21; i <= 30; i += 1 {
|
|
tk.MustExec(fmt.Sprintf("insert INTO select_order_test VALUES (%d, \"zz\");", i))
|
|
}
|
|
tk.MustExec("insert INTO select_order_test VALUES (1501, \"aa\");")
|
|
r = tk.MustQuery("select * from select_order_test order by name, id limit 1 offset 3;")
|
|
rowStr = fmt.Sprintf("%v %v", 11, []byte("hh"))
|
|
r.Check(testkit.Rows(rowStr))
|
|
executor.SortBufferSize = 500
|
|
tk.MustExec("drop table select_order_test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (c int, d int)")
|
|
tk.MustExec("insert t values (1, 1)")
|
|
tk.MustExec("insert t values (1, 2)")
|
|
tk.MustExec("insert t values (1, 3)")
|
|
r = tk.MustQuery("select 1-d as d from t order by d;")
|
|
r.Check(testkit.Rows("-2", "-1", "0"))
|
|
r = tk.MustQuery("select 1-d as d from t order by d + 1;")
|
|
r.Check(testkit.Rows("0", "-1", "-2"))
|
|
r = tk.MustQuery("select t.d from t order by d;")
|
|
r.Check(testkit.Rows("1", "2", "3"))
|
|
}
|
|
|
|
func (s *testSuite) TestSelectDistinct(c *C) {
|
|
defer testleak.AfterTest(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) TestSelectErrorRow(c *C) {
|
|
defer testleak.AfterTest(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) {
|
|
defer testleak.AfterTest(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)
|
|
|
|
// table option is auto-increment
|
|
tk.MustExec("begin")
|
|
tk.MustExec("drop table if exists update_test;")
|
|
tk.MustExec("commit")
|
|
tk.MustExec("begin")
|
|
tk.MustExec("create table update_test(id int not null auto_increment, name varchar(255), primary key(id))")
|
|
tk.MustExec("insert into update_test(name) values ('aa')")
|
|
tk.MustExec("update update_test set id = 8 where name = 'aa'")
|
|
tk.MustExec("insert into update_test(name) values ('bb')")
|
|
tk.MustExec("commit")
|
|
tk.MustExec("begin")
|
|
r = tk.MustQuery("select * from update_test;")
|
|
rowStr1 = fmt.Sprintf("%v %v", 8, []byte("aa"))
|
|
rowStr2 = fmt.Sprintf("%v %v", 9, []byte("bb"))
|
|
r.Check(testkit.Rows(rowStr1, rowStr2))
|
|
tk.MustExec("commit")
|
|
|
|
tk.MustExec("begin")
|
|
tk.MustExec("drop table if exists update_test;")
|
|
tk.MustExec("commit")
|
|
tk.MustExec("begin")
|
|
tk.MustExec("create table update_test(id int not null auto_increment, name varchar(255), index(id))")
|
|
tk.MustExec("insert into update_test(name) values ('aa')")
|
|
_, err := tk.Exec("update update_test set id = null where name = 'aa'")
|
|
c.Assert(err, NotNil)
|
|
c.Assert(err.Error(), DeepEquals, "Column 'id' cannot be null")
|
|
|
|
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) {
|
|
defer testleak.AfterTest(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) {
|
|
defer testleak.AfterTest(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) {
|
|
defer testleak.AfterTest(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) {
|
|
defer testleak.AfterTest(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"))
|
|
|
|
testSQL = `select * from (select id from union_test union select id from union_test) t;`
|
|
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) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a int PRIMARY KEY AUTO_INCREMENT)")
|
|
tk.MustExec("insert t values (),()")
|
|
tk.MustExec("insert t values (-100),(0)")
|
|
|
|
cases := []struct {
|
|
sql string
|
|
result [][]interface{}
|
|
}{
|
|
{
|
|
"select * from t",
|
|
testkit.Rows("-100", "1", "2", "3"),
|
|
},
|
|
{
|
|
"select * from t where a = 1",
|
|
testkit.Rows("1"),
|
|
},
|
|
{
|
|
"select * from t where a != 1",
|
|
testkit.Rows("-100", "2", "3"),
|
|
},
|
|
{
|
|
"select * from t where a >= '1.1'",
|
|
testkit.Rows("2", "3"),
|
|
},
|
|
{
|
|
"select * from t where a < '1.1'",
|
|
testkit.Rows("-100", "1"),
|
|
},
|
|
{
|
|
"select * from t where a > '-100.1' and a < 2",
|
|
testkit.Rows("-100", "1"),
|
|
},
|
|
{
|
|
"select * from t where a is null",
|
|
testkit.Rows(),
|
|
}, {
|
|
"select * from t where a is true",
|
|
testkit.Rows("-100", "1", "2", "3"),
|
|
}, {
|
|
"select * from t where a is false",
|
|
testkit.Rows(),
|
|
},
|
|
{
|
|
"select * from t where a in (1, 2)",
|
|
testkit.Rows("1", "2"),
|
|
},
|
|
{
|
|
"select * from t where a between 1 and 2",
|
|
testkit.Rows("1", "2"),
|
|
},
|
|
}
|
|
|
|
for _, ca := range cases {
|
|
result := tk.MustQuery(ca.sql)
|
|
result.Check(ca.result)
|
|
}
|
|
}
|
|
|
|
func (s *testSuite) TestJoin(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (c int)")
|
|
tk.MustExec("insert t values (1)")
|
|
cases := []struct {
|
|
sql string
|
|
result [][]interface{}
|
|
}{
|
|
{
|
|
"select 1 from t as a left join t as b on 0",
|
|
testkit.Rows("1"),
|
|
},
|
|
{
|
|
"select 1 from t as a join t as b on 1",
|
|
testkit.Rows("1"),
|
|
},
|
|
}
|
|
for _, ca := range cases {
|
|
result := tk.MustQuery(ca.sql)
|
|
result.Check(ca.result)
|
|
}
|
|
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("drop table if exists t1")
|
|
tk.MustExec("create table t(c1 int, c2 int)")
|
|
tk.MustExec("create table t1(c1 int, c2 int)")
|
|
tk.MustExec("insert into t values(1,1),(2,2)")
|
|
tk.MustExec("insert into t1 values(2,3),(4,4)")
|
|
result := tk.MustQuery("select * from t left outer join t1 on t.c1 = t1.c1 where t.c1 = 1 or t1.c2 > 20")
|
|
result.Check(testkit.Rows("1 1 <nil> <nil>"))
|
|
result = tk.MustQuery("select * from t1 right outer join t on t.c1 = t1.c1 where t.c1 = 1 or t1.c2 > 20")
|
|
result.Check(testkit.Rows("<nil> <nil> 1 1"))
|
|
result = tk.MustQuery("select * from t right outer join t1 on t.c1 = t1.c1 where t.c1 = 1 or t1.c2 > 20")
|
|
result.Check(testkit.Rows())
|
|
result = tk.MustQuery("select * from t left outer join t1 on t.c1 = t1.c1 where t1.c1 = 3 or false")
|
|
result.Check(testkit.Rows())
|
|
result = tk.MustQuery("select * from t left outer join t1 on t.c1 = t1.c1 and t.c1 != 1 order by t1.c1")
|
|
result.Check(testkit.Rows("1 1 <nil> <nil>", "2 2 2 3"))
|
|
|
|
tk.MustExec("drop table if exists t1")
|
|
tk.MustExec("drop table if exists t2")
|
|
tk.MustExec("drop table if exists t3")
|
|
|
|
tk.MustExec("create table t1 (c1 int, c2 int)")
|
|
tk.MustExec("create table t2 (c1 int, c2 int)")
|
|
tk.MustExec("create table t3 (c1 int, c2 int)")
|
|
|
|
tk.MustExec("insert into t1 values (1,1), (2,2), (3,3)")
|
|
tk.MustExec("insert into t2 values (1,1), (3,3), (5,5)")
|
|
tk.MustExec("insert into t3 values (1,1), (5,5), (9,9)")
|
|
|
|
result = tk.MustQuery("select * from t1 left join t2 on t1.c1 = t2.c1 right join t3 on t2.c1 = t3.c1 order by t1.c1, t1.c2, t2.c1, t2.c2, t3.c1, t3.c2;")
|
|
result.Check(testkit.Rows("<nil> <nil> <nil> <nil> 5 5", "<nil> <nil> <nil> <nil> 9 9", "1 1 1 1 1 1"))
|
|
|
|
tk.MustExec("drop table if exists t1")
|
|
tk.MustExec("create table t1 (c1 int)")
|
|
tk.MustExec("insert into t1 values (1), (1), (1)")
|
|
result = tk.MustQuery("select * from t1 a join t1 b on a.c1 = b.c1;")
|
|
result.Check(testkit.Rows("1 1", "1 1", "1 1", "1 1", "1 1", "1 1", "1 1", "1 1", "1 1"))
|
|
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("drop table if exists t1")
|
|
tk.MustExec("create table t(c1 int,c2 double)")
|
|
tk.MustExec("create table t1(c1 double,c2 int)")
|
|
tk.MustExec("insert into t values (1, 2), (1, NULL)")
|
|
tk.MustExec("insert into t1 values (1, 2), (1, NULL)")
|
|
result = tk.MustQuery("select * from t a , t1 b where (a.c1, a.c2) = (b.c1, b.c2);")
|
|
result.Check(testkit.Rows("1 2 1 2"))
|
|
|
|
}
|
|
|
|
func (s *testSuite) TestMultiJoin(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t35(a35 int primary key, b35 int, x35 int)")
|
|
tk.MustExec("create table t40(a40 int primary key, b40 int, x40 int)")
|
|
tk.MustExec("create table t14(a14 int primary key, b14 int, x14 int)")
|
|
tk.MustExec("create table t42(a42 int primary key, b42 int, x42 int)")
|
|
tk.MustExec("create table t15(a15 int primary key, b15 int, x15 int)")
|
|
tk.MustExec("create table t7(a7 int primary key, b7 int, x7 int)")
|
|
tk.MustExec("create table t64(a64 int primary key, b64 int, x64 int)")
|
|
tk.MustExec("create table t19(a19 int primary key, b19 int, x19 int)")
|
|
tk.MustExec("create table t9(a9 int primary key, b9 int, x9 int)")
|
|
tk.MustExec("create table t8(a8 int primary key, b8 int, x8 int)")
|
|
tk.MustExec("create table t57(a57 int primary key, b57 int, x57 int)")
|
|
tk.MustExec("create table t37(a37 int primary key, b37 int, x37 int)")
|
|
tk.MustExec("create table t44(a44 int primary key, b44 int, x44 int)")
|
|
tk.MustExec("create table t38(a38 int primary key, b38 int, x38 int)")
|
|
tk.MustExec("create table t18(a18 int primary key, b18 int, x18 int)")
|
|
tk.MustExec("create table t62(a62 int primary key, b62 int, x62 int)")
|
|
tk.MustExec("create table t4(a4 int primary key, b4 int, x4 int)")
|
|
tk.MustExec("create table t48(a48 int primary key, b48 int, x48 int)")
|
|
tk.MustExec("create table t31(a31 int primary key, b31 int, x31 int)")
|
|
tk.MustExec("create table t16(a16 int primary key, b16 int, x16 int)")
|
|
tk.MustExec("create table t12(a12 int primary key, b12 int, x12 int)")
|
|
tk.MustExec("insert into t35 values(1,1,1)")
|
|
tk.MustExec("insert into t40 values(1,1,1)")
|
|
tk.MustExec("insert into t14 values(1,1,1)")
|
|
tk.MustExec("insert into t42 values(1,1,1)")
|
|
tk.MustExec("insert into t15 values(1,1,1)")
|
|
tk.MustExec("insert into t7 values(1,1,1)")
|
|
tk.MustExec("insert into t64 values(1,1,1)")
|
|
tk.MustExec("insert into t19 values(1,1,1)")
|
|
tk.MustExec("insert into t9 values(1,1,1)")
|
|
tk.MustExec("insert into t8 values(1,1,1)")
|
|
tk.MustExec("insert into t57 values(1,1,1)")
|
|
tk.MustExec("insert into t37 values(1,1,1)")
|
|
tk.MustExec("insert into t44 values(1,1,1)")
|
|
tk.MustExec("insert into t38 values(1,1,1)")
|
|
tk.MustExec("insert into t18 values(1,1,1)")
|
|
tk.MustExec("insert into t62 values(1,1,1)")
|
|
tk.MustExec("insert into t4 values(1,1,1)")
|
|
tk.MustExec("insert into t48 values(1,1,1)")
|
|
tk.MustExec("insert into t31 values(1,1,1)")
|
|
tk.MustExec("insert into t16 values(1,1,1)")
|
|
tk.MustExec("insert into t12 values(1,1,1)")
|
|
tk.MustExec("insert into t35 values(7,7,7)")
|
|
tk.MustExec("insert into t40 values(7,7,7)")
|
|
tk.MustExec("insert into t14 values(7,7,7)")
|
|
tk.MustExec("insert into t42 values(7,7,7)")
|
|
tk.MustExec("insert into t15 values(7,7,7)")
|
|
tk.MustExec("insert into t7 values(7,7,7)")
|
|
tk.MustExec("insert into t64 values(7,7,7)")
|
|
tk.MustExec("insert into t19 values(7,7,7)")
|
|
tk.MustExec("insert into t9 values(7,7,7)")
|
|
tk.MustExec("insert into t8 values(7,7,7)")
|
|
tk.MustExec("insert into t57 values(7,7,7)")
|
|
tk.MustExec("insert into t37 values(7,7,7)")
|
|
tk.MustExec("insert into t44 values(7,7,7)")
|
|
tk.MustExec("insert into t38 values(7,7,7)")
|
|
tk.MustExec("insert into t18 values(7,7,7)")
|
|
tk.MustExec("insert into t62 values(7,7,7)")
|
|
tk.MustExec("insert into t4 values(7,7,7)")
|
|
tk.MustExec("insert into t48 values(7,7,7)")
|
|
tk.MustExec("insert into t31 values(7,7,7)")
|
|
tk.MustExec("insert into t16 values(7,7,7)")
|
|
tk.MustExec("insert into t12 values(7,7,7)")
|
|
result := tk.MustQuery(`SELECT x4,x8,x38,x44,x31,x9,x57,x48,x19,x40,x14,x12,x7,x64,x37,x18,x62,x35,x42,x15,x16 FROM
|
|
t35,t40,t14,t42,t15,t7,t64,t19,t9,t8,t57,t37,t44,t38,t18,t62,t4,t48,t31,t16,t12
|
|
WHERE b48=a57
|
|
AND a4=b19
|
|
AND a14=b16
|
|
AND b37=a48
|
|
AND a40=b42
|
|
AND a31=7
|
|
AND a15=b40
|
|
AND a38=b8
|
|
AND b15=a31
|
|
AND b64=a18
|
|
AND b12=a44
|
|
AND b7=a8
|
|
AND b35=a16
|
|
AND a12=b14
|
|
AND a64=b57
|
|
AND b62=a7
|
|
AND a35=b38
|
|
AND b9=a19
|
|
AND a62=b18
|
|
AND b4=a37
|
|
AND b44=a42`)
|
|
result.Check(testkit.Rows("7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7"))
|
|
}
|
|
|
|
func (s *testSuite) TestIndexScan(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a int unique)")
|
|
tk.MustExec("insert t values (-1), (2), (3), (5), (6), (7), (8), (9)")
|
|
result := tk.MustQuery("select a from t where a < 0 or (a >= 2.1 and a < 5.1) or ( a > 5.9 and a <= 7.9) or a > '8.1'")
|
|
result.Check(testkit.Rows("-1", "3", "5", "6", "7", "9"))
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a int unique)")
|
|
tk.MustExec("insert t values (0)")
|
|
result = tk.MustQuery("select NULL from t ")
|
|
result.Check(testkit.Rows("<nil>"))
|
|
}
|
|
|
|
func (s *testSuite) TestSubquerySameTable(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a int)")
|
|
tk.MustExec("insert t values (1), (2)")
|
|
result := tk.MustQuery("select a from t where exists(select 1 from t as x where x.a < t.a)")
|
|
result.Check(testkit.Rows("2"))
|
|
result = tk.MustQuery("select a from t where not exists(select 1 from t as x where x.a < t.a)")
|
|
result.Check(testkit.Rows("1"))
|
|
}
|
|
|
|
func (s *testSuite) TestIndexReverseOrder(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a int primary key auto_increment, b int, index idx (b))")
|
|
tk.MustExec("insert t (b) values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)")
|
|
result := tk.MustQuery("select b from t order by b desc")
|
|
result.Check(testkit.Rows("9", "8", "7", "6", "5", "4", "3", "2", "1", "0"))
|
|
result = tk.MustQuery("select b from t where b <3 or (b >=6 and b < 8) order by b desc")
|
|
result.Check(testkit.Rows("7", "6", "2", "1", "0"))
|
|
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a int, b int, index idx (b, a))")
|
|
tk.MustExec("insert t values (0, 2), (1, 2), (2, 2), (0, 1), (1, 1), (2, 1), (0, 0), (1, 0), (2, 0)")
|
|
result = tk.MustQuery("select b, a from t order by b, a desc")
|
|
result.Check(testkit.Rows("0 2", "0 1", "0 0", "1 2", "1 1", "1 0", "2 2", "2 1", "2 0"))
|
|
}
|
|
|
|
func (s *testSuite) TestTableReverseOrder(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a int primary key auto_increment, b int)")
|
|
tk.MustExec("insert t (b) values (1), (2), (3), (4), (5), (6), (7), (8), (9)")
|
|
result := tk.MustQuery("select b from t order by a desc")
|
|
result.Check(testkit.Rows("9", "8", "7", "6", "5", "4", "3", "2", "1"))
|
|
result = tk.MustQuery("select a from t where a <3 or (a >=6 and a < 8) order by a desc")
|
|
result.Check(testkit.Rows("7", "6", "2", "1"))
|
|
}
|
|
|
|
func (s *testSuite) TestInSubquery(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a int, b int)")
|
|
tk.MustExec("insert t values (1, 1), (2, 1)")
|
|
result := tk.MustQuery("select m1.a from t as m1 where m1.a in (select m2.b from t as m2)")
|
|
result.Check(testkit.Rows("1"))
|
|
result = tk.MustQuery("select m1.a from t as m1 where (3, m1.b) not in (select * from t as m2)")
|
|
result.Check(testkit.Rows("1", "2"))
|
|
result = tk.MustQuery("select m1.a from t as m1 where m1.a in (select m2.b+? from t as m2)", 1)
|
|
result.Check(testkit.Rows("2"))
|
|
tk.MustExec(`prepare stmt1 from 'select m1.a from t as m1 where m1.a in (select m2.b+? from t as m2)'`)
|
|
tk.MustExec("set @a = 1")
|
|
result = tk.MustQuery(`execute stmt1 using @a;`)
|
|
result.Check(testkit.Rows("2"))
|
|
tk.MustExec("set @a = 0")
|
|
result = tk.MustQuery(`execute stmt1 using @a;`)
|
|
result.Check(testkit.Rows("1"))
|
|
|
|
result = tk.MustQuery("select m1.a from t as m1 where m1.a in (1, 3, 5)")
|
|
result.Check(testkit.Rows("1"))
|
|
|
|
tk.MustExec("drop table if exists t1")
|
|
tk.MustExec("create table t1 (a float)")
|
|
tk.MustExec("insert t1 values (281.37)")
|
|
tk.MustQuery("select a from t1 where (a in (select a from t1))").Check(testkit.Rows("281.37"))
|
|
}
|
|
|
|
func (s *testSuite) TestDefaultNull(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a int primary key auto_increment, b int default 1, c int)")
|
|
tk.MustExec("insert t values ()")
|
|
tk.MustQuery("select * from t").Check(testkit.Rows("1 1 <nil>"))
|
|
tk.MustExec("update t set b = NULL where a = 1")
|
|
tk.MustQuery("select * from t").Check(testkit.Rows("1 <nil> <nil>"))
|
|
tk.MustExec("update t set c = 1")
|
|
tk.MustQuery("select * from t ").Check(testkit.Rows("1 <nil> 1"))
|
|
tk.MustExec("delete from t where a = 1")
|
|
tk.MustExec("insert t (a) values (1)")
|
|
tk.MustQuery("select * from t").Check(testkit.Rows("1 1 <nil>"))
|
|
}
|
|
|
|
func (s *testSuite) TestUnsignedPKColumn(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a int unsigned primary key, b int, c int, key idx_ba (b, c, a));")
|
|
tk.MustExec("insert t values (1, 1, 1)")
|
|
result := tk.MustQuery("select * from t;")
|
|
result.Check(testkit.Rows("1 1 1"))
|
|
tk.MustExec("update t set c=2 where a=1;")
|
|
result = tk.MustQuery("select * from t where b=1;")
|
|
result.Check(testkit.Rows("1 1 2"))
|
|
}
|
|
|
|
func (s *testSuite) TestDirtyTransaction(c *C) {
|
|
defer testleak.AfterTest(c)
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a int primary key, b int, index idx_b (b));")
|
|
tk.MustExec("insert t value (2, 3), (4, 8), (6, 8)")
|
|
tk.MustExec("begin")
|
|
tk.MustQuery("select * from t").Check(testkit.Rows("2 3", "4 8", "6 8"))
|
|
tk.MustExec("insert t values (1, 5), (3, 4), (7, 6)")
|
|
tk.MustQuery("select * from t").Check(testkit.Rows("1 5", "2 3", "3 4", "4 8", "6 8", "7 6"))
|
|
tk.MustQuery("select * from t where a = 1").Check(testkit.Rows("1 5"))
|
|
tk.MustQuery("select * from t order by a desc").Check(testkit.Rows("7 6", "6 8", "4 8", "3 4", "2 3", "1 5"))
|
|
tk.MustQuery("select * from t order by b, a").Check(testkit.Rows("2 3", "3 4", "1 5", "7 6", "4 8", "6 8"))
|
|
tk.MustQuery("select * from t order by b desc, a desc").Check(testkit.Rows("6 8", "4 8", "7 6", "1 5", "3 4", "2 3"))
|
|
tk.MustQuery("select b from t where b = 8 order by b desc").Check(testkit.Rows("8", "8"))
|
|
// Delete a snapshot row and a dirty row.
|
|
tk.MustExec("delete from t where a = 2 or a = 3")
|
|
tk.MustQuery("select * from t").Check(testkit.Rows("1 5", "4 8", "6 8", "7 6"))
|
|
tk.MustQuery("select * from t order by a desc").Check(testkit.Rows("7 6", "6 8", "4 8", "1 5"))
|
|
tk.MustQuery("select * from t order by b, a").Check(testkit.Rows("1 5", "7 6", "4 8", "6 8"))
|
|
tk.MustQuery("select * from t order by b desc, a desc").Check(testkit.Rows("6 8", "4 8", "7 6", "1 5"))
|
|
// Add deleted row back.
|
|
tk.MustExec("insert t values (2, 3), (3, 4)")
|
|
tk.MustQuery("select * from t").Check(testkit.Rows("1 5", "2 3", "3 4", "4 8", "6 8", "7 6"))
|
|
tk.MustQuery("select * from t order by a desc").Check(testkit.Rows("7 6", "6 8", "4 8", "3 4", "2 3", "1 5"))
|
|
tk.MustQuery("select * from t order by b, a").Check(testkit.Rows("2 3", "3 4", "1 5", "7 6", "4 8", "6 8"))
|
|
tk.MustQuery("select * from t order by b desc, a desc").Check(testkit.Rows("6 8", "4 8", "7 6", "1 5", "3 4", "2 3"))
|
|
// Truncate Table
|
|
tk.MustExec("truncate table t")
|
|
tk.MustQuery("select * from t").Check(testkit.Rows())
|
|
tk.MustExec("insert t values (1, 2)")
|
|
tk.MustQuery("select * from t").Check(testkit.Rows("1 2"))
|
|
tk.MustExec("truncate table t")
|
|
tk.MustExec("insert t values (3, 4)")
|
|
tk.MustQuery("select * from t").Check(testkit.Rows("3 4"))
|
|
tk.Exec("abort")
|
|
}
|
|
|
|
func (s *testSuite) TestBuiltin(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
|
|
// for is true
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a int, b int, index idx_b (b))")
|
|
tk.MustExec("insert t values (1, 1)")
|
|
tk.MustExec("insert t values (2, 2)")
|
|
tk.MustExec("insert t values (3, 2)")
|
|
result := tk.MustQuery("select * from t where b is true")
|
|
result.Check(testkit.Rows("1 1", "2 2", "3 2"))
|
|
result = tk.MustQuery("select all + a from t where a = 1")
|
|
result.Check(testkit.Rows("1"))
|
|
result = tk.MustQuery("select * from t where a is false")
|
|
result.Check(nil)
|
|
result = tk.MustQuery("select * from t where a is not true")
|
|
result.Check(nil)
|
|
// for in
|
|
result = tk.MustQuery("select * from t where b in (a)")
|
|
result.Check(testkit.Rows("1 1", "2 2"))
|
|
result = tk.MustQuery("select * from t where b not in (a)")
|
|
result.Check(testkit.Rows("3 2"))
|
|
|
|
// test cast
|
|
result = tk.MustQuery("select cast(1 as decimal(1,2))")
|
|
result.Check(testkit.Rows("1.00"))
|
|
result = tk.MustQuery("select cast('1991-09-05 11:11:11' as datetime)")
|
|
result.Check(testkit.Rows("1991-09-05 11:11:11"))
|
|
result = tk.MustQuery("select cast(cast('1991-09-05 11:11:11' as datetime) as char)")
|
|
result.Check(testkit.Rows("1991-09-05 11:11:11"))
|
|
result = tk.MustQuery("select cast('11:11:11' as time)")
|
|
result.Check(testkit.Rows("11:11:11"))
|
|
|
|
// for case
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a varchar(255), b int)")
|
|
tk.MustExec("insert t values ('str1', 1)")
|
|
result = tk.MustQuery("select * from t where a = case b when 1 then 'str1' when 2 then 'str2' end")
|
|
rowStr1 := fmt.Sprintf("%v %v", []byte("str1"), "1")
|
|
result.Check(testkit.Rows(rowStr1))
|
|
result = tk.MustQuery("select * from t where a = case b when 1 then 'str2' when 2 then 'str3' end")
|
|
result.Check(nil)
|
|
tk.MustExec("insert t values ('str2', 2)")
|
|
result = tk.MustQuery("select * from t where a = case b when 2 then 'str2' when 3 then 'str3' end")
|
|
rowStr2 := fmt.Sprintf("%v %v", []byte("str2"), "2")
|
|
result.Check(testkit.Rows(rowStr2))
|
|
tk.MustExec("insert t values ('str3', 3)")
|
|
result = tk.MustQuery("select * from t where a = case b when 4 then 'str4' when 5 then 'str5' else 'str3' end")
|
|
rowStr3 := fmt.Sprintf("%v %v", []byte("str3"), "3")
|
|
result.Check(testkit.Rows(rowStr3))
|
|
result = tk.MustQuery("select * from t where a = case b when 4 then 'str4' when 5 then 'str5' else 'str6' end")
|
|
result.Check(nil)
|
|
result = tk.MustQuery("select * from t where a = case when b then 'str3' when 1 then 'str1' else 'str2' end")
|
|
result.Check(testkit.Rows(rowStr3))
|
|
tk.MustExec("delete from t")
|
|
tk.MustExec("insert t values ('str2', 0)")
|
|
result = tk.MustQuery("select * from t where a = case when b then 'str3' when 0 then 'str1' else 'str2' end")
|
|
rowStr2 = fmt.Sprintf("%v %v", []byte("str2"), "0")
|
|
result.Check(testkit.Rows(rowStr2))
|
|
tk.MustExec("insert t values ('str1', null)")
|
|
result = tk.MustQuery("select * from t where a = case b when null then 'str3' when 10 then 'str1' else 'str2' end")
|
|
result.Check(testkit.Rows(rowStr2))
|
|
result = tk.MustQuery("select * from t where a = case null when b then 'str3' when 10 then 'str1' else 'str2' end")
|
|
result.Check(testkit.Rows(rowStr2))
|
|
|
|
// for like and regexp
|
|
type testCase struct {
|
|
pattern string
|
|
val string
|
|
result int
|
|
}
|
|
patternMatching := func(c *C, tk *testkit.TestKit, queryOp string, data []testCase) {
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a varchar(255), b int)")
|
|
for i, d := range data {
|
|
tk.MustExec(fmt.Sprintf("insert into t values('%s', %d)", d.val, i))
|
|
result := tk.MustQuery(fmt.Sprintf("select * from t where a %s '%s'", queryOp, d.pattern))
|
|
if d.result == 1 {
|
|
rowStr := fmt.Sprintf("%v %d", []byte(d.val), i)
|
|
result.Check(testkit.Rows(rowStr))
|
|
} else {
|
|
result.Check(nil)
|
|
}
|
|
tk.MustExec(fmt.Sprintf("delete from t where b = %d", i))
|
|
}
|
|
}
|
|
// for like
|
|
testCases := []testCase{
|
|
{"a", "a", 1},
|
|
{"a", "b", 0},
|
|
{"aA", "Aa", 1},
|
|
{"aA%", "aAab", 1},
|
|
{"aA_", "Aaab", 0},
|
|
{"aA_", "Aab", 1},
|
|
{"", "", 1},
|
|
{"", "a", 0},
|
|
}
|
|
patternMatching(c, tk, "like", testCases)
|
|
// for regexp
|
|
testCases = []testCase{
|
|
{"^$", "a", 0},
|
|
{"a", "a", 1},
|
|
{"a", "b", 0},
|
|
{"aA", "aA", 1},
|
|
{".", "a", 1},
|
|
{"^.$", "ab", 0},
|
|
{"..", "b", 0},
|
|
{".ab", "aab", 1},
|
|
{"ab.", "abcd", 1},
|
|
{".*", "abcd", 1},
|
|
}
|
|
patternMatching(c, tk, "regexp", testCases)
|
|
}
|
|
|
|
func (s *testSuite) TestToPBExpr(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a decimal(10,6), b decimal, index idx_b (b))")
|
|
tk.MustExec("insert t values (1.1, 1.1)")
|
|
tk.MustExec("insert t values (2.4, 2.4)")
|
|
tk.MustExec("insert t values (3.3, 2.7)")
|
|
result := tk.MustQuery("select * from t where a < 2.399999")
|
|
result.Check(testkit.Rows("1.100000 1"))
|
|
result = tk.MustQuery("select * from t where a > 1.5")
|
|
result.Check(testkit.Rows("2.400000 2", "3.300000 3"))
|
|
result = tk.MustQuery("select * from t where a <= 1.1")
|
|
result.Check(testkit.Rows("1.100000 1"))
|
|
result = tk.MustQuery("select * from t where b >= 3")
|
|
result.Check(testkit.Rows("3.300000 3"))
|
|
result = tk.MustQuery("select * from t where not (b = 1)")
|
|
result.Check(testkit.Rows("2.400000 2", "3.300000 3"))
|
|
// TODO: This test cannot pass temporarily, because local store doesn't support decimal correctly.
|
|
//result = tk.MustQuery("select * from t where b&1 = a|1")
|
|
//result.Check(testkit.Rows("1.100000 1"))
|
|
result = tk.MustQuery("select * from t where b != 2 and b <=> 3")
|
|
result.Check(testkit.Rows("3.300000 3"))
|
|
result = tk.MustQuery("select * from t where b in (3)")
|
|
result.Check(testkit.Rows("3.300000 3"))
|
|
result = tk.MustQuery("select * from t where b not in (1, 2)")
|
|
result.Check(testkit.Rows("3.300000 3"))
|
|
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a varchar(255), b int)")
|
|
tk.MustExec("insert t values ('abc123', 1)")
|
|
tk.MustExec("insert t values ('ab123', 2)")
|
|
result = tk.MustQuery("select * from t where a like 'ab%'")
|
|
rowStr0 := fmt.Sprintf("%v %v", []byte("abc123"), "1")
|
|
rowStr1 := fmt.Sprintf("%v %v", []byte("ab123"), "2")
|
|
result.Check(testkit.Rows(rowStr0, rowStr1))
|
|
result = tk.MustQuery("select * from t where a like 'ab_12'")
|
|
result.Check(nil)
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a int primary key)")
|
|
tk.MustExec("insert t values (1)")
|
|
tk.MustExec("insert t values (2)")
|
|
result = tk.MustQuery("select * from t where not (a = 1)")
|
|
result.Check(testkit.Rows("2"))
|
|
result = tk.MustQuery("select * from t where not(not (a = 1))")
|
|
result.Check(testkit.Rows("1"))
|
|
result = tk.MustQuery("select * from t where not(a != 1 and a != 2)")
|
|
result.Check(testkit.Rows("1", "2"))
|
|
}
|
|
|
|
func (s *testSuite) TestDatumXAPI(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a decimal(10,6), b decimal, index idx_b (b))")
|
|
tk.MustExec("insert t values (1.1, 1.1)")
|
|
tk.MustExec("insert t values (2.2, 2.2)")
|
|
tk.MustExec("insert t values (3.3, 2.7)")
|
|
result := tk.MustQuery("select * from t where a > 1.5")
|
|
result.Check(testkit.Rows("2.200000 2", "3.300000 3"))
|
|
result = tk.MustQuery("select * from t where b > 1.5")
|
|
result.Check(testkit.Rows("2.200000 2", "3.300000 3"))
|
|
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a time(3), b time, index idx_a (a))")
|
|
tk.MustExec("insert t values ('11:11:11', '11:11:11')")
|
|
tk.MustExec("insert t values ('11:11:12', '11:11:12')")
|
|
tk.MustExec("insert t values ('11:11:13', '11:11:13')")
|
|
result = tk.MustQuery("select * from t where a > '11:11:11.5'")
|
|
result.Check(testkit.Rows("11:11:12 11:11:12", "11:11:13 11:11:13"))
|
|
result = tk.MustQuery("select * from t where b > '11:11:11.5'")
|
|
result.Check(testkit.Rows("11:11:12 11:11:12", "11:11:13 11:11:13"))
|
|
}
|
|
|
|
func (s *testSuite) TestJoinPanic(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists events")
|
|
tk.MustExec("create table events (clock int, source int)")
|
|
tk.MustQuery("SELECT * FROM events e JOIN (SELECT MAX(clock) AS clock FROM events e2 GROUP BY e2.source) e3 ON e3.clock=e.clock")
|
|
}
|
|
|
|
func (s *testSuite) TestSQLMode(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (a tinyint not null)")
|
|
tk.MustExec("set sql_mode = 'STRICT_TRANS_TABLES'")
|
|
_, err := tk.Exec("insert t values ()")
|
|
c.Check(err, NotNil)
|
|
|
|
_, err = tk.Exec("insert t values ('1000')")
|
|
c.Check(err, NotNil)
|
|
|
|
tk.MustExec("set sql_mode = ''")
|
|
tk.MustExec("insert t values ()")
|
|
tk.MustExec("insert t values (1000)")
|
|
tk.MustQuery("select * from t").Check(testkit.Rows("0", "127"))
|
|
}
|
|
|
|
func (s *testSuite) TestNewSubquery(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (c int, d int)")
|
|
tk.MustExec("insert t values (1, 1)")
|
|
tk.MustExec("insert t values (2, 2)")
|
|
tk.MustExec("insert t values (3, 4)")
|
|
tk.MustExec("commit")
|
|
result := tk.MustQuery("select * from t where exists(select * from t k where t.c = k.c having sum(c) = 1)")
|
|
result.Check(testkit.Rows("1 1"))
|
|
result = tk.MustQuery("select * from t where exists(select k.c, k.d from t k, t p where t.c = k.d)")
|
|
result.Check(testkit.Rows("1 1", "2 2"))
|
|
result = tk.MustQuery("select 1 = (select count(*) from t where t.c = k.d) from t k")
|
|
result.Check(testkit.Rows("1", "1", "0"))
|
|
result = tk.MustQuery("select 1 = (select count(*) from t where exists( select * from t m where t.c = k.d)) from t k")
|
|
result.Check(testkit.Rows("1", "1", "0"))
|
|
result = tk.MustQuery("select t.c = any (select count(*) from t) from t")
|
|
result.Check(testkit.Rows("0", "0", "1"))
|
|
result = tk.MustQuery("select * from t where (t.c, 6) = any (select count(*), sum(t.c) from t)")
|
|
result.Check(testkit.Rows("3 4"))
|
|
result = tk.MustQuery("select t.c from t where (t.c) < all (select count(*) from t)")
|
|
result.Check(testkit.Rows("1", "2"))
|
|
result = tk.MustQuery("select t.c from t where (t.c, t.d) = any (select * from t)")
|
|
result.Check(testkit.Rows("1", "2", "3"))
|
|
result = tk.MustQuery("select t.c from t where (t.c, t.d) != all (select * from t)")
|
|
result.Check(testkit.Rows())
|
|
result = tk.MustQuery("select (select count(*) from t where t.c = k.d) from t k")
|
|
result.Check(testkit.Rows("1", "1", "0"))
|
|
result = tk.MustQuery("select t.c from t where (t.c, t.d) in (select * from t)")
|
|
result.Check(testkit.Rows("1", "2", "3"))
|
|
result = tk.MustQuery("select t.c from t where (t.c, t.d) not in (select * from t)")
|
|
result.Check(testkit.Rows())
|
|
// = all empty set is true
|
|
result = tk.MustQuery("select t.c from t where (t.c, t.d) != all (select * from t where d > 1000)")
|
|
result.Check(testkit.Rows("1", "2", "3"))
|
|
result = tk.MustQuery("select t.c from t where (t.c) < any (select c from t where d > 1000)")
|
|
result.Check(testkit.Rows())
|
|
tk.MustExec("insert t values (NULL, NULL)")
|
|
result = tk.MustQuery("select (t.c) < any (select c from t) from t")
|
|
result.Check(testkit.Rows("1", "1", "<nil>", "<nil>"))
|
|
result = tk.MustQuery("select (10) > all (select c from t) from t")
|
|
result.Check(testkit.Rows("<nil>", "<nil>", "<nil>", "<nil>"))
|
|
result = tk.MustQuery("select (c) > all (select c from t) from t")
|
|
result.Check(testkit.Rows("0", "0", "0", "<nil>"))
|
|
|
|
tk.MustExec("drop table if exists a")
|
|
tk.MustExec("create table a (c int, d int)")
|
|
tk.MustExec("insert a values (1, 2)")
|
|
tk.MustExec("drop table if exists b")
|
|
tk.MustExec("create table b (c int, d int)")
|
|
tk.MustExec("insert b values (2, 1)")
|
|
|
|
result = tk.MustQuery("select * from a b where c = (select d from b a where a.c = 2 and b.c = 1)")
|
|
result.Check(testkit.Rows("1 2"))
|
|
}
|
|
|
|
func (s *testSuite) TestNewTableDual(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
result := tk.MustQuery("Select 1")
|
|
result.Check(testkit.Rows("1"))
|
|
result = tk.MustQuery("Select 1 from dual")
|
|
result.Check(testkit.Rows("1"))
|
|
result = tk.MustQuery("Select count(*) from dual")
|
|
result.Check(testkit.Rows("1"))
|
|
result = tk.MustQuery("Select 1 from dual where 1")
|
|
result.Check(testkit.Rows("1"))
|
|
}
|
|
|
|
func (s *testSuite) TestNewTableScan(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use information_schema")
|
|
result := tk.MustQuery("select * from schemata")
|
|
// There must be these tables: information_schema, mysql, preformance_schema and test.
|
|
c.Assert(len(result.Rows()), GreaterEqual, 4)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("create database mytest")
|
|
rowStr1 := fmt.Sprintf("%s %s %s %s %v", "def", "mysql", "utf8", "utf8_general_ci", nil)
|
|
rowStr2 := fmt.Sprintf("%s %s %s %s %v", "def", "mytest", "utf8", "utf8_general_ci", nil)
|
|
tk.MustExec("use information_schema")
|
|
result = tk.MustQuery("select * from schemata where schema_name = 'mysql'")
|
|
result.Check(testkit.Rows(rowStr1))
|
|
result = tk.MustQuery("select * from schemata where schema_name like 'my%'")
|
|
result.Check(testkit.Rows(rowStr1, rowStr2))
|
|
}
|
|
|
|
func (s *testSuite) TestAggregation(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (c int, d int)")
|
|
tk.MustExec("insert t values (NULL, 1)")
|
|
tk.MustExec("insert t values (1, 1)")
|
|
tk.MustExec("insert t values (1, 2)")
|
|
tk.MustExec("insert t values (1, 3)")
|
|
tk.MustExec("insert t values (1, 1)")
|
|
tk.MustExec("insert t values (3, 2)")
|
|
tk.MustExec("insert t values (4, 3)")
|
|
result := tk.MustQuery("select count(*) from t group by d")
|
|
result.Check(testkit.Rows("3", "2", "2"))
|
|
result = tk.MustQuery("select count(*) from t having 1 = 0")
|
|
result.Check(testkit.Rows())
|
|
result = tk.MustQuery("select - c, c as d from t group by c having null not between c and avg(distinct d) - d")
|
|
result.Check(testkit.Rows())
|
|
result = tk.MustQuery("select - c as c from t group by c having t.c > 5")
|
|
result.Check(testkit.Rows())
|
|
// TODO: This query is reported error in resolver.
|
|
//result := tk.MustQuery("select t1.c from t t1, t t2 group by c having c > 5")
|
|
//result.Check(testkit.Rows())
|
|
result = tk.MustQuery("select count(*) from (select d, c from t) k where d != 0 group by d")
|
|
result.Check(testkit.Rows("3", "2", "2"))
|
|
result = tk.MustQuery("select c as a from t group by d having a < 0")
|
|
result.Check(testkit.Rows())
|
|
result = tk.MustQuery("select c as a from t group by d having sum(a) = 2")
|
|
result.Check(testkit.Rows("<nil>"))
|
|
result = tk.MustQuery("select count(distinct c) from t group by d")
|
|
result.Check(testkit.Rows("1", "2", "2"))
|
|
result = tk.MustQuery("select sum(c) from t group by d")
|
|
result.Check(testkit.Rows("2", "4", "5"))
|
|
result = tk.MustQuery("select d*2 as ee, sum(c) from t group by ee")
|
|
result.Check(testkit.Rows("2 2", "4 4", "6 5"))
|
|
result = tk.MustQuery("select sum(distinct c) from t group by d")
|
|
result.Check(testkit.Rows("1", "4", "5"))
|
|
result = tk.MustQuery("select min(c) from t group by d")
|
|
result.Check(testkit.Rows("1", "1", "1"))
|
|
result = tk.MustQuery("select max(c) from t group by d")
|
|
result.Check(testkit.Rows("1", "3", "4"))
|
|
result = tk.MustQuery("select avg(c) from t group by d")
|
|
result.Check(testkit.Rows("1.0000", "2.0000", "2.5000"))
|
|
result = tk.MustQuery("select d, d + 1 from t group by d")
|
|
result.Check(testkit.Rows("1 2", "2 3", "3 4"))
|
|
result = tk.MustQuery("select count(*) from t")
|
|
result.Check(testkit.Rows("7"))
|
|
result = tk.MustQuery("select count(distinct d) from t")
|
|
result.Check(testkit.Rows("3"))
|
|
result = tk.MustQuery("select count(*) from t group by d having sum(c) > 3")
|
|
result.Check(testkit.Rows("2", "2"))
|
|
result = tk.MustQuery("select max(c) from t group by d having sum(c) > 3 order by avg(c) desc")
|
|
result.Check(testkit.Rows("4", "3"))
|
|
result = tk.MustQuery("select count(*) from t a , t b")
|
|
result.Check(testkit.Rows("49"))
|
|
result = tk.MustQuery("select count(*) from t a join t b having sum(a.c) < 0")
|
|
result.Check(testkit.Rows())
|
|
result = tk.MustQuery("select count(*) from t a join t b where a.c < 0")
|
|
result.Check(testkit.Rows("0"))
|
|
// This two cases prove that having always resolve name from field list firstly.
|
|
result = tk.MustQuery("select 1-d as d from t having d < 0 order by d desc")
|
|
result.Check(testkit.Rows("-1", "-1", "-2", "-2"))
|
|
result = tk.MustQuery("select 1-d as d from t having d + 1 < 0 order by d + 1")
|
|
result.Check(testkit.Rows("-2", "-2"))
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (c int, d int)")
|
|
tk.MustExec("insert t values (1, -1)")
|
|
tk.MustExec("insert t values (1, 0)")
|
|
tk.MustExec("insert t values (1, 1)")
|
|
result = tk.MustQuery("select d, d*d as d from t having d = -1")
|
|
result.Check(testkit.Rows())
|
|
result = tk.MustQuery("select d*d as d from t group by d having d = -1")
|
|
result.Check(testkit.Rows("1"))
|
|
result = tk.MustQuery("select d, 1-d as d, c as d from t order by d")
|
|
result.Check(testkit.Rows("1 0 1", "0 1 1", "-1 2 1"))
|
|
result = tk.MustQuery("select d, 1-d as d, c as d from t order by d+1")
|
|
result.Check(testkit.Rows("-1 2 1", "0 1 1", "1 0 1"))
|
|
result = tk.MustQuery("select d, 1-d as d, c as d from t group by d")
|
|
result.Check(testkit.Rows("-1 2 1", "0 1 1", "1 0 1"))
|
|
result = tk.MustQuery("select d as d1, t.d as d1, 1-d as d1, c as d1 from t having d1 < 10")
|
|
result.Check(testkit.Rows("-1 -1 2 1", "0 0 1 1", "1 1 0 1"))
|
|
result = tk.MustQuery("select d*d as d1, c as d1 from t group by d1")
|
|
result.Check(testkit.Rows("1 1", "0 1"))
|
|
result = tk.MustQuery("select d*d as d1, c as d1 from t group by 2")
|
|
result.Check(testkit.Rows("1 1"))
|
|
result = tk.MustQuery("select * from t group by 2")
|
|
result.Check(testkit.Rows("1 -1", "1 0", "1 1"))
|
|
result = tk.MustQuery("select * , sum(d) from t group by 1")
|
|
result.Check(testkit.Rows("1 -1 0"))
|
|
result = tk.MustQuery("select sum(d), t.* from t group by 2")
|
|
result.Check(testkit.Rows("0 1 -1"))
|
|
result = tk.MustQuery("select d as d, c as d from t group by d + 1")
|
|
result.Check(testkit.Rows("-1 1", "0 1", "1 1"))
|
|
result = tk.MustQuery("select c as d, c as d from t group by d")
|
|
result.Check(testkit.Rows("1 1", "1 1", "1 1"))
|
|
_, err := tk.Exec("select d as d, c as d from t group by d")
|
|
c.Assert(err, NotNil)
|
|
_, err = tk.Exec("select t.d, c as d from t group by d")
|
|
c.Assert(err, NotNil)
|
|
result = tk.MustQuery("select *, c+1 as d from t group by 3")
|
|
result.Check(testkit.Rows("1 -1 2"))
|
|
tk.MustExec("drop table if exists t1")
|
|
tk.MustExec("create table t1(a float, b int default 3)")
|
|
tk.MustExec("insert into t1 (a) values (2), (11), (8)")
|
|
result = tk.MustQuery("select min(a), min(case when 1=1 then a else NULL end), min(case when 1!=1 then NULL else a end) from t1 where b=3 group by b")
|
|
result.Check(testkit.Rows("2 2 2"))
|
|
tk.MustExec("drop table if exists t1")
|
|
tk.MustExec("create table t1(a int, index(a))")
|
|
tk.MustExec("insert into t1 (a) values (1),(2),(3),(4),(5)")
|
|
result = tk.MustQuery("select count(a) from t1 where a < 3")
|
|
result.Check(testkit.Rows("2"))
|
|
}
|
|
|
|
func (s *testSuite) TestAdapterStatement(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
se, err := tidb.CreateSession(s.store)
|
|
c.Check(err, IsNil)
|
|
compiler := &executor.Compiler{}
|
|
ctx := se.(context.Context)
|
|
|
|
stmtNode, err := s.ParseOneStmt("select 1", "", "")
|
|
c.Check(err, IsNil)
|
|
stmt, err := compiler.Compile(ctx, stmtNode)
|
|
c.Check(err, IsNil)
|
|
c.Check(stmt.OriginText(), Equals, "select 1")
|
|
c.Check(stmt.IsDDL(), IsFalse)
|
|
|
|
stmtNode, err = s.ParseOneStmt("create table t (a int)", "", "")
|
|
c.Check(err, IsNil)
|
|
stmt, err = compiler.Compile(ctx, stmtNode)
|
|
c.Check(err, IsNil)
|
|
c.Check(stmt.OriginText(), Equals, "create table t (a int)")
|
|
}
|
|
|
|
func (s *testSuite) TestRow(c *C) {
|
|
defer testleak.AfterTest(c)()
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (c int, d int)")
|
|
tk.MustExec("insert t values (1, 1)")
|
|
tk.MustExec("insert t values (1, 3)")
|
|
tk.MustExec("insert t values (2, 1)")
|
|
tk.MustExec("insert t values (2, 3)")
|
|
result := tk.MustQuery("select * from t where (c, d) < (2,2)")
|
|
result.Check(testkit.Rows("1 1", "1 3", "2 1"))
|
|
result = tk.MustQuery("select * from t where (1,2,3) > (3,2,1)")
|
|
result.Check(testkit.Rows())
|
|
result = tk.MustQuery("select * from t where row(1,2,3) > (3,2,1)")
|
|
result.Check(testkit.Rows())
|
|
result = tk.MustQuery("select * from t where (c, d) = (select * from t where (c,d) = (1,1))")
|
|
result.Check(testkit.Rows("1 1"))
|
|
result = tk.MustQuery("select * from t where (c, d) = (select * from t k where (t.c,t.d) = (c,d))")
|
|
result.Check(testkit.Rows("1 1", "1 3", "2 1", "2 3"))
|
|
}
|
|
|
|
func (s *testSuite) TestColumnName(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (c int, d int)")
|
|
rs, err := tk.Exec("select 1 + c, count(*) from t")
|
|
c.Check(err, IsNil)
|
|
fields, err := rs.Fields()
|
|
c.Check(err, IsNil)
|
|
c.Check(len(fields), Equals, 2)
|
|
c.Check(fields[0].Column.Name.L, Equals, "1 + c")
|
|
c.Check(fields[1].Column.Name.L, Equals, "count(*)")
|
|
rs, err = tk.Exec("select (c) > all (select c from t) from t")
|
|
c.Check(err, IsNil)
|
|
fields, err = rs.Fields()
|
|
c.Check(err, IsNil)
|
|
c.Check(len(fields), Equals, 1)
|
|
c.Check(fields[0].Column.Name.L, Equals, "(c) > all (select c from t)")
|
|
}
|
|
|
|
func (s *testSuite) TestSelectVar(c *C) {
|
|
tk := testkit.NewTestKit(c, s.store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec("create table t (d int)")
|
|
tk.MustExec("insert into t values(1), (2), (1)")
|
|
result := tk.MustQuery("select @a, @a := d+1 from t")
|
|
result.Check(testkit.Rows("<nil> 2", "<nil> 3", "<nil> 2"))
|
|
result = tk.MustQuery("select @a, @a := d+1 from t")
|
|
result.Check(testkit.Rows("2 2", "2 3", "3 2"))
|
|
|
|
}
|