495 lines
19 KiB
Go
495 lines
19 KiB
Go
// Copyright 2023 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,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package partitiontest
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/pingcap/failpoint"
|
|
"github.com/pingcap/tidb/testkit"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestPartitionedTableReplace(t *testing.T) {
|
|
failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`)
|
|
defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune")
|
|
store := testkit.CreateMockStore(t)
|
|
tk := testkit.NewTestKit(t, 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)
|
|
partition by range (id) (
|
|
PARTITION p0 VALUES LESS THAN (3),
|
|
PARTITION p1 VALUES LESS THAN (5),
|
|
PARTITION p2 VALUES LESS THAN (7),
|
|
PARTITION p3 VALUES LESS THAN (9));`
|
|
tk.MustExec(testSQL)
|
|
testSQL = `replace replace_test (c1) values (1),(2),(NULL);`
|
|
tk.MustExec(testSQL)
|
|
require.Equal(t, tk.Session().LastMessage(), "Records: 3 Duplicates: 0 Warnings: 0")
|
|
|
|
errReplaceSQL := `replace replace_test (c1) values ();`
|
|
tk.MustExec("begin")
|
|
err := tk.ExecToErr(errReplaceSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
errReplaceSQL = `replace replace_test (c1, c2) values (1,2),(1);`
|
|
tk.MustExec("begin")
|
|
err = tk.ExecToErr(errReplaceSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
errReplaceSQL = `replace replace_test (xxx) values (3);`
|
|
tk.MustExec("begin")
|
|
err = tk.ExecToErr(errReplaceSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
errReplaceSQL = `replace replace_test_xxx (c1) values ();`
|
|
tk.MustExec("begin")
|
|
err = tk.ExecToErr(errReplaceSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
replaceSetSQL := `replace replace_test set c1 = 3;`
|
|
tk.MustExec(replaceSetSQL)
|
|
require.Empty(t, tk.Session().LastMessage())
|
|
|
|
errReplaceSetSQL := `replace replace_test set c1 = 4, c1 = 5;`
|
|
tk.MustExec("begin")
|
|
err = tk.ExecToErr(errReplaceSetSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
errReplaceSetSQL = `replace replace_test set xxx = 6;`
|
|
tk.MustExec("begin")
|
|
err = tk.ExecToErr(errReplaceSetSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
tk.MustExec(`drop table if exists replace_test_1`)
|
|
tk.MustExec(`create table replace_test_1 (id int, c1 int) partition by range (id) (
|
|
PARTITION p0 VALUES LESS THAN (4),
|
|
PARTITION p1 VALUES LESS THAN (6),
|
|
PARTITION p2 VALUES LESS THAN (8),
|
|
PARTITION p3 VALUES LESS THAN (10),
|
|
PARTITION p4 VALUES LESS THAN (100))`)
|
|
tk.MustExec(`replace replace_test_1 select id, c1 from replace_test;`)
|
|
require.Equal(t, tk.Session().LastMessage(), "Records: 4 Duplicates: 0 Warnings: 0")
|
|
|
|
tk.MustExec(`drop table if exists replace_test_2`)
|
|
tk.MustExec(`create table replace_test_2 (id int, c1 int) partition by range (id) (
|
|
PARTITION p0 VALUES LESS THAN (10),
|
|
PARTITION p1 VALUES LESS THAN (50),
|
|
PARTITION p2 VALUES LESS THAN (100),
|
|
PARTITION p3 VALUES LESS THAN (300))`)
|
|
tk.MustExec(`replace replace_test_1 select id, c1 from replace_test union select id * 10, c1 * 10 from replace_test;`)
|
|
require.Equal(t, tk.Session().LastMessage(), "Records: 8 Duplicates: 0 Warnings: 0")
|
|
|
|
errReplaceSelectSQL := `replace replace_test_1 select c1 from replace_test;`
|
|
tk.MustExec("begin")
|
|
err = tk.ExecToErr(errReplaceSelectSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
tk.MustExec(`drop table if exists replace_test_3`)
|
|
replaceUniqueIndexSQL := `create table replace_test_3 (c1 int, c2 int, UNIQUE INDEX (c2)) partition by range (c2) (
|
|
PARTITION p0 VALUES LESS THAN (4),
|
|
PARTITION p1 VALUES LESS THAN (7),
|
|
PARTITION p2 VALUES LESS THAN (11))`
|
|
tk.MustExec(replaceUniqueIndexSQL)
|
|
replaceUniqueIndexSQL = `replace into replace_test_3 set c2=8;`
|
|
tk.MustExec(replaceUniqueIndexSQL)
|
|
replaceUniqueIndexSQL = `replace into replace_test_3 set c2=8;`
|
|
tk.MustExec(replaceUniqueIndexSQL)
|
|
require.Equal(t, int64(1), int64(tk.Session().AffectedRows()))
|
|
require.Empty(t, tk.Session().LastMessage())
|
|
replaceUniqueIndexSQL = `replace into replace_test_3 set c1=8, c2=8;`
|
|
tk.MustExec(replaceUniqueIndexSQL)
|
|
require.Equal(t, int64(2), int64(tk.Session().AffectedRows()))
|
|
require.Empty(t, tk.Session().LastMessage())
|
|
|
|
replaceUniqueIndexSQL = `replace into replace_test_3 set c2=NULL;`
|
|
tk.MustExec(replaceUniqueIndexSQL)
|
|
replaceUniqueIndexSQL = `replace into replace_test_3 set c2=NULL;`
|
|
tk.MustExec(replaceUniqueIndexSQL)
|
|
require.Equal(t, int64(1), int64(tk.Session().AffectedRows()))
|
|
require.Empty(t, tk.Session().LastMessage())
|
|
|
|
replaceUniqueIndexSQL = `create table replace_test_4 (c1 int, c2 int, c3 int, UNIQUE INDEX (c1, c2)) partition by range (c1) (
|
|
PARTITION p0 VALUES LESS THAN (4),
|
|
PARTITION p1 VALUES LESS THAN (7),
|
|
PARTITION p2 VALUES LESS THAN (11));`
|
|
tk.MustExec(`drop table if exists replace_test_4`)
|
|
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)
|
|
require.Equal(t, int64(1), int64(tk.Session().AffectedRows()))
|
|
|
|
replacePrimaryKeySQL := `create table replace_test_5 (c1 int, c2 int, c3 int, PRIMARY KEY (c1, c2)) partition by range (c2) (
|
|
PARTITION p0 VALUES LESS THAN (4),
|
|
PARTITION p1 VALUES LESS THAN (7),
|
|
PARTITION p2 VALUES LESS THAN (11));`
|
|
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)
|
|
require.Equal(t, int64(1), int64(tk.Session().AffectedRows()))
|
|
|
|
issue989SQL := `CREATE TABLE tIssue989 (a int, b int, KEY(a), UNIQUE KEY(b)) partition by range (b) (
|
|
PARTITION p1 VALUES LESS THAN (100),
|
|
PARTITION p2 VALUES LESS THAN (200))`
|
|
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"))
|
|
}
|
|
|
|
func TestHashPartitionedTableReplace(t *testing.T) {
|
|
store := testkit.CreateMockStore(t)
|
|
tk := testkit.NewTestKit(t, store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("set @@session.tidb_enable_table_partition = '1';")
|
|
tk.MustExec("drop table if exists replace_test;")
|
|
testSQL := `create table replace_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 int, c3 int default 1)
|
|
partition by hash(id) partitions 4;`
|
|
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.ExecToErr(errReplaceSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
errReplaceSQL = `replace replace_test (c1, c2) values (1,2),(1);`
|
|
tk.MustExec("begin")
|
|
err = tk.ExecToErr(errReplaceSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
errReplaceSQL = `replace replace_test (xxx) values (3);`
|
|
tk.MustExec("begin")
|
|
err = tk.ExecToErr(errReplaceSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
errReplaceSQL = `replace replace_test_xxx (c1) values ();`
|
|
tk.MustExec("begin")
|
|
err = tk.ExecToErr(errReplaceSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
errReplaceSetSQL := `replace replace_test set c1 = 4, c1 = 5;`
|
|
tk.MustExec("begin")
|
|
err = tk.ExecToErr(errReplaceSetSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
errReplaceSetSQL = `replace replace_test set xxx = 6;`
|
|
tk.MustExec("begin")
|
|
err = tk.ExecToErr(errReplaceSetSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
tk.MustExec(`replace replace_test set c1 = 3;`)
|
|
tk.MustExec(`replace replace_test set c1 = 4;`)
|
|
tk.MustExec(`replace replace_test set c1 = 5;`)
|
|
tk.MustExec(`replace replace_test set c1 = 6;`)
|
|
tk.MustExec(`replace replace_test set c1 = 7;`)
|
|
|
|
tk.MustExec(`drop table if exists replace_test_1`)
|
|
tk.MustExec(`create table replace_test_1 (id int, c1 int) partition by hash(id) partitions 5;`)
|
|
tk.MustExec(`replace replace_test_1 select id, c1 from replace_test;`)
|
|
|
|
tk.MustExec(`drop table if exists replace_test_2`)
|
|
tk.MustExec(`create table replace_test_2 (id int, c1 int) partition by hash(id) partitions 6;`)
|
|
|
|
tk.MustExec(`replace replace_test_1 select id, c1 from replace_test union select id * 10, c1 * 10 from replace_test;`)
|
|
|
|
errReplaceSelectSQL := `replace replace_test_1 select c1 from replace_test;`
|
|
tk.MustExec("begin")
|
|
err = tk.ExecToErr(errReplaceSelectSQL)
|
|
require.Error(t, err)
|
|
tk.MustExec("rollback")
|
|
|
|
tk.MustExec(`drop table if exists replace_test_3`)
|
|
replaceUniqueIndexSQL := `create table replace_test_3 (c1 int, c2 int, UNIQUE INDEX (c2)) partition by hash(c2) partitions 7;`
|
|
tk.MustExec(replaceUniqueIndexSQL)
|
|
|
|
tk.MustExec(`replace into replace_test_3 set c2=8;`)
|
|
tk.MustExec(`replace into replace_test_3 set c2=8;`)
|
|
require.Equal(t, int64(1), int64(tk.Session().AffectedRows()))
|
|
tk.MustExec(`replace into replace_test_3 set c1=8, c2=8;`)
|
|
require.Equal(t, int64(2), int64(tk.Session().AffectedRows()))
|
|
|
|
tk.MustExec(`replace into replace_test_3 set c2=NULL;`)
|
|
tk.MustExec(`replace into replace_test_3 set c2=NULL;`)
|
|
require.Equal(t, int64(1), int64(tk.Session().AffectedRows()))
|
|
|
|
for i := 0; i < 100; i++ {
|
|
sql := fmt.Sprintf("replace into replace_test_3 set c2=%d;", i)
|
|
tk.MustExec(sql)
|
|
}
|
|
result := tk.MustQuery("select count(*) from replace_test_3")
|
|
result.Check(testkit.Rows("102"))
|
|
|
|
replaceUniqueIndexSQL = `create table replace_test_4 (c1 int, c2 int, c3 int, UNIQUE INDEX (c1, c2)) partition by hash(c1) partitions 8;`
|
|
tk.MustExec(`drop table if exists replace_test_4`)
|
|
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)
|
|
require.Equal(t, int64(1), int64(tk.Session().AffectedRows()))
|
|
|
|
replacePrimaryKeySQL := `create table replace_test_5 (c1 int, c2 int, c3 int, PRIMARY KEY (c1, c2)) partition by hash (c2) partitions 9;`
|
|
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)
|
|
require.Equal(t, int64(1), int64(tk.Session().AffectedRows()))
|
|
|
|
issue989SQL := `CREATE TABLE tIssue989 (a int, b int, KEY(a), UNIQUE KEY(b)) partition by hash (b) partitions 10;`
|
|
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"))
|
|
}
|
|
|
|
func TestPartitionedTableUpdate(t *testing.T) {
|
|
failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`)
|
|
defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune")
|
|
store := testkit.CreateMockStore(t)
|
|
tk := testkit.NewTestKit(t, store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec(`create table t (id int not null default 1, name varchar(255))
|
|
PARTITION BY RANGE ( id ) (
|
|
PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION p1 VALUES LESS THAN (11),
|
|
PARTITION p2 VALUES LESS THAN (16),
|
|
PARTITION p3 VALUES LESS THAN (21))`)
|
|
|
|
tk.MustExec(`insert INTO t VALUES (1, "hello");`)
|
|
tk.CheckExecResult(1, 0)
|
|
tk.MustExec(`insert INTO t VALUES (7, "hello");`)
|
|
tk.CheckExecResult(1, 0)
|
|
|
|
// update non partition column
|
|
tk.MustExec(`UPDATE t SET name = "abc" where id > 0;`)
|
|
tk.CheckExecResult(2, 0)
|
|
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 2 Changed: 2 Warnings: 0")
|
|
r := tk.MustQuery(`SELECT * from t order by id limit 2;`)
|
|
r.Check(testkit.Rows("1 abc", "7 abc"))
|
|
|
|
// update partition column
|
|
tk.MustExec(`update t set id = id + 1`)
|
|
tk.CheckExecResult(2, 0)
|
|
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 2 Changed: 2 Warnings: 0")
|
|
r = tk.MustQuery(`SELECT * from t order by id limit 2;`)
|
|
r.Check(testkit.Rows("2 abc", "8 abc"))
|
|
|
|
// update partition column, old and new record locates on different partitions
|
|
tk.MustExec(`update t set id = 20 where id = 8`)
|
|
tk.CheckExecResult(1, 0)
|
|
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
|
|
r = tk.MustQuery(`SELECT * from t order by id limit 2;`)
|
|
r.Check(testkit.Rows("2 abc", "20 abc"))
|
|
|
|
// table option is auto-increment
|
|
tk.MustExec("drop table if exists t;")
|
|
tk.MustExec(`create table t (id int not null auto_increment, name varchar(255), primary key(id))
|
|
PARTITION BY RANGE ( id ) (
|
|
PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION p1 VALUES LESS THAN (11),
|
|
PARTITION p2 VALUES LESS THAN (16),
|
|
PARTITION p3 VALUES LESS THAN (21))`)
|
|
|
|
tk.MustExec("insert into t(name) values ('aa')")
|
|
tk.MustExec("update t set id = 8 where name = 'aa'")
|
|
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
|
|
tk.MustExec("insert into t(name) values ('bb')")
|
|
r = tk.MustQuery("select * from t;")
|
|
r.Check(testkit.Rows("8 aa", "9 bb"))
|
|
|
|
err := tk.ExecToErr("update t set id = null where name = 'aa'")
|
|
require.EqualError(t, err, "[table:1048]Column 'id' cannot be null")
|
|
|
|
// Test that in a transaction, when a constraint failed in an update statement, the record is not inserted.
|
|
tk.MustExec("drop table if exists t;")
|
|
tk.MustExec(`create table t (id int, name int unique)
|
|
PARTITION BY RANGE ( name ) (
|
|
PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION p1 VALUES LESS THAN (11),
|
|
PARTITION p2 VALUES LESS THAN (16),
|
|
PARTITION p3 VALUES LESS THAN (21))`)
|
|
tk.MustExec("insert t values (1, 1), (2, 2);")
|
|
err = tk.ExecToErr("update t set name = 1 where id = 2")
|
|
require.Error(t, err)
|
|
tk.MustQuery("select * from t").Check(testkit.Rows("1 1", "2 2"))
|
|
|
|
// test update ignore for pimary key
|
|
tk.MustExec("drop table if exists t;")
|
|
tk.MustExec(`create table t(a bigint, primary key (a))
|
|
PARTITION BY RANGE (a) (
|
|
PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION p1 VALUES LESS THAN (11))`)
|
|
tk.MustExec("insert into t values (5)")
|
|
tk.MustExec("insert into t values (7)")
|
|
err = tk.ExecToErr("update ignore t set a = 5 where a = 7;")
|
|
require.NoError(t, err)
|
|
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 0 Warnings: 1")
|
|
r = tk.MustQuery("SHOW WARNINGS;")
|
|
r.Check(testkit.Rows("Warning 1062 Duplicate entry '5' for key 't.PRIMARY'"))
|
|
tk.MustQuery("select * from t order by a").Check(testkit.Rows("5", "7"))
|
|
|
|
// test update ignore for truncate as warning
|
|
err = tk.ExecToErr("update ignore t set a = 1 where a = (select '2a')")
|
|
require.NoError(t, err)
|
|
r = tk.MustQuery("SHOW WARNINGS;")
|
|
r.Check(testkit.Rows("Warning 1292 Truncated incorrect DOUBLE value: '2a'", "Warning 1292 Truncated incorrect DOUBLE value: '2a'"))
|
|
|
|
// test update ignore for unique key
|
|
tk.MustExec("drop table if exists t;")
|
|
tk.MustExec(`create table t(a bigint, unique key I_uniq (a))
|
|
PARTITION BY RANGE (a) (
|
|
PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION p1 VALUES LESS THAN (11))`)
|
|
tk.MustExec("insert into t values (5)")
|
|
tk.MustExec("insert into t values (7)")
|
|
err = tk.ExecToErr("update ignore t set a = 5 where a = 7;")
|
|
require.NoError(t, err)
|
|
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 0 Warnings: 1")
|
|
r = tk.MustQuery("SHOW WARNINGS;")
|
|
r.Check(testkit.Rows("Warning 1062 Duplicate entry '5' for key 't.I_uniq'"))
|
|
tk.MustQuery("select * from t order by a").Check(testkit.Rows("5", "7"))
|
|
}
|
|
|
|
func TestPartitionedTableDelete(t *testing.T) {
|
|
failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`)
|
|
defer failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune")
|
|
createTable := `CREATE TABLE test.t (id int not null default 1, name varchar(255), index(id))
|
|
PARTITION BY RANGE ( id ) (
|
|
PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION p1 VALUES LESS THAN (11),
|
|
PARTITION p2 VALUES LESS THAN (16),
|
|
PARTITION p3 VALUES LESS THAN (21))`
|
|
|
|
store := testkit.CreateMockStore(t)
|
|
tk := testkit.NewTestKit(t, store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec("drop table if exists t")
|
|
tk.MustExec(createTable)
|
|
for i := 1; i < 21; i++ {
|
|
tk.MustExec(fmt.Sprintf(`insert into t values (%d, "hello")`, i))
|
|
}
|
|
|
|
tk.MustExec(`delete from t where id = 2 limit 1;`)
|
|
tk.CheckExecResult(1, 0)
|
|
|
|
// Test delete with false condition
|
|
tk.MustExec(`delete from t where 0;`)
|
|
tk.CheckExecResult(0, 0)
|
|
|
|
tk.MustExec("insert into t values (2, 'abc')")
|
|
tk.MustExec(`delete from t where t.id = 2 limit 1`)
|
|
tk.CheckExecResult(1, 0)
|
|
|
|
// Test delete ignore
|
|
tk.MustExec("insert into t values (2, 'abc')")
|
|
err := tk.ExecToErr("delete from t where id = (select '2a')")
|
|
require.Error(t, err)
|
|
err = tk.ExecToErr("delete ignore from t where id = (select '2a')")
|
|
require.NoError(t, err)
|
|
tk.CheckExecResult(1, 0)
|
|
r := tk.MustQuery("SHOW WARNINGS;")
|
|
r.Check(testkit.Rows("Warning 1292 Truncated incorrect DOUBLE value: '2a'", "Warning 1292 Truncated incorrect DOUBLE value: '2a'"))
|
|
|
|
// Test delete without using index, involve multiple partitions.
|
|
tk.MustExec("delete from t ignore index(id) where id >= 13 and id <= 17")
|
|
tk.CheckExecResult(5, 0)
|
|
|
|
tk.MustExec("admin check table t")
|
|
tk.MustExec(`delete from t;`)
|
|
tk.CheckExecResult(14, 0)
|
|
|
|
// Fix that partitioned table should not use PointGetPlan.
|
|
tk.MustExec(`create table t1 (c1 bigint, c2 bigint, c3 bigint, primary key(c1)) partition by range (c1) (partition p0 values less than (3440))`)
|
|
tk.MustExec("insert into t1 values (379, 379, 379)")
|
|
tk.MustExec("delete from t1 where c1 = 379")
|
|
tk.CheckExecResult(1, 0)
|
|
tk.MustExec(`drop table t1;`)
|
|
}
|
|
|
|
func TestPartitionOnMissing(t *testing.T) {
|
|
store := testkit.CreateMockStore(t)
|
|
tk := testkit.NewTestKit(t, store)
|
|
tk.MustExec("create schema OnMissing")
|
|
tk.MustExec("use OnMissing")
|
|
tk.MustExec(`set global tidb_partition_prune_mode='dynamic'`)
|
|
tk.MustExec(`set session tidb_partition_prune_mode='dynamic'`)
|
|
|
|
tk.MustExec(`CREATE TABLE tt1 (
|
|
id INT NOT NULL,
|
|
listid INT,
|
|
name varchar(10)
|
|
)
|
|
PARTITION BY LIST (listid) (
|
|
PARTITION p1 VALUES IN (1),
|
|
PARTITION p2 VALUES IN (2),
|
|
PARTITION p3 VALUES IN (3),
|
|
PARTITION p4 VALUES IN (4)
|
|
)`)
|
|
|
|
tk.MustExec(`CREATE TABLE tt2 (
|
|
id INT NOT NULL,
|
|
listid INT
|
|
)`)
|
|
|
|
tk.MustExec(`create index idx_listid on tt1(id,listid)`)
|
|
tk.MustExec(`create index idx_listid on tt2(listid)`)
|
|
|
|
tk.MustExec(`insert into tt1 values(1,1,1)`)
|
|
tk.MustExec(`insert into tt1 values(2,2,2)`)
|
|
tk.MustExec(`insert into tt1 values(3,3,3)`)
|
|
tk.MustExec(`insert into tt1 values(4,4,4)`)
|
|
tk.MustExec(`insert into tt2 values(1,1)`)
|
|
tk.MustExec(`insert into tt2 values(2,2)`)
|
|
tk.MustExec(`insert into tt2 values(3,3)`)
|
|
tk.MustExec(`insert into tt2 values(4,4)`)
|
|
tk.MustExec(`insert into tt2 values(5,5)`)
|
|
|
|
tk.MustExec(`analyze table tt1`)
|
|
tk.MustExec(`analyze table tt2`)
|
|
|
|
tk.MustQuery(`select /*+ inl_join(tt1)*/ count(*) from tt2
|
|
left join tt1 on tt1.listid=tt2.listid and tt1.id=tt2.id`).Check(testkit.Rows("5"))
|
|
}
|