github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/interlock/infoschema_reader_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package interlock_test
    15  
    16  import (
    17  	"crypto/tls"
    18  	"fmt"
    19  	"net"
    20  	"net/http/httptest"
    21  	"strconv"
    22  	"strings"
    23  	"time"
    24  
    25  	"github.com/gorilla/mux"
    26  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    27  	"github.com/whtcorpsinc/BerolinaSQL/auth"
    28  	"github.com/whtcorpsinc/BerolinaSQL/perceptron"
    29  	. "github.com/whtcorpsinc/check"
    30  	"github.com/whtcorpsinc/failpoint"
    31  	"github.com/whtcorpsinc/fn"
    32  	"github.com/whtcorpsinc/milevadb/causetstore/einsteindb"
    33  	"github.com/whtcorpsinc/milevadb/causetstore/helper"
    34  	"github.com/whtcorpsinc/milevadb/causetstore/mockstore"
    35  	"github.com/whtcorpsinc/milevadb/config"
    36  	"github.com/whtcorpsinc/milevadb/ekv"
    37  	"github.com/whtcorpsinc/milevadb/interlock"
    38  	"github.com/whtcorpsinc/milevadb/petri"
    39  	"github.com/whtcorpsinc/milevadb/petri/infosync"
    40  	"github.com/whtcorpsinc/milevadb/server"
    41  	"github.com/whtcorpsinc/milevadb/soliton"
    42  	"github.com/whtcorpsinc/milevadb/soliton/FIDelapi"
    43  	"github.com/whtcorpsinc/milevadb/soliton/solitonutil"
    44  	"github.com/whtcorpsinc/milevadb/soliton/stringutil"
    45  	"github.com/whtcorpsinc/milevadb/soliton/testkit"
    46  	"github.com/whtcorpsinc/milevadb/soliton/testleak"
    47  	"github.com/whtcorpsinc/milevadb/statistics"
    48  	"github.com/whtcorpsinc/milevadb/statistics/handle"
    49  	"github.com/whtcorpsinc/milevadb/stochastik"
    50  	"github.com/whtcorpsinc/milevadb/stochastikctx/variable"
    51  	"google.golang.org/grpc"
    52  )
    53  
    54  var _ = Suite(&testschemaReplicantBlockSuite{})
    55  
    56  // this SerialSuites is used to solve the data race caused by BlockStatsCacheExpiry,
    57  // if your test not change the BlockStatsCacheExpiry variable, please use testschemaReplicantBlockSuite for test.
    58  var _ = SerialSuites(&testschemaReplicantBlockSerialSuite{})
    59  
    60  var _ = SerialSuites(&inspectionSuite{})
    61  
    62  type testschemaReplicantBlockSuiteBase struct {
    63  	causetstore ekv.CausetStorage
    64  	dom         *petri.Petri
    65  }
    66  
    67  type testschemaReplicantBlockSuite struct {
    68  	testschemaReplicantBlockSuiteBase
    69  }
    70  
    71  type testschemaReplicantBlockSerialSuite struct {
    72  	testschemaReplicantBlockSuiteBase
    73  }
    74  
    75  type inspectionSuite struct {
    76  	causetstore ekv.CausetStorage
    77  	dom         *petri.Petri
    78  }
    79  
    80  func (s *testschemaReplicantBlockSuiteBase) SetUpSuite(c *C) {
    81  	causetstore, dom, err := newStoreWithBootstrap()
    82  	c.Assert(err, IsNil)
    83  	s.causetstore = causetstore
    84  	s.dom = dom
    85  	config.UFIDelateGlobal(func(conf *config.Config) {
    86  		conf.OOMCausetAction = config.OOMCausetActionLog
    87  	})
    88  }
    89  
    90  func (s *testschemaReplicantBlockSuiteBase) TearDownSuite(c *C) {
    91  	s.dom.Close()
    92  	s.causetstore.Close()
    93  }
    94  
    95  func (s *inspectionSuite) SetUpSuite(c *C) {
    96  	testleak.BeforeTest()
    97  
    98  	var err error
    99  	s.causetstore, err = mockstore.NewMockStore()
   100  	c.Assert(err, IsNil)
   101  	stochastik.DisableStats4Test()
   102  	s.dom, err = stochastik.BootstrapStochastik(s.causetstore)
   103  	c.Assert(err, IsNil)
   104  }
   105  
   106  func (s *inspectionSuite) TearDownSuite(c *C) {
   107  	s.dom.Close()
   108  	s.causetstore.Close()
   109  	testleak.AfterTest(c)()
   110  }
   111  
   112  func (s *inspectionSuite) TestInspectionBlocks(c *C) {
   113  	tk := testkit.NewTestKit(c, s.causetstore)
   114  	instances := []string{
   115  		"fidel,127.0.0.1:11080,127.0.0.1:10080,mock-version,mock-githash",
   116  		"milevadb,127.0.0.1:11080,127.0.0.1:10080,mock-version,mock-githash",
   117  		"einsteindb,127.0.0.1:11080,127.0.0.1:10080,mock-version,mock-githash",
   118  	}
   119  	fpName := "github.com/whtcorpsinc/milevadb/schemareplicant/mockClusterInfo"
   120  	fpExpr := `return("` + strings.Join(instances, ";") + `")`
   121  	c.Assert(failpoint.Enable(fpName, fpExpr), IsNil)
   122  	defer func() { c.Assert(failpoint.Disable(fpName), IsNil) }()
   123  
   124  	tk.MustQuery("select type, instance, status_address, version, git_hash from information_schema.cluster_info").Check(testkit.Events(
   125  		"fidel 127.0.0.1:11080 127.0.0.1:10080 mock-version mock-githash",
   126  		"milevadb 127.0.0.1:11080 127.0.0.1:10080 mock-version mock-githash",
   127  		"einsteindb 127.0.0.1:11080 127.0.0.1:10080 mock-version mock-githash",
   128  	))
   129  
   130  	// enable inspection mode
   131  	inspectionBlockCache := map[string]variable.BlockSnapshot{}
   132  	tk.Se.GetStochastikVars().InspectionBlockCache = inspectionBlockCache
   133  	tk.MustQuery("select type, instance, status_address, version, git_hash from information_schema.cluster_info").Check(testkit.Events(
   134  		"fidel 127.0.0.1:11080 127.0.0.1:10080 mock-version mock-githash",
   135  		"milevadb 127.0.0.1:11080 127.0.0.1:10080 mock-version mock-githash",
   136  		"einsteindb 127.0.0.1:11080 127.0.0.1:10080 mock-version mock-githash",
   137  	))
   138  	c.Assert(inspectionBlockCache["cluster_info"].Err, IsNil)
   139  	c.Assert(len(inspectionBlockCache["cluster_info"].Events), DeepEquals, 3)
   140  
   141  	// check whether is obtain data from cache at the next time
   142  	inspectionBlockCache["cluster_info"].Events[0][0].SetString("modified-fidel", allegrosql.DefaultDefCauslationName)
   143  	tk.MustQuery("select type, instance, status_address, version, git_hash from information_schema.cluster_info").Check(testkit.Events(
   144  		"modified-fidel 127.0.0.1:11080 127.0.0.1:10080 mock-version mock-githash",
   145  		"milevadb 127.0.0.1:11080 127.0.0.1:10080 mock-version mock-githash",
   146  		"einsteindb 127.0.0.1:11080 127.0.0.1:10080 mock-version mock-githash",
   147  	))
   148  	tk.Se.GetStochastikVars().InspectionBlockCache = nil
   149  }
   150  
   151  func (s *testschemaReplicantBlockSuite) TestProfiling(c *C) {
   152  	tk := testkit.NewTestKit(c, s.causetstore)
   153  	tk.MustQuery("select * from information_schema.profiling").Check(testkit.Events())
   154  	tk.MustInterDirc("set @@profiling=1")
   155  	tk.MustQuery("select * from information_schema.profiling").Check(testkit.Events("0 0  0 0 0 0 0 0 0 0 0 0 0 0   0"))
   156  }
   157  
   158  func (s *testschemaReplicantBlockSuite) TestSchemataBlocks(c *C) {
   159  	tk := testkit.NewTestKit(c, s.causetstore)
   160  
   161  	tk.MustQuery("select * from information_schema.SCHEMATA where schema_name='allegrosql';").Check(
   162  		testkit.Events("def allegrosql utf8mb4 utf8mb4_bin <nil>"))
   163  
   164  	// Test the privilege of new user for information_schema.schemata.
   165  	tk.MustInterDirc("create user schemata_tester")
   166  	schemataTester := testkit.NewTestKit(c, s.causetstore)
   167  	schemataTester.MustInterDirc("use information_schema")
   168  	c.Assert(schemataTester.Se.Auth(&auth.UserIdentity{
   169  		Username: "schemata_tester",
   170  		Hostname: "127.0.0.1",
   171  	}, nil, nil), IsTrue)
   172  	schemataTester.MustQuery("select count(*) from information_schema.SCHEMATA;").Check(testkit.Events("1"))
   173  	schemataTester.MustQuery("select * from information_schema.SCHEMATA where schema_name='allegrosql';").Check(
   174  		[][]interface{}{})
   175  	schemataTester.MustQuery("select * from information_schema.SCHEMATA where schema_name='INFORMATION_SCHEMA';").Check(
   176  		testkit.Events("def INFORMATION_SCHEMA utf8mb4 utf8mb4_bin <nil>"))
   177  
   178  	// Test the privilege of user with privilege of allegrosql for information_schema.schemata.
   179  	tk.MustInterDirc("CREATE ROLE r_mysql_priv;")
   180  	tk.MustInterDirc("GRANT ALL PRIVILEGES ON allegrosql.* TO r_mysql_priv;")
   181  	tk.MustInterDirc("GRANT r_mysql_priv TO schemata_tester;")
   182  	schemataTester.MustInterDirc("set role r_mysql_priv")
   183  	schemataTester.MustQuery("select count(*) from information_schema.SCHEMATA;").Check(testkit.Events("2"))
   184  	schemataTester.MustQuery("select * from information_schema.SCHEMATA;").Check(
   185  		testkit.Events("def INFORMATION_SCHEMA utf8mb4 utf8mb4_bin <nil>", "def allegrosql utf8mb4 utf8mb4_bin <nil>"))
   186  }
   187  
   188  func (s *testschemaReplicantBlockSuite) TestBlockIDAndIndexID(c *C) {
   189  	tk := testkit.NewTestKit(c, s.causetstore)
   190  	tk.MustInterDirc("drop causet if exists test.t")
   191  	tk.MustInterDirc("create causet test.t (a int, b int, primary key(a), key k1(b))")
   192  	tk.MustQuery("select index_id from information_schema.milevadb_indexes where block_schema = 'test' and block_name = 't'").Check(testkit.Events("0", "1"))
   193  	tblID, err := strconv.Atoi(tk.MustQuery("select milevadb_block_id from information_schema.blocks where block_schema = 'test' and block_name = 't'").Events()[0][0].(string))
   194  	c.Assert(err, IsNil)
   195  	c.Assert(tblID, Greater, 0)
   196  }
   197  
   198  func (s *testschemaReplicantBlockSuite) TestSchemataCharacterSet(c *C) {
   199  	tk := testkit.NewTestKit(c, s.causetstore)
   200  	tk.MustInterDirc("CREATE DATABASE `foo` DEFAULT CHARACTER SET = 'utf8mb4'")
   201  	tk.MustQuery("select default_character_set_name, default_defCauslation_name FROM information_schema.SCHEMATA  WHERE schema_name = 'foo'").Check(
   202  		testkit.Events("utf8mb4 utf8mb4_bin"))
   203  	tk.MustInterDirc("drop database `foo`")
   204  }
   205  
   206  func (s *testschemaReplicantBlockSuite) TestViews(c *C) {
   207  	tk := testkit.NewTestKit(c, s.causetstore)
   208  	tk.MustInterDirc("CREATE DEFINER='root'@'localhost' VIEW test.v1 AS SELECT 1")
   209  	tk.MustQuery("SELECT * FROM information_schema.views WHERE block_schema='test' AND block_name='v1'").Check(testkit.Events("def test v1 SELECT 1 CASCADED NO root@localhost DEFINER utf8mb4 utf8mb4_bin"))
   210  	tk.MustQuery("SELECT block_catalog, block_schema, block_name, block_type, engine, version, row_format, block_rows, avg_row_length, data_length, max_data_length, index_length, data_free, auto_increment, uFIDelate_time, check_time, block_defCauslation, checksum, create_options, block_comment FROM information_schema.blocks WHERE block_schema='test' AND block_name='v1'").Check(testkit.Events("def test v1 VIEW <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> VIEW"))
   211  }
   212  
   213  func (s *testschemaReplicantBlockSuite) TestEngines(c *C) {
   214  	tk := testkit.NewTestKit(c, s.causetstore)
   215  	tk.MustQuery("select * from information_schema.ENGINES;").Check(testkit.Events("InnoDB DEFAULT Supports transactions, event-level locking, and foreign keys YES YES YES"))
   216  }
   217  
   218  func (s *testschemaReplicantBlockSuite) TestCharacterSetDefCauslations(c *C) {
   219  	tk := testkit.NewTestKit(c, s.causetstore)
   220  
   221  	// The description defCausumn is not important
   222  	tk.MustQuery("SELECT default_defCauslate_name, maxlen FROM information_schema.character_sets ORDER BY character_set_name").Check(
   223  		testkit.Events("ascii_bin 1", "binary 1", "latin1_bin 1", "utf8_bin 3", "utf8mb4_bin 4"))
   224  
   225  	// The is_default defCausumn is not important
   226  	// but the id's are used by client libraries and must be sblock
   227  	tk.MustQuery("SELECT character_set_name, id, sortlen FROM information_schema.defCauslations ORDER BY defCauslation_name").Check(
   228  		testkit.Events("ascii 65 1", "binary 63 1", "latin1 47 1", "utf8 83 1", "utf8mb4 46 1"))
   229  
   230  	tk.MustQuery("select * from information_schema.COLLATION_CHARACTER_SET_APPLICABILITY where COLLATION_NAME='utf8mb4_bin';").Check(
   231  		testkit.Events("utf8mb4_bin utf8mb4"))
   232  }
   233  
   234  func (s *testschemaReplicantBlockSuite) TestDBSJobs(c *C) {
   235  	tk := testkit.NewTestKit(c, s.causetstore)
   236  	tk.MustInterDirc("create database if not exists test_dbs_jobs")
   237  	tk.MustQuery("select db_name, job_type from information_schema.DBS_JOBS limit 1").Check(
   238  		testkit.Events("test_dbs_jobs create schemaReplicant"))
   239  
   240  	tk.MustInterDirc("use test_dbs_jobs")
   241  	tk.MustInterDirc("create causet t (a int);")
   242  	tk.MustQuery("select db_name, block_name, job_type from information_schema.DBS_JOBS where block_name = 't'").Check(
   243  		testkit.Events("test_dbs_jobs t create causet"))
   244  
   245  	tk.MustQuery("select job_type from information_schema.DBS_JOBS group by job_type having job_type = 'create causet'").Check(
   246  		testkit.Events("create causet"))
   247  
   248  	// Test the START_TIME and END_TIME field.
   249  	tk.MustQuery("select distinct job_type from information_schema.DBS_JOBS where job_type = 'create causet' and start_time > str_to_date('20190101','%Y%m%d%H%i%s')").Check(
   250  		testkit.Events("create causet"))
   251  
   252  	// Test the privilege of new user for information_schema.DBS_JOBS.
   253  	tk.MustInterDirc("create user DBS_JOBS_tester")
   254  	DBSJobsTester := testkit.NewTestKit(c, s.causetstore)
   255  	DBSJobsTester.MustInterDirc("use information_schema")
   256  	c.Assert(DBSJobsTester.Se.Auth(&auth.UserIdentity{
   257  		Username: "DBS_JOBS_tester",
   258  		Hostname: "127.0.0.1",
   259  	}, nil, nil), IsTrue)
   260  
   261  	// Test the privilege of user for information_schema.dbs_jobs.
   262  	DBSJobsTester.MustQuery("select DB_NAME, TABLE_NAME from information_schema.DBS_JOBS where DB_NAME = 'test_dbs_jobs' and TABLE_NAME = 't';").Check(
   263  		[][]interface{}{})
   264  	tk.MustInterDirc("CREATE ROLE r_priv;")
   265  	tk.MustInterDirc("GRANT ALL PRIVILEGES ON test_dbs_jobs.* TO r_priv;")
   266  	tk.MustInterDirc("GRANT r_priv TO DBS_JOBS_tester;")
   267  	DBSJobsTester.MustInterDirc("set role r_priv")
   268  	DBSJobsTester.MustQuery("select DB_NAME, TABLE_NAME from information_schema.DBS_JOBS where DB_NAME = 'test_dbs_jobs' and TABLE_NAME = 't';").Check(
   269  		testkit.Events("test_dbs_jobs t"))
   270  }
   271  
   272  func (s *testschemaReplicantBlockSuite) TestKeyDeferredCausetUsage(c *C) {
   273  	tk := testkit.NewTestKit(c, s.causetstore)
   274  
   275  	tk.MustQuery("select * from information_schema.KEY_COLUMN_USAGE where TABLE_NAME='stats_spacetime' and COLUMN_NAME='block_id';").Check(
   276  		testkit.Events("def allegrosql tbl def allegrosql stats_spacetime block_id 1 <nil> <nil> <nil> <nil>"))
   277  
   278  	//test the privilege of new user for information_schema.block_constraints
   279  	tk.MustInterDirc("create user key_defCausumn_tester")
   280  	keyDeferredCausetTester := testkit.NewTestKit(c, s.causetstore)
   281  	keyDeferredCausetTester.MustInterDirc("use information_schema")
   282  	c.Assert(keyDeferredCausetTester.Se.Auth(&auth.UserIdentity{
   283  		Username: "key_defCausumn_tester",
   284  		Hostname: "127.0.0.1",
   285  	}, nil, nil), IsTrue)
   286  	keyDeferredCausetTester.MustQuery("select * from information_schema.KEY_COLUMN_USAGE;").Check([][]interface{}{})
   287  
   288  	//test the privilege of user with privilege of allegrosql.gc_delete_range for information_schema.block_constraints
   289  	tk.MustInterDirc("CREATE ROLE r_stats_spacetime ;")
   290  	tk.MustInterDirc("GRANT ALL PRIVILEGES ON allegrosql.stats_spacetime TO r_stats_spacetime;")
   291  	tk.MustInterDirc("GRANT r_stats_spacetime TO key_defCausumn_tester;")
   292  	keyDeferredCausetTester.MustInterDirc("set role r_stats_spacetime")
   293  	c.Assert(len(keyDeferredCausetTester.MustQuery("select * from information_schema.KEY_COLUMN_USAGE where TABLE_NAME='stats_spacetime';").Events()), Greater, 0)
   294  }
   295  
   296  func (s *testschemaReplicantBlockSuite) TestUserPrivileges(c *C) {
   297  	tk := testkit.NewTestKit(c, s.causetstore)
   298  	//test the privilege of new user for information_schema.block_constraints
   299  	tk.MustInterDirc("create user constraints_tester")
   300  	constraintsTester := testkit.NewTestKit(c, s.causetstore)
   301  	constraintsTester.MustInterDirc("use information_schema")
   302  	c.Assert(constraintsTester.Se.Auth(&auth.UserIdentity{
   303  		Username: "constraints_tester",
   304  		Hostname: "127.0.0.1",
   305  	}, nil, nil), IsTrue)
   306  	constraintsTester.MustQuery("select * from information_schema.TABLE_CONSTRAINTS;").Check([][]interface{}{})
   307  
   308  	//test the privilege of user with privilege of allegrosql.gc_delete_range for information_schema.block_constraints
   309  	tk.MustInterDirc("CREATE ROLE r_gc_delete_range ;")
   310  	tk.MustInterDirc("GRANT ALL PRIVILEGES ON allegrosql.gc_delete_range TO r_gc_delete_range;")
   311  	tk.MustInterDirc("GRANT r_gc_delete_range TO constraints_tester;")
   312  	constraintsTester.MustInterDirc("set role r_gc_delete_range")
   313  	c.Assert(len(constraintsTester.MustQuery("select * from information_schema.TABLE_CONSTRAINTS where TABLE_NAME='gc_delete_range';").Events()), Greater, 0)
   314  	constraintsTester.MustQuery("select * from information_schema.TABLE_CONSTRAINTS where TABLE_NAME='blocks_priv';").Check([][]interface{}{})
   315  
   316  	//test the privilege of new user for information_schema
   317  	tk.MustInterDirc("create user tester1")
   318  	tk1 := testkit.NewTestKit(c, s.causetstore)
   319  	tk1.MustInterDirc("use information_schema")
   320  	c.Assert(tk1.Se.Auth(&auth.UserIdentity{
   321  		Username: "tester1",
   322  		Hostname: "127.0.0.1",
   323  	}, nil, nil), IsTrue)
   324  	tk1.MustQuery("select * from information_schema.STATISTICS;").Check([][]interface{}{})
   325  
   326  	//test the privilege of user with some privilege for information_schema
   327  	tk.MustInterDirc("create user tester2")
   328  	tk.MustInterDirc("CREATE ROLE r_defCausumns_priv;")
   329  	tk.MustInterDirc("GRANT ALL PRIVILEGES ON allegrosql.defCausumns_priv TO r_defCausumns_priv;")
   330  	tk.MustInterDirc("GRANT r_defCausumns_priv TO tester2;")
   331  	tk2 := testkit.NewTestKit(c, s.causetstore)
   332  	tk2.MustInterDirc("use information_schema")
   333  	c.Assert(tk2.Se.Auth(&auth.UserIdentity{
   334  		Username: "tester2",
   335  		Hostname: "127.0.0.1",
   336  	}, nil, nil), IsTrue)
   337  	tk2.MustInterDirc("set role r_defCausumns_priv")
   338  	result := tk2.MustQuery("select * from information_schema.STATISTICS where TABLE_NAME='defCausumns_priv' and COLUMN_NAME='Host';")
   339  	c.Assert(len(result.Events()), Greater, 0)
   340  	tk2.MustQuery("select * from information_schema.STATISTICS where TABLE_NAME='blocks_priv' and COLUMN_NAME='Host';").Check(
   341  		[][]interface{}{})
   342  
   343  	//test the privilege of user with all privilege for information_schema
   344  	tk.MustInterDirc("create user tester3")
   345  	tk.MustInterDirc("CREATE ROLE r_all_priv;")
   346  	tk.MustInterDirc("GRANT ALL PRIVILEGES ON allegrosql.* TO r_all_priv;")
   347  	tk.MustInterDirc("GRANT r_all_priv TO tester3;")
   348  	tk3 := testkit.NewTestKit(c, s.causetstore)
   349  	tk3.MustInterDirc("use information_schema")
   350  	c.Assert(tk3.Se.Auth(&auth.UserIdentity{
   351  		Username: "tester3",
   352  		Hostname: "127.0.0.1",
   353  	}, nil, nil), IsTrue)
   354  	tk3.MustInterDirc("set role r_all_priv")
   355  	result = tk3.MustQuery("select * from information_schema.STATISTICS where TABLE_NAME='defCausumns_priv' and COLUMN_NAME='Host';")
   356  	c.Assert(len(result.Events()), Greater, 0)
   357  	result = tk3.MustQuery("select * from information_schema.STATISTICS where TABLE_NAME='blocks_priv' and COLUMN_NAME='Host';")
   358  	c.Assert(len(result.Events()), Greater, 0)
   359  }
   360  
   361  func (s *testschemaReplicantBlockSerialSuite) TestDataForBlockStatsField(c *C) {
   362  	s.dom.SetStatsUFIDelating(true)
   363  	oldExpiryTime := interlock.BlockStatsCacheExpiry
   364  	interlock.BlockStatsCacheExpiry = 0
   365  	defer func() { interlock.BlockStatsCacheExpiry = oldExpiryTime }()
   366  	do := s.dom
   367  	h := do.StatsHandle()
   368  	h.Clear()
   369  	is := do.SchemaReplicant()
   370  	tk := testkit.NewTestKit(c, s.causetstore)
   371  
   372  	tk.MustInterDirc("use test")
   373  	tk.MustInterDirc("drop causet if exists t")
   374  	tk.MustInterDirc("create causet t (c int, d int, e char(5), index idx(e))")
   375  	h.HandleDBSEvent(<-h.DBSEventCh())
   376  	tk.MustQuery("select block_rows, avg_row_length, data_length, index_length from information_schema.blocks where block_name='t'").Check(
   377  		testkit.Events("0 0 0 0"))
   378  	tk.MustInterDirc(`insert into t(c, d, e) values(1, 2, "c"), (2, 3, "d"), (3, 4, "e")`)
   379  	c.Assert(h.DumpStatsDeltaToKV(handle.DumpAll), IsNil)
   380  	c.Assert(h.UFIDelate(is), IsNil)
   381  	tk.MustQuery("select block_rows, avg_row_length, data_length, index_length from information_schema.blocks where block_name='t'").Check(
   382  		testkit.Events("3 18 54 6"))
   383  	tk.MustInterDirc(`insert into t(c, d, e) values(4, 5, "f")`)
   384  	c.Assert(h.DumpStatsDeltaToKV(handle.DumpAll), IsNil)
   385  	c.Assert(h.UFIDelate(is), IsNil)
   386  	tk.MustQuery("select block_rows, avg_row_length, data_length, index_length from information_schema.blocks where block_name='t'").Check(
   387  		testkit.Events("4 18 72 8"))
   388  	tk.MustInterDirc("delete from t where c >= 3")
   389  	c.Assert(h.DumpStatsDeltaToKV(handle.DumpAll), IsNil)
   390  	c.Assert(h.UFIDelate(is), IsNil)
   391  	tk.MustQuery("select block_rows, avg_row_length, data_length, index_length from information_schema.blocks where block_name='t'").Check(
   392  		testkit.Events("2 18 36 4"))
   393  	tk.MustInterDirc("delete from t where c=3")
   394  	c.Assert(h.DumpStatsDeltaToKV(handle.DumpAll), IsNil)
   395  	c.Assert(h.UFIDelate(is), IsNil)
   396  	tk.MustQuery("select block_rows, avg_row_length, data_length, index_length from information_schema.blocks where block_name='t'").Check(
   397  		testkit.Events("2 18 36 4"))
   398  
   399  	// Test partition causet.
   400  	tk.MustInterDirc("drop causet if exists t")
   401  	tk.MustInterDirc(`CREATE TABLE t (a int, b int, c varchar(5), primary key(a), index idx(c)) PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (6), PARTITION p1 VALUES LESS THAN (11), PARTITION p2 VALUES LESS THAN (16))`)
   402  	h.HandleDBSEvent(<-h.DBSEventCh())
   403  	tk.MustInterDirc(`insert into t(a, b, c) values(1, 2, "c"), (7, 3, "d"), (12, 4, "e")`)
   404  	c.Assert(h.DumpStatsDeltaToKV(handle.DumpAll), IsNil)
   405  	c.Assert(h.UFIDelate(is), IsNil)
   406  	tk.MustQuery("select block_rows, avg_row_length, data_length, index_length from information_schema.blocks where block_name='t'").Check(
   407  		testkit.Events("3 18 54 6"))
   408  }
   409  
   410  func (s *testschemaReplicantBlockSerialSuite) TestPartitionsBlock(c *C) {
   411  	s.dom.SetStatsUFIDelating(true)
   412  	oldExpiryTime := interlock.BlockStatsCacheExpiry
   413  	interlock.BlockStatsCacheExpiry = 0
   414  	defer func() { interlock.BlockStatsCacheExpiry = oldExpiryTime }()
   415  	do := s.dom
   416  	h := do.StatsHandle()
   417  	h.Clear()
   418  	is := do.SchemaReplicant()
   419  
   420  	tk := testkit.NewTestKit(c, s.causetstore)
   421  
   422  	tk.MustInterDirc("USE test;")
   423  	tk.MustInterDirc("DROP TABLE IF EXISTS `test_partitions`;")
   424  	tk.MustInterDirc(`CREATE TABLE test_partitions (a int, b int, c varchar(5), primary key(a), index idx(c)) PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (6), PARTITION p1 VALUES LESS THAN (11), PARTITION p2 VALUES LESS THAN (16));`)
   425  	err := h.HandleDBSEvent(<-h.DBSEventCh())
   426  	c.Assert(err, IsNil)
   427  	tk.MustInterDirc(`insert into test_partitions(a, b, c) values(1, 2, "c"), (7, 3, "d"), (12, 4, "e");`)
   428  
   429  	tk.MustQuery("select PARTITION_NAME, PARTITION_DESCRIPTION from information_schema.PARTITIONS where block_name='test_partitions';").Check(
   430  		testkit.Events("" +
   431  			"p0 6]\n" +
   432  			"[p1 11]\n" +
   433  			"[p2 16"))
   434  
   435  	tk.MustQuery("select block_rows, avg_row_length, data_length, index_length from information_schema.PARTITIONS where block_name='test_partitions';").Check(
   436  		testkit.Events("" +
   437  			"0 0 0 0]\n" +
   438  			"[0 0 0 0]\n" +
   439  			"[0 0 0 0"))
   440  	c.Assert(h.DumpStatsDeltaToKV(handle.DumpAll), IsNil)
   441  	c.Assert(h.UFIDelate(is), IsNil)
   442  	tk.MustQuery("select block_rows, avg_row_length, data_length, index_length from information_schema.PARTITIONS where block_name='test_partitions';").Check(
   443  		testkit.Events("" +
   444  			"1 18 18 2]\n" +
   445  			"[1 18 18 2]\n" +
   446  			"[1 18 18 2"))
   447  
   448  	// Test for causet has no partitions.
   449  	tk.MustInterDirc("DROP TABLE IF EXISTS `test_partitions_1`;")
   450  	tk.MustInterDirc(`CREATE TABLE test_partitions_1 (a int, b int, c varchar(5), primary key(a), index idx(c));`)
   451  	err = h.HandleDBSEvent(<-h.DBSEventCh())
   452  	c.Assert(err, IsNil)
   453  	tk.MustInterDirc(`insert into test_partitions_1(a, b, c) values(1, 2, "c"), (7, 3, "d"), (12, 4, "e");`)
   454  	c.Assert(h.DumpStatsDeltaToKV(handle.DumpAll), IsNil)
   455  	c.Assert(h.UFIDelate(is), IsNil)
   456  	tk.MustQuery("select PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH, INDEX_LENGTH from information_schema.PARTITIONS where block_name='test_partitions_1';").Check(
   457  		testkit.Events("<nil> 3 18 54 6"))
   458  
   459  	tk.MustInterDirc("DROP TABLE `test_partitions`;")
   460  
   461  	tk.MustInterDirc(`CREATE TABLE test_partitions1 (id int, b int, c varchar(5), primary key(id), index idx(c)) PARTITION BY RANGE COLUMNS(id) (PARTITION p0 VALUES LESS THAN (6), PARTITION p1 VALUES LESS THAN (11), PARTITION p2 VALUES LESS THAN (16));`)
   462  	tk.MustQuery("select PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION from information_schema.partitions where block_name = 'test_partitions1';").Check(testkit.Events("p0 RANGE COLUMNS id", "p1 RANGE COLUMNS id", "p2 RANGE COLUMNS id"))
   463  	tk.MustInterDirc("DROP TABLE test_partitions1")
   464  }
   465  
   466  func (s *testschemaReplicantBlockSuite) TestMetricBlocks(c *C) {
   467  	tk := testkit.NewTestKit(c, s.causetstore)
   468  	statistics.ClearHistoryJobs()
   469  	tk.MustInterDirc("use information_schema")
   470  	tk.MustQuery("select count(*) > 0 from `METRICS_TABLES`").Check(testkit.Events("1"))
   471  	tk.MustQuery("select * from `METRICS_TABLES` where block_name='milevadb_qps'").
   472  		Check(solitonutil.EventsWithSep("|", "milevadb_qps|sum(rate(milevadb_server_query_total{$LABEL_CONDITIONS}[$RANGE_DURATION])) by (result,type,instance)|instance,type,result|0|MilevaDB query processing numbers per second"))
   473  }
   474  
   475  func (s *testschemaReplicantBlockSuite) TestBlockConstraintsBlock(c *C) {
   476  	tk := testkit.NewTestKit(c, s.causetstore)
   477  	tk.MustQuery("select * from information_schema.TABLE_CONSTRAINTS where TABLE_NAME='gc_delete_range';").Check(testkit.Events("def allegrosql delete_range_index allegrosql gc_delete_range UNIQUE"))
   478  }
   479  
   480  func (s *testschemaReplicantBlockSuite) TestBlockStochastikVar(c *C) {
   481  	tk := testkit.NewTestKit(c, s.causetstore)
   482  	tk.MustQuery("select * from information_schema.SESSION_VARIABLES where VARIABLE_NAME='milevadb_retry_limit';").Check(testkit.Events("milevadb_retry_limit 10"))
   483  }
   484  
   485  func (s *testschemaReplicantBlockSuite) TestForAnalyzeStatus(c *C) {
   486  	tk := testkit.NewTestKit(c, s.causetstore)
   487  	statistics.ClearHistoryJobs()
   488  	tk.MustInterDirc("use test")
   489  	tk.MustInterDirc("drop causet if exists analyze_test")
   490  	tk.MustInterDirc("create causet analyze_test (a int, b int, index idx(a))")
   491  	tk.MustInterDirc("insert into analyze_test values (1,2),(3,4)")
   492  
   493  	tk.MustQuery("select distinct TABLE_NAME from information_schema.analyze_status where TABLE_NAME='analyze_test'").Check([][]interface{}{})
   494  	tk.MustInterDirc("analyze causet analyze_test")
   495  	tk.MustQuery("select distinct TABLE_NAME from information_schema.analyze_status where TABLE_NAME='analyze_test'").Check(testkit.Events("analyze_test"))
   496  
   497  	//test the privilege of new user for information_schema.analyze_status
   498  	tk.MustInterDirc("create user analyze_tester")
   499  	analyzeTester := testkit.NewTestKit(c, s.causetstore)
   500  	analyzeTester.MustInterDirc("use information_schema")
   501  	c.Assert(analyzeTester.Se.Auth(&auth.UserIdentity{
   502  		Username: "analyze_tester",
   503  		Hostname: "127.0.0.1",
   504  	}, nil, nil), IsTrue)
   505  	analyzeTester.MustQuery("show analyze status").Check([][]interface{}{})
   506  	analyzeTester.MustQuery("select * from information_schema.ANALYZE_STATUS;").Check([][]interface{}{})
   507  
   508  	//test the privilege of user with privilege of test.t1 for information_schema.analyze_status
   509  	tk.MustInterDirc("create causet t1 (a int, b int, index idx(a))")
   510  	tk.MustInterDirc("insert into t1 values (1,2),(3,4)")
   511  	tk.MustInterDirc("analyze causet t1")
   512  	tk.MustInterDirc("CREATE ROLE r_t1 ;")
   513  	tk.MustInterDirc("GRANT ALL PRIVILEGES ON test.t1 TO r_t1;")
   514  	tk.MustInterDirc("GRANT r_t1 TO analyze_tester;")
   515  	analyzeTester.MustInterDirc("set role r_t1")
   516  	resultT1 := tk.MustQuery("select * from information_schema.analyze_status where TABLE_NAME='t1'").Sort()
   517  	c.Assert(len(resultT1.Events()), Greater, 0)
   518  }
   519  
   520  func (s *testschemaReplicantBlockSerialSuite) TestForServersInfo(c *C) {
   521  	tk := testkit.NewTestKit(c, s.causetstore)
   522  	result := tk.MustQuery("select * from information_schema.MilevaDB_SERVERS_INFO")
   523  	c.Assert(len(result.Events()), Equals, 1)
   524  
   525  	info, err := infosync.GetServerInfo()
   526  	c.Assert(err, IsNil)
   527  	c.Assert(info, NotNil)
   528  	c.Assert(result.Events()[0][0], Equals, info.ID)
   529  	c.Assert(result.Events()[0][1], Equals, info.IP)
   530  	c.Assert(result.Events()[0][2], Equals, strconv.FormatInt(int64(info.Port), 10))
   531  	c.Assert(result.Events()[0][3], Equals, strconv.FormatInt(int64(info.StatusPort), 10))
   532  	c.Assert(result.Events()[0][4], Equals, info.Lease)
   533  	c.Assert(result.Events()[0][5], Equals, info.Version)
   534  	c.Assert(result.Events()[0][6], Equals, info.GitHash)
   535  	c.Assert(result.Events()[0][7], Equals, info.BinlogStatus)
   536  	c.Assert(result.Events()[0][8], Equals, stringutil.BuildStringFromLabels(info.Labels))
   537  }
   538  
   539  func (s *testschemaReplicantBlockSerialSuite) TestForBlockTiFlashReplica(c *C) {
   540  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount", `return(true)`), IsNil)
   541  	defer failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/mockTiFlashStoreCount")
   542  
   543  	tk := testkit.NewTestKit(c, s.causetstore)
   544  	statistics.ClearHistoryJobs()
   545  	tk.MustInterDirc("use test")
   546  	tk.MustInterDirc("drop causet if exists t")
   547  	tk.MustInterDirc("create causet t (a int, b int, index idx(a))")
   548  	tk.MustInterDirc("alter causet t set tiflash replica 2 location labels 'a','b';")
   549  	tk.MustQuery("select TABLE_SCHEMA,TABLE_NAME,REPLICA_COUNT,LOCATION_LABELS,AVAILABLE, PROGRESS from information_schema.tiflash_replica").Check(testkit.Events("test t 2 a,b 0 0"))
   550  	tbl, err := petri.GetPetri(tk.Se).SchemaReplicant().BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t"))
   551  	c.Assert(err, IsNil)
   552  	tbl.Meta().TiFlashReplica.Available = true
   553  	tk.MustQuery("select TABLE_SCHEMA,TABLE_NAME,REPLICA_COUNT,LOCATION_LABELS,AVAILABLE, PROGRESS from information_schema.tiflash_replica").Check(testkit.Events("test t 2 a,b 1 1"))
   554  }
   555  
   556  var _ = SerialSuites(&testschemaReplicantClusterBlockSuite{testschemaReplicantBlockSuiteBase: &testschemaReplicantBlockSuiteBase{}})
   557  
   558  type testschemaReplicantClusterBlockSuite struct {
   559  	*testschemaReplicantBlockSuiteBase
   560  	rpcserver  *grpc.Server
   561  	httpServer *httptest.Server
   562  	mockAddr   string
   563  	listenAddr string
   564  	startTime  time.Time
   565  }
   566  
   567  func (s *testschemaReplicantClusterBlockSuite) SetUpSuite(c *C) {
   568  	s.testschemaReplicantBlockSuiteBase.SetUpSuite(c)
   569  	s.rpcserver, s.listenAddr = s.setUpRPCService(c, "127.0.0.1:0")
   570  	s.httpServer, s.mockAddr = s.setUpMockFIDelHTTPServer()
   571  	s.startTime = time.Now()
   572  }
   573  
   574  func (s *testschemaReplicantClusterBlockSuite) setUpRPCService(c *C, addr string) (*grpc.Server, string) {
   575  	lis, err := net.Listen("tcp", addr)
   576  	c.Assert(err, IsNil)
   577  	// Fix issue 9836
   578  	sm := &mockStochastikManager{make(map[uint64]*soliton.ProcessInfo, 1)}
   579  	sm.processInfoMap[1] = &soliton.ProcessInfo{
   580  		ID:      1,
   581  		User:    "root",
   582  		Host:    "127.0.0.1",
   583  		Command: allegrosql.ComQuery,
   584  	}
   585  	srv := server.NewRPCServer(config.GetGlobalConfig(), s.dom, sm)
   586  	port := lis.Addr().(*net.TCPAddr).Port
   587  	addr = fmt.Sprintf("127.0.0.1:%d", port)
   588  	go func() {
   589  		err = srv.Serve(lis)
   590  		c.Assert(err, IsNil)
   591  	}()
   592  	config.UFIDelateGlobal(func(conf *config.Config) {
   593  		conf.Status.StatusPort = uint(port)
   594  	})
   595  	return srv, addr
   596  }
   597  
   598  func (s *testschemaReplicantClusterBlockSuite) setUpMockFIDelHTTPServer() (*httptest.Server, string) {
   599  	// mock FIDel http server
   600  	router := mux.NewRouter()
   601  	server := httptest.NewServer(router)
   602  	// mock causetstore stats stat
   603  	mockAddr := strings.TrimPrefix(server.URL, "http://")
   604  	router.Handle(FIDelapi.Stores, fn.Wrap(func() (*helper.StoresStat, error) {
   605  		return &helper.StoresStat{
   606  			Count: 1,
   607  			Stores: []helper.StoreStat{
   608  				{
   609  					CausetStore: helper.StoreBaseStat{
   610  						ID:             1,
   611  						Address:        "127.0.0.1:20160",
   612  						State:          0,
   613  						StateName:      "Up",
   614  						Version:        "4.0.0-alpha",
   615  						StatusAddress:  mockAddr,
   616  						GitHash:        "mock-einsteindb-githash",
   617  						StartTimestamp: s.startTime.Unix(),
   618  					},
   619  				},
   620  			},
   621  		}, nil
   622  	}))
   623  	// mock FIDel API
   624  	router.Handle(FIDelapi.ClusterVersion, fn.Wrap(func() (string, error) { return "4.0.0-alpha", nil }))
   625  	router.Handle(FIDelapi.Status, fn.Wrap(func() (interface{}, error) {
   626  		return struct {
   627  			GitHash        string `json:"git_hash"`
   628  			StartTimestamp int64  `json:"start_timestamp"`
   629  		}{
   630  			GitHash:        "mock-fidel-githash",
   631  			StartTimestamp: s.startTime.Unix(),
   632  		}, nil
   633  	}))
   634  	var mockConfig = func() (map[string]interface{}, error) {
   635  		configuration := map[string]interface{}{
   636  			"key1": "value1",
   637  			"key2": map[string]string{
   638  				"nest1": "n-value1",
   639  				"nest2": "n-value2",
   640  			},
   641  			"key3": map[string]interface{}{
   642  				"nest1": "n-value1",
   643  				"nest2": "n-value2",
   644  				"key4": map[string]string{
   645  					"nest3": "n-value4",
   646  					"nest4": "n-value5",
   647  				},
   648  			},
   649  		}
   650  		return configuration, nil
   651  	}
   652  	// FIDel config.
   653  	router.Handle(FIDelapi.Config, fn.Wrap(mockConfig))
   654  	// MilevaDB/EinsteinDB config.
   655  	router.Handle("/config", fn.Wrap(mockConfig))
   656  	// FIDel region.
   657  	router.Handle("/fidel/api/v1/stats/region", fn.Wrap(func() (*helper.FIDelRegionStats, error) {
   658  		return &helper.FIDelRegionStats{
   659  			Count:            1,
   660  			EmptyCount:       1,
   661  			StorageSize:      1,
   662  			StorageKeys:      1,
   663  			StoreLeaderCount: map[uint64]int{1: 1},
   664  			StorePeerCount:   map[uint64]int{1: 1},
   665  		}, nil
   666  	}))
   667  	return server, mockAddr
   668  }
   669  
   670  func (s *testschemaReplicantClusterBlockSuite) TearDownSuite(c *C) {
   671  	if s.rpcserver != nil {
   672  		s.rpcserver.Stop()
   673  		s.rpcserver = nil
   674  	}
   675  	if s.httpServer != nil {
   676  		s.httpServer.Close()
   677  	}
   678  	s.testschemaReplicantBlockSuiteBase.TearDownSuite(c)
   679  }
   680  
   681  type mockStochastikManager struct {
   682  	processInfoMap map[uint64]*soliton.ProcessInfo
   683  }
   684  
   685  func (sm *mockStochastikManager) ShowProcessList() map[uint64]*soliton.ProcessInfo {
   686  	return sm.processInfoMap
   687  }
   688  
   689  func (sm *mockStochastikManager) GetProcessInfo(id uint64) (*soliton.ProcessInfo, bool) {
   690  	rs, ok := sm.processInfoMap[id]
   691  	return rs, ok
   692  }
   693  
   694  func (sm *mockStochastikManager) Kill(connectionID uint64, query bool) {}
   695  
   696  func (sm *mockStochastikManager) UFIDelateTLSConfig(cfg *tls.Config) {}
   697  
   698  type mockStore struct {
   699  	einsteindb.CausetStorage
   700  	host string
   701  }
   702  
   703  func (s *mockStore) EtcdAddrs() ([]string, error) { return []string{s.host}, nil }
   704  func (s *mockStore) TLSConfig() *tls.Config       { panic("not implemented") }
   705  func (s *mockStore) StartGCWorker() error         { panic("not implemented") }
   706  
   707  func (s *testschemaReplicantClusterBlockSuite) TestMilevaDBClusterInfo(c *C) {
   708  	mockAddr := s.mockAddr
   709  	causetstore := &mockStore{
   710  		s.causetstore.(einsteindb.CausetStorage),
   711  		mockAddr,
   712  	}
   713  
   714  	// information_schema.cluster_info
   715  	tk := testkit.NewTestKit(c, causetstore)
   716  	milevadbStatusAddr := fmt.Sprintf(":%d", config.GetGlobalConfig().Status.StatusPort)
   717  	event := func(defcaus ...string) string { return strings.Join(defcaus, " ") }
   718  	tk.MustQuery("select type, instance, status_address, version, git_hash from information_schema.cluster_info").Check(testkit.Events(
   719  		event("milevadb", ":4000", milevadbStatusAddr, "None", "None"),
   720  		event("fidel", mockAddr, mockAddr, "4.0.0-alpha", "mock-fidel-githash"),
   721  		event("einsteindb", "store1", "", "", ""),
   722  	))
   723  	startTime := s.startTime.Format(time.RFC3339)
   724  	tk.MustQuery("select type, instance, start_time from information_schema.cluster_info where type != 'milevadb'").Check(testkit.Events(
   725  		event("fidel", mockAddr, startTime),
   726  		event("einsteindb", "store1", ""),
   727  	))
   728  
   729  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/mockStoreTombstone", `return(true)`), IsNil)
   730  	tk.MustQuery("select type, instance, start_time from information_schema.cluster_info where type = 'einsteindb'").Check(testkit.Events())
   731  	c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/mockStoreTombstone"), IsNil)
   732  
   733  	// information_schema.cluster_config
   734  	instances := []string{
   735  		"fidel,127.0.0.1:11080," + mockAddr + ",mock-version,mock-githash",
   736  		"milevadb,127.0.0.1:11080," + mockAddr + ",mock-version,mock-githash",
   737  		"einsteindb,127.0.0.1:11080," + mockAddr + ",mock-version,mock-githash",
   738  	}
   739  	fpExpr := `return("` + strings.Join(instances, ";") + `")`
   740  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/schemareplicant/mockClusterInfo", fpExpr), IsNil)
   741  	defer func() {
   742  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/schemareplicant/mockClusterInfo"), IsNil)
   743  	}()
   744  	tk.MustQuery("select * from information_schema.cluster_config").Check(testkit.Events(
   745  		"fidel 127.0.0.1:11080 key1 value1",
   746  		"fidel 127.0.0.1:11080 key2.nest1 n-value1",
   747  		"fidel 127.0.0.1:11080 key2.nest2 n-value2",
   748  		"fidel 127.0.0.1:11080 key3.key4.nest3 n-value4",
   749  		"fidel 127.0.0.1:11080 key3.key4.nest4 n-value5",
   750  		"fidel 127.0.0.1:11080 key3.nest1 n-value1",
   751  		"fidel 127.0.0.1:11080 key3.nest2 n-value2",
   752  		"milevadb 127.0.0.1:11080 key1 value1",
   753  		"milevadb 127.0.0.1:11080 key2.nest1 n-value1",
   754  		"milevadb 127.0.0.1:11080 key2.nest2 n-value2",
   755  		"milevadb 127.0.0.1:11080 key3.key4.nest3 n-value4",
   756  		"milevadb 127.0.0.1:11080 key3.key4.nest4 n-value5",
   757  		"milevadb 127.0.0.1:11080 key3.nest1 n-value1",
   758  		"milevadb 127.0.0.1:11080 key3.nest2 n-value2",
   759  		"einsteindb 127.0.0.1:11080 key1 value1",
   760  		"einsteindb 127.0.0.1:11080 key2.nest1 n-value1",
   761  		"einsteindb 127.0.0.1:11080 key2.nest2 n-value2",
   762  		"einsteindb 127.0.0.1:11080 key3.key4.nest3 n-value4",
   763  		"einsteindb 127.0.0.1:11080 key3.key4.nest4 n-value5",
   764  		"einsteindb 127.0.0.1:11080 key3.nest1 n-value1",
   765  		"einsteindb 127.0.0.1:11080 key3.nest2 n-value2",
   766  	))
   767  	tk.MustQuery("select TYPE, `KEY`, VALUE from information_schema.cluster_config where `key`='key3.key4.nest4' order by type").Check(testkit.Events(
   768  		"fidel key3.key4.nest4 n-value5",
   769  		"milevadb key3.key4.nest4 n-value5",
   770  		"einsteindb key3.key4.nest4 n-value5",
   771  	))
   772  }
   773  
   774  func (s *testschemaReplicantClusterBlockSuite) TestBlockStorageStats(c *C) {
   775  	tk := testkit.NewTestKit(c, s.causetstore)
   776  	err := tk.QueryToErr("select * from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'test'")
   777  	c.Assert(err.Error(), Equals, "fidel unavailable")
   778  	mockAddr := s.mockAddr
   779  	causetstore := &mockStore{
   780  		s.causetstore.(einsteindb.CausetStorage),
   781  		mockAddr,
   782  	}
   783  
   784  	// Test information_schema.TABLE_STORAGE_STATS.
   785  	tk = testkit.NewTestKit(c, causetstore)
   786  
   787  	// Test not set the schemaReplicant.
   788  	err = tk.QueryToErr("select * from information_schema.TABLE_STORAGE_STATS")
   789  	c.Assert(err, NotNil)
   790  	c.Assert(err.Error(), Equals, "Please specify the 'block_schema'")
   791  
   792  	// Test it would get null set when get the sys schemaReplicant.
   793  	tk.MustQuery("select TABLE_NAME from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'information_schema';").Check([][]interface{}{})
   794  	tk.MustQuery("select TABLE_NAME from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'allegrosql';").Check([][]interface{}{})
   795  	tk.MustQuery("select TABLE_NAME from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA in ('allegrosql', 'metrics_schema');").Check([][]interface{}{})
   796  	tk.MustQuery("select TABLE_NAME from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'information_schema' and TABLE_NAME='schemata';").Check([][]interface{}{})
   797  
   798  	tk.MustInterDirc("use test")
   799  	tk.MustInterDirc("drop causet if exists t")
   800  	tk.MustInterDirc("create causet t (a int, b int, index idx(a))")
   801  	tk.MustQuery("select TABLE_NAME, TABLE_SIZE from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'test' and TABLE_NAME='t';").Check(testkit.Events("t 1"))
   802  
   803  	tk.MustInterDirc("create causet t1 (a int, b int, index idx(a))")
   804  	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.Events(
   805  		"t 1",
   806  		"t1 1",
   807  	))
   808  	tk.MustQuery("select TABLE_SCHEMA, sum(TABLE_SIZE) from information_schema.TABLE_STORAGE_STATS where TABLE_SCHEMA = 'test' group by TABLE_SCHEMA;").Check(testkit.Events(
   809  		"test 2",
   810  	))
   811  }
   812  
   813  func (s *testschemaReplicantBlockSuite) TestSequences(c *C) {
   814  	tk := testkit.NewTestKit(c, s.causetstore)
   815  	tk.MustInterDirc("CREATE SEQUENCE test.seq maxvalue 10000000")
   816  	tk.MustQuery("SELECT * FROM information_schema.sequences WHERE sequence_schema='test' AND sequence_name='seq'").Check(testkit.Events("def test seq 1 1000 0 1 10000000 1 1 "))
   817  	tk.MustInterDirc("DROP SEQUENCE test.seq")
   818  	tk.MustInterDirc("CREATE SEQUENCE test.seq start = -1 minvalue -1 maxvalue 10 increment 1 cache 10")
   819  	tk.MustQuery("SELECT * FROM information_schema.sequences WHERE sequence_schema='test' AND sequence_name='seq'").Check(testkit.Events("def test seq 1 10 0 1 10 -1 -1 "))
   820  	tk.MustInterDirc("CREATE SEQUENCE test.seq2 start = -9 minvalue -10 maxvalue 10 increment -1 cache 15")
   821  	tk.MustQuery("SELECT * FROM information_schema.sequences WHERE sequence_schema='test' AND sequence_name='seq2'").Check(testkit.Events("def test seq2 1 15 0 -1 10 -10 -9 "))
   822  }
   823  
   824  func (s *testschemaReplicantBlockSuite) TestTiFlashSystemBlocks(c *C) {
   825  	tk := testkit.NewTestKit(c, s.causetstore)
   826  	err := tk.QueryToErr("select * from information_schema.TIFLASH_TABLES;")
   827  	c.Assert(err.Error(), Equals, "Etcd addrs not found")
   828  	err = tk.QueryToErr("select * from information_schema.TIFLASH_SEGMENTS;")
   829  	c.Assert(err.Error(), Equals, "Etcd addrs not found")
   830  }
   831  
   832  func (s *testschemaReplicantBlockSuite) TestBlocksPKType(c *C) {
   833  	tk := testkit.NewTestKitWithInit(c, s.causetstore)
   834  	tk.MustInterDirc("create causet t_int (a int primary key, b int)")
   835  	tk.MustQuery("SELECT MilevaDB_PK_TYPE FROM information_schema.blocks where block_schema = 'test' and block_name = 't_int'").Check(testkit.Events("INT CLUSTERED"))
   836  	tk.MustInterDirc("set @@milevadb_enable_clustered_index = 0")
   837  	tk.MustInterDirc("create causet t_implicit (a varchar(64) primary key, b int)")
   838  	tk.MustQuery("SELECT MilevaDB_PK_TYPE FROM information_schema.blocks where block_schema = 'test' and block_name = 't_implicit'").Check(testkit.Events("NON-CLUSTERED"))
   839  	tk.MustInterDirc("set @@milevadb_enable_clustered_index = 1")
   840  	tk.MustInterDirc("create causet t_common (a varchar(64) primary key, b int)")
   841  	tk.MustQuery("SELECT MilevaDB_PK_TYPE FROM information_schema.blocks where block_schema = 'test' and block_name = 't_common'").Check(testkit.Events("COMMON CLUSTERED"))
   842  	tk.MustQuery("SELECT MilevaDB_PK_TYPE FROM information_schema.blocks where block_schema = 'INFORMATION_SCHEMA' and block_name = 'TABLES'").Check(testkit.Events("NON-CLUSTERED"))
   843  }