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 }