executor: migrate test-infra to testify for infoschema_reader_test.go (#32688)
close pingcap/tidb#28587
This commit is contained in:
@ -42,9 +42,9 @@ import (
|
||||
"github.com/pingcap/tidb/table"
|
||||
"github.com/pingcap/tidb/table/tables"
|
||||
"github.com/pingcap/tidb/testkit"
|
||||
"github.com/pingcap/tidb/testkit/testutil"
|
||||
"github.com/pingcap/tidb/types"
|
||||
"github.com/pingcap/tidb/util/chunk"
|
||||
"github.com/pingcap/tidb/util/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@ -203,7 +203,7 @@ func TestCreateTable(t *testing.T) {
|
||||
tk.MustQuery("show warnings;").Check(testkit.Rows("Note 1051 Unknown table 'test.t_if_exists'"))
|
||||
tk.MustExec("create table if not exists t1_if_exists(c int)")
|
||||
tk.MustExec("drop table if exists t1_if_exists,t2_if_exists,t3_if_exists")
|
||||
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Note|1051|Unknown table 'test.t2_if_exists'", "Note|1051|Unknown table 'test.t3_if_exists'"))
|
||||
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Note|1051|Unknown table 'test.t2_if_exists'", "Note|1051|Unknown table 'test.t3_if_exists'"))
|
||||
}
|
||||
|
||||
func TestCreateView(t *testing.T) {
|
||||
@ -292,7 +292,7 @@ func TestCreateView(t *testing.T) {
|
||||
tk.MustQuery("show warnings;").Check(testkit.Rows("Note 1051 Unknown table 'test.v_if_exists'"))
|
||||
tk.MustExec("create view v1_if_exists as (select * from t1)")
|
||||
tk.MustExec("drop view if exists v1_if_exists,v2_if_exists,v3_if_exists")
|
||||
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Note|1051|Unknown table 'test.v2_if_exists'", "Note|1051|Unknown table 'test.v3_if_exists'"))
|
||||
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Note|1051|Unknown table 'test.v2_if_exists'", "Note|1051|Unknown table 'test.v3_if_exists'"))
|
||||
|
||||
// Test for create nested view.
|
||||
tk.MustExec("create table test_v_nested(a int)")
|
||||
@ -456,22 +456,22 @@ func TestCreateDropDatabase(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
|
||||
tk.MustExec("create database charset_test charset ascii;")
|
||||
tk.MustQuery("show create database charset_test;").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create database charset_test;").Check(testkit.RowsWithSep("|",
|
||||
"charset_test|CREATE DATABASE `charset_test` /*!40100 DEFAULT CHARACTER SET ascii */",
|
||||
))
|
||||
tk.MustExec("drop database charset_test;")
|
||||
tk.MustExec("create database charset_test charset binary;")
|
||||
tk.MustQuery("show create database charset_test;").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create database charset_test;").Check(testkit.RowsWithSep("|",
|
||||
"charset_test|CREATE DATABASE `charset_test` /*!40100 DEFAULT CHARACTER SET binary */",
|
||||
))
|
||||
tk.MustExec("drop database charset_test;")
|
||||
tk.MustExec("create database charset_test collate utf8_general_ci;")
|
||||
tk.MustQuery("show create database charset_test;").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create database charset_test;").Check(testkit.RowsWithSep("|",
|
||||
"charset_test|CREATE DATABASE `charset_test` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci */",
|
||||
))
|
||||
tk.MustExec("drop database charset_test;")
|
||||
tk.MustExec("create database charset_test charset utf8 collate utf8_general_ci;")
|
||||
tk.MustQuery("show create database charset_test;").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create database charset_test;").Check(testkit.RowsWithSep("|",
|
||||
"charset_test|CREATE DATABASE `charset_test` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci */",
|
||||
))
|
||||
tk.MustGetErrMsg("create database charset_test charset utf8 collate utf8mb4_unicode_ci;", "[ddl:1253]COLLATION 'utf8mb4_unicode_ci' is not valid for CHARACTER SET 'utf8'")
|
||||
@ -481,19 +481,19 @@ func TestCreateDropDatabase(t *testing.T) {
|
||||
|
||||
tk.MustExec("drop database charset_test;")
|
||||
tk.MustExec("create database charset_test;")
|
||||
tk.MustQuery("show create database charset_test;").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create database charset_test;").Check(testkit.RowsWithSep("|",
|
||||
"charset_test|CREATE DATABASE `charset_test` /*!40100 DEFAULT CHARACTER SET ascii */",
|
||||
))
|
||||
|
||||
tk.MustExec("drop database charset_test;")
|
||||
tk.MustExec("create database charset_test collate utf8mb4_general_ci;")
|
||||
tk.MustQuery("show create database charset_test;").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create database charset_test;").Check(testkit.RowsWithSep("|",
|
||||
"charset_test|CREATE DATABASE `charset_test` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */",
|
||||
))
|
||||
|
||||
tk.MustExec("drop database charset_test;")
|
||||
tk.MustExec("create database charset_test charset utf8mb4;")
|
||||
tk.MustQuery("show create database charset_test;").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create database charset_test;").Check(testkit.RowsWithSep("|",
|
||||
"charset_test|CREATE DATABASE `charset_test` /*!40100 DEFAULT CHARACTER SET utf8mb4 */",
|
||||
))
|
||||
}
|
||||
@ -1438,14 +1438,14 @@ func TestIssue9205(t *testing.T) {
|
||||
tk.MustExec("use test")
|
||||
tk.MustExec(`drop table if exists t;`)
|
||||
tk.MustExec(`create table t(c time DEFAULT '12:12:12.8');`)
|
||||
tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `t`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `c` time DEFAULT '12:12:13'\n"+
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
|
||||
))
|
||||
tk.MustExec(`alter table t add column c1 time default '12:12:12.000000';`)
|
||||
tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `t`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `c` time DEFAULT '12:12:13',\n"+
|
||||
@ -1454,7 +1454,7 @@ func TestIssue9205(t *testing.T) {
|
||||
))
|
||||
|
||||
tk.MustExec(`alter table t alter column c1 set default '2019-02-01 12:12:10.4';`)
|
||||
tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `t`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `c` time DEFAULT '12:12:13',\n"+
|
||||
@ -1463,7 +1463,7 @@ func TestIssue9205(t *testing.T) {
|
||||
))
|
||||
|
||||
tk.MustExec(`alter table t modify c1 time DEFAULT '770:12:12.000000';`)
|
||||
tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `t`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `c` time DEFAULT '12:12:13',\n"+
|
||||
|
||||
@ -24,7 +24,6 @@ import (
|
||||
plannercore "github.com/pingcap/tidb/planner/core"
|
||||
"github.com/pingcap/tidb/session"
|
||||
"github.com/pingcap/tidb/testkit"
|
||||
"github.com/pingcap/tidb/util/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@ -386,11 +385,11 @@ func TestExplainStatementsSummary(t *testing.T) {
|
||||
tk.MustExec("use test")
|
||||
tk.MustQuery("desc select * from information_schema.statements_summary").Check(testkit.Rows(
|
||||
`MemTableScan_4 10000.00 root table:STATEMENTS_SUMMARY `))
|
||||
tk.MustQuery("desc select * from information_schema.statements_summary where digest is null").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("desc select * from information_schema.statements_summary where digest is null").Check(testkit.RowsWithSep("|",
|
||||
`Selection_5|8000.00|root| isnull(Column#5)`, `└─MemTableScan_6|10000.00|root|table:STATEMENTS_SUMMARY|`))
|
||||
tk.MustQuery("desc select * from information_schema.statements_summary where digest = 'abcdefg'").Check(testutil.RowsWithSep(" ",
|
||||
tk.MustQuery("desc select * from information_schema.statements_summary where digest = 'abcdefg'").Check(testkit.RowsWithSep(" ",
|
||||
`MemTableScan_5 10000.00 root table:STATEMENTS_SUMMARY digests: ["abcdefg"]`))
|
||||
tk.MustQuery("desc select * from information_schema.statements_summary where digest in ('a','b','c')").Check(testutil.RowsWithSep(" ",
|
||||
tk.MustQuery("desc select * from information_schema.statements_summary where digest in ('a','b','c')").Check(testkit.RowsWithSep(" ",
|
||||
`MemTableScan_5 10000.00 root table:STATEMENTS_SUMMARY digests: ["a","b","c"]`))
|
||||
}
|
||||
|
||||
|
||||
516
executor/hot_regions_history_table_test.go
Normal file
516
executor/hot_regions_history_table_test.go
Normal file
@ -0,0 +1,516 @@
|
||||
// Copyright 2022 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"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/pingcap/fn"
|
||||
"github.com/pingcap/tidb/executor"
|
||||
"github.com/pingcap/tidb/kv"
|
||||
"github.com/pingcap/tidb/parser/model"
|
||||
"github.com/pingcap/tidb/planner/core"
|
||||
"github.com/pingcap/tidb/session"
|
||||
"github.com/pingcap/tidb/store/helper"
|
||||
"github.com/pingcap/tidb/testkit"
|
||||
"github.com/pingcap/tidb/util/pdapi"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type mockStoreWithMultiPD struct {
|
||||
helper.Storage
|
||||
hosts []string
|
||||
}
|
||||
|
||||
var hotRegionsResponses = make(map[string]*executor.HistoryHotRegions, 3)
|
||||
|
||||
func (s *mockStoreWithMultiPD) EtcdAddrs() ([]string, error) { return s.hosts, nil }
|
||||
func (s *mockStoreWithMultiPD) TLSConfig() *tls.Config { panic("not implemented") }
|
||||
func (s *mockStoreWithMultiPD) StartGCWorker() error { panic("not implemented") }
|
||||
func (s *mockStoreWithMultiPD) Name() string { return "mockStore" }
|
||||
func (s *mockStoreWithMultiPD) Describe() string { return "" }
|
||||
|
||||
type hotRegionsHistoryTableSuite struct {
|
||||
suite.Suite
|
||||
store kv.Storage
|
||||
clean func()
|
||||
httpServers []*httptest.Server
|
||||
startTime time.Time
|
||||
}
|
||||
|
||||
func TestHotRegionsHistoryTable(t *testing.T) {
|
||||
suite.Run(t, new(hotRegionsHistoryTableSuite))
|
||||
}
|
||||
|
||||
func (s *hotRegionsHistoryTableSuite) SetupSuite() {
|
||||
s.store, s.clean = testkit.CreateMockStore(s.T())
|
||||
store := &mockStoreWithMultiPD{
|
||||
s.store.(helper.Storage),
|
||||
make([]string, 3),
|
||||
}
|
||||
// start 3 PD server with hotRegionsServer and store them in s.store
|
||||
for i := 0; i < 3; i++ {
|
||||
httpServer, mockAddr := s.setUpMockPDHTTPServer()
|
||||
s.Require().NotNil(httpServer)
|
||||
s.httpServers = append(s.httpServers, httpServer)
|
||||
store.hosts[i] = mockAddr
|
||||
}
|
||||
s.store = store
|
||||
s.startTime = time.Now()
|
||||
}
|
||||
|
||||
func writeResp(w http.ResponseWriter, resp interface{}) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
jsonResp, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, "unable to marshal resp", err)
|
||||
return
|
||||
}
|
||||
_, _ = w.Write(jsonResp)
|
||||
}
|
||||
|
||||
func writeJSONError(w http.ResponseWriter, code int, prefix string, err error) {
|
||||
type errorResponse struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
w.WriteHeader(code)
|
||||
if err != nil {
|
||||
prefix += ": " + err.Error()
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(errorResponse{Error: prefix})
|
||||
}
|
||||
|
||||
func hisHotRegionsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
data, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, "unable to read req", err)
|
||||
return
|
||||
}
|
||||
_ = r.Body.Close()
|
||||
req := &executor.HistoryHotRegionsRequest{}
|
||||
err = json.Unmarshal(data, req)
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, "unable to serialize req", err)
|
||||
return
|
||||
}
|
||||
resp := &executor.HistoryHotRegions{}
|
||||
for _, typ := range req.HotRegionTypes {
|
||||
resp.HistoryHotRegion = append(resp.HistoryHotRegion, hotRegionsResponses[typ+r.Host].HistoryHotRegion...)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
jsonResp, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, "unable to marshal resp", err)
|
||||
return
|
||||
}
|
||||
_, _ = w.Write(jsonResp)
|
||||
}
|
||||
|
||||
func (s *hotRegionsHistoryTableSuite) setUpMockPDHTTPServer() (*httptest.Server, string) {
|
||||
// mock PD http server
|
||||
router := mux.NewRouter()
|
||||
server := httptest.NewServer(router)
|
||||
mockAddr := strings.TrimPrefix(server.URL, "http://")
|
||||
// mock PD API
|
||||
router.Handle(pdapi.Status, fn.Wrap(func() (interface{}, error) {
|
||||
return struct {
|
||||
Version string `json:"version"`
|
||||
GitHash string `json:"git_hash"`
|
||||
StartTimestamp int64 `json:"start_timestamp"`
|
||||
}{
|
||||
Version: "4.0.0-alpha",
|
||||
GitHash: "mock-pd-githash",
|
||||
StartTimestamp: s.startTime.Unix(),
|
||||
}, nil
|
||||
}))
|
||||
// mock history hot regions response
|
||||
router.HandleFunc(pdapi.HotHistory, hisHotRegionsHandler)
|
||||
return server, mockAddr
|
||||
}
|
||||
|
||||
func (s *hotRegionsHistoryTableSuite) TearDownSuite() {
|
||||
for _, server := range s.httpServers {
|
||||
server.Close()
|
||||
}
|
||||
s.clean()
|
||||
}
|
||||
|
||||
func (s *hotRegionsHistoryTableSuite) TestTiDBHotRegionsHistory() {
|
||||
var unixTimeMs = func(v string) int64 {
|
||||
t, err := time.ParseInLocation("2006-01-02 15:04:05", v, time.Local)
|
||||
s.Require().NoError(err)
|
||||
return t.UnixNano() / int64(time.Millisecond)
|
||||
}
|
||||
fullHotRegions := [][]string{
|
||||
// mysql table_id = 11, table_name = TABLES_PRIV
|
||||
{"2019-10-10 10:10:11", "MYSQL", "TABLES_PRIV", "11", "<nil>", "<nil>", "1", "1", "11111", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:12", "MYSQL", "TABLES_PRIV", "11", "<nil>", "<nil>", "2", "2", "22222", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
// mysql table_id = 21, table_name = STATS_META
|
||||
{"2019-10-10 10:10:13", "MYSQL", "STATS_META", "21", "<nil>", "<nil>", "3", "3", "33333", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:14", "MYSQL", "STATS_META", "21", "<nil>", "<nil>", "4", "4", "44444", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
// table_id = 1313, deleted schema
|
||||
{"2019-10-10 10:10:15", "UNKNOWN", "UNKNOWN", "1313", "UNKNOWN", "<nil>", "5", "5", "55555", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:16", "UNKNOWN", "UNKNOWN", "1313", "UNKNOWN", "<nil>", "6", "6", "66666", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
// mysql table_id = 11, index_id = 1, table_name = TABLES_PRIV, index_name = PRIMARY
|
||||
{"2019-10-10 10:10:17", "MYSQL", "TABLES_PRIV", "11", "PRIMARY", "1", "1", "1", "11111", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:18", "MYSQL", "TABLES_PRIV", "11", "PRIMARY", "1", "2", "2", "22222", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
// mysql table_id = 21 ,index_id = 1, table_name = STATS_META, index_name = IDX_VER
|
||||
{"2019-10-10 10:10:19", "MYSQL", "STATS_META", "21", "IDX_VER", "1", "3", "3", "33333", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:20", "MYSQL", "STATS_META", "21", "IDX_VER", "1", "4", "4", "44444", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
// mysql table_id = 21 ,index_id = 2, table_name = STATS_META, index_name = TBL
|
||||
{"2019-10-10 10:10:21", "MYSQL", "STATS_META", "21", "TBL", "2", "5", "5", "55555", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:22", "MYSQL", "STATS_META", "21", "TBL", "2", "6", "6", "66666", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
// table_id = 1313, index_id = 1, deleted schema
|
||||
{"2019-10-10 10:10:23", "UNKNOWN", "UNKNOWN", "1313", "UNKNOWN", "1", "7", "7", "77777", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:24", "UNKNOWN", "UNKNOWN", "1313", "UNKNOWN", "1", "8", "8", "88888", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
}
|
||||
|
||||
mockDB := &model.DBInfo{}
|
||||
pdResps := []map[string]*executor.HistoryHotRegions{
|
||||
{
|
||||
core.HotRegionTypeRead: {
|
||||
HistoryHotRegion: []*executor.HistoryHotRegion{
|
||||
// mysql table_id = 11, table_name = TABLES_PRIV
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:11"), RegionID: 1, StoreID: 1, PeerID: 11111, IsLearner: false,
|
||||
IsLeader: true, HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 11}).StartKey,
|
||||
EndKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 11}).EndKey,
|
||||
},
|
||||
// mysql table_id = 21, table_name = STATS_META
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:13"), RegionID: 3, StoreID: 3, PeerID: 33333, IsLearner: false,
|
||||
IsLeader: true, HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 21}).StartKey,
|
||||
EndKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 21}).EndKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
core.HotRegionTypeWrite: {
|
||||
HistoryHotRegion: []*executor.HistoryHotRegion{
|
||||
// mysql table_id = 11, table_name = TABLES_PRIV
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:12"), RegionID: 2, StoreID: 2, PeerID: 22222, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 11}).StartKey,
|
||||
EndKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 11}).EndKey,
|
||||
},
|
||||
// mysql table_id = 21, table_name = STATS_META
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:14"), RegionID: 4, StoreID: 4, PeerID: 44444, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 21}).StartKey,
|
||||
EndKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 21}).EndKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
core.HotRegionTypeRead: {
|
||||
HistoryHotRegion: []*executor.HistoryHotRegion{
|
||||
// table_id = 1313, deleted schema
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:15"), RegionID: 5, StoreID: 5, PeerID: 55555, IsLearner: false,
|
||||
IsLeader: true, HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 1313}).StartKey,
|
||||
EndKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 1313}).EndKey,
|
||||
},
|
||||
// mysql table_id = 11, index_id = 1, table_name = TABLES_PRIV, index_name = PRIMARY
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:17"), RegionID: 1, StoreID: 1, PeerID: 11111, IsLearner: false,
|
||||
IsLeader: true, HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 11}, &model.IndexInfo{ID: 1}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 11}, &model.IndexInfo{ID: 1}).EndKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
core.HotRegionTypeWrite: {
|
||||
HistoryHotRegion: []*executor.HistoryHotRegion{
|
||||
// table_id = 1313, deleted schema
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:16"), RegionID: 6, StoreID: 6, PeerID: 66666, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 1313}).StartKey,
|
||||
EndKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 1313}).EndKey,
|
||||
},
|
||||
// mysql table_id = 11, index_id = 1, table_name = TABLES_PRIV, index_name = PRIMARY
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:18"), RegionID: 2, StoreID: 2, PeerID: 22222, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 11}, &model.IndexInfo{ID: 1}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 11}, &model.IndexInfo{ID: 1}).EndKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
core.HotRegionTypeRead: {
|
||||
HistoryHotRegion: []*executor.HistoryHotRegion{
|
||||
// mysql table_id = 21 ,index_id = 1, table_name = STATS_META, index_name = IDX_VER
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:19"), RegionID: 3, StoreID: 3, PeerID: 33333, IsLearner: false,
|
||||
IsLeader: true, HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 1}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 1}).EndKey,
|
||||
},
|
||||
// mysql table_id = 21 ,index_id = 2, table_name = STATS_META, index_name = TBL
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:21"), RegionID: 5, StoreID: 5, PeerID: 55555, IsLearner: false,
|
||||
IsLeader: true, HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 2}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 2}).EndKey,
|
||||
},
|
||||
// table_id = 1313, index_id = 1, deleted schema
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:23"), RegionID: 7, StoreID: 7, PeerID: 77777, IsLeader: true,
|
||||
HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 1313}, &model.IndexInfo{ID: 1}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 1313}, &model.IndexInfo{ID: 1}).EndKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
core.HotRegionTypeWrite: {
|
||||
HistoryHotRegion: []*executor.HistoryHotRegion{
|
||||
// mysql table_id = 21 ,index_id = 1, table_name = STATS_META, index_name = IDX_VER
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:20"), RegionID: 4, StoreID: 4, PeerID: 44444, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 1}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 1}).EndKey,
|
||||
},
|
||||
// mysql table_id = 21 ,index_id = 2, table_name = STATS_META, index_name = TBL
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:22"), RegionID: 6, StoreID: 6, PeerID: 66666, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 2}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 2}).EndKey,
|
||||
},
|
||||
// table_id = 1313, index_id = 1, deleted schema
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:24"), RegionID: 8, StoreID: 8, PeerID: 88888, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 1313}, &model.IndexInfo{ID: 1}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 1313}, &model.IndexInfo{ID: 1}).EndKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var cases = []struct {
|
||||
conditions []string
|
||||
reqCount int32
|
||||
expected [][]string
|
||||
}{
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
}, // time filtered by PD, assume response suit time range, and ignore deleted schemas
|
||||
expected: [][]string{
|
||||
fullHotRegions[0], fullHotRegions[1], fullHotRegions[2],
|
||||
fullHotRegions[3],
|
||||
fullHotRegions[6], fullHotRegions[7], fullHotRegions[8],
|
||||
fullHotRegions[9], fullHotRegions[10], fullHotRegions[11],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>=TIMESTAMP('2019-10-10 10:10:10')",
|
||||
"update_time<=TIMESTAMP('2019-10-11 10:10:10')",
|
||||
}, // test support of timestamp
|
||||
expected: [][]string{
|
||||
fullHotRegions[0], fullHotRegions[1], fullHotRegions[2],
|
||||
fullHotRegions[3],
|
||||
fullHotRegions[6], fullHotRegions[7], fullHotRegions[8],
|
||||
fullHotRegions[9], fullHotRegions[10], fullHotRegions[11],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_id=11",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullHotRegions[0], fullHotRegions[1], fullHotRegions[6], fullHotRegions[7],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_name='TABLES_PRIV'",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullHotRegions[0], fullHotRegions[1], fullHotRegions[6], fullHotRegions[7],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_id=21",
|
||||
"index_id=1",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullHotRegions[8], fullHotRegions[9],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_id=21",
|
||||
"index_id=1",
|
||||
"table_name='TABLES_PRIV'",
|
||||
}, // table_id != table_name -> nil
|
||||
expected: [][]string{},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_id=21",
|
||||
"index_id=1",
|
||||
"table_name='STATS_META'",
|
||||
}, // table_id = table_name
|
||||
expected: [][]string{
|
||||
fullHotRegions[8], fullHotRegions[9],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_id=21",
|
||||
"index_id=1",
|
||||
"index_name='UNKNOWN'",
|
||||
}, // index_id != index_name -> nil
|
||||
expected: [][]string{},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_id=21",
|
||||
"index_id=1",
|
||||
"index_name='IDX_VER'",
|
||||
}, // index_id = index_name
|
||||
expected: [][]string{
|
||||
fullHotRegions[8], fullHotRegions[9],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"index_id=1",
|
||||
"index_name='IDX_VER'",
|
||||
"table_id>=21", // unpushed down predicates 21>=21
|
||||
},
|
||||
expected: [][]string{
|
||||
fullHotRegions[8], fullHotRegions[9],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"index_id=1",
|
||||
"index_name='IDX_VER'",
|
||||
"table_id>21", // unpushed down predicates
|
||||
}, // 21!>21 -> nil
|
||||
expected: [][]string{},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"index_id=1",
|
||||
"index_name='IDX_VER'",
|
||||
"table_id>=21", // unpushed down predicates
|
||||
"db_name='MYSQL'",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullHotRegions[8], fullHotRegions[9],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"index_id=1",
|
||||
"index_name='IDX_VER'",
|
||||
"table_id>=21", // unpushed down predicates
|
||||
"db_name='MYSQL'",
|
||||
"peer_id>=33334",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullHotRegions[9],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"index_id=1",
|
||||
"index_name='IDX_VER'",
|
||||
"table_id>=21", // unpushed down predicates
|
||||
"db_name='UNKNOWN'",
|
||||
},
|
||||
expected: [][]string{},
|
||||
},
|
||||
}
|
||||
|
||||
// mock http resp
|
||||
store := s.store.(*mockStoreWithMultiPD)
|
||||
for i, resp := range pdResps {
|
||||
for k, v := range resp {
|
||||
hotRegionsResponses[k+store.hosts[i]] = v
|
||||
}
|
||||
}
|
||||
tk := testkit.NewTestKit(s.T(), s.store)
|
||||
for _, cas := range cases {
|
||||
sql := "select * from information_schema.tidb_hot_regions_history"
|
||||
if len(cas.conditions) > 0 {
|
||||
sql = fmt.Sprintf("%s where %s", sql, strings.Join(cas.conditions, " and "))
|
||||
}
|
||||
result := tk.MustQuery(sql)
|
||||
warnings := tk.Session().GetSessionVars().StmtCtx.GetWarnings()
|
||||
s.Require().Lenf(warnings, 0, "unexpected warnings: %+v, sql: %s", warnings, sql)
|
||||
var expected []string
|
||||
for _, row := range cas.expected {
|
||||
expectedRow := row
|
||||
expected = append(expected, strings.Join(expectedRow, " "))
|
||||
}
|
||||
result.Check(testkit.Rows(expected...))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *hotRegionsHistoryTableSuite) TestTiDBHotRegionsHistoryError() {
|
||||
tk := testkit.NewTestKit(s.T(), s.store)
|
||||
|
||||
// Test without start time error
|
||||
rs, err := tk.Exec("select * from information_schema.tidb_hot_regions_history")
|
||||
s.Require().NoError(err)
|
||||
_, err = session.ResultSetToStringSlice(context.Background(), tk.Session(), rs)
|
||||
s.Require().EqualError(err, "denied to scan hot regions, please specified the start time, such as `update_time > '2020-01-01 00:00:00'`")
|
||||
s.NoError(rs.Close())
|
||||
|
||||
// Test without end time error.
|
||||
rs, err = tk.Exec("select * from information_schema.tidb_hot_regions_history where update_time>='2019/08/26 06:18:13.011'")
|
||||
s.Require().NoError(err)
|
||||
_, err = session.ResultSetToStringSlice(context.Background(), tk.Session(), rs)
|
||||
s.Require().EqualError(err, "denied to scan hot regions, please specified the end time, such as `update_time < '2020-01-01 00:00:00'`")
|
||||
s.NoError(rs.Close())
|
||||
}
|
||||
356
executor/infoschema_cluster_table_test.go
Normal file
356
executor/infoschema_cluster_table_test.go
Normal file
@ -0,0 +1,356 @@
|
||||
// Copyright 2022 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 (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/pingcap/failpoint"
|
||||
"github.com/pingcap/fn"
|
||||
"github.com/pingcap/tidb/config"
|
||||
"github.com/pingcap/tidb/domain"
|
||||
"github.com/pingcap/tidb/kv"
|
||||
"github.com/pingcap/tidb/parser/auth"
|
||||
"github.com/pingcap/tidb/parser/mysql"
|
||||
"github.com/pingcap/tidb/server"
|
||||
"github.com/pingcap/tidb/session/txninfo"
|
||||
"github.com/pingcap/tidb/store/helper"
|
||||
"github.com/pingcap/tidb/testkit"
|
||||
"github.com/pingcap/tidb/util"
|
||||
"github.com/pingcap/tidb/util/pdapi"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type infosSchemaClusterTableSuite struct {
|
||||
suite.Suite
|
||||
store kv.Storage
|
||||
dom *domain.Domain
|
||||
clean func()
|
||||
rpcServer *grpc.Server
|
||||
httpServer *httptest.Server
|
||||
mockAddr string
|
||||
listenAddr string
|
||||
startTime time.Time
|
||||
}
|
||||
|
||||
func TestInfoSchemaClusterTable(t *testing.T) {
|
||||
suite.Run(t, new(infosSchemaClusterTableSuite))
|
||||
}
|
||||
|
||||
func (s *infosSchemaClusterTableSuite) SetupSuite() {
|
||||
s.store, s.dom, s.clean = testkit.CreateMockStoreAndDomain(s.T())
|
||||
s.rpcServer, s.listenAddr = s.setUpRPCService("127.0.0.1:0")
|
||||
s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer()
|
||||
s.startTime = time.Now()
|
||||
}
|
||||
|
||||
func (s *infosSchemaClusterTableSuite) setUpRPCService(addr string) (*grpc.Server, string) {
|
||||
lis, err := net.Listen("tcp", addr)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Fix issue 9836
|
||||
sm := &mockSessionManager{
|
||||
processInfoMap: make(map[uint64]*util.ProcessInfo, 1),
|
||||
serverID: 1,
|
||||
}
|
||||
sm.processInfoMap[1] = &util.ProcessInfo{
|
||||
ID: 1,
|
||||
User: "root",
|
||||
Host: "127.0.0.1",
|
||||
Command: mysql.ComQuery,
|
||||
}
|
||||
srv := server.NewRPCServer(config.GetGlobalConfig(), s.dom, sm)
|
||||
port := lis.Addr().(*net.TCPAddr).Port
|
||||
addr = fmt.Sprintf("127.0.0.1:%d", port)
|
||||
go func() {
|
||||
s.Require().NoError(srv.Serve(lis))
|
||||
}()
|
||||
config.UpdateGlobal(func(conf *config.Config) {
|
||||
conf.Status.StatusPort = uint(port)
|
||||
})
|
||||
return srv, addr
|
||||
}
|
||||
|
||||
func (s *infosSchemaClusterTableSuite) setUpMockPDHTTPServer() (*httptest.Server, string) {
|
||||
// mock PD http server
|
||||
router := mux.NewRouter()
|
||||
srv := httptest.NewServer(router)
|
||||
// mock store stats stat
|
||||
mockAddr := strings.TrimPrefix(srv.URL, "http://")
|
||||
router.Handle(pdapi.Stores, fn.Wrap(func() (*helper.StoresStat, error) {
|
||||
return &helper.StoresStat{
|
||||
Count: 1,
|
||||
Stores: []helper.StoreStat{
|
||||
{
|
||||
Store: helper.StoreBaseStat{
|
||||
ID: 1,
|
||||
Address: "127.0.0.1:20160",
|
||||
State: 0,
|
||||
StateName: "Up",
|
||||
Version: "4.0.0-alpha",
|
||||
StatusAddress: mockAddr,
|
||||
GitHash: "mock-tikv-githash",
|
||||
StartTimestamp: s.startTime.Unix(),
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}))
|
||||
// mock PD API
|
||||
router.Handle(pdapi.Status, fn.Wrap(func() (interface{}, error) {
|
||||
return struct {
|
||||
Version string `json:"version"`
|
||||
GitHash string `json:"git_hash"`
|
||||
StartTimestamp int64 `json:"start_timestamp"`
|
||||
}{
|
||||
Version: "4.0.0-alpha",
|
||||
GitHash: "mock-pd-githash",
|
||||
StartTimestamp: s.startTime.Unix(),
|
||||
}, nil
|
||||
}))
|
||||
var mockConfig = func() (map[string]interface{}, error) {
|
||||
configuration := map[string]interface{}{
|
||||
"key1": "value1",
|
||||
"key2": map[string]string{
|
||||
"nest1": "n-value1",
|
||||
"nest2": "n-value2",
|
||||
},
|
||||
"key3": map[string]interface{}{
|
||||
"nest1": "n-value1",
|
||||
"nest2": "n-value2",
|
||||
"key4": map[string]string{
|
||||
"nest3": "n-value4",
|
||||
"nest4": "n-value5",
|
||||
},
|
||||
},
|
||||
}
|
||||
return configuration, nil
|
||||
}
|
||||
// PD config.
|
||||
router.Handle(pdapi.Config, fn.Wrap(mockConfig))
|
||||
// TiDB/TiKV config.
|
||||
router.Handle("/config", fn.Wrap(mockConfig))
|
||||
// PD region.
|
||||
router.Handle("/pd/api/v1/stats/region", fn.Wrap(func() (*helper.PDRegionStats, error) {
|
||||
return &helper.PDRegionStats{
|
||||
Count: 1,
|
||||
EmptyCount: 1,
|
||||
StorageSize: 1,
|
||||
StorageKeys: 1,
|
||||
StoreLeaderCount: map[uint64]int{1: 1},
|
||||
StorePeerCount: map[uint64]int{1: 1},
|
||||
}, nil
|
||||
}))
|
||||
return srv, mockAddr
|
||||
}
|
||||
|
||||
func (s *infosSchemaClusterTableSuite) TearDownSuite() {
|
||||
s.rpcServer.Stop()
|
||||
s.httpServer.Close()
|
||||
s.clean()
|
||||
}
|
||||
|
||||
type mockSessionManager struct {
|
||||
processInfoMap map[uint64]*util.ProcessInfo
|
||||
serverID uint64
|
||||
}
|
||||
|
||||
func (sm *mockSessionManager) ShowTxnList() []*txninfo.TxnInfo {
|
||||
panic("unimplemented!")
|
||||
}
|
||||
|
||||
func (sm *mockSessionManager) ShowProcessList() map[uint64]*util.ProcessInfo {
|
||||
return sm.processInfoMap
|
||||
}
|
||||
|
||||
func (sm *mockSessionManager) GetProcessInfo(id uint64) (*util.ProcessInfo, bool) {
|
||||
rs, ok := sm.processInfoMap[id]
|
||||
return rs, ok
|
||||
}
|
||||
|
||||
func (sm *mockSessionManager) Kill(_ uint64, _ bool) {}
|
||||
|
||||
func (sm *mockSessionManager) KillAllConnections() {}
|
||||
|
||||
func (sm *mockSessionManager) UpdateTLSConfig(_ *tls.Config) {}
|
||||
|
||||
func (sm *mockSessionManager) ServerID() uint64 {
|
||||
return sm.serverID
|
||||
}
|
||||
|
||||
func (sm *mockSessionManager) SetServerID(serverID uint64) {
|
||||
sm.serverID = serverID
|
||||
}
|
||||
|
||||
type mockStore struct {
|
||||
helper.Storage
|
||||
host string
|
||||
}
|
||||
|
||||
func (s *mockStore) EtcdAddrs() ([]string, error) { return []string{s.host}, nil }
|
||||
func (s *mockStore) TLSConfig() *tls.Config { panic("not implemented") }
|
||||
func (s *mockStore) StartGCWorker() error { panic("not implemented") }
|
||||
func (s *mockStore) Name() string { return "mockStore" }
|
||||
func (s *mockStore) Describe() string { return "" }
|
||||
|
||||
func (s *infosSchemaClusterTableSuite) TestTiDBClusterInfo() {
|
||||
mockAddr := s.mockAddr
|
||||
store := &mockStore{
|
||||
s.store.(helper.Storage),
|
||||
mockAddr,
|
||||
}
|
||||
|
||||
// information_schema.cluster_info
|
||||
tk := testkit.NewTestKit(s.T(), store)
|
||||
tidbStatusAddr := fmt.Sprintf(":%d", config.GetGlobalConfig().Status.StatusPort)
|
||||
row := func(cols ...string) string { return strings.Join(cols, " ") }
|
||||
tk.MustQuery("select type, instance, status_address, version, git_hash from information_schema.cluster_info").Check(testkit.Rows(
|
||||
row("tidb", ":4000", tidbStatusAddr, "None", "None"),
|
||||
row("pd", mockAddr, mockAddr, "4.0.0-alpha", "mock-pd-githash"),
|
||||
row("tikv", "store1", "", "", ""),
|
||||
))
|
||||
startTime := s.startTime.Format(time.RFC3339)
|
||||
tk.MustQuery("select type, instance, start_time from information_schema.cluster_info where type != 'tidb'").Check(testkit.Rows(
|
||||
row("pd", mockAddr, startTime),
|
||||
row("tikv", "store1", ""),
|
||||
))
|
||||
|
||||
s.Require().NoError(failpoint.Enable("github.com/pingcap/tidb/infoschema/mockStoreTombstone", `return(true)`))
|
||||
tk.MustQuery("select type, instance, start_time from information_schema.cluster_info where type = 'tikv'").Check(testkit.Rows())
|
||||
s.Require().NoError(failpoint.Disable("github.com/pingcap/tidb/infoschema/mockStoreTombstone"))
|
||||
|
||||
// information_schema.cluster_config
|
||||
instances := []string{
|
||||
"pd,127.0.0.1:11080," + mockAddr + ",mock-version,mock-githash,0",
|
||||
"tidb,127.0.0.1:11080," + mockAddr + ",mock-version,mock-githash,1001",
|
||||
"tikv,127.0.0.1:11080," + mockAddr + ",mock-version,mock-githash,0",
|
||||
}
|
||||
fpExpr := `return("` + strings.Join(instances, ";") + `")`
|
||||
s.Require().NoError(failpoint.Enable("github.com/pingcap/tidb/infoschema/mockClusterInfo", fpExpr))
|
||||
defer func() { s.Require().NoError(failpoint.Disable("github.com/pingcap/tidb/infoschema/mockClusterInfo")) }()
|
||||
tk.MustQuery("select type, instance, status_address, version, git_hash, server_id from information_schema.cluster_info").Check(testkit.Rows(
|
||||
row("pd", "127.0.0.1:11080", mockAddr, "mock-version", "mock-githash", "0"),
|
||||
row("tidb", "127.0.0.1:11080", mockAddr, "mock-version", "mock-githash", "1001"),
|
||||
row("tikv", "127.0.0.1:11080", mockAddr, "mock-version", "mock-githash", "0"),
|
||||
))
|
||||
tk.MustQuery("select * from information_schema.cluster_config").Check(testkit.Rows(
|
||||
"pd 127.0.0.1:11080 key1 value1",
|
||||
"pd 127.0.0.1:11080 key2.nest1 n-value1",
|
||||
"pd 127.0.0.1:11080 key2.nest2 n-value2",
|
||||
"pd 127.0.0.1:11080 key3.key4.nest3 n-value4",
|
||||
"pd 127.0.0.1:11080 key3.key4.nest4 n-value5",
|
||||
"pd 127.0.0.1:11080 key3.nest1 n-value1",
|
||||
"pd 127.0.0.1:11080 key3.nest2 n-value2",
|
||||
"tidb 127.0.0.1:11080 key1 value1",
|
||||
"tidb 127.0.0.1:11080 key2.nest1 n-value1",
|
||||
"tidb 127.0.0.1:11080 key2.nest2 n-value2",
|
||||
"tidb 127.0.0.1:11080 key3.key4.nest3 n-value4",
|
||||
"tidb 127.0.0.1:11080 key3.key4.nest4 n-value5",
|
||||
"tidb 127.0.0.1:11080 key3.nest1 n-value1",
|
||||
"tidb 127.0.0.1:11080 key3.nest2 n-value2",
|
||||
"tikv 127.0.0.1:11080 key1 value1",
|
||||
"tikv 127.0.0.1:11080 key2.nest1 n-value1",
|
||||
"tikv 127.0.0.1:11080 key2.nest2 n-value2",
|
||||
"tikv 127.0.0.1:11080 key3.key4.nest3 n-value4",
|
||||
"tikv 127.0.0.1:11080 key3.key4.nest4 n-value5",
|
||||
"tikv 127.0.0.1:11080 key3.nest1 n-value1",
|
||||
"tikv 127.0.0.1:11080 key3.nest2 n-value2",
|
||||
))
|
||||
tk.MustQuery("select TYPE, `KEY`, VALUE from information_schema.cluster_config where `key`='key3.key4.nest4' order by type").Check(testkit.Rows(
|
||||
"pd key3.key4.nest4 n-value5",
|
||||
"tidb key3.key4.nest4 n-value5",
|
||||
"tikv key3.key4.nest4 n-value5",
|
||||
))
|
||||
}
|
||||
|
||||
func (s *infosSchemaClusterTableSuite) TestTableStorageStats() {
|
||||
tk := testkit.NewTestKit(s.T(), s.store)
|
||||
err := tk.QueryToErr("select * from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'test'")
|
||||
s.Require().EqualError(err, "pd unavailable")
|
||||
mockAddr := s.mockAddr
|
||||
store := &mockStore{
|
||||
s.store.(helper.Storage),
|
||||
mockAddr,
|
||||
}
|
||||
|
||||
// Test information_schema.TABLE_STORAGE_STATS.
|
||||
tk = testkit.NewTestKit(s.T(), store)
|
||||
|
||||
// Test not set the schema.
|
||||
err = tk.QueryToErr("select * from information_schema.TABLE_STORAGE_STATS")
|
||||
s.Require().EqualError(err, "Please specify the 'table_schema'")
|
||||
|
||||
// Test it would get null set when get the sys schema.
|
||||
tk.MustQuery("select TABLE_NAME from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'information_schema';").Check([][]interface{}{})
|
||||
tk.MustQuery("select TABLE_NAME from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA in ('information_schema', 'metrics_schema');").Check([][]interface{}{})
|
||||
tk.MustQuery("select TABLE_NAME from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'information_schema' and TABLE_NAME='schemata';").Check([][]interface{}{})
|
||||
|
||||
tk.MustExec("use test")
|
||||
tk.MustExec("drop table if exists t")
|
||||
tk.MustExec("create table t (a int, b int, index idx(a))")
|
||||
tk.MustQuery("select TABLE_NAME, TABLE_SIZE from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'test' and TABLE_NAME='t';").Check(testkit.Rows("t 1"))
|
||||
|
||||
tk.MustExec("create table t1 (a int, b int, index idx(a))")
|
||||
tk.MustQuery("select TABLE_NAME, sum(TABLE_SIZE) from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'test' group by TABLE_NAME;").Sort().Check(testkit.Rows(
|
||||
"t 1",
|
||||
"t1 1",
|
||||
))
|
||||
tk.MustQuery("select TABLE_SCHEMA, sum(TABLE_SIZE) from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'test' group by TABLE_SCHEMA;").Check(testkit.Rows(
|
||||
"test 2",
|
||||
))
|
||||
rows := tk.MustQuery("select TABLE_NAME from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'mysql';").Rows()
|
||||
s.Require().Len(rows, 29)
|
||||
|
||||
// More tests about the privileges.
|
||||
tk.MustExec("create user 'testuser'@'localhost'")
|
||||
tk.MustExec("create user 'testuser2'@'localhost'")
|
||||
tk.MustExec("create user 'testuser3'@'localhost'")
|
||||
tk1 := testkit.NewTestKit(s.T(), store)
|
||||
defer tk1.MustExec("drop user 'testuser'@'localhost'")
|
||||
defer tk1.MustExec("drop user 'testuser2'@'localhost'")
|
||||
defer tk1.MustExec("drop user 'testuser3'@'localhost'")
|
||||
|
||||
tk.MustExec("grant all privileges on *.* to 'testuser2'@'localhost'")
|
||||
tk.MustExec("grant select on *.* to 'testuser3'@'localhost'")
|
||||
s.Require().True(tk.Session().Auth(&auth.UserIdentity{
|
||||
Username: "testuser",
|
||||
Hostname: "localhost",
|
||||
}, nil, nil))
|
||||
|
||||
// User has no access to this schema, so the result set is empty.
|
||||
tk.MustQuery("select count(1) from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'mysql'").Check(testkit.Rows("0"))
|
||||
|
||||
s.Require().True(tk.Session().Auth(&auth.UserIdentity{
|
||||
Username: "testuser2",
|
||||
Hostname: "localhost",
|
||||
}, nil, nil))
|
||||
|
||||
tk.MustQuery("select count(1) from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'mysql'").Check(testkit.Rows("29"))
|
||||
|
||||
s.Require().True(tk.Session().Auth(&auth.UserIdentity{
|
||||
Username: "testuser3",
|
||||
Hostname: "localhost",
|
||||
}, nil, nil))
|
||||
|
||||
tk.MustQuery("select count(1) from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'mysql'").Check(testkit.Rows("29"))
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,6 @@ import (
|
||||
"github.com/pingcap/tidb/types"
|
||||
"github.com/pingcap/tidb/util"
|
||||
"github.com/pingcap/tidb/util/execdetails"
|
||||
"github.com/pingcap/tidb/util/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@ -219,20 +218,20 @@ func TestInsertOnDuplicateKey(t *testing.T) {
|
||||
tk.MustExec("insert into b values (2, '12:34:56', 'c', 10), (3, '01:23:45', 'd', 20)")
|
||||
tk.MustExec("insert into a (id) select id from b on duplicate key update a.a2 = b.b2, a.a3 = 3.3")
|
||||
require.Equal(t, uint64(3), tk.Session().AffectedRows())
|
||||
tk.MustQuery("select * from a").Check(testutil.RowsWithSep("/",
|
||||
tk.MustQuery("select * from a").Check(testkit.RowsWithSep("/",
|
||||
"1/2022-01-04 07:02:04/a/1.1",
|
||||
"2/2022-01-04 07:02:05/c/3.3",
|
||||
"3/<nil>/<nil>/<nil>"))
|
||||
tk.MustExec("insert into a (id) select 4 from b where b3 = 20 on duplicate key update a.a3 = b.b3")
|
||||
require.Equal(t, uint64(1), tk.Session().AffectedRows())
|
||||
tk.MustQuery("select * from a").Check(testutil.RowsWithSep("/",
|
||||
tk.MustQuery("select * from a").Check(testkit.RowsWithSep("/",
|
||||
"1/2022-01-04 07:02:04/a/1.1",
|
||||
"2/2022-01-04 07:02:05/c/3.3",
|
||||
"3/<nil>/<nil>/<nil>",
|
||||
"4/<nil>/<nil>/<nil>"))
|
||||
tk.MustExec("insert into a (a2, a3) select 'x', 1.2 from b on duplicate key update a.a2 = b.b3")
|
||||
require.Equal(t, uint64(2), tk.Session().AffectedRows())
|
||||
tk.MustQuery("select * from a").Check(testutil.RowsWithSep("/",
|
||||
tk.MustQuery("select * from a").Check(testkit.RowsWithSep("/",
|
||||
"1/2022-01-04 07:02:04/a/1.1",
|
||||
"2/2022-01-04 07:02:05/c/3.3",
|
||||
"3/<nil>/<nil>/<nil>",
|
||||
@ -1139,7 +1138,7 @@ func TestInsertFloatOverflow(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
_, err = tk.Exec("insert ignore into t1 values(999999999999999999999999999999999999999,-999999999999999999999999999999999999999)")
|
||||
require.NoError(t, err)
|
||||
tk.MustQuery("select @@warning_count").Check(testutil.RowsWithSep("|", "2"))
|
||||
tk.MustQuery("select @@warning_count").Check(testkit.RowsWithSep("|", "2"))
|
||||
tk.MustQuery("select convert(id1,decimal(65)),convert(id2,decimal(65)) from t1").Check(testkit.Rows("340282346638528860000000000000000000000 -340282346638528860000000000000000000000"))
|
||||
tk.MustExec("drop table if exists t,t1")
|
||||
}
|
||||
@ -1587,7 +1586,7 @@ func TestDuplicateEntryMessage(t *testing.T) {
|
||||
tk.MustExec("create table t (a char(10) collate utf8mb4_unicode_ci, b char(20) collate utf8mb4_general_ci, c int(11), primary key (a, b, c), unique key (a));")
|
||||
tk.MustExec("insert ignore into t values ('$', 'C', 10);")
|
||||
tk.MustExec("insert ignore into t values ('$', 'C', 10);")
|
||||
tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", "Warning|1062|Duplicate entry '$-C-10' for key 'PRIMARY'"))
|
||||
tk.MustQuery("show warnings;").Check(testkit.RowsWithSep("|", "Warning|1062|Duplicate entry '$-C-10' for key 'PRIMARY'"))
|
||||
|
||||
tk.MustExec("begin pessimistic;")
|
||||
tk.MustExec("insert into t values ('a7', 'a', 10);")
|
||||
@ -1852,7 +1851,7 @@ func TestStringtoDecimal(t *testing.T) {
|
||||
tk.MustGetErrCode("insert into t values('1.2.')", errno.ErrTruncatedWrongValueForField)
|
||||
tk.MustGetErrCode("insert into t values('1,999.00')", errno.ErrTruncatedWrongValueForField)
|
||||
tk.MustExec("insert into t values('12e-3')")
|
||||
tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '0.012'"))
|
||||
tk.MustQuery("show warnings;").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '0.012'"))
|
||||
tk.MustQuery("select id from t").Check(testkit.Rows("0"))
|
||||
tk.MustExec("drop table if exists t")
|
||||
}
|
||||
@ -1873,7 +1872,7 @@ func TestIssue17745(t *testing.T) {
|
||||
tk.MustExec("drop table if exists tt1")
|
||||
tk.MustGetErrCode("insert into tt1 values(4556414e723532)", errno.ErrIllegalValueForType)
|
||||
tk.MustQuery("select 888888888888888888888888888888888888888888888888888888888888888888888888888888888888").Check(testkit.Rows("99999999999999999999999999999999999999999999999999999999999999999"))
|
||||
tk.MustQuery("show warnings;").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '888888888888888888888888888888888888888888888888888888888888888888888888888888888'"))
|
||||
tk.MustQuery("show warnings;").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '888888888888888888888888888888888888888888888888888888888888888888888888888888888'"))
|
||||
}
|
||||
|
||||
// TestInsertIssue29892 test the double type with auto_increment problem, just leverage the serial test suite.
|
||||
|
||||
@ -16,17 +16,12 @@ package executor_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@ -38,12 +33,8 @@ import (
|
||||
"github.com/pingcap/kvproto/pkg/diagnosticspb"
|
||||
"github.com/pingcap/sysutil"
|
||||
"github.com/pingcap/tidb/domain"
|
||||
"github.com/pingcap/tidb/executor"
|
||||
"github.com/pingcap/tidb/kv"
|
||||
"github.com/pingcap/tidb/parser/model"
|
||||
"github.com/pingcap/tidb/planner/core"
|
||||
"github.com/pingcap/tidb/session"
|
||||
"github.com/pingcap/tidb/store/helper"
|
||||
"github.com/pingcap/tidb/util/pdapi"
|
||||
"github.com/pingcap/tidb/util/testkit"
|
||||
pmodel "github.com/prometheus/common/model"
|
||||
@ -964,664 +955,3 @@ func (s *testMemTableReaderSuite) TestTiDBClusterLogError(c *C) {
|
||||
c.Assert(err.Error(), Equals, "denied to scan full logs (use `SELECT * FROM cluster_log WHERE message LIKE '%'` explicitly if intentionally)")
|
||||
c.Assert(rs.Close(), IsNil)
|
||||
}
|
||||
|
||||
type mockStoreWithMultiPD struct {
|
||||
helper.Storage
|
||||
hosts []string
|
||||
}
|
||||
|
||||
var hotRegionsResponses = make(map[string]*executor.HistoryHotRegions, 3)
|
||||
|
||||
func (s *mockStoreWithMultiPD) EtcdAddrs() ([]string, error) { return s.hosts, nil }
|
||||
func (s *mockStoreWithMultiPD) TLSConfig() *tls.Config { panic("not implemented") }
|
||||
func (s *mockStoreWithMultiPD) StartGCWorker() error { panic("not implemented") }
|
||||
func (s *mockStoreWithMultiPD) Name() string { return "mockStore" }
|
||||
func (s *mockStoreWithMultiPD) Describe() string { return "" }
|
||||
|
||||
var _ = SerialSuites(&testHotRegionsHistoryTableSuite{testInfoschemaTableSuiteBase: &testInfoschemaTableSuiteBase{}})
|
||||
|
||||
type testHotRegionsHistoryTableSuite struct {
|
||||
*testInfoschemaTableSuiteBase
|
||||
httpServers []*httptest.Server
|
||||
startTime time.Time
|
||||
}
|
||||
|
||||
func (s *testHotRegionsHistoryTableSuite) SetUpSuite(c *C) {
|
||||
s.testInfoschemaTableSuiteBase.SetUpSuite(c)
|
||||
store := &mockStoreWithMultiPD{
|
||||
s.store.(helper.Storage),
|
||||
make([]string, 3),
|
||||
}
|
||||
// start 3 PD server with hotRegionsServer and store them in s.store
|
||||
for i := 0; i < 3; i++ {
|
||||
httpServer, mockAddr := s.setUpMockPDHTTPServer(c)
|
||||
c.Assert(httpServer, NotNil)
|
||||
s.httpServers = append(s.httpServers, httpServer)
|
||||
store.hosts[i] = mockAddr
|
||||
}
|
||||
s.store = store
|
||||
s.startTime = time.Now()
|
||||
}
|
||||
|
||||
func writeResp(w http.ResponseWriter, resp interface{}) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
jsonResp, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, "unable to marshal resp", err)
|
||||
return
|
||||
}
|
||||
w.Write(jsonResp)
|
||||
}
|
||||
|
||||
func writeJSONError(w http.ResponseWriter, code int, prefix string, err error) {
|
||||
type errorResponse struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
w.WriteHeader(code)
|
||||
if err != nil {
|
||||
prefix += ": " + err.Error()
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(errorResponse{Error: prefix})
|
||||
}
|
||||
|
||||
func hisHotRegionsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
data, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, "unable to read req", err)
|
||||
return
|
||||
}
|
||||
r.Body.Close()
|
||||
req := &executor.HistoryHotRegionsRequest{}
|
||||
err = json.Unmarshal(data, req)
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, "unable to serialize req", err)
|
||||
return
|
||||
}
|
||||
resp := &executor.HistoryHotRegions{}
|
||||
for _, typ := range req.HotRegionTypes {
|
||||
resp.HistoryHotRegion = append(resp.HistoryHotRegion, hotRegionsResponses[typ+r.Host].HistoryHotRegion...)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
jsonResp, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, "unable to marshal resp", err)
|
||||
return
|
||||
}
|
||||
w.Write(jsonResp)
|
||||
}
|
||||
|
||||
func (s *testHotRegionsHistoryTableSuite) setUpMockPDHTTPServer(c *C) (*httptest.Server, string) {
|
||||
// mock PD http server
|
||||
router := mux.NewRouter()
|
||||
server := httptest.NewServer(router)
|
||||
mockAddr := strings.TrimPrefix(server.URL, "http://")
|
||||
// mock PD API
|
||||
router.Handle(pdapi.Status, fn.Wrap(func() (interface{}, error) {
|
||||
return struct {
|
||||
Version string `json:"version"`
|
||||
GitHash string `json:"git_hash"`
|
||||
StartTimestamp int64 `json:"start_timestamp"`
|
||||
}{
|
||||
Version: "4.0.0-alpha",
|
||||
GitHash: "mock-pd-githash",
|
||||
StartTimestamp: s.startTime.Unix(),
|
||||
}, nil
|
||||
}))
|
||||
// mock hisory hot regions response
|
||||
router.HandleFunc(pdapi.HotHistory, hisHotRegionsHandler)
|
||||
return server, mockAddr
|
||||
}
|
||||
|
||||
func (s *testHotRegionsHistoryTableSuite) TearDownSuite(c *C) {
|
||||
for _, server := range s.httpServers {
|
||||
server.Close()
|
||||
}
|
||||
s.testInfoschemaTableSuiteBase.TearDownSuite(c)
|
||||
}
|
||||
|
||||
func (s *testHotRegionsHistoryTableSuite) TestTiDBHotRegionsHistory(c *C) {
|
||||
var unixTimeMs = func(s string) int64 {
|
||||
t, err := time.ParseInLocation("2006-01-02 15:04:05", s, time.Local)
|
||||
c.Assert(err, IsNil)
|
||||
return t.UnixNano() / int64(time.Millisecond)
|
||||
}
|
||||
fullHotRegions := [][]string{
|
||||
// mysql table_id = 11, table_name = TABLES_PRIV
|
||||
{"2019-10-10 10:10:11", "MYSQL", "TABLES_PRIV", "11", "<nil>", "<nil>", "1", "1", "11111", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:12", "MYSQL", "TABLES_PRIV", "11", "<nil>", "<nil>", "2", "2", "22222", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
// mysql table_id = 21, table_name = STATS_META
|
||||
{"2019-10-10 10:10:13", "MYSQL", "STATS_META", "21", "<nil>", "<nil>", "3", "3", "33333", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:14", "MYSQL", "STATS_META", "21", "<nil>", "<nil>", "4", "4", "44444", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
// table_id = 1313, deleted schema
|
||||
{"2019-10-10 10:10:15", "UNKNOWN", "UNKNOWN", "1313", "UNKNOWN", "<nil>", "5", "5", "55555", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:16", "UNKNOWN", "UNKNOWN", "1313", "UNKNOWN", "<nil>", "6", "6", "66666", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
// mysql table_id = 11, index_id = 1, table_name = TABLES_PRIV, index_name = PRIMARY
|
||||
{"2019-10-10 10:10:17", "MYSQL", "TABLES_PRIV", "11", "PRIMARY", "1", "1", "1", "11111", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:18", "MYSQL", "TABLES_PRIV", "11", "PRIMARY", "1", "2", "2", "22222", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
// mysql table_id = 21 ,index_id = 1, table_name = STATS_META, index_name = IDX_VER
|
||||
{"2019-10-10 10:10:19", "MYSQL", "STATS_META", "21", "IDX_VER", "1", "3", "3", "33333", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:20", "MYSQL", "STATS_META", "21", "IDX_VER", "1", "4", "4", "44444", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
// mysql table_id = 21 ,index_id = 2, table_name = STATS_META, index_name = TBL
|
||||
{"2019-10-10 10:10:21", "MYSQL", "STATS_META", "21", "TBL", "2", "5", "5", "55555", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:22", "MYSQL", "STATS_META", "21", "TBL", "2", "6", "6", "66666", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
// table_id = 1313, index_id = 1, deleted schema
|
||||
{"2019-10-10 10:10:23", "UNKNOWN", "UNKNOWN", "1313", "UNKNOWN", "1", "7", "7", "77777", "0", "1", "READ", "99", "99", "99", "99"},
|
||||
{"2019-10-10 10:10:24", "UNKNOWN", "UNKNOWN", "1313", "UNKNOWN", "1", "8", "8", "88888", "0", "0", "WRITE", "99", "99", "99", "99"},
|
||||
}
|
||||
|
||||
mockDB := &model.DBInfo{}
|
||||
pdResps := []map[string]*executor.HistoryHotRegions{
|
||||
{
|
||||
core.HotRegionTypeRead: {
|
||||
HistoryHotRegion: []*executor.HistoryHotRegion{
|
||||
// mysql table_id = 11, table_name = TABLES_PRIV
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:11"), RegionID: 1, StoreID: 1, PeerID: 11111, IsLearner: false,
|
||||
IsLeader: true, HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 11}).StartKey,
|
||||
EndKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 11}).EndKey,
|
||||
},
|
||||
// mysql table_id = 21, table_name = STATS_META
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:13"), RegionID: 3, StoreID: 3, PeerID: 33333, IsLearner: false,
|
||||
IsLeader: true, HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 21}).StartKey,
|
||||
EndKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 21}).EndKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
core.HotRegionTypeWrite: {
|
||||
HistoryHotRegion: []*executor.HistoryHotRegion{
|
||||
// mysql table_id = 11, table_name = TABLES_PRIV
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:12"), RegionID: 2, StoreID: 2, PeerID: 22222, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 11}).StartKey,
|
||||
EndKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 11}).EndKey,
|
||||
},
|
||||
// mysql table_id = 21, table_name = STATS_META
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:14"), RegionID: 4, StoreID: 4, PeerID: 44444, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 21}).StartKey,
|
||||
EndKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 21}).EndKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
core.HotRegionTypeRead: {
|
||||
HistoryHotRegion: []*executor.HistoryHotRegion{
|
||||
// table_id = 1313, deleted schema
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:15"), RegionID: 5, StoreID: 5, PeerID: 55555, IsLearner: false,
|
||||
IsLeader: true, HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 1313}).StartKey,
|
||||
EndKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 1313}).EndKey,
|
||||
},
|
||||
// mysql table_id = 11, index_id = 1, table_name = TABLES_PRIV, index_name = PRIMARY
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:17"), RegionID: 1, StoreID: 1, PeerID: 11111, IsLearner: false,
|
||||
IsLeader: true, HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 11}, &model.IndexInfo{ID: 1}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 11}, &model.IndexInfo{ID: 1}).EndKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
core.HotRegionTypeWrite: {
|
||||
HistoryHotRegion: []*executor.HistoryHotRegion{
|
||||
// table_id = 1313, deleted schema
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:16"), RegionID: 6, StoreID: 6, PeerID: 66666, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 1313}).StartKey,
|
||||
EndKey: helper.NewTableWithKeyRange(mockDB, &model.TableInfo{ID: 1313}).EndKey,
|
||||
},
|
||||
// mysql table_id = 11, index_id = 1, table_name = TABLES_PRIV, index_name = PRIMARY
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:18"), RegionID: 2, StoreID: 2, PeerID: 22222, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 11}, &model.IndexInfo{ID: 1}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 11}, &model.IndexInfo{ID: 1}).EndKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
core.HotRegionTypeRead: {
|
||||
HistoryHotRegion: []*executor.HistoryHotRegion{
|
||||
// mysql table_id = 21 ,index_id = 1, table_name = STATS_META, index_name = IDX_VER
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:19"), RegionID: 3, StoreID: 3, PeerID: 33333, IsLearner: false,
|
||||
IsLeader: true, HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 1}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 1}).EndKey,
|
||||
},
|
||||
// mysql table_id = 21 ,index_id = 2, table_name = STATS_META, index_name = TBL
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:21"), RegionID: 5, StoreID: 5, PeerID: 55555, IsLearner: false,
|
||||
IsLeader: true, HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 2}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 2}).EndKey,
|
||||
},
|
||||
// table_id = 1313, index_id = 1, deleted schema
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:23"), RegionID: 7, StoreID: 7, PeerID: 77777, IsLeader: true,
|
||||
HotRegionType: "READ", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 1313}, &model.IndexInfo{ID: 1}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 1313}, &model.IndexInfo{ID: 1}).EndKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
core.HotRegionTypeWrite: {
|
||||
HistoryHotRegion: []*executor.HistoryHotRegion{
|
||||
// mysql table_id = 21 ,index_id = 1, table_name = STATS_META, index_name = IDX_VER
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:20"), RegionID: 4, StoreID: 4, PeerID: 44444, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 1}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 1}).EndKey,
|
||||
},
|
||||
// mysql table_id = 21 ,index_id = 2, table_name = STATS_META, index_name = TBL
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:22"), RegionID: 6, StoreID: 6, PeerID: 66666, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 2}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 21}, &model.IndexInfo{ID: 2}).EndKey,
|
||||
},
|
||||
// table_id = 1313, index_id = 1, deleted schema
|
||||
{UpdateTime: unixTimeMs("2019-10-10 10:10:24"), RegionID: 8, StoreID: 8, PeerID: 88888, IsLearner: false,
|
||||
IsLeader: false, HotRegionType: "WRITE", HotDegree: 99, FlowBytes: 99, KeyRate: 99, QueryRate: 99,
|
||||
StartKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 1313}, &model.IndexInfo{ID: 1}).StartKey,
|
||||
EndKey: helper.NewIndexWithKeyRange(mockDB, &model.TableInfo{ID: 1313}, &model.IndexInfo{ID: 1}).EndKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var cases = []struct {
|
||||
conditions []string
|
||||
reqCount int32
|
||||
expected [][]string
|
||||
}{
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
}, // time filtered by PD, assume response suit time range, and ignore deleted schemas
|
||||
expected: [][]string{
|
||||
fullHotRegions[0], fullHotRegions[1], fullHotRegions[2],
|
||||
fullHotRegions[3],
|
||||
fullHotRegions[6], fullHotRegions[7], fullHotRegions[8],
|
||||
fullHotRegions[9], fullHotRegions[10], fullHotRegions[11],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>=TIMESTAMP('2019-10-10 10:10:10')",
|
||||
"update_time<=TIMESTAMP('2019-10-11 10:10:10')",
|
||||
}, // test support of timestamp
|
||||
expected: [][]string{
|
||||
fullHotRegions[0], fullHotRegions[1], fullHotRegions[2],
|
||||
fullHotRegions[3],
|
||||
fullHotRegions[6], fullHotRegions[7], fullHotRegions[8],
|
||||
fullHotRegions[9], fullHotRegions[10], fullHotRegions[11],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_id=11",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullHotRegions[0], fullHotRegions[1], fullHotRegions[6], fullHotRegions[7],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_name='TABLES_PRIV'",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullHotRegions[0], fullHotRegions[1], fullHotRegions[6], fullHotRegions[7],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_id=21",
|
||||
"index_id=1",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullHotRegions[8], fullHotRegions[9],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_id=21",
|
||||
"index_id=1",
|
||||
"table_name='TABLES_PRIV'",
|
||||
}, // table_id != table_name -> nil
|
||||
expected: [][]string{},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_id=21",
|
||||
"index_id=1",
|
||||
"table_name='STATS_META'",
|
||||
}, // table_id = table_name
|
||||
expected: [][]string{
|
||||
fullHotRegions[8], fullHotRegions[9],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_id=21",
|
||||
"index_id=1",
|
||||
"index_name='UNKNOWN'",
|
||||
}, // index_id != index_name -> nil
|
||||
expected: [][]string{},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"table_id=21",
|
||||
"index_id=1",
|
||||
"index_name='IDX_VER'",
|
||||
}, // index_id = index_name
|
||||
expected: [][]string{
|
||||
fullHotRegions[8], fullHotRegions[9],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"index_id=1",
|
||||
"index_name='IDX_VER'",
|
||||
"table_id>=21", // unpushed down predicates 21>=21
|
||||
},
|
||||
expected: [][]string{
|
||||
fullHotRegions[8], fullHotRegions[9],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"index_id=1",
|
||||
"index_name='IDX_VER'",
|
||||
"table_id>21", // unpushed down predicates
|
||||
}, // 21!>21 -> nil
|
||||
expected: [][]string{},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"index_id=1",
|
||||
"index_name='IDX_VER'",
|
||||
"table_id>=21", // unpushed down predicates
|
||||
"db_name='MYSQL'",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullHotRegions[8], fullHotRegions[9],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"index_id=1",
|
||||
"index_name='IDX_VER'",
|
||||
"table_id>=21", // unpushed down predicates
|
||||
"db_name='MYSQL'",
|
||||
"peer_id>=33334",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullHotRegions[9],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"update_time>='2019-10-10 10:10:10'",
|
||||
"update_time<='2019-10-11 10:10:10'",
|
||||
"index_id=1",
|
||||
"index_name='IDX_VER'",
|
||||
"table_id>=21", // unpushed down predicates
|
||||
"db_name='UNKNOWN'",
|
||||
},
|
||||
expected: [][]string{},
|
||||
},
|
||||
}
|
||||
|
||||
// mock http resp
|
||||
store := s.store.(*mockStoreWithMultiPD)
|
||||
for i, resp := range pdResps {
|
||||
for k, v := range resp {
|
||||
hotRegionsResponses[k+store.hosts[i]] = v
|
||||
}
|
||||
}
|
||||
tk := testkit.NewTestKit(c, s.store)
|
||||
for _, cas := range cases {
|
||||
sql := "select * from information_schema.tidb_hot_regions_history"
|
||||
if len(cas.conditions) > 0 {
|
||||
sql = fmt.Sprintf("%s where %s", sql, strings.Join(cas.conditions, " and "))
|
||||
}
|
||||
result := tk.MustQuery(sql)
|
||||
warnings := tk.Se.GetSessionVars().StmtCtx.GetWarnings()
|
||||
c.Assert(len(warnings), Equals, 0, Commentf("unexpected warnigns: %+v, sql: %s", warnings))
|
||||
var expected []string
|
||||
for _, row := range cas.expected {
|
||||
expectedRow := row
|
||||
expected = append(expected, strings.Join(expectedRow, " "))
|
||||
}
|
||||
result.Check(testkit.Rows(expected...))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *testHotRegionsHistoryTableSuite) TestTiDBHotRegionsHistoryError(c *C) {
|
||||
tk := testkit.NewTestKit(c, s.store)
|
||||
|
||||
// Test without start time error
|
||||
rs, err := tk.Exec("select * from information_schema.tidb_hot_regions_history")
|
||||
c.Assert(err, IsNil)
|
||||
_, err = session.ResultSetToStringSlice(context.Background(), tk.Se, rs)
|
||||
c.Assert(err, NotNil)
|
||||
c.Assert(err.Error(), Equals, "denied to scan hot regions, please specified the start time, such as `update_time > '2020-01-01 00:00:00'`")
|
||||
c.Assert(rs.Close(), IsNil)
|
||||
|
||||
// Test without end time error.
|
||||
rs, err = tk.Exec("select * from information_schema.tidb_hot_regions_history where update_time>='2019/08/26 06:18:13.011'")
|
||||
c.Assert(err, IsNil)
|
||||
_, err = session.ResultSetToStringSlice(context.Background(), tk.Se, rs)
|
||||
c.Assert(err, NotNil)
|
||||
c.Assert(err.Error(), Equals, "denied to scan hot regions, please specified the end time, such as `update_time < '2020-01-01 00:00:00'`")
|
||||
c.Assert(rs.Close(), IsNil)
|
||||
}
|
||||
|
||||
var regionsInfo = map[uint64]helper.RegionInfo{
|
||||
1: {
|
||||
ID: 1,
|
||||
Peers: []helper.RegionPeer{{ID: 11, StoreID: 1, IsLearner: false}, {ID: 12, StoreID: 2, IsLearner: false}, {ID: 13, StoreID: 3, IsLearner: false}},
|
||||
Leader: helper.RegionPeer{ID: 11, StoreID: 1, IsLearner: false},
|
||||
},
|
||||
2: {
|
||||
ID: 2,
|
||||
Peers: []helper.RegionPeer{{ID: 21, StoreID: 1, IsLearner: false}, {ID: 22, StoreID: 2, IsLearner: false}, {ID: 23, StoreID: 3, IsLearner: false}},
|
||||
Leader: helper.RegionPeer{ID: 22, StoreID: 2, IsLearner: false},
|
||||
},
|
||||
3: {
|
||||
ID: 3,
|
||||
Peers: []helper.RegionPeer{{ID: 31, StoreID: 1, IsLearner: false}, {ID: 32, StoreID: 2, IsLearner: false}, {ID: 33, StoreID: 3, IsLearner: false}},
|
||||
Leader: helper.RegionPeer{ID: 33, StoreID: 3, IsLearner: false},
|
||||
},
|
||||
}
|
||||
|
||||
var storeRegionsInfo = &helper.RegionsInfo{
|
||||
Count: 3,
|
||||
Regions: []helper.RegionInfo{
|
||||
regionsInfo[1],
|
||||
regionsInfo[2],
|
||||
regionsInfo[3],
|
||||
},
|
||||
}
|
||||
|
||||
var storesRegionsInfo = map[uint64]*helper.RegionsInfo{
|
||||
1: storeRegionsInfo,
|
||||
2: storeRegionsInfo,
|
||||
3: storeRegionsInfo,
|
||||
}
|
||||
|
||||
var _ = SerialSuites(&testTikvRegionPeersTableSuite{testInfoschemaTableSuiteBase: &testInfoschemaTableSuiteBase{}})
|
||||
|
||||
type testTikvRegionPeersTableSuite struct {
|
||||
*testInfoschemaTableSuiteBase
|
||||
httpServer *httptest.Server
|
||||
mockAddr string
|
||||
startTime time.Time
|
||||
}
|
||||
|
||||
func (s *testTikvRegionPeersTableSuite) SetUpSuite(c *C) {
|
||||
s.testInfoschemaTableSuiteBase.SetUpSuite(c)
|
||||
s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer()
|
||||
s.startTime = time.Now()
|
||||
}
|
||||
|
||||
func storesRegionsInfoHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusBadRequest, "unable to parse id", err)
|
||||
return
|
||||
}
|
||||
writeResp(w, storesRegionsInfo[uint64(id)])
|
||||
}
|
||||
|
||||
func regionsInfoHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusBadRequest, "unable to parse id", err)
|
||||
return
|
||||
}
|
||||
writeResp(w, regionsInfo[uint64(id)])
|
||||
}
|
||||
func (s *testTikvRegionPeersTableSuite) TearDownSuite(c *C) {
|
||||
s.httpServer.Close()
|
||||
s.testInfoschemaTableSuiteBase.TearDownSuite(c)
|
||||
}
|
||||
|
||||
func (s *testTikvRegionPeersTableSuite) setUpMockPDHTTPServer() (*httptest.Server, string) {
|
||||
// mock PD http server
|
||||
router := mux.NewRouter()
|
||||
server := httptest.NewServer(router)
|
||||
// mock store stats stat
|
||||
mockAddr := strings.TrimPrefix(server.URL, "http://")
|
||||
// mock PD API
|
||||
router.Handle(pdapi.Status, fn.Wrap(func() (interface{}, error) {
|
||||
return struct {
|
||||
Version string `json:"version"`
|
||||
GitHash string `json:"git_hash"`
|
||||
StartTimestamp int64 `json:"start_timestamp"`
|
||||
}{
|
||||
Version: "4.0.0-alpha",
|
||||
GitHash: "mock-pd-githash",
|
||||
StartTimestamp: s.startTime.Unix(),
|
||||
}, nil
|
||||
}))
|
||||
// mock get regionsInfo by store id
|
||||
router.HandleFunc(pdapi.StoreRegions+"/"+"{id}", storesRegionsInfoHandler)
|
||||
// mock get regionInfo by region id
|
||||
router.HandleFunc(pdapi.RegionByID+"/"+"{id}", regionsInfoHandler)
|
||||
return server, mockAddr
|
||||
}
|
||||
|
||||
func (s *testTikvRegionPeersTableSuite) TestTikvRegionPeers(c *C) {
|
||||
mockAddr := s.mockAddr
|
||||
store := &mockStore{
|
||||
s.store.(helper.Storage),
|
||||
mockAddr,
|
||||
}
|
||||
|
||||
fullRegionPeers := [][]string{
|
||||
{"1", "11", "1", "0", "1", "NORMAL", "<nil>"},
|
||||
{"1", "12", "2", "0", "0", "NORMAL", "<nil>"},
|
||||
{"1", "13", "3", "0", "0", "NORMAL", "<nil>"},
|
||||
|
||||
{"2", "21", "1", "0", "0", "NORMAL", "<nil>"},
|
||||
{"2", "22", "2", "0", "1", "NORMAL", "<nil>"},
|
||||
{"2", "23", "3", "0", "0", "NORMAL", "<nil>"},
|
||||
|
||||
{"3", "31", "1", "0", "0", "NORMAL", "<nil>"},
|
||||
{"3", "32", "2", "0", "0", "NORMAL", "<nil>"},
|
||||
{"3", "33", "3", "0", "1", "NORMAL", "<nil>"},
|
||||
}
|
||||
|
||||
var cases = []struct {
|
||||
conditions []string
|
||||
reqCount int32
|
||||
expected [][]string
|
||||
}{
|
||||
{
|
||||
conditions: []string{
|
||||
"store_id in (1,2,3)",
|
||||
"region_id in (1,2,3)",
|
||||
},
|
||||
expected: fullRegionPeers,
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"store_id in (1,2)",
|
||||
"region_id=1",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullRegionPeers[0], fullRegionPeers[1],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"store_id in (1,2)",
|
||||
"region_id=1",
|
||||
"is_leader=1",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullRegionPeers[0],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"store_id in (1,2)",
|
||||
"region_id=1",
|
||||
"is_leader=0",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullRegionPeers[1],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"store_id =1",
|
||||
"region_id =1",
|
||||
"is_leader =0",
|
||||
},
|
||||
expected: [][]string{},
|
||||
},
|
||||
}
|
||||
|
||||
tk := testkit.NewTestKit(c, store)
|
||||
for _, cas := range cases {
|
||||
sql := "select * from information_schema.tikv_region_peers"
|
||||
if len(cas.conditions) > 0 {
|
||||
sql = fmt.Sprintf("%s where %s", sql, strings.Join(cas.conditions, " and "))
|
||||
}
|
||||
result := tk.MustQuery(sql)
|
||||
warnings := tk.Se.GetSessionVars().StmtCtx.GetWarnings()
|
||||
c.Assert(len(warnings), Equals, 0, Commentf("unexpected warnigns: %+v", warnings))
|
||||
var expected []string
|
||||
for _, row := range cas.expected {
|
||||
expectedRow := row
|
||||
expected = append(expected, strings.Join(expectedRow, " "))
|
||||
}
|
||||
result.Check(testkit.Rows(expected...))
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,6 @@ import (
|
||||
"github.com/pingcap/tidb/sessionctx/variable"
|
||||
"github.com/pingcap/tidb/testkit"
|
||||
"github.com/pingcap/tidb/testkit/testdata"
|
||||
"github.com/pingcap/tidb/util/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@ -1113,28 +1112,28 @@ func TestPartitionTableWithDifferentJoin(t *testing.T) {
|
||||
// require.True(t,tk.HasPlan(queryHash, "IndexMergeJoin"))
|
||||
// tk.MustQuery(queryHash).Sort().Check(tk.MustQuery(queryRegular).Sort().Rows())
|
||||
tk.MustQuery(queryHash)
|
||||
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1815|Optimizer Hint /*+ INL_MERGE_JOIN(trange, trange2) */ is inapplicable"))
|
||||
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1815|Optimizer Hint /*+ INL_MERGE_JOIN(trange, trange2) */ is inapplicable"))
|
||||
|
||||
queryHash = fmt.Sprintf("select /*+ inl_merge_join(trange, trange2) */ * from trange, trange2 where trange.a=trange2.a and trange.a > %v and trange2.a > %v;", x1, x2)
|
||||
// queryRegular = fmt.Sprintf("select /*+ inl_merge_join(tregular2, tregular4) */ * from tregular2, tregular4 where tregular2.a=tregular4.a and tregular2.a > %v and tregular4.a > %v;", x1, x2)
|
||||
// require.True(t,tk.HasPlan(queryHash, "IndexMergeJoin"))
|
||||
// tk.MustQuery(queryHash).Sort().Check(tk.MustQuery(queryRegular).Sort().Rows())
|
||||
tk.MustQuery(queryHash)
|
||||
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1815|Optimizer Hint /*+ INL_MERGE_JOIN(trange, trange2) */ is inapplicable"))
|
||||
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1815|Optimizer Hint /*+ INL_MERGE_JOIN(trange, trange2) */ is inapplicable"))
|
||||
|
||||
queryHash = fmt.Sprintf("select /*+ inl_merge_join(trange, trange2) */ * from trange, trange2 where trange.a=trange2.a and trange.a > %v and trange.b > %v;", x1, x2)
|
||||
// queryRegular = fmt.Sprintf("select /*+ inl_merge_join(tregular2, tregular4) */ * from tregular2, tregular4 where tregular2.a=tregular4.a and tregular2.a > %v and tregular2.b > %v;", x1, x2)
|
||||
// require.True(t,tk.HasPlan(queryHash, "IndexMergeJoin"))
|
||||
// tk.MustQuery(queryHash).Sort().Check(tk.MustQuery(queryRegular).Sort().Rows())
|
||||
tk.MustQuery(queryHash)
|
||||
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1815|Optimizer Hint /*+ INL_MERGE_JOIN(trange, trange2) */ is inapplicable"))
|
||||
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1815|Optimizer Hint /*+ INL_MERGE_JOIN(trange, trange2) */ is inapplicable"))
|
||||
|
||||
queryHash = fmt.Sprintf("select /*+ inl_merge_join(trange, trange2) */ * from trange, trange2 where trange.a=trange2.a and trange.a > %v and trange2.b > %v;", x1, x2)
|
||||
// queryRegular = fmt.Sprintf("select /*+ inl_merge_join(tregular2, tregular4) */ * from tregular2, tregular4 where tregular2.a=tregular4.a and tregular2.a > %v and tregular4.b > %v;", x1, x2)
|
||||
// require.True(t,tk.HasPlan(queryHash, "IndexMergeJoin"))
|
||||
// tk.MustQuery(queryHash).Sort().Check(tk.MustQuery(queryRegular).Sort().Rows())
|
||||
tk.MustQuery(queryHash)
|
||||
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1815|Optimizer Hint /*+ INL_MERGE_JOIN(trange, trange2) */ is inapplicable"))
|
||||
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1815|Optimizer Hint /*+ INL_MERGE_JOIN(trange, trange2) */ is inapplicable"))
|
||||
|
||||
// group 6
|
||||
// index_merge_join range partition and regualr table
|
||||
|
||||
@ -50,8 +50,8 @@ import (
|
||||
"github.com/pingcap/tidb/store/mockstore"
|
||||
"github.com/pingcap/tidb/tablecodec"
|
||||
"github.com/pingcap/tidb/testkit"
|
||||
"github.com/pingcap/tidb/testkit/testutil"
|
||||
"github.com/pingcap/tidb/util/gcutil"
|
||||
"github.com/pingcap/tidb/util/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tikv/client-go/v2/testutils"
|
||||
"github.com/tikv/client-go/v2/tikv"
|
||||
@ -271,7 +271,7 @@ func TestShow(t *testing.T) {
|
||||
tk.MustExec(`create index idx9 on show_index (id) invisible;`)
|
||||
tk.MustExec(`create index expr_idx on show_index ((id*2+1))`)
|
||||
testSQL = "SHOW index from show_index;"
|
||||
tk.MustQuery(testSQL).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(testSQL).Check(testkit.RowsWithSep("|",
|
||||
"show_index|0|PRIMARY|1|id|A|0|<nil>|<nil>||BTREE| |YES|<nil>|YES",
|
||||
"show_index|1|cIdx|1|c|A|0|<nil>|<nil>|YES|HASH||index_comment_for_cIdx|YES|<nil>|NO",
|
||||
"show_index|1|idx1|1|id|A|0|<nil>|<nil>||HASH| |YES|<nil>|NO",
|
||||
@ -324,11 +324,11 @@ func TestShow(t *testing.T) {
|
||||
testSQL = `create database show_test_DB`
|
||||
tk.MustExec(testSQL)
|
||||
testSQL = "show create database show_test_DB;"
|
||||
tk.MustQuery(testSQL).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(testSQL).Check(testkit.RowsWithSep("|",
|
||||
"show_test_DB|CREATE DATABASE `show_test_DB` /*!40100 DEFAULT CHARACTER SET utf8mb4 */",
|
||||
))
|
||||
testSQL = "show create database if not exists show_test_DB;"
|
||||
tk.MustQuery(testSQL).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(testSQL).Check(testkit.RowsWithSep("|",
|
||||
"show_test_DB|CREATE DATABASE /*!32312 IF NOT EXISTS*/ `show_test_DB` /*!40100 DEFAULT CHARACTER SET utf8mb4 */",
|
||||
))
|
||||
|
||||
@ -340,7 +340,7 @@ func TestShow(t *testing.T) {
|
||||
// for issue https://github.com/pingcap/tidb/issues/4224
|
||||
tk.MustExec(`drop table if exists show_test_comment`)
|
||||
tk.MustExec(`create table show_test_comment (id int not null default 0 comment "show_test_comment_id")`)
|
||||
tk.MustQuery(`show full columns from show_test_comment`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show full columns from show_test_comment`).Check(testkit.RowsWithSep("|",
|
||||
"id|int(11)|<nil>|NO||0||select,insert,update,references|show_test_comment_id",
|
||||
))
|
||||
|
||||
@ -348,7 +348,7 @@ func TestShow(t *testing.T) {
|
||||
// for issue https://github.com/pingcap/tidb/issues/3747
|
||||
tk.MustExec(`drop table if exists show_auto_increment`)
|
||||
tk.MustExec(`create table show_auto_increment (id int key auto_increment) auto_increment=4`)
|
||||
tk.MustQuery(`show create table show_auto_increment`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table show_auto_increment`).Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"show_auto_increment CREATE TABLE `show_auto_increment` (\n"+
|
||||
" `id` int(11) NOT NULL AUTO_INCREMENT,\n"+
|
||||
@ -359,7 +359,7 @@ func TestShow(t *testing.T) {
|
||||
autoIDStep := autoid.GetStep()
|
||||
tk.MustExec("insert into show_auto_increment values(20)")
|
||||
autoID := autoIDStep + 21
|
||||
tk.MustQuery(`show create table show_auto_increment`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table show_auto_increment`).Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"show_auto_increment CREATE TABLE `show_auto_increment` (\n"+
|
||||
" `id` int(11) NOT NULL AUTO_INCREMENT,\n"+
|
||||
@ -368,7 +368,7 @@ func TestShow(t *testing.T) {
|
||||
))
|
||||
tk.MustExec(`drop table show_auto_increment`)
|
||||
tk.MustExec(`create table show_auto_increment (id int primary key auto_increment)`)
|
||||
tk.MustQuery(`show create table show_auto_increment`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table show_auto_increment`).Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"show_auto_increment CREATE TABLE `show_auto_increment` (\n"+
|
||||
" `id` int(11) NOT NULL AUTO_INCREMENT,\n"+
|
||||
@ -377,7 +377,7 @@ func TestShow(t *testing.T) {
|
||||
))
|
||||
tk.MustExec("insert into show_auto_increment values(10)")
|
||||
autoID = autoIDStep + 11
|
||||
tk.MustQuery(`show create table show_auto_increment`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table show_auto_increment`).Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"show_auto_increment CREATE TABLE `show_auto_increment` (\n"+
|
||||
" `id` int(11) NOT NULL AUTO_INCREMENT,\n"+
|
||||
@ -389,7 +389,7 @@ func TestShow(t *testing.T) {
|
||||
// for issue https://github.com/pingcap/tidb/issues/4411
|
||||
tk.MustExec(`drop table if exists show_escape_character`)
|
||||
tk.MustExec(`create table show_escape_character(id int comment 'a\rb\nc\td\0ef')`)
|
||||
tk.MustQuery(`show create table show_escape_character`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table show_escape_character`).Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"show_escape_character CREATE TABLE `show_escape_character` (\n"+
|
||||
" `id` int(11) DEFAULT NULL COMMENT 'a\\rb\\nc d\\0ef'\n"+
|
||||
@ -479,7 +479,7 @@ func TestShow(t *testing.T) {
|
||||
// Test get default collate for a specified charset.
|
||||
tk.MustExec(`drop table if exists t`)
|
||||
tk.MustExec(`create table t (a int) default charset=utf8mb4`)
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|",
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL\n"+
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin",
|
||||
@ -491,7 +491,7 @@ func TestShow(t *testing.T) {
|
||||
PARTITION p0 VALUES LESS THAN (10),
|
||||
PARTITION p1 VALUES LESS THAN (20),
|
||||
PARTITION p2 VALUES LESS THAN (MAXVALUE))`)
|
||||
tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table t").Check(testkit.RowsWithSep("|",
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL\n"+
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"+"\nPARTITION BY RANGE (`a`)\n(PARTITION `p0` VALUES LESS THAN (10),\n PARTITION `p1` VALUES LESS THAN (20),\n PARTITION `p2` VALUES LESS THAN (MAXVALUE))",
|
||||
@ -511,7 +511,7 @@ func TestShow(t *testing.T) {
|
||||
PARTITION p1 VALUES LESS THAN (10,20,'mmm'),
|
||||
PARTITION p2 VALUES LESS THAN (15,30,'sss'),
|
||||
PARTITION p3 VALUES LESS THAN (50,MAXVALUE,MAXVALUE))`)
|
||||
tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table t").Check(testkit.RowsWithSep("|",
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL,\n"+
|
||||
" `b` int(11) DEFAULT NULL,\n"+
|
||||
@ -523,7 +523,7 @@ func TestShow(t *testing.T) {
|
||||
// Test hash partition
|
||||
tk.MustExec(`drop table if exists t`)
|
||||
tk.MustExec(`CREATE TABLE t (a int) PARTITION BY HASH(a) PARTITIONS 4`)
|
||||
tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table t").Check(testkit.RowsWithSep("|",
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL\n"+
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\n"+
|
||||
@ -532,7 +532,7 @@ func TestShow(t *testing.T) {
|
||||
// Test show create table compression type.
|
||||
tk.MustExec(`drop table if exists t1`)
|
||||
tk.MustExec(`CREATE TABLE t1 (c1 INT) COMPRESSION="zlib";`)
|
||||
tk.MustQuery("show create table t1").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table t1").Check(testkit.RowsWithSep("|",
|
||||
"t1 CREATE TABLE `t1` (\n"+
|
||||
" `c1` int(11) DEFAULT NULL\n"+
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMPRESSION='zlib'",
|
||||
@ -541,7 +541,7 @@ func TestShow(t *testing.T) {
|
||||
// Test show create table year type
|
||||
tk.MustExec(`drop table if exists t`)
|
||||
tk.MustExec(`create table t(y year unsigned signed zerofill zerofill, x int, primary key(y));`)
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|",
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `y` year(4) NOT NULL,\n"+
|
||||
" `x` int(11) DEFAULT NULL,\n"+
|
||||
@ -551,7 +551,7 @@ func TestShow(t *testing.T) {
|
||||
// Test show create table with zerofill flag
|
||||
tk.MustExec(`drop table if exists t`)
|
||||
tk.MustExec(`create table t(id int primary key, val tinyint(10) zerofill);`)
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|",
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `id` int(11) NOT NULL,\n"+
|
||||
" `val` tinyint(10) unsigned zerofill DEFAULT NULL,\n"+
|
||||
@ -573,7 +573,7 @@ func TestShow(t *testing.T) {
|
||||
c9 year default '2014',
|
||||
c10 enum('2', '3', '4') default 2
|
||||
);`)
|
||||
tk.MustQuery(`show columns from t`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show columns from t`).Check(testkit.RowsWithSep("|",
|
||||
"c0|int(11)|YES||1|",
|
||||
"c1|int(11)|YES||2|",
|
||||
"c2|bigint(20)|YES||167|",
|
||||
|
||||
@ -33,7 +33,6 @@ import (
|
||||
"github.com/pingcap/tidb/sessionctx/variable"
|
||||
"github.com/pingcap/tidb/testkit"
|
||||
"github.com/pingcap/tidb/types"
|
||||
"github.com/pingcap/tidb/util/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@ -105,9 +104,9 @@ func TestShowWarnings(t *testing.T) {
|
||||
tk.MustExec("set @@sql_mode=''")
|
||||
tk.MustExec("insert show_warnings values ('a')")
|
||||
require.Equal(t, uint16(1), tk.Session().GetSessionVars().StmtCtx.WarningCount())
|
||||
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DOUBLE value: 'a'"))
|
||||
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect DOUBLE value: 'a'"))
|
||||
require.Equal(t, uint16(0), tk.Session().GetSessionVars().StmtCtx.WarningCount())
|
||||
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DOUBLE value: 'a'"))
|
||||
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1292|Truncated incorrect DOUBLE value: 'a'"))
|
||||
require.Equal(t, uint16(0), tk.Session().GetSessionVars().StmtCtx.WarningCount())
|
||||
|
||||
// Test Warning level 'Error'
|
||||
@ -115,8 +114,8 @@ func TestShowWarnings(t *testing.T) {
|
||||
_, _ = tk.Exec(testSQL)
|
||||
// FIXME: Table 'test.show_warnings' already exists
|
||||
require.Equal(t, uint16(1), tk.Session().GetSessionVars().StmtCtx.WarningCount())
|
||||
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Error|1050|Table 'test.show_warnings' already exists"))
|
||||
tk.MustQuery("select @@error_count").Check(testutil.RowsWithSep("|", "1"))
|
||||
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Error|1050|Table 'test.show_warnings' already exists"))
|
||||
tk.MustQuery("select @@error_count").Check(testkit.RowsWithSep("|", "1"))
|
||||
|
||||
// Test Warning level 'Note'
|
||||
testSQL = `create table show_warnings_2 (a int)`
|
||||
@ -125,9 +124,9 @@ func TestShowWarnings(t *testing.T) {
|
||||
_, err := tk.Exec(testSQL)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, uint16(1), tk.Session().GetSessionVars().StmtCtx.WarningCount())
|
||||
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Note|1050|Table 'test.show_warnings_2' already exists"))
|
||||
tk.MustQuery("select @@warning_count").Check(testutil.RowsWithSep("|", "1"))
|
||||
tk.MustQuery("select @@warning_count").Check(testutil.RowsWithSep("|", "0"))
|
||||
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Note|1050|Table 'test.show_warnings_2' already exists"))
|
||||
tk.MustQuery("select @@warning_count").Check(testkit.RowsWithSep("|", "1"))
|
||||
tk.MustQuery("select @@warning_count").Check(testkit.RowsWithSep("|", "0"))
|
||||
}
|
||||
|
||||
func TestShowErrors(t *testing.T) {
|
||||
@ -141,7 +140,7 @@ func TestShowErrors(t *testing.T) {
|
||||
// FIXME: 'test.show_errors' already exists
|
||||
_, _ = tk.Exec(testSQL)
|
||||
|
||||
tk.MustQuery("show errors").Check(testutil.RowsWithSep("|", "Error|1050|Table 'test.show_errors' already exists"))
|
||||
tk.MustQuery("show errors").Check(testkit.RowsWithSep("|", "Error|1050|Table 'test.show_errors' already exists"))
|
||||
}
|
||||
|
||||
func TestShowWarningsForExprPushdown(t *testing.T) {
|
||||
@ -169,17 +168,17 @@ func TestShowWarningsForExprPushdown(t *testing.T) {
|
||||
tk.MustExec("set tidb_allow_mpp=0")
|
||||
tk.MustExec("explain select * from show_warnings_expr_pushdown t where md5(value) = '2020-01-01'")
|
||||
require.Equal(t, uint16(1), tk.Session().GetSessionVars().StmtCtx.WarningCount())
|
||||
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1105|Scalar function 'md5'(signature: MD5, return type: var_string(32)) is not supported to push down to tiflash now."))
|
||||
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1105|Scalar function 'md5'(signature: MD5, return type: var_string(32)) is not supported to push down to tiflash now."))
|
||||
tk.MustExec("explain select max(md5(value)) from show_warnings_expr_pushdown group by a")
|
||||
require.Equal(t, uint16(2), tk.Session().GetSessionVars().StmtCtx.WarningCount())
|
||||
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1105|Scalar function 'md5'(signature: MD5, return type: var_string(32)) is not supported to push down to tiflash now.", "Warning|1105|Aggregation can not be pushed to tiflash because arguments of AggFunc `max` contains unsupported exprs"))
|
||||
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1105|Scalar function 'md5'(signature: MD5, return type: var_string(32)) is not supported to push down to tiflash now.", "Warning|1105|Aggregation can not be pushed to tiflash because arguments of AggFunc `max` contains unsupported exprs"))
|
||||
tk.MustExec("explain select max(a) from show_warnings_expr_pushdown group by md5(value)")
|
||||
require.Equal(t, uint16(2), tk.Session().GetSessionVars().StmtCtx.WarningCount())
|
||||
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1105|Scalar function 'md5'(signature: MD5, return type: var_string(32)) is not supported to push down to tiflash now.", "Warning|1105|Aggregation can not be pushed to tiflash because groupByItems contain unsupported exprs"))
|
||||
tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1105|Scalar function 'md5'(signature: MD5, return type: var_string(32)) is not supported to push down to tiflash now.", "Warning|1105|Aggregation can not be pushed to tiflash because groupByItems contain unsupported exprs"))
|
||||
tk.MustExec("set tidb_opt_distinct_agg_push_down=0")
|
||||
tk.MustExec("explain select max(distinct a) from show_warnings_expr_pushdown group by value")
|
||||
require.Equal(t, uint16(0), tk.Session().GetSessionVars().StmtCtx.WarningCount())
|
||||
// tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1105|Aggregation can not be pushed to storage layer in non-mpp mode because it contains agg function with distinct"))
|
||||
// tk.MustQuery("show warnings").Check(testkit.RowsWithSep("|", "Warning|1105|Aggregation can not be pushed to storage layer in non-mpp mode because it contains agg function with distinct"))
|
||||
}
|
||||
|
||||
func TestShowGrantsPrivilege(t *testing.T) {
|
||||
@ -388,11 +387,11 @@ func TestShow2(t *testing.T) {
|
||||
tk.MustExec("drop table if exists t")
|
||||
tk.MustExec(`create table if not exists t (c int) comment '注释'`)
|
||||
tk.MustExec("create or replace definer='root'@'localhost' view v as select * from t")
|
||||
tk.MustQuery(`show columns from t`).Check(testutil.RowsWithSep(",", "c,int(11),YES,,<nil>,"))
|
||||
tk.MustQuery(`describe t`).Check(testutil.RowsWithSep(",", "c,int(11),YES,,<nil>,"))
|
||||
tk.MustQuery(`show columns from v`).Check(testutil.RowsWithSep(",", "c,int(11),YES,,<nil>,"))
|
||||
tk.MustQuery(`describe v`).Check(testutil.RowsWithSep(",", "c,int(11),YES,,<nil>,"))
|
||||
tk.MustQuery("show collation where Charset = 'utf8' and Collation = 'utf8_bin'").Check(testutil.RowsWithSep(",", "utf8_bin,utf8,83,Yes,Yes,1"))
|
||||
tk.MustQuery(`show columns from t`).Check(testkit.RowsWithSep(",", "c,int(11),YES,,<nil>,"))
|
||||
tk.MustQuery(`describe t`).Check(testkit.RowsWithSep(",", "c,int(11),YES,,<nil>,"))
|
||||
tk.MustQuery(`show columns from v`).Check(testkit.RowsWithSep(",", "c,int(11),YES,,<nil>,"))
|
||||
tk.MustQuery(`describe v`).Check(testkit.RowsWithSep(",", "c,int(11),YES,,<nil>,"))
|
||||
tk.MustQuery("show collation where Charset = 'utf8' and Collation = 'utf8_bin'").Check(testkit.RowsWithSep(",", "utf8_bin,utf8,83,Yes,Yes,1"))
|
||||
tk.MustExec(`drop sequence if exists seq`)
|
||||
tk.MustExec(`create sequence seq`)
|
||||
tk.MustQuery("show tables").Check(testkit.Rows("seq", "t", "v"))
|
||||
@ -627,7 +626,7 @@ func TestShowCreateViewDefiner(t *testing.T) {
|
||||
|
||||
tk.MustExec("use test")
|
||||
tk.MustExec("create or replace view v1 as select 1")
|
||||
tk.MustQuery("show create view v1").Check(testutil.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `v1` (`1`) AS SELECT 1 AS `1`|utf8mb4|utf8mb4_bin"))
|
||||
tk.MustQuery("show create view v1").Check(testkit.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `v1` (`1`) AS SELECT 1 AS `1`|utf8mb4|utf8mb4_bin"))
|
||||
tk.MustExec("drop view v1")
|
||||
}
|
||||
|
||||
@ -641,29 +640,29 @@ func TestShowCreateTable(t *testing.T) {
|
||||
tk.MustExec("create table t1(a int,b int)")
|
||||
tk.MustExec("drop view if exists v1")
|
||||
tk.MustExec("create or replace definer=`root`@`127.0.0.1` view v1 as select * from t1")
|
||||
tk.MustQuery("show create table v1").Check(testutil.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` (`a`, `b`) AS SELECT `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` FROM `test`.`t1`|utf8mb4|utf8mb4_bin"))
|
||||
tk.MustQuery("show create view v1").Check(testutil.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` (`a`, `b`) AS SELECT `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` FROM `test`.`t1`|utf8mb4|utf8mb4_bin"))
|
||||
tk.MustQuery("show create table v1").Check(testkit.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` (`a`, `b`) AS SELECT `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` FROM `test`.`t1`|utf8mb4|utf8mb4_bin"))
|
||||
tk.MustQuery("show create view v1").Check(testkit.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` (`a`, `b`) AS SELECT `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` FROM `test`.`t1`|utf8mb4|utf8mb4_bin"))
|
||||
tk.MustExec("drop view v1")
|
||||
tk.MustExec("drop table t1")
|
||||
|
||||
tk.MustExec("drop view if exists v")
|
||||
tk.MustExec("create or replace definer=`root`@`127.0.0.1` view v as select JSON_MERGE('{}', '{}') as col;")
|
||||
tk.MustQuery("show create view v").Check(testutil.RowsWithSep("|", "v|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v` (`col`) AS SELECT JSON_MERGE(_UTF8MB4'{}', _UTF8MB4'{}') AS `col`|utf8mb4|utf8mb4_bin"))
|
||||
tk.MustQuery("show create view v").Check(testkit.RowsWithSep("|", "v|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v` (`col`) AS SELECT JSON_MERGE(_UTF8MB4'{}', _UTF8MB4'{}') AS `col`|utf8mb4|utf8mb4_bin"))
|
||||
tk.MustExec("drop view if exists v")
|
||||
|
||||
tk.MustExec("drop table if exists t1")
|
||||
tk.MustExec("create table t1(a int,b int)")
|
||||
tk.MustExec("create or replace definer=`root`@`127.0.0.1` view v1 as select avg(a),t1.* from t1 group by a")
|
||||
tk.MustQuery("show create view v1").Check(testutil.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` (`avg(a)`, `a`, `b`) AS SELECT AVG(`a`) AS `avg(a)`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` FROM `test`.`t1` GROUP BY `a`|utf8mb4|utf8mb4_bin"))
|
||||
tk.MustQuery("show create view v1").Check(testkit.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` (`avg(a)`, `a`, `b`) AS SELECT AVG(`a`) AS `avg(a)`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` FROM `test`.`t1` GROUP BY `a`|utf8mb4|utf8mb4_bin"))
|
||||
tk.MustExec("drop view v1")
|
||||
tk.MustExec("create or replace definer=`root`@`127.0.0.1` view v1 as select a+b, t1.* , a as c from t1")
|
||||
tk.MustQuery("show create view v1").Check(testutil.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` (`a+b`, `a`, `b`, `c`) AS SELECT `a`+`b` AS `a+b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`a` AS `c` FROM `test`.`t1`|utf8mb4|utf8mb4_bin"))
|
||||
tk.MustQuery("show create view v1").Check(testkit.RowsWithSep("|", "v1|CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `v1` (`a+b`, `a`, `b`, `c`) AS SELECT `a`+`b` AS `a+b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`a` AS `c` FROM `test`.`t1`|utf8mb4|utf8mb4_bin"))
|
||||
tk.MustExec("drop table t1")
|
||||
tk.MustExec("drop view v1")
|
||||
|
||||
// For issue #9211
|
||||
tk.MustExec("create table t(c int, b int as (c + 1))ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
|
||||
tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `t`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `c` int(11) DEFAULT NULL,\n"+
|
||||
@ -673,7 +672,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
|
||||
tk.MustExec("drop table t")
|
||||
tk.MustExec("create table t(c int, b int as (c + 1) not null)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;")
|
||||
tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `t`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `c` int(11) DEFAULT NULL,\n"+
|
||||
@ -682,7 +681,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
))
|
||||
tk.MustExec("drop table t")
|
||||
tk.MustExec("create table t ( a char(10) charset utf8 collate utf8_bin, b char(10) as (rtrim(a)));")
|
||||
tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `t`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` char(10) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,\n"+
|
||||
@ -693,7 +692,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
|
||||
tk.MustExec(`drop table if exists different_charset`)
|
||||
tk.MustExec(`create table different_charset(ch1 varchar(10) charset utf8, ch2 varchar(10) charset binary);`)
|
||||
tk.MustQuery(`show create table different_charset`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table different_charset`).Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"different_charset CREATE TABLE `different_charset` (\n"+
|
||||
" `ch1` varchar(10) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,\n"+
|
||||
@ -710,7 +709,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
"`e` varchar(20) default 'cUrrent_tImestamp',\n" +
|
||||
"`f` datetime(2) default current_timestamp(2) on update current_timestamp(2),\n" +
|
||||
"`g` timestamp(2) default current_timestamp(2) on update current_timestamp(2))")
|
||||
tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `t`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n"+
|
||||
@ -725,7 +724,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
tk.MustExec("drop table t")
|
||||
|
||||
tk.MustExec("create table t (a int, b int) shard_row_id_bits = 4 pre_split_regions=3;")
|
||||
tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `t`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL,\n"+
|
||||
@ -737,7 +736,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
// for issue #20446
|
||||
tk.MustExec("drop table if exists t1;")
|
||||
tk.MustExec("create table t1(c int unsigned default 0);")
|
||||
tk.MustQuery("show create table `t1`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `t1`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t1 CREATE TABLE `t1` (\n"+
|
||||
" `c` int(10) unsigned DEFAULT '0'\n"+
|
||||
@ -771,7 +770,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
"PARTITION `p10` VALUES LESS THAN (11)," +
|
||||
"PARTITION `p11` VALUES LESS THAN (12)," +
|
||||
"PARTITION `p12` VALUES LESS THAN (MAXVALUE))")
|
||||
tk.MustQuery("show create table log").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table log").Check(testkit.RowsWithSep("|",
|
||||
"log CREATE TABLE `log` (\n"+
|
||||
" `LOG_ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,\n"+
|
||||
" `ROUND_ID` bigint(20) unsigned NOT NULL,\n"+
|
||||
@ -801,14 +800,14 @@ func TestShowCreateTable(t *testing.T) {
|
||||
|
||||
// for issue #11831
|
||||
tk.MustExec("create table ttt4(a varchar(123) default null collate utf8mb4_unicode_ci)engine=innodb default charset=utf8mb4 collate=utf8mb4_unicode_ci;")
|
||||
tk.MustQuery("show create table `ttt4`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `ttt4`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"ttt4 CREATE TABLE `ttt4` (\n"+
|
||||
" `a` varchar(123) COLLATE utf8mb4_unicode_ci DEFAULT NULL\n"+
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
|
||||
))
|
||||
tk.MustExec("create table ttt5(a varchar(123) default null)engine=innodb default charset=utf8mb4 collate=utf8mb4_bin;")
|
||||
tk.MustQuery("show create table `ttt5`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `ttt5`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"ttt5 CREATE TABLE `ttt5` (\n"+
|
||||
" `a` varchar(123) DEFAULT NULL\n"+
|
||||
@ -819,7 +818,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
tk.MustExec("drop table if exists t;")
|
||||
tk.MustExec("create table t(a int, b real);")
|
||||
tk.MustExec("alter table t add index expr_idx((a*b+1));")
|
||||
tk.MustQuery("show create table t;").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table t;").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL,\n"+
|
||||
@ -836,7 +835,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
// Test for issue #15633, 'binary' collation should be ignored in the result of 'show create table'.
|
||||
tk.MustExec(`drop table if exists binary_collate`)
|
||||
tk.MustExec(`create table binary_collate(a varchar(10)) default collate=binary;`)
|
||||
tk.MustQuery(`show create table binary_collate`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table binary_collate`).Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"binary_collate CREATE TABLE `binary_collate` (\n"+
|
||||
" `a` varbinary(10) DEFAULT NULL\n"+
|
||||
@ -844,7 +843,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
))
|
||||
tk.MustExec(`drop table if exists binary_collate`)
|
||||
tk.MustExec(`create table binary_collate(a varchar(10)) default charset=binary collate=binary;`)
|
||||
tk.MustQuery(`show create table binary_collate`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table binary_collate`).Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"binary_collate CREATE TABLE `binary_collate` (\n"+
|
||||
" `a` varbinary(10) DEFAULT NULL\n"+
|
||||
@ -852,7 +851,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
))
|
||||
tk.MustExec(`drop table if exists binary_collate`)
|
||||
tk.MustExec(`create table binary_collate(a varchar(10)) default charset=utf8mb4 collate=utf8mb4_bin;`)
|
||||
tk.MustQuery(`show create table binary_collate`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table binary_collate`).Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"binary_collate CREATE TABLE `binary_collate` (\n"+
|
||||
" `a` varchar(10) DEFAULT NULL\n"+
|
||||
@ -861,7 +860,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
// Test for issue #17 in bug competition, default num and sequence should be shown without quote.
|
||||
tk.MustExec(`drop table if exists default_num`)
|
||||
tk.MustExec("create table default_num(a int default 11)")
|
||||
tk.MustQuery("show create table default_num").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table default_num").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"default_num CREATE TABLE `default_num` (\n"+
|
||||
" `a` int(11) DEFAULT '11'\n"+
|
||||
@ -869,7 +868,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
))
|
||||
tk.MustExec(`drop table if exists default_varchar`)
|
||||
tk.MustExec("create table default_varchar(a varchar(10) default \"haha\")")
|
||||
tk.MustQuery("show create table default_varchar").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table default_varchar").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"default_varchar CREATE TABLE `default_varchar` (\n"+
|
||||
" `a` varchar(10) DEFAULT 'haha'\n"+
|
||||
@ -877,7 +876,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
))
|
||||
tk.MustExec(`drop table if exists default_sequence`)
|
||||
tk.MustExec("create table default_sequence(a int default nextval(seq))")
|
||||
tk.MustQuery("show create table default_sequence").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table default_sequence").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"default_sequence CREATE TABLE `default_sequence` (\n"+
|
||||
" `a` int(11) DEFAULT nextval(`test`.`seq`)\n"+
|
||||
@ -890,7 +889,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
tk.MustExec(`DROP TABLE IF EXISTS parent, child`)
|
||||
tk.MustExec(`CREATE TABLE child (id INT NOT NULL PRIMARY KEY auto_increment, parent_id INT NOT NULL, INDEX par_ind (parent_id), CONSTRAINT child_ibfk_1 FOREIGN KEY (parent_id) REFERENCES parent(id))`)
|
||||
tk.MustExec(`CREATE TABLE parent ( id INT NOT NULL PRIMARY KEY auto_increment )`)
|
||||
tk.MustQuery(`show create table child`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table child`).Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"child CREATE TABLE `child` (\n"+
|
||||
" `id` int(11) NOT NULL AUTO_INCREMENT,\n"+
|
||||
@ -904,7 +903,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
// Test Foreign keys + ON DELETE / ON UPDATE
|
||||
tk.MustExec(`DROP TABLE child`)
|
||||
tk.MustExec(`CREATE TABLE child (id INT NOT NULL PRIMARY KEY auto_increment, parent_id INT NOT NULL, INDEX par_ind (parent_id), CONSTRAINT child_ibfk_1 FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE SET NULL ON UPDATE CASCADE)`)
|
||||
tk.MustQuery(`show create table child`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table child`).Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"child CREATE TABLE `child` (\n"+
|
||||
" `id` int(11) NOT NULL AUTO_INCREMENT,\n"+
|
||||
@ -933,7 +932,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
partition p2 values in (4,12,13,14,18),
|
||||
partition p3 values in (7,8,15,16,null)
|
||||
);`)
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|",
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `id` int(11) DEFAULT NULL,\n"+
|
||||
" `name` varchar(10) DEFAULT NULL,\n"+
|
||||
@ -952,7 +951,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
partition p2 values in (4,12,13,14,18),
|
||||
partition p3 values in (7,8,15,16,null)
|
||||
);`)
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|",
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `id` int(11) DEFAULT NULL,\n"+
|
||||
" `name` varchar(10) DEFAULT NULL,\n"+
|
||||
@ -967,7 +966,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
tk.MustExec(`create table t (id int, name varchar(10), unique index idx (id, name)) partition by list columns (id, name) (
|
||||
partition p0 values in ((3, '1'), (5, '5')),
|
||||
partition p1 values in ((1, '1')));`)
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|",
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `id` int(11) DEFAULT NULL,\n"+
|
||||
" `name` varchar(10) DEFAULT NULL,\n"+
|
||||
@ -978,7 +977,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
" PARTITION `p1` VALUES IN ((1,\"1\")))"))
|
||||
tk.MustExec(`DROP TABLE IF EXISTS t`)
|
||||
tk.MustExec(`create table t (id int primary key, v varchar(255) not null, key idx_v (v) comment 'foo\'bar')`)
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|",
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `id` int(11) NOT NULL,\n"+
|
||||
" `v` varchar(255) NOT NULL,\n"+
|
||||
@ -988,7 +987,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
|
||||
// For issue #29922
|
||||
tk.MustExec("CREATE TABLE `thash` (\n `id` bigint unsigned NOT NULL,\n `data` varchar(255) DEFAULT NULL,\n PRIMARY KEY (`id`)\n)\nPARTITION BY HASH (`id`)\n(PARTITION pEven COMMENT = \"Even ids\",\n PARTITION pOdd COMMENT = \"Odd ids\");")
|
||||
tk.MustQuery("show create table `thash`").Check(testutil.RowsWithSep("|", ""+
|
||||
tk.MustQuery("show create table `thash`").Check(testkit.RowsWithSep("|", ""+
|
||||
"thash CREATE TABLE `thash` (\n"+
|
||||
" `id` bigint(20) unsigned NOT NULL,\n"+
|
||||
" `data` varchar(255) DEFAULT NULL,\n"+
|
||||
@ -1001,7 +1000,7 @@ func TestShowCreateTable(t *testing.T) {
|
||||
// empty edge case
|
||||
tk.MustExec("drop table if exists `thash`")
|
||||
tk.MustExec("CREATE TABLE `thash` (\n `id` bigint unsigned NOT NULL,\n `data` varchar(255) DEFAULT NULL,\n PRIMARY KEY (`id`)\n)\nPARTITION BY HASH (`id`);")
|
||||
tk.MustQuery("show create table `thash`").Check(testutil.RowsWithSep("|", ""+
|
||||
tk.MustQuery("show create table `thash`").Check(testkit.RowsWithSep("|", ""+
|
||||
"thash CREATE TABLE `thash` (\n"+
|
||||
" `id` bigint(20) unsigned NOT NULL,\n"+
|
||||
" `data` varchar(255) DEFAULT NULL,\n"+
|
||||
@ -1026,7 +1025,7 @@ func TestShowCreateTablePlacement(t *testing.T) {
|
||||
defer tk.MustExec(`DROP PLACEMENT POLICY IF EXISTS x`)
|
||||
tk.MustExec("create table t(a int)" +
|
||||
"PLACEMENT POLICY=\"x\"")
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|",
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL\n"+
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin "+
|
||||
@ -1037,7 +1036,7 @@ func TestShowCreateTablePlacement(t *testing.T) {
|
||||
tk.MustExec(`DROP TABLE IF EXISTS t`)
|
||||
tk.MustExec("create table t(a int)" +
|
||||
"/*T![placement] PLACEMENT POLICY=\"x\" */")
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|",
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL\n"+
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin "+
|
||||
@ -1055,7 +1054,7 @@ func TestShowCreateTablePlacement(t *testing.T) {
|
||||
"(PARTITION pLow VALUES in (1,2,3,5,8) COMMENT 'a comment' placement policy 'x'," +
|
||||
" PARTITION pMid VALUES in (9) COMMENT 'another comment'," +
|
||||
"partition pMax values IN (10,11,12))")
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|", ""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL,\n"+
|
||||
" `b` varchar(255) DEFAULT NULL\n"+
|
||||
@ -1071,7 +1070,7 @@ func TestShowCreateTablePlacement(t *testing.T) {
|
||||
"PARTITION BY LIST COLUMNS (b)\n" +
|
||||
"(PARTITION pLow VALUES in ('1','2','3','5','8') COMMENT 'a comment' placement policy 'x'," +
|
||||
"partition pMax values IN ('10','11','12'))")
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|", ""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL,\n"+
|
||||
" `b` varchar(255) DEFAULT NULL\n"+
|
||||
@ -1086,7 +1085,7 @@ func TestShowCreateTablePlacement(t *testing.T) {
|
||||
"PARTITION BY LIST COLUMNS (a,b)\n" +
|
||||
"(PARTITION pLow VALUES in ((1,'1'),(2,'2'),(3,'3'),(5,'5'),(8,'8')) COMMENT 'a comment' placement policy 'x'," +
|
||||
"partition pMax values IN ((10,'10'),(11,'11'),(12,'12')))")
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|", ""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL,\n"+
|
||||
" `b` varchar(255) DEFAULT NULL\n"+
|
||||
@ -1101,7 +1100,7 @@ func TestShowCreateTablePlacement(t *testing.T) {
|
||||
"PARTITION BY RANGE (a)\n" +
|
||||
"(PARTITION pLow VALUES less than (1000000) COMMENT 'a comment' placement policy 'x'," +
|
||||
"partition pMax values LESS THAN (MAXVALUE))")
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|", ""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL,\n"+
|
||||
" `b` varchar(255) DEFAULT NULL\n"+
|
||||
@ -1116,7 +1115,7 @@ func TestShowCreateTablePlacement(t *testing.T) {
|
||||
"PARTITION BY RANGE COLUMNS (b)\n" +
|
||||
"(PARTITION pLow VALUES less than ('1000000') COMMENT 'a comment' placement policy 'x'," +
|
||||
"partition pMax values LESS THAN (MAXVALUE))")
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|", ""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL,\n"+
|
||||
" `b` varchar(255) DEFAULT NULL\n"+
|
||||
@ -1136,7 +1135,7 @@ func TestShowCreateTablePlacement(t *testing.T) {
|
||||
" PARTITION pMadMax VALUES less than (MAXVALUE,'1000000') COMMENT ='Not a comment' placement policy 'x'," +
|
||||
"partition pMax values LESS THAN (MAXVALUE, MAXVALUE))")
|
||||
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 8200 Unsupported partition type RANGE, treat as normal table"))
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|", ""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL,\n"+
|
||||
" `b` varchar(255) DEFAULT NULL\n"+
|
||||
@ -1147,7 +1146,7 @@ func TestShowCreateTablePlacement(t *testing.T) {
|
||||
tk.MustExec("create table t(a int, b varchar(255))" +
|
||||
"/*T![placement] PLACEMENT POLICY=\"x\" */" +
|
||||
"PARTITION BY HASH (a) PARTITIONS 2")
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|", ""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL,\n"+
|
||||
" `b` varchar(255) DEFAULT NULL\n"+
|
||||
@ -1160,7 +1159,7 @@ func TestShowCreateTablePlacement(t *testing.T) {
|
||||
"PARTITION BY HASH (a)\n" +
|
||||
"(PARTITION pLow COMMENT 'a comment' placement policy 'x'," +
|
||||
"partition pMax)")
|
||||
tk.MustQuery(`show create table t`).Check(testutil.RowsWithSep("|", ""+
|
||||
tk.MustQuery(`show create table t`).Check(testkit.RowsWithSep("|", ""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) DEFAULT NULL,\n"+
|
||||
" `b` varchar(255) DEFAULT NULL\n"+
|
||||
@ -1180,7 +1179,7 @@ func TestShowCreateTableAutoRandom(t *testing.T) {
|
||||
|
||||
// Basic show create table.
|
||||
tk.MustExec("create table auto_random_tbl1 (a bigint primary key auto_random(3), b varchar(255))")
|
||||
tk.MustQuery("show create table `auto_random_tbl1`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `auto_random_tbl1`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"auto_random_tbl1 CREATE TABLE `auto_random_tbl1` (\n"+
|
||||
" `a` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(3) */,\n"+
|
||||
@ -1191,7 +1190,7 @@ func TestShowCreateTableAutoRandom(t *testing.T) {
|
||||
|
||||
// Implicit auto_random value should be shown explicitly.
|
||||
tk.MustExec("create table auto_random_tbl2 (a bigint auto_random primary key, b char)")
|
||||
tk.MustQuery("show create table auto_random_tbl2").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table auto_random_tbl2").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"auto_random_tbl2 CREATE TABLE `auto_random_tbl2` (\n"+
|
||||
" `a` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(5) */,\n"+
|
||||
@ -1202,7 +1201,7 @@ func TestShowCreateTableAutoRandom(t *testing.T) {
|
||||
|
||||
// Special version comment can be shown in TiDB with new version.
|
||||
tk.MustExec("create table auto_random_tbl3 (a bigint /*T![auto_rand] auto_random */ primary key)")
|
||||
tk.MustQuery("show create table auto_random_tbl3").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table auto_random_tbl3").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"auto_random_tbl3 CREATE TABLE `auto_random_tbl3` (\n"+
|
||||
" `a` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(5) */,\n"+
|
||||
@ -1211,7 +1210,7 @@ func TestShowCreateTableAutoRandom(t *testing.T) {
|
||||
))
|
||||
// Test show auto_random table option.
|
||||
tk.MustExec("create table auto_random_tbl4 (a bigint primary key auto_random(5), b varchar(255)) auto_random_base = 100")
|
||||
tk.MustQuery("show create table `auto_random_tbl4`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `auto_random_tbl4`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"auto_random_tbl4 CREATE TABLE `auto_random_tbl4` (\n"+
|
||||
" `a` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(5) */,\n"+
|
||||
@ -1221,7 +1220,7 @@ func TestShowCreateTableAutoRandom(t *testing.T) {
|
||||
))
|
||||
// Test implicit auto_random with auto_random table option.
|
||||
tk.MustExec("create table auto_random_tbl5 (a bigint auto_random primary key, b char) auto_random_base 50")
|
||||
tk.MustQuery("show create table auto_random_tbl5").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table auto_random_tbl5").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"auto_random_tbl5 CREATE TABLE `auto_random_tbl5` (\n"+
|
||||
" `a` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(5) */,\n"+
|
||||
@ -1231,7 +1230,7 @@ func TestShowCreateTableAutoRandom(t *testing.T) {
|
||||
))
|
||||
// Test auto_random table option already with special comment.
|
||||
tk.MustExec("create table auto_random_tbl6 (a bigint /*T![auto_rand] auto_random */ primary key) auto_random_base 200")
|
||||
tk.MustQuery("show create table auto_random_tbl6").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table auto_random_tbl6").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"auto_random_tbl6 CREATE TABLE `auto_random_tbl6` (\n"+
|
||||
" `a` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(5) */,\n"+
|
||||
@ -1249,7 +1248,7 @@ func TestAutoIdCache(t *testing.T) {
|
||||
|
||||
tk.MustExec("drop table if exists t")
|
||||
tk.MustExec("create table t(a int auto_increment key) auto_id_cache = 10")
|
||||
tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table t").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) NOT NULL AUTO_INCREMENT,\n"+
|
||||
@ -1258,7 +1257,7 @@ func TestAutoIdCache(t *testing.T) {
|
||||
))
|
||||
tk.MustExec("drop table if exists t")
|
||||
tk.MustExec("create table t(a int auto_increment unique, b int key) auto_id_cache 100")
|
||||
tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table t").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) NOT NULL AUTO_INCREMENT,\n"+
|
||||
@ -1269,7 +1268,7 @@ func TestAutoIdCache(t *testing.T) {
|
||||
))
|
||||
tk.MustExec("drop table if exists t")
|
||||
tk.MustExec("create table t(a int key) auto_id_cache 5")
|
||||
tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table t").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` int(11) NOT NULL,\n"+
|
||||
@ -1288,7 +1287,7 @@ func TestShowCreateStmtIgnoreLocalTemporaryTables(t *testing.T) {
|
||||
tk.MustExec("drop view if exists v1")
|
||||
tk.MustExec("create view v1 as select 1")
|
||||
tk.MustExec("create temporary table v1 (a int)")
|
||||
tk.MustQuery("show create table v1").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table v1").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"v1 CREATE TEMPORARY TABLE `v1` (\n"+
|
||||
" `a` int(11) DEFAULT NULL\n"+
|
||||
@ -1302,7 +1301,7 @@ func TestShowCreateStmtIgnoreLocalTemporaryTables(t *testing.T) {
|
||||
tk.MustExec("drop view if exists seq1")
|
||||
tk.MustExec("create sequence seq1")
|
||||
tk.MustExec("create temporary table seq1 (a int)")
|
||||
tk.MustQuery("show create sequence seq1").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create sequence seq1").Check(testkit.RowsWithSep("|",
|
||||
"seq1 CREATE SEQUENCE `seq1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB",
|
||||
))
|
||||
tk.MustExec("drop sequence seq1")
|
||||
@ -1323,7 +1322,7 @@ func TestAutoRandomBase(t *testing.T) {
|
||||
|
||||
tk.MustExec("drop table if exists t")
|
||||
tk.MustExec("create table t (a bigint primary key auto_random(5), b int unique key auto_increment) auto_random_base = 100, auto_increment = 100")
|
||||
tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table t").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(5) */,\n"+
|
||||
@ -1334,7 +1333,7 @@ func TestAutoRandomBase(t *testing.T) {
|
||||
))
|
||||
|
||||
tk.MustExec("insert into t(`a`) values (1000)")
|
||||
tk.MustQuery("show create table t").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table t").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t CREATE TABLE `t` (\n"+
|
||||
" `a` bigint(20) NOT NULL /*T![auto_rand] AUTO_RANDOM(5) */,\n"+
|
||||
@ -1374,7 +1373,7 @@ func TestShowEscape(t *testing.T) {
|
||||
tk.MustExec("use test")
|
||||
tk.MustExec("drop table if exists `t``abl\"e`")
|
||||
tk.MustExec("create table `t``abl\"e`(`c``olum\"n` int(11) primary key)")
|
||||
tk.MustQuery("show create table `t``abl\"e`").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table `t``abl\"e`").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t`abl\"e CREATE TABLE `t``abl\"e` (\n"+
|
||||
" `c``olum\"n` int(11) NOT NULL,\n"+
|
||||
@ -1385,7 +1384,7 @@ func TestShowEscape(t *testing.T) {
|
||||
// ANSI_QUOTES will change the SHOW output
|
||||
tk.MustExec("set @old_sql_mode=@@sql_mode")
|
||||
tk.MustExec("set sql_mode=ansi_quotes")
|
||||
tk.MustQuery("show create table \"t`abl\"\"e\"").Check(testutil.RowsWithSep("|",
|
||||
tk.MustQuery("show create table \"t`abl\"\"e\"").Check(testkit.RowsWithSep("|",
|
||||
""+
|
||||
"t`abl\"e CREATE TABLE \"t`abl\"\"e\" (\n"+
|
||||
" \"c`olum\"\"n\" int(11) NOT NULL,\n"+
|
||||
@ -1593,14 +1592,14 @@ func TestIssue19507(t *testing.T) {
|
||||
tk.MustExec("use test")
|
||||
tk.MustExec("CREATE TABLE t2(a int primary key, b int unique, c int not null, unique index (c));")
|
||||
tk.MustQuery("SHOW INDEX IN t2;").Check(
|
||||
testutil.RowsWithSep("|", "t2|0|PRIMARY|1|a|A|0|<nil>|<nil>||BTREE|||YES|<nil>|YES",
|
||||
testkit.RowsWithSep("|", "t2|0|PRIMARY|1|a|A|0|<nil>|<nil>||BTREE|||YES|<nil>|YES",
|
||||
"t2|0|c|1|c|A|0|<nil>|<nil>||BTREE|||YES|<nil>|NO",
|
||||
"t2|0|b|1|b|A|0|<nil>|<nil>|YES|BTREE|||YES|<nil>|NO"))
|
||||
|
||||
tk.MustExec("CREATE INDEX t2_b_c_index ON t2 (b, c);")
|
||||
tk.MustExec("CREATE INDEX t2_c_b_index ON t2 (c, b);")
|
||||
tk.MustQuery("SHOW INDEX IN t2;").Check(
|
||||
testutil.RowsWithSep("|", "t2|0|PRIMARY|1|a|A|0|<nil>|<nil>||BTREE|||YES|<nil>|YES",
|
||||
testkit.RowsWithSep("|", "t2|0|PRIMARY|1|a|A|0|<nil>|<nil>||BTREE|||YES|<nil>|YES",
|
||||
"t2|0|c|1|c|A|0|<nil>|<nil>||BTREE|||YES|<nil>|NO",
|
||||
"t2|0|b|1|b|A|0|<nil>|<nil>|YES|BTREE|||YES|<nil>|NO",
|
||||
"t2|1|t2_b_c_index|1|b|A|0|<nil>|<nil>|YES|BTREE|||YES|<nil>|NO",
|
||||
|
||||
201
executor/tikv_regions_peers_table_test.go
Normal file
201
executor/tikv_regions_peers_table_test.go
Normal file
@ -0,0 +1,201 @@
|
||||
// Copyright 2022 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 (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/pingcap/fn"
|
||||
"github.com/pingcap/tidb/store/helper"
|
||||
"github.com/pingcap/tidb/testkit"
|
||||
"github.com/pingcap/tidb/util/pdapi"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var regionsInfo = map[uint64]helper.RegionInfo{
|
||||
1: {
|
||||
ID: 1,
|
||||
Peers: []helper.RegionPeer{{ID: 11, StoreID: 1, IsLearner: false}, {ID: 12, StoreID: 2, IsLearner: false}, {ID: 13, StoreID: 3, IsLearner: false}},
|
||||
Leader: helper.RegionPeer{ID: 11, StoreID: 1, IsLearner: false},
|
||||
},
|
||||
2: {
|
||||
ID: 2,
|
||||
Peers: []helper.RegionPeer{{ID: 21, StoreID: 1, IsLearner: false}, {ID: 22, StoreID: 2, IsLearner: false}, {ID: 23, StoreID: 3, IsLearner: false}},
|
||||
Leader: helper.RegionPeer{ID: 22, StoreID: 2, IsLearner: false},
|
||||
},
|
||||
3: {
|
||||
ID: 3,
|
||||
Peers: []helper.RegionPeer{{ID: 31, StoreID: 1, IsLearner: false}, {ID: 32, StoreID: 2, IsLearner: false}, {ID: 33, StoreID: 3, IsLearner: false}},
|
||||
Leader: helper.RegionPeer{ID: 33, StoreID: 3, IsLearner: false},
|
||||
},
|
||||
}
|
||||
|
||||
var storeRegionsInfo = &helper.RegionsInfo{
|
||||
Count: 3,
|
||||
Regions: []helper.RegionInfo{
|
||||
regionsInfo[1],
|
||||
regionsInfo[2],
|
||||
regionsInfo[3],
|
||||
},
|
||||
}
|
||||
|
||||
var storesRegionsInfo = map[uint64]*helper.RegionsInfo{
|
||||
1: storeRegionsInfo,
|
||||
2: storeRegionsInfo,
|
||||
3: storeRegionsInfo,
|
||||
}
|
||||
|
||||
func storesRegionsInfoHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusBadRequest, "unable to parse id", err)
|
||||
return
|
||||
}
|
||||
writeResp(w, storesRegionsInfo[uint64(id)])
|
||||
}
|
||||
|
||||
func regionsInfoHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id, err := strconv.Atoi(vars["id"])
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusBadRequest, "unable to parse id", err)
|
||||
return
|
||||
}
|
||||
writeResp(w, regionsInfo[uint64(id)])
|
||||
}
|
||||
|
||||
func TestTikvRegionPeers(t *testing.T) {
|
||||
startTime := time.Now()
|
||||
// mock PD http server
|
||||
router := mux.NewRouter()
|
||||
server := httptest.NewServer(router)
|
||||
// mock store stats stat
|
||||
mockAddr := strings.TrimPrefix(server.URL, "http://")
|
||||
// mock PD API
|
||||
router.Handle(pdapi.Status, fn.Wrap(func() (interface{}, error) {
|
||||
return struct {
|
||||
Version string `json:"version"`
|
||||
GitHash string `json:"git_hash"`
|
||||
StartTimestamp int64 `json:"start_timestamp"`
|
||||
}{
|
||||
Version: "4.0.0-alpha",
|
||||
GitHash: "mock-pd-githash",
|
||||
StartTimestamp: startTime.Unix(),
|
||||
}, nil
|
||||
}))
|
||||
// mock get regionsInfo by store id
|
||||
router.HandleFunc(pdapi.StoreRegions+"/"+"{id}", storesRegionsInfoHandler)
|
||||
// mock get regionInfo by region id
|
||||
router.HandleFunc(pdapi.RegionByID+"/"+"{id}", regionsInfoHandler)
|
||||
defer server.Close()
|
||||
|
||||
store, clean := testkit.CreateMockStore(t)
|
||||
defer clean()
|
||||
|
||||
store = &mockStore{
|
||||
store.(helper.Storage),
|
||||
mockAddr,
|
||||
}
|
||||
|
||||
fullRegionPeers := [][]string{
|
||||
{"1", "11", "1", "0", "1", "NORMAL", "<nil>"},
|
||||
{"1", "12", "2", "0", "0", "NORMAL", "<nil>"},
|
||||
{"1", "13", "3", "0", "0", "NORMAL", "<nil>"},
|
||||
|
||||
{"2", "21", "1", "0", "0", "NORMAL", "<nil>"},
|
||||
{"2", "22", "2", "0", "1", "NORMAL", "<nil>"},
|
||||
{"2", "23", "3", "0", "0", "NORMAL", "<nil>"},
|
||||
|
||||
{"3", "31", "1", "0", "0", "NORMAL", "<nil>"},
|
||||
{"3", "32", "2", "0", "0", "NORMAL", "<nil>"},
|
||||
{"3", "33", "3", "0", "1", "NORMAL", "<nil>"},
|
||||
}
|
||||
|
||||
var cases = []struct {
|
||||
conditions []string
|
||||
reqCount int32
|
||||
expected [][]string
|
||||
}{
|
||||
{
|
||||
conditions: []string{
|
||||
"store_id in (1,2,3)",
|
||||
"region_id in (1,2,3)",
|
||||
},
|
||||
expected: fullRegionPeers,
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"store_id in (1,2)",
|
||||
"region_id=1",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullRegionPeers[0], fullRegionPeers[1],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"store_id in (1,2)",
|
||||
"region_id=1",
|
||||
"is_leader=1",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullRegionPeers[0],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"store_id in (1,2)",
|
||||
"region_id=1",
|
||||
"is_leader=0",
|
||||
},
|
||||
expected: [][]string{
|
||||
fullRegionPeers[1],
|
||||
},
|
||||
},
|
||||
{
|
||||
conditions: []string{
|
||||
"store_id =1",
|
||||
"region_id =1",
|
||||
"is_leader =0",
|
||||
},
|
||||
expected: [][]string{},
|
||||
},
|
||||
}
|
||||
|
||||
tk := testkit.NewTestKit(t, store)
|
||||
for _, cas := range cases {
|
||||
sql := "select * from information_schema.tikv_region_peers"
|
||||
if len(cas.conditions) > 0 {
|
||||
sql = fmt.Sprintf("%s where %s", sql, strings.Join(cas.conditions, " and "))
|
||||
}
|
||||
result := tk.MustQuery(sql)
|
||||
warnings := tk.Session().GetSessionVars().StmtCtx.GetWarnings()
|
||||
require.Lenf(t, warnings, 0, "unexpected warnings: %+v", warnings)
|
||||
var expected []string
|
||||
for _, row := range cas.expected {
|
||||
expectedRow := row
|
||||
expected = append(expected, strings.Join(expectedRow, " "))
|
||||
}
|
||||
result.Check(testkit.Rows(expected...))
|
||||
}
|
||||
}
|
||||
@ -38,7 +38,6 @@ import (
|
||||
"github.com/pingcap/tidb/types"
|
||||
"github.com/pingcap/tidb/util"
|
||||
"github.com/pingcap/tidb/util/mock"
|
||||
"github.com/pingcap/tidb/util/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@ -950,7 +949,7 @@ func TestInsertOnDupUpdateDefault(t *testing.T) {
|
||||
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(testutil.RowsWithSep("|", "21|silver sight", "22|gold witch", "24|gray singer"))
|
||||
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;")
|
||||
}
|
||||
|
||||
|
||||
@ -18,9 +18,11 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/pingcap/tidb/kv"
|
||||
"github.com/pingcap/tidb/parser/mysql"
|
||||
"github.com/pingcap/tidb/sessionctx/stmtctx"
|
||||
"github.com/pingcap/tidb/types"
|
||||
"github.com/pingcap/tidb/util/codec"
|
||||
@ -35,3 +37,16 @@ func MustNewCommonHandle(t *testing.T, values ...interface{}) kv.Handle {
|
||||
require.NoError(t, err)
|
||||
return ch
|
||||
}
|
||||
|
||||
// MaskSortHandles sorts the handles by lowest (fieldTypeBits - 1 - shardBitsCount) bits.
|
||||
func MaskSortHandles(handles []int64, shardBitsCount int, fieldType byte) []int64 {
|
||||
typeBitsLength := mysql.DefaultLengthOfMysqlTypes[fieldType] * 8
|
||||
const signBitCount = 1
|
||||
shiftBitsCount := 64 - typeBitsLength + shardBitsCount + signBitCount
|
||||
ordered := make([]int64, len(handles))
|
||||
for i, h := range handles {
|
||||
ordered[i] = h << shiftBitsCount >> shiftBitsCount
|
||||
}
|
||||
sort.Slice(ordered, func(i, j int) bool { return ordered[i] < ordered[j] })
|
||||
return ordered
|
||||
}
|
||||
|
||||
@ -27,13 +27,11 @@ import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/pingcap/check"
|
||||
"github.com/pingcap/errors"
|
||||
"github.com/pingcap/tidb/kv"
|
||||
"github.com/pingcap/tidb/parser/mysql"
|
||||
"github.com/pingcap/tidb/sessionctx/stmtctx"
|
||||
"github.com/pingcap/tidb/testkit/testdata"
|
||||
"github.com/pingcap/tidb/types"
|
||||
@ -305,16 +303,3 @@ func (t *TestData) GenerateOutputIfNeeded() error {
|
||||
_, err = file.Write(buf.Bytes())
|
||||
return err
|
||||
}
|
||||
|
||||
// MaskSortHandles sorts the handles by lowest (fieldTypeBits - 1 - shardBitsCount) bits.
|
||||
func MaskSortHandles(handles []int64, shardBitsCount int, fieldType byte) []int64 {
|
||||
typeBitsLength := mysql.DefaultLengthOfMysqlTypes[fieldType] * 8
|
||||
const signBitCount = 1
|
||||
shiftBitsCount := 64 - typeBitsLength + shardBitsCount + signBitCount
|
||||
ordered := make([]int64, len(handles))
|
||||
for i, h := range handles {
|
||||
ordered[i] = h << shiftBitsCount >> shiftBitsCount
|
||||
}
|
||||
sort.Slice(ordered, func(i, j int) bool { return ordered[i] < ordered[j] })
|
||||
return ordered
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user