Files
tidb/executor/write_test.go

4302 lines
204 KiB
Go

// Copyright 2016 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 executor_test
import (
"context"
"errors"
"fmt"
"strconv"
"testing"
"github.com/pingcap/failpoint"
"github.com/pingcap/tidb/config"
"github.com/pingcap/tidb/executor"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/parser/mysql"
"github.com/pingcap/tidb/planner/core"
"github.com/pingcap/tidb/session"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/sessionctx/stmtctx"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/sessiontxn"
"github.com/pingcap/tidb/store/mockstore"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/table/tables"
"github.com/pingcap/tidb/testkit"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util"
"github.com/pingcap/tidb/util/mock"
"github.com/stretchr/testify/require"
)
func TestInsert(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, 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)
require.Equal(t, tk.Session().LastMessage(), "Records: 3 Duplicates: 0 Warnings: 0")
errInsertSelectSQL := `insert insert_test (c1) values ();`
tk.MustExec("begin")
err := tk.ExecToErr(errInsertSelectSQL)
require.Error(t, err)
tk.MustExec("rollback")
errInsertSelectSQL = `insert insert_test (c1, c2) values (1,2),(1);`
tk.MustExec("begin")
err = tk.ExecToErr(errInsertSelectSQL)
require.Error(t, err)
tk.MustExec("rollback")
errInsertSelectSQL = `insert insert_test (xxx) values (3);`
tk.MustExec("begin")
err = tk.ExecToErr(errInsertSelectSQL)
require.Error(t, err)
tk.MustExec("rollback")
errInsertSelectSQL = `insert insert_test_xxx (c1) values ();`
tk.MustExec("begin")
err = tk.ExecToErr(errInsertSelectSQL)
require.Error(t, err)
tk.MustExec("rollback")
insertSetSQL := `insert insert_test set c1 = 3;`
tk.MustExec(insertSetSQL)
require.Empty(t, tk.Session().LastMessage())
errInsertSelectSQL = `insert insert_test set c1 = 4, c1 = 5;`
tk.MustExec("begin")
err = tk.ExecToErr(errInsertSelectSQL)
require.Error(t, err)
tk.MustExec("rollback")
errInsertSelectSQL = `insert insert_test set xxx = 6;`
tk.MustExec("begin")
err = tk.ExecToErr(errInsertSelectSQL)
require.Error(t, err)
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)
require.Equal(t, tk.Session().LastMessage(), "Records: 4 Duplicates: 0 Warnings: 0")
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)
require.Equal(t, tk.Session().LastMessage(), "Records: 8 Duplicates: 0 Warnings: 0")
errInsertSelectSQL = `insert insert_test_1 select c1 from insert_test;`
tk.MustExec("begin")
err = tk.ExecToErr(errInsertSelectSQL)
require.Error(t, err)
tk.MustExec("rollback")
errInsertSelectSQL = `insert insert_test_1 values(default, default, default, default, default)`
tk.MustExec("begin")
err = tk.ExecToErr(errInsertSelectSQL)
require.Error(t, err)
tk.MustExec("rollback")
// Updating column is PK handle.
// Make sure the record is "1, 1, nil, 1".
r := tk.MustQuery("select * from insert_test where id = 1;")
rowStr := fmt.Sprintf("%v %v %v %v", "1", "1", nil, "1")
r.Check(testkit.Rows(rowStr))
insertSQL := `insert into insert_test (id, c3) values (1, 2) on duplicate key update id=values(id), c2=10;`
tk.MustExec(insertSQL)
require.Empty(t, tk.Session().LastMessage())
r = tk.MustQuery("select * from insert_test where id = 1;")
rowStr = fmt.Sprintf("%v %v %v %v", "1", "1", "10", "1")
r.Check(testkit.Rows(rowStr))
insertSQL = `insert into insert_test (id, c2) values (1, 1) on duplicate key update insert_test.c2=10;`
tk.MustExec(insertSQL)
require.Empty(t, tk.Session().LastMessage())
err = tk.ExecToErr(`insert into insert_test (id, c2) values(1, 1) on duplicate key update t.c2 = 10`)
require.Error(t, err)
// for on duplicate key
insertSQL = `INSERT INTO insert_test (id, c3) VALUES (1, 2) ON DUPLICATE KEY UPDATE c3=values(c3)+c3+3;`
tk.MustExec(insertSQL)
require.Empty(t, tk.Session().LastMessage())
r = tk.MustQuery("select * from insert_test where id = 1;")
rowStr = fmt.Sprintf("%v %v %v %v", "1", "1", "10", "6")
r.Check(testkit.Rows(rowStr))
// for on duplicate key with ignore
insertSQL = `INSERT IGNORE INTO insert_test (id, c3) VALUES (1, 2) ON DUPLICATE KEY UPDATE c3=values(c3)+c3+3;`
tk.MustExec(insertSQL)
require.Empty(t, tk.Session().LastMessage())
r = tk.MustQuery("select * from insert_test where id = 1;")
rowStr = fmt.Sprintf("%v %v %v %v", "1", "1", "10", "11")
r.Check(testkit.Rows(rowStr))
tk.MustExec("create table insert_err (id int, c1 varchar(8))")
err = tk.ExecToErr("insert insert_err values (1, 'abcdabcdabcd')")
require.True(t, types.ErrDataTooLong.Equal(err))
err = tk.ExecToErr("insert insert_err values (1, '你好,世界')")
require.NoError(t, err)
tk.MustExec("create table TEST1 (ID INT NOT NULL, VALUE INT DEFAULT NULL, PRIMARY KEY (ID))")
err = tk.ExecToErr("INSERT INTO TEST1(id,value) VALUE(3,3) on DUPLICATE KEY UPDATE VALUE=4")
require.NoError(t, err)
require.Empty(t, tk.Session().LastMessage())
tk.MustExec("create table t (id int)")
tk.MustExec("insert into t values(1)")
tk.MustExec("update t t1 set id = (select count(*) + 1 from t t2 where t1.id = t2.id)")
r = tk.MustQuery("select * from t;")
r.Check(testkit.Rows("2"))
// issue 3235
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(c decimal(5, 5))")
err = tk.ExecToErr("insert into t value(0)")
require.NoError(t, err)
err = tk.ExecToErr("insert into t value(1)")
require.True(t, types.ErrWarnDataOutOfRange.Equal(err))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(c binary(255))")
err = tk.ExecToErr("insert into t value(1)")
require.NoError(t, err)
r = tk.MustQuery("select length(c) from t;")
r.Check(testkit.Rows("255"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(c varbinary(255))")
err = tk.ExecToErr("insert into t value(1)")
require.NoError(t, err)
r = tk.MustQuery("select length(c) from t;")
r.Check(testkit.Rows("1"))
// issue 3509
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(c int)")
tk.MustExec("set @origin_time_zone = @@time_zone")
tk.MustExec("set @@time_zone = '+08:00'")
err = tk.ExecToErr("insert into t value(Unix_timestamp('2002-10-27 01:00'))")
require.NoError(t, err)
r = tk.MustQuery("select * from t;")
r.Check(testkit.Rows("1035651600"))
tk.MustExec("set @@time_zone = @origin_time_zone")
// issue 3832
tk.MustExec("create table t1 (b char(0));")
err = tk.ExecToErr(`insert into t1 values ("");`)
require.NoError(t, err)
// issue 3895
tk.MustExec("USE test;")
tk.MustExec("DROP TABLE IF EXISTS t;")
tk.MustExec("CREATE TABLE t(a DECIMAL(4,2));")
tk.MustExec("INSERT INTO t VALUES (1.000001);")
r = tk.MustQuery("SHOW WARNINGS;")
// TODO: MySQL8.0 reports Note 1265 Data truncated for column 'a' at row 1
r.Check(testkit.Rows("Warning 1366 Incorrect decimal value: '1.000001' for column 'a' at row 1"))
tk.MustExec("INSERT INTO t VALUES (1.000000);")
r = tk.MustQuery("SHOW WARNINGS;")
r.Check(testkit.Rows())
// issue 4653
tk.MustExec("DROP TABLE IF EXISTS t;")
tk.MustExec("CREATE TABLE t(a datetime);")
err = tk.ExecToErr("INSERT INTO t VALUES('2017-00-00')")
require.Error(t, err)
tk.MustExec("set sql_mode = ''")
tk.MustExec("INSERT INTO t VALUES('2017-00-00')")
r = tk.MustQuery("SELECT * FROM t;")
r.Check(testkit.Rows("2017-00-00 00:00:00"))
tk.MustExec("set sql_mode = 'strict_all_tables';")
r = tk.MustQuery("SELECT * FROM t;")
r.Check(testkit.Rows("2017-00-00 00:00:00"))
// test auto_increment with unsigned.
tk.MustExec("drop table if exists test")
tk.MustExec("CREATE TABLE test(id int(10) UNSIGNED NOT NULL AUTO_INCREMENT, p int(10) UNSIGNED NOT NULL, PRIMARY KEY(p), KEY(id))")
tk.MustExec("insert into test(p) value(1)")
tk.MustQuery("select * from test").Check(testkit.Rows("1 1"))
tk.MustQuery("select * from test use index (id) where id = 1").Check(testkit.Rows("1 1"))
tk.MustExec("insert into test values(NULL, 2)")
tk.MustQuery("select * from test use index (id) where id = 2").Check(testkit.Rows("2 2"))
tk.MustExec("insert into test values(2, 3)")
tk.MustQuery("select * from test use index (id) where id = 2").Check(testkit.Rows("2 2", "2 3"))
// issue 6360
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t(a bigint unsigned);")
tk.MustExec(" set @orig_sql_mode = @@sql_mode; set @@sql_mode = 'strict_all_tables';")
err = tk.ExecToErr("insert into t value (-1);")
require.True(t, types.ErrWarnDataOutOfRange.Equal(err))
tk.MustExec("set @@sql_mode = '';")
tk.MustExec("insert into t value (-1);")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1264 Out of range value for column 'a' at row 1"))
tk.MustExec("insert into t select -1;")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1690 constant -1 overflows bigint"))
tk.MustExec("insert into t select cast(-1 as unsigned);")
tk.MustExec("insert into t value (-1.111);")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1264 Out of range value for column 'a' at row 1"))
tk.MustExec("insert into t value ('-1.111');")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1264 Out of range value for column 'a' at row 1"))
tk.MustExec("update t set a = -1 limit 1;")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1690 constant -1 overflows bigint"))
r = tk.MustQuery("select * from t;")
r.Check(testkit.Rows("0", "0", "18446744073709551615", "0", "0"))
tk.MustExec("set @@sql_mode = @orig_sql_mode;")
// issue 6424 & issue 20207
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a time(6))")
tk.MustExec("insert into t value('20070219173709.055870'), ('20070219173709.055'), ('20070219173709.055870123')")
tk.MustQuery("select * from t").Check(testkit.Rows("17:37:09.055870", "17:37:09.055000", "17:37:09.055870"))
tk.MustExec("truncate table t")
tk.MustExec("insert into t value(20070219173709.055870), (20070219173709.055), (20070219173709.055870123)")
tk.MustQuery("select * from t").Check(testkit.Rows("17:37:09.055870", "17:37:09.055000", "17:37:09.055870"))
err = tk.ExecToErr("insert into t value(-20070219173709.055870)")
require.EqualError(t, err, "[table:1292]Incorrect time value: '-20070219173709.055870' for column 'a' at row 1")
tk.MustExec("drop table if exists t")
tk.MustExec("set @@sql_mode=''")
tk.MustExec("create table t(a float unsigned, b double unsigned)")
tk.MustExec("insert into t value(-1.1, -1.1), (-2.1, -2.1), (0, 0), (1.1, 1.1)")
tk.MustQuery("show warnings").
Check(testkit.Rows("Warning 1264 Out of range value for column 'a' at row 1", "Warning 1264 Out of range value for column 'b' at row 1",
"Warning 1264 Out of range value for column 'a' at row 2", "Warning 1264 Out of range value for column 'b' at row 2"))
tk.MustQuery("select * from t").Check(testkit.Rows("0 0", "0 0", "0 0", "1.1 1.1"))
// issue 7061
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int default 1, b int default 2)")
tk.MustExec("insert into t values(default, default)")
tk.MustQuery("select * from t").Check(testkit.Rows("1 2"))
tk.MustExec("truncate table t")
tk.MustExec("insert into t values(default(b), default(a))")
tk.MustQuery("select * from t").Check(testkit.Rows("2 1"))
tk.MustExec("truncate table t")
tk.MustExec("insert into t (b) values(default)")
tk.MustQuery("select * from t").Check(testkit.Rows("1 2"))
tk.MustExec("truncate table t")
tk.MustExec("insert into t (b) values(default(a))")
tk.MustQuery("select * from t").Check(testkit.Rows("1 1"))
tk.MustExec("create view v as select * from t")
err = tk.ExecToErr("insert into v values(1,2)")
require.EqualError(t, err, "insert into view v is not supported now")
err = tk.ExecToErr("replace into v values(1,2)")
require.EqualError(t, err, "replace into view v is not supported now")
tk.MustExec("drop view v")
tk.MustExec("create sequence seq")
err = tk.ExecToErr("insert into seq values()")
require.EqualError(t, err, "insert into sequence seq is not supported now")
err = tk.ExecToErr("replace into seq values()")
require.EqualError(t, err, "replace into sequence seq is not supported now")
tk.MustExec("drop sequence seq")
// issue 22851
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(name varchar(255), b int, c int, primary key(name(2)))")
tk.MustExec("insert into t(name, b) values(\"cha\", 3)")
err = tk.ExecToErr("insert into t(name, b) values(\"chb\", 3)")
require.EqualError(t, err, "[kv:1062]Duplicate entry 'ch' for key 't.PRIMARY'")
tk.MustExec("insert into t(name, b) values(\"测试\", 3)")
err = tk.ExecToErr("insert into t(name, b) values(\"测试\", 3)")
require.EqualError(t, err, "[kv:1062]Duplicate entry '\xe6\xb5' for key 't.PRIMARY'")
}
func TestMultiBatch(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t,t0")
tk.MustExec("create table t0 (i int)")
tk.MustExec("insert into t0 values (1), (1)")
tk.MustExec("create table t (i int unique key)")
tk.MustExec("set @@tidb_dml_batch_size = 1")
tk.MustExec("insert ignore into t select * from t0")
tk.MustExec("admin check table t")
}
func TestInsertAutoInc(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, 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))
// SQL_MODE=NO_AUTO_VALUE_ON_ZERO
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 (5, 1)`
tk.MustExec(insertSQL)
r = tk.MustQuery("select * from insert_autoinc_test;")
rowStr1 = fmt.Sprintf("%v %v", "5", "1")
r.Check(testkit.Rows(rowStr1))
insertSQL = `insert into insert_autoinc_test(id, c1) values (0, 2)`
tk.MustExec(insertSQL)
r = tk.MustQuery("select * from insert_autoinc_test;")
rowStr2 = fmt.Sprintf("%v %v", "6", "2")
r.Check(testkit.Rows(rowStr1, rowStr2))
insertSQL = `insert into insert_autoinc_test(id, c1) values (0, 3)`
tk.MustExec(insertSQL)
r = tk.MustQuery("select * from insert_autoinc_test;")
rowStr3 = fmt.Sprintf("%v %v", "7", "3")
r.Check(testkit.Rows(rowStr1, rowStr2, rowStr3))
tk.MustExec("set SQL_MODE=NO_AUTO_VALUE_ON_ZERO")
insertSQL = `insert into insert_autoinc_test(id, c1) values (0, 4)`
tk.MustExec(insertSQL)
r = tk.MustQuery("select * from insert_autoinc_test;")
rowStr4 = fmt.Sprintf("%v %v", "0", "4")
r.Check(testkit.Rows(rowStr4, rowStr1, rowStr2, rowStr3))
insertSQL = `insert into insert_autoinc_test(id, c1) values (0, 5)`
err := tk.ExecToErr(insertSQL)
// ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'
require.Error(t, err)
insertSQL = `insert into insert_autoinc_test(c1) values (6)`
tk.MustExec(insertSQL)
r = tk.MustQuery("select * from insert_autoinc_test;")
rowStr5 = fmt.Sprintf("%v %v", "8", "6")
r.Check(testkit.Rows(rowStr4, rowStr1, rowStr2, rowStr3, rowStr5))
insertSQL = `insert into insert_autoinc_test(id, c1) values (null, 7)`
tk.MustExec(insertSQL)
r = tk.MustQuery("select * from insert_autoinc_test;")
rowStr6 = fmt.Sprintf("%v %v", "9", "7")
r.Check(testkit.Rows(rowStr4, rowStr1, rowStr2, rowStr3, rowStr5, rowStr6))
tk.MustExec("set SQL_MODE='';")
insertSQL = `insert into insert_autoinc_test(id, c1) values (0, 8)`
tk.MustExec(insertSQL)
r = tk.MustQuery("select * from insert_autoinc_test;")
rowStr7 := fmt.Sprintf("%v %v", "10", "8")
r.Check(testkit.Rows(rowStr4, rowStr1, rowStr2, rowStr3, rowStr5, rowStr6, rowStr7))
insertSQL = `insert into insert_autoinc_test(id, c1) values (null, 9)`
tk.MustExec(insertSQL)
r = tk.MustQuery("select * from insert_autoinc_test;")
rowStr8 := fmt.Sprintf("%v %v", "11", "9")
r.Check(testkit.Rows(rowStr4, rowStr1, rowStr2, rowStr3, rowStr5, rowStr6, rowStr7, rowStr8))
}
func TestInsertIgnore(t *testing.T) {
store := testkit.CreateMockStore(t)
var cfg kv.InjectionConfig
tk := testkit.NewTestKit(t, kv.NewInjectedStore(store, &cfg))
tk.MustExec("use test")
testSQL := `drop table if exists t;
create table t (id int PRIMARY KEY AUTO_INCREMENT, c1 int unique key);`
tk.MustExec(testSQL)
testSQL = `insert into t values (1, 2);`
tk.MustExec(testSQL)
require.Empty(t, tk.Session().LastMessage())
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)")
require.Equal(t, tk.Session().LastMessage(), "Records: 2 Duplicates: 1 Warnings: 1")
r = tk.MustQuery("select * from t;")
rowStr1 := fmt.Sprintf("%v %v", "2", "3")
r.Check(testkit.Rows(rowStr, rowStr1))
tk.MustExec("insert ignore into t values (3, 4), (3, 4)")
require.Equal(t, tk.Session().LastMessage(), "Records: 2 Duplicates: 1 Warnings: 1")
r = tk.MustQuery("select * from t;")
rowStr2 := fmt.Sprintf("%v %v", "3", "4")
r.Check(testkit.Rows(rowStr, rowStr1, rowStr2))
tk.MustExec("begin")
tk.MustExec("insert ignore into t values (4, 4), (4, 5), (4, 6)")
require.Equal(t, tk.Session().LastMessage(), "Records: 3 Duplicates: 2 Warnings: 2")
r = tk.MustQuery("select * from t;")
rowStr3 := fmt.Sprintf("%v %v", "4", "5")
r.Check(testkit.Rows(rowStr, rowStr1, rowStr2, rowStr3))
tk.MustExec("commit")
cfg.SetGetError(errors.New("foo"))
err := tk.ExecToErr("insert ignore into t values (1, 3)")
require.Error(t, err)
cfg.SetGetError(nil)
// for issue 4268
testSQL = `drop table if exists t;
create table t (a bigint);`
tk.MustExec(testSQL)
testSQL = "insert ignore into t select '1a';"
err = tk.ExecToErr(testSQL)
require.NoError(t, err)
require.Equal(t, tk.Session().LastMessage(), "Records: 1 Duplicates: 0 Warnings: 1")
r = tk.MustQuery("SHOW WARNINGS")
r.Check(testkit.Rows("Warning 1292 Truncated incorrect DOUBLE value: '1a'"))
testSQL = "insert ignore into t values ('1a')"
err = tk.ExecToErr(testSQL)
require.NoError(t, err)
require.Empty(t, tk.Session().LastMessage())
r = tk.MustQuery("SHOW WARNINGS")
// TODO: MySQL8.0 reports Warning 1265 Data truncated for column 'a' at row 1
r.Check(testkit.Rows("Warning 1366 Incorrect bigint value: '1a' for column 'a' at row 1"))
// for duplicates with warning
testSQL = `drop table if exists t;
create table t(a int primary key, b int);`
tk.MustExec(testSQL)
testSQL = "insert ignore into t values (1,1);"
tk.MustExec(testSQL)
require.Empty(t, tk.Session().LastMessage())
err = tk.ExecToErr(testSQL)
require.Empty(t, tk.Session().LastMessage())
require.NoError(t, err)
r = tk.MustQuery("SHOW WARNINGS")
r.Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 't.PRIMARY'"))
testSQL = `drop table if exists test;
create table test (i int primary key, j int unique);
begin;
insert into test values (1,1);
insert ignore into test values (2,1);
commit;`
tk.MustExec(testSQL)
testSQL = `select * from test;`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("1 1"))
testSQL = `delete from test;
insert into test values (1, 1);
begin;
delete from test where i = 1;
insert ignore into test values (2, 1);
commit;`
tk.MustExec(testSQL)
testSQL = `select * from test;`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("2 1"))
testSQL = `delete from test;
insert into test values (1, 1);
begin;
update test set i = 2, j = 2 where i = 1;
insert ignore into test values (1, 3);
insert ignore into test values (2, 4);
commit;`
tk.MustExec(testSQL)
testSQL = `select * from test order by i;`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("1 3", "2 2"))
testSQL = `create table badnull (i int not null)`
tk.MustExec(testSQL)
testSQL = `insert ignore into badnull values (null)`
tk.MustExec(testSQL)
require.Empty(t, tk.Session().LastMessage())
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1048 Column 'i' cannot be null"))
testSQL = `select * from badnull`
tk.MustQuery(testSQL).Check(testkit.Rows("0"))
tk.MustExec("create table tp (id int) partition by range (id) (partition p0 values less than (1), partition p1 values less than(2))")
tk.MustExec("insert ignore into tp values (1), (3)")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1526 Table has no partition for value 3"))
}
func TestInsertOnDup(t *testing.T) {
store := testkit.CreateMockStore(t)
var cfg kv.InjectionConfig
tk := testkit.NewTestKit(t, kv.NewInjectedStore(store, &cfg))
tk.MustExec("use test")
testSQL := `drop table if exists t;
create table t (i int unique key);`
tk.MustExec(testSQL)
testSQL = `insert into t values (1),(2);`
tk.MustExec(testSQL)
require.Equal(t, tk.Session().LastMessage(), "Records: 2 Duplicates: 0 Warnings: 0")
r := tk.MustQuery("select * from t;")
rowStr1 := fmt.Sprintf("%v", "1")
rowStr2 := fmt.Sprintf("%v", "2")
r.Check(testkit.Rows(rowStr1, rowStr2))
tk.MustExec("insert into t values (1), (2) on duplicate key update i = values(i)")
require.Equal(t, tk.Session().LastMessage(), "Records: 2 Duplicates: 0 Warnings: 0")
r = tk.MustQuery("select * from t;")
r.Check(testkit.Rows(rowStr1, rowStr2))
tk.MustExec("insert into t values (2), (3) on duplicate key update i = 3")
require.Equal(t, tk.Session().LastMessage(), "Records: 2 Duplicates: 1 Warnings: 0")
r = tk.MustQuery("select * from t;")
rowStr3 := fmt.Sprintf("%v", "3")
r.Check(testkit.Rows(rowStr1, rowStr3))
testSQL = `drop table if exists t;
create table t (i int primary key, j int unique key);`
tk.MustExec(testSQL)
testSQL = `insert into t values (-1, 1);`
tk.MustExec(testSQL)
require.Empty(t, tk.Session().LastMessage())
r = tk.MustQuery("select * from t;")
rowStr1 = fmt.Sprintf("%v %v", "-1", "1")
r.Check(testkit.Rows(rowStr1))
tk.MustExec("insert into t values (1, 1) on duplicate key update j = values(j)")
require.Empty(t, tk.Session().LastMessage())
r = tk.MustQuery("select * from t;")
r.Check(testkit.Rows(rowStr1))
testSQL = `drop table if exists test;
create table test (i int primary key, j int unique);
begin;
insert into test values (1,1);
insert into test values (2,1) on duplicate key update i = -i, j = -j;
commit;`
tk.MustExec(testSQL)
testSQL = `select * from test;`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("-1 -1"))
testSQL = `delete from test;
insert into test values (1, 1);
begin;
delete from test where i = 1;
insert into test values (2, 1) on duplicate key update i = -i, j = -j;
commit;`
tk.MustExec(testSQL)
testSQL = `select * from test;`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("2 1"))
testSQL = `delete from test;
insert into test values (1, 1);
begin;
update test set i = 2, j = 2 where i = 1;
insert into test values (1, 3) on duplicate key update i = -i, j = -j;
insert into test values (2, 4) on duplicate key update i = -i, j = -j;
commit;`
tk.MustExec(testSQL)
testSQL = `select * from test order by i;`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("-2 -2", "1 3"))
testSQL = `delete from test;
begin;
insert into test values (1, 3), (1, 3) on duplicate key update i = values(i), j = values(j);
commit;`
tk.MustExec(testSQL)
testSQL = `select * from test order by i;`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("1 3"))
testSQL = `create table tmp (id int auto_increment, code int, primary key(id, code));
create table m (id int primary key auto_increment, code int unique);
insert tmp (code) values (1);
insert tmp (code) values (1);
set tidb_init_chunk_size=1;
insert m (code) select code from tmp on duplicate key update code = values(code);`
tk.MustExec(testSQL)
testSQL = `select * from m;`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("1 1"))
// The following two cases are used for guaranteeing the last_insert_id
// to be set as the value of on-duplicate-update assigned.
testSQL = `DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (f1 INT AUTO_INCREMENT PRIMARY KEY,
f2 VARCHAR(5) NOT NULL UNIQUE);
INSERT t1 (f2) VALUES ('test') ON DUPLICATE KEY UPDATE f1 = LAST_INSERT_ID(f1);`
tk.MustExec(testSQL)
require.Empty(t, tk.Session().LastMessage())
testSQL = `SELECT LAST_INSERT_ID();`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("1"))
testSQL = `INSERT t1 (f2) VALUES ('test') ON DUPLICATE KEY UPDATE f1 = LAST_INSERT_ID(f1);`
tk.MustExec(testSQL)
require.Empty(t, tk.Session().LastMessage())
testSQL = `SELECT LAST_INSERT_ID();`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("1"))
testSQL = `DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (f1 INT AUTO_INCREMENT UNIQUE,
f2 VARCHAR(5) NOT NULL UNIQUE);
INSERT t1 (f2) VALUES ('test') ON DUPLICATE KEY UPDATE f1 = LAST_INSERT_ID(f1);`
tk.MustExec(testSQL)
require.Empty(t, tk.Session().LastMessage())
testSQL = `SELECT LAST_INSERT_ID();`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("1"))
testSQL = `INSERT t1 (f2) VALUES ('test') ON DUPLICATE KEY UPDATE f1 = LAST_INSERT_ID(f1);`
tk.MustExec(testSQL)
require.Empty(t, tk.Session().LastMessage())
testSQL = `SELECT LAST_INSERT_ID();`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("1"))
testSQL = `INSERT t1 (f2) VALUES ('test') ON DUPLICATE KEY UPDATE f1 = 2;`
tk.MustExec(testSQL)
require.Empty(t, tk.Session().LastMessage())
testSQL = `SELECT LAST_INSERT_ID();`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("1"))
testSQL = `DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (f1 INT);
INSERT t1 VALUES (1) ON DUPLICATE KEY UPDATE f1 = 1;`
tk.MustExec(testSQL)
require.Empty(t, tk.Session().LastMessage())
tk.MustQuery(`SELECT * FROM t1;`).Check(testkit.Rows("1"))
testSQL = `DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (f1 INT PRIMARY KEY, f2 INT NOT NULL UNIQUE);
INSERT t1 VALUES (1, 1);`
tk.MustExec(testSQL)
require.Empty(t, tk.Session().LastMessage())
tk.MustExec(`INSERT t1 VALUES (1, 1), (1, 1) ON DUPLICATE KEY UPDATE f1 = 2, f2 = 2;`)
require.Equal(t, tk.Session().LastMessage(), "Records: 2 Duplicates: 1 Warnings: 0")
tk.MustQuery(`SELECT * FROM t1 order by f1;`).Check(testkit.Rows("1 1", "2 2"))
err := tk.ExecToErr(`INSERT t1 VALUES (1, 1) ON DUPLICATE KEY UPDATE f2 = null;`)
require.Error(t, err)
tk.MustExec(`INSERT IGNORE t1 VALUES (1, 1) ON DUPLICATE KEY UPDATE f2 = null;`)
require.Empty(t, tk.Session().LastMessage())
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1048 Column 'f2' cannot be null"))
tk.MustQuery(`SELECT * FROM t1 order by f1;`).Check(testkit.Rows("1 0", "2 2"))
tk.MustExec(`SET sql_mode='';`)
tk.MustExec(`INSERT t1 VALUES (1, 1) ON DUPLICATE KEY UPDATE f2 = null;`)
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1048 Column 'f2' cannot be null"))
tk.MustQuery(`SELECT * FROM t1 order by f1;`).Check(testkit.Rows("1 0", "2 2"))
}
func TestInsertIgnoreOnDup(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
testSQL := `drop table if exists t;
create table t (i int not null primary key, j int unique key);`
tk.MustExec(testSQL)
testSQL = `insert into t values (1, 1), (2, 2);`
tk.MustExec(testSQL)
require.Equal(t, tk.Session().LastMessage(), "Records: 2 Duplicates: 0 Warnings: 0")
testSQL = `insert ignore into t values(1, 1) on duplicate key update i = 2;`
tk.MustExec(testSQL)
require.Empty(t, tk.Session().LastMessage())
testSQL = `select * from t;`
r := tk.MustQuery(testSQL)
r.Check(testkit.Rows("1 1", "2 2"))
testSQL = `insert ignore into t values(1, 1) on duplicate key update j = 2;`
tk.MustExec(testSQL)
require.Empty(t, tk.Session().LastMessage())
testSQL = `select * from t;`
r = tk.MustQuery(testSQL)
r.Check(testkit.Rows("1 1", "2 2"))
tk.MustExec("drop table if exists t2")
tk.MustExec("create table t2(`col_25` set('Alice','Bob','Charlie','David') NOT NULL,`col_26` date NOT NULL DEFAULT '2016-04-15', PRIMARY KEY (`col_26`) clustered, UNIQUE KEY `idx_9` (`col_25`,`col_26`),UNIQUE KEY `idx_10` (`col_25`))")
tk.MustExec("insert into t2(col_25, col_26) values('Bob', '1989-03-23'),('Alice', '2023-11-24'), ('Charlie', '2023-12-05')")
tk.MustExec("insert ignore into t2 (col_25,col_26) values ( 'Bob','1977-11-23' ) on duplicate key update col_25 = 'Alice', col_26 = '2036-12-13'")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry 'Alice' for key 't2.idx_10'"))
tk.MustQuery("select * from t2").Check(testkit.Rows("Bob 1989-03-23", "Alice 2023-11-24", "Charlie 2023-12-05"))
tk.MustExec("drop table if exists t4")
tk.MustExec("create table t4(id int primary key clustered, k int, v int, unique key uk1(k))")
tk.MustExec("insert into t4 values (1, 10, 100), (3, 30, 300)")
tk.MustExec("insert ignore into t4 (id, k, v) values(1, 0, 0) on duplicate key update id = 2, k = 30")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '30' for key 't4.uk1'"))
tk.MustQuery("select * from t4").Check(testkit.Rows("1 10 100", "3 30 300"))
tk.MustExec("drop table if exists t5")
tk.MustExec("create table t5(k1 varchar(100), k2 varchar(100), uk1 int, v int, primary key(k1, k2) clustered, unique key ukk1(uk1), unique key ukk2(v))")
tk.MustExec("insert into t5(k1, k2, uk1, v) values('1', '1', 1, '100'), ('1', '3', 2, '200')")
tk.MustExec("update ignore t5 set k2 = '2', uk1 = 2 where k1 = '1' and k2 = '1'")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '2' for key 't5.ukk1'"))
tk.MustQuery("select * from t5").Check(testkit.Rows("1 1 1 100", "1 3 2 200"))
tk.MustExec("drop table if exists t6")
tk.MustExec("create table t6 (a int, b int, c int, primary key(a, b) clustered, unique key idx_14(b), unique key idx_15(b), unique key idx_16(a, b))")
tk.MustExec("insert into t6 select 10, 10, 20")
tk.MustExec("insert ignore into t6 set a = 20, b = 10 on duplicate key update a = 100")
tk.MustQuery("select * from t6").Check(testkit.Rows("100 10 20"))
tk.MustExec("insert ignore into t6 set a = 200, b= 10 on duplicate key update c = 1000")
tk.MustQuery("select * from t6").Check(testkit.Rows("100 10 1000"))
}
func TestInsertSetWithDefault(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
// Assign `DEFAULT` in `INSERT ... SET ...` statement
tk.MustExec("drop table if exists t1, t2;")
tk.MustExec("create table t1 (a int default 10, b int default 20);")
tk.MustExec("insert into t1 set a=default;")
tk.MustQuery("select * from t1;").Check(testkit.Rows("10 20"))
tk.MustExec("delete from t1;")
tk.MustExec("insert into t1 set b=default;")
tk.MustQuery("select * from t1;").Check(testkit.Rows("10 20"))
tk.MustExec("delete from t1;")
tk.MustExec("insert into t1 set b=default, a=1;")
tk.MustQuery("select * from t1;").Check(testkit.Rows("1 20"))
tk.MustExec("delete from t1;")
tk.MustExec("insert into t1 set a=default(a);")
tk.MustQuery("select * from t1;").Check(testkit.Rows("10 20"))
tk.MustExec("delete from t1;")
tk.MustExec("insert into t1 set a=default(b), b=default(a)")
tk.MustQuery("select * from t1;").Check(testkit.Rows("20 10"))
tk.MustExec("delete from t1;")
tk.MustExec("insert into t1 set a=default(b)+default(a);")
tk.MustQuery("select * from t1;").Check(testkit.Rows("30 20"))
// With generated columns
tk.MustExec("create table t2 (a int default 10 primary key, b int generated always as (-a) virtual, c int generated always as (-a) stored);")
tk.MustExec("insert into t2 set a=default;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("10 -10 -10"))
tk.MustExec("delete from t2;")
tk.MustExec("insert into t2 set a=2, b=default;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("2 -2 -2"))
tk.MustExec("delete from t2;")
tk.MustExec("insert into t2 set c=default, a=3;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("3 -3 -3"))
tk.MustExec("delete from t2;")
tk.MustExec("insert into t2 set a=default, b=default, c=default;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("10 -10 -10"))
tk.MustExec("delete from t2;")
tk.MustExec("insert into t2 set a=default(a), b=default, c=default;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("10 -10 -10"))
tk.MustExec("delete from t2;")
// Looks like MySQL accepts this, but still the inserted value would be default(b) i.e. ignored
tk.MustGetErrCode("insert into t2 set b=default(a);", mysql.ErrBadGeneratedColumn)
// Looks like MySQL accepts this, but inserted values are all NULL
tk.MustGetErrCode("insert into t2 set a=default(b), b=default(b);", mysql.ErrBadGeneratedColumn)
tk.MustExec("insert into t2 set a=default(a), c=default(c)")
tk.MustGetErrCode("insert into t2 set a=default(a), c=default(a);", mysql.ErrBadGeneratedColumn)
tk.MustExec("insert into t2 set a=3, b=default, c=default(c) ON DUPLICATE KEY UPDATE b = default(b)")
// This fails most likely due only the generated column is updated -> no change -> duplicate key?
// Too odd to create a bug, better to have it documented by this test instead...
tk.MustGetErrCode("insert into t2 set a=3, b=default, c=default(c) ON DUPLICATE KEY UPDATE b = default(b)", mysql.ErrDupEntry)
tk.MustGetErrCode("insert into t2 set a=3, b=default, c=default(c) ON DUPLICATE KEY UPDATE b = default(a)", mysql.ErrBadGeneratedColumn)
tk.MustQuery("select * from t2").Sort().Check(testkit.Rows("10 -10 -10", "3 -3 -3"))
tk.MustExec("drop table t1, t2")
// Issue 29926
tk.MustExec("create table t1 (a int not null auto_increment,primary key(a), t timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP)")
defer tk.MustExec("drop table if exists t1")
tk.MustExec("set @@timestamp = 1637541064")
defer tk.MustExec("set @@timestamp = DEFAULT")
tk.MustExec("insert into t1 set a=default,t=default")
tk.MustQuery("show warnings").Check(testkit.Rows())
tk.MustExec("set @@timestamp = 1637541082")
tk.MustExec("insert into t1 VALUES (default,default)")
tk.MustQuery("select * from t1").Sort().Check(testkit.Rows(
"1 2021-11-22 08:31:04",
"2 2021-11-22 08:31:22"))
tk.MustExec("set @@timestamp = 1637541332")
tk.MustExec("insert into t1 set a=1,t='2001-02-03 04:05:06' ON DUPLICATE KEY UPDATE t = default")
tk.MustQuery("show warnings").Check(testkit.Rows())
tk.MustExec("insert into t1 set a=2,t='2001-02-03 04:05:06' ON DUPLICATE KEY UPDATE t = default(t)")
tk.MustQuery("show warnings").Check(testkit.Rows())
tk.MustQuery("select * from t1").Sort().Check(testkit.Rows(
"1 2021-11-22 08:35:32",
"2 2021-11-22 08:35:32"))
tk.MustExec(`DROP TABLE t1`)
tk.MustExec(`CREATE TABLE t1 (a int default 1 PRIMARY KEY, b int default 2)`)
tk.MustExec(`INSERT INTO t1 VALUES (2,2), (3,3)`)
tk.MustExec(`INSERT INTO t1 VALUES (3,2) ON DUPLICATE KEY UPDATE b = DEFAULT(a)`)
tk.MustExec(`INSERT INTO t1 SET a = 2, b = 3 ON DUPLICATE KEY UPDATE b = DEFAULT(a)`)
tk.MustQuery("show warnings").Check(testkit.Rows())
tk.MustQuery("select * from t1").Sort().Check(testkit.Rows(
"2 1",
"3 1"))
}
func TestInsertOnDupUpdateDefault(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
// Assign `DEFAULT` in `INSERT ... ON DUPLICATE KEY UPDATE ...` statement
tk.MustExec("drop table if exists t1, t2;")
tk.MustExec("create table t1 (a int unique, b int default 20, c int default 30);")
tk.MustExec("insert into t1 values (1,default,default);")
tk.MustExec("insert into t1 values (1,default,default) on duplicate key update b=default;")
tk.MustQuery("select * from t1;").Check(testkit.Rows("1 20 30"))
tk.MustExec("insert into t1 values (1,default,default) on duplicate key update c=default, b=default;")
tk.MustQuery("select * from t1;").Check(testkit.Rows("1 20 30"))
tk.MustExec("insert into t1 values (1,default,default) on duplicate key update c=default, a=2")
tk.MustQuery("select * from t1;").Check(testkit.Rows("2 20 30"))
tk.MustExec("insert into t1 values (2,default,default) on duplicate key update c=default(b)")
tk.MustQuery("select * from t1;").Check(testkit.Rows("2 20 20"))
tk.MustExec("insert into t1 values (2,default,default) on duplicate key update a=default(b)+default(c)")
tk.MustQuery("select * from t1;").Check(testkit.Rows("50 20 20"))
// With generated columns
tk.MustExec("create table t2 (a int unique, b int generated always as (-a) virtual, c int generated always as (-a) stored);")
tk.MustExec("insert into t2 values (1,default,default);")
tk.MustExec("insert into t2 values (1,default,default) on duplicate key update a=2, b=default;")
tk.MustQuery("select * from t2").Check(testkit.Rows("2 -2 -2"))
tk.MustExec("insert into t2 values (2,default,default) on duplicate key update a=3, c=default;")
tk.MustQuery("select * from t2").Check(testkit.Rows("3 -3 -3"))
tk.MustExec("insert into t2 values (3,default,default) on duplicate key update c=default, b=default, a=4;")
tk.MustQuery("select * from t2").Check(testkit.Rows("4 -4 -4"))
tk.MustExec("insert into t2 values (4,default,default) on duplicate key update b=default, a=5, c=default;")
tk.MustQuery("select * from t2").Check(testkit.Rows("5 -5 -5"))
tk.MustGetErrCode("insert into t2 values (5,default,default) on duplicate key update b=default(a);", mysql.ErrBadGeneratedColumn)
tk.MustExec("insert into t2 values (5,default,default) on duplicate key update a=default(a), c=default(c)")
tk.MustQuery("select * from t2").Check(testkit.Rows("<nil> <nil> <nil>"))
tk.MustExec("delete from t2")
tk.MustExec("insert into t2 (a) values (1);")
tk.MustExec("insert into t2 values (1,default,default) on duplicate key update a=default(b), b=default(b);")
tk.MustQuery("select * from t2").Check(testkit.Rows("<nil> <nil> <nil>"))
tk.MustExec("delete from t2")
tk.MustExec("insert into t2 (a) values (1);")
tk.MustGetErrCode("insert into t2 values (1,default,default) on duplicate key update a=default(a), c=default(a);", mysql.ErrBadGeneratedColumn)
tk.MustExec("drop table t1, t2")
tk.MustExec("set @@tidb_txn_mode = 'pessimistic'")
tk.MustExec("create table t ( c_int int, c_string varchar(40) collate utf8mb4_bin , primary key (c_string), unique key (c_int));")
tk.MustExec("insert into t values (22, 'gold witch'), (24, 'gray singer'), (21, 'silver sight');")
tk.MustExec("begin;")
err := tk.ExecToErr("insert into t values (21,'black warlock'), (22, 'dark sloth'), (21, 'cyan song') on duplicate key update c_int = c_int + 1, c_string = concat(c_int, ':', c_string);")
require.True(t, kv.ErrKeyExists.Equal(err))
tk.MustExec("commit;")
tk.MustQuery("select * from t order by c_int;").Check(testkit.RowsWithSep("|", "21|silver sight", "22|gold witch", "24|gray singer"))
tk.MustExec("drop table t;")
}
func TestReplace(t *testing.T) {
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);`
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")
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)
require.Equal(t, tk.Session().LastMessage(), "Records: 4 Duplicates: 0 Warnings: 0")
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)
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")
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)
require.Equal(t, int64(1), int64(tk.Session().AffectedRows()))
require.Empty(t, tk.Session().LastMessage())
replaceUniqueIndexSQL = `replace into replace_test_3 set c1=1, c2=1;`
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));`
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()))
require.Empty(t, tk.Session().LastMessage())
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)
require.Equal(t, int64(1), int64(tk.Session().AffectedRows()))
require.Empty(t, tk.Session().LastMessage())
// 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)
require.Empty(t, tk.Session().LastMessage())
issue989SQL = `replace into tIssue989(a, b) values (111, 2);`
tk.MustExec(issue989SQL)
require.Empty(t, tk.Session().LastMessage())
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)
require.Equal(t, int64(3), int64(tk.Session().AffectedRows()))
require.Empty(t, tk.Session().LastMessage())
r = tk.MustQuery("select * from tIssue1012;")
r.Check(testkit.Rows("1 1"))
// Test Replace with info message
tk.MustExec(`drop table if exists t1`)
tk.MustExec(`create table t1(a int primary key, b int);`)
tk.MustExec(`insert into t1 values(1,1),(2,2),(3,3),(4,4),(5,5);`)
tk.MustExec(`replace into t1 values(1,1);`)
require.Equal(t, int64(1), int64(tk.Session().AffectedRows()))
require.Empty(t, tk.Session().LastMessage())
tk.MustExec(`replace into t1 values(1,1),(2,2);`)
require.Equal(t, int64(2), int64(tk.Session().AffectedRows()))
require.Equal(t, tk.Session().LastMessage(), "Records: 2 Duplicates: 0 Warnings: 0")
tk.MustExec(`replace into t1 values(4,14),(5,15),(6,16),(7,17),(8,18)`)
require.Equal(t, int64(7), int64(tk.Session().AffectedRows()))
require.Equal(t, tk.Session().LastMessage(), "Records: 5 Duplicates: 2 Warnings: 0")
tk.MustExec(`replace into t1 select * from (select 1, 2) as tmp;`)
require.Equal(t, int64(2), int64(tk.Session().AffectedRows()))
require.Equal(t, tk.Session().LastMessage(), "Records: 1 Duplicates: 1 Warnings: 0")
// Assign `DEFAULT` in `REPLACE` statement
tk.MustExec("drop table if exists t1, t2;")
tk.MustExec("create table t1 (a int primary key, b int default 20, c int default 30);")
tk.MustExec("insert into t1 value (1, 2, 3);")
tk.MustExec("replace t1 set a=1, b=default;")
tk.MustQuery("select * from t1;").Check(testkit.Rows("1 20 30"))
tk.MustExec("replace t1 set a=2, b=default, c=default")
tk.MustQuery("select * from t1;").Check(testkit.Rows("1 20 30", "2 20 30"))
tk.MustExec("replace t1 set a=2, b=default(c), c=default(b);")
tk.MustQuery("select * from t1;").Check(testkit.Rows("1 20 30", "2 30 20"))
tk.MustExec("replace t1 set a=default(b)+default(c)")
tk.MustQuery("select * from t1;").Check(testkit.Rows("1 20 30", "2 30 20", "50 20 30"))
// With generated columns
tk.MustExec("create table t2 (pk int primary key, a int default 1, b int generated always as (-a) virtual, c int generated always as (-a) stored);")
tk.MustExec("replace t2 set pk=1, b=default;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("1 1 -1 -1"))
tk.MustExec("replace t2 set pk=2, a=10, b=default;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("1 1 -1 -1", "2 10 -10 -10"))
tk.MustExec("replace t2 set pk=2, c=default, a=20;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("1 1 -1 -1", "2 20 -20 -20"))
tk.MustExec("replace t2 set pk=2, a=default, b=default, c=default;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("1 1 -1 -1", "2 1 -1 -1"))
tk.MustExec("replace t2 set pk=3, a=default(a), b=default, c=default;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("1 1 -1 -1", "2 1 -1 -1", "3 1 -1 -1"))
tk.MustGetErrCode("replace t2 set b=default(a);", mysql.ErrBadGeneratedColumn)
tk.MustGetErrCode("replace t2 set a=default(b), b=default(b);", mysql.ErrBadGeneratedColumn)
tk.MustGetErrCode("replace t2 set a=default(a), c=default(c);", mysql.ErrNoDefaultForField)
tk.MustGetErrCode("replace t2 set c=default(a);", mysql.ErrBadGeneratedColumn)
tk.MustExec("drop table t1, t2")
}
func TestReplaceWithCICollation(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table t (a varchar(20) charset utf8mb4 collate utf8mb4_general_ci primary key);")
tk.MustExec("replace into t(a) values (_binary'A '),(_binary'A');")
tk.MustQuery("select a from t use index(primary);").Check(testkit.Rows("A"))
tk.MustQuery("select a from t ignore index(primary);").Check(testkit.Rows("A"))
}
func TestGeneratedColumnForInsert(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
// test cases for default behavior
tk.MustExec(`drop table if exists t1;`)
tk.MustExec(`create table t1(id int, id_gen int as(id + 42), b int, unique key id_gen(id_gen));`)
tk.MustExec(`insert into t1 (id, b) values(1,1),(2,2),(3,3),(4,4),(5,5);`)
tk.MustExec(`replace into t1 (id, b) values(1,1);`)
tk.MustExec(`replace into t1 (id, b) values(1,1),(2,2);`)
tk.MustExec(`replace into t1 (id, b) values(6,16),(7,17),(8,18);`)
tk.MustQuery("select * from t1;").Check(testkit.Rows(
"1 43 1", "2 44 2", "3 45 3", "4 46 4", "5 47 5", "6 48 16", "7 49 17", "8 50 18"))
tk.MustExec(`insert into t1 (id, b) values (6,18) on duplicate key update id = -id;`)
tk.MustExec(`insert into t1 (id, b) values (7,28) on duplicate key update b = -values(b);`)
tk.MustQuery("select * from t1;").Check(testkit.Rows(
"1 43 1", "2 44 2", "3 45 3", "4 46 4", "5 47 5", "-6 36 16", "7 49 -28", "8 50 18"))
// test cases for virtual and stored columns in the same table
tk.MustExec(`drop table if exists t`)
tk.MustExec(`create table t
(i int as(k+1) stored, j int as(k+2) virtual, k int, unique key idx_i(i), unique key idx_j(j))`)
tk.MustExec(`insert into t (k) values (1), (2)`)
tk.MustExec(`replace into t (k) values (1), (2)`)
tk.MustQuery(`select * from t`).Check(testkit.Rows("2 3 1", "3 4 2"))
tk.MustExec(`drop table if exists t`)
tk.MustExec(`create table t
(i int as(k+1) stored, j int as(k+2) virtual, k int, unique key idx_j(j))`)
tk.MustExec(`insert into t (k) values (1), (2)`)
tk.MustExec(`replace into t (k) values (1), (2)`)
tk.MustQuery(`select * from t`).Check(testkit.Rows("2 3 1", "3 4 2"))
tk.MustExec(`drop table if exists t`)
tk.MustExec(`create table t
(i int as(k+1) stored, j int as(k+2) virtual, k int, unique key idx_i(i))`)
tk.MustExec(`insert into t (k) values (1), (2)`)
tk.MustExec(`replace into t (k) values (1), (2)`)
tk.MustQuery(`select * from t`).Check(testkit.Rows("2 3 1", "3 4 2"))
// For issue 14340
tk.MustExec(`drop table if exists t1`)
tk.MustExec(`create table t1(f1 json, f2 real as (cast(f1 as decimal(2,1))))`)
tk.MustGetErrMsg(`INSERT INTO t1 (f1) VALUES (CAST(1000 AS JSON))`, "[types:1690]DECIMAL value is out of range in '(2, 1)'")
tk.MustExec(`set @@sql_mode = ''`)
tk.MustExec(`INSERT INTO t1 (f1) VALUES (CAST(1000 AS JSON))`)
tk.MustQuery(`select * from t1`).Check(testkit.Rows("1000 9.9"))
}
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"))
}
// TestUpdateCastOnlyModifiedValues for issue #4514.
func TestUpdateCastOnlyModifiedValues(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table update_modified (col_1 int, col_2 enum('a', 'b'))")
tk.MustExec("set SQL_MODE=''")
tk.MustExec("insert into update_modified values (0, 3)")
r := tk.MustQuery("SELECT * FROM update_modified")
r.Check(testkit.Rows("0 "))
tk.MustExec("set SQL_MODE=STRICT_ALL_TABLES")
tk.MustExec("update update_modified set col_1 = 1")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
r = tk.MustQuery("SELECT * FROM update_modified")
r.Check(testkit.Rows("1 "))
err := tk.ExecToErr("update update_modified set col_1 = 2, col_2 = 'c'")
require.Error(t, err)
r = tk.MustQuery("SELECT * FROM update_modified")
r.Check(testkit.Rows("1 "))
tk.MustExec("update update_modified set col_1 = 3, col_2 = 'a'")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
r = tk.MustQuery("SELECT * FROM update_modified")
r.Check(testkit.Rows("3 a"))
// Test update a field with different column type.
tk.MustExec(`CREATE TABLE update_with_diff_type (a int, b JSON)`)
tk.MustExec(`INSERT INTO update_with_diff_type VALUES(3, '{"a": "测试"}')`)
tk.MustExec(`UPDATE update_with_diff_type SET a = '300'`)
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
r = tk.MustQuery("SELECT a FROM update_with_diff_type")
r.Check(testkit.Rows("300"))
tk.MustExec(`UPDATE update_with_diff_type SET b = '{"a": "\\u6d4b\\u8bd5"}'`)
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 0 Warnings: 0")
r = tk.MustQuery("SELECT b FROM update_with_diff_type")
r.Check(testkit.Rows(`{"a": "测试"}`))
}
func 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 TestMultipleTableUpdate(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
fillMultiTableForUpdate(tk)
tk.MustExec(`UPDATE items, month SET items.price=month.mprice WHERE items.id=month.mid;`)
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 2 Changed: 2 Warnings: 0")
tk.MustExec("begin")
r := tk.MustQuery("SELECT * FROM items")
r.Check(testkit.Rows("11 month_price_11", "12 items_price_12", "13 month_price_13"))
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;`)
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 2 Changed: 2 Warnings: 0")
tk.MustExec("begin")
r = tk.MustQuery("SELECT * FROM items")
r.Check(testkit.Rows("11 11", "12 items_price_12", "13 13"))
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;`)
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 2 Changed: 2 Warnings: 0")
tk.MustExec("begin")
r = tk.MustQuery("SELECT * FROM items")
r.Check(testkit.Rows("11 month_price_11", "12 items_price_12", "13 month_price_13"))
tk.MustExec("commit")
// 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)
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 4 Changed: 4 Warnings: 0")
// 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)
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 3 Changed: 3 Warnings: 0")
r = tk.MustQuery("select * from t1")
r.Check(testkit.Rows("10", "10"))
// test https://github.com/pingcap/tidb/issues/3604
tk.MustExec("drop table if exists t, t")
tk.MustExec("create table t (a int, b int)")
tk.MustExec("insert into t values(1, 1), (2, 2), (3, 3)")
require.Equal(t, tk.Session().LastMessage(), "Records: 3 Duplicates: 0 Warnings: 0")
tk.MustExec("update t m, t n set m.a = m.a + 1")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 3 Changed: 3 Warnings: 0")
tk.MustQuery("select * from t").Check(testkit.Rows("2 1", "3 2", "4 3"))
tk.MustExec("update t m, t n set n.a = n.a - 1, n.b = n.b + 1")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 3 Changed: 3 Warnings: 0")
tk.MustQuery("select * from t").Check(testkit.Rows("1 2", "2 3", "3 4"))
}
func TestDelete(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
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;`)
rows.Check(testkit.Rows("1 hello"))
tk.MustExec("commit")
// Test delete ignore
tk.MustExec("insert into delete_test values (2, 'abc')")
err := tk.ExecToErr("delete from delete_test where id = (select '2a')")
require.Error(t, err)
err = tk.ExecToErr("delete ignore from delete_test 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'"))
tk.MustExec(`delete from delete_test ;`)
tk.CheckExecResult(1, 0)
tk.MustExec("create view v as select * from delete_test")
err = tk.ExecToErr("delete from v where name = 'aaa'")
require.EqualError(t, err, core.ErrViewInvalid.GenWithStackByArgs("test", "v").Error())
tk.MustExec("drop view v")
tk.MustExec("create sequence seq")
err = tk.ExecToErr("delete from seq")
require.EqualError(t, err, "delete sequence seq is not supported now")
tk.MustExec("drop sequence seq")
}
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 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 TestMultiTableDelete(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
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")
require.Len(t, r.Rows(), 3)
}
func TestQualifiedDelete(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, 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")
require.Len(t, r.Rows(), 0)
tk.MustExec("insert into t1 values (1, 3)")
tk.MustExec("delete from t1 as a where a.c1 = 1")
tk.CheckExecResult(1, 0)
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.ExecToErr("delete t1, t2 from t1 as a join t2 as b where a.c2 = b.c1")
require.Error(t, err)
}
type testCase struct {
data1 []byte
data2 []byte
expected []string
restData []byte
expectedMsg string
}
func checkCases(tests []testCase, ld *executor.LoadDataInfo, t *testing.T, tk *testkit.TestKit, ctx sessionctx.Context, selectSQL, deleteSQL string) {
origin := ld.IgnoreLines
for _, tt := range tests {
ld.IgnoreLines = origin
require.Nil(t, sessiontxn.NewTxn(context.Background(), ctx))
ctx.GetSessionVars().StmtCtx.DupKeyAsWarning = true
ctx.GetSessionVars().StmtCtx.BadNullAsWarning = true
ctx.GetSessionVars().StmtCtx.InLoadDataStmt = true
ctx.GetSessionVars().StmtCtx.InDeleteStmt = false
data, reachLimit, err1 := ld.InsertData(context.Background(), tt.data1, tt.data2)
require.NoError(t, err1)
require.False(t, reachLimit)
err1 = ld.CheckAndInsertOneBatch(context.Background(), ld.GetRows(), ld.GetCurBatchCnt())
require.NoError(t, err1)
ld.SetMaxRowsInBatch(20000)
comment := fmt.Sprintf("data1:%v, data2:%v, data:%v", string(tt.data1), string(tt.data2), string(data))
if tt.restData == nil {
require.Len(t, data, 0, comment)
} else {
require.Equal(t, tt.restData, data, comment)
}
ld.SetMessage()
require.Equal(t, tt.expectedMsg, tk.Session().LastMessage())
ctx.StmtCommit()
txn, err := ctx.Txn(true)
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
tk.MustQuery(selectSQL).Check(testkit.RowsWithSep("|", tt.expected...))
tk.MustExec(deleteSQL)
}
}
func TestLoadDataMissingColumn(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
createSQL := `create table load_data_missing (id int, t timestamp not null)`
tk.MustExec(createSQL)
tk.MustExec("load data local infile '/tmp/nonexistence.csv' ignore into table load_data_missing")
ctx := tk.Session().(sessionctx.Context)
ld, ok := ctx.Value(executor.LoadDataVarKey).(*executor.LoadDataInfo)
require.True(t, ok)
defer ctx.SetValue(executor.LoadDataVarKey, nil)
require.NotNil(t, ld)
deleteSQL := "delete from load_data_missing"
selectSQL := "select id, hour(t), minute(t) from load_data_missing;"
_, reachLimit, err := ld.InsertData(context.Background(), nil, nil)
require.NoError(t, err)
require.False(t, reachLimit)
r := tk.MustQuery(selectSQL)
r.Check(nil)
curTime := types.CurrentTime(mysql.TypeTimestamp)
timeHour := curTime.Hour()
timeMinute := curTime.Minute()
tests := []testCase{
{nil, []byte("12\n"), []string{fmt.Sprintf("12|%v|%v", timeHour, timeMinute)}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 0"},
}
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
tk.MustExec("alter table load_data_missing add column t2 timestamp null")
curTime = types.CurrentTime(mysql.TypeTimestamp)
timeHour = curTime.Hour()
timeMinute = curTime.Minute()
selectSQL = "select id, hour(t), minute(t), t2 from load_data_missing;"
tests = []testCase{
{nil, []byte("12\n"), []string{fmt.Sprintf("12|%v|%v|<nil>", timeHour, timeMinute)}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 0"},
}
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
}
func TestIssue18681(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
createSQL := `drop table if exists load_data_test;
create table load_data_test (a bit(1),b bit(1),c bit(1),d bit(1));`
tk.MustExec(createSQL)
tk.MustExec("load data local infile '/tmp/nonexistence.csv' ignore into table load_data_test")
ctx := tk.Session().(sessionctx.Context)
ld, ok := ctx.Value(executor.LoadDataVarKey).(*executor.LoadDataInfo)
require.True(t, ok)
defer ctx.SetValue(executor.LoadDataVarKey, nil)
require.NotNil(t, ld)
deleteSQL := "delete from load_data_test"
selectSQL := "select bin(a), bin(b), bin(c), bin(d) from load_data_test;"
ctx.GetSessionVars().StmtCtx.DupKeyAsWarning = true
ctx.GetSessionVars().StmtCtx.BadNullAsWarning = true
ld.SetMaxRowsInBatch(20000)
sc := ctx.GetSessionVars().StmtCtx
originIgnoreTruncate := sc.IgnoreTruncate
defer func() {
sc.IgnoreTruncate = originIgnoreTruncate
}()
sc.IgnoreTruncate = false
tests := []testCase{
{nil, []byte("true\tfalse\t0\t1\n"), []string{"1|0|0|1"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 0"},
}
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
require.Equal(t, uint16(0), sc.WarningCount())
}
func TestIssue33298(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
ctx := tk.Session().(sessionctx.Context)
defer ctx.SetValue(executor.LoadDataVarKey, nil)
tk.MustExec("use test")
tk.MustExec("drop table if exists load_data_test")
tk.MustExec("create table load_data_test (a varchar(10), b varchar(10))")
// According to https://dev.mysql.com/doc/refman/8.0/en/load-data.html , fixed-row format should be used when fields
// terminated by '' and enclosed by ''. However, tidb doesn't support it yet and empty terminator leads to infinite
// loop in `indexOfTerminator` (see https://github.com/pingcap/tidb/issues/33298).
require.Error(t, tk.ExecToErr("load data local infile '/tmp/nonexistence.csv' into table load_data_test fields terminated by ''"))
require.Error(t, tk.ExecToErr("load data local infile '/tmp/nonexistence.csv' into table load_data_test fields terminated by '' enclosed by ''"))
}
func TestIssue34358(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
ctx := tk.Session().(sessionctx.Context)
defer ctx.SetValue(executor.LoadDataVarKey, nil)
tk.MustExec("use test")
tk.MustExec("drop table if exists load_data_test")
tk.MustExec("create table load_data_test (a varchar(10), b varchar(10))")
tk.MustExec("load data local infile '/tmp/nonexistence.csv' into table load_data_test ( @v1, @v2 ) set a = @v1, b = @v2")
ld, ok := ctx.Value(executor.LoadDataVarKey).(*executor.LoadDataInfo)
require.True(t, ok)
require.NotNil(t, ld)
checkCases([]testCase{
{nil, []byte("\\N\n"), []string{"<nil>|<nil>"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 0"},
}, ld, t, tk, ctx, "select * from load_data_test", "delete from load_data_test")
}
func TestLoadData(t *testing.T) {
trivialMsg := "Records: 1 Deleted: 0 Skipped: 0 Warnings: 0"
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
createSQL := `drop table if exists load_data_test;
create table load_data_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 varchar(255) default "def", c3 int);`
err := tk.ExecToErr("load data local infile '/tmp/nonexistence.csv' into table load_data_test")
require.Error(t, err)
tk.MustExec(createSQL)
err = tk.ExecToErr("load data infile '/tmp/nonexistence.csv' into table load_data_test")
require.Error(t, err)
tk.MustExec("load data local infile '/tmp/nonexistence.csv' ignore into table load_data_test")
ctx := tk.Session().(sessionctx.Context)
ld, ok := ctx.Value(executor.LoadDataVarKey).(*executor.LoadDataInfo)
require.True(t, ok)
defer ctx.SetValue(executor.LoadDataVarKey, nil)
require.NotNil(t, ld)
deleteSQL := "delete from load_data_test"
selectSQL := "select * from load_data_test;"
// data1 = nil, data2 = nil, fields and lines is default
ctx.GetSessionVars().StmtCtx.DupKeyAsWarning = true
ctx.GetSessionVars().StmtCtx.BadNullAsWarning = true
_, reachLimit, err := ld.InsertData(context.Background(), nil, nil)
require.NoError(t, err)
require.False(t, reachLimit)
err = ld.CheckAndInsertOneBatch(context.Background(), ld.GetRows(), ld.GetCurBatchCnt())
require.NoError(t, err)
ld.SetMaxRowsInBatch(20000)
r := tk.MustQuery(selectSQL)
r.Check(nil)
sc := ctx.GetSessionVars().StmtCtx
originIgnoreTruncate := sc.IgnoreTruncate
defer func() {
sc.IgnoreTruncate = originIgnoreTruncate
}()
sc.IgnoreTruncate = false
// fields and lines are default, InsertData returns data is nil
tests := []testCase{
// data1 = nil, data2 != nil
{nil, []byte("\n"), []string{"1|<nil>|<nil>|<nil>"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
{nil, []byte("\t\n"), []string{"2|0|<nil>|<nil>"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 2"},
{nil, []byte("3\t2\t3\t4\n"), []string{"3|2|3|4"}, nil, trivialMsg},
{nil, []byte("3*1\t2\t3\t4\n"), []string{"3|2|3|4"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
{nil, []byte("4\t2\t\t3\t4\n"), []string{"4|2||3"}, nil, trivialMsg},
{nil, []byte("\t1\t2\t3\t4\n"), []string{"5|1|2|3"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
{nil, []byte("6\t2\t3\n"), []string{"6|2|3|<nil>"}, nil, trivialMsg},
{nil, []byte("\t2\t3\t4\n\t22\t33\t44\n"), []string{"7|2|3|4", "8|22|33|44"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 2"},
{nil, []byte("7\t2\t3\t4\n7\t22\t33\t44\n"), []string{"7|2|3|4"}, nil, "Records: 2 Deleted: 0 Skipped: 1 Warnings: 1"},
// data1 != nil, data2 = nil
{[]byte("\t2\t3\t4"), nil, []string{"9|2|3|4"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
// data1 != nil, data2 != nil
{[]byte("\t2\t3"), []byte("\t4\t5\n"), []string{"10|2|3|4"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
{[]byte("\t2\t3"), []byte("4\t5\n"), []string{"11|2|34|5"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
// data1 != nil, data2 != nil, InsertData returns data isn't nil
{[]byte("\t2\t3"), []byte("\t4\t5"), nil, []byte("\t2\t3\t4\t5"), "Records: 0 Deleted: 0 Skipped: 0 Warnings: 0"},
}
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
// lines starting symbol is "" and terminated symbol length is 2, InsertData returns data is nil
ld.LinesInfo.Terminated = "||"
tests = []testCase{
// data1 != nil, data2 != nil
{[]byte("0\t2\t3"), []byte("\t4\t5||"), []string{"12|2|3|4"}, nil, trivialMsg},
{[]byte("1\t2\t3\t4\t5|"), []byte("|"), []string{"1|2|3|4"}, nil, trivialMsg},
{[]byte("2\t2\t3\t4\t5|"), []byte("|3\t22\t33\t44\t55||"),
[]string{"2|2|3|4", "3|22|33|44"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("3\t2\t3\t4\t5|"), []byte("|4\t22\t33||"), []string{
"3|2|3|4", "4|22|33|<nil>"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("4\t2\t3\t4\t5|"), []byte("|5\t22\t33||6\t222||"),
[]string{"4|2|3|4", "5|22|33|<nil>", "6|222|<nil>|<nil>"}, nil, "Records: 3 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("6\t2\t3"), []byte("4\t5||"), []string{"6|2|34|5"}, nil, trivialMsg},
}
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
// fields and lines aren't default, InsertData returns data is nil
ld.FieldsInfo.Terminated = "\\"
ld.LinesInfo.Starting = "xxx"
ld.LinesInfo.Terminated = "|!#^"
tests = []testCase{
// data1 = nil, data2 != nil
{nil, []byte("xxx|!#^"), []string{"13|<nil>|<nil>|<nil>"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
{nil, []byte("xxx\\|!#^"), []string{"14|0|<nil>|<nil>"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 2"},
{nil, []byte("xxx3\\2\\3\\4|!#^"), []string{"3|2|3|4"}, nil, trivialMsg},
{nil, []byte("xxx4\\2\\\\3\\4|!#^"), []string{"4|2||3"}, nil, trivialMsg},
{nil, []byte("xxx\\1\\2\\3\\4|!#^"), []string{"15|1|2|3"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
{nil, []byte("xxx6\\2\\3|!#^"), []string{"6|2|3|<nil>"}, nil, trivialMsg},
{nil, []byte("xxx\\2\\3\\4|!#^xxx\\22\\33\\44|!#^"), []string{
"16|2|3|4",
"17|22|33|44"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 2"},
{nil, []byte("\\2\\3\\4|!#^\\22\\33\\44|!#^xxx\\222\\333\\444|!#^"), []string{
"18|222|333|444"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
// data1 != nil, data2 = nil
{[]byte("xxx\\2\\3\\4"), nil, []string{"19|2|3|4"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
{[]byte("\\2\\3\\4|!#^"), nil, []string{}, nil, "Records: 0 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("\\2\\3\\4|!#^xxx18\\22\\33\\44|!#^"), nil,
[]string{"18|22|33|44"}, nil, trivialMsg},
// data1 != nil, data2 != nil
{[]byte("xxx10\\2\\3"), []byte("\\4|!#^"),
[]string{"10|2|3|4"}, nil, trivialMsg},
{[]byte("10\\2\\3xx"), []byte("x11\\4\\5|!#^"),
[]string{"11|4|5|<nil>"}, nil, trivialMsg},
{[]byte("xxx21\\2\\3\\4\\5|!"), []byte("#^"),
[]string{"21|2|3|4"}, nil, trivialMsg},
{[]byte("xxx22\\2\\3\\4\\5|!"), []byte("#^xxx23\\22\\33\\44\\55|!#^"),
[]string{"22|2|3|4", "23|22|33|44"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("xxx23\\2\\3\\4\\5|!"), []byte("#^xxx24\\22\\33|!#^"),
[]string{"23|2|3|4", "24|22|33|<nil>"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("xxx24\\2\\3\\4\\5|!"), []byte("#^xxx25\\22\\33|!#^xxx26\\222|!#^"),
[]string{"24|2|3|4", "25|22|33|<nil>", "26|222|<nil>|<nil>"}, nil, "Records: 3 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("xxx25\\2\\3\\4\\5|!"), []byte("#^26\\22\\33|!#^xxx27\\222|!#^"),
[]string{"25|2|3|4", "27|222|<nil>|<nil>"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("xxx\\2\\3"), []byte("4\\5|!#^"), []string{"28|2|34|5"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
// InsertData returns data isn't nil
{nil, []byte("\\2\\3\\4|!#^"), nil, []byte("#^"), "Records: 0 Deleted: 0 Skipped: 0 Warnings: 0"},
{nil, []byte("\\4\\5"), nil, []byte("\\5"), "Records: 0 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("\\2\\3"), []byte("\\4\\5"), nil, []byte("\\5"), "Records: 0 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("xxx1\\2\\3|"), []byte("!#^\\4\\5|!#"),
[]string{"1|2|3|<nil>"}, []byte("!#"), trivialMsg},
{[]byte("xxx1\\2\\3\\4\\5|!"), []byte("#^xxx2\\22\\33|!#^3\\222|!#^"),
[]string{"1|2|3|4", "2|22|33|<nil>"}, []byte("#^"), "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("xx1\\2\\3"), []byte("\\4\\5|!#^"), nil, []byte("#^"), "Records: 0 Deleted: 0 Skipped: 0 Warnings: 0"},
}
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
// lines starting symbol is the same as terminated symbol, InsertData returns data is nil
ld.LinesInfo.Terminated = "xxx"
tests = []testCase{
// data1 = nil, data2 != nil
{nil, []byte("xxxxxx"), []string{"29|<nil>|<nil>|<nil>"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
{nil, []byte("xxx3\\2\\3\\4xxx"), []string{"3|2|3|4"}, nil, trivialMsg},
{nil, []byte("xxx\\2\\3\\4xxxxxx\\22\\33\\44xxx"),
[]string{"30|2|3|4", "31|22|33|44"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 2"},
// data1 != nil, data2 = nil
{[]byte("xxx\\2\\3\\4"), nil, []string{"32|2|3|4"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
// data1 != nil, data2 != nil
{[]byte("xxx10\\2\\3"), []byte("\\4\\5xxx"), []string{"10|2|3|4"}, nil, trivialMsg},
{[]byte("xxxxx10\\2\\3"), []byte("\\4\\5xxx"), []string{"33|2|3|4"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
{[]byte("xxx21\\2\\3\\4\\5xx"), []byte("x"), []string{"21|2|3|4"}, nil, trivialMsg},
{[]byte("xxx32\\2\\3\\4\\5x"), []byte("xxxxx33\\22\\33\\44\\55xxx"),
[]string{"32|2|3|4", "33|22|33|44"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("xxx33\\2\\3\\4\\5xxx"), []byte("xxx34\\22\\33xxx"),
[]string{"33|2|3|4", "34|22|33|<nil>"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("xxx34\\2\\3\\4\\5xx"), []byte("xxxx35\\22\\33xxxxxx36\\222xxx"),
[]string{"34|2|3|4", "35|22|33|<nil>", "36|222|<nil>|<nil>"}, nil, "Records: 3 Deleted: 0 Skipped: 0 Warnings: 0"},
// InsertData returns data isn't nil
{nil, []byte("\\2\\3\\4xxxx"), nil, []byte("xxxx"), "Records: 0 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("\\2\\3\\4xxx"), nil, []string{"37|<nil>|<nil>|<nil>"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 1"},
{[]byte("\\2\\3\\4xxxxxx11\\22\\33\\44xxx"), nil,
[]string{"38|<nil>|<nil>|<nil>", "39|<nil>|<nil>|<nil>"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 2"},
{[]byte("xx10\\2\\3"), []byte("\\4\\5xxx"), nil, []byte("xxx"), "Records: 0 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("xxx10\\2\\3"), []byte("\\4xxxx"), []string{"10|2|3|4"}, []byte("x"), trivialMsg},
{[]byte("xxx10\\2\\3\\4\\5x"), []byte("xx11\\22\\33xxxxxx12\\222xxx"),
[]string{"10|2|3|4", "40|<nil>|<nil>|<nil>"}, []byte("xxx"), "Records: 2 Deleted: 0 Skipped: 0 Warnings: 1"},
}
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
// test line terminator in field quoter
ld.LinesInfo.Terminated = "\n"
ld.FieldsInfo.Enclosed = '"'
tests = []testCase{
{[]byte("xxx1\\1\\\"2\n\"\\3\nxxx4\\4\\\"5\n5\"\\6"), nil, []string{"1|1|2\n|3", "4|4|5\n5|6"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
}
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
ld.LinesInfo.Terminated = "#\n"
ld.FieldsInfo.Terminated = "#"
tests = []testCase{
{[]byte("xxx1#\nxxx2#\n"), nil, []string{"1|<nil>|<nil>|<nil>", "2|<nil>|<nil>|<nil>"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("xxx1#2#3#4#\nnxxx2#3#4#5#\n"), nil, []string{"1|2|3|4", "2|3|4|5"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("xxx1#2#\"3#\"#\"4\n\"#\nxxx2#3#\"#4#\n\"#5#\n"), nil, []string{"1|2|3#|4", "2|3|#4#\n|5"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
}
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
ld.LinesInfo.Terminated = "#"
ld.FieldsInfo.Terminated = "##"
ld.LinesInfo.Starting = ""
tests = []testCase{
{[]byte("1#2#"), nil, []string{"1|<nil>|<nil>|<nil>", "2|<nil>|<nil>|<nil>"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("1##2##3##4#2##3##4##5#"), nil, []string{"1|2|3|4", "2|3|4|5"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
{[]byte("1##2##\"3##\"##\"4\n\"#2##3##\"##4#\"##5#"), nil, []string{"1|2|3##|4", "2|3|##4#|5"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
}
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
}
func TestLoadDataEscape(t *testing.T) {
trivialMsg := "Records: 1 Deleted: 0 Skipped: 0 Warnings: 0"
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test; drop table if exists load_data_test;")
tk.MustExec("CREATE TABLE load_data_test (id INT NOT NULL PRIMARY KEY, value TEXT NOT NULL) CHARACTER SET utf8")
tk.MustExec("load data local infile '/tmp/nonexistence.csv' into table load_data_test")
ctx := tk.Session().(sessionctx.Context)
ld, ok := ctx.Value(executor.LoadDataVarKey).(*executor.LoadDataInfo)
require.True(t, ok)
defer ctx.SetValue(executor.LoadDataVarKey, nil)
require.NotNil(t, ld)
// test escape
tests := []testCase{
// data1 = nil, data2 != nil
{nil, []byte("1\ta string\n"), []string{"1|a string"}, nil, trivialMsg},
{nil, []byte("2\tstr \\t\n"), []string{"2|str \t"}, nil, trivialMsg},
{nil, []byte("3\tstr \\n\n"), []string{"3|str \n"}, nil, trivialMsg},
{nil, []byte("4\tboth \\t\\n\n"), []string{"4|both \t\n"}, nil, trivialMsg},
{nil, []byte("5\tstr \\\\\n"), []string{"5|str \\"}, nil, trivialMsg},
{nil, []byte("6\t\\r\\t\\n\\0\\Z\\b\n"), []string{"6|" + string([]byte{'\r', '\t', '\n', 0, 26, '\b'})}, nil, trivialMsg},
{nil, []byte("7\trtn0ZbN\n"), []string{"7|" + string([]byte{'r', 't', 'n', '0', 'Z', 'b', 'N'})}, nil, trivialMsg},
{nil, []byte("8\trtn0Zb\\N\n"), []string{"8|" + string([]byte{'r', 't', 'n', '0', 'Z', 'b', 'N'})}, nil, trivialMsg},
{nil, []byte("9\ttab\\ tab\n"), []string{"9|tab tab"}, nil, trivialMsg},
// data broken at escape character.
{[]byte("1\ta string\\"), []byte("\n1\n"), []string{"1|a string\n1"}, nil, trivialMsg},
}
deleteSQL := "delete from load_data_test"
selectSQL := "select * from load_data_test;"
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
}
// TestLoadDataSpecifiedColumns reuse TestLoadDataEscape's test case :-)
func TestLoadDataSpecifiedColumns(t *testing.T) {
trivialMsg := "Records: 1 Deleted: 0 Skipped: 0 Warnings: 0"
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test; drop table if exists load_data_test;")
tk.MustExec(`create table load_data_test (id int PRIMARY KEY AUTO_INCREMENT, c1 int, c2 varchar(255) default "def", c3 int default 0);`)
tk.MustExec("load data local infile '/tmp/nonexistence.csv' into table load_data_test (c1, c2)")
ctx := tk.Session().(sessionctx.Context)
ld, ok := ctx.Value(executor.LoadDataVarKey).(*executor.LoadDataInfo)
require.True(t, ok)
defer ctx.SetValue(executor.LoadDataVarKey, nil)
require.NotNil(t, ld)
// test
tests := []testCase{
// data1 = nil, data2 != nil
{nil, []byte("7\ta string\n"), []string{"1|7|a string|0"}, nil, trivialMsg},
{nil, []byte("8\tstr \\t\n"), []string{"2|8|str \t|0"}, nil, trivialMsg},
{nil, []byte("9\tstr \\n\n"), []string{"3|9|str \n|0"}, nil, trivialMsg},
{nil, []byte("10\tboth \\t\\n\n"), []string{"4|10|both \t\n|0"}, nil, trivialMsg},
{nil, []byte("11\tstr \\\\\n"), []string{"5|11|str \\|0"}, nil, trivialMsg},
{nil, []byte("12\t\\r\\t\\n\\0\\Z\\b\n"), []string{"6|12|" + string([]byte{'\r', '\t', '\n', 0, 26, '\b'}) + "|0"}, nil, trivialMsg},
{nil, []byte("\\N\ta string\n"), []string{"7|<nil>|a string|0"}, nil, trivialMsg},
}
deleteSQL := "delete from load_data_test"
selectSQL := "select * from load_data_test;"
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
}
func TestLoadDataIgnoreLines(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test; drop table if exists load_data_test;")
tk.MustExec("CREATE TABLE load_data_test (id INT NOT NULL PRIMARY KEY, value TEXT NOT NULL) CHARACTER SET utf8")
tk.MustExec("load data local infile '/tmp/nonexistence.csv' into table load_data_test ignore 1 lines")
ctx := tk.Session().(sessionctx.Context)
ld, ok := ctx.Value(executor.LoadDataVarKey).(*executor.LoadDataInfo)
require.True(t, ok)
defer ctx.SetValue(executor.LoadDataVarKey, nil)
require.NotNil(t, ld)
tests := []testCase{
{nil, []byte("1\tline1\n2\tline2\n"), []string{"2|line2"}, nil, "Records: 1 Deleted: 0 Skipped: 0 Warnings: 0"},
{nil, []byte("1\tline1\n2\tline2\n3\tline3\n"), []string{"2|line2", "3|line3"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 0"},
}
deleteSQL := "delete from load_data_test"
selectSQL := "select * from load_data_test;"
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
}
func TestLoadDataReplace(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("USE test; DROP TABLE IF EXISTS load_data_replace;")
tk.MustExec("CREATE TABLE load_data_replace (id INT NOT NULL PRIMARY KEY, value TEXT NOT NULL)")
tk.MustExec("INSERT INTO load_data_replace VALUES(1,'val 1'),(2,'val 2')")
tk.MustExec("LOAD DATA LOCAL INFILE '/tmp/nonexistence.csv' REPLACE INTO TABLE load_data_replace")
ctx := tk.Session().(sessionctx.Context)
ld, ok := ctx.Value(executor.LoadDataVarKey).(*executor.LoadDataInfo)
require.True(t, ok)
defer ctx.SetValue(executor.LoadDataVarKey, nil)
require.NotNil(t, ld)
tests := []testCase{
{nil, []byte("1\tline1\n2\tline2\n"), []string{"1|line1", "2|line2"}, nil, "Records: 2 Deleted: 2 Skipped: 0 Warnings: 0"},
{nil, []byte("2\tnew line2\n3\tnew line3\n"), []string{"1|line1", "2|new line2", "3|new line3"}, nil, "Records: 2 Deleted: 1 Skipped: 0 Warnings: 0"},
}
deleteSQL := "DO 1"
selectSQL := "TABLE load_data_replace;"
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
}
// TestLoadDataOverflowBigintUnsigned related to issue 6360
func TestLoadDataOverflowBigintUnsigned(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test; drop table if exists load_data_test;")
tk.MustExec("CREATE TABLE load_data_test (a bigint unsigned);")
tk.MustExec("load data local infile '/tmp/nonexistence.csv' into table load_data_test")
ctx := tk.Session().(sessionctx.Context)
ld, ok := ctx.Value(executor.LoadDataVarKey).(*executor.LoadDataInfo)
require.True(t, ok)
defer ctx.SetValue(executor.LoadDataVarKey, nil)
require.NotNil(t, ld)
tests := []testCase{
{nil, []byte("-1\n-18446744073709551615\n-18446744073709551616\n"), []string{"0", "0", "0"}, nil, "Records: 3 Deleted: 0 Skipped: 0 Warnings: 3"},
{nil, []byte("-9223372036854775809\n18446744073709551616\n"), []string{"0", "18446744073709551615"}, nil, "Records: 2 Deleted: 0 Skipped: 0 Warnings: 2"},
}
deleteSQL := "delete from load_data_test"
selectSQL := "select * from load_data_test;"
checkCases(tests, ld, t, tk, ctx, selectSQL, deleteSQL)
}
func TestLoadDataIntoPartitionedTable(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table range_t (a int, b int) partition by range (a) ( " +
"partition p0 values less than (4)," +
"partition p1 values less than (7)," +
"partition p2 values less than (11))")
tk.MustExec("load data local infile '/tmp/nonexistence.csv' into table range_t fields terminated by ','")
ctx := tk.Session().(sessionctx.Context)
ld := ctx.Value(executor.LoadDataVarKey).(*executor.LoadDataInfo)
require.Nil(t, sessiontxn.NewTxn(context.Background(), ctx))
_, _, err := ld.InsertData(context.Background(), nil, []byte("1,2\n3,4\n5,6\n7,8\n9,10\n"))
require.NoError(t, err)
err = ld.CheckAndInsertOneBatch(context.Background(), ld.GetRows(), ld.GetCurBatchCnt())
require.NoError(t, err)
ld.SetMaxRowsInBatch(20000)
ld.SetMessage()
ctx.StmtCommit()
txn, err := ctx.Txn(true)
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
}
func TestNullDefault(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test; drop table if exists test_null_default;")
tk.MustExec("set timestamp = 1234")
tk.MustExec("set time_zone = '+08:00'")
tk.MustExec("create table test_null_default (ts timestamp null default current_timestamp)")
tk.MustExec("insert into test_null_default values (null)")
tk.MustQuery("select * from test_null_default").Check(testkit.Rows("<nil>"))
tk.MustExec("insert into test_null_default values ()")
tk.MustQuery("select * from test_null_default").Check(testkit.Rows("<nil>", "1970-01-01 08:20:34"))
}
func TestNotNullDefault(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test; drop table if exists t1,t2;")
defer tk.MustExec("drop table t1,t2")
tk.MustExec("create table t1 (a int not null default null default 1);")
tk.MustExec("create table t2 (a int);")
tk.MustExec("alter table t2 change column a a int not null default null default 1;")
}
func TestLatch(t *testing.T) {
store, err := mockstore.NewMockStore(
// Small latch slot size to make conflicts.
mockstore.WithTxnLocalLatches(64),
)
require.NoError(t, err)
defer func() {
err := store.Close()
require.NoError(t, err)
}()
dom, err1 := session.BootstrapSession(store)
require.Nil(t, err1)
defer dom.Close()
setTxnTk := testkit.NewTestKit(t, store)
setTxnTk.MustExec("set global tidb_txn_mode=''")
tk1 := testkit.NewTestKit(t, store)
tk1.MustExec("use test")
tk1.MustExec("drop table if exists t")
tk1.MustExec("create table t (id int)")
tk1.MustExec("set @@tidb_disable_txn_auto_retry = true")
tk2 := testkit.NewTestKit(t, store)
tk2.MustExec("use test")
tk1.MustExec("set @@tidb_disable_txn_auto_retry = true")
fn := func() {
tk1.MustExec("begin")
for i := 0; i < 100; i++ {
tk1.MustExec(fmt.Sprintf("insert into t values (%d)", i))
}
tk2.MustExec("begin")
for i := 100; i < 200; i++ {
tk1.MustExec(fmt.Sprintf("insert into t values (%d)", i))
}
tk2.MustExec("commit")
}
// txn1 and txn2 data range do not overlap, using latches should not
// result in txn conflict.
fn()
tk1.MustExec("commit")
tk1.MustExec("truncate table t")
fn()
tk1.MustExec("commit")
// Test the error type of latch and it could be retry if TiDB enable the retry.
tk1.MustExec("begin")
tk1.MustExec("update t set id = id + 1")
tk2.MustExec("update t set id = id + 1")
tk1.MustGetDBError("commit", kv.ErrWriteConflictInTiDB)
tk1.MustExec("set @@tidb_disable_txn_auto_retry = 0")
tk1.MustExec("update t set id = id + 1")
tk2.MustExec("update t set id = id + 1")
tk1.MustExec("commit")
}
// TestIssue4067 Test issue https://github.com/pingcap/tidb/issues/4067
func TestIssue4067(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1, t2")
tk.MustExec("create table t1(id int)")
tk.MustExec("create table t2(id int)")
tk.MustExec("insert into t1 values(123)")
tk.MustExec("insert into t2 values(123)")
tk.MustExec("delete from t1 where id not in (select id from t2)")
tk.MustQuery("select * from t1").Check(testkit.Rows("123"))
tk.MustExec("delete from t1 where id in (select id from t2)")
tk.MustQuery("select * from t1").Check(nil)
}
func TestInsertCalculatedValue(t *testing.T) {
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(a int, b int)")
tk.MustExec("insert into t set a=1, b=a+1")
tk.MustQuery("select a, b from t").Check(testkit.Rows("1 2"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int default 100, b int)")
tk.MustExec("insert into t set b=a+1, a=1")
tk.MustQuery("select a, b from t").Check(testkit.Rows("1 101"))
tk.MustExec("insert into t (b) value (a)")
tk.MustQuery("select * from t where b = 100").Check(testkit.Rows("100 100"))
tk.MustExec("insert into t set a=2, b=a+1")
tk.MustQuery("select * from t where a = 2").Check(testkit.Rows("2 3"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (c int)")
tk.MustExec("insert into test.t set test.t.c = '1'")
tk.MustQuery("select * from t").Check(testkit.Rows("1"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int default 1)")
tk.MustExec("insert into t values (a)")
tk.MustQuery("select * from t").Check(testkit.Rows("1"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a int, b int, c int, d int)")
tk.MustExec("insert into t value (1, 2, a+1, b+1)")
tk.MustQuery("select * from t").Check(testkit.Rows("1 2 2 3"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a int not null)")
tk.MustExec("insert into t values (a+2)")
tk.MustExec("insert into t values (a)")
tk.MustQuery("select * from t order by a").Check(testkit.Rows("0", "2"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a bigint not null, b bigint not null)")
tk.MustExec("insert into t value(b + 1, a)")
tk.MustExec("insert into t set a = b + a, b = a + 1")
tk.MustExec("insert into t value(1000, a)")
tk.MustExec("insert t set b = sqrt(a + 4), a = 10")
tk.MustQuery("select * from t order by a").Check(testkit.Rows("0 1", "1 1", "10 2", "1000 1000"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int)")
tk.MustExec("insert into t values(a)")
tk.MustQuery("select * from t").Check(testkit.Rows("<nil>"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a enum('a', 'b'))")
tk.MustExec("insert into t values(a)")
tk.MustQuery("select * from t").Check(testkit.Rows("<nil>"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a enum('a', 'b') default 'a')")
tk.MustExec("insert into t values(a)")
tk.MustExec("insert into t values(a+1)")
tk.MustQuery("select * from t order by a").Check(testkit.Rows("a", "b"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a blob)")
tk.MustExec("insert into t values(a)")
tk.MustQuery("select * from t").Check(testkit.Rows("<nil>"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a varchar(20) default 'a')")
tk.MustExec("insert into t values(a)")
tk.MustExec("insert into t values(upper(a))")
tk.MustQuery("select * from t order by a").Check(testkit.Rows("A", "a"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a varchar(20) not null, b varchar(20))")
tk.MustExec("insert into t value (a, b)")
tk.MustQuery("select * from t").Check(testkit.Rows(" <nil>"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int, b int)")
tk.MustExec("insert into t values(a*b, b*b)")
tk.MustQuery("select * from t").Check(testkit.Rows("<nil> <nil>"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a json not null, b int)")
// TODO: MySQL reports 3156 instead of ErrTruncatedWrongValueForField.
tk.MustGetErrCode("insert into t value (a,a->'$')", mysql.ErrTruncatedWrongValueForField)
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a json not null, b varchar(10))")
tk.MustExec("insert into t value (a,a->'$')")
tk.MustQuery("select * from t").Check(testkit.Rows("null null"))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a json, b int, c int as (a->'$.a'))")
tk.MustExec("insert into t (a, b) value (a, a->'$.a'+1)")
tk.MustExec("insert into t (b) value (a->'$.a'+1)")
tk.MustQuery("select * from t").Check(testkit.Rows("<nil> <nil> <nil>", "<nil> <nil> <nil>"))
tk.MustExec(`insert into t (a, b) value ('{"a": 1}', a->'$.a'+1)`)
tk.MustQuery("select * from t where c = 1").Check(testkit.Rows(`{"a": 1} 2 1`))
tk.MustExec("truncate table t")
tk.MustExec("insert t set b = c + 1")
tk.MustQuery("select * from t").Check(testkit.Rows("<nil> <nil> <nil>"))
tk.MustExec("truncate table t")
tk.MustExec(`insert t set a = '{"a": 1}', b = c`)
tk.MustQuery("select * from t").Check(testkit.Rows(`{"a": 1} <nil> 1`))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int auto_increment key, b int)")
tk.MustExec("insert into t (b) value (a)")
tk.MustExec("insert into t value (a, a+1)")
tk.MustExec("set SQL_MODE=NO_AUTO_VALUE_ON_ZERO")
tk.MustExec("insert into t (b) value (a+1)")
tk.MustQuery("select * from t order by a").Check(testkit.Rows("1 0", "2 1", "3 1"))
tk.MustExec("set SQL_MODE=STRICT_ALL_TABLES")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int not null, b int, c int as (sqrt(a)))")
tk.MustExec("insert t set b = a, a = 4")
tk.MustQuery("select * from t").Check(testkit.Rows("4 0 2"))
}
func TestDataTooLongErrMsg(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table t(a varchar(2));")
err := tk.ExecToErr("insert into t values('123');")
require.True(t, types.ErrDataTooLong.Equal(err))
require.EqualError(t, err, "[types:1406]Data too long for column 'a' at row 1")
tk.MustExec("insert into t values('12')")
err = tk.ExecToErr("update t set a = '123' where a = '12';")
require.True(t, types.ErrDataTooLong.Equal(err))
require.EqualError(t, err, "[types:1406]Data too long for column 'a' at row 1")
}
func TestUpdateSelect(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table msg (id varchar(8), b int, status int, primary key (id, b))")
tk.MustExec("insert msg values ('abc', 1, 1)")
tk.MustExec("create table detail (id varchar(8), start varchar(8), status int, index idx_start(start))")
tk.MustExec("insert detail values ('abc', '123', 2)")
tk.MustExec("UPDATE msg SET msg.status = (SELECT detail.status FROM detail WHERE msg.id = detail.id)")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
tk.MustExec("admin check table msg")
}
func TestUpdateDelete(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("CREATE TABLE ttt (id bigint(20) NOT NULL, host varchar(30) NOT NULL, PRIMARY KEY (id), UNIQUE KEY i_host (host));")
tk.MustExec("insert into ttt values (8,8),(9,9);")
tk.MustExec("begin")
tk.MustExec("update ttt set id = 0, host='9' where id = 9 limit 1;")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
tk.MustExec("delete from ttt where id = 0 limit 1;")
tk.MustQuery("select * from ttt use index (i_host) order by host;").Check(testkit.Rows("8 8"))
tk.MustExec("update ttt set id = 0, host='8' where id = 8 limit 1;")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
tk.MustExec("delete from ttt where id = 0 limit 1;")
tk.MustQuery("select * from ttt use index (i_host) order by host;").Check(testkit.Rows())
tk.MustExec("commit")
tk.MustExec("admin check table ttt;")
tk.MustExec("drop table ttt")
}
func TestUpdateAffectRowCnt(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table a(id int auto_increment, a int default null, primary key(id))")
tk.MustExec("insert into a values (1, 1001), (2, 1001), (10001, 1), (3, 1)")
tk.MustExec("update a set id = id*10 where a = 1001")
ctx := tk.Session().(sessionctx.Context)
require.Equal(t, uint64(2), ctx.GetSessionVars().StmtCtx.AffectedRows())
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 2 Changed: 2 Warnings: 0")
tk.MustExec("drop table a")
tk.MustExec("create table a ( a bigint, b bigint)")
tk.MustExec("insert into a values (1, 1001), (2, 1001), (10001, 1), (3, 1)")
tk.MustExec("update a set a = a*10 where b = 1001")
ctx = tk.Session().(sessionctx.Context)
require.Equal(t, uint64(2), ctx.GetSessionVars().StmtCtx.AffectedRows())
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 2 Changed: 2 Warnings: 0")
}
func TestReplaceLog(t *testing.T) {
store, domain := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table testLog (a int not null primary key, b int unique key);`)
// Make some dangling index.
ctx := mock.NewContext()
ctx.Store = store
is := domain.InfoSchema()
dbName := model.NewCIStr("test")
tblName := model.NewCIStr("testLog")
tbl, err := is.TableByName(dbName, tblName)
require.NoError(t, err)
tblInfo := tbl.Meta()
idxInfo := tblInfo.FindIndexByName("b")
indexOpr := tables.NewIndex(tblInfo.ID, tblInfo, idxInfo)
txn, err := store.Begin()
require.NoError(t, err)
_, err = indexOpr.Create(ctx, txn, types.MakeDatums(1), kv.IntHandle(1), nil)
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
err = tk.ExecToErr(`replace into testLog values (0, 0), (1, 1);`)
require.Error(t, err)
require.EqualError(t, err, `can not be duplicated row, due to old row not found. handle 1 not found`)
tk.MustQuery(`admin cleanup index testLog b;`).Check(testkit.Rows("1"))
}
// TestRebaseIfNeeded is for issue 7422.
// There is no need to do the rebase when updating a record if the auto-increment ID not changed.
// This could make the auto ID increasing speed slower.
func TestRebaseIfNeeded(t *testing.T) {
store, domain := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t (a int not null primary key auto_increment, b int unique key);`)
tk.MustExec(`insert into t (b) values (1);`)
ctx := mock.NewContext()
ctx.Store = store
tbl, err := domain.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
require.NoError(t, err)
require.Nil(t, sessiontxn.NewTxn(context.Background(), ctx))
// AddRecord directly here will skip to rebase the auto ID in the insert statement,
// which could simulate another TiDB adds a large auto ID.
_, err = tbl.AddRecord(ctx, types.MakeDatums(30001, 2))
require.NoError(t, err)
txn, err := ctx.Txn(true)
require.NoError(t, err)
require.NoError(t, txn.Commit(context.Background()))
tk.MustExec(`update t set b = 3 where a = 30001;`)
tk.MustExec(`insert into t (b) values (4);`)
tk.MustQuery(`select a from t where b = 4;`).Check(testkit.Rows("2"))
tk.MustExec(`insert into t set b = 3 on duplicate key update a = a;`)
tk.MustExec(`insert into t (b) values (5);`)
tk.MustQuery(`select a from t where b = 5;`).Check(testkit.Rows("4"))
tk.MustExec(`insert into t set b = 3 on duplicate key update a = a + 1;`)
tk.MustExec(`insert into t (b) values (6);`)
tk.MustQuery(`select a from t where b = 6;`).Check(testkit.Rows("30003"))
}
func TestDeferConstraintCheckForDelete(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set tidb_constraint_check_in_place = 0")
tk.MustExec("set @@tidb_txn_mode = 'optimistic'")
tk.MustExec("use test")
tk.MustExec("drop table if exists t1, t2, t3, t4, t5")
tk.MustExec("create table t1(i int primary key, j int)")
tk.MustExec("insert into t1 values(1, 2)")
tk.MustExec("begin")
tk.MustExec("insert into t1 values(1, 3)")
tk.MustExec("delete from t1 where j = 3")
tk.MustGetErrMsg("commit", "previous statement: delete from t1 where j = 3: [kv:1062]Duplicate entry '1' for key 't1.PRIMARY'")
tk.MustExec("rollback")
tk.MustExec("create table t2(i int, j int, unique index idx(i))")
tk.MustExec("insert into t2 values(1, 2)")
tk.MustExec("begin")
tk.MustExec("insert into t2 values(1, 3)")
tk.MustExec("delete from t2 where j = 3")
tk.MustGetErrMsg("commit", "previous statement: delete from t2 where j = 3: [kv:1062]Duplicate entry '1' for key 't2.idx'")
tk.MustExec("admin check table t2")
tk.MustExec("create table t3(i int, j int, primary key(i))")
tk.MustExec("begin")
tk.MustExec("insert into t3 values(1, 3)")
tk.MustExec("delete from t3 where j = 3")
tk.MustExec("commit")
tk.MustExec("create table t4(i int, j int, primary key(i))")
tk.MustExec("begin")
tk.MustExec("insert into t4 values(1, 3)")
tk.MustExec("delete from t4 where j = 3")
tk.MustExec("insert into t4 values(2, 3)")
tk.MustExec("commit")
tk.MustExec("admin check table t4")
tk.MustQuery("select * from t4").Check(testkit.Rows("2 3"))
tk.MustExec("create table t5(i int, j int, primary key(i))")
tk.MustExec("begin")
tk.MustExec("insert into t5 values(1, 3)")
tk.MustExec("delete from t5 where j = 3")
tk.MustExec("insert into t5 values(1, 4)")
tk.MustExec("commit")
tk.MustExec("admin check table t5")
tk.MustQuery("select * from t5").Check(testkit.Rows("1 4"))
}
func TestDeferConstraintCheckForInsert(t *testing.T) {
store := testkit.CreateMockStore(t)
setTxnTk := testkit.NewTestKit(t, store)
setTxnTk.MustExec("set global tidb_txn_mode=''")
tk := testkit.NewTestKit(t, store)
tk.MustExec(`use test`)
tk.MustExec(`drop table if exists t;create table t (a int primary key, b int);`)
tk.MustExec(`insert into t values (1,2),(2,2)`)
err := tk.ExecToErr("update t set a=a+1 where b=2")
require.Error(t, err)
tk.MustExec(`drop table if exists t;create table t (i int key);`)
tk.MustExec(`insert t values (1);`)
tk.MustExec(`set tidb_constraint_check_in_place = 1;`)
tk.MustExec(`begin;`)
err = tk.ExecToErr(`insert t values (1);`)
require.Error(t, err)
tk.MustExec(`update t set i = 2 where i = 1;`)
tk.MustExec(`commit;`)
tk.MustQuery(`select * from t;`).Check(testkit.Rows("2"))
tk.MustExec(`set tidb_constraint_check_in_place = 0;`)
tk.MustExec("replace into t values (1),(2)")
tk.MustExec("begin")
err = tk.ExecToErr("update t set i = 2 where i = 1")
require.Error(t, err)
err = tk.ExecToErr("insert into t values (1) on duplicate key update i = i + 1")
require.Error(t, err)
tk.MustExec("rollback")
tk.MustExec(`drop table t; create table t (id int primary key, v int unique);`)
tk.MustExec(`insert into t values (1, 1)`)
tk.MustExec(`set tidb_constraint_check_in_place = 1;`)
tk.MustExec(`set @@autocommit = 0;`)
err = tk.ExecToErr("insert into t values (3, 1)")
require.Error(t, err)
err = tk.ExecToErr("insert into t values (1, 3)")
require.Error(t, err)
tk.MustExec("commit")
tk.MustExec(`set tidb_constraint_check_in_place = 0;`)
tk.MustExec("insert into t values (3, 1)")
tk.MustExec("insert into t values (1, 3)")
err = tk.ExecToErr("commit")
require.Error(t, err)
// Cover the temporary table.
for val := range []int{0, 1} {
tk.MustExec("set tidb_constraint_check_in_place = ?", val)
tk.MustExec("drop table t")
tk.MustExec("create global temporary table t (a int primary key, b int) on commit delete rows")
tk.MustExec("begin")
tk.MustExec("insert into t values (1, 1)")
err = tk.ExecToErr(`insert into t values (1, 3)`)
require.Error(t, err)
tk.MustExec("insert into t values (2, 2)")
err = tk.ExecToErr("update t set a = a + 1 where a = 1")
require.Error(t, err)
err = tk.ExecToErr("insert into t values (1, 3) on duplicated key update a = a + 1")
require.Error(t, err)
tk.MustExec("commit")
tk.MustExec("drop table t")
tk.MustExec("create global temporary table t (a int, b int unique) on commit delete rows")
tk.MustExec("begin")
tk.MustExec("insert into t values (1, 1)")
err = tk.ExecToErr(`insert into t values (3, 1)`)
require.Error(t, err)
tk.MustExec("insert into t values (2, 2)")
err = tk.ExecToErr("update t set b = b + 1 where a = 1")
require.Error(t, err)
err = tk.ExecToErr("insert into t values (3, 1) on duplicated key update b = b + 1")
require.Error(t, err)
tk.MustExec("commit")
// cases for temporary table
tk.MustExec("drop table if exists tl")
tk.MustExec("create temporary table tl (a int primary key, b int)")
tk.MustExec("begin")
tk.MustExec("insert into tl values (1, 1)")
err = tk.ExecToErr(`insert into tl values (1, 3)`)
require.Error(t, err)
tk.MustExec("insert into tl values (2, 2)")
err = tk.ExecToErr("update tl set a = a + 1 where a = 1")
require.Error(t, err)
err = tk.ExecToErr("insert into tl values (1, 3) on duplicated key update a = a + 1")
require.Error(t, err)
tk.MustExec("commit")
tk.MustExec("begin")
tk.MustQuery("select * from tl").Check(testkit.Rows("1 1", "2 2"))
err = tk.ExecToErr(`insert into tl values (1, 3)`)
require.Error(t, err)
err = tk.ExecToErr("update tl set a = a + 1 where a = 1")
require.Error(t, err)
err = tk.ExecToErr("insert into tl values (1, 3) on duplicated key update a = a + 1")
require.Error(t, err)
tk.MustExec("rollback")
tk.MustExec("drop table tl")
tk.MustExec("create temporary table tl (a int, b int unique)")
tk.MustExec("begin")
tk.MustExec("insert into tl values (1, 1)")
err = tk.ExecToErr(`insert into tl values (3, 1)`)
require.Error(t, err)
tk.MustExec("insert into tl values (2, 2)")
err = tk.ExecToErr("update tl set b = b + 1 where a = 1")
require.Error(t, err)
err = tk.ExecToErr("insert into tl values (3, 1) on duplicated key update b = b + 1")
require.Error(t, err)
tk.MustExec("commit")
tk.MustExec("begin")
tk.MustQuery("select * from tl").Check(testkit.Rows("1 1", "2 2"))
err = tk.ExecToErr(`insert into tl values (3, 1)`)
require.Error(t, err)
err = tk.ExecToErr("update tl set b = b + 1 where a = 1")
require.Error(t, err)
err = tk.ExecToErr("insert into tl values (3, 1) on duplicated key update b = b + 1")
require.Error(t, err)
tk.MustExec("rollback")
}
}
func TestPessimisticDeleteYourWrites(t *testing.T) {
store := testkit.CreateMockStore(t)
session1 := testkit.NewTestKit(t, store)
session1.MustExec("use test")
session2 := testkit.NewTestKit(t, store)
session2.MustExec("use test")
session1.MustExec("drop table if exists x;")
session1.MustExec("create table x (id int primary key, c int);")
session1.MustExec("set tidb_txn_mode = 'pessimistic'")
session2.MustExec("set tidb_txn_mode = 'pessimistic'")
session1.MustExec("begin;")
session1.MustExec("insert into x select 1, 1")
session1.MustExec("delete from x where id = 1")
session2.MustExec("begin;")
var wg util.WaitGroupWrapper
wg.Run(func() {
session2.MustExec("insert into x select 1, 2")
})
session1.MustExec("commit;")
wg.Wait()
session2.MustExec("commit;")
session2.MustQuery("select * from x").Check(testkit.Rows("1 2"))
}
func TestDefEnumInsert(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table test (id int, prescription_type enum('a','b','c','d','e','f') NOT NULL, primary key(id));")
tk.MustExec("insert into test (id) values (1)")
tk.MustQuery("select prescription_type from test").Check(testkit.Rows("a"))
}
func TestIssue11059(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table t (pk int primary key, uk int unique, v int)")
tk.MustExec("insert into t values (2, 11, 215)")
tk.MustExec("insert into t values (3, 7, 2111)")
err := tk.ExecToErr("update t set pk = 2 where uk = 7")
require.Error(t, err)
}
func TestSetWithRefGenCol(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t (i int, j int as (i+1) not null);`)
tk.MustExec(`insert into t set i = j + 1;`)
tk.MustQuery("select * from t").Check(testkit.Rows("1 2"))
tk.MustExec(`insert into t set i = j + 100;`)
tk.MustQuery("select * from t").Check(testkit.Rows("1 2", "100 101"))
tk.MustExec(`create table te (i int)`)
tk.MustExec(`insert into te set i = i + 10;`)
tk.MustQuery("select * from te").Check(testkit.Rows("<nil>"))
tk.MustExec(`insert into te set i = i;`)
tk.MustQuery("select * from te").Check(testkit.Rows("<nil>", "<nil>"))
tk.MustExec(`create table tn (i int not null)`)
tk.MustExec(`insert into tn set i = i;`)
tk.MustQuery("select * from tn").Check(testkit.Rows("0"))
tk.MustExec(`insert into tn set i = i + 10;`)
tk.MustQuery("select * from tn").Check(testkit.Rows("0", "10"))
//
tk.MustExec(`create table t1 (j int(11) GENERATED ALWAYS AS (i + 1) stored, i int(11) DEFAULT '10');`)
tk.MustExec(`insert into t1 values()`)
tk.MustQuery("select * from t1").Check(testkit.Rows("11 10"))
tk.MustExec(`insert into t1 values()`)
tk.MustQuery("select * from t1").Check(testkit.Rows("11 10", "11 10"))
tk.MustExec(`create table t2 (j int(11) GENERATED ALWAYS AS (i + 1) stored not null, i int(11) DEFAULT '5');`)
tk.MustExec(`insert into t2 set i = j + 9`)
tk.MustQuery("select * from t2").Check(testkit.Rows("10 9"))
err := tk.ExecToErr(`insert into t2 set j = i + 1`)
require.Error(t, err)
tk.MustExec(`insert into t2 set i = j + 100`)
tk.MustQuery("select * from t2").Check(testkit.Rows("10 9", "101 100"))
tk.MustExec(`create table t3(j int(11) GENERATED ALWAYS AS (i + 1) stored, i int(11) DEFAULT '5');`)
tk.MustExec(`insert into t3 set i = j + 100`)
tk.MustQuery("select * from t3").Check(testkit.Rows("<nil> <nil>"))
err = tk.ExecToErr(`insert into t3 set j = i + 1`)
require.Error(t, err)
}
func TestSetWithCurrentTimestampAndNow(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`drop table if exists tbl;`)
tk.MustExec(`create table t1(c1 timestamp default current_timestamp, c2 int, c3 timestamp default current_timestamp);`)
// c1 insert using now() function result, c3 using default value calculation, should be same
tk.MustExec(`insert into t1 set c1 = current_timestamp, c2 = sleep(2);`)
tk.MustQuery("select c1 = c3 from t1").Check(testkit.Rows("1"))
tk.MustExec(`insert into t1 set c1 = current_timestamp, c2 = sleep(1);`)
tk.MustQuery("select c1 = c3 from t1").Check(testkit.Rows("1", "1"))
}
func TestApplyWithPointAndBatchPointGet(t *testing.T) {
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 ( c_int int, c_str varchar(40),c_datetime datetime, c_timestamp timestamp,
c_double double, c_decimal decimal(12, 6) , primary key(c_int, c_str) , unique key(c_int) , unique key(c_str) ,
unique key(c_decimal) , unique key(c_datetime) , key(c_timestamp) );`)
tk.MustExec(`insert into t values (1, 'zen ardinghelli', '2020-02-03 18:15:17', '2020-03-11 05:47:11', 36.226534, 3.763),
(2, 'suspicious joliot', '2020-01-01 22:56:37', '2020-04-07 06:19:07', 62.756537, 5.567),
(3, 'keen zhukovsky', '2020-01-21 04:09:20', '2020-06-06 08:32:14', 33.115065, 1.381),
(4, 'crazy newton', '2020-02-14 21:37:56', '2020-04-28 08:33:48', 44.146318, 4.249),
(5, 'happy black', '2020-03-12 16:04:14', '2020-01-18 09:17:37', 41.962653, 5.959);`)
tk.MustExec(`insert into t values (6, 'vigilant swartz', '2020-06-01 07:37:44', '2020-05-25 01:26:43', 56.352233, 2.202),
(7, 'suspicious germain', '2020-04-16 23:25:23', '2020-03-17 05:06:57', 55.897698, 3.460),
(8, 'festive chandrasekhar', '2020-02-11 23:40:29', '2020-04-08 10:13:04', 77.565691, 0.540),
(9, 'vigorous meninsky', '2020-02-17 10:03:17', '2020-01-02 15:02:02', 6.484815, 6.292),
(10, 'heuristic moser', '2020-04-20 12:18:49', '2020-06-20 20:20:18', 28.023822, 2.765);`)
tk.MustExec(`insert into t values (11, 'sharp carver', '2020-03-01 11:23:41', '2020-03-23 17:59:05', 40.842442, 6.345),
(12, 'trusting noether', '2020-03-28 06:42:34', '2020-01-27 15:33:40', 49.544658, 4.811),
(13, 'objective ishizaka', '2020-01-28 17:30:55', '2020-04-02 17:45:39', 59.523930, 5.015),
(14, 'sad rhodes', '2020-03-30 21:43:37', '2020-06-09 06:53:53', 87.295753, 2.413),
(15, 'wonderful shockley', '2020-04-29 09:17:11', '2020-03-14 04:36:51', 6.778588, 8.497);`)
tk.MustExec("begin pessimistic")
tk.MustExec(`insert into t values (13, 'vibrant yalow', '2020-05-15 06:59:05', '2020-05-03 05:58:45', 43.721929, 8.066),
(14, 'xenodochial spence', '2020-02-13 17:28:07', '2020-04-01 12:18:30', 19.981331, 5.774),
(22, 'eloquent neumann', '2020-02-10 16:00:20', '2020-03-28 00:24:42', 10.702532, 7.618)
on duplicate key update c_int=values(c_int), c_str=values(c_str), c_double=values(c_double), c_timestamp=values(c_timestamp);`)
// Test pointGet.
tk.MustQuery(`select sum((select t1.c_str from t t1 where t1.c_int = 11 and t1.c_str > t.c_str order by t1.c_decimal limit 1) is null) nulls
from t order by c_str;`).Check(testkit.Rows("10"))
// Test batchPointGet
tk.MustQuery(`select sum((select t1.c_str from t t1 where t1.c_int in (11, 10086) and t1.c_str > t.c_str order by t1.c_decimal limit 1) is null) nulls
from t order by c_str;`).Check(testkit.Rows("10"))
tk.MustExec("commit")
tk.MustQuery(`select sum((select t1.c_str from t t1 where t1.c_int = 11 and t1.c_str > t.c_str order by t1.c_decimal limit 1) is null) nulls
from t order by c_str;`).Check(testkit.Rows("10"))
// Test batchPointGet
tk.MustQuery(`select sum((select t1.c_str from t t1 where t1.c_int in (11, 10086) and t1.c_str > t.c_str order by t1.c_decimal limit 1) is null) nulls
from t order by c_str;`).Check(testkit.Rows("10"))
}
func TestWriteListPartitionTable(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@session.tidb_enable_list_partition = ON")
tk.MustExec("drop table if exists t")
tk.MustExec(`create table t (id int, name varchar(10), unique index idx (id)) partition by list (id) (
partition p0 values in (3,5,6,9,17),
partition p1 values in (1,2,10,11,19,20),
partition p2 values in (4,12,13,14,18),
partition p3 values in (7,8,15,16,null)
);`)
// Test insert,update,delete
tk.MustExec("insert into t values (1, 'a')")
tk.MustExec("update t set name='b' where id=2;")
tk.MustQuery("select * from t").Check(testkit.Rows("1 a"))
tk.MustExec("update t set name='b' where id=1;")
tk.MustQuery("select * from t").Check(testkit.Rows("1 b"))
tk.MustExec("replace into t values (1, 'c')")
tk.MustQuery("select * from t").Check(testkit.Rows("1 c"))
tk.MustExec("insert into t values (1, 'd') on duplicate key update name='e'")
tk.MustQuery("select * from t").Check(testkit.Rows("1 e"))
tk.MustExec("delete from t where id=1")
tk.MustQuery("select * from t").Check(testkit.Rows())
tk.MustExec("insert into t values (2, 'f')")
tk.MustExec("delete from t where name='f'")
tk.MustQuery("select * from t").Check(testkit.Rows())
// Test insert error
tk.MustExec("insert into t values (1, 'a')")
tk.MustGetErrMsg("insert into t values (1, 'd')", "[kv:1062]Duplicate entry '1' for key 't.idx'")
tk.MustGetErrMsg("insert into t values (100, 'd')", "[table:1526]Table has no partition for value 100")
tk.MustExec("admin check table t;")
// Test select partition
tk.MustExec("insert into t values (2,'b'),(3,'c'),(4,'d'),(7,'f'), (null,null)")
tk.MustQuery("select * from t partition (p0) order by id").Check(testkit.Rows("3 c"))
tk.MustQuery("select * from t partition (p1,p3) order by id").Check(testkit.Rows("<nil> <nil>", "1 a", "2 b", "7 f"))
tk.MustQuery("select * from t partition (p1,p3,p0,p2) order by id").Check(testkit.Rows("<nil> <nil>", "1 a", "2 b", "3 c", "4 d", "7 f"))
tk.MustQuery("select * from t order by id").Check(testkit.Rows("<nil> <nil>", "1 a", "2 b", "3 c", "4 d", "7 f"))
tk.MustExec("delete from t partition (p0)")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("<nil> <nil>", "1 a", "2 b", "4 d", "7 f"))
tk.MustExec("delete from t partition (p3,p2)")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 a", "2 b"))
}
func TestWriteListColumnsPartitionTable(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@session.tidb_enable_list_partition = ON")
tk.MustExec("drop table if exists t")
tk.MustExec(`create table t (id int, name varchar(10), unique index idx (id)) partition by list columns (id) (
partition p0 values in (3,5,6,9,17),
partition p1 values in (1,2,10,11,19,20),
partition p2 values in (4,12,13,14,18),
partition p3 values in (7,8,15,16,null)
);`)
// Test insert,update,delete
tk.MustExec("insert into t values (1, 'a')")
tk.MustExec("update t set name='b' where id=2;")
tk.MustQuery("select * from t").Check(testkit.Rows("1 a"))
tk.MustExec("update t set name='b' where id=1;")
tk.MustQuery("select * from t").Check(testkit.Rows("1 b"))
tk.MustExec("replace into t values (1, 'c')")
tk.MustQuery("select * from t").Check(testkit.Rows("1 c"))
tk.MustExec("insert into t values (1, 'd') on duplicate key update name='e'")
tk.MustQuery("select * from t").Check(testkit.Rows("1 e"))
tk.MustExec("delete from t where id=1")
tk.MustQuery("select * from t").Check(testkit.Rows())
tk.MustExec("insert into t values (2, 'f')")
tk.MustExec("delete from t where name='f'")
tk.MustQuery("select * from t").Check(testkit.Rows())
// Test insert error
tk.MustExec("insert into t values (1, 'a')")
err := tk.ExecToErr("insert into t values (1, 'd')")
require.EqualError(t, err, "[kv:1062]Duplicate entry '1' for key 't.idx'")
err = tk.ExecToErr("insert into t values (100, 'd')")
require.EqualError(t, err, "[table:1526]Table has no partition for value from column_list")
tk.MustExec("admin check table t;")
// Test select partition
tk.MustExec("insert into t values (2,'b'),(3,'c'),(4,'d'),(7,'f'), (null,null)")
tk.MustQuery("select * from t partition (p0) order by id").Check(testkit.Rows("3 c"))
tk.MustQuery("select * from t partition (p1,p3) order by id").Check(testkit.Rows("<nil> <nil>", "1 a", "2 b", "7 f"))
tk.MustQuery("select * from t partition (p1,p3,p0,p2) order by id").Check(testkit.Rows("<nil> <nil>", "1 a", "2 b", "3 c", "4 d", "7 f"))
tk.MustQuery("select * from t order by id").Check(testkit.Rows("<nil> <nil>", "1 a", "2 b", "3 c", "4 d", "7 f"))
tk.MustExec("delete from t partition (p0)")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("<nil> <nil>", "1 a", "2 b", "4 d", "7 f"))
tk.MustExec("delete from t partition (p3,p2)")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 a", "2 b"))
}
// TestWriteListPartitionTable1 test for write list partition when the partition expression is simple.
func TestWriteListPartitionTable1(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@session.tidb_enable_list_partition = ON")
tk.MustExec("drop table if exists t")
tk.MustExec(`create table t (id int, name varchar(10)) partition by list (id) (
partition p0 values in (3,5,6,9,17),
partition p1 values in (1,2,10,11,19,20),
partition p2 values in (4,12,13,14,18),
partition p3 values in (7,8,15,16,null)
);`)
// Test add unique index failed.
tk.MustExec("insert into t values (1, 'a'),(1,'b')")
err := tk.ExecToErr("alter table t add unique index idx (id)")
require.EqualError(t, err, "[kv:1062]Duplicate entry '1' for key 't.idx'")
// Test add unique index success.
tk.MustExec("delete from t where name='b'")
tk.MustExec("alter table t add unique index idx (id)")
// --------------------------Test insert---------------------------
// Test insert 1 partition.
tk.MustExec("delete from t")
tk.MustExec("insert into t values (1, 'a'),(2,'b'),(10,'c')")
tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows("1 a", "2 b", "10 c"))
// Test insert multi-partitions.
tk.MustExec("delete from t")
tk.MustExec("insert into t values (1, 'a'),(3,'c'),(4,'e')")
tk.MustQuery("select * from t partition(p0) order by id").Check(testkit.Rows("3 c"))
tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows("1 a"))
tk.MustQuery("select * from t partition(p2) order by id").Check(testkit.Rows("4 e"))
tk.MustQuery("select * from t partition(p3) order by id").Check(testkit.Rows())
// Test insert on duplicate.
tk.MustExec("insert into t values (1, 'd'), (3,'f'),(5,'g') on duplicate key update name='x'")
tk.MustQuery("select * from t partition(p0) order by id").Check(testkit.Rows("3 x", "5 g"))
tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows("1 x"))
tk.MustQuery("select * from t partition(p2) order by id").Check(testkit.Rows("4 e"))
tk.MustQuery("select * from t partition(p3) order by id").Check(testkit.Rows())
// Test insert on duplicate error
err = tk.ExecToErr("insert into t values (3, 'a'), (11,'x') on duplicate key update id=id+1")
require.EqualError(t, err, "[kv:1062]Duplicate entry '4' for key 't.idx'")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 x", "3 x", "4 e", "5 g"))
// Test insert ignore with duplicate
tk.MustExec("insert ignore into t values (1, 'b'), (5,'a'),(null,'y')")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 't.idx'", "Warning 1062 Duplicate entry '5' for key 't.idx'"))
tk.MustQuery("select * from t partition(p0) order by id").Check(testkit.Rows("3 x", "5 g"))
tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows("1 x"))
tk.MustQuery("select * from t partition(p2) order by id").Check(testkit.Rows("4 e"))
tk.MustQuery("select * from t partition(p3) order by id").Check(testkit.Rows("<nil> y"))
// Test insert ignore without duplicate
tk.MustExec("insert ignore into t values (15, 'a'),(17,'a')")
tk.MustQuery("select * from t partition(p0,p1,p2) order by id").Check(testkit.Rows("1 x", "3 x", "4 e", "5 g", "17 a"))
tk.MustQuery("select * from t partition(p3) order by id").Check(testkit.Rows("<nil> y", "15 a"))
// Test insert meet no partition error.
err = tk.ExecToErr("insert into t values (100, 'd')")
require.EqualError(t, err, "[table:1526]Table has no partition for value 100")
// --------------------------Test update---------------------------
// Test update 1 partition.
tk.MustExec("delete from t")
tk.MustExec("insert into t values (1, 'a'),(2,'b'),(3,'c')")
tk.MustExec("update t set name='b' where id=2;")
tk.MustQuery("select * from t partition(p1)").Check(testkit.Rows("1 a", "2 b"))
tk.MustExec("update t set name='x' where id in (1,2)")
tk.MustQuery("select * from t partition(p1)").Check(testkit.Rows("1 x", "2 x"))
tk.MustExec("update t set name='y' where id < 3")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 y", "2 y", "3 c"))
// Test update meet duplicate error.
err = tk.ExecToErr("update t set id=2 where id = 1")
require.EqualError(t, err, "[kv:1062]Duplicate entry '2' for key 't.idx'")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 y", "2 y", "3 c"))
// Test update multi-partitions
tk.MustExec("update t set name='z' where id in (1,2,3);")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 z", "2 z", "3 z"))
tk.MustExec("update t set name='a' limit 3")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 a", "2 a", "3 a"))
tk.MustExec("update t set id=id*10 where id in (1,2)")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a"))
// Test update meet duplicate error.
err = tk.ExecToErr("update t set id=id+17 where id in (3,10)")
require.EqualError(t, err, "[kv:1062]Duplicate entry '20' for key 't.idx'")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a"))
// Test update meet no partition error.
err = tk.ExecToErr("update t set id=id*2 where id in (3,20)")
require.EqualError(t, err, "[table:1526]Table has no partition for value 40")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a"))
// --------------------------Test replace---------------------------
// Test replace 1 partition.
tk.MustExec("delete from t")
tk.MustExec("replace into t values (1, 'a'),(2,'b')")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 a", "2 b"))
// Test replace multi-partitions.
tk.MustExec("replace into t values (3, 'c'),(4,'d'),(7,'f')")
tk.MustQuery("select * from t partition(p0) order by id").Check(testkit.Rows("3 c"))
tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows("1 a", "2 b"))
tk.MustQuery("select * from t partition(p2) order by id").Check(testkit.Rows("4 d"))
tk.MustQuery("select * from t partition(p3) order by id").Check(testkit.Rows("7 f"))
// Test replace on duplicate.
tk.MustExec("replace into t values (1, 'x'),(7,'x')")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 x", "2 b", "3 c", "4 d", "7 x"))
// Test replace meet no partition error.
err = tk.ExecToErr("replace into t values (10,'x'),(50,'x')")
require.EqualError(t, err, "[table:1526]Table has no partition for value 50")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 x", "2 b", "3 c", "4 d", "7 x"))
// --------------------------Test delete---------------------------
// Test delete 1 partition.
tk.MustExec("delete from t where id = 3")
tk.MustQuery("select * from t partition(p0) order by id").Check(testkit.Rows())
tk.MustExec("delete from t where id in (1,2)")
tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows())
// Test delete multi-partitions.
tk.MustExec("delete from t where id in (4,7,10,11)")
tk.MustQuery("select * from t").Check(testkit.Rows())
tk.MustExec("insert into t values (3, 'c'),(4,'d'),(7,'f')")
tk.MustExec("delete from t where id < 10")
tk.MustQuery("select * from t").Check(testkit.Rows())
tk.MustExec("insert into t values (3, 'c'),(4,'d'),(7,'f')")
tk.MustExec("delete from t limit 3")
tk.MustQuery("select * from t").Check(testkit.Rows())
}
// TestWriteListPartitionTable2 test for write list partition when the partition expression is complicated and contain generated column.
func TestWriteListPartitionTable2(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("set @@session.tidb_enable_list_partition = ON")
tk.MustExec("drop table if exists t")
tk.MustExec(`create table t (id int, name varchar(10),b int generated always as (length(name)+1) virtual)
partition by list (id*2 + b*b + b*b - b*b*2 - abs(id)) (
partition p0 values in (3,5,6,9,17),
partition p1 values in (1,2,10,11,19,20),
partition p2 values in (4,12,13,14,18),
partition p3 values in (7,8,15,16,null)
);`)
// Test add unique index failed.
tk.MustExec("insert into t (id,name) values (1, 'a'),(1,'b')")
err := tk.ExecToErr("alter table t add unique index idx (id,b)")
require.EqualError(t, err, "[kv:1062]Duplicate entry '1-2' for key 't.idx'")
// Test add unique index success.
tk.MustExec("delete from t where name='b'")
tk.MustExec("alter table t add unique index idx (id,b)")
// --------------------------Test insert---------------------------
// Test insert 1 partition.
tk.MustExec("delete from t")
tk.MustExec("insert into t (id,name) values (1, 'a'),(2,'b'),(10,'c')")
tk.MustQuery("select id,name from t partition(p1) order by id").Check(testkit.Rows("1 a", "2 b", "10 c"))
// Test insert multi-partitions.
tk.MustExec("delete from t")
tk.MustExec("insert into t (id,name) values (1, 'a'),(3,'c'),(4,'e')")
tk.MustQuery("select id,name from t partition(p0) order by id").Check(testkit.Rows("3 c"))
tk.MustQuery("select id,name from t partition(p1) order by id").Check(testkit.Rows("1 a"))
tk.MustQuery("select id,name from t partition(p2) order by id").Check(testkit.Rows("4 e"))
tk.MustQuery("select id,name from t partition(p3) order by id").Check(testkit.Rows())
// Test insert on duplicate.
tk.MustExec("insert into t (id,name) values (1, 'd'), (3,'f'),(5,'g') on duplicate key update name='x'")
tk.MustQuery("select id,name from t partition(p0) order by id").Check(testkit.Rows("3 x", "5 g"))
tk.MustQuery("select id,name from t partition(p1) order by id").Check(testkit.Rows("1 x"))
tk.MustQuery("select id,name from t partition(p2) order by id").Check(testkit.Rows("4 e"))
tk.MustQuery("select id,name from t partition(p3) order by id").Check(testkit.Rows())
// Test insert on duplicate error
err = tk.ExecToErr("insert into t (id,name) values (3, 'a'), (11,'x') on duplicate key update id=id+1")
require.EqualError(t, err, "[kv:1062]Duplicate entry '4-2' for key 't.idx'")
tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("1 x", "3 x", "4 e", "5 g"))
// Test insert ignore with duplicate
tk.MustExec("insert ignore into t (id,name) values (1, 'b'), (5,'a'),(null,'y')")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1-2' for key 't.idx'", "Warning 1062 Duplicate entry '5-2' for key 't.idx'"))
tk.MustQuery("select id,name from t partition(p0) order by id").Check(testkit.Rows("3 x", "5 g"))
tk.MustQuery("select id,name from t partition(p1) order by id").Check(testkit.Rows("1 x"))
tk.MustQuery("select id,name from t partition(p2) order by id").Check(testkit.Rows("4 e"))
tk.MustQuery("select id,name from t partition(p3) order by id").Check(testkit.Rows("<nil> y"))
// Test insert ignore without duplicate
tk.MustExec("insert ignore into t (id,name) values (15, 'a'),(17,'a')")
tk.MustQuery("select id,name from t partition(p0,p1,p2) order by id").Check(testkit.Rows("1 x", "3 x", "4 e", "5 g", "17 a"))
tk.MustQuery("select id,name from t partition(p3) order by id").Check(testkit.Rows("<nil> y", "15 a"))
// Test insert meet no partition error.
err = tk.ExecToErr("insert into t (id,name) values (100, 'd')")
require.EqualError(t, err, "[table:1526]Table has no partition for value 100")
// --------------------------Test update---------------------------
// Test update 1 partition.
tk.MustExec("delete from t")
tk.MustExec("insert into t (id,name) values (1, 'a'),(2,'b'),(3,'c')")
tk.MustExec("update t set name='b' where id=2;")
tk.MustQuery("select id,name from t partition(p1)").Check(testkit.Rows("1 a", "2 b"))
tk.MustExec("update t set name='x' where id in (1,2)")
tk.MustQuery("select id,name from t partition(p1)").Check(testkit.Rows("1 x", "2 x"))
tk.MustExec("update t set name='y' where id < 3")
tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("1 y", "2 y", "3 c"))
// Test update meet duplicate error.
tk.MustGetErrMsg("update t set id=2 where id = 1", "[kv:1062]Duplicate entry '2-2' for key 't.idx'")
tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("1 y", "2 y", "3 c"))
// Test update multi-partitions
tk.MustExec("update t set name='z' where id in (1,2,3);")
tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("1 z", "2 z", "3 z"))
tk.MustExec("update t set name='a' limit 3")
tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("1 a", "2 a", "3 a"))
tk.MustExec("update t set id=id*10 where id in (1,2)")
tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a"))
// Test update meet duplicate error.
tk.MustGetErrMsg("update t set id=id+17 where id in (3,10)", "[kv:1062]Duplicate entry '20-2' for key 't.idx'")
tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a"))
// Test update meet no partition error.
tk.MustGetErrMsg("update t set id=id*2 where id in (3,20)", "[table:1526]Table has no partition for value 40")
tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a"))
// --------------------------Test replace---------------------------
// Test replace 1 partition.
tk.MustExec("delete from t")
tk.MustExec("replace into t (id,name) values (1, 'a'),(2,'b')")
tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("1 a", "2 b"))
// Test replace multi-partitions.
tk.MustExec("replace into t (id,name) values (3, 'c'),(4,'d'),(7,'f')")
tk.MustQuery("select id,name from t partition(p0) order by id").Check(testkit.Rows("3 c"))
tk.MustQuery("select id,name from t partition(p1) order by id").Check(testkit.Rows("1 a", "2 b"))
tk.MustQuery("select id,name from t partition(p2) order by id").Check(testkit.Rows("4 d"))
tk.MustQuery("select id,name from t partition(p3) order by id").Check(testkit.Rows("7 f"))
// Test replace on duplicate.
tk.MustExec("replace into t (id,name) values (1, 'x'),(7,'x')")
tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("1 x", "2 b", "3 c", "4 d", "7 x"))
// Test replace meet no partition error.
tk.MustGetErrMsg("replace into t (id,name) values (10,'x'),(50,'x')", "[table:1526]Table has no partition for value 50")
tk.MustQuery("select id,name from t order by id").Check(testkit.Rows("1 x", "2 b", "3 c", "4 d", "7 x"))
// --------------------------Test delete---------------------------
// Test delete 1 partition.
tk.MustExec("delete from t where id = 3")
tk.MustQuery("select id,name from t partition(p0) order by id").Check(testkit.Rows())
tk.MustExec("delete from t where id in (1,2)")
tk.MustQuery("select id,name from t partition(p1) order by id").Check(testkit.Rows())
// Test delete multi-partitions.
tk.MustExec("delete from t where id in (4,7,10,11)")
tk.MustQuery("select id,name from t").Check(testkit.Rows())
tk.MustExec("insert into t (id,name) values (3, 'c'),(4,'d'),(7,'f')")
tk.MustExec("delete from t where id < 10")
tk.MustQuery("select id,name from t").Check(testkit.Rows())
tk.MustExec("insert into t (id,name) values (3, 'c'),(4,'d'),(7,'f')")
tk.MustExec("delete from t limit 3")
tk.MustQuery("select id,name from t").Check(testkit.Rows())
}
func TestWriteListColumnsPartitionTable1(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("set @@session.tidb_enable_list_partition = ON")
tk.MustExec("drop table if exists t")
tk.MustExec(`create table t (id int, name varchar(10)) partition by list columns (id) (
partition p0 values in (3,5,6,9,17),
partition p1 values in (1,2,10,11,19,20),
partition p2 values in (4,12,13,14,18),
partition p3 values in (7,8,15,16,null)
);`)
// Test add unique index failed.
tk.MustExec("insert into t values (1, 'a'),(1,'b')")
tk.MustGetErrMsg("alter table t add unique index idx (id)", "[kv:1062]Duplicate entry '1' for key 't.idx'")
// Test add unique index success.
tk.MustExec("delete from t where name='b'")
tk.MustExec("alter table t add unique index idx (id)")
// --------------------------Test insert---------------------------
// Test insert 1 partition.
tk.MustExec("delete from t")
tk.MustExec("insert into t values (1, 'a'),(2,'b'),(10,'c')")
tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows("1 a", "2 b", "10 c"))
// Test insert multi-partitions.
tk.MustExec("delete from t")
tk.MustExec("insert into t values (1, 'a'),(3,'c'),(4,'e')")
tk.MustQuery("select * from t partition(p0) order by id").Check(testkit.Rows("3 c"))
tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows("1 a"))
tk.MustQuery("select * from t partition(p2) order by id").Check(testkit.Rows("4 e"))
tk.MustQuery("select * from t partition(p3) order by id").Check(testkit.Rows())
// Test insert on duplicate.
tk.MustExec("insert into t values (1, 'd'), (3,'f'),(5,'g') on duplicate key update name='x'")
tk.MustQuery("select * from t partition(p0) order by id").Check(testkit.Rows("3 x", "5 g"))
tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows("1 x"))
tk.MustQuery("select * from t partition(p2) order by id").Check(testkit.Rows("4 e"))
tk.MustQuery("select * from t partition(p3) order by id").Check(testkit.Rows())
// Test insert on duplicate error
tk.MustGetErrMsg("insert into t values (3, 'a'), (11,'x') on duplicate key update id=id+1", "[kv:1062]Duplicate entry '4' for key 't.idx'")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 x", "3 x", "4 e", "5 g"))
// Test insert ignore with duplicate
tk.MustExec("insert ignore into t values (1, 'b'), (5,'a'),(null,'y')")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry '1' for key 't.idx'", "Warning 1062 Duplicate entry '5' for key 't.idx'"))
tk.MustQuery("select * from t partition(p0) order by id").Check(testkit.Rows("3 x", "5 g"))
tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows("1 x"))
tk.MustQuery("select * from t partition(p2) order by id").Check(testkit.Rows("4 e"))
tk.MustQuery("select * from t partition(p3) order by id").Check(testkit.Rows("<nil> y"))
// Test insert ignore without duplicate
tk.MustExec("insert ignore into t values (15, 'a'),(17,'a')")
tk.MustQuery("select * from t partition(p0,p1,p2) order by id").Check(testkit.Rows("1 x", "3 x", "4 e", "5 g", "17 a"))
tk.MustQuery("select * from t partition(p3) order by id").Check(testkit.Rows("<nil> y", "15 a"))
// Test insert meet no partition error.
tk.MustGetErrMsg("insert into t values (100, 'd')", "[table:1526]Table has no partition for value from column_list")
// --------------------------Test update---------------------------
// Test update 1 partition.
tk.MustExec("delete from t")
tk.MustExec("insert into t values (1, 'a'),(2,'b'),(3,'c')")
tk.MustExec("update t set name='b' where id=2;")
tk.MustQuery("select * from t partition(p1)").Check(testkit.Rows("1 a", "2 b"))
tk.MustExec("update t set name='x' where id in (1,2)")
tk.MustQuery("select * from t partition(p1)").Check(testkit.Rows("1 x", "2 x"))
tk.MustExec("update t set name='y' where id < 3")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 y", "2 y", "3 c"))
// Test update meet duplicate error.
tk.MustGetErrMsg("update t set id=2 where id = 1", "[kv:1062]Duplicate entry '2' for key 't.idx'")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 y", "2 y", "3 c"))
// Test update multi-partitions
tk.MustExec("update t set name='z' where id in (1,2,3);")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 z", "2 z", "3 z"))
tk.MustExec("update t set name='a' limit 3")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 a", "2 a", "3 a"))
tk.MustExec("update t set id=id*10 where id in (1,2)")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a"))
// Test update meet duplicate error.
tk.MustGetErrMsg("update t set id=id+17 where id in (3,10)", "[kv:1062]Duplicate entry '20' for key 't.idx'")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a"))
// Test update meet no partition error.
tk.MustGetErrMsg("update t set id=id*2 where id in (3,20)", "[table:1526]Table has no partition for value from column_list")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("3 a", "10 a", "20 a"))
// --------------------------Test replace---------------------------
// Test replace 1 partition.
tk.MustExec("delete from t")
tk.MustExec("replace into t values (1, 'a'),(2,'b')")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 a", "2 b"))
// Test replace multi-partitions.
tk.MustExec("replace into t values (3, 'c'),(4,'d'),(7,'f')")
tk.MustQuery("select * from t partition(p0) order by id").Check(testkit.Rows("3 c"))
tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows("1 a", "2 b"))
tk.MustQuery("select * from t partition(p2) order by id").Check(testkit.Rows("4 d"))
tk.MustQuery("select * from t partition(p3) order by id").Check(testkit.Rows("7 f"))
// Test replace on duplicate.
tk.MustExec("replace into t values (1, 'x'),(7,'x')")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 x", "2 b", "3 c", "4 d", "7 x"))
// Test replace meet no partition error.
tk.MustGetErrMsg("replace into t values (10,'x'),(100,'x')", "[table:1526]Table has no partition for value from column_list")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("1 x", "2 b", "3 c", "4 d", "7 x"))
// --------------------------Test delete---------------------------
// Test delete 1 partition.
tk.MustExec("delete from t where id = 3")
tk.MustQuery("select * from t partition(p0) order by id").Check(testkit.Rows())
tk.MustExec("delete from t where id in (1,2)")
tk.MustQuery("select * from t partition(p1) order by id").Check(testkit.Rows())
// Test delete multi-partitions.
tk.MustExec("delete from t where id in (4,7,10,11)")
tk.MustQuery("select * from t").Check(testkit.Rows())
tk.MustExec("insert into t values (3, 'c'),(4,'d'),(7,'f')")
tk.MustExec("delete from t where id < 10")
tk.MustQuery("select * from t").Check(testkit.Rows())
tk.MustExec("insert into t values (3, 'c'),(4,'d'),(7,'f')")
tk.MustExec("delete from t limit 3")
tk.MustQuery("select * from t").Check(testkit.Rows())
}
// TestWriteListColumnsPartitionTable2 test for write list partition when the partition by multi-columns.
func TestWriteListColumnsPartitionTable2(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@session.tidb_enable_list_partition = ON")
tk.MustExec("drop table if exists t")
tk.MustExec(`create table t (location varchar(10), id int, a int) partition by list columns (location,id) (
partition p_west values in (('w', 1),('w', 2),('w', 3),('w', 4)),
partition p_east values in (('e', 5),('e', 6),('e', 7),('e', 8)),
partition p_north values in (('n', 9),('n',10),('n',11),('n',12)),
partition p_south values in (('s',13),('s',14),('s',15),('s',16))
);`)
// Test add unique index failed.
tk.MustExec("insert into t values ('w', 1, 1),('w', 1, 2)")
err := tk.ExecToErr("alter table t add unique index idx (location,id)")
require.EqualError(t, err, "[kv:1062]Duplicate entry 'w-1' for key 't.idx'")
// Test add unique index success.
tk.MustExec("delete from t where a=2")
tk.MustExec("alter table t add unique index idx (location,id)")
// --------------------------Test insert---------------------------
// Test insert 1 partition.
tk.MustExec("delete from t")
tk.MustExec("insert into t values ('w', 1, 1),('w', 2, 2),('w', 3, 3)")
tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows("w 1 1", "w 2 2", "w 3 3"))
// Test insert multi-partitions.
tk.MustExec("delete from t")
tk.MustExec("insert into t values ('w', 1, 1),('e', 5, 5),('n', 9, 9)")
tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows("w 1 1"))
tk.MustQuery("select * from t partition(p_east) order by id").Check(testkit.Rows("e 5 5"))
tk.MustQuery("select * from t partition(p_north) order by id").Check(testkit.Rows("n 9 9"))
tk.MustQuery("select * from t partition(p_south) order by id").Check(testkit.Rows())
// Test insert on duplicate.
tk.MustExec("insert into t values ('w', 1, 1) on duplicate key update a=a+1")
tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows("w 1 2"))
// Test insert on duplicate and move from partition 1 to partition 2
tk.MustExec("insert into t values ('w', 1, 1) on duplicate key update location='s', id=13")
tk.MustQuery("select * from t partition(p_south) order by id").Check(testkit.Rows("s 13 2"))
tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows())
// Test insert on duplicate error
tk.MustExec("insert into t values ('w', 2, 2), ('w', 1, 1)")
tk.MustGetErrMsg("insert into t values ('w', 2, 3) on duplicate key update id=1", "[kv:1062]Duplicate entry 'w-1' for key 't.idx'")
tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows("w 1 1", "w 2 2"))
// Test insert ignore with duplicate
tk.MustExec("insert ignore into t values ('w', 2, 2), ('w', 3, 3), ('n', 10, 10)")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1062 Duplicate entry 'w-2' for key 't.idx'"))
tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows("w 1 1", "w 2 2", "w 3 3"))
tk.MustQuery("select * from t partition(p_north) order by id").Check(testkit.Rows("n 9 9", "n 10 10"))
// Test insert ignore without duplicate
tk.MustExec("insert ignore into t values ('w', 4, 4), ('s', 14, 14)")
tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows("w 1 1", "w 2 2", "w 3 3", "w 4 4"))
tk.MustQuery("select * from t partition(p_south) order by id").Check(testkit.Rows("s 13 2", "s 14 14"))
// Test insert meet no partition error.
tk.MustGetErrMsg("insert into t values ('w', 5, 5)", "[table:1526]Table has no partition for value from column_list")
tk.MustGetErrMsg("insert into t values ('s', 5, 5)", "[table:1526]Table has no partition for value from column_list")
tk.MustGetErrMsg("insert into t values ('s', 100, 5)", "[table:1526]Table has no partition for value from column_list")
tk.MustGetErrMsg("insert into t values ('x', 1, 5)", "[table:1526]Table has no partition for value from column_list")
// --------------------------Test update---------------------------
// Test update 1 partition.
tk.MustExec("delete from t")
tk.MustExec("insert into t values ('w', 1, 1),('w', 2, 2),('w', 3, 3)")
tk.MustExec("update t set a=2 where a=1")
tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows("w 1 2", "w 2 2", "w 3 3"))
tk.MustExec("update t set a=3 where location='w'")
tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows("w 1 3", "w 2 3", "w 3 3"))
tk.MustExec("update t set a=4 where location='w' and id=1")
tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows("w 1 4", "w 2 3", "w 3 3"))
tk.MustExec("update t set a=5 where id=1")
tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows("w 1 5", "w 2 3", "w 3 3"))
tk.MustExec("update t set a=a+id where id>1")
tk.MustQuery("select * from t partition(p_west) order by id,a").Check(testkit.Rows("w 1 5", "w 2 5", "w 3 6"))
// Test update meet duplicate error.
err = tk.ExecToErr("update t set id=id+1 where location='w' and id<2")
require.EqualError(t, err, "[kv:1062]Duplicate entry 'w-2' for key 't.idx'")
tk.MustQuery("select * from t partition(p_west) order by id,a").Check(testkit.Rows("w 1 5", "w 2 5", "w 3 6"))
// Test update multi-partitions
tk.MustExec("delete from t")
tk.MustExec("insert into t values ('w', 1, 1), ('w', 2, 2), ('e', 8, 8),('n', 11, 11)")
tk.MustExec("update t set a=a+1 where id < 20")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("w 1 2", "w 2 3", "e 8 9", "n 11 12"))
tk.MustExec("update t set a=a+1 where location in ('w','s','n')")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("w 1 3", "w 2 4", "e 8 9", "n 11 13"))
tk.MustExec("update t set a=a+1 where location in ('w','s','n') and id in (1,3,5,7,8,9,11)")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("w 1 4", "w 2 4", "e 8 9", "n 11 14"))
tk.MustExec("update t set a=a+1 where location='n' and id=12")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("w 1 4", "w 2 4", "e 8 9", "n 11 14"))
tk.MustExec("update t set a=a+1 where location='n' and id=11")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("w 1 4", "w 2 4", "e 8 9", "n 11 15"))
// Test update meet duplicate error.
err = tk.ExecToErr("update t set id=id+1 where location='w' and id in (1,2)")
require.EqualError(t, err, "[kv:1062]Duplicate entry 'w-2' for key 't.idx'")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("w 1 4", "w 2 4", "e 8 9", "n 11 15"))
// Test update meet no partition error.
err = tk.ExecToErr("update t set id=id+3 where location='w' and id in (1,2)")
require.EqualError(t, err, "[table:1526]Table has no partition for value from column_list")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("w 1 4", "w 2 4", "e 8 9", "n 11 15"))
// Test update that move from partition 1 to partition 2.
// TODO: fix this
tk.MustExec("update t set location='s', id=14 where location='e' and id=8")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("w 1 4", "w 2 4", "n 11 15", "s 14 9"))
// --------------------------Test replace---------------------------
// Test replace 1 partition.
tk.MustExec("delete from t")
tk.MustExec("replace into t values ('w', 1, 1),('w', 2, 2),('w', 3, 3)")
tk.MustQuery("select * from t partition(p_west) order by id").Check(testkit.Rows("w 1 1", "w 2 2", "w 3 3"))
// Test replace multi-partitions.
tk.MustExec("delete from t")
tk.MustExec("replace into t values ('w', 1, 1),('e', 5, 5),('n', 9, 9)")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("w 1 1", "e 5 5", "n 9 9"))
// Test replace on duplicate.
tk.MustExec("replace into t values ('w', 1, 2),('n', 10, 10)")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("w 1 2", "e 5 5", "n 9 9", "n 10 10"))
// Test replace meet no partition error.
tk.MustGetErrMsg("replace into t values ('w', 5, 5)", "[table:1526]Table has no partition for value from column_list")
tk.MustGetErrMsg("replace into t values ('s', 5, 5)", "[table:1526]Table has no partition for value from column_list")
tk.MustGetErrMsg("replace into t values ('s', 100, 5)", "[table:1526]Table has no partition for value from column_list")
tk.MustGetErrMsg("replace into t values ('x', 1, 5)", "[table:1526]Table has no partition for value from column_list")
// --------------------------Test delete---------------------------
// Test delete 1 partition.
tk.MustExec("delete from t where location='w' and id=2")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("w 1 2", "e 5 5", "n 9 9", "n 10 10"))
tk.MustExec("delete from t where location='w' and id=1")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("e 5 5", "n 9 9", "n 10 10"))
// Test delete multi-partitions.
tk.MustExec("delete from t where location in ('w','e','n') and id in (1,2,3,4,5,8,9)")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("n 10 10"))
tk.MustExec("delete from t where a=10")
tk.MustQuery("select * from t order by id").Check(testkit.Rows())
tk.MustExec("replace into t values ('w', 1, 1),('e', 5, 5),('n', 11, 11)")
tk.MustExec("delete from t where id < 10")
tk.MustQuery("select * from t order by id").Check(testkit.Rows("n 11 11"))
tk.MustExec("delete from t limit 1")
tk.MustQuery("select * from t order by id").Check(testkit.Rows())
}
// TestWriteListColumnsPartitionTable2 test for write list partition when the partition by multi-columns.
func TestWriteListPartitionTableIssue21437(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@session.tidb_enable_list_partition = ON")
tk.MustExec("drop table if exists t")
tk.MustExec(`create table t (a int) partition by list (a%10) (partition p0 values in (0,1));`)
err := tk.ExecToErr("replace into t values (null)")
require.EqualError(t, err, "[table:1526]Table has no partition for value NULL")
}
func TestListPartitionWithAutoRandom(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@session.tidb_enable_list_partition = ON")
tk.MustExec("drop table if exists t")
tk.MustExec(`create table t (a bigint key auto_random (3), b int) partition by list (a%5) (partition p0 values in (0,1,2), partition p1 values in (3,4));`)
tk.MustExec("set @@allow_auto_random_explicit_insert = true")
tk.MustExec("replace into t values (1,1)")
result := []string{"1"}
for i := 2; i < 100; i++ {
sql := fmt.Sprintf("insert into t (b) values (%v)", i)
tk.MustExec(sql)
result = append(result, strconv.Itoa(i))
}
tk.MustQuery("select b from t order by b").Check(testkit.Rows(result...))
tk.MustExec("update t set b=b+1 where a=1")
tk.MustQuery("select b from t where a=1").Check(testkit.Rows("2"))
tk.MustExec("update t set b=b+1 where a<2")
tk.MustQuery("select b from t where a<2").Check(testkit.Rows("3"))
tk.MustExec("insert into t values (1, 1) on duplicate key update b=b+1")
tk.MustQuery("select b from t where a=1").Check(testkit.Rows("4"))
}
func TestListPartitionWithAutoIncrement(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@session.tidb_enable_list_partition = ON")
tk.MustExec("drop table if exists t")
tk.MustExec(`create table t (a bigint key auto_increment, b int) partition by list (a%5) (partition p0 values in (0,1,2), partition p1 values in (3,4));`)
tk.MustExec("set @@allow_auto_random_explicit_insert = true")
tk.MustExec("replace into t values (1,1)")
result := []string{"1"}
for i := 2; i < 100; i++ {
sql := fmt.Sprintf("insert into t (b) values (%v)", i)
tk.MustExec(sql)
result = append(result, strconv.Itoa(i))
}
tk.MustQuery("select b from t order by b").Check(testkit.Rows(result...))
tk.MustExec("update t set b=b+1 where a=1")
tk.MustQuery("select b from t where a=1").Check(testkit.Rows("2"))
tk.MustExec("update t set b=b+1 where a<2")
tk.MustQuery("select b from t where a<2").Check(testkit.Rows("3"))
tk.MustExec("insert into t values (1, 1) on duplicate key update b=b+1")
tk.MustQuery("select b from t where a=1").Check(testkit.Rows("4"))
}
func TestListPartitionWithGeneratedColumn(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@session.tidb_enable_list_partition = ON")
// Test for generated column with bigint type.
tableDefs := []string{
// Test for virtual generated column for list partition
`create table t (a bigint, b bigint GENERATED ALWAYS AS (3*a - 2*a) VIRTUAL, index idx(a)) partition by list (5*b - 4*b) (partition p0 values in (1,2,3,4,5), partition p1 values in (6,7,8,9,10));`,
// Test for stored generated column for list partition
`create table t (a bigint, b bigint GENERATED ALWAYS AS (3*a - 2*a) STORED, index idx(a)) partition by list (5*b - 4*b) (partition p0 values in (1,2,3,4,5), partition p1 values in (6,7,8,9,10));`,
// Test for virtual generated column for list columns partition
`create table t (a bigint, b bigint GENERATED ALWAYS AS (3*a - 2*a) VIRTUAL, index idx(a)) partition by list columns(b) (partition p0 values in (1,2,3,4,5), partition p1 values in (6,7,8,9,10));`,
// Test for stored generated column for list columns partition
`create table t (a bigint, b bigint GENERATED ALWAYS AS (3*a - 2*a) STORED, index idx(a)) partition by list columns(b) (partition p0 values in (1,2,3,4,5), partition p1 values in (6,7,8,9,10));`,
}
for _, tbl := range tableDefs {
tk.MustExec("drop table if exists t")
tk.MustExec(tbl)
// Test for insert
tk.MustExec("insert into t (a) values (1),(3),(5),(7),(9)")
tk.MustQuery("select a from t partition (p0) order by a").Check(testkit.Rows("1", "3", "5"))
tk.MustQuery("select a from t partition (p1) order by a").Check(testkit.Rows("7", "9"))
tk.MustQuery("select * from t where a = 1").Check(testkit.Rows("1 1"))
// Test for update
tk.MustExec("update t set a=a+1 where a = 1")
tk.MustQuery("select a from t partition (p0) order by a").Check(testkit.Rows("2", "3", "5"))
tk.MustQuery("select a from t partition (p1) order by a").Check(testkit.Rows("7", "9"))
tk.MustQuery("select * from t where a = 1").Check(testkit.Rows())
tk.MustQuery("select * from t where a = 2").Check(testkit.Rows("2 2"))
// Test for delete
tk.MustExec("delete from t where a>10")
tk.MustQuery("select count(1) from t").Check(testkit.Rows("5"))
tk.MustExec("delete from t where a=9")
tk.MustQuery("select a from t partition (p1) order by a").Check(testkit.Rows("7"))
tk.MustQuery("select count(1) from t").Check(testkit.Rows("4"))
// Test for insert meet no partition error
err := tk.ExecToErr("insert into t (a) values (11)")
require.True(t, table.ErrNoPartitionForGivenValue.Equal(err))
// Test for update meet no partition error
err = tk.ExecToErr("update t set a=a+10 where a = 2")
require.True(t, table.ErrNoPartitionForGivenValue.Equal(err))
}
}
func TestListPartitionWithGeneratedColumn1(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@session.tidb_enable_list_partition = ON")
// Test for generated column with year type.
tableDefs := []string{
// Test for virtual generated column for list partition
`create table t (a year, b year GENERATED ALWAYS AS (3*a - 2*a) VIRTUAL, index idx(a)) partition by list (1 + b - 1) (partition p0 values in (2001,2002,2003,2004,2005), partition p1 values in (2006,2007,2008,2009));`,
// Test for stored generated column for list partition
`create table t (a year, b year GENERATED ALWAYS AS (3*a - 2*a) STORED, index idx(a)) partition by list (1 + b - 1) (partition p0 values in (2001,2002,2003,2004,2005), partition p1 values in (2006,2007,2008,2009));`,
}
for _, tbl := range tableDefs {
tk.MustExec("drop table if exists t")
tk.MustExec(tbl)
// Test for insert
tk.MustExec("insert into t (a) values (1),(3),(5),(7),(9)")
tk.MustQuery("select a from t partition (p0) order by a").Check(testkit.Rows("2001", "2003", "2005"))
tk.MustQuery("select a from t partition (p1) order by a").Check(testkit.Rows("2007", "2009"))
tk.MustQuery("select * from t where a = 1").Check(testkit.Rows("2001 2001"))
// Test for update
tk.MustExec("update t set a=a+1 where a = 1")
tk.MustQuery("select a from t partition (p0) order by a").Check(testkit.Rows("2002", "2003", "2005"))
tk.MustQuery("select a from t partition (p1) order by a").Check(testkit.Rows("2007", "2009"))
tk.MustQuery("select * from t where a = 1").Check(testkit.Rows())
tk.MustQuery("select * from t where a = 2").Check(testkit.Rows("2002 2002"))
// Test for delete
tk.MustExec("delete from t where a>10")
tk.MustQuery("select count(1) from t").Check(testkit.Rows("5"))
tk.MustExec("delete from t where a=9")
tk.MustQuery("select a from t partition (p1) order by a").Check(testkit.Rows("2007"))
tk.MustQuery("select count(1) from t").Check(testkit.Rows("4"))
// Test for insert meet no partition error
err := tk.ExecToErr("insert into t (a) values (11)")
require.EqualError(t, err, "[table:1526]Table has no partition for value 2011")
// Test for update meet no partition error
err = tk.ExecToErr("update t set a=a+10 where a = 2")
require.EqualError(t, err, "[table:1526]Table has no partition for value 2012")
tk.MustExec("delete from t")
// Test for insert
tk.MustExec("insert into t (a) values (2001),(2003),(2005),(2007),(2009)")
tk.MustQuery("select a from t partition (p0) order by a").Check(testkit.Rows("2001", "2003", "2005"))
tk.MustQuery("select a from t partition (p1) order by a").Check(testkit.Rows("2007", "2009"))
tk.MustQuery("select * from t where a = 2001").Check(testkit.Rows("2001 2001"))
// Test for update
tk.MustExec("update t set a=a+1 where a = 2001")
tk.MustQuery("select a from t partition (p0) order by a").Check(testkit.Rows("2002", "2003", "2005"))
tk.MustQuery("select a from t partition (p1) order by a").Check(testkit.Rows("2007", "2009"))
tk.MustQuery("select * from t where a = 2001").Check(testkit.Rows())
tk.MustQuery("select * from t where a = 2002").Check(testkit.Rows("2002 2002"))
// Test for delete
tk.MustExec("delete from t where a>2010")
tk.MustQuery("select count(1) from t").Check(testkit.Rows("5"))
tk.MustExec("delete from t where a=2009")
tk.MustQuery("select a from t partition (p1) order by a").Check(testkit.Rows("2007"))
tk.MustQuery("select count(1) from t").Check(testkit.Rows("4"))
// Test for insert meet no partition error
tk.MustGetErrMsg("insert into t (a) values (2011)", "[table:1526]Table has no partition for value 2011")
// Test for update meet no partition error
tk.MustGetErrMsg("update t set a=a+10 where a = 2002", "[table:1526]Table has no partition for value 2012")
}
}
func TestListPartitionWithGeneratedColumn2(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@session.tidb_enable_list_partition = ON")
tableDefs := []string{
// Test for virtual generated column for datetime type in list partition.
`create table t (a datetime, b bigint GENERATED ALWAYS AS (to_seconds(a)) VIRTUAL, index idx(a)) partition by list (1 + b - 1) (
partition p0 values in (to_seconds('2020-09-28 17:03:38'),to_seconds('2020-09-28 17:03:39')),
partition p1 values in (to_seconds('2020-09-28 17:03:40'),to_seconds('2020-09-28 17:03:41')));`,
// Test for stored generated column for datetime type in list partition.
`create table t (a datetime, b bigint GENERATED ALWAYS AS (to_seconds(a)) STORED, index idx(a)) partition by list (1 + b - 1) (
partition p0 values in (to_seconds('2020-09-28 17:03:38'),to_seconds('2020-09-28 17:03:39')),
partition p1 values in (to_seconds('2020-09-28 17:03:40'),to_seconds('2020-09-28 17:03:41')));`,
// Test for virtual generated column for timestamp type in list partition.
`create table t (a timestamp, b bigint GENERATED ALWAYS AS (to_seconds(a)) VIRTUAL, index idx(a)) partition by list (1 + b - 1) (
partition p0 values in (to_seconds('2020-09-28 17:03:38'),to_seconds('2020-09-28 17:03:39')),
partition p1 values in (to_seconds('2020-09-28 17:03:40'),to_seconds('2020-09-28 17:03:41')));`,
// Test for stored generated column for timestamp type in list partition.
`create table t (a timestamp, b bigint GENERATED ALWAYS AS (to_seconds(a)) STORED, index idx(a)) partition by list (1 + b - 1) (
partition p0 values in (to_seconds('2020-09-28 17:03:38'),to_seconds('2020-09-28 17:03:39')),
partition p1 values in (to_seconds('2020-09-28 17:03:40'),to_seconds('2020-09-28 17:03:41')));`,
// Test for virtual generated column for timestamp type in list columns partition.
`create table t (a timestamp, b bigint GENERATED ALWAYS AS (to_seconds(a)) VIRTUAL, index idx(a)) partition by list columns(b) (
partition p0 values in (to_seconds('2020-09-28 17:03:38'),to_seconds('2020-09-28 17:03:39')),
partition p1 values in (to_seconds('2020-09-28 17:03:40'),to_seconds('2020-09-28 17:03:41')));`,
// Test for stored generated column for timestamp type in list columns partition.
`create table t (a timestamp, b bigint GENERATED ALWAYS AS (to_seconds(a)) STORED, index idx(a)) partition by list columns(b) (
partition p0 values in (to_seconds('2020-09-28 17:03:38'),to_seconds('2020-09-28 17:03:39')),
partition p1 values in (to_seconds('2020-09-28 17:03:40'),to_seconds('2020-09-28 17:03:41')));`,
}
for _, tbl := range tableDefs {
tk.MustExec("drop table if exists t")
tk.MustExec(tbl)
tk.MustExec("insert into t (a) values ('2020-09-28 17:03:38'),('2020-09-28 17:03:40')")
tk.MustQuery("select a from t partition (p0)").Check(testkit.Rows("2020-09-28 17:03:38"))
tk.MustQuery("select a from t where a = '2020-09-28 17:03:40'").Check(testkit.Rows("2020-09-28 17:03:40"))
tk.MustExec("update t set a='2020-09-28 17:03:41' where a = '2020-09-28 17:03:38'")
tk.MustQuery("select a from t partition (p0)").Check(testkit.Rows())
tk.MustQuery("select a from t partition (p1) order by a").Check(testkit.Rows("2020-09-28 17:03:40", "2020-09-28 17:03:41"))
}
}
func TestListColumnsPartitionWithGeneratedColumn(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@session.tidb_enable_list_partition = ON")
// Test for generated column with substr expression.
tableDefs := []string{
// Test for virtual generated column
`create table t (a varchar(10), b varchar(1) GENERATED ALWAYS AS (substr(a,1,1)) VIRTUAL, index idx(a)) partition by list columns(b) (partition p0 values in ('a','c'), partition p1 values in ('b','d'));`,
// Test for stored generated column
`create table t (a varchar(10), b varchar(1) GENERATED ALWAYS AS (substr(a,1,1)) STORED, index idx(a)) partition by list columns(b) (partition p0 values in ('a','c'), partition p1 values in ('b','d'));`,
}
for _, tbl := range tableDefs {
tk.MustExec("drop table if exists t")
tk.MustExec(tbl)
tk.MustExec("insert into t (a) values ('aaa'),('abc'),('acd')")
tk.MustQuery("select a from t partition (p0) order by a").Check(testkit.Rows("aaa", "abc", "acd"))
tk.MustQuery("select * from t where a = 'abc' order by a").Check(testkit.Rows("abc a"))
tk.MustExec("update t set a='bbb' where a = 'aaa'")
tk.MustQuery("select a from t partition (p0) order by a").Check(testkit.Rows("abc", "acd"))
tk.MustQuery("select a from t partition (p1) order by a").Check(testkit.Rows("bbb"))
tk.MustQuery("select * from t where a = 'bbb' order by a").Check(testkit.Rows("bbb b"))
}
}
func TestIssue22496(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t12")
tk.MustExec("create table t12(d decimal(15,2));")
err := tk.ExecToErr("insert into t12 values('1,9999.00')")
require.Error(t, err)
tk.MustExec("set sql_mode=''")
tk.MustExec("insert into t12 values('1,999.00');")
tk.MustQuery("SELECT * FROM t12;").Check(testkit.Rows("1.00"))
tk.MustExec("drop table t12")
}
func TestEqualDatumsAsBinary(t *testing.T) {
tests := []struct {
a []interface{}
b []interface{}
same bool
}{
// Positive cases
{[]interface{}{1}, []interface{}{1}, true},
{[]interface{}{1, "aa"}, []interface{}{1, "aa"}, true},
{[]interface{}{1, "aa", 1}, []interface{}{1, "aa", 1}, true},
// negative cases
{[]interface{}{1}, []interface{}{2}, false},
{[]interface{}{1, "a"}, []interface{}{1, "aaaaaa"}, false},
{[]interface{}{1, "aa", 3}, []interface{}{1, "aa", 2}, false},
// Corner cases
{[]interface{}{}, []interface{}{}, true},
{[]interface{}{nil}, []interface{}{nil}, true},
{[]interface{}{}, []interface{}{1}, false},
{[]interface{}{1}, []interface{}{1, 1}, false},
{[]interface{}{nil}, []interface{}{1}, false},
}
for _, tt := range tests {
testEqualDatumsAsBinary(t, tt.a, tt.b, tt.same)
}
}
func TestIssue21232(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t, t1")
tk.MustExec("create table t(a varchar(1), index idx(a))")
tk.MustExec("create table t1(a varchar(5), index idx(a))")
tk.MustExec("insert into t values('a'), ('b')")
tk.MustExec("insert into t1 values('a'), ('bbbbb')")
tk.MustExec("update /*+ INL_JOIN(t) */ t, t1 set t.a='a' where t.a=t1.a")
tk.MustQuery("show warnings").Check(testkit.Rows())
tk.MustQuery("select * from t").Check(testkit.Rows("a", "b"))
tk.MustExec("update /*+ INL_HASH_JOIN(t) */ t, t1 set t.a='a' where t.a=t1.a")
tk.MustQuery("show warnings").Check(testkit.Rows())
tk.MustQuery("select * from t").Check(testkit.Rows("a", "b"))
tk.MustExec("update /*+ INL_MERGE_JOIN(t) */ t, t1 set t.a='a' where t.a=t1.a")
tk.MustQuery("show warnings").Check(testkit.Rows())
tk.MustQuery("select * from t").Check(testkit.Rows("a", "b"))
}
func testEqualDatumsAsBinary(t *testing.T, a []interface{}, b []interface{}, same bool) {
sc := new(stmtctx.StatementContext)
re := new(executor.ReplaceExec)
sc.IgnoreTruncate = true
res, err := re.EqualDatumsAsBinary(sc, types.MakeDatums(a...), types.MakeDatums(b...))
require.NoError(t, err)
require.Equal(t, same, res, "a: %v, b: %v", a, b)
}
func TestUpdate(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")
fillData(tk, "update_test")
updateStr := `UPDATE update_test SET name = "abc" where id > 0;`
tk.MustExec(updateStr)
tk.CheckExecResult(2, 0)
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 2 Changed: 2 Warnings: 0")
// select data
tk.MustExec("begin")
r := tk.MustQuery(`SELECT * from update_test limit 2;`)
r.Check(testkit.Rows("1 abc", "2 abc"))
tk.MustExec("commit")
tk.MustExec(`UPDATE update_test SET name = "foo"`)
tk.CheckExecResult(2, 0)
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 2 Changed: 2 Warnings: 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'")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
tk.MustExec("insert into update_test(name) values ('bb')")
tk.MustExec("commit")
tk.MustExec("begin")
r = tk.MustQuery("select * from update_test;")
r.Check(testkit.Rows("8 aa", "9 bb"))
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.ExecToErr("update update_test set id = null where name = 'aa'")
require.EqualError(t, err, "[table:1048]Column 'id' cannot be null")
tk.MustExec("drop table update_test")
tk.MustExec("create table update_test(id int)")
tk.MustExec("begin")
tk.MustExec("insert into update_test(id) values (1)")
tk.MustExec("update update_test set id = 2 where id = 1 limit 1")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
r = tk.MustQuery("select * from update_test;")
r.Check(testkit.Rows("2"))
tk.MustExec("commit")
// Test that in a transaction, when a constraint failed in an update statement, the record is not inserted.
tk.MustExec("create table update_unique (id int primary key, name int unique)")
tk.MustExec("insert update_unique values (1, 1), (2, 2);")
tk.MustExec("begin")
err = tk.ExecToErr("update update_unique set name = 1 where id = 2")
require.Error(t, err)
tk.MustExec("commit")
tk.MustQuery("select * from update_unique").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));")
tk.MustExec("insert into t values (1)")
tk.MustExec("insert into t values (2)")
err = tk.ExecToErr("update ignore t set a = 1 where a = 2;")
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 '1' for key 't.PRIMARY'"))
tk.MustQuery("select * from t").Check(testkit.Rows("1", "2"))
// 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'", "Warning 1062 Duplicate entry '1' for key 't.PRIMARY'"))
tk.MustExec("update ignore t set a = 42 where a = 2;")
tk.MustQuery("select * from t").Check(testkit.Rows("1", "42"))
// 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));")
tk.MustExec("insert into t values (1)")
tk.MustExec("insert into t values (2)")
err = tk.ExecToErr("update ignore t set a = 1 where a = 2;")
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 '1' for key 't.I_uniq'"))
tk.MustQuery("select * from t").Check(testkit.Rows("1", "2"))
// test issue21965
tk.MustExec("drop table if exists t;")
tk.MustExec("set @@session.tidb_enable_list_partition = ON")
tk.MustExec("create table t (a int) partition by list (a) (partition p0 values in (0,1));")
tk.MustExec("insert ignore into t values (1);")
tk.MustExec("update ignore t set a=2 where a=1;")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 0 Warnings: 0")
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t (a int key) partition by list (a) (partition p0 values in (0,1));")
tk.MustExec("insert ignore into t values (1);")
tk.MustExec("update ignore t set a=2 where a=1;")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 0 Warnings: 0")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(id integer auto_increment, t1 datetime, t2 datetime, primary key (id))")
tk.MustExec("insert into t(t1, t2) values('2000-10-01 01:01:01', '2017-01-01 10:10:10')")
tk.MustQuery("select * from t").Check(testkit.Rows("1 2000-10-01 01:01:01 2017-01-01 10:10:10"))
tk.MustExec("update t set t1 = '2017-10-01 10:10:11', t2 = date_add(t1, INTERVAL 10 MINUTE) where id = 1")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
tk.MustQuery("select * from t").Check(testkit.Rows("1 2017-10-01 10:10:11 2000-10-01 01:11:01"))
// for issue #5132
tk.MustExec("CREATE TABLE `tt1` (" +
"`a` int(11) NOT NULL," +
"`b` varchar(32) DEFAULT NULL," +
"`c` varchar(32) DEFAULT NULL," +
"PRIMARY KEY (`a`)," +
"UNIQUE KEY `b_idx` (`b`)" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;")
tk.MustExec("insert into tt1 values(1, 'a', 'a');")
tk.MustExec("insert into tt1 values(2, 'd', 'b');")
r = tk.MustQuery("select * from tt1;")
r.Check(testkit.Rows("1 a a", "2 d b"))
tk.MustExec("update tt1 set a=5 where c='b';")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
r = tk.MustQuery("select * from tt1;")
r.Check(testkit.Rows("1 a a", "5 d b"))
// Automatic Updating for TIMESTAMP
tk.MustExec("CREATE TABLE `tsup` (" +
"`a` int," +
"`ts` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP," +
"KEY `idx` (`ts`)" +
");")
tk.MustExec("set @orig_sql_mode=@@sql_mode; set @@sql_mode='';")
tk.MustExec("insert into tsup values(1, '0000-00-00 00:00:00');")
tk.MustExec("update tsup set a=5;")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
r1 := tk.MustQuery("select ts from tsup use index (idx);")
r2 := tk.MustQuery("select ts from tsup;")
r1.Check(r2.Rows())
tk.MustExec("update tsup set ts='2019-01-01';")
tk.MustQuery("select ts from tsup;").Check(testkit.Rows("2019-01-01 00:00:00"))
tk.MustExec("set @@sql_mode=@orig_sql_mode;")
// issue 5532
tk.MustExec("create table decimals (a decimal(20, 0) not null)")
tk.MustExec("insert into decimals values (201)")
// A warning rather than data truncated error.
tk.MustExec("update decimals set a = a + 1.23;")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 1")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1292 Truncated incorrect DECIMAL value: '202.23'"))
r = tk.MustQuery("select * from decimals")
r.Check(testkit.Rows("202"))
tk.MustExec("drop table t")
tk.MustExec("CREATE TABLE `t` ( `c1` year DEFAULT NULL, `c2` year DEFAULT NULL, `c3` date DEFAULT NULL, `c4` datetime DEFAULT NULL, KEY `idx` (`c1`,`c2`))")
err = tk.ExecToErr("UPDATE t SET c2=16777215 WHERE c1>= -8388608 AND c1 < -9 ORDER BY c1 LIMIT 2")
require.NoError(t, err)
tk.MustGetErrCode("update (select * from t) t set c1 = 1111111", mysql.ErrNonUpdatableTable)
// test update ignore for bad null error
tk.MustExec("drop table if exists t;")
tk.MustExec(`create table t (i int not null default 10)`)
tk.MustExec("insert into t values (1)")
tk.MustExec("update ignore t set i = null;")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 1")
r = tk.MustQuery("SHOW WARNINGS;")
r.Check(testkit.Rows("Warning 1048 Column 'i' cannot be null"))
tk.MustQuery("select * from t").Check(testkit.Rows("0"))
// issue 7237, update subquery table should be forbidden
tk.MustExec("drop table t")
tk.MustExec("create table t (k int, v int)")
err = tk.ExecToErr("update t, (select * from t) as b set b.k = t.k")
require.EqualError(t, err, "[planner:1288]The target table b of the UPDATE is not updatable")
tk.MustExec("update t, (select * from t) as b set t.k = b.k")
// issue 8045
tk.MustExec("drop table if exists t1")
tk.MustExec(`CREATE TABLE t1 (c1 float)`)
tk.MustExec("INSERT INTO t1 SET c1 = 1")
tk.MustExec("UPDATE t1 SET c1 = 1.2 WHERE c1=1;")
require.Equal(t, tk.Session().LastMessage(), "Rows matched: 1 Changed: 1 Warnings: 0")
// issue 8119
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t (c1 float(1,1));")
tk.MustExec("insert into t values (0.0);")
err = tk.ExecToErr("update t set c1 = 2.0;")
require.True(t, types.ErrWarnDataOutOfRange.Equal(err))
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a datetime not null, b datetime)")
tk.MustExec("insert into t value('1999-12-12', '1999-12-13')")
tk.MustExec("set @orig_sql_mode=@@sql_mode; set @@sql_mode='';")
tk.MustQuery("select * from t").Check(testkit.Rows("1999-12-12 00:00:00 1999-12-13 00:00:00"))
tk.MustExec("update t set a = ''")
tk.MustQuery("select * from t").Check(testkit.Rows("0000-00-00 00:00:00 1999-12-13 00:00:00"))
tk.MustExec("update t set b = ''")
tk.MustQuery("select * from t").Check(testkit.Rows("0000-00-00 00:00:00 0000-00-00 00:00:00"))
tk.MustExec("set @@sql_mode=@orig_sql_mode;")
tk.MustExec("create view v as select * from t")
err = tk.ExecToErr("update v set a = '2000-11-11'")
require.EqualError(t, err, core.ErrViewInvalid.GenWithStackByArgs("test", "v").Error())
tk.MustExec("drop view v")
tk.MustExec("create sequence seq")
tk.MustGetErrCode("update seq set minvalue=1", mysql.ErrBadField)
tk.MustExec("drop sequence seq")
tk.MustExec("drop table if exists t1, t2")
tk.MustExec("create table t1(a int, b int, c int, d int, e int, index idx(a))")
tk.MustExec("create table t2(a int, b int, c int)")
tk.MustExec("update t1 join t2 on t1.a=t2.a set t1.a=1 where t2.b=1 and t2.c=2")
// Assign `DEFAULT` in `UPDATE` statement
tk.MustExec("drop table if exists t1, t2;")
tk.MustExec("create table t1 (a int default 1, b int default 2);")
tk.MustExec("insert into t1 values (10, 10), (20, 20);")
tk.MustExec("update t1 set a=default where b=10;")
tk.MustQuery("select * from t1;").Check(testkit.Rows("1 10", "20 20"))
tk.MustExec("update t1 set a=30, b=default where a=20;")
tk.MustQuery("select * from t1;").Check(testkit.Rows("1 10", "30 2"))
tk.MustExec("update t1 set a=default, b=default where a=30;")
tk.MustQuery("select * from t1;").Check(testkit.Rows("1 10", "1 2"))
tk.MustExec("insert into t1 values (40, 40)")
tk.MustExec("update t1 set a=default, b=default")
tk.MustQuery("select * from t1;").Check(testkit.Rows("1 2", "1 2", "1 2"))
tk.MustExec("update t1 set a=default(b), b=default(a)")
tk.MustQuery("select * from t1;").Check(testkit.Rows("2 1", "2 1", "2 1"))
// With generated columns
tk.MustExec("create table t2 (a int default 1, b int generated always as (-a) virtual, c int generated always as (-a) stored);")
tk.MustExec("insert into t2 values (10, default, default), (20, default, default)")
tk.MustExec("update t2 set b=default;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("10 -10 -10", "20 -20 -20"))
tk.MustExec("update t2 set a=30, b=default where a=10;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("30 -30 -30", "20 -20 -20"))
tk.MustExec("update t2 set c=default, a=40 where c=-20;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("30 -30 -30", "40 -40 -40"))
tk.MustExec("update t2 set a=default, b=default, c=default where b=-30;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("1 -1 -1", "40 -40 -40"))
tk.MustExec("update t2 set a=default(a), b=default, c=default;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("1 -1 -1", "1 -1 -1"))
// Same as in MySQL 8.0.27, but still weird behavior: a=default(b) => NULL
tk.MustExec("update t2 set a=default(b), b=default, c=default;")
tk.MustQuery("select * from t2;").Check(testkit.Rows("<nil> <nil> <nil>", "<nil> <nil> <nil>"))
tk.MustGetErrCode("update t2 set b=default(a);", mysql.ErrBadGeneratedColumn)
tk.MustExec("update t2 set a=default(a), c=default(c)")
tk.MustQuery("select * from t2;").Check(testkit.Rows("1 -1 -1", "1 -1 -1"))
// Same as in MySQL 8.0.27, but still weird behavior: a=default(b) => NULL
tk.MustExec("update t2 set a=default(b), b=default(b)")
tk.MustQuery("select * from t2;").Check(testkit.Rows("<nil> <nil> <nil>", "<nil> <nil> <nil>"))
tk.MustExec("update t2 set a=default(a), c=default(c)")
tk.MustQuery("select * from t2;").Check(testkit.Rows("1 -1 -1", "1 -1 -1"))
// Allowed in MySQL, but should probably not be allowed.
tk.MustGetErrCode("update t2 set a=default(a), c=default(a)", mysql.ErrBadGeneratedColumn)
tk.MustExec("drop table t1, t2")
}
func TestListColumnsPartitionWithGlobalIndex(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("set @@session.tidb_enable_list_partition = ON")
// Test generated column with global index
restoreConfig := config.RestoreFunc()
defer restoreConfig()
config.UpdateGlobal(func(conf *config.Config) {
conf.EnableGlobalIndex = true
})
tableDefs := []string{
// Test for virtual generated column with global index
`create table t (a varchar(10), b varchar(1) GENERATED ALWAYS AS (substr(a,1,1)) VIRTUAL) partition by list columns(b) (partition p0 values in ('a','c'), partition p1 values in ('b','d'));`,
// Test for stored generated column with global index
`create table t (a varchar(10), b varchar(1) GENERATED ALWAYS AS (substr(a,1,1)) STORED) partition by list columns(b) (partition p0 values in ('a','c'), partition p1 values in ('b','d'));`,
}
for _, tbl := range tableDefs {
tk.MustExec("drop table if exists t")
tk.MustExec(tbl)
tk.MustExec("alter table t add unique index (a)")
tk.MustExec("insert into t (a) values ('aaa'),('abc'),('acd')")
tk.MustQuery("select a from t partition (p0) order by a").Check(testkit.Rows("aaa", "abc", "acd"))
tk.MustQuery("select * from t where a = 'abc' order by a").Check(testkit.Rows("abc a"))
tk.MustExec("update t set a='bbb' where a = 'aaa'")
tk.MustExec("admin check table t")
tk.MustQuery("select a from t order by a").Check(testkit.Rows("abc", "acd", "bbb"))
// TODO: fix below test.
//tk.MustQuery("select a from t partition (p0) order by a").Check(testkit.Rows("abc", "acd"))
//tk.MustQuery("select a from t partition (p1) order by a").Check(testkit.Rows("bbb"))
tk.MustQuery("select * from t where a = 'bbb' order by a").Check(testkit.Rows("bbb b"))
// Test insert meet duplicate error.
err := tk.ExecToErr("insert into t (a) values ('abc')")
require.Error(t, err)
// Test insert on duplicate update
tk.MustExec("insert into t (a) values ('abc') on duplicate key update a='bbc'")
tk.MustQuery("select a from t order by a").Check(testkit.Rows("acd", "bbb", "bbc"))
tk.MustQuery("select * from t where a = 'bbc'").Check(testkit.Rows("bbc b"))
// TODO: fix below test.
//tk.MustQuery("select a from t partition (p0) order by a").Check(testkit.Rows("acd"))
//tk.MustQuery("select a from t partition (p1) order by a").Check(testkit.Rows("bbb", "bbc"))
}
}
func TestIssue20724(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1(a varchar(10) collate utf8mb4_general_ci)")
tk.MustExec("insert into t1 values ('a')")
tk.MustExec("update t1 set a = 'A'")
tk.MustQuery("select * from t1").Check(testkit.Rows("A"))
tk.MustExec("drop table t1")
}
func TestIssue20840(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1")
tk.Session().GetSessionVars().EnableClusteredIndex = variable.ClusteredIndexDefModeIntOnly
tk.MustExec("create table t1 (i varchar(20) unique key) collate=utf8mb4_general_ci")
tk.MustExec("insert into t1 values ('a')")
tk.MustExec("replace into t1 values ('A')")
tk.MustQuery("select * from t1").Check(testkit.Rows("A"))
tk.MustExec("drop table t1")
}
func TestIssueInsertPrefixIndexForNonUTF8Collation(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1, t2, t3")
tk.MustExec("create table t1 ( c_int int, c_str varchar(40) character set ascii collate ascii_bin, primary key(c_int, c_str(8)) clustered , unique key(c_str))")
tk.MustExec("create table t2 ( c_int int, c_str varchar(40) character set latin1 collate latin1_bin, primary key(c_int, c_str(8)) clustered , unique key(c_str))")
tk.MustExec("insert into t1 values (3, 'fervent brattain')")
tk.MustExec("insert into t2 values (3, 'fervent brattain')")
tk.MustExec("admin check table t1")
tk.MustExec("admin check table t2")
tk.MustExec("create table t3 (x varchar(40) CHARACTER SET ascii COLLATE ascii_bin, UNIQUE KEY uk(x(4)))")
tk.MustExec("insert into t3 select 'abc '")
tk.MustGetErrCode("insert into t3 select 'abc d'", 1062)
}