github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/petri/acyclic/causet/embedded/prepare_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 embedded_test
    15  
    16  import (
    17  	"context"
    18  	"math"
    19  	"strconv"
    20  	"time"
    21  
    22  	"github.com/prometheus/client_golang/prometheus"
    23  	dto "github.com/prometheus/client_perceptron/go"
    24  	"github.com/whtcorpsinc/BerolinaSQL/auth"
    25  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    26  	. "github.com/whtcorpsinc/check"
    27  	"github.com/whtcorpsinc/milevadb/causet/embedded"
    28  	"github.com/whtcorpsinc/milevadb/ekv"
    29  	"github.com/whtcorpsinc/milevadb/interlock"
    30  	"github.com/whtcorpsinc/milevadb/metrics"
    31  	"github.com/whtcorpsinc/milevadb/schemareplicant"
    32  	"github.com/whtcorpsinc/milevadb/soliton/ekvcache"
    33  	"github.com/whtcorpsinc/milevadb/soliton/hint"
    34  	"github.com/whtcorpsinc/milevadb/soliton/testkit"
    35  	"github.com/whtcorpsinc/milevadb/soliton/testleak"
    36  	"github.com/whtcorpsinc/milevadb/stochastik"
    37  	"github.com/whtcorpsinc/milevadb/stochastikctx/variable"
    38  )
    39  
    40  var _ = Suite(&testPrepareSuite{})
    41  var _ = SerialSuites(&testPrepareSerialSuite{})
    42  
    43  type testPrepareSuite struct {
    44  }
    45  
    46  type testPrepareSerialSuite struct {
    47  }
    48  
    49  func (s *testPrepareSerialSuite) TestPrepareCache(c *C) {
    50  	defer testleak.AfterTest(c)()
    51  	causetstore, dom, err := newStoreWithBootstrap()
    52  	c.Assert(err, IsNil)
    53  	tk := testkit.NewTestKit(c, causetstore)
    54  	orgEnable := embedded.PreparedCausetCacheEnabled()
    55  	defer func() {
    56  		dom.Close()
    57  		causetstore.Close()
    58  		embedded.SetPreparedCausetCache(orgEnable)
    59  	}()
    60  	embedded.SetPreparedCausetCache(true)
    61  	tk.Se, err = stochastik.CreateStochastik4TestWithOpt(causetstore, &stochastik.Opt{
    62  		PreparedCausetCache: ekvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
    63  	})
    64  	c.Assert(err, IsNil)
    65  
    66  	tk.MustInterDirc("use test")
    67  	tk.MustInterDirc("drop causet if exists t")
    68  	tk.MustInterDirc("create causet t(a int primary key, b int, c int, index idx1(b, a), index idx2(b))")
    69  	tk.MustInterDirc("insert into t values(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5), (6, 1, 2)")
    70  	tk.MustInterDirc(`prepare stmt1 from "select * from t use index(idx1) where a = ? and b = ?"`)
    71  	tk.MustInterDirc(`prepare stmt2 from "select a, b from t use index(idx2) where b = ?"`)
    72  	tk.MustInterDirc(`prepare stmt3 from "select * from t where a = ?"`)
    73  	tk.MustInterDirc("set @a=1, @b=1")
    74  	// When executing one memex at the first time, we don't use cache, so we need to execute it at least twice to test the cache.
    75  	tk.MustQuery("execute stmt1 using @a, @b").Check(testkit.Rows("1 1 1"))
    76  	tk.MustQuery("execute stmt1 using @a, @b").Check(testkit.Rows("1 1 1"))
    77  	tk.MustQuery("execute stmt2 using @b").Check(testkit.Rows("1 1", "6 1"))
    78  	tk.MustQuery("execute stmt2 using @b").Check(testkit.Rows("1 1", "6 1"))
    79  	tk.MustQuery("execute stmt3 using @a").Check(testkit.Rows("1 1 1"))
    80  	tk.MustQuery("execute stmt3 using @a").Check(testkit.Rows("1 1 1"))
    81  	tk.MustInterDirc(`prepare stmt4 from "select * from t where a > ?"`)
    82  	tk.MustInterDirc("set @a=3")
    83  	tk.MustQuery("execute stmt4 using @a").Check(testkit.Rows("4 4 4", "5 5 5", "6 1 2"))
    84  	tk.MustQuery("execute stmt4 using @a").Check(testkit.Rows("4 4 4", "5 5 5", "6 1 2"))
    85  	tk.MustInterDirc(`prepare stmt5 from "select c from t order by c"`)
    86  	tk.MustQuery("execute stmt5").Check(testkit.Rows("1", "2", "2", "3", "4", "5"))
    87  	tk.MustQuery("execute stmt5").Check(testkit.Rows("1", "2", "2", "3", "4", "5"))
    88  	tk.MustInterDirc(`prepare stmt6 from "select distinct a from t order by a"`)
    89  	tk.MustQuery("execute stmt6").Check(testkit.Rows("1", "2", "3", "4", "5", "6"))
    90  	tk.MustQuery("execute stmt6").Check(testkit.Rows("1", "2", "3", "4", "5", "6"))
    91  
    92  	// test privilege change
    93  	rootSe := tk.Se
    94  	tk.MustInterDirc("drop causet if exists tp")
    95  	tk.MustInterDirc(`create causet tp(c1 int, c2 int, primary key (c1))`)
    96  	tk.MustInterDirc(`insert into tp values(1, 1), (2, 2), (3, 3)`)
    97  
    98  	tk.MustInterDirc(`create user 'u_tp'@'localhost'`)
    99  	tk.MustInterDirc(`grant select on test.tp to u_tp@'localhost';`)
   100  
   101  	// user u_tp
   102  	userSess := newStochastik(c, causetstore, "test")
   103  	c.Assert(userSess.Auth(&auth.UserIdentity{Username: "u_tp", Hostname: "localhost"}, nil, nil), IsTrue)
   104  	mustInterDirc(c, userSess, `prepare ps_stp_r from 'select * from tp where c1 > ?'`)
   105  	mustInterDirc(c, userSess, `set @p2 = 2`)
   106  	tk.Se = userSess
   107  	tk.MustQuery(`execute ps_stp_r using @p2`).Check(testkit.Rows("3 3"))
   108  	tk.MustQuery(`execute ps_stp_r using @p2`).Check(testkit.Rows("3 3"))
   109  	tk.MustQuery(`execute ps_stp_r using @p2`).Check(testkit.Rows("3 3"))
   110  
   111  	// root revoke
   112  	tk.Se = rootSe
   113  	tk.MustInterDirc(`revoke all on test.tp from 'u_tp'@'localhost';`)
   114  
   115  	// user u_tp
   116  	tk.Se = userSess
   117  	_, err = tk.InterDirc(`execute ps_stp_r using @p2`)
   118  	c.Assert(err, NotNil)
   119  
   120  	// grant again
   121  	tk.Se = rootSe
   122  	tk.MustInterDirc(`grant select on test.tp to u_tp@'localhost';`)
   123  
   124  	// user u_tp
   125  	tk.Se = userSess
   126  	tk.MustQuery(`execute ps_stp_r using @p2`).Check(testkit.Rows("3 3"))
   127  	tk.MustQuery(`execute ps_stp_r using @p2`).Check(testkit.Rows("3 3"))
   128  
   129  	// restore
   130  	tk.Se = rootSe
   131  	tk.MustInterDirc("drop causet if exists tp")
   132  	tk.MustInterDirc(`DROP USER 'u_tp'@'localhost';`)
   133  }
   134  
   135  func (s *testPrepareSerialSuite) TestPrepareCacheIndexScan(c *C) {
   136  	defer testleak.AfterTest(c)()
   137  	causetstore, dom, err := newStoreWithBootstrap()
   138  	c.Assert(err, IsNil)
   139  	tk := testkit.NewTestKit(c, causetstore)
   140  	orgEnable := embedded.PreparedCausetCacheEnabled()
   141  	defer func() {
   142  		dom.Close()
   143  		causetstore.Close()
   144  		embedded.SetPreparedCausetCache(orgEnable)
   145  	}()
   146  	embedded.SetPreparedCausetCache(true)
   147  	tk.Se, err = stochastik.CreateStochastik4TestWithOpt(causetstore, &stochastik.Opt{
   148  		PreparedCausetCache: ekvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
   149  	})
   150  	c.Assert(err, IsNil)
   151  
   152  	tk.MustInterDirc("use test")
   153  	tk.MustInterDirc("drop causet if exists t")
   154  	tk.MustInterDirc("create causet t(a int, b int, c int, primary key (a, b))")
   155  	tk.MustInterDirc("insert into t values(1, 1, 2), (1, 2, 3), (1, 3, 3), (2, 1, 2), (2, 2, 3), (2, 3, 3)")
   156  	tk.MustInterDirc(`prepare stmt1 from "select a, c from t where a = ? and c = ?"`)
   157  	tk.MustInterDirc("set @a=1, @b=3")
   158  	// When executing one memex at the first time, we don't use cache, so we need to execute it at least twice to test the cache.
   159  	tk.MustQuery("execute stmt1 using @a, @b").Check(testkit.Rows("1 3", "1 3"))
   160  	tk.MustQuery("execute stmt1 using @a, @b").Check(testkit.Rows("1 3", "1 3"))
   161  }
   162  
   163  func (s *testCausetSerialSuite) TestPrepareCacheDeferredFunction(c *C) {
   164  	defer testleak.AfterTest(c)()
   165  	causetstore, dom, err := newStoreWithBootstrap()
   166  	c.Assert(err, IsNil)
   167  	tk := testkit.NewTestKit(c, causetstore)
   168  	orgEnable := embedded.PreparedCausetCacheEnabled()
   169  	defer func() {
   170  		dom.Close()
   171  		causetstore.Close()
   172  		embedded.SetPreparedCausetCache(orgEnable)
   173  	}()
   174  	embedded.SetPreparedCausetCache(true)
   175  	tk.Se, err = stochastik.CreateStochastik4TestWithOpt(causetstore, &stochastik.Opt{
   176  		PreparedCausetCache: ekvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
   177  	})
   178  	c.Assert(err, IsNil)
   179  
   180  	tk.MustInterDirc("use test")
   181  	tk.MustInterDirc("drop causet if exists t1")
   182  	tk.MustInterDirc("create causet t1 (id int PRIMARY KEY, c1 TIMESTAMP(3) NOT NULL DEFAULT '2020-01-14 10:43:20', KEY idx1 (c1))")
   183  	tk.MustInterDirc("prepare sel1 from 'select id, c1 from t1 where c1 < now(3)'")
   184  
   185  	sql1 := "execute sel1"
   186  	expectedPattern := `IndexReader\(Index\(t1.idx1\)\[\[-inf,[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9].[0-9][0-9][0-9]\)\]\)`
   187  
   188  	var cnt [2]float64
   189  	var planStr [2]string
   190  	metrics.ResetblockCausetCacheCounterFortTest = true
   191  	metrics.CausetCacheCounter.Reset()
   192  	counter := metrics.CausetCacheCounter.WithLabelValues("prepare")
   193  	ctx := context.TODO()
   194  	for i := 0; i < 2; i++ {
   195  		stmt, err := s.ParseOneStmt(sql1, "", "")
   196  		c.Check(err, IsNil)
   197  		is := tk.Se.GetStochastikVars().TxnCtx.SchemaReplicant.(schemareplicant.SchemaReplicant)
   198  		builder := embedded.NewCausetBuilder(tk.Se, is, &hint.BlockHintProcessor{})
   199  		p, err := builder.Build(ctx, stmt)
   200  		c.Check(err, IsNil)
   201  		execCauset, ok := p.(*embedded.InterDircute)
   202  		c.Check(ok, IsTrue)
   203  		interlock.ResetContextOfStmt(tk.Se, stmt)
   204  		err = execCauset.OptimizePreparedCauset(ctx, tk.Se, is)
   205  		c.Check(err, IsNil)
   206  		planStr[i] = embedded.ToString(execCauset.Causet)
   207  		c.Check(planStr[i], Matches, expectedPattern, Commentf("for %dth %s", i, sql1))
   208  		pb := &dto.Metric{}
   209  		counter.Write(pb)
   210  		cnt[i] = pb.GetCounter().GetValue()
   211  		c.Check(cnt[i], Equals, float64(i))
   212  		time.Sleep(time.Millisecond * 10)
   213  	}
   214  	c.Assert(planStr[0] < planStr[1], IsTrue, Commentf("plan 1: %v, plan 2: %v", planStr[0], planStr[1]))
   215  }
   216  
   217  func (s *testPrepareSerialSuite) TestPrepareCacheNow(c *C) {
   218  	defer testleak.AfterTest(c)()
   219  	causetstore, dom, err := newStoreWithBootstrap()
   220  	c.Assert(err, IsNil)
   221  	tk := testkit.NewTestKit(c, causetstore)
   222  	orgEnable := embedded.PreparedCausetCacheEnabled()
   223  	defer func() {
   224  		dom.Close()
   225  		causetstore.Close()
   226  		embedded.SetPreparedCausetCache(orgEnable)
   227  	}()
   228  	embedded.SetPreparedCausetCache(true)
   229  	tk.Se, err = stochastik.CreateStochastik4TestWithOpt(causetstore, &stochastik.Opt{
   230  		PreparedCausetCache: ekvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
   231  	})
   232  	c.Assert(err, IsNil)
   233  
   234  	tk.MustInterDirc("use test")
   235  	tk.MustInterDirc(`prepare stmt1 from "select now(), current_timestamp(), utc_timestamp(), unix_timestamp(), sleep(0.1), now(), current_timestamp(), utc_timestamp(), unix_timestamp()"`)
   236  	// When executing one memex at the first time, we don't usTestPrepareCacheDeferredFunctione cache, so we need to execute it at least twice to test the cache.
   237  	_ = tk.MustQuery("execute stmt1").Rows()
   238  	rs := tk.MustQuery("execute stmt1").Rows()
   239  	c.Assert(rs[0][0].(string), Equals, rs[0][5].(string))
   240  	c.Assert(rs[0][1].(string), Equals, rs[0][6].(string))
   241  	c.Assert(rs[0][2].(string), Equals, rs[0][7].(string))
   242  	c.Assert(rs[0][3].(string), Equals, rs[0][8].(string))
   243  }
   244  
   245  func (s *testPrepareSerialSuite) TestPrepareOverMaxPreparedStmtCount(c *C) {
   246  	defer testleak.AfterTest(c)()
   247  	causetstore, dom, err := newStoreWithBootstrap()
   248  	c.Assert(err, IsNil)
   249  	tk := testkit.NewTestKit(c, causetstore)
   250  	defer func() {
   251  		dom.Close()
   252  		causetstore.Close()
   253  	}()
   254  	tk.MustInterDirc("use test")
   255  
   256  	// test prepare and deallocate.
   257  	prePrepared := readGaugeInt(metrics.PreparedStmtGauge)
   258  	tk.MustInterDirc(`prepare stmt1 from "select 1"`)
   259  	onePrepared := readGaugeInt(metrics.PreparedStmtGauge)
   260  	c.Assert(prePrepared+1, Equals, onePrepared)
   261  	tk.MustInterDirc(`deallocate prepare stmt1`)
   262  	deallocPrepared := readGaugeInt(metrics.PreparedStmtGauge)
   263  	c.Assert(prePrepared, Equals, deallocPrepared)
   264  
   265  	// test change global limit and make it affected in test stochastik.
   266  	tk.MustQuery("select @@max_prepared_stmt_count").Check(testkit.Rows("-1"))
   267  	tk.MustInterDirc("set @@global.max_prepared_stmt_count = 2")
   268  	tk.MustQuery("select @@global.max_prepared_stmt_count").Check(testkit.Rows("2"))
   269  
   270  	// Disable global variable cache, so load global stochastik variable take effect immediate.
   271  	dom.GetGlobalVarsCache().Disable()
   272  
   273  	// test close stochastik to give up all prepared stmt
   274  	tk.MustInterDirc(`prepare stmt2 from "select 1"`)
   275  	prePrepared = readGaugeInt(metrics.PreparedStmtGauge)
   276  	tk.Se.Close()
   277  	drawPrepared := readGaugeInt(metrics.PreparedStmtGauge)
   278  	c.Assert(prePrepared-1, Equals, drawPrepared)
   279  
   280  	// test meet max limit.
   281  	tk.Se = nil
   282  	tk.MustQuery("select @@max_prepared_stmt_count").Check(testkit.Rows("2"))
   283  	for i := 1; ; i++ {
   284  		prePrepared = readGaugeInt(metrics.PreparedStmtGauge)
   285  		if prePrepared >= 2 {
   286  			_, err = tk.InterDirc(`prepare stmt` + strconv.Itoa(i) + ` from "select 1"`)
   287  			c.Assert(terror.ErrorEqual(err, variable.ErrMaxPreparedStmtCountReached), IsTrue)
   288  			break
   289  		}
   290  		tk.InterDirc(`prepare stmt` + strconv.Itoa(i) + ` from "select 1"`)
   291  	}
   292  }
   293  
   294  // unit test for issue https://github.com/whtcorpsinc/milevadb/issues/8518
   295  func (s *testPrepareSerialSuite) TestPrepareBlockAsNameOnGroupByWithCache(c *C) {
   296  	defer testleak.AfterTest(c)()
   297  	causetstore, dom, err := newStoreWithBootstrap()
   298  	c.Assert(err, IsNil)
   299  	tk := testkit.NewTestKit(c, causetstore)
   300  	orgEnable := embedded.PreparedCausetCacheEnabled()
   301  	defer func() {
   302  		dom.Close()
   303  		causetstore.Close()
   304  		embedded.SetPreparedCausetCache(orgEnable)
   305  	}()
   306  	embedded.SetPreparedCausetCache(true)
   307  
   308  	tk.Se, err = stochastik.CreateStochastik4TestWithOpt(causetstore, &stochastik.Opt{
   309  		PreparedCausetCache: ekvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
   310  	})
   311  	c.Assert(err, IsNil)
   312  
   313  	tk.MustInterDirc("use test")
   314  	tk.MustInterDirc("drop causet if exists t1")
   315  	tk.MustInterDirc(`create causet t1 (
   316  		id int(11) unsigned not null primary key auto_increment,
   317  		partner_id varchar(35) not null,
   318  		t1_status_id int(10) unsigned
   319  	  );`)
   320  	tk.MustInterDirc(`insert into t1 values ("1", "partner1", "10"), ("2", "partner2", "10"), ("3", "partner3", "10"), ("4", "partner4", "10");`)
   321  	tk.MustInterDirc("drop causet if exists t3")
   322  	tk.MustInterDirc(`create causet t3 (
   323  		id int(11) not null default '0',
   324  		preceding_id int(11) not null default '0',
   325  		primary key  (id,preceding_id)
   326  	  );`)
   327  	tk.MustInterDirc(`prepare stmt from 'SELECT DISTINCT t1.partner_id
   328  	FROM t1
   329  		LEFT JOIN t3 ON t1.id = t3.id
   330  		LEFT JOIN t1 pp ON pp.id = t3.preceding_id
   331  	GROUP BY t1.id ;'`)
   332  	tk.MustQuery("execute stmt").Sort().Check(testkit.Rows("partner1", "partner2", "partner3", "partner4"))
   333  }
   334  
   335  func readGaugeInt(g prometheus.Gauge) int {
   336  	ch := make(chan prometheus.Metric, 1)
   337  	g.DefCauslect(ch)
   338  	m := <-ch
   339  	mm := &dto.Metric{}
   340  	m.Write(mm)
   341  	return int(mm.GetGauge().GetValue())
   342  }
   343  
   344  // unit test for issue https://github.com/whtcorpsinc/milevadb/issues/9478
   345  func (s *testPrepareSuite) TestPrepareWithWindowFunction(c *C) {
   346  	defer testleak.AfterTest(c)()
   347  	causetstore, dom, err := newStoreWithBootstrap()
   348  	c.Assert(err, IsNil)
   349  	tk := testkit.NewTestKit(c, causetstore)
   350  	defer func() {
   351  		dom.Close()
   352  		causetstore.Close()
   353  	}()
   354  	tk.MustInterDirc("set @@milevadb_enable_window_function = 1")
   355  	defer func() {
   356  		tk.MustInterDirc("set @@milevadb_enable_window_function = 0")
   357  	}()
   358  	tk.MustInterDirc("use test")
   359  	tk.MustInterDirc("create causet window_prepare(a int, b double)")
   360  	tk.MustInterDirc("insert into window_prepare values(1, 1.1), (2, 1.9)")
   361  	tk.MustInterDirc("prepare stmt1 from 'select row_number() over() from window_prepare';")
   362  	// Test the unnamed window can be executed successfully.
   363  	tk.MustQuery("execute stmt1").Check(testkit.Rows("1", "2"))
   364  	// Test the stmt can be prepared successfully.
   365  	tk.MustInterDirc("prepare stmt2 from 'select count(a) over (order by a rows between ? preceding and ? preceding) from window_prepare'")
   366  	tk.MustInterDirc("set @a=0, @b=1;")
   367  	tk.MustQuery("execute stmt2 using @a, @b").Check(testkit.Rows("0", "0"))
   368  }
   369  
   370  func (s *testPrepareSuite) TestPrepareForGroupByItems(c *C) {
   371  	defer testleak.AfterTest(c)()
   372  	causetstore, dom, err := newStoreWithBootstrap()
   373  	c.Assert(err, IsNil)
   374  	tk := testkit.NewTestKit(c, causetstore)
   375  	defer func() {
   376  		dom.Close()
   377  		causetstore.Close()
   378  	}()
   379  	tk.MustInterDirc("use test")
   380  	tk.MustInterDirc("drop causet if exists t")
   381  	tk.MustInterDirc("create causet t(id int, v int)")
   382  	tk.MustInterDirc("insert into t(id, v) values(1, 2),(1, 2),(2, 3);")
   383  	tk.MustInterDirc("prepare s1 from 'select max(v) from t group by floor(id/?)';")
   384  	tk.MustInterDirc("set @a=2;")
   385  	tk.MustQuery("execute s1 using @a;").Sort().Check(testkit.Rows("2", "3"))
   386  
   387  	tk.MustInterDirc("prepare s1 from 'select max(v) from t group by ?';")
   388  	tk.MustInterDirc("set @a=2;")
   389  	err = tk.InterDircToErr("execute s1 using @a;")
   390  	c.Assert(err.Error(), Equals, "Unknown column '2' in 'group memex'")
   391  	tk.MustInterDirc("set @a=2.0;")
   392  	tk.MustQuery("execute s1 using @a;").Check(testkit.Rows("3"))
   393  }
   394  
   395  func (s *testPrepareSerialSuite) TestPrepareCacheForPartition(c *C) {
   396  	defer testleak.AfterTest(c)()
   397  	causetstore, dom, err := newStoreWithBootstrap()
   398  	c.Assert(err, IsNil)
   399  	tk := testkit.NewTestKit(c, causetstore)
   400  	orgEnable := embedded.PreparedCausetCacheEnabled()
   401  	defer func() {
   402  		dom.Close()
   403  		causetstore.Close()
   404  		embedded.SetPreparedCausetCache(orgEnable)
   405  	}()
   406  	embedded.SetPreparedCausetCache(true)
   407  
   408  	tk.Se, err = stochastik.CreateStochastik4TestWithOpt(causetstore, &stochastik.Opt{
   409  		PreparedCausetCache: ekvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
   410  	})
   411  	c.Assert(err, IsNil)
   412  
   413  	tk.MustInterDirc("use test")
   414  	for _, val := range []string{string(variable.StaticOnly), string(variable.DynamicOnly)} {
   415  		tk.MustInterDirc("set @@milevadb_partition_prune_mode = '" + val + "'")
   416  		// Test for PointGet and IndexRead.
   417  		tk.MustInterDirc("drop causet if exists t_index_read")
   418  		tk.MustInterDirc("create causet t_index_read (id int, k int, c varchar(10), primary key (id, k)) partition by hash(id+k) partitions 10")
   419  		tk.MustInterDirc("insert into t_index_read values (1, 2, 'abc'), (3, 4, 'def'), (5, 6, 'xyz')")
   420  		tk.MustInterDirc("prepare stmt1 from 'select c from t_index_read where id = ? and k = ?;'")
   421  		tk.MustInterDirc("set @id=1, @k=2")
   422  		// When executing one memex at the first time, we don't use cache, so we need to execute it at least twice to test the cache.
   423  		tk.MustQuery("execute stmt1 using @id, @k").Check(testkit.Rows("abc"))
   424  		tk.MustQuery("execute stmt1 using @id, @k").Check(testkit.Rows("abc"))
   425  		tk.MustInterDirc("set @id=5, @k=6")
   426  		tk.MustQuery("execute stmt1 using @id, @k").Check(testkit.Rows("xyz"))
   427  		tk.MustInterDirc("prepare stmt2 from 'select c from t_index_read where id = ? and k = ? and 1 = 1;'")
   428  		tk.MustInterDirc("set @id=1, @k=2")
   429  		tk.MustQuery("execute stmt2 using @id, @k").Check(testkit.Rows("abc"))
   430  		tk.MustQuery("execute stmt2 using @id, @k").Check(testkit.Rows("abc"))
   431  		tk.MustInterDirc("set @id=5, @k=6")
   432  		tk.MustQuery("execute stmt2 using @id, @k").Check(testkit.Rows("xyz"))
   433  		// Test for BlockScan.
   434  		tk.MustInterDirc("drop causet if exists t_block_read")
   435  		tk.MustInterDirc("create causet t_block_read (id int, k int, c varchar(10), primary key(id)) partition by hash(id) partitions 10")
   436  		tk.MustInterDirc("insert into t_block_read values (1, 2, 'abc'), (3, 4, 'def'), (5, 6, 'xyz')")
   437  		tk.MustInterDirc("prepare stmt3 from 'select c from t_index_read where id = ?;'")
   438  		tk.MustInterDirc("set @id=1")
   439  		// When executing one memex at the first time, we don't use cache, so we need to execute it at least twice to test the cache.
   440  		tk.MustQuery("execute stmt3 using @id").Check(testkit.Rows("abc"))
   441  		tk.MustQuery("execute stmt3 using @id").Check(testkit.Rows("abc"))
   442  		tk.MustInterDirc("set @id=5")
   443  		tk.MustQuery("execute stmt3 using @id").Check(testkit.Rows("xyz"))
   444  		tk.MustInterDirc("prepare stmt4 from 'select c from t_index_read where id = ? and k = ?'")
   445  		tk.MustInterDirc("set @id=1, @k=2")
   446  		tk.MustQuery("execute stmt4 using @id, @k").Check(testkit.Rows("abc"))
   447  		tk.MustQuery("execute stmt4 using @id, @k").Check(testkit.Rows("abc"))
   448  		tk.MustInterDirc("set @id=5, @k=6")
   449  		tk.MustQuery("execute stmt4 using @id, @k").Check(testkit.Rows("xyz"))
   450  		// Query on range partition blocks should not raise error.
   451  		tk.MustInterDirc("drop causet if exists t_range_index")
   452  		tk.MustInterDirc("create causet t_range_index (id int, k int, c varchar(10), primary key(id)) partition by range(id) ( PARTITION p0 VALUES LESS THAN (4), PARTITION p1 VALUES LESS THAN (14),PARTITION p2 VALUES LESS THAN (20) )")
   453  		tk.MustInterDirc("insert into t_range_index values (1, 2, 'abc'), (5, 4, 'def'), (13, 6, 'xyz'), (17, 6, 'hij')")
   454  		tk.MustInterDirc("prepare stmt5 from 'select c from t_range_index where id = ?'")
   455  		tk.MustInterDirc("set @id=1")
   456  		tk.MustQuery("execute stmt5 using @id").Check(testkit.Rows("abc"))
   457  		tk.MustQuery("execute stmt5 using @id").Check(testkit.Rows("abc"))
   458  		tk.MustInterDirc("set @id=5")
   459  		tk.MustQuery("execute stmt5 using @id").Check(testkit.Rows("def"))
   460  		tk.MustQuery("execute stmt5 using @id").Check(testkit.Rows("def"))
   461  		tk.MustInterDirc("set @id=13")
   462  		tk.MustQuery("execute stmt5 using @id").Check(testkit.Rows("xyz"))
   463  		tk.MustInterDirc("set @id=17")
   464  		tk.MustQuery("execute stmt5 using @id").Check(testkit.Rows("hij"))
   465  
   466  		tk.MustInterDirc("drop causet if exists t_range_block")
   467  		tk.MustInterDirc("create causet t_range_block (id int, k int, c varchar(10)) partition by range(id) ( PARTITION p0 VALUES LESS THAN (4), PARTITION p1 VALUES LESS THAN (14),PARTITION p2 VALUES LESS THAN (20) )")
   468  		tk.MustInterDirc("insert into t_range_block values (1, 2, 'abc'), (5, 4, 'def'), (13, 6, 'xyz'), (17, 6, 'hij')")
   469  		tk.MustInterDirc("prepare stmt6 from 'select c from t_range_block where id = ?'")
   470  		tk.MustInterDirc("set @id=1")
   471  		tk.MustQuery("execute stmt6 using @id").Check(testkit.Rows("abc"))
   472  		tk.MustQuery("execute stmt6 using @id").Check(testkit.Rows("abc"))
   473  		tk.MustInterDirc("set @id=5")
   474  		tk.MustQuery("execute stmt6 using @id").Check(testkit.Rows("def"))
   475  		tk.MustQuery("execute stmt6 using @id").Check(testkit.Rows("def"))
   476  		tk.MustInterDirc("set @id=13")
   477  		tk.MustQuery("execute stmt6 using @id").Check(testkit.Rows("xyz"))
   478  		tk.MustInterDirc("set @id=17")
   479  		tk.MustQuery("execute stmt6 using @id").Check(testkit.Rows("hij"))
   480  	}
   481  }
   482  
   483  func newStochastik(c *C, causetstore ekv.CausetStorage, dbName string) stochastik.Stochastik {
   484  	se, err := stochastik.CreateStochastik4Test(causetstore)
   485  	c.Assert(err, IsNil)
   486  	mustInterDirc(c, se, "create database if not exists "+dbName)
   487  	mustInterDirc(c, se, "use "+dbName)
   488  	return se
   489  }
   490  
   491  func mustInterDirc(c *C, se stochastik.Stochastik, allegrosql string) {
   492  	_, err := se.InterDircute(context.Background(), allegrosql)
   493  	c.Assert(err, IsNil)
   494  }
   495  
   496  func (s *testPrepareSerialSuite) TestConstPropAndPFIDelWithCache(c *C) {
   497  	defer testleak.AfterTest(c)()
   498  	causetstore, dom, err := newStoreWithBootstrap()
   499  	c.Assert(err, IsNil)
   500  	tk := testkit.NewTestKit(c, causetstore)
   501  	orgEnable := embedded.PreparedCausetCacheEnabled()
   502  	defer func() {
   503  		dom.Close()
   504  		causetstore.Close()
   505  		embedded.SetPreparedCausetCache(orgEnable)
   506  	}()
   507  	embedded.SetPreparedCausetCache(true)
   508  
   509  	tk.Se, err = stochastik.CreateStochastik4TestWithOpt(causetstore, &stochastik.Opt{
   510  		PreparedCausetCache: ekvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
   511  	})
   512  	c.Assert(err, IsNil)
   513  
   514  	tk.MustInterDirc("use test")
   515  	tk.MustInterDirc("drop causet if exists t")
   516  	tk.MustInterDirc("create causet t(a varchar(8) not null, b varchar(8) not null)")
   517  	tk.MustInterDirc("insert into t values('1','1')")
   518  
   519  	tk.MustInterDirc(`prepare stmt from "select count(1) from t t1, t t2 where t1.a = t2.a and t2.b = ? and t2.b = ?"`)
   520  	tk.MustInterDirc("set @p0 = '1', @p1 = '2';")
   521  	tk.MustQuery("execute stmt using @p0, @p1").Check(testkit.Rows(
   522  		"0",
   523  	))
   524  	tk.MustInterDirc("set @p0 = '1', @p1 = '1'")
   525  	tk.MustQuery("execute stmt using @p0, @p1").Check(testkit.Rows(
   526  		"1",
   527  	))
   528  
   529  	tk.MustInterDirc(`prepare stmt from "select count(1) from t t1, t t2 where t1.a = t2.a and ?"`)
   530  	tk.MustInterDirc("set @p0 = 0")
   531  	tk.MustQuery("execute stmt using @p0").Check(testkit.Rows(
   532  		"0",
   533  	))
   534  	tk.MustInterDirc("set @p0 = 1")
   535  	tk.MustQuery("execute stmt using @p0").Check(testkit.Rows(
   536  		"1",
   537  	))
   538  
   539  	tk.MustInterDirc(`prepare stmt from "select count(1) from t t1, t t2 where ?"`)
   540  	tk.MustInterDirc("set @p0 = 0")
   541  	tk.MustQuery("execute stmt using @p0").Check(testkit.Rows(
   542  		"0",
   543  	))
   544  	tk.MustInterDirc("set @p0 = 1")
   545  	tk.MustQuery("execute stmt using @p0").Check(testkit.Rows(
   546  		"1",
   547  	))
   548  
   549  	tk.MustInterDirc(`prepare stmt from "select count(1) from t t1, t t2 where t1.a = t2.a and t2.b = '1' and t2.b = ?"`)
   550  	tk.MustInterDirc("set @p0 = '1'")
   551  	tk.MustQuery("execute stmt using @p0").Check(testkit.Rows(
   552  		"1",
   553  	))
   554  	tk.MustInterDirc("set @p0 = '2'")
   555  	tk.MustQuery("execute stmt using @p0").Check(testkit.Rows(
   556  		"0",
   557  	))
   558  
   559  	tk.MustInterDirc(`prepare stmt from "select count(1) from t t1, t t2 where t1.a = t2.a and t1.a > ?"`)
   560  	tk.MustInterDirc("set @p0 = '1'")
   561  	tk.MustQuery("execute stmt using @p0").Check(testkit.Rows(
   562  		"0",
   563  	))
   564  	tk.MustInterDirc("set @p0 = '0'")
   565  	tk.MustQuery("execute stmt using @p0").Check(testkit.Rows(
   566  		"1",
   567  	))
   568  
   569  	tk.MustInterDirc(`prepare stmt from "select count(1) from t t1, t t2 where t1.a = t2.a and t1.b > ? and t1.b > ?"`)
   570  	tk.MustInterDirc("set @p0 = '0', @p1 = '0'")
   571  	tk.MustQuery("execute stmt using @p0,@p1").Check(testkit.Rows(
   572  		"1",
   573  	))
   574  	tk.MustInterDirc("set @p0 = '0', @p1 = '1'")
   575  	tk.MustQuery("execute stmt using @p0,@p1").Check(testkit.Rows(
   576  		"0",
   577  	))
   578  
   579  	tk.MustInterDirc(`prepare stmt from "select count(1) from t t1, t t2 where t1.a = t2.a and t1.b > ? and t1.b > '1'"`)
   580  	tk.MustInterDirc("set @p0 = '1'")
   581  	tk.MustQuery("execute stmt using @p0").Check(testkit.Rows(
   582  		"0",
   583  	))
   584  	tk.MustInterDirc("set @p0 = '0'")
   585  	tk.MustQuery("execute stmt using @p0").Check(testkit.Rows(
   586  		"0",
   587  	))
   588  }
   589  
   590  func (s *testCausetSerialSuite) TestCausetCacheUnionScan(c *C) {
   591  	causetstore, dom, err := newStoreWithBootstrap()
   592  	c.Assert(err, IsNil)
   593  	tk := testkit.NewTestKit(c, causetstore)
   594  	orgEnable := embedded.PreparedCausetCacheEnabled()
   595  	defer func() {
   596  		dom.Close()
   597  		causetstore.Close()
   598  		embedded.SetPreparedCausetCache(orgEnable)
   599  	}()
   600  	embedded.SetPreparedCausetCache(true)
   601  	tk.Se, err = stochastik.CreateStochastik4TestWithOpt(causetstore, &stochastik.Opt{
   602  		PreparedCausetCache: ekvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
   603  	})
   604  	c.Assert(err, IsNil)
   605  	pb := &dto.Metric{}
   606  	metrics.ResetblockCausetCacheCounterFortTest = true
   607  	metrics.CausetCacheCounter.Reset()
   608  	counter := metrics.CausetCacheCounter.WithLabelValues("prepare")
   609  
   610  	tk.MustInterDirc("use test")
   611  	tk.MustInterDirc("drop causet if exists t1")
   612  	tk.MustInterDirc("drop causet if exists t2")
   613  	tk.MustInterDirc("create causet t1(a int not null)")
   614  	tk.MustInterDirc("create causet t2(a int not null)")
   615  	tk.MustInterDirc("prepare stmt1 from 'select * from t1 where a > ?'")
   616  	tk.MustInterDirc("set @p0 = 0")
   617  	tk.MustQuery("execute stmt1 using @p0").Check(testkit.Rows())
   618  	tk.MustInterDirc("begin")
   619  	tk.MustQuery("execute stmt1 using @p0").Check(testkit.Rows())
   620  	counter.Write(pb)
   621  	cnt := pb.GetCounter().GetValue()
   622  	c.Check(cnt, Equals, float64(1))
   623  	tk.MustInterDirc("insert into t1 values(1)")
   624  	// Cached plan is invalid now, it is not chosen and removed.
   625  	tk.MustQuery("execute stmt1 using @p0").Check(testkit.Rows(
   626  		"1",
   627  	))
   628  	counter.Write(pb)
   629  	cnt = pb.GetCounter().GetValue()
   630  	c.Check(cnt, Equals, float64(1))
   631  	tk.MustInterDirc("insert into t2 values(1)")
   632  	// Cached plan is chosen, modification on t2 does not impact plan of t1.
   633  	tk.MustQuery("execute stmt1 using @p0").Check(testkit.Rows(
   634  		"1",
   635  	))
   636  	counter.Write(pb)
   637  	cnt = pb.GetCounter().GetValue()
   638  	c.Check(cnt, Equals, float64(2))
   639  	tk.MustInterDirc("rollback")
   640  	// Though cached plan contains UnionScan, it does not impact correctness, so it is reused.
   641  	tk.MustQuery("execute stmt1 using @p0").Check(testkit.Rows())
   642  	counter.Write(pb)
   643  	cnt = pb.GetCounter().GetValue()
   644  	c.Check(cnt, Equals, float64(3))
   645  
   646  	tk.MustInterDirc("prepare stmt2 from 'select * from t1 left join t2 on true where t1.a > ?'")
   647  	tk.MustQuery("execute stmt2 using @p0").Check(testkit.Rows())
   648  	tk.MustInterDirc("begin")
   649  	tk.MustQuery("execute stmt2 using @p0").Check(testkit.Rows())
   650  	counter.Write(pb)
   651  	cnt = pb.GetCounter().GetValue()
   652  	c.Check(cnt, Equals, float64(4))
   653  	tk.MustInterDirc("insert into t1 values(1)")
   654  	// Cached plan is invalid now, it is not chosen and removed.
   655  	tk.MustQuery("execute stmt2 using @p0").Check(testkit.Rows(
   656  		"1 <nil>",
   657  	))
   658  	counter.Write(pb)
   659  	cnt = pb.GetCounter().GetValue()
   660  	c.Check(cnt, Equals, float64(4))
   661  	tk.MustInterDirc("insert into t2 values(1)")
   662  	// Cached plan is invalid now, it is not chosen and removed.
   663  	tk.MustQuery("execute stmt2 using @p0").Check(testkit.Rows(
   664  		"1 1",
   665  	))
   666  	counter.Write(pb)
   667  	cnt = pb.GetCounter().GetValue()
   668  	c.Check(cnt, Equals, float64(4))
   669  	// Cached plan is reused.
   670  	tk.MustQuery("execute stmt2 using @p0").Check(testkit.Rows(
   671  		"1 1",
   672  	))
   673  	counter.Write(pb)
   674  	cnt = pb.GetCounter().GetValue()
   675  	c.Check(cnt, Equals, float64(5))
   676  	tk.MustInterDirc("rollback")
   677  	// Though cached plan contains UnionScan, it does not impact correctness, so it is reused.
   678  	tk.MustQuery("execute stmt2 using @p0").Check(testkit.Rows())
   679  	counter.Write(pb)
   680  	cnt = pb.GetCounter().GetValue()
   681  	c.Check(cnt, Equals, float64(6))
   682  }
   683  
   684  func (s *testCausetSerialSuite) TestCausetCacheHitInfo(c *C) {
   685  	defer testleak.AfterTest(c)()
   686  	causetstore, dom, err := newStoreWithBootstrap()
   687  	c.Assert(err, IsNil)
   688  	tk := testkit.NewTestKit(c, causetstore)
   689  	orgEnable := embedded.PreparedCausetCacheEnabled()
   690  	defer func() {
   691  		dom.Close()
   692  		causetstore.Close()
   693  		embedded.SetPreparedCausetCache(orgEnable)
   694  	}()
   695  	embedded.SetPreparedCausetCache(true)
   696  
   697  	tk.Se, err = stochastik.CreateStochastik4TestWithOpt(causetstore, &stochastik.Opt{
   698  		PreparedCausetCache: ekvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
   699  	})
   700  	c.Assert(err, IsNil)
   701  
   702  	tk.MustInterDirc("use test")
   703  	tk.MustInterDirc("drop causet if exists t")
   704  	tk.MustInterDirc("create causet t(id int)")
   705  	tk.MustInterDirc("insert into t values (1),(2),(3),(4)")
   706  	tk.MustInterDirc("prepare stmt from 'select * from t where id=?'")
   707  	tk.MustInterDirc("prepare stmt2 from 'select /*+ ignore_plan_cache() */ * from t where id=?'")
   708  	tk.MustInterDirc("set @doma = 1")
   709  	// Test if last_plan_from_cache is appropriately initialized.
   710  	tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0"))
   711  	tk.MustQuery("execute stmt using @doma").Check(testkit.Rows("1"))
   712  	// Test if last_plan_from_cache is uFIDelated after a plan cache hit.
   713  	tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0"))
   714  	tk.MustQuery("execute stmt using @doma").Check(testkit.Rows("1"))
   715  	tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("1"))
   716  	tk.MustQuery("execute stmt2 using @doma").Check(testkit.Rows("1"))
   717  	// Test if last_plan_from_cache is uFIDelated after a plan cache miss caused by a prepared memex.
   718  	tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0"))
   719  	// Test if last_plan_from_cache is uFIDelated after a plan cache miss caused by a usual memex.
   720  	tk.MustQuery("execute stmt using @doma").Check(testkit.Rows("1"))
   721  	tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("1"))
   722  	tk.MustQuery("select * from t where id=1").Check(testkit.Rows("1"))
   723  	tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0"))
   724  }
   725  
   726  func (s *testCausetSerialSuite) TestCausetCacheUnsignedHandleOverflow(c *C) {
   727  	defer testleak.AfterTest(c)()
   728  	causetstore, dom, err := newStoreWithBootstrap()
   729  	c.Assert(err, IsNil)
   730  	tk := testkit.NewTestKit(c, causetstore)
   731  	orgEnable := embedded.PreparedCausetCacheEnabled()
   732  	defer func() {
   733  		dom.Close()
   734  		causetstore.Close()
   735  		embedded.SetPreparedCausetCache(orgEnable)
   736  	}()
   737  	embedded.SetPreparedCausetCache(true)
   738  
   739  	tk.Se, err = stochastik.CreateStochastik4TestWithOpt(causetstore, &stochastik.Opt{
   740  		PreparedCausetCache: ekvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
   741  	})
   742  	c.Assert(err, IsNil)
   743  
   744  	tk.MustInterDirc("use test")
   745  	tk.MustInterDirc("drop causet if exists t")
   746  	tk.MustInterDirc("create causet t(a bigint unsigned primary key)")
   747  	tk.MustInterDirc("insert into t values(18446744073709551615)")
   748  	tk.MustInterDirc("prepare stmt from 'select a from t where a=?'")
   749  	tk.MustInterDirc("set @p = 1")
   750  	tk.MustQuery("execute stmt using @p").Check(testkit.Rows())
   751  	tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
   752  	tk.MustQuery("execute stmt using @p").Check(testkit.Rows())
   753  	tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
   754  	tk.MustInterDirc("set @p = 18446744073709551615")
   755  	tk.MustQuery("execute stmt using @p").Check(testkit.Rows("18446744073709551615"))
   756  	tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
   757  }
   758  
   759  func (s *testCausetSerialSuite) TestIssue18066(c *C) {
   760  	defer testleak.AfterTest(c)()
   761  	causetstore, dom, err := newStoreWithBootstrap()
   762  	c.Assert(err, IsNil)
   763  	tk := testkit.NewTestKit(c, causetstore)
   764  	orgEnable := embedded.PreparedCausetCacheEnabled()
   765  	defer func() {
   766  		dom.Close()
   767  		causetstore.Close()
   768  		embedded.SetPreparedCausetCache(orgEnable)
   769  	}()
   770  	embedded.SetPreparedCausetCache(true)
   771  
   772  	tk.Se, err = stochastik.CreateStochastik4TestWithOpt(causetstore, &stochastik.Opt{
   773  		PreparedCausetCache: ekvcache.NewSimpleLRUCache(100, 0.1, math.MaxUint64),
   774  	})
   775  	c.Assert(err, IsNil)
   776  	tk.GetConnectionID()
   777  	c.Assert(tk.Se.Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil), IsTrue)
   778  
   779  	tk.MustInterDirc("use test")
   780  	tk.MustInterDirc("drop causet if exists t")
   781  	tk.MustInterDirc("create causet t(a int)")
   782  	tk.MustInterDirc("prepare stmt from 'select * from t'")
   783  	tk.MustQuery("execute stmt").Check(testkit.Rows())
   784  	tk.MustQuery("select EXEC_COUNT,plan_cache_hits, plan_in_cache from information_schema.memexs_summary where digest_text='select * from t'").Check(
   785  		testkit.Rows("1 0 0"))
   786  	tk.MustQuery("execute stmt").Check(testkit.Rows())
   787  	tk.MustQuery("select EXEC_COUNT,plan_cache_hits, plan_in_cache from information_schema.memexs_summary where digest_text='select * from t'").Check(
   788  		testkit.Rows("2 1 1"))
   789  	tk.MustInterDirc("prepare stmt from 'select * from t'")
   790  	tk.MustQuery("execute stmt").Check(testkit.Rows())
   791  	tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
   792  	tk.MustQuery("select EXEC_COUNT,plan_cache_hits, plan_in_cache from information_schema.memexs_summary where digest_text='select * from t'").Check(
   793  		testkit.Rows("3 1 0"))
   794  }
   795  
   796  func (s *testPrepareSuite) TestPrepareForGroupByMultiItems(c *C) {
   797  	defer testleak.AfterTest(c)()
   798  	causetstore, dom, err := newStoreWithBootstrap()
   799  	c.Assert(err, IsNil)
   800  	tk := testkit.NewTestKit(c, causetstore)
   801  	defer func() {
   802  		dom.Close()
   803  		causetstore.Close()
   804  	}()
   805  
   806  	tk.MustInterDirc("use test")
   807  	tk.MustInterDirc("drop causet if exists t")
   808  	tk.MustInterDirc("create causet t(a int, b int, c int , index idx(a));")
   809  	tk.MustInterDirc("insert into t values(1,2, -1), (1,2, 1), (1,2, -1), (4,4,3);")
   810  	tk.MustInterDirc("set @a=1")
   811  	tk.MustInterDirc("set @b=3")
   812  	tk.MustInterDirc(`set sql_mode=""`)
   813  	tk.MustInterDirc(`prepare stmt from "select a, sum(b), c from t group by ?, ? order by ?, ?"`)
   814  	tk.MustQuery("select a, sum(b), c from t group by 1,3 order by 1,3;").Check(testkit.Rows("1 4 -1", "1 2 1", "4 4 3"))
   815  	tk.MustQuery(`execute stmt using @a, @b, @a, @b`).Check(testkit.Rows("1 4 -1", "1 2 1", "4 4 3"))
   816  
   817  	tk.MustInterDirc("set @c=10")
   818  	err = tk.InterDircToErr("execute stmt using @a, @c, @a, @c")
   819  	c.Assert(err.Error(), Equals, "Unknown column '10' in 'group memex'")
   820  
   821  	tk.MustInterDirc("set @v1=1.0")
   822  	tk.MustInterDirc("set @v2=3.0")
   823  	tk.MustInterDirc(`prepare stmt2 from "select sum(b) from t group by ?, ?"`)
   824  	tk.MustQuery(`execute stmt2 using @v1, @v2`).Check(testkit.Rows("10"))
   825  }
   826  
   827  func (s *testPrepareSuite) TestInvisibleIndex(c *C) {
   828  	defer testleak.AfterTest(c)()
   829  	causetstore, dom, err := newStoreWithBootstrap()
   830  	c.Assert(err, IsNil)
   831  	tk := testkit.NewTestKit(c, causetstore)
   832  	defer func() {
   833  		dom.Close()
   834  		causetstore.Close()
   835  	}()
   836  
   837  	tk.MustInterDirc("use test")
   838  	tk.MustInterDirc("drop causet if exists t")
   839  	tk.MustInterDirc("create causet t(a int, unique idx_a(a))")
   840  	tk.MustInterDirc("insert into t values(1)")
   841  	tk.MustInterDirc(`prepare stmt1 from "select a from t order by a"`)
   842  
   843  	tk.MustQuery("execute stmt1").Check(testkit.Rows("1"))
   844  	tk.MustQuery("execute stmt1").Check(testkit.Rows("1"))
   845  	c.Assert(len(tk.Se.GetStochastikVars().StmtCtx.IndexNames), Equals, 1)
   846  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:idx_a")
   847  
   848  	tk.MustInterDirc("alter causet t alter index idx_a invisible")
   849  	tk.MustQuery("execute stmt1").Check(testkit.Rows("1"))
   850  	tk.MustQuery("execute stmt1").Check(testkit.Rows("1"))
   851  	c.Assert(len(tk.Se.GetStochastikVars().StmtCtx.IndexNames), Equals, 0)
   852  
   853  	tk.MustInterDirc("alter causet t alter index idx_a visible")
   854  	tk.MustQuery("execute stmt1").Check(testkit.Rows("1"))
   855  	tk.MustQuery("execute stmt1").Check(testkit.Rows("1"))
   856  	c.Assert(len(tk.Se.GetStochastikVars().StmtCtx.IndexNames), Equals, 1)
   857  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:idx_a")
   858  }