443 lines
14 KiB
Go
443 lines
14 KiB
Go
// Copyright 2021 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 ddl_test
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
. "github.com/pingcap/check"
|
|
"github.com/pingcap/tidb/session"
|
|
"github.com/pingcap/tidb/store/mockstore"
|
|
"github.com/pingcap/tidb/util/gcutil"
|
|
"github.com/pingcap/tidb/util/testkit"
|
|
)
|
|
|
|
func (s *testDBSuite8) TestAlterTableAttributes(c *C) {
|
|
store, err := mockstore.NewMockStore()
|
|
c.Assert(err, IsNil)
|
|
dom, err := session.BootstrapSession(store)
|
|
c.Assert(err, IsNil)
|
|
defer func() {
|
|
dom.Close()
|
|
err := store.Close()
|
|
c.Assert(err, IsNil)
|
|
}()
|
|
tk := testkit.NewTestKit(c, store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec(`create table t1 (c int);`)
|
|
|
|
// normal cases
|
|
_, err = tk.Exec(`alter table t1 attributes="merge_option=allow";`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 attributes="merge_option=allow,key=value";`)
|
|
c.Assert(err, IsNil)
|
|
|
|
// space cases
|
|
_, err = tk.Exec(`alter table t1 attributes=" merge_option=allow ";`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 attributes=" merge_option = allow , key = value ";`)
|
|
c.Assert(err, IsNil)
|
|
|
|
// without equal
|
|
_, err = tk.Exec(`alter table t1 attributes " merge_option=allow ";`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 attributes " merge_option=allow , key=value ";`)
|
|
c.Assert(err, IsNil)
|
|
}
|
|
|
|
func (s *testDBSuite8) TestAlterTablePartitionAttributes(c *C) {
|
|
store, err := mockstore.NewMockStore()
|
|
c.Assert(err, IsNil)
|
|
dom, err := session.BootstrapSession(store)
|
|
c.Assert(err, IsNil)
|
|
defer func() {
|
|
dom.Close()
|
|
err := store.Close()
|
|
c.Assert(err, IsNil)
|
|
}()
|
|
tk := testkit.NewTestKit(c, store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec(`create table t1 (c int)
|
|
PARTITION BY RANGE (c) (
|
|
PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION p1 VALUES LESS THAN (11),
|
|
PARTITION p2 VALUES LESS THAN (16),
|
|
PARTITION p3 VALUES LESS THAN (21)
|
|
);`)
|
|
|
|
// normal cases
|
|
_, err = tk.Exec(`alter table t1 partition p0 attributes="merge_option=allow";`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 partition p1 attributes="merge_option=allow,key=value";`)
|
|
c.Assert(err, IsNil)
|
|
|
|
// space cases
|
|
_, err = tk.Exec(`alter table t1 partition p2 attributes=" merge_option=allow ";`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 partition p3 attributes=" merge_option = allow , key = value ";`)
|
|
c.Assert(err, IsNil)
|
|
|
|
// without equal
|
|
_, err = tk.Exec(`alter table t1 partition p1 attributes " merge_option=allow ";`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 partition p1 attributes " merge_option=allow , key=value ";`)
|
|
c.Assert(err, IsNil)
|
|
}
|
|
|
|
func (s *testDBSuite8) TestTruncateTable(c *C) {
|
|
store, err := mockstore.NewMockStore()
|
|
c.Assert(err, IsNil)
|
|
dom, err := session.BootstrapSession(store)
|
|
c.Assert(err, IsNil)
|
|
defer func() {
|
|
dom.Close()
|
|
err := store.Close()
|
|
c.Assert(err, IsNil)
|
|
}()
|
|
tk := testkit.NewTestKit(c, store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec(`create table t1 (c int)
|
|
PARTITION BY RANGE (c) (
|
|
PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION p1 VALUES LESS THAN (11)
|
|
);`)
|
|
|
|
// add rules
|
|
_, err = tk.Exec(`alter table t1 attributes="key=value";`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 partition p0 attributes="key1=value1";`)
|
|
c.Assert(err, IsNil)
|
|
rows := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows), Equals, 2)
|
|
// truncate table
|
|
_, err = tk.Exec(`truncate table t1;`)
|
|
c.Assert(err, IsNil)
|
|
rows1 := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows1), Equals, 2)
|
|
// check table t1's rule
|
|
c.Assert(rows1[0][0], Equals, "schema/test/t1")
|
|
c.Assert(rows1[0][2], Equals, `"key=value"`)
|
|
c.Assert(rows1[0][3], Not(Equals), rows[0][3])
|
|
// check partition p0's rule
|
|
c.Assert(rows1[1][0], Equals, "schema/test/t1/p0")
|
|
c.Assert(rows1[1][2], Equals, `"key1=value1"`)
|
|
c.Assert(rows1[1][3], Not(Equals), rows[1][3])
|
|
|
|
// test only table
|
|
tk.MustExec(`create table t2 (c int);`)
|
|
|
|
// add rule
|
|
_, err = tk.Exec(`alter table t2 attributes="key=value";`)
|
|
c.Assert(err, IsNil)
|
|
rows2 := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows2), Equals, 3)
|
|
// truncate table
|
|
_, err = tk.Exec(`truncate table t2;`)
|
|
c.Assert(err, IsNil)
|
|
rows3 := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows3), Equals, 3)
|
|
// check table t1's rule
|
|
c.Assert(rows3[2][0], Equals, "schema/test/t2")
|
|
c.Assert(rows3[2][2], Equals, `"key=value"`)
|
|
c.Assert(rows3[2][3], Not(Equals), rows2[2][3])
|
|
}
|
|
|
|
func (s *testDBSuite8) TestRenameTable(c *C) {
|
|
store, err := mockstore.NewMockStore()
|
|
c.Assert(err, IsNil)
|
|
dom, err := session.BootstrapSession(store)
|
|
c.Assert(err, IsNil)
|
|
defer func() {
|
|
dom.Close()
|
|
err := store.Close()
|
|
c.Assert(err, IsNil)
|
|
}()
|
|
tk := testkit.NewTestKit(c, store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec(`create table t1 (c int)
|
|
PARTITION BY RANGE (c) (
|
|
PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION p1 VALUES LESS THAN (11)
|
|
);`)
|
|
|
|
// add rules
|
|
_, err = tk.Exec(`alter table t1 attributes="key=value";`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 partition p0 attributes="key1=value1";`)
|
|
c.Assert(err, IsNil)
|
|
rows := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows), Equals, 2)
|
|
// rename table
|
|
_, err = tk.Exec(`rename table t1 to t2;`)
|
|
c.Assert(err, IsNil)
|
|
rows1 := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows1), Equals, 2)
|
|
// check table t2's rule
|
|
c.Assert(rows1[0][0], Equals, "schema/test/t2")
|
|
c.Assert(rows1[0][2], Equals, `"key=value"`)
|
|
c.Assert(rows1[0][3], Equals, rows[0][3])
|
|
// check partition p0's rule
|
|
c.Assert(rows1[1][0], Equals, "schema/test/t2/p0")
|
|
c.Assert(rows1[1][2], Equals, `"key1=value1"`)
|
|
c.Assert(rows1[1][3], Equals, rows[1][3])
|
|
|
|
// test only table
|
|
tk.MustExec(`create table t3 (c int);`)
|
|
|
|
// add rule
|
|
_, err = tk.Exec(`alter table t3 attributes="key=value";`)
|
|
c.Assert(err, IsNil)
|
|
rows2 := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows2), Equals, 3)
|
|
// rename table
|
|
_, err = tk.Exec(`rename table t3 to t4;`)
|
|
c.Assert(err, IsNil)
|
|
rows3 := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows3), Equals, 3)
|
|
// check table t4's rule
|
|
c.Assert(rows3[2][0], Equals, "schema/test/t4")
|
|
c.Assert(rows3[2][2], Equals, `"key=value"`)
|
|
c.Assert(rows3[2][3], Equals, rows2[2][3])
|
|
}
|
|
|
|
func (s *testDBSuite8) TestRecoverTable(c *C) {
|
|
store, err := mockstore.NewMockStore()
|
|
c.Assert(err, IsNil)
|
|
dom, err := session.BootstrapSession(store)
|
|
c.Assert(err, IsNil)
|
|
defer func() {
|
|
dom.Close()
|
|
err := store.Close()
|
|
c.Assert(err, IsNil)
|
|
}()
|
|
tk := testkit.NewTestKit(c, store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec(`create table t1 (c int)
|
|
PARTITION BY RANGE (c) (
|
|
PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION p1 VALUES LESS THAN (11)
|
|
);`)
|
|
|
|
timeBeforeDrop, _, safePointSQL, resetGC := testkit.MockGC(tk)
|
|
defer resetGC()
|
|
|
|
// Set GC safe point
|
|
tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop))
|
|
// Set GC enable.
|
|
err = gcutil.EnableGC(tk.Se)
|
|
c.Assert(err, IsNil)
|
|
|
|
// add rules
|
|
_, err = tk.Exec(`alter table t1 attributes="key=value";`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 partition p0 attributes="key1=value1";`)
|
|
c.Assert(err, IsNil)
|
|
rows := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows), Equals, 2)
|
|
// drop table
|
|
_, err = tk.Exec(`drop table t1;`)
|
|
c.Assert(err, IsNil)
|
|
// recover table
|
|
_, err = tk.Exec(`recover table t1;`)
|
|
c.Assert(err, IsNil)
|
|
rows1 := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows1), Equals, 2)
|
|
// check table t1's rule
|
|
c.Assert(rows1[0][0], Equals, "schema/test/t1")
|
|
c.Assert(rows1[0][2], Equals, `"key=value"`)
|
|
c.Assert(rows1[0][3], Equals, rows[0][3])
|
|
// check partition p0's rule
|
|
c.Assert(rows1[1][0], Equals, "schema/test/t1/p0")
|
|
c.Assert(rows1[1][2], Equals, `"key1=value1"`)
|
|
c.Assert(rows1[1][3], Equals, rows[1][3])
|
|
}
|
|
|
|
func (s *testDBSuite8) TestFlashbackTable(c *C) {
|
|
store, err := mockstore.NewMockStore()
|
|
c.Assert(err, IsNil)
|
|
dom, err := session.BootstrapSession(store)
|
|
c.Assert(err, IsNil)
|
|
defer func() {
|
|
dom.Close()
|
|
err := store.Close()
|
|
c.Assert(err, IsNil)
|
|
}()
|
|
tk := testkit.NewTestKit(c, store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec(`create table t1 (c int)
|
|
PARTITION BY RANGE (c) (
|
|
PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION p1 VALUES LESS THAN (11)
|
|
);`)
|
|
|
|
timeBeforeDrop, _, safePointSQL, resetGC := testkit.MockGC(tk)
|
|
defer resetGC()
|
|
|
|
// Set GC safe point
|
|
tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop))
|
|
// Set GC enable.
|
|
err = gcutil.EnableGC(tk.Se)
|
|
c.Assert(err, IsNil)
|
|
|
|
// add rules
|
|
_, err = tk.Exec(`alter table t1 attributes="key=value";`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 partition p0 attributes="key1=value1";`)
|
|
c.Assert(err, IsNil)
|
|
rows := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows), Equals, 2)
|
|
// drop table
|
|
_, err = tk.Exec(`drop table t1;`)
|
|
c.Assert(err, IsNil)
|
|
// flashback table
|
|
_, err = tk.Exec(`flashback table t1 to t2;`)
|
|
c.Assert(err, IsNil)
|
|
rows1 := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows1), Equals, 2)
|
|
// check table t2's rule
|
|
c.Assert(rows1[0][0], Equals, "schema/test/t2")
|
|
c.Assert(rows1[0][2], Equals, `"key=value"`)
|
|
c.Assert(rows1[0][3], Equals, rows[0][3])
|
|
// check partition p0's rule
|
|
c.Assert(rows1[1][0], Equals, "schema/test/t2/p0")
|
|
c.Assert(rows1[1][2], Equals, `"key1=value1"`)
|
|
c.Assert(rows1[1][3], Equals, rows[1][3])
|
|
|
|
// truncate table
|
|
_, err = tk.Exec(`truncate table t2;`)
|
|
c.Assert(err, IsNil)
|
|
// flashback table
|
|
_, err = tk.Exec(`flashback table t2 to t3;`)
|
|
c.Assert(err, IsNil)
|
|
rows2 := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows1), Equals, 2)
|
|
// check table t3's rule
|
|
c.Assert(rows2[0][0], Equals, "schema/test/t3")
|
|
c.Assert(rows2[0][2], Equals, `"key=value"`)
|
|
c.Assert(rows2[0][3], Equals, rows[0][3])
|
|
// check partition p0's rule
|
|
c.Assert(rows2[1][0], Equals, "schema/test/t3/p0")
|
|
c.Assert(rows2[1][2], Equals, `"key1=value1"`)
|
|
c.Assert(rows2[1][3], Equals, rows[1][3])
|
|
}
|
|
|
|
func (s *testDBSuite8) TestPartition(c *C) {
|
|
store, err := mockstore.NewMockStore()
|
|
c.Assert(err, IsNil)
|
|
dom, err := session.BootstrapSession(store)
|
|
c.Assert(err, IsNil)
|
|
defer func() {
|
|
dom.Close()
|
|
err := store.Close()
|
|
c.Assert(err, IsNil)
|
|
}()
|
|
tk := testkit.NewTestKit(c, store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec(`create table t1 (c int)
|
|
PARTITION BY RANGE (c) (
|
|
PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION p1 VALUES LESS THAN (11),
|
|
PARTITION p2 VALUES LESS THAN (20)
|
|
);`)
|
|
tk.MustExec(`create table t2 (c int);`)
|
|
|
|
// add rules
|
|
_, err = tk.Exec(`alter table t1 attributes="key=value";`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 partition p0 attributes="key1=value1";`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 partition p1 attributes="key2=value2";`)
|
|
c.Assert(err, IsNil)
|
|
rows := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows), Equals, 3)
|
|
// drop partition
|
|
// partition p0's rule will be deleted
|
|
_, err = tk.Exec(`alter table t1 drop partition p0;`)
|
|
c.Assert(err, IsNil)
|
|
rows1 := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows1), Equals, 2)
|
|
c.Assert(rows1[0][0], Equals, "schema/test/t1")
|
|
c.Assert(rows1[0][2], Equals, `"key=value"`)
|
|
c.Assert(rows1[0][3], Equals, rows[0][3])
|
|
c.Assert(rows1[1][0], Equals, "schema/test/t1/p1")
|
|
c.Assert(rows1[1][2], Equals, `"key2=value2"`)
|
|
c.Assert(rows1[1][3], Equals, rows[2][3])
|
|
|
|
// truncate partition
|
|
// partition p1's key range will be updated
|
|
_, err = tk.Exec(`alter table t1 truncate partition p1;`)
|
|
c.Assert(err, IsNil)
|
|
rows2 := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows2), Equals, 2)
|
|
c.Assert(rows2[0][0], Equals, "schema/test/t1")
|
|
c.Assert(rows2[0][2], Equals, `"key=value"`)
|
|
c.Assert(rows2[0][3], Not(Equals), rows1[0][3])
|
|
c.Assert(rows2[1][0], Equals, "schema/test/t1/p1")
|
|
c.Assert(rows2[1][2], Equals, `"key2=value2"`)
|
|
c.Assert(rows2[1][3], Not(Equals), rows1[1][3])
|
|
|
|
// exchange partition
|
|
// partition p1's rule will be exchanged to table t2
|
|
_, err = tk.Exec(`set @@tidb_enable_exchange_partition=1;`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 exchange partition p1 with table t2;`)
|
|
c.Assert(err, IsNil)
|
|
rows3 := tk.MustQuery(`select * from information_schema.region_label;`).Sort().Rows()
|
|
c.Assert(len(rows3), Equals, 2)
|
|
c.Assert(rows3[0][0], Equals, "schema/test/t1")
|
|
c.Assert(rows3[0][2], Equals, `"key=value"`)
|
|
c.Assert(rows3[0][3], Equals, rows2[0][3])
|
|
c.Assert(rows3[1][0], Equals, "schema/test/t2")
|
|
c.Assert(rows3[1][2], Equals, `"key2=value2"`)
|
|
c.Assert(rows3[1][3], Equals, rows2[1][3])
|
|
}
|
|
|
|
func (s *testDBSuite8) TestDefaultKeyword(c *C) {
|
|
store, err := mockstore.NewMockStore()
|
|
c.Assert(err, IsNil)
|
|
dom, err := session.BootstrapSession(store)
|
|
c.Assert(err, IsNil)
|
|
defer func() {
|
|
dom.Close()
|
|
err := store.Close()
|
|
c.Assert(err, IsNil)
|
|
}()
|
|
tk := testkit.NewTestKit(c, store)
|
|
tk.MustExec("use test")
|
|
tk.MustExec(`create table t1 (c int)
|
|
PARTITION BY RANGE (c) (
|
|
PARTITION p0 VALUES LESS THAN (6),
|
|
PARTITION p1 VALUES LESS THAN (11)
|
|
);`)
|
|
|
|
// add rules
|
|
_, err = tk.Exec(`alter table t1 attributes="key=value";`)
|
|
c.Assert(err, IsNil)
|
|
_, err = tk.Exec(`alter table t1 partition p0 attributes="key1=value1";`)
|
|
c.Assert(err, IsNil)
|
|
rows := tk.MustQuery(`select * from information_schema.region_label;`).Rows()
|
|
c.Assert(len(rows), Equals, 2)
|
|
// reset the partition p0's rule
|
|
_, err = tk.Exec(`alter table t1 partition p0 attributes=default;`)
|
|
c.Assert(err, IsNil)
|
|
rows = tk.MustQuery(`select * from information_schema.region_label;`).Rows()
|
|
c.Assert(len(rows), Equals, 1)
|
|
// reset the table t1's rule
|
|
_, err = tk.Exec(`alter table t1 attributes=default;`)
|
|
c.Assert(err, IsNil)
|
|
rows = tk.MustQuery(`select * from information_schema.region_label;`).Rows()
|
|
c.Assert(len(rows), Equals, 0)
|
|
}
|