github.com/pingcap/tidb/parser@v0.0.0-20231013125129-93a834a6bf8d/hintparser.y (about) 1 %{ 2 // Copyright 2020 PingCAP, Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package parser 16 17 import ( 18 "math" 19 "strconv" 20 21 "github.com/pingcap/tidb/parser/ast" 22 "github.com/pingcap/tidb/parser/model" 23 ) 24 25 %} 26 27 %union { 28 offset int 29 ident string 30 number uint64 31 hint *ast.TableOptimizerHint 32 hints []*ast.TableOptimizerHint 33 table ast.HintTable 34 modelIdents []model.CIStr 35 } 36 37 %token <number> 38 39 /*yy:token "%d" */ 40 hintIntLit "a 64-bit unsigned integer" 41 42 %token <ident> 43 44 /*yy:token "%c" */ 45 hintIdentifier 46 hintInvalid "a special token never used by parser, used by lexer to indicate error" 47 48 /*yy:token "@%c" */ 49 hintSingleAtIdentifier "identifier with single leading at" 50 51 /*yy:token "'%c'" */ 52 hintStringLit 53 54 /* MySQL 8.0 hint names */ 55 hintJoinFixedOrder "JOIN_FIXED_ORDER" 56 hintJoinOrder "JOIN_ORDER" 57 hintJoinPrefix "JOIN_PREFIX" 58 hintJoinSuffix "JOIN_SUFFIX" 59 hintBKA "BKA" 60 hintNoBKA "NO_BKA" 61 hintBNL "BNL" 62 hintNoBNL "NO_BNL" 63 hintHashJoin "HASH_JOIN" 64 hintHashJoinBuild "HASH_JOIN_BUILD" 65 hintHashJoinProbe "HASH_JOIN_PROBE" 66 hintNoHashJoin "NO_HASH_JOIN" 67 hintMerge "MERGE" 68 hintNoMerge "NO_MERGE" 69 hintIndexMerge "INDEX_MERGE" 70 hintNoIndexMerge "NO_INDEX_MERGE" 71 hintMRR "MRR" 72 hintNoMRR "NO_MRR" 73 hintNoICP "NO_ICP" 74 hintNoRangeOptimization "NO_RANGE_OPTIMIZATION" 75 hintSkipScan "SKIP_SCAN" 76 hintNoSkipScan "NO_SKIP_SCAN" 77 hintSemijoin "SEMIJOIN" 78 hintNoSemijoin "NO_SEMIJOIN" 79 hintMaxExecutionTime "MAX_EXECUTION_TIME" 80 hintSetVar "SET_VAR" 81 hintResourceGroup "RESOURCE_GROUP" 82 hintQBName "QB_NAME" 83 84 /* TiDB hint names */ 85 hintAggToCop "AGG_TO_COP" 86 hintIgnorePlanCache "IGNORE_PLAN_CACHE" 87 hintHashAgg "HASH_AGG" 88 hintMpp1PhaseAgg "MPP_1PHASE_AGG" 89 hintMpp2PhaseAgg "MPP_2PHASE_AGG" 90 hintIgnoreIndex "IGNORE_INDEX" 91 hintIndexJoin "INDEX_JOIN" 92 hintNoIndexJoin "NO_INDEX_JOIN" 93 hintInlHashJoin "INL_HASH_JOIN" 94 hintIndexHashJoin "INDEX_HASH_JOIN" 95 hintNoIndexHashJoin "NO_INDEX_HASH_JOIN" 96 hintInlJoin "INL_JOIN" 97 hintInlMergeJoin "INL_MERGE_JOIN" 98 hintIndexMergeJoin "INDEX_MERGE_JOIN" 99 hintNoIndexMergeJoin "NO_INDEX_MERGE_JOIN" 100 hintMemoryQuota "MEMORY_QUOTA" 101 hintNoSwapJoinInputs "NO_SWAP_JOIN_INPUTS" 102 hintQueryType "QUERY_TYPE" 103 hintReadConsistentReplica "READ_CONSISTENT_REPLICA" 104 hintReadFromStorage "READ_FROM_STORAGE" 105 hintSMJoin "MERGE_JOIN" 106 hintNoSMJoin "NO_MERGE_JOIN" 107 hintBCJoin "BROADCAST_JOIN" 108 hintShuffleJoin "SHUFFLE_JOIN" 109 hintStreamAgg "STREAM_AGG" 110 hintSwapJoinInputs "SWAP_JOIN_INPUTS" 111 hintUseIndexMerge "USE_INDEX_MERGE" 112 hintUseIndex "USE_INDEX" 113 hintOrderIndex "ORDER_INDEX" 114 hintNoOrderIndex "NO_ORDER_INDEX" 115 hintUsePlanCache "USE_PLAN_CACHE" 116 hintUseToja "USE_TOJA" 117 hintTimeRange "TIME_RANGE" 118 hintUseCascades "USE_CASCADES" 119 hintNthPlan "NTH_PLAN" 120 hintLimitToCop "LIMIT_TO_COP" 121 hintForceIndex "FORCE_INDEX" 122 hintStraightJoin "STRAIGHT_JOIN" 123 hintLeading "LEADING" 124 hintSemiJoinRewrite "SEMI_JOIN_REWRITE" 125 hintNoDecorrelate "NO_DECORRELATE" 126 127 /* Other keywords */ 128 hintOLAP "OLAP" 129 hintOLTP "OLTP" 130 hintPartition "PARTITION" 131 hintTiKV "TIKV" 132 hintTiFlash "TIFLASH" 133 hintFalse "FALSE" 134 hintTrue "TRUE" 135 hintMB "MB" 136 hintGB "GB" 137 hintDupsWeedOut "DUPSWEEDOUT" 138 hintFirstMatch "FIRSTMATCH" 139 hintLooseScan "LOOSESCAN" 140 hintMaterialization "MATERIALIZATION" 141 142 %type <ident> 143 Identifier "identifier (including keywords)" 144 QueryBlockOpt "Query block identifier optional" 145 JoinOrderOptimizerHintName 146 UnsupportedTableLevelOptimizerHintName 147 SupportedTableLevelOptimizerHintName 148 UnsupportedIndexLevelOptimizerHintName 149 SupportedIndexLevelOptimizerHintName 150 SubqueryOptimizerHintName 151 BooleanHintName "name of hints which take a boolean input" 152 NullaryHintName "name of hints which take no input" 153 SubqueryStrategy 154 Value "the value in the SET_VAR() hint" 155 HintQueryType "query type in optimizer hint (OLAP or OLTP)" 156 HintStorageType "storage type in optimizer hint (TiKV or TiFlash)" 157 158 %type <number> 159 UnitOfBytes "unit of bytes (MB or GB)" 160 CommaOpt "optional ','" 161 162 %type <hints> 163 OptimizerHintList "optimizer hint list" 164 StorageOptimizerHintOpt "storage level optimizer hint" 165 HintStorageTypeAndTableList "storage type and tables list in optimizer hint" 166 167 %type <hint> 168 TableOptimizerHintOpt "optimizer hint" 169 HintTableList "table list in optimizer hint" 170 HintTableListOpt "optional table list in optimizer hint" 171 HintIndexList "table name with index list in optimizer hint" 172 IndexNameList "index list in optimizer hint" 173 IndexNameListOpt "optional index list in optimizer hint" 174 ViewNameList "view name list in optimizer hint" 175 SubqueryStrategies "subquery strategies" 176 SubqueryStrategiesOpt "optional subquery strategies" 177 HintTrueOrFalse "true or false in optimizer hint" 178 HintStorageTypeAndTable "storage type and tables in optimizer hint" 179 180 %type <table> 181 HintTable "Table in optimizer hint" 182 ViewName "View name in optimizer hint" 183 184 %type <modelIdents> 185 PartitionList "partition name list in optimizer hint" 186 PartitionListOpt "optional partition name list in optimizer hint" 187 188 189 %start Start 190 191 %% 192 193 Start: 194 OptimizerHintList 195 { 196 parser.result = $1 197 } 198 199 OptimizerHintList: 200 TableOptimizerHintOpt 201 { 202 if $1 != nil { 203 $$ = []*ast.TableOptimizerHint{$1} 204 } 205 } 206 | OptimizerHintList CommaOpt TableOptimizerHintOpt 207 { 208 if $3 != nil { 209 $$ = append($1, $3) 210 } else { 211 $$ = $1 212 } 213 } 214 | StorageOptimizerHintOpt 215 { 216 $$ = $1 217 } 218 | OptimizerHintList CommaOpt StorageOptimizerHintOpt 219 { 220 $$ = append($1, $3...) 221 } 222 223 TableOptimizerHintOpt: 224 "JOIN_FIXED_ORDER" '(' QueryBlockOpt ')' 225 { 226 parser.warnUnsupportedHint($1) 227 $$ = nil 228 } 229 | JoinOrderOptimizerHintName '(' HintTableList ')' 230 { 231 parser.warnUnsupportedHint($1) 232 $$ = nil 233 } 234 | UnsupportedTableLevelOptimizerHintName '(' HintTableListOpt ')' 235 { 236 parser.warnUnsupportedHint($1) 237 $$ = nil 238 } 239 | SupportedTableLevelOptimizerHintName '(' HintTableListOpt ')' 240 { 241 h := $3 242 h.HintName = model.NewCIStr($1) 243 $$ = h 244 } 245 | UnsupportedIndexLevelOptimizerHintName '(' HintIndexList ')' 246 { 247 parser.warnUnsupportedHint($1) 248 $$ = nil 249 } 250 | SupportedIndexLevelOptimizerHintName '(' HintIndexList ')' 251 { 252 h := $3 253 h.HintName = model.NewCIStr($1) 254 $$ = h 255 } 256 | SubqueryOptimizerHintName '(' QueryBlockOpt SubqueryStrategiesOpt ')' 257 { 258 parser.warnUnsupportedHint($1) 259 $$ = nil 260 } 261 | "MAX_EXECUTION_TIME" '(' QueryBlockOpt hintIntLit ')' 262 { 263 $$ = &ast.TableOptimizerHint{ 264 HintName: model.NewCIStr($1), 265 QBName: model.NewCIStr($3), 266 HintData: $4, 267 } 268 } 269 | "NTH_PLAN" '(' QueryBlockOpt hintIntLit ')' 270 { 271 $$ = &ast.TableOptimizerHint{ 272 HintName: model.NewCIStr($1), 273 QBName: model.NewCIStr($3), 274 HintData: int64($4), 275 } 276 } 277 | "SET_VAR" '(' Identifier '=' Value ')' 278 { 279 $$ = &ast.TableOptimizerHint{ 280 HintName: model.NewCIStr($1), 281 HintData: ast.HintSetVar{ 282 VarName: $3, 283 Value: $5, 284 }, 285 } 286 } 287 | "RESOURCE_GROUP" '(' Identifier ')' 288 { 289 $$ = &ast.TableOptimizerHint{ 290 HintName: model.NewCIStr($1), 291 HintData: $3, 292 } 293 } 294 | "QB_NAME" '(' Identifier ')' 295 { 296 $$ = &ast.TableOptimizerHint{ 297 HintName: model.NewCIStr($1), 298 QBName: model.NewCIStr($3), 299 } 300 } 301 | "QB_NAME" '(' Identifier ',' ViewNameList ')' 302 { 303 $$ = &ast.TableOptimizerHint{ 304 HintName: model.NewCIStr($1), 305 QBName: model.NewCIStr($3), 306 Tables: $5.Tables, 307 } 308 } 309 | "MEMORY_QUOTA" '(' QueryBlockOpt hintIntLit UnitOfBytes ')' 310 { 311 maxValue := uint64(math.MaxInt64) / $5 312 if $4 <= maxValue { 313 $$ = &ast.TableOptimizerHint{ 314 HintName: model.NewCIStr($1), 315 HintData: int64($4 * $5), 316 QBName: model.NewCIStr($3), 317 } 318 } else { 319 yylex.AppendError(ErrWarnMemoryQuotaOverflow.GenWithStackByArgs(math.MaxInt64)) 320 parser.lastErrorAsWarn() 321 $$ = nil 322 } 323 } 324 | "TIME_RANGE" '(' hintStringLit CommaOpt hintStringLit ')' 325 { 326 $$ = &ast.TableOptimizerHint{ 327 HintName: model.NewCIStr($1), 328 HintData: ast.HintTimeRange{ 329 From: $3, 330 To: $5, 331 }, 332 } 333 } 334 | BooleanHintName '(' QueryBlockOpt HintTrueOrFalse ')' 335 { 336 h := $4 337 h.HintName = model.NewCIStr($1) 338 h.QBName = model.NewCIStr($3) 339 $$ = h 340 } 341 | NullaryHintName '(' QueryBlockOpt ')' 342 { 343 $$ = &ast.TableOptimizerHint{ 344 HintName: model.NewCIStr($1), 345 QBName: model.NewCIStr($3), 346 } 347 } 348 | "QUERY_TYPE" '(' QueryBlockOpt HintQueryType ')' 349 { 350 $$ = &ast.TableOptimizerHint{ 351 HintName: model.NewCIStr($1), 352 QBName: model.NewCIStr($3), 353 HintData: model.NewCIStr($4), 354 } 355 } 356 357 StorageOptimizerHintOpt: 358 "READ_FROM_STORAGE" '(' QueryBlockOpt HintStorageTypeAndTableList ')' 359 { 360 hs := $4 361 name := model.NewCIStr($1) 362 qb := model.NewCIStr($3) 363 for _, h := range hs { 364 h.HintName = name 365 h.QBName = qb 366 } 367 $$ = hs 368 } 369 370 HintStorageTypeAndTableList: 371 HintStorageTypeAndTable 372 { 373 $$ = []*ast.TableOptimizerHint{$1} 374 } 375 | HintStorageTypeAndTableList ',' HintStorageTypeAndTable 376 { 377 $$ = append($1, $3) 378 } 379 380 HintStorageTypeAndTable: 381 HintStorageType '[' HintTableList ']' 382 { 383 h := $3 384 h.HintData = model.NewCIStr($1) 385 $$ = h 386 } 387 388 QueryBlockOpt: 389 /* empty */ 390 { 391 $$ = "" 392 } 393 | hintSingleAtIdentifier 394 395 CommaOpt: 396 /*empty*/ 397 {} 398 | ',' 399 {} 400 401 PartitionListOpt: 402 /* empty */ 403 { 404 $$ = nil 405 } 406 | "PARTITION" '(' PartitionList ')' 407 { 408 $$ = $3 409 } 410 411 PartitionList: 412 Identifier 413 { 414 $$ = []model.CIStr{model.NewCIStr($1)} 415 } 416 | PartitionList CommaOpt Identifier 417 { 418 $$ = append($1, model.NewCIStr($3)) 419 } 420 421 /** 422 * HintTableListOpt: 423 * 424 * [@query_block_name] [tbl_name [, tbl_name] ...] 425 * [tbl_name@query_block_name [, tbl_name@query_block_name] ...] 426 * 427 */ 428 HintTableListOpt: 429 HintTableList 430 | QueryBlockOpt 431 { 432 $$ = &ast.TableOptimizerHint{ 433 QBName: model.NewCIStr($1), 434 } 435 } 436 437 HintTableList: 438 QueryBlockOpt HintTable 439 { 440 $$ = &ast.TableOptimizerHint{ 441 Tables: []ast.HintTable{$2}, 442 QBName: model.NewCIStr($1), 443 } 444 } 445 | HintTableList ',' HintTable 446 { 447 h := $1 448 h.Tables = append(h.Tables, $3) 449 $$ = h 450 } 451 452 HintTable: 453 Identifier QueryBlockOpt PartitionListOpt 454 { 455 $$ = ast.HintTable{ 456 TableName: model.NewCIStr($1), 457 QBName: model.NewCIStr($2), 458 PartitionList: $3, 459 } 460 } 461 | Identifier '.' Identifier QueryBlockOpt PartitionListOpt 462 { 463 $$ = ast.HintTable{ 464 DBName: model.NewCIStr($1), 465 TableName: model.NewCIStr($3), 466 QBName: model.NewCIStr($4), 467 PartitionList: $5, 468 } 469 } 470 471 ViewNameList: 472 ViewNameList '.' ViewName 473 { 474 h := $1 475 h.Tables = append(h.Tables, $3) 476 $$ = h 477 } 478 | ViewName 479 { 480 $$ = &ast.TableOptimizerHint{ 481 Tables: []ast.HintTable{$1}, 482 } 483 } 484 485 ViewName: 486 Identifier QueryBlockOpt 487 { 488 $$ = ast.HintTable{ 489 TableName: model.NewCIStr($1), 490 QBName: model.NewCIStr($2), 491 } 492 } 493 | QueryBlockOpt 494 { 495 $$ = ast.HintTable{ 496 QBName: model.NewCIStr($1), 497 } 498 } 499 500 /** 501 * HintIndexList: 502 * 503 * [@query_block_name] tbl_name [index_name [, index_name] ...] 504 * tbl_name@query_block_name [index_name [, index_name] ...] 505 */ 506 HintIndexList: 507 QueryBlockOpt HintTable CommaOpt IndexNameListOpt 508 { 509 h := $4 510 h.Tables = []ast.HintTable{$2} 511 h.QBName = model.NewCIStr($1) 512 $$ = h 513 } 514 515 IndexNameListOpt: 516 /* empty */ 517 { 518 $$ = &ast.TableOptimizerHint{} 519 } 520 | IndexNameList 521 522 IndexNameList: 523 Identifier 524 { 525 $$ = &ast.TableOptimizerHint{ 526 Indexes: []model.CIStr{model.NewCIStr($1)}, 527 } 528 } 529 | IndexNameList ',' Identifier 530 { 531 h := $1 532 h.Indexes = append(h.Indexes, model.NewCIStr($3)) 533 $$ = h 534 } 535 536 /** 537 * Miscellaneous rules 538 */ 539 SubqueryStrategiesOpt: 540 /* empty */ 541 {} 542 | SubqueryStrategies 543 544 SubqueryStrategies: 545 SubqueryStrategy 546 {} 547 | SubqueryStrategies ',' SubqueryStrategy 548 549 Value: 550 hintStringLit 551 | Identifier 552 | hintIntLit 553 { 554 $$ = strconv.FormatUint($1, 10) 555 } 556 | '+' hintIntLit 557 { 558 $$ = strconv.FormatUint($2, 10) 559 } 560 | '-' hintIntLit 561 { 562 if $2 > 9223372036854775808 { 563 yylex.AppendError(yylex.Errorf("the Signed Value should be at the range of [-9223372036854775808, 9223372036854775807].")) 564 return 1 565 } else if $2 == 9223372036854775808 { 566 signed_one := int64(1) 567 $$ = strconv.FormatInt(signed_one<<63, 10) 568 } else { 569 $$ = strconv.FormatInt(-int64($2), 10) 570 } 571 } 572 573 UnitOfBytes: 574 "MB" 575 { 576 $$ = 1024 * 1024 577 } 578 | "GB" 579 { 580 $$ = 1024 * 1024 * 1024 581 } 582 583 HintTrueOrFalse: 584 "TRUE" 585 { 586 $$ = &ast.TableOptimizerHint{HintData: true} 587 } 588 | "FALSE" 589 { 590 $$ = &ast.TableOptimizerHint{HintData: false} 591 } 592 593 JoinOrderOptimizerHintName: 594 "JOIN_ORDER" 595 | "JOIN_PREFIX" 596 | "JOIN_SUFFIX" 597 598 UnsupportedTableLevelOptimizerHintName: 599 "BKA" 600 | "NO_BKA" 601 | "BNL" 602 | "NO_BNL" 603 /* HASH_JOIN is supported by TiDB */ 604 | "NO_MERGE" 605 606 SupportedTableLevelOptimizerHintName: 607 "MERGE_JOIN" 608 | "NO_MERGE_JOIN" 609 | "BROADCAST_JOIN" 610 | "SHUFFLE_JOIN" 611 | "INL_JOIN" 612 | "INDEX_JOIN" 613 | "NO_INDEX_JOIN" 614 | "MERGE" 615 | "INL_HASH_JOIN" 616 | "INDEX_HASH_JOIN" 617 | "NO_INDEX_HASH_JOIN" 618 | "SWAP_JOIN_INPUTS" 619 | "NO_SWAP_JOIN_INPUTS" 620 | "INL_MERGE_JOIN" 621 | "INDEX_MERGE_JOIN" 622 | "NO_INDEX_MERGE_JOIN" 623 | "HASH_JOIN" 624 | "NO_HASH_JOIN" 625 | "HASH_JOIN_BUILD" 626 | "HASH_JOIN_PROBE" 627 | "LEADING" 628 629 UnsupportedIndexLevelOptimizerHintName: 630 "INDEX_MERGE" 631 /* NO_INDEX_MERGE is currently a nullary hint in TiDB */ 632 | "MRR" 633 | "NO_MRR" 634 | "NO_ICP" 635 | "NO_RANGE_OPTIMIZATION" 636 | "SKIP_SCAN" 637 | "NO_SKIP_SCAN" 638 639 SupportedIndexLevelOptimizerHintName: 640 "USE_INDEX" 641 | "IGNORE_INDEX" 642 | "USE_INDEX_MERGE" 643 | "FORCE_INDEX" 644 | "ORDER_INDEX" 645 | "NO_ORDER_INDEX" 646 647 SubqueryOptimizerHintName: 648 "SEMIJOIN" 649 | "NO_SEMIJOIN" 650 651 SubqueryStrategy: 652 "DUPSWEEDOUT" 653 | "FIRSTMATCH" 654 | "LOOSESCAN" 655 | "MATERIALIZATION" 656 657 BooleanHintName: 658 "USE_TOJA" 659 | "USE_CASCADES" 660 661 NullaryHintName: 662 "USE_PLAN_CACHE" 663 | "HASH_AGG" 664 | "MPP_1PHASE_AGG" 665 | "MPP_2PHASE_AGG" 666 | "STREAM_AGG" 667 | "AGG_TO_COP" 668 | "LIMIT_TO_COP" 669 | "NO_INDEX_MERGE" 670 | "READ_CONSISTENT_REPLICA" 671 | "IGNORE_PLAN_CACHE" 672 | "STRAIGHT_JOIN" 673 | "SEMI_JOIN_REWRITE" 674 | "NO_DECORRELATE" 675 676 HintQueryType: 677 "OLAP" 678 | "OLTP" 679 680 HintStorageType: 681 "TIKV" 682 | "TIFLASH" 683 684 Identifier: 685 hintIdentifier 686 /* MySQL 8.0 hint names */ 687 | "JOIN_FIXED_ORDER" 688 | "JOIN_ORDER" 689 | "JOIN_PREFIX" 690 | "JOIN_SUFFIX" 691 | "BKA" 692 | "NO_BKA" 693 | "BNL" 694 | "NO_BNL" 695 | "HASH_JOIN" 696 | "HASH_JOIN_BUILD" 697 | "HASH_JOIN_PROBE" 698 | "NO_HASH_JOIN" 699 | "MERGE" 700 | "NO_MERGE" 701 | "INDEX_MERGE" 702 | "NO_INDEX_MERGE" 703 | "MRR" 704 | "NO_MRR" 705 | "NO_ICP" 706 | "NO_RANGE_OPTIMIZATION" 707 | "SKIP_SCAN" 708 | "NO_SKIP_SCAN" 709 | "SEMIJOIN" 710 | "NO_SEMIJOIN" 711 | "MAX_EXECUTION_TIME" 712 | "SET_VAR" 713 | "RESOURCE_GROUP" 714 | "QB_NAME" 715 /* TiDB hint names */ 716 | "AGG_TO_COP" 717 | "LIMIT_TO_COP" 718 | "IGNORE_PLAN_CACHE" 719 | "HASH_AGG" 720 | "MPP_1PHASE_AGG" 721 | "MPP_2PHASE_AGG" 722 | "IGNORE_INDEX" 723 | "INL_HASH_JOIN" 724 | "INDEX_HASH_JOIN" 725 | "NO_INDEX_HASH_JOIN" 726 | "INL_JOIN" 727 | "INDEX_JOIN" 728 | "NO_INDEX_JOIN" 729 | "INL_MERGE_JOIN" 730 | "INDEX_MERGE_JOIN" 731 | "NO_INDEX_MERGE_JOIN" 732 | "MEMORY_QUOTA" 733 | "NO_SWAP_JOIN_INPUTS" 734 | "QUERY_TYPE" 735 | "READ_CONSISTENT_REPLICA" 736 | "READ_FROM_STORAGE" 737 | "MERGE_JOIN" 738 | "NO_MERGE_JOIN" 739 | "BROADCAST_JOIN" 740 | "SHUFFLE_JOIN" 741 | "STREAM_AGG" 742 | "SWAP_JOIN_INPUTS" 743 | "USE_INDEX_MERGE" 744 | "USE_INDEX" 745 | "ORDER_INDEX" 746 | "NO_ORDER_INDEX" 747 | "USE_PLAN_CACHE" 748 | "USE_TOJA" 749 | "TIME_RANGE" 750 | "USE_CASCADES" 751 | "NTH_PLAN" 752 | "FORCE_INDEX" 753 | "STRAIGHT_JOIN" 754 | "LEADING" 755 | "SEMI_JOIN_REWRITE" 756 | "NO_DECORRELATE" 757 /* other keywords */ 758 | "OLAP" 759 | "OLTP" 760 | "TIKV" 761 | "TIFLASH" 762 | "FALSE" 763 | "TRUE" 764 | "MB" 765 | "GB" 766 | "DUPSWEEDOUT" 767 | "FIRSTMATCH" 768 | "LOOSESCAN" 769 | "MATERIALIZATION" 770 %%