github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/soliton/ranger/ranger_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 ranger_test 15 16 import ( 17 "context" 18 "fmt" 19 "testing" 20 21 "github.com/whtcorpsinc/BerolinaSQL" 22 . "github.com/whtcorpsinc/check" 23 "github.com/whtcorpsinc/errors" 24 causetembedded "github.com/whtcorpsinc/milevadb/causet/embedded" 25 "github.com/whtcorpsinc/milevadb/causetstore/mockstore" 26 "github.com/whtcorpsinc/milevadb/ekv" 27 "github.com/whtcorpsinc/milevadb/memex" 28 "github.com/whtcorpsinc/milevadb/petri" 29 "github.com/whtcorpsinc/milevadb/soliton/defCauslate" 30 "github.com/whtcorpsinc/milevadb/soliton/ranger" 31 "github.com/whtcorpsinc/milevadb/soliton/solitonutil" 32 "github.com/whtcorpsinc/milevadb/soliton/testkit" 33 "github.com/whtcorpsinc/milevadb/soliton/testleak" 34 "github.com/whtcorpsinc/milevadb/stochastik" 35 "github.com/whtcorpsinc/milevadb/stochastikctx" 36 "github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx" 37 "github.com/whtcorpsinc/milevadb/types" 38 ) 39 40 func TestT(t *testing.T) { 41 TestingT(t) 42 } 43 44 var _ = SerialSuites(&testRangerSuite{}) 45 46 type testRangerSuite struct { 47 *BerolinaSQL.BerolinaSQL 48 testData solitonutil.TestData 49 } 50 51 func (s *testRangerSuite) SetUpSuite(c *C) { 52 s.BerolinaSQL = BerolinaSQL.New() 53 var err error 54 s.testData, err = solitonutil.LoadTestSuiteData("testdata", "ranger_suite") 55 c.Assert(err, IsNil) 56 } 57 58 func (s *testRangerSuite) TearDownSuite(c *C) { 59 c.Assert(s.testData.GenerateOutputIfNeeded(), IsNil) 60 } 61 62 func newPetriStoreWithBootstrap(c *C) (*petri.Petri, ekv.CausetStorage, error) { 63 causetstore, err := mockstore.NewMockStore() 64 c.Assert(err, IsNil) 65 stochastik.SetSchemaLease(0) 66 stochastik.DisableStats4Test() 67 if err != nil { 68 return nil, nil, errors.Trace(err) 69 } 70 dom, err := stochastik.BootstrapStochastik(causetstore) 71 return dom, causetstore, errors.Trace(err) 72 } 73 74 func (s *testRangerSuite) TestBlockRange(c *C) { 75 defer testleak.AfterTest(c)() 76 dom, causetstore, err := newPetriStoreWithBootstrap(c) 77 defer func() { 78 dom.Close() 79 causetstore.Close() 80 }() 81 c.Assert(err, IsNil) 82 testKit := testkit.NewTestKit(c, causetstore) 83 testKit.MustInterDirc("use test") 84 testKit.MustInterDirc("drop causet if exists t") 85 testKit.MustInterDirc("create causet t(a int, b int, c int unsigned)") 86 87 tests := []struct { 88 exprStr string 89 accessConds string 90 filterConds string 91 resultStr string 92 }{ 93 { 94 exprStr: "a = 1", 95 accessConds: "[eq(test.t.a, 1)]", 96 filterConds: "[]", 97 resultStr: "[[1,1]]", 98 }, 99 { 100 exprStr: "1 = a", 101 accessConds: "[eq(1, test.t.a)]", 102 filterConds: "[]", 103 resultStr: "[[1,1]]", 104 }, 105 { 106 exprStr: "a != 1", 107 accessConds: "[ne(test.t.a, 1)]", 108 filterConds: "[]", 109 resultStr: "[[-inf,1) (1,+inf]]", 110 }, 111 { 112 exprStr: "1 != a", 113 accessConds: "[ne(1, test.t.a)]", 114 filterConds: "[]", 115 resultStr: "[[-inf,1) (1,+inf]]", 116 }, 117 { 118 exprStr: "a > 1", 119 accessConds: "[gt(test.t.a, 1)]", 120 filterConds: "[]", 121 resultStr: "[(1,+inf]]", 122 }, 123 { 124 exprStr: "1 < a", 125 accessConds: "[lt(1, test.t.a)]", 126 filterConds: "[]", 127 resultStr: "[(1,+inf]]", 128 }, 129 { 130 exprStr: "a >= 1", 131 accessConds: "[ge(test.t.a, 1)]", 132 filterConds: "[]", 133 resultStr: "[[1,+inf]]", 134 }, 135 { 136 exprStr: "1 <= a", 137 accessConds: "[le(1, test.t.a)]", 138 filterConds: "[]", 139 resultStr: "[[1,+inf]]", 140 }, 141 { 142 exprStr: "a < 1", 143 accessConds: "[lt(test.t.a, 1)]", 144 filterConds: "[]", 145 resultStr: "[[-inf,1)]", 146 }, 147 { 148 exprStr: "1 > a", 149 accessConds: "[gt(1, test.t.a)]", 150 filterConds: "[]", 151 resultStr: "[[-inf,1)]", 152 }, 153 { 154 exprStr: "a <= 1", 155 accessConds: "[le(test.t.a, 1)]", 156 filterConds: "[]", 157 resultStr: "[[-inf,1]]", 158 }, 159 { 160 exprStr: "1 >= test.t.a", 161 accessConds: "[ge(1, test.t.a)]", 162 filterConds: "[]", 163 resultStr: "[[-inf,1]]", 164 }, 165 { 166 exprStr: "(a)", 167 accessConds: "[test.t.a]", 168 filterConds: "[]", 169 resultStr: "[[-inf,0) (0,+inf]]", 170 }, 171 { 172 exprStr: "a in (1, 3, NULL, 2)", 173 accessConds: "[in(test.t.a, 1, 3, <nil>, 2)]", 174 filterConds: "[]", 175 resultStr: "[[1,1] [2,2] [3,3]]", 176 }, 177 { 178 exprStr: `a IN (8,8,81,45)`, 179 accessConds: "[in(test.t.a, 8, 8, 81, 45)]", 180 filterConds: "[]", 181 resultStr: `[[8,8] [45,45] [81,81]]`, 182 }, 183 { 184 exprStr: "a between 1 and 2", 185 accessConds: "[ge(test.t.a, 1) le(test.t.a, 2)]", 186 filterConds: "[]", 187 resultStr: "[[1,2]]", 188 }, 189 { 190 exprStr: "a not between 1 and 2", 191 accessConds: "[or(lt(test.t.a, 1), gt(test.t.a, 2))]", 192 filterConds: "[]", 193 resultStr: "[[-inf,1) (2,+inf]]", 194 }, 195 { 196 exprStr: "a between 2 and 1", 197 accessConds: "[ge(test.t.a, 2) le(test.t.a, 1)]", 198 filterConds: "[]", 199 resultStr: "[]", 200 }, 201 { 202 exprStr: "a not between 2 and 1", 203 accessConds: "[or(lt(test.t.a, 2), gt(test.t.a, 1))]", 204 filterConds: "[]", 205 resultStr: "[[-inf,+inf]]", 206 }, 207 { 208 exprStr: "a IS NULL", 209 accessConds: "[isnull(test.t.a)]", 210 filterConds: "[]", 211 resultStr: "[]", 212 }, 213 { 214 exprStr: "a IS NOT NULL", 215 accessConds: "[not(isnull(test.t.a))]", 216 filterConds: "[]", 217 resultStr: "[[-inf,+inf]]", 218 }, 219 { 220 exprStr: "a IS TRUE", 221 accessConds: "[istrue(test.t.a)]", 222 filterConds: "[]", 223 resultStr: "[[-inf,0) (0,+inf]]", 224 }, 225 { 226 exprStr: "a IS NOT TRUE", 227 accessConds: "[not(istrue(test.t.a))]", 228 filterConds: "[]", 229 resultStr: "[[0,0]]", 230 }, 231 { 232 exprStr: "a IS FALSE", 233 accessConds: "[isfalse(test.t.a)]", 234 filterConds: "[]", 235 resultStr: "[[0,0]]", 236 }, 237 { 238 exprStr: "a IS NOT FALSE", 239 accessConds: "[not(isfalse(test.t.a))]", 240 filterConds: "[]", 241 resultStr: "[[-inf,0) (0,+inf]]", 242 }, 243 { 244 exprStr: "a = 1 or a = 3 or a = 4 or (a > 1 and (a = -1 or a = 5))", 245 accessConds: "[or(or(eq(test.t.a, 1), eq(test.t.a, 3)), or(eq(test.t.a, 4), and(gt(test.t.a, 1), or(eq(test.t.a, -1), eq(test.t.a, 5)))))]", 246 filterConds: "[]", 247 resultStr: "[[1,1] [3,3] [4,4] [5,5]]", 248 }, 249 { 250 exprStr: "(a = 1 and b = 1) or (a = 2 and b = 2)", 251 accessConds: "[or(eq(test.t.a, 1), eq(test.t.a, 2))]", 252 filterConds: "[or(and(eq(test.t.a, 1), eq(test.t.b, 1)), and(eq(test.t.a, 2), eq(test.t.b, 2)))]", 253 resultStr: "[[1,1] [2,2]]", 254 }, 255 { 256 exprStr: "a = 1 or a = 3 or a = 4 or (b > 1 and (a = -1 or a = 5))", 257 accessConds: "[or(or(eq(test.t.a, 1), eq(test.t.a, 3)), or(eq(test.t.a, 4), or(eq(test.t.a, -1), eq(test.t.a, 5))))]", 258 filterConds: "[or(or(or(eq(test.t.a, 1), eq(test.t.a, 3)), eq(test.t.a, 4)), and(gt(test.t.b, 1), or(eq(test.t.a, -1), eq(test.t.a, 5))))]", 259 resultStr: "[[-1,-1] [1,1] [3,3] [4,4] [5,5]]", 260 }, 261 { 262 exprStr: "a in (1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 2, 3, 4, 4, 1, 2)", 263 accessConds: "[in(test.t.a, 1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 2, 3, 4, 4, 1, 2)]", 264 filterConds: "[]", 265 resultStr: "[[1,1] [2,2] [3,3] [4,4]]", 266 }, 267 { 268 exprStr: "a not in (1, 2, 3)", 269 accessConds: "[not(in(test.t.a, 1, 2, 3))]", 270 filterConds: "[]", 271 resultStr: "[[-inf,1) (3,+inf]]", 272 }, 273 { 274 exprStr: "a > 9223372036854775807", 275 accessConds: "[gt(test.t.a, 9223372036854775807)]", 276 filterConds: "[]", 277 resultStr: "[]", 278 }, 279 { 280 exprStr: "a >= 9223372036854775807", 281 accessConds: "[ge(test.t.a, 9223372036854775807)]", 282 filterConds: "[]", 283 resultStr: "[[9223372036854775807,+inf]]", 284 }, 285 { 286 exprStr: "a < -9223372036854775807", 287 accessConds: "[lt(test.t.a, -9223372036854775807)]", 288 filterConds: "[]", 289 resultStr: "[[-inf,-9223372036854775807)]", 290 }, 291 { 292 exprStr: "a < -9223372036854775808", 293 accessConds: "[lt(test.t.a, -9223372036854775808)]", 294 filterConds: "[]", 295 resultStr: "[]", 296 }, 297 } 298 299 ctx := context.Background() 300 for _, tt := range tests { 301 allegrosql := "select * from t where " + tt.exprStr 302 sctx := testKit.Se.(stochastikctx.Context) 303 stmts, err := stochastik.Parse(sctx, allegrosql) 304 c.Assert(err, IsNil, Commentf("error %v, for expr %s", err, tt.exprStr)) 305 c.Assert(stmts, HasLen, 1) 306 is := petri.GetPetri(sctx).SchemaReplicant() 307 err = causetembedded.Preprocess(sctx, stmts[0], is) 308 c.Assert(err, IsNil, Commentf("error %v, for resolve name, expr %s", err, tt.exprStr)) 309 p, _, err := causetembedded.BuildLogicalCauset(ctx, sctx, stmts[0], is) 310 c.Assert(err, IsNil, Commentf("error %v, for build plan, expr %s", err, tt.exprStr)) 311 selection := p.(causetembedded.LogicalCauset).Children()[0].(*causetembedded.LogicalSelection) 312 conds := make([]memex.Expression, len(selection.Conditions)) 313 for i, cond := range selection.Conditions { 314 conds[i] = memex.PushDownNot(sctx, cond) 315 } 316 tbl := selection.Children()[0].(*causetembedded.DataSource).BlockInfo() 317 defCaus := memex.DefCausInfo2DefCaus(selection.Schema().DeferredCausets, tbl.DeferredCausets[0]) 318 c.Assert(defCaus, NotNil) 319 var filter []memex.Expression 320 conds, filter = ranger.DetachCondsForDeferredCauset(sctx, conds, defCaus) 321 c.Assert(fmt.Sprintf("%s", conds), Equals, tt.accessConds, Commentf("wrong access conditions for expr: %s", tt.exprStr)) 322 c.Assert(fmt.Sprintf("%s", filter), Equals, tt.filterConds, Commentf("wrong filter conditions for expr: %s", tt.exprStr)) 323 result, err := ranger.BuildBlockRange(conds, new(stmtctx.StatementContext), defCaus.RetType) 324 c.Assert(err, IsNil, Commentf("failed to build causet range for expr %s", tt.exprStr)) 325 got := fmt.Sprintf("%v", result) 326 c.Assert(got, Equals, tt.resultStr, Commentf("different for expr %s", tt.exprStr)) 327 } 328 } 329 330 func (s *testRangerSuite) TestIndexRange(c *C) { 331 defer testleak.AfterTest(c)() 332 dom, causetstore, err := newPetriStoreWithBootstrap(c) 333 defer func() { 334 dom.Close() 335 causetstore.Close() 336 }() 337 c.Assert(err, IsNil) 338 testKit := testkit.NewTestKit(c, causetstore) 339 testKit.MustInterDirc("use test") 340 testKit.MustInterDirc("drop causet if exists t") 341 testKit.MustInterDirc(` 342 create causet t( 343 a varchar(50), 344 b int, 345 c double, 346 d varchar(10), 347 e binary(10), 348 f varchar(10) defCauslate utf8mb4_general_ci, 349 index idx_ab(a(50), b), 350 index idx_cb(c, a), 351 index idx_d(d(2)), 352 index idx_e(e(2)), 353 index idx_f(f) 354 )`) 355 356 tests := []struct { 357 indexPos int 358 exprStr string 359 accessConds string 360 filterConds string 361 resultStr string 362 }{ 363 { 364 indexPos: 0, 365 exprStr: `a LIKE 'abc%'`, 366 accessConds: `[like(test.t.a, abc%, 92)]`, 367 filterConds: "[]", 368 resultStr: "[[\"abc\",\"abd\")]", 369 }, 370 { 371 indexPos: 0, 372 exprStr: "a LIKE 'abc_'", 373 accessConds: "[like(test.t.a, abc_, 92)]", 374 filterConds: "[like(test.t.a, abc_, 92)]", 375 resultStr: "[(\"abc\",\"abd\")]", 376 }, 377 { 378 indexPos: 0, 379 exprStr: "a LIKE 'abc'", 380 accessConds: "[eq(test.t.a, abc)]", 381 filterConds: "[]", 382 resultStr: "[[\"abc\",\"abc\"]]", 383 }, 384 { 385 indexPos: 0, 386 exprStr: `a LIKE "ab\_c"`, 387 accessConds: "[eq(test.t.a, ab_c)]", 388 filterConds: "[]", 389 resultStr: "[[\"ab_c\",\"ab_c\"]]", 390 }, 391 { 392 indexPos: 0, 393 exprStr: `a LIKE '%'`, 394 accessConds: "[]", 395 filterConds: `[like(test.t.a, %, 92)]`, 396 resultStr: "[[NULL,+inf]]", 397 }, 398 { 399 indexPos: 0, 400 exprStr: `a LIKE '\%a'`, 401 accessConds: "[eq(test.t.a, %a)]", 402 filterConds: "[]", 403 resultStr: `[["%a","%a"]]`, 404 }, 405 { 406 indexPos: 0, 407 exprStr: `a LIKE "\\"`, 408 accessConds: "[eq(test.t.a, \\)]", 409 filterConds: "[]", 410 resultStr: "[[\"\\\",\"\\\"]]", 411 }, 412 { 413 indexPos: 0, 414 exprStr: `a LIKE "\\\\a%"`, 415 accessConds: `[like(test.t.a, \\a%, 92)]`, 416 filterConds: "[]", 417 resultStr: "[[\"\\a\",\"\\b\")]", 418 }, 419 { 420 indexPos: 0, 421 exprStr: `a > NULL`, 422 accessConds: "[gt(test.t.a, <nil>)]", 423 filterConds: "[]", 424 resultStr: `[]`, 425 }, 426 { 427 indexPos: 0, 428 exprStr: `a = 'a' and b in (1, 2, 3)`, 429 accessConds: "[eq(test.t.a, a) in(test.t.b, 1, 2, 3)]", 430 filterConds: "[]", 431 resultStr: "[[\"a\" 1,\"a\" 1] [\"a\" 2,\"a\" 2] [\"a\" 3,\"a\" 3]]", 432 }, 433 { 434 indexPos: 0, 435 exprStr: `a = 'a' and b not in (1, 2, 3)`, 436 accessConds: "[eq(test.t.a, a) not(in(test.t.b, 1, 2, 3))]", 437 filterConds: "[]", 438 resultStr: "[(\"a\" NULL,\"a\" 1) (\"a\" 3,\"a\" +inf]]", 439 }, 440 { 441 indexPos: 0, 442 exprStr: `a in ('a') and b in ('1', 2.0, NULL)`, 443 accessConds: "[eq(test.t.a, a) in(test.t.b, 1, 2, <nil>)]", 444 filterConds: "[]", 445 resultStr: `[["a" 1,"a" 1] ["a" 2,"a" 2]]`, 446 }, 447 { 448 indexPos: 1, 449 exprStr: `c in ('1.1', 1, 1.1) and a in ('1', 'a', NULL)`, 450 accessConds: "[in(test.t.c, 1.1, 1, 1.1) in(test.t.a, 1, a, <nil>)]", 451 filterConds: "[]", 452 resultStr: "[[1 \"1\",1 \"1\"] [1 \"a\",1 \"a\"] [1.1 \"1\",1.1 \"1\"] [1.1 \"a\",1.1 \"a\"]]", 453 }, 454 { 455 indexPos: 1, 456 exprStr: "c in (1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 2, 3, 4, 4, 1, 2)", 457 accessConds: "[in(test.t.c, 1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 2, 3, 4, 4, 1, 2)]", 458 filterConds: "[]", 459 resultStr: "[[1,1] [2,2] [3,3] [4,4]]", 460 }, 461 { 462 indexPos: 1, 463 exprStr: "c not in (1, 2, 3)", 464 accessConds: "[not(in(test.t.c, 1, 2, 3))]", 465 filterConds: "[]", 466 resultStr: "[(NULL,1) (1,2) (2,3) (3,+inf]]", 467 }, 468 { 469 indexPos: 1, 470 exprStr: "c in (1, 2) and c in (1, 3)", 471 accessConds: "[eq(test.t.c, 1)]", 472 filterConds: "[]", 473 resultStr: "[[1,1]]", 474 }, 475 { 476 indexPos: 1, 477 exprStr: "c = 1 and c = 2", 478 accessConds: "[]", 479 filterConds: "[]", 480 resultStr: "[]", 481 }, 482 { 483 indexPos: 0, 484 exprStr: "a in (NULL)", 485 accessConds: "[eq(test.t.a, <nil>)]", 486 filterConds: "[]", 487 resultStr: "[]", 488 }, 489 { 490 indexPos: 0, 491 exprStr: "a not in (NULL, '1', '2', '3')", 492 accessConds: "[not(in(test.t.a, <nil>, 1, 2, 3))]", 493 filterConds: "[]", 494 resultStr: "[]", 495 }, 496 { 497 indexPos: 0, 498 exprStr: "not (a not in (NULL, '1', '2', '3') and a > '2')", 499 accessConds: "[or(in(test.t.a, <nil>, 1, 2, 3), le(test.t.a, 2))]", 500 filterConds: "[]", 501 resultStr: "[[-inf,\"2\"] [\"3\",\"3\"]]", 502 }, 503 { 504 indexPos: 0, 505 exprStr: "not (a not in (NULL) and a > '2')", 506 accessConds: "[or(eq(test.t.a, <nil>), le(test.t.a, 2))]", 507 filterConds: "[]", 508 resultStr: "[[-inf,\"2\"]]", 509 }, 510 { 511 indexPos: 0, 512 exprStr: "not (a not in (NULL) or a > '2')", 513 accessConds: "[and(eq(test.t.a, <nil>), le(test.t.a, 2))]", 514 filterConds: "[]", 515 resultStr: "[]", 516 }, 517 { 518 indexPos: 0, 519 exprStr: "(a > 'b' and a < 'bbb') or (a < 'cb' and a > 'a')", 520 accessConds: "[or(and(gt(test.t.a, b), lt(test.t.a, bbb)), and(lt(test.t.a, cb), gt(test.t.a, a)))]", 521 filterConds: "[]", 522 resultStr: "[(\"a\",\"cb\")]", 523 }, 524 { 525 indexPos: 0, 526 exprStr: "(a > 'a' and a < 'b') or (a >= 'b' and a < 'c')", 527 accessConds: "[or(and(gt(test.t.a, a), lt(test.t.a, b)), and(ge(test.t.a, b), lt(test.t.a, c)))]", 528 filterConds: "[]", 529 resultStr: "[(\"a\",\"c\")]", 530 }, 531 { 532 indexPos: 0, 533 exprStr: "(a > 'a' and a < 'b' and b < 1) or (a >= 'b' and a < 'c')", 534 accessConds: "[or(and(gt(test.t.a, a), lt(test.t.a, b)), and(ge(test.t.a, b), lt(test.t.a, c)))]", 535 filterConds: "[or(and(and(gt(test.t.a, a), lt(test.t.a, b)), lt(test.t.b, 1)), and(ge(test.t.a, b), lt(test.t.a, c)))]", 536 resultStr: "[(\"a\",\"c\")]", 537 }, 538 { 539 indexPos: 0, 540 exprStr: "(a in ('a', 'b') and b < 1) or (a >= 'b' and a < 'c')", 541 accessConds: "[or(and(in(test.t.a, a, b), lt(test.t.b, 1)), and(ge(test.t.a, b), lt(test.t.a, c)))]", 542 filterConds: "[]", 543 resultStr: `[["a" -inf,"a" 1) ["b","c")]`, 544 }, 545 { 546 indexPos: 0, 547 exprStr: "(a > 'a') or (c > 1)", 548 accessConds: "[]", 549 filterConds: "[or(gt(test.t.a, a), gt(test.t.c, 1))]", 550 resultStr: "[[NULL,+inf]]", 551 }, 552 { 553 indexPos: 2, 554 exprStr: `d = "你好啊"`, 555 accessConds: "[eq(test.t.d, 你好啊)]", 556 filterConds: "[eq(test.t.d, 你好啊)]", 557 resultStr: "[[\"你好\",\"你好\"]]", 558 }, 559 { 560 indexPos: 3, 561 exprStr: `e = "你好啊"`, 562 accessConds: "[eq(test.t.e, 你好啊)]", 563 filterConds: "[eq(test.t.e, 你好啊)]", 564 resultStr: "[[\"[228 189]\",\"[228 189]\"]]", 565 }, 566 { 567 indexPos: 2, 568 exprStr: `d in ("你好啊", "再见")`, 569 accessConds: "[in(test.t.d, 你好啊, 再见)]", 570 filterConds: "[in(test.t.d, 你好啊, 再见)]", 571 resultStr: "[[\"你好\",\"你好\"] [\"再见\",\"再见\"]]", 572 }, 573 { 574 indexPos: 2, 575 exprStr: `d not in ("你好啊")`, 576 accessConds: "[]", 577 filterConds: "[ne(test.t.d, 你好啊)]", 578 resultStr: "[[NULL,+inf]]", 579 }, 580 { 581 indexPos: 2, 582 exprStr: `d < "你好" || d > "你好"`, 583 accessConds: "[or(lt(test.t.d, 你好), gt(test.t.d, 你好))]", 584 filterConds: "[or(lt(test.t.d, 你好), gt(test.t.d, 你好))]", 585 resultStr: "[[-inf,\"你好\") (\"你好\",+inf]]", 586 }, 587 { 588 indexPos: 2, 589 exprStr: `not(d < "你好" || d > "你好")`, 590 accessConds: "[and(ge(test.t.d, 你好), le(test.t.d, 你好))]", 591 filterConds: "[and(ge(test.t.d, 你好), le(test.t.d, 你好))]", 592 resultStr: "[[\"你好\",\"你好\"]]", 593 }, 594 { 595 indexPos: 4, 596 exprStr: "f >= 'a' and f <= 'B'", 597 accessConds: "[ge(test.t.f, a) le(test.t.f, B)]", 598 filterConds: "[]", 599 resultStr: "[[\"a\",\"B\"]]", 600 }, 601 { 602 indexPos: 4, 603 exprStr: "f in ('a', 'B')", 604 accessConds: "[in(test.t.f, a, B)]", 605 filterConds: "[]", 606 resultStr: "[[\"a\",\"a\"] [\"B\",\"B\"]]", 607 }, 608 { 609 indexPos: 4, 610 exprStr: "f = 'a' and f = 'B' defCauslate utf8mb4_bin", 611 accessConds: "[eq(test.t.f, a)]", 612 filterConds: "[eq(test.t.f, B)]", 613 resultStr: "[[\"a\",\"a\"]]", 614 }, 615 { 616 indexPos: 4, 617 exprStr: "f like '@%' defCauslate utf8mb4_bin", 618 accessConds: "[]", 619 filterConds: "[like(test.t.f, @%, 92)]", 620 resultStr: "[[NULL,+inf]]", 621 }, 622 } 623 624 defCauslate.SetNewDefCauslationEnabledForTest(true) 625 defer func() { defCauslate.SetNewDefCauslationEnabledForTest(false) }() 626 ctx := context.Background() 627 for _, tt := range tests { 628 allegrosql := "select * from t where " + tt.exprStr 629 sctx := testKit.Se.(stochastikctx.Context) 630 stmts, err := stochastik.Parse(sctx, allegrosql) 631 c.Assert(err, IsNil, Commentf("error %v, for expr %s", err, tt.exprStr)) 632 c.Assert(stmts, HasLen, 1) 633 is := petri.GetPetri(sctx).SchemaReplicant() 634 err = causetembedded.Preprocess(sctx, stmts[0], is) 635 c.Assert(err, IsNil, Commentf("error %v, for resolve name, expr %s", err, tt.exprStr)) 636 p, _, err := causetembedded.BuildLogicalCauset(ctx, sctx, stmts[0], is) 637 c.Assert(err, IsNil, Commentf("error %v, for build plan, expr %s", err, tt.exprStr)) 638 selection := p.(causetembedded.LogicalCauset).Children()[0].(*causetembedded.LogicalSelection) 639 tbl := selection.Children()[0].(*causetembedded.DataSource).BlockInfo() 640 c.Assert(selection, NotNil, Commentf("expr:%v", tt.exprStr)) 641 conds := make([]memex.Expression, len(selection.Conditions)) 642 for i, cond := range selection.Conditions { 643 conds[i] = memex.PushDownNot(sctx, cond) 644 } 645 defcaus, lengths := memex.IndexInfo2PrefixDefCauss(tbl.DeferredCausets, selection.Schema().DeferredCausets, tbl.Indices[tt.indexPos]) 646 c.Assert(defcaus, NotNil) 647 res, err := ranger.DetachCondAndBuildRangeForIndex(sctx, conds, defcaus, lengths) 648 c.Assert(err, IsNil) 649 c.Assert(fmt.Sprintf("%s", res.AccessConds), Equals, tt.accessConds, Commentf("wrong access conditions for expr: %s", tt.exprStr)) 650 c.Assert(fmt.Sprintf("%s", res.RemainedConds), Equals, tt.filterConds, Commentf("wrong filter conditions for expr: %s", tt.exprStr)) 651 got := fmt.Sprintf("%v", res.Ranges) 652 c.Assert(got, Equals, tt.resultStr, Commentf("different for expr %s", tt.exprStr)) 653 } 654 } 655 656 // for issue #6661 657 func (s *testRangerSuite) TestIndexRangeForUnsignedInt(c *C) { 658 defer testleak.AfterTest(c)() 659 dom, causetstore, err := newPetriStoreWithBootstrap(c) 660 defer func() { 661 dom.Close() 662 causetstore.Close() 663 }() 664 c.Assert(err, IsNil) 665 testKit := testkit.NewTestKit(c, causetstore) 666 testKit.MustInterDirc("use test") 667 testKit.MustInterDirc("drop causet if exists t") 668 testKit.MustInterDirc("create causet t (a smallint(5) unsigned,key (a) )") 669 670 tests := []struct { 671 indexPos int 672 exprStr string 673 accessConds string 674 filterConds string 675 resultStr string 676 }{ 677 { 678 indexPos: 0, 679 exprStr: `a not in (0, 1, 2)`, 680 accessConds: "[not(in(test.t.a, 0, 1, 2))]", 681 filterConds: "[]", 682 resultStr: `[(NULL,0) (2,+inf]]`, 683 }, 684 { 685 indexPos: 0, 686 exprStr: `a not in (-1, 1, 2)`, 687 accessConds: "[not(in(test.t.a, -1, 1, 2))]", 688 filterConds: "[]", 689 resultStr: `[(NULL,1) (2,+inf]]`, 690 }, 691 { 692 indexPos: 0, 693 exprStr: `a not in (-2, -1, 1, 2)`, 694 accessConds: "[not(in(test.t.a, -2, -1, 1, 2))]", 695 filterConds: "[]", 696 resultStr: `[(NULL,1) (2,+inf]]`, 697 }, 698 { 699 indexPos: 0, 700 exprStr: `a not in (111)`, 701 accessConds: "[ne(test.t.a, 111)]", 702 filterConds: "[]", 703 resultStr: `[[-inf,111) (111,+inf]]`, 704 }, 705 { 706 indexPos: 0, 707 exprStr: `a not in (1, 2, 9223372036854775810)`, 708 accessConds: "[not(in(test.t.a, 1, 2, 9223372036854775810))]", 709 filterConds: "[]", 710 resultStr: `[(NULL,1) (2,9223372036854775810) (9223372036854775810,+inf]]`, 711 }, 712 { 713 indexPos: 0, 714 exprStr: `a >= -2147483648`, 715 accessConds: "[ge(test.t.a, -2147483648)]", 716 filterConds: "[]", 717 resultStr: `[[0,+inf]]`, 718 }, 719 { 720 indexPos: 0, 721 exprStr: `a > -2147483648`, 722 accessConds: "[gt(test.t.a, -2147483648)]", 723 filterConds: "[]", 724 resultStr: `[[0,+inf]]`, 725 }, 726 { 727 indexPos: 0, 728 exprStr: `a != -2147483648`, 729 accessConds: "[ne(test.t.a, -2147483648)]", 730 filterConds: "[]", 731 resultStr: `[[0,+inf]]`, 732 }, 733 { 734 exprStr: "a < -1 or a < 1", 735 accessConds: "[or(lt(test.t.a, -1), lt(test.t.a, 1))]", 736 filterConds: "[]", 737 resultStr: "[[-inf,1)]", 738 }, 739 { 740 exprStr: "a < -1 and a < 1", 741 accessConds: "[]", 742 filterConds: "[]", 743 resultStr: "[]", 744 }, 745 } 746 747 ctx := context.Background() 748 for _, tt := range tests { 749 allegrosql := "select * from t where " + tt.exprStr 750 sctx := testKit.Se.(stochastikctx.Context) 751 stmts, err := stochastik.Parse(sctx, allegrosql) 752 c.Assert(err, IsNil, Commentf("error %v, for expr %s", err, tt.exprStr)) 753 c.Assert(stmts, HasLen, 1) 754 is := petri.GetPetri(sctx).SchemaReplicant() 755 err = causetembedded.Preprocess(sctx, stmts[0], is) 756 c.Assert(err, IsNil, Commentf("error %v, for resolve name, expr %s", err, tt.exprStr)) 757 p, _, err := causetembedded.BuildLogicalCauset(ctx, sctx, stmts[0], is) 758 c.Assert(err, IsNil, Commentf("error %v, for build plan, expr %s", err, tt.exprStr)) 759 selection := p.(causetembedded.LogicalCauset).Children()[0].(*causetembedded.LogicalSelection) 760 tbl := selection.Children()[0].(*causetembedded.DataSource).BlockInfo() 761 c.Assert(selection, NotNil, Commentf("expr:%v", tt.exprStr)) 762 conds := make([]memex.Expression, len(selection.Conditions)) 763 for i, cond := range selection.Conditions { 764 conds[i] = memex.PushDownNot(sctx, cond) 765 } 766 defcaus, lengths := memex.IndexInfo2PrefixDefCauss(tbl.DeferredCausets, selection.Schema().DeferredCausets, tbl.Indices[tt.indexPos]) 767 c.Assert(defcaus, NotNil) 768 res, err := ranger.DetachCondAndBuildRangeForIndex(sctx, conds, defcaus, lengths) 769 c.Assert(err, IsNil) 770 c.Assert(fmt.Sprintf("%s", res.AccessConds), Equals, tt.accessConds, Commentf("wrong access conditions for expr: %s", tt.exprStr)) 771 c.Assert(fmt.Sprintf("%s", res.RemainedConds), Equals, tt.filterConds, Commentf("wrong filter conditions for expr: %s", tt.exprStr)) 772 got := fmt.Sprintf("%v", res.Ranges) 773 c.Assert(got, Equals, tt.resultStr, Commentf("different for expr %s", tt.exprStr)) 774 } 775 } 776 777 func (s *testRangerSuite) TestDeferredCausetRange(c *C) { 778 defer testleak.AfterTest(c)() 779 dom, causetstore, err := newPetriStoreWithBootstrap(c) 780 defer func() { 781 dom.Close() 782 causetstore.Close() 783 }() 784 c.Assert(err, IsNil) 785 testKit := testkit.NewTestKit(c, causetstore) 786 testKit.MustInterDirc("use test") 787 testKit.MustInterDirc("drop causet if exists t") 788 testKit.MustInterDirc("create causet t(a int, b double, c float(3, 2), d varchar(3), e bigint unsigned)") 789 790 tests := []struct { 791 defCausPos int 792 exprStr string 793 accessConds string 794 filterConds string 795 resultStr string 796 length int 797 }{ 798 { 799 defCausPos: 0, 800 exprStr: "a = 1 and b > 1", 801 accessConds: "[eq(test.t.a, 1)]", 802 filterConds: "[gt(test.t.b, 1)]", 803 resultStr: "[[1,1]]", 804 length: types.UnspecifiedLength, 805 }, 806 { 807 defCausPos: 1, 808 exprStr: "b > 1", 809 accessConds: "[gt(test.t.b, 1)]", 810 filterConds: "[]", 811 resultStr: "[(1,+inf]]", 812 length: types.UnspecifiedLength, 813 }, 814 { 815 defCausPos: 0, 816 exprStr: "1 = a", 817 accessConds: "[eq(1, test.t.a)]", 818 filterConds: "[]", 819 resultStr: "[[1,1]]", 820 length: types.UnspecifiedLength, 821 }, 822 { 823 defCausPos: 0, 824 exprStr: "a != 1", 825 accessConds: "[ne(test.t.a, 1)]", 826 filterConds: "[]", 827 resultStr: "[[-inf,1) (1,+inf]]", 828 length: types.UnspecifiedLength, 829 }, 830 { 831 defCausPos: 0, 832 exprStr: "1 != a", 833 accessConds: "[ne(1, test.t.a)]", 834 filterConds: "[]", 835 resultStr: "[[-inf,1) (1,+inf]]", 836 length: types.UnspecifiedLength, 837 }, 838 { 839 defCausPos: 0, 840 exprStr: "a > 1", 841 accessConds: "[gt(test.t.a, 1)]", 842 filterConds: "[]", 843 resultStr: "[(1,+inf]]", 844 length: types.UnspecifiedLength, 845 }, 846 { 847 defCausPos: 0, 848 exprStr: "1 < a", 849 accessConds: "[lt(1, test.t.a)]", 850 filterConds: "[]", 851 resultStr: "[(1,+inf]]", 852 length: types.UnspecifiedLength, 853 }, 854 { 855 defCausPos: 0, 856 exprStr: "a >= 1", 857 accessConds: "[ge(test.t.a, 1)]", 858 filterConds: "[]", 859 resultStr: "[[1,+inf]]", 860 length: types.UnspecifiedLength, 861 }, 862 { 863 defCausPos: 0, 864 exprStr: "1 <= a", 865 accessConds: "[le(1, test.t.a)]", 866 filterConds: "[]", 867 resultStr: "[[1,+inf]]", 868 length: types.UnspecifiedLength, 869 }, 870 { 871 defCausPos: 0, 872 exprStr: "a < 1", 873 accessConds: "[lt(test.t.a, 1)]", 874 filterConds: "[]", 875 resultStr: "[[-inf,1)]", 876 length: types.UnspecifiedLength, 877 }, 878 { 879 defCausPos: 0, 880 exprStr: "1 > a", 881 accessConds: "[gt(1, test.t.a)]", 882 filterConds: "[]", 883 resultStr: "[[-inf,1)]", 884 length: types.UnspecifiedLength, 885 }, 886 { 887 defCausPos: 0, 888 exprStr: "a <= 1", 889 accessConds: "[le(test.t.a, 1)]", 890 filterConds: "[]", 891 resultStr: "[[-inf,1]]", 892 length: types.UnspecifiedLength, 893 }, 894 { 895 defCausPos: 0, 896 exprStr: "1 >= a", 897 accessConds: "[ge(1, test.t.a)]", 898 filterConds: "[]", 899 resultStr: "[[-inf,1]]", 900 length: types.UnspecifiedLength, 901 }, 902 { 903 defCausPos: 0, 904 exprStr: "(a)", 905 accessConds: "[test.t.a]", 906 filterConds: "[]", 907 resultStr: "[[-inf,0) (0,+inf]]", 908 length: types.UnspecifiedLength, 909 }, 910 { 911 defCausPos: 0, 912 exprStr: "a in (1, 3, NULL, 2)", 913 accessConds: "[in(test.t.a, 1, 3, <nil>, 2)]", 914 filterConds: "[]", 915 resultStr: "[[1,1] [2,2] [3,3]]", 916 length: types.UnspecifiedLength, 917 }, 918 { 919 defCausPos: 0, 920 exprStr: `a IN (8,8,81,45)`, 921 accessConds: "[in(test.t.a, 8, 8, 81, 45)]", 922 filterConds: "[]", 923 resultStr: `[[8,8] [45,45] [81,81]]`, 924 length: types.UnspecifiedLength, 925 }, 926 { 927 defCausPos: 0, 928 exprStr: "a between 1 and 2", 929 accessConds: "[ge(test.t.a, 1) le(test.t.a, 2)]", 930 filterConds: "[]", 931 resultStr: "[[1,2]]", 932 length: types.UnspecifiedLength, 933 }, 934 { 935 defCausPos: 0, 936 exprStr: "a not between 1 and 2", 937 accessConds: "[or(lt(test.t.a, 1), gt(test.t.a, 2))]", 938 filterConds: "[]", 939 resultStr: "[[-inf,1) (2,+inf]]", 940 length: types.UnspecifiedLength, 941 }, 942 //{ 943 // `a > null` will be converted to `castAsString(a) > null` which can not be extracted as access condition. 944 // exprStr: "a not between null and 0", 945 // resultStr[(0,+inf]] 946 //}, 947 { 948 defCausPos: 0, 949 exprStr: "a between 2 and 1", 950 accessConds: "[ge(test.t.a, 2) le(test.t.a, 1)]", 951 filterConds: "[]", 952 resultStr: "[]", 953 length: types.UnspecifiedLength, 954 }, 955 { 956 defCausPos: 0, 957 exprStr: "a not between 2 and 1", 958 accessConds: "[or(lt(test.t.a, 2), gt(test.t.a, 1))]", 959 filterConds: "[]", 960 resultStr: "[[-inf,+inf]]", 961 length: types.UnspecifiedLength, 962 }, 963 { 964 defCausPos: 0, 965 exprStr: "a IS NULL", 966 accessConds: "[isnull(test.t.a)]", 967 filterConds: "[]", 968 resultStr: "[[NULL,NULL]]", 969 length: types.UnspecifiedLength, 970 }, 971 { 972 defCausPos: 0, 973 exprStr: "a IS NOT NULL", 974 accessConds: "[not(isnull(test.t.a))]", 975 filterConds: "[]", 976 resultStr: "[[-inf,+inf]]", 977 length: types.UnspecifiedLength, 978 }, 979 { 980 defCausPos: 0, 981 exprStr: "a IS TRUE", 982 accessConds: "[istrue(test.t.a)]", 983 filterConds: "[]", 984 resultStr: "[[-inf,0) (0,+inf]]", 985 length: types.UnspecifiedLength, 986 }, 987 { 988 defCausPos: 0, 989 exprStr: "a IS NOT TRUE", 990 accessConds: "[not(istrue(test.t.a))]", 991 filterConds: "[]", 992 resultStr: "[[NULL,NULL] [0,0]]", 993 length: types.UnspecifiedLength, 994 }, 995 { 996 defCausPos: 0, 997 exprStr: "a IS FALSE", 998 accessConds: "[isfalse(test.t.a)]", 999 filterConds: "[]", 1000 resultStr: "[[0,0]]", 1001 length: types.UnspecifiedLength, 1002 }, 1003 { 1004 defCausPos: 0, 1005 exprStr: "a IS NOT FALSE", 1006 accessConds: "[not(isfalse(test.t.a))]", 1007 filterConds: "[]", 1008 resultStr: "[[NULL,0) (0,+inf]]", 1009 length: types.UnspecifiedLength, 1010 }, 1011 { 1012 defCausPos: 1, 1013 exprStr: `b in (1, '2.1')`, 1014 accessConds: "[in(test.t.b, 1, 2.1)]", 1015 filterConds: "[]", 1016 resultStr: "[[1,1] [2.1,2.1]]", 1017 length: types.UnspecifiedLength, 1018 }, 1019 { 1020 defCausPos: 0, 1021 exprStr: `a > 9223372036854775807`, 1022 accessConds: "[gt(test.t.a, 9223372036854775807)]", 1023 filterConds: "[]", 1024 resultStr: "[(9223372036854775807,+inf]]", 1025 length: types.UnspecifiedLength, 1026 }, 1027 { 1028 defCausPos: 2, 1029 exprStr: `c > 111.11111111`, 1030 accessConds: "[gt(test.t.c, 111.11111111)]", 1031 filterConds: "[]", 1032 resultStr: "[[111.111115,+inf]]", 1033 length: types.UnspecifiedLength, 1034 }, 1035 { 1036 defCausPos: 3, 1037 exprStr: `d > 'aaaaaaaaaaaaaa'`, 1038 accessConds: "[gt(test.t.d, aaaaaaaaaaaaaa)]", 1039 filterConds: "[]", 1040 resultStr: "[(\"aaaaaaaaaaaaaa\",+inf]]", 1041 length: types.UnspecifiedLength, 1042 }, 1043 { 1044 defCausPos: 4, 1045 exprStr: `e > 18446744073709500000`, 1046 accessConds: "[gt(test.t.e, 18446744073709500000)]", 1047 filterConds: "[]", 1048 resultStr: "[(18446744073709500000,+inf]]", 1049 length: types.UnspecifiedLength, 1050 }, 1051 { 1052 defCausPos: 4, 1053 exprStr: `e > -2147483648`, 1054 accessConds: "[gt(test.t.e, -2147483648)]", 1055 filterConds: "[]", 1056 resultStr: "[[0,+inf]]", 1057 length: types.UnspecifiedLength, 1058 }, 1059 { 1060 defCausPos: 3, 1061 exprStr: "d = 'aab' or d = 'aac'", 1062 accessConds: "[or(eq(test.t.d, aab), eq(test.t.d, aac))]", 1063 filterConds: "[]", 1064 resultStr: "[[\"a\",\"a\"]]", 1065 length: 1, 1066 }, 1067 // This test case cannot be simplified to [1, 3] otherwise the index join will executes wrongly. 1068 { 1069 defCausPos: 0, 1070 exprStr: "a in (1, 2, 3)", 1071 accessConds: "[in(test.t.a, 1, 2, 3)]", 1072 filterConds: "", 1073 resultStr: "[[1,1] [2,2] [3,3]]", 1074 length: types.UnspecifiedLength, 1075 }, 1076 // test cases for nulleq 1077 { 1078 defCausPos: 0, 1079 exprStr: "a <=> 1", 1080 accessConds: "[nulleq(test.t.a, 1)]", 1081 filterConds: "", 1082 resultStr: "[[1,1]]", 1083 length: types.UnspecifiedLength, 1084 }, 1085 { 1086 defCausPos: 0, 1087 exprStr: "a <=> null", 1088 accessConds: "[nulleq(test.t.a, <nil>)]", 1089 filterConds: "", 1090 resultStr: "[[NULL,NULL]]", 1091 length: types.UnspecifiedLength, 1092 }, 1093 } 1094 1095 ctx := context.Background() 1096 for _, tt := range tests { 1097 allegrosql := "select * from t where " + tt.exprStr 1098 sctx := testKit.Se.(stochastikctx.Context) 1099 stmts, err := stochastik.Parse(sctx, allegrosql) 1100 c.Assert(err, IsNil, Commentf("error %v, for expr %s", err, tt.exprStr)) 1101 c.Assert(stmts, HasLen, 1) 1102 is := petri.GetPetri(sctx).SchemaReplicant() 1103 err = causetembedded.Preprocess(sctx, stmts[0], is) 1104 c.Assert(err, IsNil, Commentf("error %v, for resolve name, expr %s", err, tt.exprStr)) 1105 p, _, err := causetembedded.BuildLogicalCauset(ctx, sctx, stmts[0], is) 1106 c.Assert(err, IsNil, Commentf("error %v, for build plan, expr %s", err, tt.exprStr)) 1107 sel := p.(causetembedded.LogicalCauset).Children()[0].(*causetembedded.LogicalSelection) 1108 ds, ok := sel.Children()[0].(*causetembedded.DataSource) 1109 c.Assert(ok, IsTrue, Commentf("expr:%v", tt.exprStr)) 1110 conds := make([]memex.Expression, len(sel.Conditions)) 1111 for i, cond := range sel.Conditions { 1112 conds[i] = memex.PushDownNot(sctx, cond) 1113 } 1114 defCaus := memex.DefCausInfo2DefCaus(sel.Schema().DeferredCausets, ds.BlockInfo().DeferredCausets[tt.defCausPos]) 1115 c.Assert(defCaus, NotNil) 1116 conds = ranger.ExtractAccessConditionsForDeferredCauset(conds, defCaus.UniqueID) 1117 c.Assert(fmt.Sprintf("%s", conds), Equals, tt.accessConds, Commentf("wrong access conditions for expr: %s", tt.exprStr)) 1118 result, err := ranger.BuildDeferredCausetRange(conds, new(stmtctx.StatementContext), defCaus.RetType, tt.length) 1119 c.Assert(err, IsNil) 1120 got := fmt.Sprintf("%v", result) 1121 c.Assert(got, Equals, tt.resultStr, Commentf("different for expr %s, defCaus: %v", tt.exprStr, defCaus)) 1122 } 1123 } 1124 1125 func (s *testRangerSuite) TestIndexRangeElimininatedProjection(c *C) { 1126 defer testleak.AfterTest(c)() 1127 dom, causetstore, err := newPetriStoreWithBootstrap(c) 1128 defer func() { 1129 dom.Close() 1130 causetstore.Close() 1131 }() 1132 c.Assert(err, IsNil) 1133 testKit := testkit.NewTestKit(c, causetstore) 1134 testKit.MustInterDirc("use test") 1135 testKit.MustInterDirc("drop causet if exists t") 1136 testKit.MustInterDirc("set @@milevadb_enable_clustered_index=0") 1137 testKit.MustInterDirc("create causet t(a int not null, b int not null, primary key(a,b))") 1138 testKit.MustInterDirc("insert into t values(1,2)") 1139 testKit.MustInterDirc("analyze causet t") 1140 testKit.MustQuery("explain select * from (select * from t union all select ifnull(a,b), b from t) sub where a > 0").Check(testkit.Rows( 1141 "Union_11 2.00 root ", 1142 "├─IndexReader_14 1.00 root index:IndexRangeScan_13", 1143 "│ └─IndexRangeScan_13 1.00 cop[einsteindb] causet:t, index:PRIMARY(a, b) range:(0,+inf], keep order:false", 1144 "└─IndexReader_17 1.00 root index:IndexRangeScan_16", 1145 " └─IndexRangeScan_16 1.00 cop[einsteindb] causet:t, index:PRIMARY(a, b) range:(0,+inf], keep order:false", 1146 )) 1147 testKit.MustQuery("select * from (select * from t union all select ifnull(a,b), b from t) sub where a > 0").Check(testkit.Rows( 1148 "1 2", 1149 "1 2", 1150 )) 1151 } 1152 1153 func (s *testRangerSuite) TestCompIndexInExprCorrDefCaus(c *C) { 1154 defer testleak.AfterTest(c)() 1155 dom, causetstore, err := newPetriStoreWithBootstrap(c) 1156 defer func() { 1157 dom.Close() 1158 causetstore.Close() 1159 }() 1160 c.Assert(err, IsNil) 1161 testKit := testkit.NewTestKit(c, causetstore) 1162 testKit.MustInterDirc("use test") 1163 testKit.MustInterDirc("drop causet if exists t") 1164 testKit.MustInterDirc("create causet t(a int primary key, b int, c int, d int, e int, index idx(b,c,d))") 1165 testKit.MustInterDirc("insert into t values(1,1,1,1,2),(2,1,2,1,0)") 1166 testKit.MustInterDirc("analyze causet t") 1167 1168 var input []string 1169 var output []struct { 1170 ALLEGROALLEGROSQL string 1171 Result []string 1172 } 1173 s.testData.GetTestCases(c, &input, &output) 1174 for i, tt := range input { 1175 s.testData.OnRecord(func() { 1176 output[i].ALLEGROALLEGROSQL = tt 1177 output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows()) 1178 }) 1179 testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...)) 1180 } 1181 } 1182 1183 func (s *testRangerSuite) TestIndexStringIsTrueRange(c *C) { 1184 defer testleak.AfterTest(c)() 1185 dom, causetstore, err := newPetriStoreWithBootstrap(c) 1186 defer func() { 1187 dom.Close() 1188 causetstore.Close() 1189 }() 1190 c.Assert(err, IsNil) 1191 testKit := testkit.NewTestKit(c, causetstore) 1192 testKit.MustInterDirc("use test") 1193 testKit.MustInterDirc("drop causet if exists t0") 1194 testKit.MustInterDirc("CREATE TABLE t0(c0 TEXT(10));") 1195 testKit.MustInterDirc("INSERT INTO t0(c0) VALUES (1);") 1196 testKit.MustInterDirc("CREATE INDEX i0 ON t0(c0(10));") 1197 testKit.MustInterDirc("analyze causet t0;") 1198 1199 var input []string 1200 var output []struct { 1201 ALLEGROALLEGROSQL string 1202 Result []string 1203 } 1204 s.testData.GetTestCases(c, &input, &output) 1205 for i, tt := range input { 1206 s.testData.OnRecord(func() { 1207 output[i].ALLEGROALLEGROSQL = tt 1208 output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows()) 1209 }) 1210 testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...)) 1211 } 1212 } 1213 1214 func (s *testRangerSuite) TestCompIndexDNFMatch(c *C) { 1215 defer testleak.AfterTest(c)() 1216 dom, causetstore, err := newPetriStoreWithBootstrap(c) 1217 defer func() { 1218 dom.Close() 1219 causetstore.Close() 1220 }() 1221 c.Assert(err, IsNil) 1222 testKit := testkit.NewTestKit(c, causetstore) 1223 testKit.MustInterDirc("use test") 1224 testKit.MustInterDirc("drop causet if exists t") 1225 testKit.MustInterDirc("create causet t(a int, b int, c int, key(a,b,c));") 1226 testKit.MustInterDirc("insert into t values(1,2,2)") 1227 1228 var input []string 1229 var output []struct { 1230 ALLEGROALLEGROSQL string 1231 Causet []string 1232 Result []string 1233 } 1234 s.testData.GetTestCases(c, &input, &output) 1235 for i, tt := range input { 1236 s.testData.OnRecord(func() { 1237 output[i].ALLEGROALLEGROSQL = tt 1238 output[i].Causet = s.testData.ConvertRowsToStrings(testKit.MustQuery("explain " + tt).Rows()) 1239 output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows()) 1240 }) 1241 testKit.MustQuery("explain " + tt).Check(testkit.Rows(output[i].Causet...)) 1242 testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...)) 1243 } 1244 } 1245 1246 func (s *testRangerSuite) TestCompIndexMultiDefCausDNF1(c *C) { 1247 defer testleak.AfterTest(c)() 1248 dom, causetstore, err := newPetriStoreWithBootstrap(c) 1249 defer func() { 1250 dom.Close() 1251 causetstore.Close() 1252 }() 1253 c.Assert(err, IsNil) 1254 testKit := testkit.NewTestKit(c, causetstore) 1255 testKit.MustInterDirc("use test") 1256 testKit.MustInterDirc("drop causet if exists t") 1257 testKit.MustInterDirc("create causet t(a int, b int, c int, primary key(a,b));") 1258 testKit.MustInterDirc("insert into t values(1,1,1),(2,2,3)") 1259 testKit.MustInterDirc("analyze causet t") 1260 1261 var input []string 1262 var output []struct { 1263 ALLEGROALLEGROSQL string 1264 Causet []string 1265 Result []string 1266 } 1267 s.testData.GetTestCases(c, &input, &output) 1268 for i, tt := range input { 1269 s.testData.OnRecord(func() { 1270 output[i].ALLEGROALLEGROSQL = tt 1271 output[i].Causet = s.testData.ConvertRowsToStrings(testKit.MustQuery("explain " + tt).Rows()) 1272 output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows()) 1273 }) 1274 testKit.MustQuery("explain " + tt).Check(testkit.Rows(output[i].Causet...)) 1275 testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...)) 1276 } 1277 } 1278 1279 func (s *testRangerSuite) TestCompIndexMultiDefCausDNF2(c *C) { 1280 defer testleak.AfterTest(c)() 1281 dom, causetstore, err := newPetriStoreWithBootstrap(c) 1282 defer func() { 1283 dom.Close() 1284 causetstore.Close() 1285 }() 1286 c.Assert(err, IsNil) 1287 testKit := testkit.NewTestKit(c, causetstore) 1288 testKit.MustInterDirc("use test") 1289 testKit.MustInterDirc("drop causet if exists t") 1290 testKit.MustInterDirc("create causet t(a int, b int, c int, primary key(a,b,c));") 1291 testKit.MustInterDirc("insert into t values(1,1,1),(2,2,3)") 1292 testKit.MustInterDirc("analyze causet t") 1293 1294 var input []string 1295 var output []struct { 1296 ALLEGROALLEGROSQL string 1297 Causet []string 1298 Result []string 1299 } 1300 s.testData.GetTestCases(c, &input, &output) 1301 for i, tt := range input { 1302 s.testData.OnRecord(func() { 1303 output[i].ALLEGROALLEGROSQL = tt 1304 output[i].Causet = s.testData.ConvertRowsToStrings(testKit.MustQuery("explain " + tt).Rows()) 1305 output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows()) 1306 }) 1307 testKit.MustQuery("explain " + tt).Check(testkit.Rows(output[i].Causet...)) 1308 testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...)) 1309 } 1310 }