Files
tidb/stmt/stmts/delete_test.go
shenli 3c28357b09 *: Pass context to Compile()
Compile should know context to get current charset info.
2015-10-22 17:09:53 +08:00

207 lines
5.5 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 stmts_test
import (
"database/sql"
"strings"
. "github.com/pingcap/check"
"github.com/pingcap/tidb"
)
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)
// Test compile
stmtList, err := tidb.Compile(s.ctx, "DELETE from test where id = 2;")
c.Assert(err, IsNil)
str := stmtList[0].OriginText()
c.Assert(0, Less, len(str))
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)
// Should use index
strs := s.queryStrings(s.testDB, `explain DELETE from test where id = 2;`, c)
var useIndex bool
for _, str := range strs {
if strings.Index(str, "index") > 0 {
useIndex = true
}
}
if !useIndex {
c.Fatal(strs)
}
// Should not use index
strs = s.queryStrings(s.testDB, `explain DELETE from test;`, c)
useIndex = false
for _, str := range strs {
if strings.Index(str, "index") > 0 {
useIndex = true
}
}
if useIndex {
c.Fatal(strs)
}
}
func (s *testStmtSuite) TestMultiTableDelete(c *C) {
s.fillDataMultiTable(s.testDB, c)
// Test compile
stmtList, err := tidb.Compile(s.ctx, "DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;")
c.Assert(err, IsNil)
str := stmtList[0].OriginText()
c.Assert(0, Less, len(str))
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")
}