github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/allegrosql/physical_plan_test.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package embedded_test 15 16 import ( 17 "context" 18 "fmt" 19 20 "github.com/whtcorpsinc/BerolinaSQL" 21 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 22 "github.com/whtcorpsinc/BerolinaSQL/terror" 23 . "github.com/whtcorpsinc/check" 24 "github.com/whtcorpsinc/milevadb/causet" 25 "github.com/whtcorpsinc/milevadb/causet/embedded" 26 "github.com/whtcorpsinc/milevadb/ekv" 27 "github.com/whtcorpsinc/milevadb/interlock" 28 "github.com/whtcorpsinc/milevadb/petri" 29 "github.com/whtcorpsinc/milevadb/schemareplicant" 30 "github.com/whtcorpsinc/milevadb/soliton/hint" 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/stochastikctx/variable" 38 ) 39 40 var _ = Suite(&testCausetSuite{}) 41 var _ = SerialSuites(&testCausetSerialSuite{}) 42 43 type testCausetSuiteBase struct { 44 *BerolinaSQL.BerolinaSQL 45 is schemareplicant.SchemaReplicant 46 } 47 48 func (s *testCausetSuiteBase) SetUpSuite(c *C) { 49 s.is = schemareplicant.MockSchemaReplicant([]*perceptron.BlockInfo{embedded.MockSignedBlock(), embedded.MockUnsignedBlock()}) 50 s.BerolinaSQL = BerolinaSQL.New() 51 s.BerolinaSQL.EnableWindowFunc(true) 52 } 53 54 type testCausetSerialSuite struct { 55 testCausetSuiteBase 56 } 57 58 type testCausetSuite struct { 59 testCausetSuiteBase 60 61 testData solitonutil.TestData 62 } 63 64 func (s *testCausetSuite) SetUpSuite(c *C) { 65 s.testCausetSuiteBase.SetUpSuite(c) 66 67 var err error 68 s.testData, err = solitonutil.LoadTestSuiteData("testdata", "plan_suite") 69 c.Assert(err, IsNil) 70 } 71 72 func (s *testCausetSuite) TearDownSuite(c *C) { 73 c.Assert(s.testData.GenerateOutputIfNeeded(), IsNil) 74 } 75 76 func (s *testCausetSuite) TestPosetDagCausetBuilderSimpleCase(c *C) { 77 defer testleak.AfterTest(c)() 78 causetstore, dom, err := newStoreWithBootstrap() 79 c.Assert(err, IsNil) 80 defer func() { 81 dom.Close() 82 causetstore.Close() 83 }() 84 se, err := stochastik.CreateStochastik4Test(causetstore) 85 c.Assert(err, IsNil) 86 _, err = se.InterDircute(context.Background(), "use test") 87 c.Assert(err, IsNil) 88 var input []string 89 var output []struct { 90 ALLEGROALLEGROSQL string 91 Best string 92 } 93 s.testData.GetTestCases(c, &input, &output) 94 for i, tt := range input { 95 comment := Commentf("case:%v allegrosql:%s", i, tt) 96 stmt, err := s.ParseOneStmt(tt, "", "") 97 c.Assert(err, IsNil, comment) 98 99 err = se.NewTxn(context.Background()) 100 c.Assert(err, IsNil) 101 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 102 c.Assert(err, IsNil) 103 s.testData.OnRecord(func() { 104 output[i].ALLEGROALLEGROSQL = tt 105 output[i].Best = embedded.ToString(p) 106 }) 107 c.Assert(embedded.ToString(p), Equals, output[i].Best, comment) 108 } 109 } 110 111 func (s *testCausetSuite) TestPosetDagCausetBuilderJoin(c *C) { 112 defer testleak.AfterTest(c)() 113 causetstore, dom, err := newStoreWithBootstrap() 114 c.Assert(err, IsNil) 115 defer func() { 116 dom.Close() 117 causetstore.Close() 118 }() 119 se, err := stochastik.CreateStochastik4Test(causetstore) 120 c.Assert(err, IsNil) 121 _, err = se.InterDircute(context.Background(), "use test") 122 c.Assert(err, IsNil) 123 ctx := se.(stochastikctx.Context) 124 stochastikVars := ctx.GetStochastikVars() 125 stochastikVars.InterlockingDirectorateConcurrency = 4 126 stochastikVars.SetDistALLEGROSQLScanConcurrency(15) 127 stochastikVars.SetHashJoinConcurrency(5) 128 129 var input []string 130 var output []struct { 131 ALLEGROALLEGROSQL string 132 Best string 133 } 134 s.testData.GetTestCases(c, &input, &output) 135 for i, tt := range input { 136 comment := Commentf("case:%v allegrosql:%s", i, tt) 137 stmt, err := s.ParseOneStmt(tt, "", "") 138 c.Assert(err, IsNil, comment) 139 140 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 141 c.Assert(err, IsNil) 142 s.testData.OnRecord(func() { 143 output[i].ALLEGROALLEGROSQL = tt 144 output[i].Best = embedded.ToString(p) 145 }) 146 c.Assert(embedded.ToString(p), Equals, output[i].Best, comment) 147 } 148 } 149 150 func (s *testCausetSuite) TestPosetDagCausetBuilderSubquery(c *C) { 151 defer testleak.AfterTest(c)() 152 causetstore, dom, err := newStoreWithBootstrap() 153 c.Assert(err, IsNil) 154 defer func() { 155 dom.Close() 156 causetstore.Close() 157 }() 158 se, err := stochastik.CreateStochastik4Test(causetstore) 159 c.Assert(err, IsNil) 160 _, err = se.InterDircute(context.Background(), "use test") 161 c.Assert(err, IsNil) 162 se.InterDircute(context.Background(), "set sql_mode='STRICT_TRANS_TABLES'") // disable only full group by 163 ctx := se.(stochastikctx.Context) 164 stochastikVars := ctx.GetStochastikVars() 165 stochastikVars.SetHashAggFinalConcurrency(1) 166 stochastikVars.SetHashAggPartialConcurrency(1) 167 stochastikVars.SetHashJoinConcurrency(5) 168 stochastikVars.SetDistALLEGROSQLScanConcurrency(15) 169 stochastikVars.InterlockingDirectorateConcurrency = 4 170 var input []string 171 var output []struct { 172 ALLEGROALLEGROSQL string 173 Best string 174 } 175 s.testData.GetTestCases(c, &input, &output) 176 for i, tt := range input { 177 comment := Commentf("for %s", tt) 178 stmt, err := s.ParseOneStmt(tt, "", "") 179 c.Assert(err, IsNil, comment) 180 181 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 182 c.Assert(err, IsNil) 183 s.testData.OnRecord(func() { 184 output[i].ALLEGROALLEGROSQL = tt 185 output[i].Best = embedded.ToString(p) 186 }) 187 c.Assert(embedded.ToString(p), Equals, output[i].Best, Commentf("for %s", tt)) 188 } 189 } 190 191 func (s *testCausetSuite) TestPosetDagCausetTopN(c *C) { 192 defer testleak.AfterTest(c)() 193 causetstore, dom, err := newStoreWithBootstrap() 194 c.Assert(err, IsNil) 195 defer func() { 196 dom.Close() 197 causetstore.Close() 198 }() 199 se, err := stochastik.CreateStochastik4Test(causetstore) 200 c.Assert(err, IsNil) 201 _, err = se.InterDircute(context.Background(), "use test") 202 c.Assert(err, IsNil) 203 204 var input []string 205 var output []struct { 206 ALLEGROALLEGROSQL string 207 Best string 208 } 209 s.testData.GetTestCases(c, &input, &output) 210 for i, tt := range input { 211 comment := Commentf("case:%v allegrosql:%s", i, tt) 212 stmt, err := s.ParseOneStmt(tt, "", "") 213 c.Assert(err, IsNil, comment) 214 215 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 216 c.Assert(err, IsNil) 217 s.testData.OnRecord(func() { 218 output[i].ALLEGROALLEGROSQL = tt 219 output[i].Best = embedded.ToString(p) 220 }) 221 c.Assert(embedded.ToString(p), Equals, output[i].Best, comment) 222 } 223 } 224 225 func (s *testCausetSuite) TestPosetDagCausetBuilderBasePhysicalCauset(c *C) { 226 defer testleak.AfterTest(c)() 227 causetstore, dom, err := newStoreWithBootstrap() 228 c.Assert(err, IsNil) 229 defer func() { 230 dom.Close() 231 causetstore.Close() 232 }() 233 se, err := stochastik.CreateStochastik4Test(causetstore) 234 c.Assert(err, IsNil) 235 236 _, err = se.InterDircute(context.Background(), "use test") 237 c.Assert(err, IsNil) 238 239 var input []string 240 var output []struct { 241 ALLEGROALLEGROSQL string 242 Best string 243 Hints string 244 } 245 s.testData.GetTestCases(c, &input, &output) 246 for i, tt := range input { 247 comment := Commentf("for %s", tt) 248 stmt, err := s.ParseOneStmt(tt, "", "") 249 c.Assert(err, IsNil, comment) 250 251 embedded.Preprocess(se, stmt, s.is) 252 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 253 c.Assert(err, IsNil) 254 s.testData.OnRecord(func() { 255 output[i].ALLEGROALLEGROSQL = tt 256 output[i].Best = embedded.ToString(p) 257 output[i].Hints = hint.RestoreOptimizerHints(embedded.GenHintsFromPhysicalCauset(p)) 258 }) 259 c.Assert(embedded.ToString(p), Equals, output[i].Best, Commentf("for %s", tt)) 260 c.Assert(hint.RestoreOptimizerHints(embedded.GenHintsFromPhysicalCauset(p)), Equals, output[i].Hints, Commentf("for %s", tt)) 261 } 262 } 263 264 func (s *testCausetSuite) TestPosetDagCausetBuilderUnion(c *C) { 265 defer testleak.AfterTest(c)() 266 causetstore, dom, err := newStoreWithBootstrap() 267 c.Assert(err, IsNil) 268 defer func() { 269 dom.Close() 270 causetstore.Close() 271 }() 272 se, err := stochastik.CreateStochastik4Test(causetstore) 273 c.Assert(err, IsNil) 274 _, err = se.InterDircute(context.Background(), "use test") 275 c.Assert(err, IsNil) 276 277 var input []string 278 var output []struct { 279 ALLEGROALLEGROSQL string 280 Best string 281 } 282 s.testData.GetTestCases(c, &input, &output) 283 for i, tt := range input { 284 comment := Commentf("case:%v allegrosql:%s", i, tt) 285 stmt, err := s.ParseOneStmt(tt, "", "") 286 c.Assert(err, IsNil, comment) 287 288 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 289 c.Assert(err, IsNil) 290 s.testData.OnRecord(func() { 291 output[i].ALLEGROALLEGROSQL = tt 292 output[i].Best = embedded.ToString(p) 293 }) 294 c.Assert(embedded.ToString(p), Equals, output[i].Best, comment) 295 } 296 } 297 298 func (s *testCausetSuite) TestPosetDagCausetBuilderUnionScan(c *C) { 299 defer testleak.AfterTest(c)() 300 causetstore, dom, err := newStoreWithBootstrap() 301 c.Assert(err, IsNil) 302 defer func() { 303 dom.Close() 304 causetstore.Close() 305 }() 306 se, err := stochastik.CreateStochastik4Test(causetstore) 307 c.Assert(err, IsNil) 308 _, err = se.InterDircute(context.Background(), "use test") 309 c.Assert(err, IsNil) 310 311 var input []string 312 var output []struct { 313 ALLEGROALLEGROSQL string 314 Best string 315 } 316 for i, tt := range input { 317 comment := Commentf("for %s", tt) 318 stmt, err := s.ParseOneStmt(tt, "", "") 319 c.Assert(err, IsNil, comment) 320 321 err = se.NewTxn(context.Background()) 322 c.Assert(err, IsNil) 323 // Make txn not read only. 324 txn, err := se.Txn(true) 325 c.Assert(err, IsNil) 326 txn.Set(ekv.Key("AAA"), []byte("BBB")) 327 se.StmtCommit() 328 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 329 c.Assert(err, IsNil) 330 s.testData.OnRecord(func() { 331 output[i].ALLEGROALLEGROSQL = tt 332 output[i].Best = embedded.ToString(p) 333 }) 334 c.Assert(embedded.ToString(p), Equals, output[i].Best, Commentf("for %s", tt)) 335 } 336 } 337 338 func (s *testCausetSuite) TestPosetDagCausetBuilderAgg(c *C) { 339 defer testleak.AfterTest(c)() 340 causetstore, dom, err := newStoreWithBootstrap() 341 c.Assert(err, IsNil) 342 defer func() { 343 dom.Close() 344 causetstore.Close() 345 }() 346 se, err := stochastik.CreateStochastik4Test(causetstore) 347 c.Assert(err, IsNil) 348 se.InterDircute(context.Background(), "use test") 349 se.InterDircute(context.Background(), "set sql_mode='STRICT_TRANS_TABLES'") // disable only full group by 350 ctx := se.(stochastikctx.Context) 351 stochastikVars := ctx.GetStochastikVars() 352 stochastikVars.SetHashAggFinalConcurrency(1) 353 stochastikVars.SetHashAggPartialConcurrency(1) 354 stochastikVars.SetDistALLEGROSQLScanConcurrency(15) 355 stochastikVars.InterlockingDirectorateConcurrency = 4 356 357 var input []string 358 var output []struct { 359 ALLEGROALLEGROSQL string 360 Best string 361 } 362 s.testData.GetTestCases(c, &input, &output) 363 for i, tt := range input { 364 comment := Commentf("for %s", tt) 365 stmt, err := s.ParseOneStmt(tt, "", "") 366 c.Assert(err, IsNil, comment) 367 368 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 369 c.Assert(err, IsNil) 370 s.testData.OnRecord(func() { 371 output[i].ALLEGROALLEGROSQL = tt 372 output[i].Best = embedded.ToString(p) 373 }) 374 c.Assert(embedded.ToString(p), Equals, output[i].Best, Commentf("for %s", tt)) 375 } 376 } 377 378 func (s *testCausetSuite) TestRefine(c *C) { 379 defer testleak.AfterTest(c)() 380 causetstore, dom, err := newStoreWithBootstrap() 381 c.Assert(err, IsNil) 382 defer func() { 383 dom.Close() 384 causetstore.Close() 385 }() 386 se, err := stochastik.CreateStochastik4Test(causetstore) 387 c.Assert(err, IsNil) 388 _, err = se.InterDircute(context.Background(), "use test") 389 c.Assert(err, IsNil) 390 391 var input []string 392 var output []struct { 393 ALLEGROALLEGROSQL string 394 Best string 395 } 396 s.testData.GetTestCases(c, &input, &output) 397 for i, tt := range input { 398 comment := Commentf("for %s", tt) 399 stmt, err := s.ParseOneStmt(tt, "", "") 400 c.Assert(err, IsNil, comment) 401 sc := se.(stochastikctx.Context).GetStochastikVars().StmtCtx 402 sc.IgnoreTruncate = false 403 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 404 c.Assert(err, IsNil, comment) 405 s.testData.OnRecord(func() { 406 output[i].ALLEGROALLEGROSQL = tt 407 output[i].Best = embedded.ToString(p) 408 }) 409 c.Assert(embedded.ToString(p), Equals, output[i].Best, comment) 410 } 411 } 412 413 func (s *testCausetSuite) TestAggEliminator(c *C) { 414 defer testleak.AfterTest(c)() 415 causetstore, dom, err := newStoreWithBootstrap() 416 c.Assert(err, IsNil) 417 defer func() { 418 dom.Close() 419 causetstore.Close() 420 }() 421 se, err := stochastik.CreateStochastik4Test(causetstore) 422 c.Assert(err, IsNil) 423 _, err = se.InterDircute(context.Background(), "use test") 424 c.Assert(err, IsNil) 425 se.InterDircute(context.Background(), "set sql_mode='STRICT_TRANS_TABLES'") // disable only full group by 426 var input []string 427 var output []struct { 428 ALLEGROALLEGROSQL string 429 Best string 430 } 431 s.testData.GetTestCases(c, &input, &output) 432 for i, tt := range input { 433 comment := Commentf("for %s", tt) 434 stmt, err := s.ParseOneStmt(tt, "", "") 435 c.Assert(err, IsNil, comment) 436 sc := se.(stochastikctx.Context).GetStochastikVars().StmtCtx 437 sc.IgnoreTruncate = false 438 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 439 c.Assert(err, IsNil) 440 s.testData.OnRecord(func() { 441 output[i].ALLEGROALLEGROSQL = tt 442 output[i].Best = embedded.ToString(p) 443 }) 444 c.Assert(embedded.ToString(p), Equals, output[i].Best, Commentf("for %s", tt)) 445 } 446 } 447 448 type overrideStore struct{ ekv.CausetStorage } 449 450 func (causetstore overrideStore) GetClient() ekv.Client { 451 cli := causetstore.CausetStorage.GetClient() 452 return overrideClient{cli} 453 } 454 455 type overrideClient struct{ ekv.Client } 456 457 func (cli overrideClient) IsRequestTypeSupported(reqType, subType int64) bool { 458 return false 459 } 460 461 func (s *testCausetSuite) TestRequestTypeSupportedOff(c *C) { 462 defer testleak.AfterTest(c)() 463 causetstore, dom, err := newStoreWithBootstrap() 464 c.Assert(err, IsNil) 465 defer func() { 466 dom.Close() 467 causetstore.Close() 468 }() 469 se, err := stochastik.CreateStochastik4Test(overrideStore{causetstore}) 470 c.Assert(err, IsNil) 471 _, err = se.InterDircute(context.Background(), "use test") 472 c.Assert(err, IsNil) 473 474 allegrosql := "select * from t where a in (1, 10, 20)" 475 expect := "BlockReader(Block(t))->Sel([in(test.t.a, 1, 10, 20)])" 476 477 stmt, err := s.ParseOneStmt(allegrosql, "", "") 478 c.Assert(err, IsNil) 479 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 480 c.Assert(err, IsNil) 481 c.Assert(embedded.ToString(p), Equals, expect, Commentf("for %s", allegrosql)) 482 } 483 484 func (s *testCausetSuite) TestIndexJoinUnionScan(c *C) { 485 defer testleak.AfterTest(c)() 486 causetstore, dom, err := newStoreWithBootstrap() 487 c.Assert(err, IsNil) 488 tk := testkit.NewTestKit(c, causetstore) 489 defer func() { 490 dom.Close() 491 causetstore.Close() 492 }() 493 494 tk.MustInterDirc("use test") 495 var input [][]string 496 var output []struct { 497 ALLEGROALLEGROSQL []string 498 Causet []string 499 } 500 tk.MustInterDirc("create causet t (a int primary key, b int, index idx(a))") 501 tk.MustInterDirc("create causet tt (a int primary key) partition by range (a) (partition p0 values less than (100), partition p1 values less than (200))") 502 503 tk.MustInterDirc(`set @@milevadb_partition_prune_mode='` + string(variable.StaticOnly) + `'`) 504 505 s.testData.GetTestCases(c, &input, &output) 506 for i, ts := range input { 507 tk.MustInterDirc("begin") 508 for j, tt := range ts { 509 if j != len(ts)-1 { 510 tk.MustInterDirc(tt) 511 } 512 s.testData.OnRecord(func() { 513 output[i].ALLEGROALLEGROSQL = ts 514 if j == len(ts)-1 { 515 output[i].Causet = s.testData.ConvertRowsToStrings(tk.MustQuery(tt).Rows()) 516 } 517 }) 518 if j == len(ts)-1 { 519 tk.MustQuery(tt).Check(testkit.Rows(output[i].Causet...)) 520 } 521 } 522 tk.MustInterDirc("rollback") 523 } 524 } 525 526 func (s *testCausetSuite) TestDoSubquery(c *C) { 527 defer testleak.AfterTest(c)() 528 causetstore, dom, err := newStoreWithBootstrap() 529 c.Assert(err, IsNil) 530 defer func() { 531 dom.Close() 532 causetstore.Close() 533 }() 534 se, err := stochastik.CreateStochastik4Test(causetstore) 535 c.Assert(err, IsNil) 536 _, err = se.InterDircute(context.Background(), "use test") 537 c.Assert(err, IsNil) 538 tests := []struct { 539 allegrosql string 540 best string 541 }{ 542 { 543 allegrosql: "do 1 in (select a from t)", 544 best: "LeftHashJoin{Dual->PointGet(Handle(t.a)1)}->Projection", 545 }, 546 } 547 for _, tt := range tests { 548 comment := Commentf("for %s", tt.allegrosql) 549 stmt, err := s.ParseOneStmt(tt.allegrosql, "", "") 550 c.Assert(err, IsNil, comment) 551 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 552 c.Assert(err, IsNil) 553 c.Assert(embedded.ToString(p), Equals, tt.best, comment) 554 } 555 } 556 557 func (s *testCausetSuite) TestIndexLookupCartesianJoin(c *C) { 558 defer testleak.AfterTest(c)() 559 causetstore, dom, err := newStoreWithBootstrap() 560 c.Assert(err, IsNil) 561 defer func() { 562 dom.Close() 563 causetstore.Close() 564 }() 565 se, err := stochastik.CreateStochastik4Test(causetstore) 566 c.Assert(err, IsNil) 567 _, err = se.InterDircute(context.Background(), "use test") 568 c.Assert(err, IsNil) 569 allegrosql := "select /*+ MilevaDB_INLJ(t1, t2) */ * from t t1 join t t2" 570 stmt, err := s.ParseOneStmt(allegrosql, "", "") 571 c.Assert(err, IsNil) 572 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 573 c.Assert(err, IsNil) 574 c.Assert(embedded.ToString(p), Equals, "LeftHashJoin{BlockReader(Block(t))->BlockReader(Block(t))}") 575 warnings := se.GetStochastikVars().StmtCtx.GetWarnings() 576 lastWarn := warnings[len(warnings)-1] 577 err = embedded.ErrInternal.GenWithStack("MilevaDB_INLJ hint is inapplicable without column equal ON condition") 578 c.Assert(terror.ErrorEqual(err, lastWarn.Err), IsTrue) 579 } 580 581 func (s *testCausetSuite) TestSemiJoinToInner(c *C) { 582 defer testleak.AfterTest(c)() 583 causetstore, dom, err := newStoreWithBootstrap() 584 c.Assert(err, IsNil) 585 defer func() { 586 dom.Close() 587 causetstore.Close() 588 }() 589 se, err := stochastik.CreateStochastik4Test(causetstore) 590 c.Assert(err, IsNil) 591 _, err = se.InterDircute(context.Background(), "use test") 592 c.Assert(err, IsNil) 593 var input []string 594 var output []struct { 595 ALLEGROALLEGROSQL string 596 Best string 597 } 598 s.testData.GetTestCases(c, &input, &output) 599 for i, tt := range input { 600 stmt, err := s.ParseOneStmt(tt, "", "") 601 c.Assert(err, IsNil) 602 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 603 c.Assert(err, IsNil) 604 s.testData.OnRecord(func() { 605 output[i].ALLEGROALLEGROSQL = tt 606 output[i].Best = embedded.ToString(p) 607 }) 608 c.Assert(embedded.ToString(p), Equals, output[i].Best) 609 } 610 } 611 612 func (s *testCausetSuite) TestUnmatchedBlockInHint(c *C) { 613 defer testleak.AfterTest(c)() 614 causetstore, dom, err := newStoreWithBootstrap() 615 c.Assert(err, IsNil) 616 defer func() { 617 dom.Close() 618 causetstore.Close() 619 }() 620 se, err := stochastik.CreateStochastik4Test(causetstore) 621 c.Assert(err, IsNil) 622 _, err = se.InterDircute(context.Background(), "use test") 623 c.Assert(err, IsNil) 624 var input []string 625 var output []struct { 626 ALLEGROALLEGROSQL string 627 Warning string 628 } 629 s.testData.GetTestCases(c, &input, &output) 630 for i, test := range input { 631 se.GetStochastikVars().StmtCtx.SetWarnings(nil) 632 stmt, err := s.ParseOneStmt(test, "", "") 633 c.Assert(err, IsNil) 634 _, _, err = causet.Optimize(context.TODO(), se, stmt, s.is) 635 c.Assert(err, IsNil) 636 warnings := se.GetStochastikVars().StmtCtx.GetWarnings() 637 s.testData.OnRecord(func() { 638 output[i].ALLEGROALLEGROSQL = test 639 if len(warnings) > 0 { 640 output[i].Warning = warnings[0].Err.Error() 641 } 642 }) 643 if output[i].Warning == "" { 644 c.Assert(len(warnings), Equals, 0) 645 } else { 646 c.Assert(len(warnings), Equals, 1) 647 c.Assert(warnings[0].Level, Equals, stmtctx.WarnLevelWarning) 648 c.Assert(warnings[0].Err.Error(), Equals, output[i].Warning) 649 } 650 } 651 } 652 653 func (s *testCausetSuite) TestHintScope(c *C) { 654 defer testleak.AfterTest(c)() 655 causetstore, dom, err := newStoreWithBootstrap() 656 c.Assert(err, IsNil) 657 defer func() { 658 dom.Close() 659 causetstore.Close() 660 }() 661 se, err := stochastik.CreateStochastik4Test(causetstore) 662 c.Assert(err, IsNil) 663 _, err = se.InterDircute(context.Background(), "use test") 664 c.Assert(err, IsNil) 665 666 var input []string 667 var output []struct { 668 ALLEGROALLEGROSQL string 669 Best string 670 } 671 s.testData.GetTestCases(c, &input, &output) 672 for i, test := range input { 673 comment := Commentf("case:%v allegrosql:%s", i, test) 674 stmt, err := s.ParseOneStmt(test, "", "") 675 c.Assert(err, IsNil, comment) 676 677 p, _, err := causet.Optimize(context.Background(), se, stmt, s.is) 678 c.Assert(err, IsNil) 679 s.testData.OnRecord(func() { 680 output[i].ALLEGROALLEGROSQL = test 681 output[i].Best = embedded.ToString(p) 682 }) 683 c.Assert(embedded.ToString(p), Equals, output[i].Best) 684 685 warnings := se.GetStochastikVars().StmtCtx.GetWarnings() 686 c.Assert(warnings, HasLen, 0, comment) 687 } 688 } 689 690 func (s *testCausetSuite) TestJoinHints(c *C) { 691 defer testleak.AfterTest(c)() 692 causetstore, dom, err := newStoreWithBootstrap() 693 c.Assert(err, IsNil) 694 defer func() { 695 dom.Close() 696 causetstore.Close() 697 }() 698 se, err := stochastik.CreateStochastik4Test(causetstore) 699 c.Assert(err, IsNil) 700 _, err = se.InterDircute(context.Background(), "use test") 701 c.Assert(err, IsNil) 702 703 var input []string 704 var output []struct { 705 ALLEGROALLEGROSQL string 706 Best string 707 Warning string 708 Hints string 709 } 710 s.testData.GetTestCases(c, &input, &output) 711 ctx := context.Background() 712 for i, test := range input { 713 comment := Commentf("case:%v allegrosql:%s", i, test) 714 stmt, err := s.ParseOneStmt(test, "", "") 715 c.Assert(err, IsNil, comment) 716 717 se.GetStochastikVars().StmtCtx.SetWarnings(nil) 718 p, _, err := causet.Optimize(ctx, se, stmt, s.is) 719 c.Assert(err, IsNil) 720 warnings := se.GetStochastikVars().StmtCtx.GetWarnings() 721 722 s.testData.OnRecord(func() { 723 output[i].ALLEGROALLEGROSQL = test 724 output[i].Best = embedded.ToString(p) 725 if len(warnings) > 0 { 726 output[i].Warning = warnings[0].Err.Error() 727 } 728 output[i].Hints = hint.RestoreOptimizerHints(embedded.GenHintsFromPhysicalCauset(p)) 729 }) 730 c.Assert(embedded.ToString(p), Equals, output[i].Best) 731 if output[i].Warning == "" { 732 c.Assert(len(warnings), Equals, 0) 733 } else { 734 c.Assert(len(warnings), Equals, 1, Commentf("%v", warnings)) 735 c.Assert(warnings[0].Level, Equals, stmtctx.WarnLevelWarning) 736 c.Assert(warnings[0].Err.Error(), Equals, output[i].Warning) 737 } 738 c.Assert(hint.RestoreOptimizerHints(embedded.GenHintsFromPhysicalCauset(p)), Equals, output[i].Hints, comment) 739 } 740 } 741 742 func (s *testCausetSuite) TestAggregationHints(c *C) { 743 defer testleak.AfterTest(c)() 744 causetstore, dom, err := newStoreWithBootstrap() 745 c.Assert(err, IsNil) 746 defer func() { 747 dom.Close() 748 causetstore.Close() 749 }() 750 se, err := stochastik.CreateStochastik4Test(causetstore) 751 c.Assert(err, IsNil) 752 _, err = se.InterDircute(context.Background(), "use test") 753 c.Assert(err, IsNil) 754 755 stochastikVars := se.(stochastikctx.Context).GetStochastikVars() 756 stochastikVars.SetHashAggFinalConcurrency(1) 757 stochastikVars.SetHashAggPartialConcurrency(1) 758 759 var input []struct { 760 ALLEGROALLEGROSQL string 761 AggPushDown bool 762 } 763 var output []struct { 764 ALLEGROALLEGROSQL string 765 Best string 766 Warning string 767 } 768 s.testData.GetTestCases(c, &input, &output) 769 ctx := context.Background() 770 for i, test := range input { 771 comment := Commentf("case:%v allegrosql:%s", i, test) 772 se.GetStochastikVars().StmtCtx.SetWarnings(nil) 773 se.GetStochastikVars().AllowAggPushDown = test.AggPushDown 774 775 stmt, err := s.ParseOneStmt(test.ALLEGROALLEGROSQL, "", "") 776 c.Assert(err, IsNil, comment) 777 778 p, _, err := causet.Optimize(ctx, se, stmt, s.is) 779 c.Assert(err, IsNil) 780 warnings := se.GetStochastikVars().StmtCtx.GetWarnings() 781 782 s.testData.OnRecord(func() { 783 output[i].ALLEGROALLEGROSQL = test.ALLEGROALLEGROSQL 784 output[i].Best = embedded.ToString(p) 785 if len(warnings) > 0 { 786 output[i].Warning = warnings[0].Err.Error() 787 } 788 }) 789 c.Assert(embedded.ToString(p), Equals, output[i].Best, comment) 790 if output[i].Warning == "" { 791 c.Assert(len(warnings), Equals, 0, comment) 792 } else { 793 c.Assert(len(warnings), Equals, 1, comment) 794 c.Assert(warnings[0].Level, Equals, stmtctx.WarnLevelWarning, comment) 795 c.Assert(warnings[0].Err.Error(), Equals, output[i].Warning, comment) 796 } 797 } 798 } 799 800 func (s *testCausetSuite) TestAggToCopHint(c *C) { 801 defer testleak.AfterTest(c)() 802 causetstore, dom, err := newStoreWithBootstrap() 803 c.Assert(err, IsNil) 804 defer func() { 805 dom.Close() 806 causetstore.Close() 807 }() 808 tk := testkit.NewTestKit(c, causetstore) 809 tk.MustInterDirc("use test") 810 tk.MustInterDirc("drop causet if exists ta") 811 tk.MustInterDirc("create causet ta(a int, b int, index(a))") 812 813 var ( 814 input []string 815 output []struct { 816 ALLEGROALLEGROSQL string 817 Best string 818 Warning string 819 } 820 ) 821 s.testData.GetTestCases(c, &input, &output) 822 823 ctx := context.Background() 824 is := petri.GetPetri(tk.Se).SchemaReplicant() 825 for i, test := range input { 826 comment := Commentf("case:%v allegrosql:%s", i, test) 827 s.testData.OnRecord(func() { 828 output[i].ALLEGROALLEGROSQL = test 829 }) 830 c.Assert(test, Equals, output[i].ALLEGROALLEGROSQL, comment) 831 832 tk.Se.GetStochastikVars().StmtCtx.SetWarnings(nil) 833 834 stmt, err := s.ParseOneStmt(test, "", "") 835 c.Assert(err, IsNil, comment) 836 837 p, _, err := causet.Optimize(ctx, tk.Se, stmt, is) 838 c.Assert(err, IsNil) 839 planString := embedded.ToString(p) 840 s.testData.OnRecord(func() { 841 output[i].Best = planString 842 }) 843 c.Assert(planString, Equals, output[i].Best, comment) 844 845 warnings := tk.Se.GetStochastikVars().StmtCtx.GetWarnings() 846 s.testData.OnRecord(func() { 847 if len(warnings) > 0 { 848 output[i].Warning = warnings[0].Err.Error() 849 } 850 }) 851 if output[i].Warning == "" { 852 c.Assert(len(warnings), Equals, 0, comment) 853 } else { 854 c.Assert(len(warnings), Equals, 1, comment) 855 c.Assert(warnings[0].Level, Equals, stmtctx.WarnLevelWarning, comment) 856 c.Assert(warnings[0].Err.Error(), Equals, output[i].Warning, comment) 857 } 858 } 859 } 860 861 func (s *testCausetSuite) TestLimitToCopHint(c *C) { 862 defer testleak.AfterTest(c)() 863 causetstore, dom, err := newStoreWithBootstrap() 864 c.Assert(err, IsNil) 865 defer func() { 866 dom.Close() 867 causetstore.Close() 868 }() 869 tk := testkit.NewTestKit(c, causetstore) 870 tk.MustInterDirc("use test") 871 tk.MustInterDirc("drop causet if exists tn") 872 tk.MustInterDirc("create causet tn(a int, b int, c int, d int, key (a, b, c, d))") 873 874 var ( 875 input []string 876 output []struct { 877 ALLEGROALLEGROSQL string 878 Causet []string 879 Warning string 880 } 881 ) 882 883 s.testData.GetTestCases(c, &input, &output) 884 885 for i, ts := range input { 886 s.testData.OnRecord(func() { 887 output[i].ALLEGROALLEGROSQL = ts 888 output[i].Causet = s.testData.ConvertRowsToStrings(tk.MustQuery("explain " + ts).Rows()) 889 }) 890 tk.MustQuery("explain " + ts).Check(testkit.Rows(output[i].Causet...)) 891 892 comment := Commentf("case:%v allegrosql:%s", i, ts) 893 warnings := tk.Se.GetStochastikVars().StmtCtx.GetWarnings() 894 s.testData.OnRecord(func() { 895 if len(warnings) > 0 { 896 output[i].Warning = warnings[0].Err.Error() 897 } 898 }) 899 if output[i].Warning == "" { 900 c.Assert(len(warnings), Equals, 0, comment) 901 } else { 902 c.Assert(len(warnings), Equals, 1, comment) 903 c.Assert(warnings[0].Level, Equals, stmtctx.WarnLevelWarning, comment) 904 c.Assert(warnings[0].Err.Error(), Equals, output[i].Warning, comment) 905 } 906 } 907 } 908 909 func (s *testCausetSuite) TestPushdownDistinctEnable(c *C) { 910 defer testleak.AfterTest(c)() 911 var ( 912 input []string 913 output []struct { 914 ALLEGROALLEGROSQL string 915 Causet []string 916 Result []string 917 } 918 ) 919 s.testData.GetTestCases(c, &input, &output) 920 vars := []string{ 921 fmt.Sprintf("set @@stochastik.%s = 1", variable.MilevaDBOptDistinctAggPushDown), 922 "set stochastik milevadb_opt_agg_push_down = 1", 923 } 924 s.doTestPushdownDistinct(c, vars, input, output) 925 } 926 927 func (s *testCausetSuite) TestPushdownDistinctDisable(c *C) { 928 defer testleak.AfterTest(c)() 929 var ( 930 input []string 931 output []struct { 932 ALLEGROALLEGROSQL string 933 Causet []string 934 Result []string 935 } 936 ) 937 938 s.testData.GetTestCases(c, &input, &output) 939 vars := []string{ 940 fmt.Sprintf("set @@stochastik.%s = 0", variable.MilevaDBOptDistinctAggPushDown), 941 "set stochastik milevadb_opt_agg_push_down = 1", 942 } 943 s.doTestPushdownDistinct(c, vars, input, output) 944 } 945 946 func (s *testCausetSuite) TestPushdownDistinctEnableAggPushDownDisable(c *C) { 947 var ( 948 input []string 949 output []struct { 950 ALLEGROALLEGROSQL string 951 Causet []string 952 Result []string 953 } 954 ) 955 s.testData.GetTestCases(c, &input, &output) 956 vars := []string{ 957 fmt.Sprintf("set @@stochastik.%s = 1", variable.MilevaDBOptDistinctAggPushDown), 958 "set stochastik milevadb_opt_agg_push_down = 0", 959 } 960 s.doTestPushdownDistinct(c, vars, input, output) 961 } 962 963 func (s *testCausetSuite) doTestPushdownDistinct(c *C, vars, input []string, output []struct { 964 ALLEGROALLEGROSQL string 965 Causet []string 966 Result []string 967 }) { 968 causetstore, dom, err := newStoreWithBootstrap() 969 c.Assert(err, IsNil) 970 defer func() { 971 dom.Close() 972 causetstore.Close() 973 }() 974 tk := testkit.NewTestKit(c, causetstore) 975 tk.MustInterDirc("use test") 976 977 tk.MustInterDirc("drop causet if exists t") 978 tk.MustInterDirc("create causet t(a int, b int, c int, index(c))") 979 tk.MustInterDirc("insert into t values (1, 1, 1), (1, 1, 3), (1, 2, 3), (2, 1, 3), (1, 2, NULL);") 980 981 tk.MustInterDirc("drop causet if exists pt") 982 tk.MustInterDirc(`CREATE TABLE pt (a int, b int) PARTITION BY RANGE (a) ( 983 PARTITION p0 VALUES LESS THAN (2), 984 PARTITION p1 VALUES LESS THAN (100) 985 );`) 986 987 tk.MustInterDirc("drop causet if exists ta") 988 tk.MustInterDirc("create causet ta(a int);") 989 tk.MustInterDirc("insert into ta values(1), (1);") 990 tk.MustInterDirc("drop causet if exists tb") 991 tk.MustInterDirc("create causet tb(a int);") 992 tk.MustInterDirc("insert into tb values(1), (1);") 993 994 tk.MustInterDirc("set stochastik sql_mode=''") 995 tk.MustInterDirc(fmt.Sprintf("set stochastik %s=1", variable.MilevaDBHashAggPartialConcurrency)) 996 tk.MustInterDirc(fmt.Sprintf("set stochastik %s=1", variable.MilevaDBHashAggFinalConcurrency)) 997 998 tk.MustInterDirc(`set @@milevadb_partition_prune_mode='` + string(variable.StaticOnly) + `'`) 999 1000 for _, v := range vars { 1001 tk.MustInterDirc(v) 1002 } 1003 1004 for i, ts := range input { 1005 s.testData.OnRecord(func() { 1006 output[i].ALLEGROALLEGROSQL = ts 1007 output[i].Causet = s.testData.ConvertRowsToStrings(tk.MustQuery("explain " + ts).Rows()) 1008 output[i].Result = s.testData.ConvertRowsToStrings(tk.MustQuery(ts).Sort().Rows()) 1009 }) 1010 tk.MustQuery("explain " + ts).Check(testkit.Rows(output[i].Causet...)) 1011 tk.MustQuery(ts).Sort().Check(testkit.Rows(output[i].Result...)) 1012 } 1013 } 1014 1015 func (s *testCausetSuite) TestGroupConcatOrderby(c *C) { 1016 var ( 1017 input []string 1018 output []struct { 1019 ALLEGROALLEGROSQL string 1020 Causet []string 1021 Result []string 1022 } 1023 ) 1024 s.testData.GetTestCases(c, &input, &output) 1025 causetstore, dom, err := newStoreWithBootstrap() 1026 c.Assert(err, IsNil) 1027 defer func() { 1028 dom.Close() 1029 causetstore.Close() 1030 }() 1031 tk := testkit.NewTestKit(c, causetstore) 1032 tk.MustInterDirc("use test") 1033 tk.MustInterDirc("drop causet if exists test;") 1034 tk.MustInterDirc("create causet test(id int, name int)") 1035 tk.MustInterDirc("insert into test values(1, 10);") 1036 tk.MustInterDirc("insert into test values(1, 20);") 1037 tk.MustInterDirc("insert into test values(1, 30);") 1038 tk.MustInterDirc("insert into test values(2, 20);") 1039 tk.MustInterDirc("insert into test values(3, 200);") 1040 tk.MustInterDirc("insert into test values(3, 500);") 1041 1042 tk.MustInterDirc("drop causet if exists ptest;") 1043 tk.MustInterDirc("CREATE TABLE ptest (id int,name int) PARTITION BY RANGE ( id ) " + 1044 "(PARTITION `p0` VALUES LESS THAN (2), PARTITION `p1` VALUES LESS THAN (11))") 1045 tk.MustInterDirc("insert into ptest select * from test;") 1046 tk.MustInterDirc(fmt.Sprintf("set stochastik milevadb_opt_distinct_agg_push_down = %v", 1)) 1047 tk.MustInterDirc(fmt.Sprintf("set stochastik milevadb_opt_agg_push_down = %v", 1)) 1048 1049 for i, ts := range input { 1050 s.testData.OnRecord(func() { 1051 output[i].ALLEGROALLEGROSQL = ts 1052 output[i].Causet = s.testData.ConvertRowsToStrings(tk.MustQuery("explain " + ts).Rows()) 1053 output[i].Result = s.testData.ConvertRowsToStrings(tk.MustQuery(ts).Sort().Rows()) 1054 }) 1055 tk.MustQuery("explain " + ts).Check(testkit.Rows(output[i].Causet...)) 1056 tk.MustQuery(ts).Check(testkit.Rows(output[i].Result...)) 1057 } 1058 } 1059 1060 func (s *testCausetSuite) TestHintAlias(c *C) { 1061 defer testleak.AfterTest(c)() 1062 causetstore, dom, err := newStoreWithBootstrap() 1063 c.Assert(err, IsNil) 1064 defer func() { 1065 dom.Close() 1066 causetstore.Close() 1067 }() 1068 se, err := stochastik.CreateStochastik4Test(causetstore) 1069 c.Assert(err, IsNil) 1070 _, err = se.InterDircute(context.Background(), "use test") 1071 c.Assert(err, IsNil) 1072 1073 tests := []struct { 1074 sql1 string 1075 sql2 string 1076 }{ 1077 { 1078 sql1: "select /*+ MilevaDB_SMJ(t1) */ t1.a, t1.b from t t1, (select /*+ MilevaDB_INLJ(t3) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", 1079 sql2: "select /*+ MERGE_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ INL_JOIN(t3) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", 1080 }, 1081 { 1082 sql1: "select /*+ MilevaDB_HJ(t1) */ t1.a, t1.b from t t1, (select /*+ MilevaDB_SMJ(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", 1083 sql2: "select /*+ HASH_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ MERGE_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", 1084 }, 1085 { 1086 sql1: "select /*+ MilevaDB_INLJ(t1) */ t1.a, t1.b from t t1, (select /*+ MilevaDB_HJ(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", 1087 sql2: "select /*+ INL_JOIN(t1) */ t1.a, t1.b from t t1, (select /*+ HASH_JOIN(t2) */ t2.a from t t2, t t3 where t2.a = t3.c) s where t1.a=s.a", 1088 }, 1089 } 1090 ctx := context.TODO() 1091 for i, tt := range tests { 1092 comment := Commentf("case:%v sql1:%s sql2:%s", i, tt.sql1, tt.sql2) 1093 stmt1, err := s.ParseOneStmt(tt.sql1, "", "") 1094 c.Assert(err, IsNil, comment) 1095 stmt2, err := s.ParseOneStmt(tt.sql2, "", "") 1096 c.Assert(err, IsNil, comment) 1097 1098 p1, _, err := causet.Optimize(ctx, se, stmt1, s.is) 1099 c.Assert(err, IsNil) 1100 p2, _, err := causet.Optimize(ctx, se, stmt2, s.is) 1101 c.Assert(err, IsNil) 1102 1103 c.Assert(embedded.ToString(p1), Equals, embedded.ToString(p2)) 1104 } 1105 } 1106 1107 func (s *testCausetSuite) TestIndexHint(c *C) { 1108 defer testleak.AfterTest(c)() 1109 causetstore, dom, err := newStoreWithBootstrap() 1110 c.Assert(err, IsNil) 1111 defer func() { 1112 dom.Close() 1113 causetstore.Close() 1114 }() 1115 se, err := stochastik.CreateStochastik4Test(causetstore) 1116 c.Assert(err, IsNil) 1117 _, err = se.InterDircute(context.Background(), "use test") 1118 c.Assert(err, IsNil) 1119 1120 var input []string 1121 var output []struct { 1122 ALLEGROALLEGROSQL string 1123 Best string 1124 HasWarn bool 1125 Hints string 1126 } 1127 s.testData.GetTestCases(c, &input, &output) 1128 ctx := context.Background() 1129 for i, test := range input { 1130 comment := Commentf("case:%v allegrosql:%s", i, test) 1131 se.GetStochastikVars().StmtCtx.SetWarnings(nil) 1132 1133 stmt, err := s.ParseOneStmt(test, "", "") 1134 c.Assert(err, IsNil, comment) 1135 1136 p, _, err := causet.Optimize(ctx, se, stmt, s.is) 1137 c.Assert(err, IsNil) 1138 s.testData.OnRecord(func() { 1139 output[i].ALLEGROALLEGROSQL = test 1140 output[i].Best = embedded.ToString(p) 1141 output[i].HasWarn = len(se.GetStochastikVars().StmtCtx.GetWarnings()) > 0 1142 output[i].Hints = hint.RestoreOptimizerHints(embedded.GenHintsFromPhysicalCauset(p)) 1143 }) 1144 c.Assert(embedded.ToString(p), Equals, output[i].Best, comment) 1145 warnings := se.GetStochastikVars().StmtCtx.GetWarnings() 1146 if output[i].HasWarn { 1147 c.Assert(warnings, HasLen, 1, comment) 1148 } else { 1149 c.Assert(warnings, HasLen, 0, comment) 1150 } 1151 c.Assert(hint.RestoreOptimizerHints(embedded.GenHintsFromPhysicalCauset(p)), Equals, output[i].Hints, comment) 1152 } 1153 } 1154 1155 func (s *testCausetSuite) TestIndexMergeHint(c *C) { 1156 defer testleak.AfterTest(c)() 1157 causetstore, dom, err := newStoreWithBootstrap() 1158 c.Assert(err, IsNil) 1159 defer func() { 1160 dom.Close() 1161 causetstore.Close() 1162 }() 1163 se, err := stochastik.CreateStochastik4Test(causetstore) 1164 c.Assert(err, IsNil) 1165 _, err = se.InterDircute(context.Background(), "use test") 1166 c.Assert(err, IsNil) 1167 1168 var input []string 1169 var output []struct { 1170 ALLEGROALLEGROSQL string 1171 Best string 1172 HasWarn bool 1173 Hints string 1174 } 1175 s.testData.GetTestCases(c, &input, &output) 1176 ctx := context.Background() 1177 for i, test := range input { 1178 comment := Commentf("case:%v allegrosql:%s", i, test) 1179 se.GetStochastikVars().StmtCtx.SetWarnings(nil) 1180 stmt, err := s.ParseOneStmt(test, "", "") 1181 c.Assert(err, IsNil, comment) 1182 sctx := se.(stochastikctx.Context) 1183 err = interlock.ResetContextOfStmt(sctx, stmt) 1184 c.Assert(err, IsNil) 1185 p, _, err := causet.Optimize(ctx, se, stmt, s.is) 1186 c.Assert(err, IsNil) 1187 s.testData.OnRecord(func() { 1188 output[i].ALLEGROALLEGROSQL = test 1189 output[i].Best = embedded.ToString(p) 1190 output[i].HasWarn = len(se.GetStochastikVars().StmtCtx.GetWarnings()) > 0 1191 output[i].Hints = hint.RestoreOptimizerHints(embedded.GenHintsFromPhysicalCauset(p)) 1192 }) 1193 c.Assert(embedded.ToString(p), Equals, output[i].Best, comment) 1194 warnings := se.GetStochastikVars().StmtCtx.GetWarnings() 1195 if output[i].HasWarn { 1196 c.Assert(warnings, HasLen, 1, comment) 1197 } else { 1198 c.Assert(warnings, HasLen, 0, comment) 1199 } 1200 c.Assert(hint.RestoreOptimizerHints(embedded.GenHintsFromPhysicalCauset(p)), Equals, output[i].Hints, comment) 1201 } 1202 } 1203 1204 func (s *testCausetSuite) TestQueryBlockHint(c *C) { 1205 defer testleak.AfterTest(c)() 1206 causetstore, dom, err := newStoreWithBootstrap() 1207 c.Assert(err, IsNil) 1208 defer func() { 1209 dom.Close() 1210 causetstore.Close() 1211 }() 1212 se, err := stochastik.CreateStochastik4Test(causetstore) 1213 c.Assert(err, IsNil) 1214 _, err = se.InterDircute(context.Background(), "use test") 1215 c.Assert(err, IsNil) 1216 1217 var input []string 1218 var output []struct { 1219 ALLEGROALLEGROSQL string 1220 Causet string 1221 Hints string 1222 } 1223 s.testData.GetTestCases(c, &input, &output) 1224 ctx := context.TODO() 1225 for i, tt := range input { 1226 comment := Commentf("case:%v allegrosql: %s", i, tt) 1227 stmt, err := s.ParseOneStmt(tt, "", "") 1228 c.Assert(err, IsNil, comment) 1229 1230 p, _, err := causet.Optimize(ctx, se, stmt, s.is) 1231 c.Assert(err, IsNil, comment) 1232 s.testData.OnRecord(func() { 1233 output[i].ALLEGROALLEGROSQL = tt 1234 output[i].Causet = embedded.ToString(p) 1235 output[i].Hints = hint.RestoreOptimizerHints(embedded.GenHintsFromPhysicalCauset(p)) 1236 }) 1237 c.Assert(embedded.ToString(p), Equals, output[i].Causet, comment) 1238 c.Assert(hint.RestoreOptimizerHints(embedded.GenHintsFromPhysicalCauset(p)), Equals, output[i].Hints, comment) 1239 } 1240 } 1241 1242 func (s *testCausetSuite) TestInlineProjection(c *C) { 1243 defer testleak.AfterTest(c)() 1244 causetstore, dom, err := newStoreWithBootstrap() 1245 c.Assert(err, IsNil) 1246 defer func() { 1247 dom.Close() 1248 causetstore.Close() 1249 }() 1250 se, err := stochastik.CreateStochastik4Test(causetstore) 1251 c.Assert(err, IsNil) 1252 ctx := context.Background() 1253 _, err = se.InterDircute(ctx, "use test") 1254 c.Assert(err, IsNil) 1255 _, err = se.InterDircute(ctx, `drop causet if exists test.t1, test.t2;`) 1256 c.Assert(err, IsNil) 1257 _, err = se.InterDircute(ctx, `create causet test.t1(a bigint, b bigint, index idx_a(a), index idx_b(b));`) 1258 c.Assert(err, IsNil) 1259 _, err = se.InterDircute(ctx, `create causet test.t2(a bigint, b bigint, index idx_a(a), index idx_b(b));`) 1260 c.Assert(err, IsNil) 1261 1262 var input []string 1263 var output []struct { 1264 ALLEGROALLEGROSQL string 1265 Causet string 1266 Hints string 1267 } 1268 is := petri.GetPetri(se).SchemaReplicant() 1269 s.testData.GetTestCases(c, &input, &output) 1270 for i, tt := range input { 1271 comment := Commentf("case:%v allegrosql: %s", i, tt) 1272 stmt, err := s.ParseOneStmt(tt, "", "") 1273 c.Assert(err, IsNil, comment) 1274 1275 p, _, err := causet.Optimize(ctx, se, stmt, is) 1276 c.Assert(err, IsNil, comment) 1277 s.testData.OnRecord(func() { 1278 output[i].ALLEGROALLEGROSQL = tt 1279 output[i].Causet = embedded.ToString(p) 1280 output[i].Hints = hint.RestoreOptimizerHints(embedded.GenHintsFromPhysicalCauset(p)) 1281 }) 1282 c.Assert(embedded.ToString(p), Equals, output[i].Causet, comment) 1283 c.Assert(hint.RestoreOptimizerHints(embedded.GenHintsFromPhysicalCauset(p)), Equals, output[i].Hints, comment) 1284 } 1285 } 1286 1287 func (s *testCausetSuite) TestPosetDagCausetBuilderSplitAvg(c *C) { 1288 defer testleak.AfterTest(c)() 1289 causetstore, dom, err := newStoreWithBootstrap() 1290 c.Assert(err, IsNil) 1291 defer func() { 1292 dom.Close() 1293 causetstore.Close() 1294 }() 1295 se, err := stochastik.CreateStochastik4Test(causetstore) 1296 c.Assert(err, IsNil) 1297 _, err = se.InterDircute(context.Background(), "use test") 1298 c.Assert(err, IsNil) 1299 tests := []struct { 1300 allegrosql string 1301 plan string 1302 }{ 1303 { 1304 allegrosql: "select avg(a),avg(b),avg(c) from t", 1305 plan: "BlockReader(Block(t)->StreamAgg)->StreamAgg", 1306 }, 1307 { 1308 allegrosql: "select /*+ HASH_AGG() */ avg(a),avg(b),avg(c) from t", 1309 plan: "BlockReader(Block(t)->HashAgg)->HashAgg", 1310 }, 1311 } 1312 1313 for _, tt := range tests { 1314 comment := Commentf("for %s", tt.allegrosql) 1315 stmt, err := s.ParseOneStmt(tt.allegrosql, "", "") 1316 c.Assert(err, IsNil, comment) 1317 1318 embedded.Preprocess(se, stmt, s.is) 1319 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 1320 c.Assert(err, IsNil, comment) 1321 1322 c.Assert(embedded.ToString(p), Equals, tt.plan, comment) 1323 root, ok := p.(embedded.PhysicalCauset) 1324 if !ok { 1325 continue 1326 } 1327 testPosetDagCausetBuilderSplitAvg(c, root) 1328 } 1329 } 1330 1331 func testPosetDagCausetBuilderSplitAvg(c *C, root embedded.PhysicalCauset) { 1332 if p, ok := root.(*embedded.PhysicalBlockReader); ok { 1333 if p.BlockCausets != nil { 1334 baseAgg := p.BlockCausets[len(p.BlockCausets)-1] 1335 if agg, ok := baseAgg.(*embedded.PhysicalHashAgg); ok { 1336 for i, aggfunc := range agg.AggFuncs { 1337 c.Assert(agg.Schema().DeferredCausets[i].RetType, Equals, aggfunc.RetTp) 1338 } 1339 } 1340 if agg, ok := baseAgg.(*embedded.PhysicalStreamAgg); ok { 1341 for i, aggfunc := range agg.AggFuncs { 1342 c.Assert(agg.Schema().DeferredCausets[i].RetType, Equals, aggfunc.RetTp) 1343 } 1344 } 1345 } 1346 } 1347 1348 childs := root.Children() 1349 if childs == nil { 1350 return 1351 } 1352 for _, son := range childs { 1353 testPosetDagCausetBuilderSplitAvg(c, son) 1354 } 1355 } 1356 1357 func (s *testCausetSuite) TestIndexJoinHint(c *C) { 1358 defer testleak.AfterTest(c)() 1359 causetstore, dom, err := newStoreWithBootstrap() 1360 c.Assert(err, IsNil) 1361 defer func() { 1362 dom.Close() 1363 causetstore.Close() 1364 }() 1365 se, err := stochastik.CreateStochastik4Test(causetstore) 1366 c.Assert(err, IsNil) 1367 ctx := context.Background() 1368 _, err = se.InterDircute(ctx, "use test") 1369 c.Assert(err, IsNil) 1370 _, err = se.InterDircute(ctx, `drop causet if exists test.t1, test.t2, test.t;`) 1371 c.Assert(err, IsNil) 1372 _, err = se.InterDircute(ctx, `create causet test.t1(a bigint, b bigint, index idx_a(a), index idx_b(b));`) 1373 c.Assert(err, IsNil) 1374 _, err = se.InterDircute(ctx, `create causet test.t2(a bigint, b bigint, index idx_a(a), index idx_b(b));`) 1375 c.Assert(err, IsNil) 1376 _, err = se.InterDircute(ctx, "CREATE TABLE `t` ( `a` bigint(20) NOT NULL, `b` tinyint(1) DEFAULT NULL, `c` datetime DEFAULT NULL, `d` int(10) unsigned DEFAULT NULL, `e` varchar(20) DEFAULT NULL, `f` double DEFAULT NULL, `g` decimal(30,5) DEFAULT NULL, `h` float DEFAULT NULL, `i` date DEFAULT NULL, `j` timestamp NULL DEFAULT NULL, PRIMARY KEY (`a`), UNIQUE KEY `b` (`b`), KEY `c` (`c`,`d`,`e`), KEY `f` (`f`), KEY `g` (`g`,`h`), KEY `g_2` (`g`), UNIQUE KEY `g_3` (`g`), KEY `i` (`i`) );") 1377 c.Assert(err, IsNil) 1378 var input []string 1379 var output []struct { 1380 ALLEGROALLEGROSQL string 1381 Causet string 1382 } 1383 is := petri.GetPetri(se).SchemaReplicant() 1384 s.testData.GetTestCases(c, &input, &output) 1385 for i, tt := range input { 1386 comment := Commentf("case:%v allegrosql: %s", i, tt) 1387 stmt, err := s.ParseOneStmt(tt, "", "") 1388 c.Assert(err, IsNil, comment) 1389 p, _, err := causet.Optimize(ctx, se, stmt, is) 1390 c.Assert(err, IsNil, comment) 1391 s.testData.OnRecord(func() { 1392 output[i].ALLEGROALLEGROSQL = tt 1393 output[i].Causet = embedded.ToString(p) 1394 }) 1395 c.Assert(embedded.ToString(p), Equals, output[i].Causet, comment) 1396 } 1397 } 1398 1399 func (s *testCausetSuite) TestPosetDagCausetBuilderWindow(c *C) { 1400 defer testleak.AfterTest(c)() 1401 var input []string 1402 var output []struct { 1403 ALLEGROALLEGROSQL string 1404 Best string 1405 } 1406 s.testData.GetTestCases(c, &input, &output) 1407 vars := []string{ 1408 "set @@stochastik.milevadb_window_concurrency = 1", 1409 } 1410 s.doTestPosetDagCausetBuilderWindow(c, vars, input, output) 1411 } 1412 1413 func (s *testCausetSuite) TestPosetDagCausetBuilderWindowParallel(c *C) { 1414 defer testleak.AfterTest(c)() 1415 var input []string 1416 var output []struct { 1417 ALLEGROALLEGROSQL string 1418 Best string 1419 } 1420 s.testData.GetTestCases(c, &input, &output) 1421 vars := []string{ 1422 "set @@stochastik.milevadb_window_concurrency = 4", 1423 } 1424 s.doTestPosetDagCausetBuilderWindow(c, vars, input, output) 1425 } 1426 1427 func (s *testCausetSuite) doTestPosetDagCausetBuilderWindow(c *C, vars, input []string, output []struct { 1428 ALLEGROALLEGROSQL string 1429 Best string 1430 }) { 1431 causetstore, dom, err := newStoreWithBootstrap() 1432 c.Assert(err, IsNil) 1433 defer func() { 1434 dom.Close() 1435 causetstore.Close() 1436 }() 1437 se, err := stochastik.CreateStochastik4Test(causetstore) 1438 c.Assert(err, IsNil) 1439 ctx := context.Background() 1440 _, err = se.InterDircute(ctx, "use test") 1441 c.Assert(err, IsNil) 1442 1443 for _, v := range vars { 1444 _, err = se.InterDircute(ctx, v) 1445 c.Assert(err, IsNil) 1446 } 1447 1448 for i, tt := range input { 1449 comment := Commentf("case:%v allegrosql:%s", i, tt) 1450 stmt, err := s.ParseOneStmt(tt, "", "") 1451 c.Assert(err, IsNil, comment) 1452 1453 err = se.NewTxn(context.Background()) 1454 c.Assert(err, IsNil) 1455 p, _, err := causet.Optimize(context.TODO(), se, stmt, s.is) 1456 c.Assert(err, IsNil) 1457 s.testData.OnRecord(func() { 1458 output[i].ALLEGROALLEGROSQL = tt 1459 output[i].Best = embedded.ToString(p) 1460 }) 1461 c.Assert(embedded.ToString(p), Equals, output[i].Best, comment) 1462 } 1463 } 1464 1465 func (s *testCausetSuite) TestNominalSort(c *C) { 1466 defer testleak.AfterTest(c)() 1467 causetstore, dom, err := newStoreWithBootstrap() 1468 c.Assert(err, IsNil) 1469 tk := testkit.NewTestKit(c, causetstore) 1470 defer func() { 1471 dom.Close() 1472 causetstore.Close() 1473 }() 1474 tk.MustInterDirc("use test") 1475 var input []string 1476 var output []struct { 1477 ALLEGROALLEGROSQL string 1478 Causet []string 1479 Result []string 1480 } 1481 tk.MustInterDirc("create causet t (a int, b int, index idx_a(a), index idx_b(b))") 1482 tk.MustInterDirc("insert into t values(1, 1)") 1483 tk.MustInterDirc("insert into t values(1, 2)") 1484 tk.MustInterDirc("insert into t values(2, 4)") 1485 tk.MustInterDirc("insert into t values(3, 5)") 1486 s.testData.GetTestCases(c, &input, &output) 1487 for i, ts := range input { 1488 s.testData.OnRecord(func() { 1489 output[i].ALLEGROALLEGROSQL = ts 1490 output[i].Causet = s.testData.ConvertRowsToStrings(tk.MustQuery("explain " + ts).Rows()) 1491 output[i].Result = s.testData.ConvertRowsToStrings(tk.MustQuery(ts).Rows()) 1492 }) 1493 tk.MustQuery("explain " + ts).Check(testkit.Rows(output[i].Causet...)) 1494 tk.MustQuery(ts).Check(testkit.Rows(output[i].Result...)) 1495 } 1496 } 1497 1498 func (s *testCausetSuite) TestHintFromDiffDatabase(c *C) { 1499 defer testleak.AfterTest(c)() 1500 causetstore, dom, err := newStoreWithBootstrap() 1501 c.Assert(err, IsNil) 1502 defer func() { 1503 dom.Close() 1504 causetstore.Close() 1505 }() 1506 se, err := stochastik.CreateStochastik4Test(causetstore) 1507 c.Assert(err, IsNil) 1508 ctx := context.Background() 1509 _, err = se.InterDircute(ctx, "use test") 1510 c.Assert(err, IsNil) 1511 _, err = se.InterDircute(ctx, `drop causet if exists test.t1`) 1512 c.Assert(err, IsNil) 1513 _, err = se.InterDircute(ctx, `create causet test.t1(a bigint, index idx_a(a));`) 1514 c.Assert(err, IsNil) 1515 _, err = se.InterDircute(ctx, `create causet test.t2(a bigint, index idx_a(a));`) 1516 c.Assert(err, IsNil) 1517 1518 _, err = se.InterDircute(ctx, "drop database if exists test2") 1519 c.Assert(err, IsNil) 1520 _, err = se.InterDircute(ctx, "create database test2") 1521 c.Assert(err, IsNil) 1522 _, err = se.InterDircute(ctx, "use test2") 1523 c.Assert(err, IsNil) 1524 1525 var input []string 1526 var output []struct { 1527 ALLEGROALLEGROSQL string 1528 Causet string 1529 } 1530 is := petri.GetPetri(se).SchemaReplicant() 1531 s.testData.GetTestCases(c, &input, &output) 1532 for i, tt := range input { 1533 comment := Commentf("case:%v allegrosql: %s", i, tt) 1534 stmt, err := s.ParseOneStmt(tt, "", "") 1535 c.Assert(err, IsNil, comment) 1536 p, _, err := causet.Optimize(ctx, se, stmt, is) 1537 c.Assert(err, IsNil, comment) 1538 s.testData.OnRecord(func() { 1539 output[i].ALLEGROALLEGROSQL = tt 1540 output[i].Causet = embedded.ToString(p) 1541 }) 1542 c.Assert(embedded.ToString(p), Equals, output[i].Causet, comment) 1543 } 1544 } 1545 1546 func (s *testCausetSuite) TestNthCausetHintWithExplain(c *C) { 1547 defer testleak.AfterTest(c)() 1548 causetstore, dom, err := newStoreWithBootstrap() 1549 c.Assert(err, IsNil) 1550 tk := testkit.NewTestKit(c, causetstore) 1551 defer func() { 1552 dom.Close() 1553 causetstore.Close() 1554 }() 1555 se, err := stochastik.CreateStochastik4Test(causetstore) 1556 c.Assert(err, IsNil) 1557 ctx := context.Background() 1558 _, err = se.InterDircute(ctx, "use test") 1559 c.Assert(err, IsNil) 1560 _, err = se.InterDircute(ctx, `drop causet if exists test.tt`) 1561 c.Assert(err, IsNil) 1562 _, err = se.InterDircute(ctx, `create causet test.tt (a int,b int, index(a), index(b));`) 1563 c.Assert(err, IsNil) 1564 1565 _, err = se.InterDircute(ctx, "insert into tt values (1, 1), (2, 2), (3, 4)") 1566 c.Assert(err, IsNil) 1567 1568 tk.MustInterDirc(`set @@milevadb_partition_prune_mode='` + string(variable.StaticOnly) + `'`) 1569 1570 var input []string 1571 var output []struct { 1572 ALLEGROALLEGROSQL string 1573 Causet []string 1574 } 1575 s.testData.GetTestCases(c, &input, &output) 1576 for i, ts := range input { 1577 s.testData.OnRecord(func() { 1578 output[i].ALLEGROALLEGROSQL = ts 1579 output[i].Causet = s.testData.ConvertRowsToStrings(tk.MustQuery("explain " + ts).Rows()) 1580 }) 1581 tk.MustQuery("explain " + ts).Check(testkit.Rows(output[i].Causet...)) 1582 } 1583 1584 // This assert makes sure a query with or without nth_plan() hint output exactly the same plan(including plan ID). 1585 // The query below is the same as queries in the testdata except for nth_plan() hint. 1586 // Currently its output is the same as the second test case in the testdata, which is `output[1]`. If this doesn't 1587 // hold in the future, you may need to modify this. 1588 tk.MustQuery("explain select * from test.tt where a=1 and b=1").Check(testkit.Rows(output[1].Causet...)) 1589 }