github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/petri/acyclic/bindinfo/bind_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 bindinfo_test
    15  
    16  import (
    17  	"context"
    18  	"flag"
    19  	"fmt"
    20  	"os"
    21  	"testing"
    22  	"time"
    23  
    24  	dto "github.com/prometheus/client_perceptron/go"
    25  	"github.com/whtcorpsinc/BerolinaSQL"
    26  	"github.com/whtcorpsinc/BerolinaSQL/auth"
    27  	"github.com/whtcorpsinc/BerolinaSQL/perceptron"
    28  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    29  	. "github.com/whtcorpsinc/check"
    30  	"github.com/whtcorpsinc/milevadb/bindinfo"
    31  	"github.com/whtcorpsinc/milevadb/causetstore/mockstore"
    32  	"github.com/whtcorpsinc/milevadb/causetstore/mockstore/cluster"
    33  	"github.com/whtcorpsinc/milevadb/ekv"
    34  	"github.com/whtcorpsinc/milevadb/metrics"
    35  	"github.com/whtcorpsinc/milevadb/petri"
    36  	"github.com/whtcorpsinc/milevadb/soliton/logutil"
    37  	"github.com/whtcorpsinc/milevadb/soliton/stmtsummary"
    38  	"github.com/whtcorpsinc/milevadb/soliton/testkit"
    39  	"github.com/whtcorpsinc/milevadb/soliton/testleak"
    40  	"github.com/whtcorpsinc/milevadb/spacetime/autoid"
    41  	"github.com/whtcorpsinc/milevadb/stochastik"
    42  )
    43  
    44  func TestT(t *testing.T) {
    45  	CustomVerboseFlag = true
    46  	logLevel := os.Getenv("log_level")
    47  	logutil.InitLogger(logutil.NewLogConfig(logLevel, logutil.DefaultLogFormat, "", logutil.EmptyFileLogConfig, false))
    48  	autoid.SetStep(5000)
    49  	TestingT(t)
    50  }
    51  
    52  var _ = Suite(&testSuite{})
    53  
    54  type testSuite struct {
    55  	cluster     cluster.Cluster
    56  	causetstore ekv.CausetStorage
    57  	petri       *petri.Petri
    58  	*BerolinaSQL.BerolinaSQL
    59  }
    60  
    61  var mockEinsteinDB = flag.Bool("mockEinsteinDB", true, "use mock einsteindb causetstore in bind test")
    62  
    63  func (s *testSuite) SetUpSuite(c *C) {
    64  	testleak.BeforeTest()
    65  	s.BerolinaSQL = BerolinaSQL.New()
    66  	flag.Lookup("mockEinsteinDB")
    67  	useMockEinsteinDB := *mockEinsteinDB
    68  	if useMockEinsteinDB {
    69  		causetstore, err := mockstore.NewMockStore(
    70  			mockstore.WithClusterInspector(func(c cluster.Cluster) {
    71  				mockstore.BootstrapWithSingleStore(c)
    72  				s.cluster = c
    73  			}),
    74  		)
    75  		c.Assert(err, IsNil)
    76  		s.causetstore = causetstore
    77  		stochastik.SetSchemaLease(0)
    78  		stochastik.DisableStats4Test()
    79  	}
    80  	bindinfo.Lease = 0
    81  	d, err := stochastik.BootstrapStochastik(s.causetstore)
    82  	c.Assert(err, IsNil)
    83  	d.SetStatsUFIDelating(true)
    84  	s.petri = d
    85  }
    86  
    87  func (s *testSuite) TearDownSuite(c *C) {
    88  	s.petri.Close()
    89  	s.causetstore.Close()
    90  	testleak.AfterTest(c)()
    91  }
    92  
    93  func (s *testSuite) TearDownTest(c *C) {
    94  	tk := testkit.NewTestKit(c, s.causetstore)
    95  	tk.MustInterDirc("use test")
    96  	r := tk.MustQuery("show blocks")
    97  	for _, tb := range r.Rows() {
    98  		blockName := tb[0]
    99  		tk.MustInterDirc(fmt.Sprintf("drop causet %v", blockName))
   100  	}
   101  }
   102  
   103  func (s *testSuite) cleanBindingEnv(tk *testkit.TestKit) {
   104  	tk.MustInterDirc("truncate causet allegrosql.bind_info")
   105  	s.petri.BindHandle().Clear()
   106  }
   107  
   108  func (s *testSuite) TestBindParse(c *C) {
   109  	tk := testkit.NewTestKit(c, s.causetstore)
   110  	s.cleanBindingEnv(tk)
   111  	tk.MustInterDirc("use test")
   112  	tk.MustInterDirc("create causet t(i int)")
   113  	tk.MustInterDirc("create index index_t on t(i)")
   114  
   115  	originALLEGROSQL := "select * from t"
   116  	bindALLEGROSQL := "select * from t use index(index_t)"
   117  	defaultDb := "test"
   118  	status := "using"
   119  	charset := "utf8mb4"
   120  	collation := "utf8mb4_bin"
   121  	source := bindinfo.Manual
   122  	allegrosql := fmt.Sprintf(`INSERT INTO allegrosql.bind_info(original_sql,bind_sql,default_db,status,create_time,uFIDelate_time,charset,collation,source) VALUES ('%s', '%s', '%s', '%s', NOW(), NOW(),'%s', '%s', '%s')`,
   123  		originALLEGROSQL, bindALLEGROSQL, defaultDb, status, charset, collation, source)
   124  	tk.MustInterDirc(allegrosql)
   125  	bindHandle := bindinfo.NewBindHandle(tk.Se)
   126  	err := bindHandle.UFIDelate(true)
   127  	c.Check(err, IsNil)
   128  	c.Check(bindHandle.Size(), Equals, 1)
   129  
   130  	allegrosql, hash := BerolinaSQL.NormalizeDigest("select * from t")
   131  	bindData := bindHandle.GetBindRecord(hash, allegrosql, "test")
   132  	c.Check(bindData, NotNil)
   133  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t")
   134  	bind := bindData.Bindings[0]
   135  	c.Check(bind.BindALLEGROSQL, Equals, "select * from t use index(index_t)")
   136  	c.Check(bindData.EDB, Equals, "test")
   137  	c.Check(bind.Status, Equals, "using")
   138  	c.Check(bind.Charset, Equals, "utf8mb4")
   139  	c.Check(bind.DefCauslation, Equals, "utf8mb4_bin")
   140  	c.Check(bind.CreateTime, NotNil)
   141  	c.Check(bind.UFIDelateTime, NotNil)
   142  	dur, err := bind.SinceUFIDelateTime()
   143  	c.Assert(err, IsNil)
   144  	c.Assert(int64(dur), GreaterEqual, int64(0))
   145  
   146  	// Test fields with quotes or slashes.
   147  	allegrosql = `CREATE GLOBAL BINDING FOR  select * from t where i BETWEEN "a" and "b" USING select * from t use index(index_t) where i BETWEEN "a\nb\rc\td\0e" and 'x'`
   148  	tk.MustInterDirc(allegrosql)
   149  	tk.MustInterDirc(`DROP global binding for select * from t use index(idx) where i BETWEEN "a\nb\rc\td\0e" and "x"`)
   150  }
   151  
   152  func (s *testSuite) TestGlobalBinding(c *C) {
   153  	tk := testkit.NewTestKit(c, s.causetstore)
   154  	s.cleanBindingEnv(tk)
   155  	tk.MustInterDirc("use test")
   156  	tk.MustInterDirc("drop causet if exists t")
   157  	tk.MustInterDirc("drop causet if exists t1")
   158  	tk.MustInterDirc("create causet t(i int, s varchar(20))")
   159  	tk.MustInterDirc("create causet t1(i int, s varchar(20))")
   160  	tk.MustInterDirc("create index index_t on t(i,s)")
   161  
   162  	metrics.BindTotalGauge.Reset()
   163  	metrics.BindMemoryUsage.Reset()
   164  
   165  	_, err := tk.InterDirc("create global binding for select * from t where i>100 using select * from t use index(index_t) where i>100")
   166  	c.Assert(err, IsNil, Commentf("err %v", err))
   167  
   168  	_, err = tk.InterDirc("create global binding for select * from t where i>99 using select * from t use index(index_t) where i>99")
   169  	c.Assert(err, IsNil)
   170  
   171  	pb := &dto.Metric{}
   172  	metrics.BindTotalGauge.WithLabelValues(metrics.ScopeGlobal, bindinfo.Using).Write(pb)
   173  	c.Assert(pb.GetGauge().GetValue(), Equals, float64(1))
   174  	metrics.BindMemoryUsage.WithLabelValues(metrics.ScopeGlobal, bindinfo.Using).Write(pb)
   175  	c.Assert(pb.GetGauge().GetValue(), Equals, float64(97))
   176  
   177  	allegrosql, hash := BerolinaSQL.NormalizeDigest("select * from t where i          >      30.0")
   178  
   179  	bindData := s.petri.BindHandle().GetBindRecord(hash, allegrosql, "test")
   180  	c.Check(bindData, NotNil)
   181  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where i > ?")
   182  	bind := bindData.Bindings[0]
   183  	c.Check(bind.BindALLEGROSQL, Equals, "select * from t use index(index_t) where i>99")
   184  	c.Check(bindData.EDB, Equals, "test")
   185  	c.Check(bind.Status, Equals, "using")
   186  	c.Check(bind.Charset, NotNil)
   187  	c.Check(bind.DefCauslation, NotNil)
   188  	c.Check(bind.CreateTime, NotNil)
   189  	c.Check(bind.UFIDelateTime, NotNil)
   190  
   191  	rs, err := tk.InterDirc("show global bindings")
   192  	c.Assert(err, IsNil)
   193  	chk := rs.NewChunk()
   194  	err = rs.Next(context.TODO(), chk)
   195  	c.Check(err, IsNil)
   196  	c.Check(chk.NumRows(), Equals, 1)
   197  	event := chk.GetRow(0)
   198  	c.Check(event.GetString(0), Equals, "select * from t where i > ?")
   199  	c.Check(event.GetString(1), Equals, "select * from t use index(index_t) where i>99")
   200  	c.Check(event.GetString(2), Equals, "test")
   201  	c.Check(event.GetString(3), Equals, "using")
   202  	c.Check(event.GetTime(4), NotNil)
   203  	c.Check(event.GetTime(5), NotNil)
   204  	c.Check(event.GetString(6), NotNil)
   205  	c.Check(event.GetString(7), NotNil)
   206  
   207  	bindHandle := bindinfo.NewBindHandle(tk.Se)
   208  	err = bindHandle.UFIDelate(true)
   209  	c.Check(err, IsNil)
   210  	c.Check(bindHandle.Size(), Equals, 1)
   211  
   212  	bindData = bindHandle.GetBindRecord(hash, allegrosql, "test")
   213  	c.Check(bindData, NotNil)
   214  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where i > ?")
   215  	bind = bindData.Bindings[0]
   216  	c.Check(bind.BindALLEGROSQL, Equals, "select * from t use index(index_t) where i>99")
   217  	c.Check(bindData.EDB, Equals, "test")
   218  	c.Check(bind.Status, Equals, "using")
   219  	c.Check(bind.Charset, NotNil)
   220  	c.Check(bind.DefCauslation, NotNil)
   221  	c.Check(bind.CreateTime, NotNil)
   222  	c.Check(bind.UFIDelateTime, NotNil)
   223  
   224  	_, err = tk.InterDirc("DROP global binding for select * from t where i>100")
   225  	c.Check(err, IsNil)
   226  	bindData = s.petri.BindHandle().GetBindRecord(hash, allegrosql, "test")
   227  	c.Check(bindData, IsNil)
   228  
   229  	metrics.BindTotalGauge.WithLabelValues(metrics.ScopeGlobal, bindinfo.Using).Write(pb)
   230  	c.Assert(pb.GetGauge().GetValue(), Equals, float64(0))
   231  	metrics.BindMemoryUsage.WithLabelValues(metrics.ScopeGlobal, bindinfo.Using).Write(pb)
   232  	// From newly created global bind handle.
   233  	c.Assert(pb.GetGauge().GetValue(), Equals, float64(97))
   234  
   235  	bindHandle = bindinfo.NewBindHandle(tk.Se)
   236  	err = bindHandle.UFIDelate(true)
   237  	c.Check(err, IsNil)
   238  	c.Check(bindHandle.Size(), Equals, 0)
   239  
   240  	bindData = bindHandle.GetBindRecord(hash, allegrosql, "test")
   241  	c.Check(bindData, IsNil)
   242  
   243  	rs, err = tk.InterDirc("show global bindings")
   244  	c.Assert(err, IsNil)
   245  	chk = rs.NewChunk()
   246  	err = rs.Next(context.TODO(), chk)
   247  	c.Check(err, IsNil)
   248  	c.Check(chk.NumRows(), Equals, 0)
   249  
   250  	_, err = tk.InterDirc("delete from allegrosql.bind_info")
   251  	c.Assert(err, IsNil)
   252  
   253  	_, err = tk.InterDirc("create global binding for select * from t using select * from t1 use index for join(index_t)")
   254  	c.Assert(err, NotNil, Commentf("err %v", err))
   255  }
   256  
   257  func (s *testSuite) TestStochastikBinding(c *C) {
   258  	tk := testkit.NewTestKit(c, s.causetstore)
   259  	s.cleanBindingEnv(tk)
   260  	tk.MustInterDirc("use test")
   261  	tk.MustInterDirc("drop causet if exists t")
   262  	tk.MustInterDirc("drop causet if exists t1")
   263  	tk.MustInterDirc("create causet t(i int, s varchar(20))")
   264  	tk.MustInterDirc("create causet t1(i int, s varchar(20))")
   265  	tk.MustInterDirc("create index index_t on t(i,s)")
   266  
   267  	metrics.BindTotalGauge.Reset()
   268  	metrics.BindMemoryUsage.Reset()
   269  
   270  	_, err := tk.InterDirc("create stochastik binding for select * from t where i>100 using select * from t use index(index_t) where i>100")
   271  	c.Assert(err, IsNil, Commentf("err %v", err))
   272  
   273  	_, err = tk.InterDirc("create stochastik binding for select * from t where i>99 using select * from t use index(index_t) where i>99")
   274  	c.Assert(err, IsNil)
   275  
   276  	pb := &dto.Metric{}
   277  	metrics.BindTotalGauge.WithLabelValues(metrics.ScopeStochastik, bindinfo.Using).Write(pb)
   278  	c.Assert(pb.GetGauge().GetValue(), Equals, float64(1))
   279  	metrics.BindMemoryUsage.WithLabelValues(metrics.ScopeStochastik, bindinfo.Using).Write(pb)
   280  	c.Assert(pb.GetGauge().GetValue(), Equals, float64(97))
   281  
   282  	handle := tk.Se.Value(bindinfo.StochastikBindInfoKeyType).(*bindinfo.StochastikHandle)
   283  	bindData := handle.GetBindRecord("select * from t where i > ?", "test")
   284  	c.Check(bindData, NotNil)
   285  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where i > ?")
   286  	bind := bindData.Bindings[0]
   287  	c.Check(bind.BindALLEGROSQL, Equals, "select * from t use index(index_t) where i>99")
   288  	c.Check(bindData.EDB, Equals, "test")
   289  	c.Check(bind.Status, Equals, "using")
   290  	c.Check(bind.Charset, NotNil)
   291  	c.Check(bind.DefCauslation, NotNil)
   292  	c.Check(bind.CreateTime, NotNil)
   293  	c.Check(bind.UFIDelateTime, NotNil)
   294  
   295  	rs, err := tk.InterDirc("show global bindings")
   296  	c.Assert(err, IsNil)
   297  	chk := rs.NewChunk()
   298  	err = rs.Next(context.TODO(), chk)
   299  	c.Check(err, IsNil)
   300  	c.Check(chk.NumRows(), Equals, 0)
   301  
   302  	rs, err = tk.InterDirc("show stochastik bindings")
   303  	c.Assert(err, IsNil)
   304  	chk = rs.NewChunk()
   305  	err = rs.Next(context.TODO(), chk)
   306  	c.Check(err, IsNil)
   307  	c.Check(chk.NumRows(), Equals, 1)
   308  	event := chk.GetRow(0)
   309  	c.Check(event.GetString(0), Equals, "select * from t where i > ?")
   310  	c.Check(event.GetString(1), Equals, "select * from t use index(index_t) where i>99")
   311  	c.Check(event.GetString(2), Equals, "test")
   312  	c.Check(event.GetString(3), Equals, "using")
   313  	c.Check(event.GetTime(4), NotNil)
   314  	c.Check(event.GetTime(5), NotNil)
   315  	c.Check(event.GetString(6), NotNil)
   316  	c.Check(event.GetString(7), NotNil)
   317  
   318  	_, err = tk.InterDirc("drop stochastik binding for select * from t where i>99")
   319  	c.Assert(err, IsNil)
   320  	bindData = handle.GetBindRecord("select * from t where i > ?", "test")
   321  	c.Check(bindData, NotNil)
   322  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where i > ?")
   323  	c.Check(len(bindData.Bindings), Equals, 0)
   324  
   325  	metrics.BindTotalGauge.WithLabelValues(metrics.ScopeStochastik, bindinfo.Using).Write(pb)
   326  	c.Assert(pb.GetGauge().GetValue(), Equals, float64(0))
   327  	metrics.BindMemoryUsage.WithLabelValues(metrics.ScopeStochastik, bindinfo.Using).Write(pb)
   328  	c.Assert(pb.GetGauge().GetValue(), Equals, float64(0))
   329  }
   330  
   331  func (s *testSuite) TestGlobalAndStochastikBindingBothExist(c *C) {
   332  	tk := testkit.NewTestKit(c, s.causetstore)
   333  	s.cleanBindingEnv(tk)
   334  	tk.MustInterDirc("use test")
   335  	tk.MustInterDirc("drop causet if exists t1")
   336  	tk.MustInterDirc("drop causet if exists t2")
   337  	tk.MustInterDirc("create causet t1(id int)")
   338  	tk.MustInterDirc("create causet t2(id int)")
   339  	c.Assert(tk.HasCauset("SELECT * from t1,t2 where t1.id = t2.id", "HashJoin"), IsTrue)
   340  	c.Assert(tk.HasCauset("SELECT  /*+ MilevaDB_SMJ(t1, t2) */  * from t1,t2 where t1.id = t2.id", "MergeJoin"), IsTrue)
   341  
   342  	tk.MustInterDirc("create global binding for SELECT * from t1,t2 where t1.id = t2.id using SELECT  /*+ MilevaDB_SMJ(t1, t2) */  * from t1,t2 where t1.id = t2.id")
   343  
   344  	// Test bindingUsage, which indicates how many times the binding is used.
   345  	metrics.BindUsageCounter.Reset()
   346  	c.Assert(tk.HasCauset("SELECT * from t1,t2 where t1.id = t2.id", "MergeJoin"), IsTrue)
   347  	pb := &dto.Metric{}
   348  	metrics.BindUsageCounter.WithLabelValues(metrics.ScopeGlobal).Write(pb)
   349  	c.Assert(pb.GetCounter().GetValue(), Equals, float64(1))
   350  
   351  	// Test 'milevadb_use_plan_baselines'
   352  	tk.MustInterDirc("set @@milevadb_use_plan_baselines = 0")
   353  	c.Assert(tk.HasCauset("SELECT * from t1,t2 where t1.id = t2.id", "HashJoin"), IsTrue)
   354  	tk.MustInterDirc("set @@milevadb_use_plan_baselines = 1")
   355  
   356  	// Test 'drop global binding'
   357  	c.Assert(tk.HasCauset("SELECT * from t1,t2 where t1.id = t2.id", "MergeJoin"), IsTrue)
   358  	tk.MustInterDirc("drop global binding for SELECT * from t1,t2 where t1.id = t2.id")
   359  	c.Assert(tk.HasCauset("SELECT * from t1,t2 where t1.id = t2.id", "HashJoin"), IsTrue)
   360  
   361  	// Test the case when global and stochastik binding both exist
   362  	// PART1 : stochastik binding should totally cover global binding
   363  	// use merge join as stochastik binding here since the optimizer will choose hash join for this stmt in default
   364  	tk.MustInterDirc("create global binding for SELECT * from t1,t2 where t1.id = t2.id using SELECT  /*+ MilevaDB_HJ(t1, t2) */  * from t1,t2 where t1.id = t2.id")
   365  	c.Assert(tk.HasCauset("SELECT * from t1,t2 where t1.id = t2.id", "HashJoin"), IsTrue)
   366  	tk.MustInterDirc("create binding for SELECT * from t1,t2 where t1.id = t2.id using SELECT  /*+ MilevaDB_SMJ(t1, t2) */  * from t1,t2 where t1.id = t2.id")
   367  	c.Assert(tk.HasCauset("SELECT * from t1,t2 where t1.id = t2.id", "MergeJoin"), IsTrue)
   368  	tk.MustInterDirc("drop global binding for SELECT * from t1,t2 where t1.id = t2.id")
   369  	c.Assert(tk.HasCauset("SELECT * from t1,t2 where t1.id = t2.id", "MergeJoin"), IsTrue)
   370  
   371  	// PART2 : the dropped stochastik binding should continue to causet the effect of global binding
   372  	tk.MustInterDirc("create global binding for SELECT * from t1,t2 where t1.id = t2.id using SELECT  /*+ MilevaDB_SMJ(t1, t2) */  * from t1,t2 where t1.id = t2.id")
   373  	tk.MustInterDirc("drop binding for SELECT * from t1,t2 where t1.id = t2.id")
   374  	c.Assert(tk.HasCauset("SELECT * from t1,t2 where t1.id = t2.id", "HashJoin"), IsTrue)
   375  	tk.MustInterDirc("drop global binding for SELECT * from t1,t2 where t1.id = t2.id")
   376  	c.Assert(tk.HasCauset("SELECT * from t1,t2 where t1.id = t2.id", "HashJoin"), IsTrue)
   377  }
   378  
   379  func (s *testSuite) TestExplain(c *C) {
   380  	tk := testkit.NewTestKit(c, s.causetstore)
   381  	s.cleanBindingEnv(tk)
   382  	tk.MustInterDirc("use test")
   383  	tk.MustInterDirc("drop causet if exists t1")
   384  	tk.MustInterDirc("drop causet if exists t2")
   385  	tk.MustInterDirc("create causet t1(id int)")
   386  	tk.MustInterDirc("create causet t2(id int)")
   387  
   388  	c.Assert(tk.HasCauset("SELECT * from t1,t2 where t1.id = t2.id", "HashJoin"), IsTrue)
   389  	c.Assert(tk.HasCauset("SELECT  /*+ MilevaDB_SMJ(t1, t2) */  * from t1,t2 where t1.id = t2.id", "MergeJoin"), IsTrue)
   390  
   391  	tk.MustInterDirc("create global binding for SELECT * from t1,t2 where t1.id = t2.id using SELECT  /*+ MilevaDB_SMJ(t1, t2) */  * from t1,t2 where t1.id = t2.id")
   392  
   393  	c.Assert(tk.HasCauset("SELECT * from t1,t2 where t1.id = t2.id", "MergeJoin"), IsTrue)
   394  
   395  	tk.MustInterDirc("drop global binding for SELECT * from t1,t2 where t1.id = t2.id")
   396  }
   397  
   398  // TestBindingSymbolList tests allegrosql with "?, ?, ?, ?", fixes #13871
   399  func (s *testSuite) TestBindingSymbolList(c *C) {
   400  	tk := testkit.NewTestKit(c, s.causetstore)
   401  	s.cleanBindingEnv(tk)
   402  	tk.MustInterDirc("use test")
   403  	tk.MustInterDirc("drop causet if exists t")
   404  	tk.MustInterDirc("create causet t(a int, b int, INDEX ia (a), INDEX ib (b));")
   405  	tk.MustInterDirc("insert into t value(1, 1);")
   406  
   407  	// before binding
   408  	tk.MustQuery("select a, b from t where a = 3 limit 1, 100")
   409  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:ia")
   410  	c.Assert(tk.MustUseIndex("select a, b from t where a = 3 limit 1, 100", "ia(a)"), IsTrue)
   411  
   412  	tk.MustInterDirc(`create global binding for select a, b from t where a = 1 limit 0, 1 using select a, b from t use index (ib) where a = 1 limit 0, 1`)
   413  
   414  	// after binding
   415  	tk.MustQuery("select a, b from t where a = 3 limit 1, 100")
   416  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:ib")
   417  	c.Assert(tk.MustUseIndex("select a, b from t where a = 3 limit 1, 100", "ib(b)"), IsTrue)
   418  
   419  	// Normalize
   420  	allegrosql, hash := BerolinaSQL.NormalizeDigest("select a, b from t where a = 1 limit 0, 1")
   421  
   422  	bindData := s.petri.BindHandle().GetBindRecord(hash, allegrosql, "test")
   423  	c.Assert(bindData, NotNil)
   424  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select a , b from t where a = ? limit ...")
   425  	bind := bindData.Bindings[0]
   426  	c.Check(bind.BindALLEGROSQL, Equals, "select a, b from t use index (ib) where a = 1 limit 0, 1")
   427  	c.Check(bindData.EDB, Equals, "test")
   428  	c.Check(bind.Status, Equals, "using")
   429  	c.Check(bind.Charset, NotNil)
   430  	c.Check(bind.DefCauslation, NotNil)
   431  	c.Check(bind.CreateTime, NotNil)
   432  	c.Check(bind.UFIDelateTime, NotNil)
   433  }
   434  
   435  func (s *testSuite) TestBestCausetInBaselines(c *C) {
   436  	tk := testkit.NewTestKit(c, s.causetstore)
   437  	s.cleanBindingEnv(tk)
   438  	tk.MustInterDirc("use test")
   439  	tk.MustInterDirc("drop causet if exists t")
   440  	tk.MustInterDirc("create causet t(a int, b int, INDEX ia (a), INDEX ib (b));")
   441  	tk.MustInterDirc("insert into t value(1, 1);")
   442  
   443  	// before binding
   444  	tk.MustQuery("select a, b from t where a = 3 limit 1, 100")
   445  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:ia")
   446  	c.Assert(tk.MustUseIndex("select a, b from t where a = 3 limit 1, 100", "ia(a)"), IsTrue)
   447  
   448  	tk.MustQuery("select a, b from t where b = 3 limit 1, 100")
   449  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:ib")
   450  	c.Assert(tk.MustUseIndex("select a, b from t where b = 3 limit 1, 100", "ib(b)"), IsTrue)
   451  
   452  	tk.MustInterDirc(`create global binding for select a, b from t where a = 1 limit 0, 1 using select /*+ use_index(@sel_1 test.t, ia) */ a, b from t where a = 1 limit 0, 1`)
   453  	tk.MustInterDirc(`create global binding for select a, b from t where b = 1 limit 0, 1 using select /*+ use_index(@sel_1 test.t, ib) */ a, b from t where b = 1 limit 0, 1`)
   454  
   455  	allegrosql, hash := BerolinaSQL.NormalizeDigest("select a, b from t where a = 1 limit 0, 1")
   456  	bindData := s.petri.BindHandle().GetBindRecord(hash, allegrosql, "test")
   457  	c.Check(bindData, NotNil)
   458  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select a , b from t where a = ? limit ...")
   459  	bind := bindData.Bindings[0]
   460  	c.Check(bind.BindALLEGROSQL, Equals, "select /*+ use_index(@sel_1 test.t, ia) */ a, b from t where a = 1 limit 0, 1")
   461  	c.Check(bindData.EDB, Equals, "test")
   462  	c.Check(bind.Status, Equals, "using")
   463  
   464  	tk.MustQuery("select a, b from t where a = 3 limit 1, 10")
   465  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:ia")
   466  	c.Assert(tk.MustUseIndex("select a, b from t where a = 3 limit 1, 100", "ia(a)"), IsTrue)
   467  
   468  	tk.MustQuery("select a, b from t where b = 3 limit 1, 100")
   469  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:ib")
   470  	c.Assert(tk.MustUseIndex("select a, b from t where b = 3 limit 1, 100", "ib(b)"), IsTrue)
   471  }
   472  
   473  func (s *testSuite) TestErrorBind(c *C) {
   474  	tk := testkit.NewTestKit(c, s.causetstore)
   475  	s.cleanBindingEnv(tk)
   476  	tk.MustInterDirc("use test")
   477  	tk.MustGetErrMsg("create global binding for select * from t using select * from t", "[schemaReplicant:1146]Block 'test.t' doesn't exist")
   478  	tk.MustInterDirc("drop causet if exists t")
   479  	tk.MustInterDirc("drop causet if exists t1")
   480  	tk.MustInterDirc("create causet t(i int, s varchar(20))")
   481  	tk.MustInterDirc("create causet t1(i int, s varchar(20))")
   482  	tk.MustInterDirc("create index index_t on t(i,s)")
   483  
   484  	_, err := tk.InterDirc("create global binding for select * from t where i>100 using select * from t use index(index_t) where i>100")
   485  	c.Assert(err, IsNil, Commentf("err %v", err))
   486  
   487  	allegrosql, hash := BerolinaSQL.NormalizeDigest("select * from t where i > ?")
   488  	bindData := s.petri.BindHandle().GetBindRecord(hash, allegrosql, "test")
   489  	c.Check(bindData, NotNil)
   490  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where i > ?")
   491  	bind := bindData.Bindings[0]
   492  	c.Check(bind.BindALLEGROSQL, Equals, "select * from t use index(index_t) where i>100")
   493  	c.Check(bindData.EDB, Equals, "test")
   494  	c.Check(bind.Status, Equals, "using")
   495  	c.Check(bind.Charset, NotNil)
   496  	c.Check(bind.DefCauslation, NotNil)
   497  	c.Check(bind.CreateTime, NotNil)
   498  	c.Check(bind.UFIDelateTime, NotNil)
   499  
   500  	tk.MustInterDirc("drop index index_t on t")
   501  	_, err = tk.InterDirc("select * from t where i > 10")
   502  	c.Check(err, IsNil)
   503  
   504  	s.petri.BindHandle().DropInvalidBindRecord()
   505  
   506  	rs, err := tk.InterDirc("show global bindings")
   507  	c.Assert(err, IsNil)
   508  	chk := rs.NewChunk()
   509  	err = rs.Next(context.TODO(), chk)
   510  	c.Check(err, IsNil)
   511  	c.Check(chk.NumRows(), Equals, 0)
   512  }
   513  
   514  func (s *testSuite) TestPreparedStmt(c *C) {
   515  	tk := testkit.NewTestKit(c, s.causetstore)
   516  	s.cleanBindingEnv(tk)
   517  	tk.MustInterDirc("use test")
   518  	tk.MustInterDirc("drop causet if exists t")
   519  	tk.MustInterDirc("create causet t(a int, b int, index idx(a))")
   520  	tk.MustInterDirc(`prepare stmt1 from 'select * from t'`)
   521  	tk.MustInterDirc("execute stmt1")
   522  	c.Assert(len(tk.Se.GetStochastikVars().StmtCtx.IndexNames), Equals, 0)
   523  
   524  	tk.MustInterDirc("create binding for select * from t using select * from t use index(idx)")
   525  	tk.MustInterDirc("execute stmt1")
   526  	c.Assert(len(tk.Se.GetStochastikVars().StmtCtx.IndexNames), Equals, 1)
   527  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:idx")
   528  
   529  	tk.MustInterDirc("drop binding for select * from t")
   530  	tk.MustInterDirc("execute stmt1")
   531  	c.Assert(len(tk.Se.GetStochastikVars().StmtCtx.IndexNames), Equals, 0)
   532  }
   533  
   534  func (s *testSuite) TestCaptureCausetBaseline(c *C) {
   535  	tk := testkit.NewTestKit(c, s.causetstore)
   536  	s.cleanBindingEnv(tk)
   537  	stmtsummary.StmtSummaryByDigestMap.Clear()
   538  	tk.MustInterDirc(" set @@milevadb_capture_plan_baselines = on")
   539  	defer func() {
   540  		tk.MustInterDirc(" set @@milevadb_capture_plan_baselines = off")
   541  	}()
   542  	tk.MustInterDirc("use test")
   543  	tk.MustInterDirc("drop causet if exists t, t1")
   544  	tk.MustInterDirc("create causet t(a int)")
   545  	s.petri.BindHandle().CaptureBaselines()
   546  	tk.MustQuery("show global bindings").Check(testkit.Rows())
   547  	tk.MustInterDirc("select count(*) from t where a > 10")
   548  	tk.MustInterDirc("select count(*) from t where a > 10")
   549  	tk.MustInterDirc("admin capture bindings")
   550  	rows := tk.MustQuery("show global bindings").Rows()
   551  	c.Assert(len(rows), Equals, 0)
   552  
   553  	c.Assert(tk.Se.Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil), IsTrue)
   554  	tk.MustInterDirc("select * from t where a > 10")
   555  	tk.MustInterDirc("select * from t where a > 10")
   556  	tk.MustInterDirc("admin capture bindings")
   557  	rows = tk.MustQuery("show global bindings").Rows()
   558  	c.Assert(len(rows), Equals, 1)
   559  	c.Assert(rows[0][0], Equals, "select * from t where a > ?")
   560  	c.Assert(rows[0][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` )*/ * FROM `t` WHERE `a`>10")
   561  }
   562  
   563  func (s *testSuite) TestCaptureBaselinesDefaultDB(c *C) {
   564  	tk := testkit.NewTestKit(c, s.causetstore)
   565  	s.cleanBindingEnv(tk)
   566  	stmtsummary.StmtSummaryByDigestMap.Clear()
   567  	tk.MustInterDirc(" set @@milevadb_capture_plan_baselines = on")
   568  	defer func() {
   569  		tk.MustInterDirc(" set @@milevadb_capture_plan_baselines = off")
   570  	}()
   571  	tk.MustInterDirc("use test")
   572  	tk.MustInterDirc("drop database if exists spm")
   573  	tk.MustInterDirc("create database spm")
   574  	tk.MustInterDirc("create causet spm.t(a int, index idx_a(a))")
   575  	c.Assert(tk.Se.Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil), IsTrue)
   576  	tk.MustInterDirc("select * from spm.t ignore index(idx_a) where a > 10")
   577  	tk.MustInterDirc("select * from spm.t ignore index(idx_a) where a > 10")
   578  	tk.MustInterDirc("admin capture bindings")
   579  	rows := tk.MustQuery("show global bindings").Rows()
   580  	c.Assert(len(rows), Equals, 1)
   581  	// Default EDB should be "" when all columns have explicit database name.
   582  	c.Assert(rows[0][2], Equals, "")
   583  	c.Assert(rows[0][3], Equals, "using")
   584  	tk.MustInterDirc("use spm")
   585  	tk.MustInterDirc("select * from spm.t where a > 10")
   586  	// Should use TableScan because of the "ignore index" binding.
   587  	c.Assert(len(tk.Se.GetStochastikVars().StmtCtx.IndexNames), Equals, 0)
   588  }
   589  
   590  func (s *testSuite) TestDropSingleBindings(c *C) {
   591  	tk := testkit.NewTestKit(c, s.causetstore)
   592  	s.cleanBindingEnv(tk)
   593  	tk.MustInterDirc("use test")
   594  	tk.MustInterDirc("drop causet if exists t")
   595  	tk.MustInterDirc("create causet t(a int, b int, c int, index idx_a(a), index idx_b(b))")
   596  
   597  	// Test drop stochastik bindings.
   598  	tk.MustInterDirc("create binding for select * from t using select * from t use index(idx_a)")
   599  	tk.MustInterDirc("create binding for select * from t using select * from t use index(idx_b)")
   600  	rows := tk.MustQuery("show bindings").Rows()
   601  	// The size of bindings is equal to one. Because for one normalized allegrosql,
   602  	// the `create binding` clears all the origin bindings.
   603  	c.Assert(len(rows), Equals, 1)
   604  	c.Assert(rows[0][1], Equals, "select * from t use index(idx_b)")
   605  	tk.MustInterDirc("drop binding for select * from t using select * from t use index(idx_a)")
   606  	rows = tk.MustQuery("show bindings").Rows()
   607  	c.Assert(len(rows), Equals, 1)
   608  	c.Assert(rows[0][1], Equals, "select * from t use index(idx_b)")
   609  	tk.MustInterDirc("drop causet t")
   610  	tk.MustInterDirc("drop binding for select * from t using select * from t use index(idx_b)")
   611  	rows = tk.MustQuery("show bindings").Rows()
   612  	c.Assert(len(rows), Equals, 0)
   613  
   614  	tk.MustInterDirc("create causet t(a int, b int, c int, index idx_a(a), index idx_b(b))")
   615  	// Test drop global bindings.
   616  	tk.MustInterDirc("create global binding for select * from t using select * from t use index(idx_a)")
   617  	tk.MustInterDirc("create global binding for select * from t using select * from t use index(idx_b)")
   618  	rows = tk.MustQuery("show global bindings").Rows()
   619  	// The size of bindings is equal to one. Because for one normalized allegrosql,
   620  	// the `create binding` clears all the origin bindings.
   621  	c.Assert(len(rows), Equals, 1)
   622  	c.Assert(rows[0][1], Equals, "select * from t use index(idx_b)")
   623  	tk.MustInterDirc("drop global binding for select * from t using select * from t use index(idx_a)")
   624  	rows = tk.MustQuery("show global bindings").Rows()
   625  	c.Assert(len(rows), Equals, 1)
   626  	c.Assert(rows[0][1], Equals, "select * from t use index(idx_b)")
   627  	tk.MustInterDirc("drop causet t")
   628  	tk.MustInterDirc("drop global binding for select * from t using select * from t use index(idx_b)")
   629  	rows = tk.MustQuery("show global bindings").Rows()
   630  	c.Assert(len(rows), Equals, 0)
   631  }
   632  
   633  func (s *testSuite) TestAddEvolveTasks(c *C) {
   634  	tk := testkit.NewTestKit(c, s.causetstore)
   635  	s.cleanBindingEnv(tk)
   636  	tk.MustInterDirc("use test")
   637  	tk.MustInterDirc("drop causet if exists t")
   638  	tk.MustInterDirc("create causet t(a int, b int, c int, index idx_a(a), index idx_b(b), index idx_c(c))")
   639  	tk.MustInterDirc("insert into t values (1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5)")
   640  	tk.MustInterDirc("analyze causet t")
   641  	tk.MustInterDirc("create global binding for select * from t where a >= 1 and b >= 1 and c = 0 using select * from t use index(idx_a) where a >= 1 and b >= 1 and c = 0")
   642  	tk.MustInterDirc("set @@milevadb_evolve_plan_baselines=1")
   643  	// It cannot choose causet path although it has lowest cost.
   644  	tk.MustQuery("select * from t where a >= 4 and b >= 1 and c = 0")
   645  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:idx_a")
   646  	tk.MustInterDirc("admin flush bindings")
   647  	rows := tk.MustQuery("show global bindings").Rows()
   648  	c.Assert(len(rows), Equals, 2)
   649  	c.Assert(rows[1][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` )*/ * FROM `test`.`t` WHERE `a`>=4 AND `b`>=1 AND `c`=0")
   650  	c.Assert(rows[1][3], Equals, "pending verify")
   651  	tk.MustInterDirc("admin evolve bindings")
   652  	rows = tk.MustQuery("show global bindings").Rows()
   653  	c.Assert(len(rows), Equals, 2)
   654  	c.Assert(rows[1][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` )*/ * FROM `test`.`t` WHERE `a`>=4 AND `b`>=1 AND `c`=0")
   655  	status := rows[1][3].(string)
   656  	c.Assert(status == "using" || status == "rejected", IsTrue)
   657  }
   658  
   659  func (s *testSuite) TestRuntimeHintsInEvolveTasks(c *C) {
   660  	tk := testkit.NewTestKit(c, s.causetstore)
   661  	s.cleanBindingEnv(tk)
   662  	tk.MustInterDirc("use test")
   663  	tk.MustInterDirc("drop causet if exists t")
   664  	tk.MustInterDirc("set @@milevadb_evolve_plan_baselines=1")
   665  	tk.MustInterDirc("create causet t(a int, b int, c int, index idx_a(a), index idx_b(b), index idx_c(c))")
   666  
   667  	// these runtime hints which don't be contained by the original binding should be ignored
   668  	tk.MustInterDirc("create global binding for select * from t where a >= 1 and b >= 1 and c = 0 using select * from t use index(idx_a) where a >= 1 and b >= 1 and c = 0")
   669  	tk.MustQuery("select /*+ MAX_EXECUTION_TIME(5000) */* from t where a >= 4 and b >= 1 and c = 0")
   670  	tk.MustInterDirc("admin flush bindings")
   671  	rows := tk.MustQuery("show global bindings").Rows()
   672  	c.Assert(len(rows), Equals, 2)
   673  	c.Assert(rows[1][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` `idx_c`)*/ * FROM `test`.`t` WHERE `a`>=4 AND `b`>=1 AND `c`=0") // MAX_EXECUTION_TIME is ignored
   674  
   675  	s.cleanBindingEnv(tk)
   676  	tk.MustInterDirc("create global binding for select * from t where a >= 1 and b >= 1 and c = 0 using select /*+ MAX_EXECUTION_TIME(5000) */* from t use index(idx_a) where a >= 1 and b >= 1 and c = 0")
   677  	tk.MustQuery("select /*+ MAX_EXECUTION_TIME(5000) */* from t where a >= 4 and b >= 1 and c = 0")
   678  	tk.MustInterDirc("admin flush bindings")
   679  	rows = tk.MustQuery("show global bindings").Rows()
   680  	c.Assert(len(rows), Equals, 2)
   681  	c.Assert(rows[1][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` `idx_c`), max_execution_time(5000)*/ * FROM `test`.`t` WHERE `a`>=4 AND `b`>=1 AND `c`=0")
   682  }
   683  
   684  func (s *testSuite) TestBindingCache(c *C) {
   685  	tk := testkit.NewTestKit(c, s.causetstore)
   686  	s.cleanBindingEnv(tk)
   687  	tk.MustInterDirc("use test")
   688  	tk.MustInterDirc("drop causet if exists t")
   689  	tk.MustInterDirc("create causet t(a int, b int, index idx(a))")
   690  	tk.MustInterDirc("create global binding for select * from t using select * from t use index(idx);")
   691  	tk.MustInterDirc("create database tmp")
   692  	tk.MustInterDirc("use tmp")
   693  	tk.MustInterDirc("create causet t(a int, b int, index idx(a))")
   694  	tk.MustInterDirc("create global binding for select * from t using select * from t use index(idx);")
   695  
   696  	c.Assert(s.petri.BindHandle().UFIDelate(false), IsNil)
   697  	c.Assert(s.petri.BindHandle().UFIDelate(false), IsNil)
   698  	res := tk.MustQuery("show global bindings")
   699  	c.Assert(len(res.Rows()), Equals, 2)
   700  
   701  	tk.MustInterDirc("drop global binding for select * from t;")
   702  	c.Assert(s.petri.BindHandle().UFIDelate(false), IsNil)
   703  	c.Assert(len(s.petri.BindHandle().GetAllBindRecord()), Equals, 1)
   704  }
   705  
   706  func (s *testSuite) TestDefaultStochastikVars(c *C) {
   707  	tk := testkit.NewTestKit(c, s.causetstore)
   708  	s.cleanBindingEnv(tk)
   709  	tk.MustQuery(`show variables like "%baselines%"`).Sort().Check(testkit.Rows(
   710  		"milevadb_capture_plan_baselines off",
   711  		"milevadb_evolve_plan_baselines off",
   712  		"milevadb_use_plan_baselines on"))
   713  	tk.MustQuery(`show global variables like "%baselines%"`).Sort().Check(testkit.Rows(
   714  		"milevadb_capture_plan_baselines off",
   715  		"milevadb_evolve_plan_baselines off",
   716  		"milevadb_use_plan_baselines on"))
   717  }
   718  
   719  func (s *testSuite) TestCaptureBaselinesScope(c *C) {
   720  	tk1 := testkit.NewTestKit(c, s.causetstore)
   721  	tk2 := testkit.NewTestKit(c, s.causetstore)
   722  	s.cleanBindingEnv(tk1)
   723  	tk1.MustQuery(`show stochastik variables like "milevadb_capture_plan_baselines"`).Check(testkit.Rows(
   724  		"milevadb_capture_plan_baselines off",
   725  	))
   726  	tk1.MustQuery(`show global variables like "milevadb_capture_plan_baselines"`).Check(testkit.Rows(
   727  		"milevadb_capture_plan_baselines off",
   728  	))
   729  	tk1.MustQuery(`select @@stochastik.milevadb_capture_plan_baselines`).Check(testkit.Rows(
   730  		"off",
   731  	))
   732  	tk1.MustQuery(`select @@global.milevadb_capture_plan_baselines`).Check(testkit.Rows(
   733  		"off",
   734  	))
   735  
   736  	tk1.MustInterDirc("set @@stochastik.milevadb_capture_plan_baselines = on")
   737  	defer func() {
   738  		tk1.MustInterDirc(" set @@stochastik.milevadb_capture_plan_baselines = off")
   739  	}()
   740  	tk1.MustQuery(`show stochastik variables like "milevadb_capture_plan_baselines"`).Check(testkit.Rows(
   741  		"milevadb_capture_plan_baselines on",
   742  	))
   743  	tk1.MustQuery(`show global variables like "milevadb_capture_plan_baselines"`).Check(testkit.Rows(
   744  		"milevadb_capture_plan_baselines off",
   745  	))
   746  	tk1.MustQuery(`select @@stochastik.milevadb_capture_plan_baselines`).Check(testkit.Rows(
   747  		"on",
   748  	))
   749  	tk1.MustQuery(`select @@global.milevadb_capture_plan_baselines`).Check(testkit.Rows(
   750  		"off",
   751  	))
   752  	tk2.MustQuery(`show stochastik variables like "milevadb_capture_plan_baselines"`).Check(testkit.Rows(
   753  		"milevadb_capture_plan_baselines on",
   754  	))
   755  	tk2.MustQuery(`show global variables like "milevadb_capture_plan_baselines"`).Check(testkit.Rows(
   756  		"milevadb_capture_plan_baselines off",
   757  	))
   758  	tk2.MustQuery(`select @@stochastik.milevadb_capture_plan_baselines`).Check(testkit.Rows(
   759  		"on",
   760  	))
   761  	tk2.MustQuery(`select @@global.milevadb_capture_plan_baselines`).Check(testkit.Rows(
   762  		"off",
   763  	))
   764  }
   765  
   766  func (s *testSuite) TestDuplicateBindings(c *C) {
   767  	tk := testkit.NewTestKit(c, s.causetstore)
   768  	s.cleanBindingEnv(tk)
   769  	tk.MustInterDirc("use test")
   770  	tk.MustInterDirc("drop causet if exists t")
   771  	tk.MustInterDirc("create causet t(a int, b int, index idx(a))")
   772  	tk.MustInterDirc("create global binding for select * from t using select * from t use index(idx);")
   773  	rows := tk.MustQuery("show global bindings").Rows()
   774  	c.Assert(len(rows), Equals, 1)
   775  	createTime := rows[0][4]
   776  	time.Sleep(1000000)
   777  	tk.MustInterDirc("create global binding for select * from t using select * from t use index(idx);")
   778  	rows = tk.MustQuery("show global bindings").Rows()
   779  	c.Assert(len(rows), Equals, 1)
   780  	c.Assert(createTime == rows[0][4], Equals, false)
   781  
   782  	tk.MustInterDirc("create stochastik binding for select * from t using select * from t use index(idx);")
   783  	rows = tk.MustQuery("show stochastik bindings").Rows()
   784  	c.Assert(len(rows), Equals, 1)
   785  	createTime = rows[0][4]
   786  	time.Sleep(1000000)
   787  	tk.MustInterDirc("create stochastik binding for select * from t using select * from t use index(idx);")
   788  	rows = tk.MustQuery("show stochastik bindings").Rows()
   789  	c.Assert(len(rows), Equals, 1)
   790  	c.Assert(createTime == rows[0][4], Equals, false)
   791  }
   792  
   793  func (s *testSuite) TestStmtHints(c *C) {
   794  	tk := testkit.NewTestKit(c, s.causetstore)
   795  	s.cleanBindingEnv(tk)
   796  	tk.MustInterDirc("use test")
   797  	tk.MustInterDirc("drop causet if exists t")
   798  	tk.MustInterDirc("create causet t(a int, b int, index idx(a))")
   799  	tk.MustInterDirc("create global binding for select * from t using select /*+ MAX_EXECUTION_TIME(100), MEMORY_QUOTA(1 GB) */ * from t use index(idx)")
   800  	tk.MustQuery("select * from t")
   801  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.MemQuotaQuery, Equals, int64(1073741824))
   802  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.MaxInterDircutionTime, Equals, uint64(100))
   803  	tk.MustQuery("select a, b from t")
   804  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.MemQuotaQuery, Equals, int64(0))
   805  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.MaxInterDircutionTime, Equals, uint64(0))
   806  }
   807  
   808  func (s *testSuite) TestReloadBindings(c *C) {
   809  	tk := testkit.NewTestKit(c, s.causetstore)
   810  	s.cleanBindingEnv(tk)
   811  	tk.MustInterDirc("use test")
   812  	tk.MustInterDirc("drop causet if exists t")
   813  	tk.MustInterDirc("create causet t(a int, b int, index idx(a))")
   814  	tk.MustInterDirc("create global binding for select * from t using select * from t use index(idx)")
   815  	rows := tk.MustQuery("show global bindings").Rows()
   816  	c.Assert(len(rows), Equals, 1)
   817  	rows = tk.MustQuery("select * from allegrosql.bind_info").Rows()
   818  	c.Assert(len(rows), Equals, 1)
   819  	tk.MustInterDirc("truncate causet allegrosql.bind_info")
   820  	c.Assert(s.petri.BindHandle().UFIDelate(false), IsNil)
   821  	rows = tk.MustQuery("show global bindings").Rows()
   822  	c.Assert(len(rows), Equals, 1)
   823  	c.Assert(s.petri.BindHandle().UFIDelate(true), IsNil)
   824  	rows = tk.MustQuery("show global bindings").Rows()
   825  	c.Assert(len(rows), Equals, 1)
   826  	tk.MustInterDirc("admin reload bindings")
   827  	rows = tk.MustQuery("show global bindings").Rows()
   828  	c.Assert(len(rows), Equals, 0)
   829  }
   830  
   831  func (s *testSuite) TestDefaultDB(c *C) {
   832  	tk := testkit.NewTestKit(c, s.causetstore)
   833  	s.cleanBindingEnv(tk)
   834  	tk.MustInterDirc("use test")
   835  	tk.MustInterDirc("create causet t(a int, b int, index idx(a))")
   836  	tk.MustInterDirc("create global binding for select * from test.t using select * from test.t use index(idx)")
   837  	tk.MustInterDirc("use allegrosql")
   838  	tk.MustQuery("select * from test.t")
   839  	// Even in another database, we could still use the bindings.
   840  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:idx")
   841  	tk.MustInterDirc("drop global binding for select * from test.t")
   842  	tk.MustQuery("show global bindings").Check(testkit.Rows())
   843  
   844  	tk.MustInterDirc("use test")
   845  	tk.MustInterDirc("create stochastik binding for select * from test.t using select * from test.t use index(idx)")
   846  	tk.MustInterDirc("use allegrosql")
   847  	tk.MustQuery("select * from test.t")
   848  	// Even in another database, we could still use the bindings.
   849  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:idx")
   850  	tk.MustInterDirc("drop stochastik binding for select * from test.t")
   851  	tk.MustQuery("show stochastik bindings").Check(testkit.Rows())
   852  }
   853  
   854  func (s *testSuite) TestEvolveInvalidBindings(c *C) {
   855  	tk := testkit.NewTestKit(c, s.causetstore)
   856  	s.cleanBindingEnv(tk)
   857  	tk.MustInterDirc("use test")
   858  	tk.MustInterDirc("drop causet if exists t")
   859  	tk.MustInterDirc("create causet t(a int, b int, index idx_a(a))")
   860  	tk.MustInterDirc("create global binding for select * from t where a > 10 using select /*+ USE_INDEX(t) */ * from t where a > 10")
   861  	// Manufacture a rejected binding by reploging allegrosql.bind_info.
   862  	tk.MustInterDirc("insert into allegrosql.bind_info values('select * from t where a > ?', 'select /*+ USE_INDEX(t,idx_a) */ * from t where a > 10', 'test', 'rejected', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" +
   863  		bindinfo.Manual + "')")
   864  	tk.MustQuery("select bind_sql, status from allegrosql.bind_info").Sort().Check(testkit.Rows(
   865  		"select /*+ USE_INDEX(t) */ * from t where a > 10 using",
   866  		"select /*+ USE_INDEX(t,idx_a) */ * from t where a > 10 rejected",
   867  	))
   868  	// Reload cache from allegrosql.bind_info.
   869  	s.petri.BindHandle().Clear()
   870  	c.Assert(s.petri.BindHandle().UFIDelate(true), IsNil)
   871  
   872  	tk.MustInterDirc("alter causet t drop index idx_a")
   873  	tk.MustInterDirc("admin evolve bindings")
   874  	c.Assert(s.petri.BindHandle().UFIDelate(false), IsNil)
   875  	rows := tk.MustQuery("show global bindings").Sort().Rows()
   876  	c.Assert(len(rows), Equals, 2)
   877  	// Make sure this "using" binding is not overrided.
   878  	c.Assert(rows[0][1], Equals, "select /*+ USE_INDEX(t) */ * from t where a > 10")
   879  	status := rows[0][3].(string)
   880  	c.Assert(status == "using", IsTrue)
   881  	c.Assert(rows[1][1], Equals, "select /*+ USE_INDEX(t,idx_a) */ * from t where a > 10")
   882  	status = rows[1][3].(string)
   883  	c.Assert(status == "using" || status == "rejected", IsTrue)
   884  }
   885  
   886  func (s *testSuite) TestOutdatedSchemaReplicant(c *C) {
   887  	tk := testkit.NewTestKit(c, s.causetstore)
   888  	s.cleanBindingEnv(tk)
   889  	tk.MustInterDirc("use test")
   890  	tk.MustInterDirc("drop causet if exists t")
   891  	tk.MustInterDirc("create causet t(a int, b int, index idx(a))")
   892  	tk.MustInterDirc("create global binding for select * from t using select * from t use index(idx)")
   893  	c.Assert(s.petri.BindHandle().UFIDelate(false), IsNil)
   894  	tk.MustInterDirc("truncate causet allegrosql.bind_info")
   895  	tk.MustInterDirc("create global binding for select * from t using select * from t use index(idx)")
   896  }
   897  
   898  func (s *testSuite) TestPrivileges(c *C) {
   899  	tk := testkit.NewTestKit(c, s.causetstore)
   900  	s.cleanBindingEnv(tk)
   901  	tk.MustInterDirc("use test")
   902  	tk.MustInterDirc("drop causet if exists t")
   903  	tk.MustInterDirc("create causet t(a int, b int, index idx(a))")
   904  	tk.MustInterDirc("create global binding for select * from t using select * from t use index(idx)")
   905  	c.Assert(tk.Se.Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil), IsTrue)
   906  	rows := tk.MustQuery("show global bindings").Rows()
   907  	c.Assert(len(rows), Equals, 1)
   908  	tk.MustInterDirc("create user test@'%'")
   909  	c.Assert(tk.Se.Auth(&auth.UserIdentity{Username: "test", Hostname: "%"}, nil, nil), IsTrue)
   910  	rows = tk.MustQuery("show global bindings").Rows()
   911  	c.Assert(len(rows), Equals, 0)
   912  }
   913  
   914  func (s *testSuite) TestHintsSetEvolveTask(c *C) {
   915  	tk := testkit.NewTestKit(c, s.causetstore)
   916  	s.cleanBindingEnv(tk)
   917  	tk.MustInterDirc("use test")
   918  	tk.MustInterDirc("drop causet if exists t")
   919  	tk.MustInterDirc("create causet t(a int, index idx_a(a))")
   920  	tk.MustInterDirc("create global binding for select * from t where a > 10 using select * from t ignore index(idx_a) where a > 10")
   921  	tk.MustInterDirc("set @@milevadb_evolve_plan_baselines=1")
   922  	tk.MustQuery("select * from t use index(idx_a) where a > 0")
   923  	bindHandle := s.petri.BindHandle()
   924  	bindHandle.SaveEvolveTasksToStore()
   925  	// Verify the added Binding for evolution contains valid ID and Hint, otherwise, panic may happen.
   926  	allegrosql, hash := BerolinaSQL.NormalizeDigest("select * from t where a > ?")
   927  	bindData := bindHandle.GetBindRecord(hash, allegrosql, "test")
   928  	c.Check(bindData, NotNil)
   929  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where a > ?")
   930  	c.Assert(len(bindData.Bindings), Equals, 2)
   931  	bind := bindData.Bindings[1]
   932  	c.Assert(bind.Status, Equals, bindinfo.PendingVerify)
   933  	c.Assert(bind.ID, Not(Equals), "")
   934  	c.Assert(bind.Hint, NotNil)
   935  }
   936  
   937  func (s *testSuite) TestHintsSetID(c *C) {
   938  	tk := testkit.NewTestKit(c, s.causetstore)
   939  	s.cleanBindingEnv(tk)
   940  	tk.MustInterDirc("use test")
   941  	tk.MustInterDirc("drop causet if exists t")
   942  	tk.MustInterDirc("create causet t(a int, index idx_a(a))")
   943  	tk.MustInterDirc("create global binding for select * from t where a > 10 using select /*+ use_index(test.t, idx_a) */ * from t where a > 10")
   944  	bindHandle := s.petri.BindHandle()
   945  	// Verify the added Binding contains ID with restored query causet.
   946  	allegrosql, hash := BerolinaSQL.NormalizeDigest("select * from t where a > ?")
   947  	bindData := bindHandle.GetBindRecord(hash, allegrosql, "test")
   948  	c.Check(bindData, NotNil)
   949  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where a > ?")
   950  	c.Assert(len(bindData.Bindings), Equals, 1)
   951  	bind := bindData.Bindings[0]
   952  	c.Assert(bind.ID, Equals, "use_index(@`sel_1` `test`.`t` `idx_a`)")
   953  
   954  	s.cleanBindingEnv(tk)
   955  	tk.MustInterDirc("create global binding for select * from t where a > 10 using select /*+ use_index(t, idx_a) */ * from t where a > 10")
   956  	bindData = bindHandle.GetBindRecord(hash, allegrosql, "test")
   957  	c.Check(bindData, NotNil)
   958  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where a > ?")
   959  	c.Assert(len(bindData.Bindings), Equals, 1)
   960  	bind = bindData.Bindings[0]
   961  	c.Assert(bind.ID, Equals, "use_index(@`sel_1` `test`.`t` `idx_a`)")
   962  
   963  	s.cleanBindingEnv(tk)
   964  	tk.MustInterDirc("create global binding for select * from t where a > 10 using select /*+ use_index(@sel_1 t, idx_a) */ * from t where a > 10")
   965  	bindData = bindHandle.GetBindRecord(hash, allegrosql, "test")
   966  	c.Check(bindData, NotNil)
   967  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where a > ?")
   968  	c.Assert(len(bindData.Bindings), Equals, 1)
   969  	bind = bindData.Bindings[0]
   970  	c.Assert(bind.ID, Equals, "use_index(@`sel_1` `test`.`t` `idx_a`)")
   971  
   972  	s.cleanBindingEnv(tk)
   973  	tk.MustInterDirc("create global binding for select * from t where a > 10 using select /*+ use_index(@qb1 t, idx_a) qb_name(qb1) */ * from t where a > 10")
   974  	bindData = bindHandle.GetBindRecord(hash, allegrosql, "test")
   975  	c.Check(bindData, NotNil)
   976  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where a > ?")
   977  	c.Assert(len(bindData.Bindings), Equals, 1)
   978  	bind = bindData.Bindings[0]
   979  	c.Assert(bind.ID, Equals, "use_index(@`sel_1` `test`.`t` `idx_a`)")
   980  
   981  	s.cleanBindingEnv(tk)
   982  	tk.MustInterDirc("create global binding for select * from t where a > 10 using select /*+ use_index(T, IDX_A) */ * from t where a > 10")
   983  	bindData = bindHandle.GetBindRecord(hash, allegrosql, "test")
   984  	c.Check(bindData, NotNil)
   985  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where a > ?")
   986  	c.Assert(len(bindData.Bindings), Equals, 1)
   987  	bind = bindData.Bindings[0]
   988  	c.Assert(bind.ID, Equals, "use_index(@`sel_1` `test`.`t` `idx_a`)")
   989  
   990  	s.cleanBindingEnv(tk)
   991  	err := tk.InterDircToErr("create global binding for select * from t using select /*+ non_exist_hint() */ * from t")
   992  	c.Assert(terror.ErrorEqual(err, BerolinaSQL.ErrWarnOptimizerHintParseError), IsTrue)
   993  	tk.MustInterDirc("create global binding for select * from t where a > 10 using select * from t where a > 10")
   994  	bindData = bindHandle.GetBindRecord(hash, allegrosql, "test")
   995  	c.Check(bindData, NotNil)
   996  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where a > ?")
   997  	c.Assert(len(bindData.Bindings), Equals, 1)
   998  	bind = bindData.Bindings[0]
   999  	c.Assert(bind.ID, Equals, "")
  1000  }
  1001  
  1002  func (s *testSuite) TestCaptureCausetBaselineIgnoreTiFlash(c *C) {
  1003  	tk := testkit.NewTestKit(c, s.causetstore)
  1004  	s.cleanBindingEnv(tk)
  1005  	stmtsummary.StmtSummaryByDigestMap.Clear()
  1006  	tk.MustInterDirc("use test")
  1007  	tk.MustInterDirc("drop causet if exists t")
  1008  	tk.MustInterDirc("create causet t(a int, b int, key(a), key(b))")
  1009  	c.Assert(tk.Se.Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil), IsTrue)
  1010  	tk.MustInterDirc("select * from t")
  1011  	tk.MustInterDirc("select * from t")
  1012  	// Create virtual tiflash replica info.
  1013  	dom := petri.GetPetri(tk.Se)
  1014  	is := dom.SchemaReplicant()
  1015  	EDB, exists := is.SchemaByName(perceptron.NewCIStr("test"))
  1016  	c.Assert(exists, IsTrue)
  1017  	for _, tblInfo := range EDB.Tables {
  1018  		if tblInfo.Name.L == "t" {
  1019  			tblInfo.TiFlashReplica = &perceptron.TiFlashReplicaInfo{
  1020  				Count:     1,
  1021  				Available: true,
  1022  			}
  1023  		}
  1024  	}
  1025  	// Here the plan is the TiFlash plan.
  1026  	rows := tk.MustQuery("explain select * from t").Rows()
  1027  	c.Assert(fmt.Sprintf("%v", rows[len(rows)-1][2]), Equals, "cop[tiflash]")
  1028  
  1029  	tk.MustQuery("show global bindings").Check(testkit.Rows())
  1030  	tk.MustInterDirc("admin capture bindings")
  1031  	// Don't have the TiFlash plan even we have TiFlash replica.
  1032  	rows = tk.MustQuery("show global bindings").Rows()
  1033  	c.Assert(len(rows), Equals, 1)
  1034  	c.Assert(rows[0][0], Equals, "select * from t")
  1035  	c.Assert(rows[0][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` )*/ * FROM `t`")
  1036  }
  1037  
  1038  func (s *testSuite) TestNotEvolveCausetForReadStorageHint(c *C) {
  1039  	tk := testkit.NewTestKit(c, s.causetstore)
  1040  	s.cleanBindingEnv(tk)
  1041  	tk.MustInterDirc("use test")
  1042  	tk.MustInterDirc("drop causet if exists t")
  1043  	tk.MustInterDirc("create causet t(a int, b int, index idx_a(a), index idx_b(b))")
  1044  	tk.MustInterDirc("insert into t values (1,1), (2,2), (3,3), (4,4), (5,5), (6,6), (7,7), (8,8), (9,9), (10,10)")
  1045  	tk.MustInterDirc("analyze causet t")
  1046  	// Create virtual tiflash replica info.
  1047  	dom := petri.GetPetri(tk.Se)
  1048  	is := dom.SchemaReplicant()
  1049  	EDB, exists := is.SchemaByName(perceptron.NewCIStr("test"))
  1050  	c.Assert(exists, IsTrue)
  1051  	for _, tblInfo := range EDB.Tables {
  1052  		if tblInfo.Name.L == "t" {
  1053  			tblInfo.TiFlashReplica = &perceptron.TiFlashReplicaInfo{
  1054  				Count:     1,
  1055  				Available: true,
  1056  			}
  1057  		}
  1058  	}
  1059  
  1060  	// Make sure the best plan of the ALLEGROALLEGROSQL is use EinsteinDB index.
  1061  	tk.MustInterDirc("set @@stochastik.milevadb_interlock_concurrency = 4;")
  1062  	rows := tk.MustQuery("explain select * from t where a >= 11 and b >= 11").Rows()
  1063  	c.Assert(fmt.Sprintf("%v", rows[len(rows)-1][2]), Equals, "cop[einsteindb]")
  1064  
  1065  	tk.MustInterDirc("create global binding for select * from t where a >= 1 and b >= 1 using select /*+ read_from_storage(tiflash[t]) */ * from t where a >= 1 and b >= 1")
  1066  	tk.MustInterDirc("set @@milevadb_evolve_plan_baselines=1")
  1067  
  1068  	// Even if index of EinsteinDB has lower cost, it chooses TiFlash.
  1069  	rows = tk.MustQuery("explain select * from t where a >= 11 and b >= 11").Rows()
  1070  	c.Assert(fmt.Sprintf("%v", rows[len(rows)-1][2]), Equals, "cop[tiflash]")
  1071  
  1072  	tk.MustInterDirc("admin flush bindings")
  1073  	rows = tk.MustQuery("show global bindings").Rows()
  1074  	// None evolve task, because of the origin binding is a read_from_storage binding.
  1075  	c.Assert(len(rows), Equals, 1)
  1076  	c.Assert(rows[0][1], Equals, "select /*+ read_from_storage(tiflash[t]) */ * from t where a >= 1 and b >= 1")
  1077  	c.Assert(rows[0][3], Equals, "using")
  1078  }
  1079  
  1080  func (s *testSuite) TestBindingWithIsolationRead(c *C) {
  1081  	tk := testkit.NewTestKit(c, s.causetstore)
  1082  	s.cleanBindingEnv(tk)
  1083  	tk.MustInterDirc("use test")
  1084  	tk.MustInterDirc("drop causet if exists t")
  1085  	tk.MustInterDirc("create causet t(a int, b int, index idx_a(a), index idx_b(b))")
  1086  	tk.MustInterDirc("insert into t values (1,1), (2,2), (3,3), (4,4), (5,5), (6,6), (7,7), (8,8), (9,9), (10,10)")
  1087  	tk.MustInterDirc("analyze causet t")
  1088  	// Create virtual tiflash replica info.
  1089  	dom := petri.GetPetri(tk.Se)
  1090  	is := dom.SchemaReplicant()
  1091  	EDB, exists := is.SchemaByName(perceptron.NewCIStr("test"))
  1092  	c.Assert(exists, IsTrue)
  1093  	for _, tblInfo := range EDB.Tables {
  1094  		if tblInfo.Name.L == "t" {
  1095  			tblInfo.TiFlashReplica = &perceptron.TiFlashReplicaInfo{
  1096  				Count:     1,
  1097  				Available: true,
  1098  			}
  1099  		}
  1100  	}
  1101  	tk.MustInterDirc("create global binding for select * from t where a >= 1 and b >= 1 using select * from t use index(idx_a) where a >= 1 and b >= 1")
  1102  	tk.MustInterDirc("set @@milevadb_use_plan_baselines = 1")
  1103  	rows := tk.MustQuery("explain select * from t where a >= 11 and b >= 11").Rows()
  1104  	c.Assert(rows[len(rows)-1][2], Equals, "cop[einsteindb]")
  1105  	// Even if we build a binding use index for ALLEGROALLEGROSQL, but after we set the isolation read for TiFlash, it choose TiFlash instead of index of EinsteinDB.
  1106  	tk.MustInterDirc("set @@milevadb_isolation_read_engines = \"tiflash\"")
  1107  	rows = tk.MustQuery("explain select * from t where a >= 11 and b >= 11").Rows()
  1108  	c.Assert(rows[len(rows)-1][2], Equals, "cop[tiflash]")
  1109  }
  1110  
  1111  func (s *testSuite) TestReCreateBindAfterEvolveCauset(c *C) {
  1112  	tk := testkit.NewTestKit(c, s.causetstore)
  1113  	s.cleanBindingEnv(tk)
  1114  	tk.MustInterDirc("use test")
  1115  	tk.MustInterDirc("drop causet if exists t")
  1116  	tk.MustInterDirc("create causet t(a int, b int, c int, index idx_a(a), index idx_b(b), index idx_c(c))")
  1117  	tk.MustInterDirc("insert into t values (1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5)")
  1118  	tk.MustInterDirc("analyze causet t")
  1119  	tk.MustInterDirc("create global binding for select * from t where a >= 1 and b >= 1 using select * from t use index(idx_a) where a >= 1 and b >= 1")
  1120  	tk.MustInterDirc("set @@milevadb_evolve_plan_baselines=1")
  1121  
  1122  	// It cannot choose causet path although it has lowest cost.
  1123  	tk.MustQuery("select * from t where a >= 0 and b >= 0")
  1124  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:idx_a")
  1125  
  1126  	tk.MustInterDirc("admin flush bindings")
  1127  	rows := tk.MustQuery("show global bindings").Rows()
  1128  	c.Assert(len(rows), Equals, 2)
  1129  	c.Assert(rows[1][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` )*/ * FROM `test`.`t` WHERE `a`>=0 AND `b`>=0")
  1130  	c.Assert(rows[1][3], Equals, "pending verify")
  1131  
  1132  	tk.MustInterDirc("create global binding for select * from t where a >= 1 and b >= 1 using select * from t use index(idx_b) where a >= 1 and b >= 1")
  1133  	rows = tk.MustQuery("show global bindings").Rows()
  1134  	c.Assert(len(rows), Equals, 1)
  1135  	tk.MustQuery("select * from t where a >= 4 and b >= 1")
  1136  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:idx_b")
  1137  }
  1138  
  1139  func (s *testSuite) TestInvisibleIndex(c *C) {
  1140  	tk := testkit.NewTestKit(c, s.causetstore)
  1141  	s.cleanBindingEnv(tk)
  1142  	tk.MustInterDirc("use test")
  1143  	tk.MustInterDirc("drop causet if exists t")
  1144  	tk.MustInterDirc("create causet t(a int, b int, unique idx_a(a), index idx_b(b) invisible)")
  1145  	tk.MustGetErrMsg(
  1146  		"create global binding for select * from t using select * from t use index(idx_b) ",
  1147  		"[causet:1176]Key 'idx_b' doesn't exist in causet 't'")
  1148  
  1149  	// Create bind using index
  1150  	tk.MustInterDirc("create global binding for select * from t using select * from t use index(idx_a) ")
  1151  
  1152  	tk.MustQuery("select * from t")
  1153  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:idx_a")
  1154  	c.Assert(tk.MustUseIndex("select * from t", "idx_a(a)"), IsTrue)
  1155  
  1156  	tk.MustInterDirc(`prepare stmt1 from 'select * from t'`)
  1157  	tk.MustInterDirc("execute stmt1")
  1158  	c.Assert(len(tk.Se.GetStochastikVars().StmtCtx.IndexNames), Equals, 1)
  1159  	c.Assert(tk.Se.GetStochastikVars().StmtCtx.IndexNames[0], Equals, "t:idx_a")
  1160  
  1161  	// And then make this index invisible
  1162  	tk.MustInterDirc("alter causet t alter index idx_a invisible")
  1163  	tk.MustQuery("select * from t")
  1164  	c.Assert(len(tk.Se.GetStochastikVars().StmtCtx.IndexNames), Equals, 0)
  1165  
  1166  	tk.MustInterDirc("execute stmt1")
  1167  	c.Assert(len(tk.Se.GetStochastikVars().StmtCtx.IndexNames), Equals, 0)
  1168  
  1169  	tk.MustInterDirc("drop binding for select * from t")
  1170  }
  1171  
  1172  func (s *testSuite) TestbindingSource(c *C) {
  1173  	tk := testkit.NewTestKit(c, s.causetstore)
  1174  	s.cleanBindingEnv(tk)
  1175  	tk.MustInterDirc("use test")
  1176  	tk.MustInterDirc("drop causet if exists t")
  1177  	tk.MustInterDirc("create causet t(a int, index idx_a(a))")
  1178  
  1179  	// Test Source for ALLEGROALLEGROSQL created allegrosql
  1180  	tk.MustInterDirc("create global binding for select * from t where a > 10 using select * from t ignore index(idx_a) where a > 10")
  1181  	bindHandle := s.petri.BindHandle()
  1182  	allegrosql, hash := BerolinaSQL.NormalizeDigest("select * from t where a > ?")
  1183  	bindData := bindHandle.GetBindRecord(hash, allegrosql, "test")
  1184  	c.Check(bindData, NotNil)
  1185  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where a > ?")
  1186  	c.Assert(len(bindData.Bindings), Equals, 1)
  1187  	bind := bindData.Bindings[0]
  1188  	c.Assert(bind.Source, Equals, bindinfo.Manual)
  1189  
  1190  	// Test Source for evolved allegrosql
  1191  	tk.MustInterDirc("set @@milevadb_evolve_plan_baselines=1")
  1192  	tk.MustQuery("select * from t where a > 10")
  1193  	bindHandle.SaveEvolveTasksToStore()
  1194  	allegrosql, hash = BerolinaSQL.NormalizeDigest("select * from t where a > ?")
  1195  	bindData = bindHandle.GetBindRecord(hash, allegrosql, "test")
  1196  	c.Check(bindData, NotNil)
  1197  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where a > ?")
  1198  	c.Assert(len(bindData.Bindings), Equals, 2)
  1199  	bind = bindData.Bindings[1]
  1200  	c.Assert(bind.Source, Equals, bindinfo.Evolve)
  1201  	tk.MustInterDirc("set @@milevadb_evolve_plan_baselines=0")
  1202  
  1203  	// Test Source for captured sqls
  1204  	stmtsummary.StmtSummaryByDigestMap.Clear()
  1205  	tk.MustInterDirc("set @@milevadb_capture_plan_baselines = on")
  1206  	defer func() {
  1207  		tk.MustInterDirc("set @@milevadb_capture_plan_baselines = off")
  1208  	}()
  1209  	tk.MustInterDirc("use test")
  1210  	c.Assert(tk.Se.Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil), IsTrue)
  1211  	tk.MustInterDirc("select * from t ignore index(idx_a) where a < 10")
  1212  	tk.MustInterDirc("select * from t ignore index(idx_a) where a < 10")
  1213  	tk.MustInterDirc("admin capture bindings")
  1214  	bindHandle.CaptureBaselines()
  1215  	allegrosql, hash = BerolinaSQL.NormalizeDigest("select * from t where a < ?")
  1216  	bindData = bindHandle.GetBindRecord(hash, allegrosql, "test")
  1217  	c.Check(bindData, NotNil)
  1218  	c.Check(bindData.OriginalALLEGROSQL, Equals, "select * from t where a < ?")
  1219  	c.Assert(len(bindData.Bindings), Equals, 1)
  1220  	bind = bindData.Bindings[0]
  1221  	c.Assert(bind.Source, Equals, bindinfo.Capture)
  1222  }