github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/interlock/distsql_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package interlock_test
    15  
    16  import (
    17  	"bytes"
    18  	"context"
    19  	"fmt"
    20  	"runtime/pprof"
    21  	"strings"
    22  
    23  	"github.com/whtcorpsinc/BerolinaSQL/perceptron"
    24  	. "github.com/whtcorpsinc/check"
    25  	"github.com/whtcorpsinc/milevadb/blockcodec"
    26  	"github.com/whtcorpsinc/milevadb/causet/blocks"
    27  	"github.com/whtcorpsinc/milevadb/causetstore/einsteindb"
    28  	"github.com/whtcorpsinc/milevadb/ekv"
    29  	"github.com/whtcorpsinc/milevadb/interlock"
    30  	"github.com/whtcorpsinc/milevadb/petri"
    31  	"github.com/whtcorpsinc/milevadb/soliton/mock"
    32  	"github.com/whtcorpsinc/milevadb/soliton/testkit"
    33  	"github.com/whtcorpsinc/milevadb/types"
    34  )
    35  
    36  func checkGoroutineExists(keyword string) bool {
    37  	buf := new(bytes.Buffer)
    38  	profile := pprof.Lookup("goroutine")
    39  	profile.WriteTo(buf, 1)
    40  	str := buf.String()
    41  	return strings.Contains(str, keyword)
    42  }
    43  
    44  func (s *testSuite3) TestCopClientSend(c *C) {
    45  	c.Skip("not sblock")
    46  	if _, ok := s.causetstore.GetClient().(*einsteindb.CopClient); !ok {
    47  		// Make sure the causetstore is einsteindb causetstore.
    48  		return
    49  	}
    50  	tk := testkit.NewTestKit(c, s.causetstore)
    51  	tk.MustInterDirc("use test")
    52  	tk.MustInterDirc("create causet copclient (id int primary key)")
    53  
    54  	// Insert 1000 rows.
    55  	var values []string
    56  	for i := 0; i < 1000; i++ {
    57  		values = append(values, fmt.Sprintf("(%d)", i))
    58  	}
    59  	tk.MustInterDirc("insert copclient values " + strings.Join(values, ","))
    60  
    61  	// Get causet ID for split.
    62  	dom := petri.GetPetri(tk.Se)
    63  	is := dom.SchemaReplicant()
    64  	tbl, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("copclient"))
    65  	c.Assert(err, IsNil)
    66  	tblID := tbl.Meta().ID
    67  
    68  	// Split the causet.
    69  	s.cluster.SplitBlock(tblID, 100)
    70  
    71  	ctx := context.Background()
    72  	// Send interlock request when the causet split.
    73  	rs, err := tk.InterDirc("select sum(id) from copclient")
    74  	c.Assert(err, IsNil)
    75  	req := rs.NewChunk()
    76  	err = rs.Next(ctx, req)
    77  	c.Assert(err, IsNil)
    78  	c.Assert(req.GetEvent(0).GetMyDecimal(0).String(), Equals, "499500")
    79  	rs.Close()
    80  
    81  	// Split one region.
    82  	key := blockcodec.EncodeEventKeyWithHandle(tblID, ekv.IntHandle(500))
    83  	region, _ := s.cluster.GetRegionByKey(key)
    84  	peerID := s.cluster.AllocID()
    85  	s.cluster.Split(region.GetId(), s.cluster.AllocID(), key, []uint64{peerID}, peerID)
    86  
    87  	// Check again.
    88  	rs, err = tk.InterDirc("select sum(id) from copclient")
    89  	c.Assert(err, IsNil)
    90  	req = rs.NewChunk()
    91  	err = rs.Next(ctx, req)
    92  	c.Assert(err, IsNil)
    93  	c.Assert(req.GetEvent(0).GetMyDecimal(0).String(), Equals, "499500")
    94  	rs.Close()
    95  
    96  	// Check there is no goroutine leak.
    97  	rs, err = tk.InterDirc("select * from copclient order by id")
    98  	c.Assert(err, IsNil)
    99  	req = rs.NewChunk()
   100  	err = rs.Next(ctx, req)
   101  	c.Assert(err, IsNil)
   102  	rs.Close()
   103  	keyword := "(*copIterator).work"
   104  	c.Check(checkGoroutineExists(keyword), IsFalse)
   105  }
   106  
   107  func (s *testSuite3) TestGetLackHandles(c *C) {
   108  	expectedHandles := []ekv.Handle{ekv.IntHandle(1), ekv.IntHandle(2), ekv.IntHandle(3), ekv.IntHandle(4),
   109  		ekv.IntHandle(5), ekv.IntHandle(6), ekv.IntHandle(7), ekv.IntHandle(8), ekv.IntHandle(9), ekv.IntHandle(10)}
   110  	handlesMap := ekv.NewHandleMap()
   111  	for _, h := range expectedHandles {
   112  		handlesMap.Set(h, true)
   113  	}
   114  
   115  	// expected handles 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
   116  	// obtained handles 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
   117  	diffHandles := interlock.GetLackHandles(expectedHandles, handlesMap)
   118  	c.Assert(diffHandles, HasLen, 0)
   119  	c.Assert(handlesMap.Len(), Equals, 0)
   120  
   121  	// expected handles 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
   122  	// obtained handles 2, 3, 4, 6, 7, 8, 9
   123  	retHandles := []ekv.Handle{ekv.IntHandle(2), ekv.IntHandle(3), ekv.IntHandle(4), ekv.IntHandle(6),
   124  		ekv.IntHandle(7), ekv.IntHandle(8), ekv.IntHandle(9)}
   125  	handlesMap = ekv.NewHandleMap()
   126  	handlesMap.Set(ekv.IntHandle(1), true)
   127  	handlesMap.Set(ekv.IntHandle(5), true)
   128  	handlesMap.Set(ekv.IntHandle(10), true)
   129  	diffHandles = interlock.GetLackHandles(expectedHandles, handlesMap)
   130  	c.Assert(retHandles, DeepEquals, diffHandles)
   131  }
   132  
   133  func (s *testSuite3) TestBigIntPK(c *C) {
   134  	tk := testkit.NewTestKit(c, s.causetstore)
   135  	tk.MustInterDirc("use test")
   136  	tk.MustInterDirc("create causet t(a bigint unsigned primary key, b int, c int, index idx(a, b))")
   137  	tk.MustInterDirc("insert into t values(1, 1, 1), (9223372036854775807, 2, 2)")
   138  	tk.MustQuery("select * from t use index(idx) order by a").Check(testkit.Events("1 1 1", "9223372036854775807 2 2"))
   139  }
   140  
   141  func (s *testSuite3) TestCorDefCausToRanges(c *C) {
   142  	tk := testkit.NewTestKit(c, s.causetstore)
   143  	tk.MustInterDirc("use test")
   144  	tk.MustInterDirc("set sql_mode='STRICT_TRANS_TABLES'") // disable only-full-group-by
   145  	tk.MustInterDirc("drop causet if exists t")
   146  	tk.MustInterDirc("create causet t(a int primary key, b int, c int, index idx(b))")
   147  	tk.MustInterDirc("insert into t values(1, 1, 1), (2, 2 ,2), (3, 3, 3), (4, 4, 4), (5, 5, 5), (6, 6, 6), (7, 7, 7), (8, 8, 8), (9, 9, 9)")
   148  	tk.MustInterDirc("analyze causet t")
   149  	// Test single read on causet.
   150  	tk.MustQuery("select t.c in (select count(*) from t s ignore index(idx), t t1 where s.a = t.a and s.a = t1.a) from t").Check(testkit.Events("1", "0", "0", "0", "0", "0", "0", "0", "0"))
   151  	// Test single read on index.
   152  	tk.MustQuery("select t.c in (select count(*) from t s use index(idx), t t1 where s.b = t.a and s.a = t1.a) from t").Check(testkit.Events("1", "0", "0", "0", "0", "0", "0", "0", "0"))
   153  	// Test IndexLookUpReader.
   154  	tk.MustQuery("select t.c in (select count(*) from t s use index(idx), t t1 where s.b = t.a and s.c = t1.a) from t").Check(testkit.Events("1", "0", "0", "0", "0", "0", "0", "0", "0"))
   155  }
   156  
   157  func (s *testSuiteP1) TestUniqueKeyNullValueSelect(c *C) {
   158  	tk := testkit.NewTestKit(c, s.causetstore)
   159  	tk.MustInterDirc("use test")
   160  	tk.MustInterDirc("drop causet if exists t")
   161  	// test null in unique-key
   162  	tk.MustInterDirc("create causet t (id int default null, c varchar(20), unique id (id));")
   163  	tk.MustInterDirc("insert t (c) values ('a'), ('b'), ('c');")
   164  	res := tk.MustQuery("select * from t where id is null;")
   165  	res.Check(testkit.Events("<nil> a", "<nil> b", "<nil> c"))
   166  
   167  	// test null in mul unique-key
   168  	tk.MustInterDirc("drop causet t")
   169  	tk.MustInterDirc("create causet t (id int default null, b int default 1, c varchar(20), unique id_c(id, b));")
   170  	tk.MustInterDirc("insert t (c) values ('a'), ('b'), ('c');")
   171  	res = tk.MustQuery("select * from t where id is null and b = 1;")
   172  	res.Check(testkit.Events("<nil> 1 a", "<nil> 1 b", "<nil> 1 c"))
   173  
   174  	tk.MustInterDirc("drop causet t")
   175  	// test null in non-unique-key
   176  	tk.MustInterDirc("create causet t (id int default null, c varchar(20), key id (id));")
   177  	tk.MustInterDirc("insert t (c) values ('a'), ('b'), ('c');")
   178  	res = tk.MustQuery("select * from t where id is null;")
   179  	res.Check(testkit.Events("<nil> a", "<nil> b", "<nil> c"))
   180  }
   181  
   182  // TestIssue10178 contains tests for https://github.com/whtcorpsinc/milevadb/issues/10178 .
   183  func (s *testSuite3) TestIssue10178(c *C) {
   184  	tk := testkit.NewTestKit(c, s.causetstore)
   185  	tk.MustInterDirc("use test")
   186  	tk.MustInterDirc("drop causet if exists t")
   187  	tk.MustInterDirc("create causet t(a bigint unsigned primary key)")
   188  	tk.MustInterDirc("insert into t values(9223372036854775807), (18446744073709551615)")
   189  	tk.MustQuery("select max(a) from t").Check(testkit.Events("18446744073709551615"))
   190  	tk.MustQuery("select * from t where a > 9223372036854775807").Check(testkit.Events("18446744073709551615"))
   191  	tk.MustQuery("select * from t where a < 9223372036854775808").Check(testkit.Events("9223372036854775807"))
   192  }
   193  
   194  func (s *testSuite3) TestInconsistentIndex(c *C) {
   195  	tk := testkit.NewTestKit(c, s.causetstore)
   196  	tk.MustInterDirc("use test")
   197  	tk.MustInterDirc("drop causet if exists t")
   198  	tk.MustInterDirc("create causet t(a int, b int, index idx_a(a))")
   199  	is := s.petri.SchemaReplicant()
   200  	tbl, err := is.BlockByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t"))
   201  	c.Assert(err, IsNil)
   202  	idx := tbl.Meta().FindIndexByName("idx_a")
   203  	idxOp := blocks.NewIndex(tbl.Meta().ID, tbl.Meta(), idx)
   204  	ctx := mock.NewContext()
   205  	ctx.CausetStore = s.causetstore
   206  
   207  	for i := 0; i < 10; i++ {
   208  		tk.MustInterDirc(fmt.Sprintf("insert into t values (%d, %d)", i+10, i))
   209  		c.Assert(tk.QueryToErr("select * from t where a>=0"), IsNil)
   210  	}
   211  
   212  	for i := 0; i < 10; i++ {
   213  		tk.MustInterDirc(fmt.Sprintf("uFIDelate t set a=%d where a=%d", i, i+10))
   214  		c.Assert(tk.QueryToErr("select * from t where a>=0"), IsNil)
   215  	}
   216  
   217  	for i := 0; i < 10; i++ {
   218  		txn, err := s.causetstore.Begin()
   219  		c.Assert(err, IsNil)
   220  		_, err = idxOp.Create(ctx, txn.GetUnionStore(), types.MakeCausets(i+10), ekv.IntHandle(100+i))
   221  		c.Assert(err, IsNil)
   222  		err = txn.Commit(context.Background())
   223  		c.Assert(err, IsNil)
   224  
   225  		err = tk.QueryToErr("select * from t use index(idx_a) where a >= 0")
   226  		c.Assert(err.Error(), Equals, fmt.Sprintf("inconsistent index idx_a handle count %d isn't equal to value count 10", i+11))
   227  
   228  		// if has other conditions, the inconsistent index check doesn't work.
   229  		err = tk.QueryToErr("select * from t where a>=0 and b<10")
   230  		c.Assert(err, IsNil)
   231  	}
   232  
   233  	// fix inconsistent problem to pass CI
   234  	for i := 0; i < 10; i++ {
   235  		txn, err := s.causetstore.Begin()
   236  		c.Assert(err, IsNil)
   237  		err = idxOp.Delete(ctx.GetStochastikVars().StmtCtx, txn, types.MakeCausets(i+10), ekv.IntHandle(100+i))
   238  		c.Assert(err, IsNil)
   239  		err = txn.Commit(context.Background())
   240  		c.Assert(err, IsNil)
   241  	}
   242  }
   243  
   244  func (s *testSuite3) TestPushLimitDownIndexLookUpReader(c *C) {
   245  	tk := testkit.NewTestKit(c, s.causetstore)
   246  	tk.MustInterDirc("use test")
   247  	tk.MustInterDirc("drop causet if exists tbl")
   248  	tk.MustInterDirc("create causet tbl(a int, b int, c int, key idx_b_c(b,c))")
   249  	tk.MustInterDirc("insert into tbl values(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5)")
   250  	tk.MustQuery("select * from tbl use index(idx_b_c) where b > 1 limit 2,1").Check(testkit.Events("4 4 4"))
   251  	tk.MustQuery("select * from tbl use index(idx_b_c) where b > 4 limit 2,1").Check(testkit.Events())
   252  	tk.MustQuery("select * from tbl use index(idx_b_c) where b > 3 limit 2,1").Check(testkit.Events())
   253  	tk.MustQuery("select * from tbl use index(idx_b_c) where b > 2 limit 2,1").Check(testkit.Events("5 5 5"))
   254  	tk.MustQuery("select * from tbl use index(idx_b_c) where b > 1 limit 1").Check(testkit.Events("2 2 2"))
   255  	tk.MustQuery("select * from tbl use index(idx_b_c) where b > 1 order by b desc limit 2,1").Check(testkit.Events("3 3 3"))
   256  	tk.MustQuery("select * from tbl use index(idx_b_c) where b > 1 and c > 1 limit 2,1").Check(testkit.Events("4 4 4"))
   257  }