123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661 |
- %{
- // Copyright 2020 PingCAP, Inc.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package parser
- import (
- "math"
- "strconv"
- "github.com/pingcap/parser/ast"
- "github.com/pingcap/parser/model"
- )
- %}
- %union {
- offset int
- ident string
- number uint64
- hint *ast.TableOptimizerHint
- hints []*ast.TableOptimizerHint
- table ast.HintTable
- modelIdents []model.CIStr
- }
- %token <number>
- /*yy:token "%d" */
- hintIntLit "a 64-bit unsigned integer"
- %token <ident>
- /*yy:token "%c" */
- hintIdentifier
- /*yy:token "@%c" */
- hintSingleAtIdentifier "identifier with single leading at"
- /*yy:token "'%c'" */
- hintStringLit
- /* MySQL 8.0 hint names */
- hintJoinFixedOrder "JOIN_FIXED_ORDER"
- hintJoinOrder "JOIN_ORDER"
- hintJoinPrefix "JOIN_PREFIX"
- hintJoinSuffix "JOIN_SUFFIX"
- hintBKA "BKA"
- hintNoBKA "NO_BKA"
- hintBNL "BNL"
- hintNoBNL "NO_BNL"
- hintHashJoin "HASH_JOIN"
- hintNoHashJoin "NO_HASH_JOIN"
- hintMerge "MERGE"
- hintNoMerge "NO_MERGE"
- hintIndexMerge "INDEX_MERGE"
- hintNoIndexMerge "NO_INDEX_MERGE"
- hintMRR "MRR"
- hintNoMRR "NO_MRR"
- hintNoICP "NO_ICP"
- hintNoRangeOptimization "NO_RANGE_OPTIMIZATION"
- hintSkipScan "SKIP_SCAN"
- hintNoSkipScan "NO_SKIP_SCAN"
- hintSemijoin "SEMIJOIN"
- hintNoSemijoin "NO_SEMIJOIN"
- hintMaxExecutionTime "MAX_EXECUTION_TIME"
- hintSetVar "SET_VAR"
- hintResourceGroup "RESOURCE_GROUP"
- hintQBName "QB_NAME"
- /* TiDB hint names */
- hintAggToCop "AGG_TO_COP"
- hintIgnorePlanCache "IGNORE_PLAN_CACHE"
- hintHashAgg "HASH_AGG"
- hintIgnoreIndex "IGNORE_INDEX"
- hintInlHashJoin "INL_HASH_JOIN"
- hintInlJoin "INL_JOIN"
- hintInlMergeJoin "INL_MERGE_JOIN"
- hintMemoryQuota "MEMORY_QUOTA"
- hintNoSwapJoinInputs "NO_SWAP_JOIN_INPUTS"
- hintQueryType "QUERY_TYPE"
- hintReadConsistentReplica "READ_CONSISTENT_REPLICA"
- hintReadFromStorage "READ_FROM_STORAGE"
- hintSMJoin "MERGE_JOIN"
- hintBCJoin "BROADCAST_JOIN"
- hintBCJoinPreferLocal "BROADCAST_JOIN_LOCAL"
- hintStreamAgg "STREAM_AGG"
- hintSwapJoinInputs "SWAP_JOIN_INPUTS"
- hintUseIndexMerge "USE_INDEX_MERGE"
- hintUseIndex "USE_INDEX"
- hintUsePlanCache "USE_PLAN_CACHE"
- hintUseToja "USE_TOJA"
- hintTimeRange "TIME_RANGE"
- hintUseCascades "USE_CASCADES"
- hintNthPlan "NTH_PLAN"
- hintLimitToCop "LIMIT_TO_COP"
- hintForceIndex "FORCE_INDEX"
- /* Other keywords */
- hintOLAP "OLAP"
- hintOLTP "OLTP"
- hintPartition "PARTITION"
- hintTiKV "TIKV"
- hintTiFlash "TIFLASH"
- hintFalse "FALSE"
- hintTrue "TRUE"
- hintMB "MB"
- hintGB "GB"
- hintDupsWeedOut "DUPSWEEDOUT"
- hintFirstMatch "FIRSTMATCH"
- hintLooseScan "LOOSESCAN"
- hintMaterialization "MATERIALIZATION"
- %type <ident>
- Identifier "identifier (including keywords)"
- QueryBlockOpt "Query block identifier optional"
- JoinOrderOptimizerHintName
- UnsupportedTableLevelOptimizerHintName
- SupportedTableLevelOptimizerHintName
- UnsupportedIndexLevelOptimizerHintName
- SupportedIndexLevelOptimizerHintName
- SubqueryOptimizerHintName
- BooleanHintName "name of hints which take a boolean input"
- NullaryHintName "name of hints which take no input"
- SubqueryStrategy
- Value "the value in the SET_VAR() hint"
- HintQueryType "query type in optimizer hint (OLAP or OLTP)"
- HintStorageType "storage type in optimizer hint (TiKV or TiFlash)"
- %type <number>
- UnitOfBytes "unit of bytes (MB or GB)"
- CommaOpt "optional ','"
- %type <hints>
- OptimizerHintList "optimizer hint list"
- StorageOptimizerHintOpt "storage level optimizer hint"
- HintStorageTypeAndTableList "storage type and tables list in optimizer hint"
- %type <hint>
- TableOptimizerHintOpt "optimizer hint"
- HintTableList "table list in optimizer hint"
- HintTableListOpt "optional table list in optimizer hint"
- HintIndexList "table name with index list in optimizer hint"
- IndexNameList "index list in optimizer hint"
- IndexNameListOpt "optional index list in optimizer hint"
- SubqueryStrategies "subquery strategies"
- SubqueryStrategiesOpt "optional subquery strategies"
- HintTrueOrFalse "true or false in optimizer hint"
- HintStorageTypeAndTable "storage type and tables in optimizer hint"
- %type <table>
- HintTable "Table in optimizer hint"
- %type <modelIdents>
- PartitionList "partition name list in optimizer hint"
- PartitionListOpt "optional partition name list in optimizer hint"
- %start Start
- %%
- Start:
- OptimizerHintList
- {
- parser.result = $1
- }
- OptimizerHintList:
- TableOptimizerHintOpt
- {
- if $1 != nil {
- $$ = []*ast.TableOptimizerHint{$1}
- }
- }
- | OptimizerHintList CommaOpt TableOptimizerHintOpt
- {
- if $3 != nil {
- $$ = append($1, $3)
- } else {
- $$ = $1
- }
- }
- | StorageOptimizerHintOpt
- {
- $$ = $1
- }
- | OptimizerHintList CommaOpt StorageOptimizerHintOpt
- {
- $$ = append($1, $3...)
- }
- TableOptimizerHintOpt:
- "JOIN_FIXED_ORDER" '(' QueryBlockOpt ')'
- {
- parser.warnUnsupportedHint($1)
- $$ = nil
- }
- | JoinOrderOptimizerHintName '(' HintTableList ')'
- {
- parser.warnUnsupportedHint($1)
- $$ = nil
- }
- | UnsupportedTableLevelOptimizerHintName '(' HintTableListOpt ')'
- {
- parser.warnUnsupportedHint($1)
- $$ = nil
- }
- | SupportedTableLevelOptimizerHintName '(' HintTableListOpt ')'
- {
- h := $3
- h.HintName = model.NewCIStr($1)
- $$ = h
- }
- | UnsupportedIndexLevelOptimizerHintName '(' HintIndexList ')'
- {
- parser.warnUnsupportedHint($1)
- $$ = nil
- }
- | SupportedIndexLevelOptimizerHintName '(' HintIndexList ')'
- {
- h := $3
- h.HintName = model.NewCIStr($1)
- $$ = h
- }
- | SubqueryOptimizerHintName '(' QueryBlockOpt SubqueryStrategiesOpt ')'
- {
- parser.warnUnsupportedHint($1)
- $$ = nil
- }
- | "MAX_EXECUTION_TIME" '(' QueryBlockOpt hintIntLit ')'
- {
- $$ = &ast.TableOptimizerHint{
- HintName: model.NewCIStr($1),
- QBName: model.NewCIStr($3),
- HintData: $4,
- }
- }
- | "NTH_PLAN" '(' QueryBlockOpt hintIntLit ')'
- {
- $$ = &ast.TableOptimizerHint{
- HintName: model.NewCIStr($1),
- QBName: model.NewCIStr($3),
- HintData: int64($4),
- }
- }
- | "SET_VAR" '(' Identifier '=' Value ')'
- {
- $$ = &ast.TableOptimizerHint{
- HintName: model.NewCIStr($1),
- HintData: ast.HintSetVar{
- VarName: $3,
- Value: $5,
- },
- }
- }
- | "RESOURCE_GROUP" '(' Identifier ')'
- {
- parser.warnUnsupportedHint($1)
- $$ = nil
- }
- | "QB_NAME" '(' Identifier ')'
- {
- $$ = &ast.TableOptimizerHint{
- HintName: model.NewCIStr($1),
- QBName: model.NewCIStr($3),
- }
- }
- | "MEMORY_QUOTA" '(' QueryBlockOpt hintIntLit UnitOfBytes ')'
- {
- maxValue := uint64(math.MaxInt64) / $5
- if $4 <= maxValue {
- $$ = &ast.TableOptimizerHint{
- HintName: model.NewCIStr($1),
- HintData: int64($4 * $5),
- QBName: model.NewCIStr($3),
- }
- } else {
- yylex.AppendError(ErrWarnMemoryQuotaOverflow.GenWithStackByArgs(math.MaxInt64))
- parser.lastErrorAsWarn()
- $$ = nil
- }
- }
- | "TIME_RANGE" '(' hintStringLit CommaOpt hintStringLit ')'
- {
- $$ = &ast.TableOptimizerHint{
- HintName: model.NewCIStr($1),
- HintData: ast.HintTimeRange{
- From: $3,
- To: $5,
- },
- }
- }
- | BooleanHintName '(' QueryBlockOpt HintTrueOrFalse ')'
- {
- h := $4
- h.HintName = model.NewCIStr($1)
- h.QBName = model.NewCIStr($3)
- $$ = h
- }
- | NullaryHintName '(' QueryBlockOpt ')'
- {
- $$ = &ast.TableOptimizerHint{
- HintName: model.NewCIStr($1),
- QBName: model.NewCIStr($3),
- }
- }
- | "QUERY_TYPE" '(' QueryBlockOpt HintQueryType ')'
- {
- $$ = &ast.TableOptimizerHint{
- HintName: model.NewCIStr($1),
- QBName: model.NewCIStr($3),
- HintData: model.NewCIStr($4),
- }
- }
- StorageOptimizerHintOpt:
- "READ_FROM_STORAGE" '(' QueryBlockOpt HintStorageTypeAndTableList ')'
- {
- hs := $4
- name := model.NewCIStr($1)
- qb := model.NewCIStr($3)
- for _, h := range hs {
- h.HintName = name
- h.QBName = qb
- }
- $$ = hs
- }
- HintStorageTypeAndTableList:
- HintStorageTypeAndTable
- {
- $$ = []*ast.TableOptimizerHint{$1}
- }
- | HintStorageTypeAndTableList ',' HintStorageTypeAndTable
- {
- $$ = append($1, $3)
- }
- HintStorageTypeAndTable:
- HintStorageType '[' HintTableList ']'
- {
- h := $3
- h.HintData = model.NewCIStr($1)
- $$ = h
- }
- QueryBlockOpt:
- /* empty */
- {
- $$ = ""
- }
- | hintSingleAtIdentifier
- CommaOpt:
- /*empty*/
- {}
- | ','
- {}
- PartitionListOpt:
- /* empty */
- {
- $$ = nil
- }
- | "PARTITION" '(' PartitionList ')'
- {
- $$ = $3
- }
- PartitionList:
- Identifier
- {
- $$ = []model.CIStr{model.NewCIStr($1)}
- }
- | PartitionList CommaOpt Identifier
- {
- $$ = append($1, model.NewCIStr($3))
- }
- /**
- * HintTableListOpt:
- *
- * [@query_block_name] [tbl_name [, tbl_name] ...]
- * [tbl_name@query_block_name [, tbl_name@query_block_name] ...]
- *
- */
- HintTableListOpt:
- HintTableList
- | QueryBlockOpt
- {
- $$ = &ast.TableOptimizerHint{
- QBName: model.NewCIStr($1),
- }
- }
- HintTableList:
- QueryBlockOpt HintTable
- {
- $$ = &ast.TableOptimizerHint{
- Tables: []ast.HintTable{$2},
- QBName: model.NewCIStr($1),
- }
- }
- | HintTableList ',' HintTable
- {
- h := $1
- h.Tables = append(h.Tables, $3)
- $$ = h
- }
- HintTable:
- Identifier QueryBlockOpt PartitionListOpt
- {
- $$ = ast.HintTable{
- TableName: model.NewCIStr($1),
- QBName: model.NewCIStr($2),
- PartitionList: $3,
- }
- }
- | Identifier '.' Identifier QueryBlockOpt PartitionListOpt
- {
- $$ = ast.HintTable{
- DBName: model.NewCIStr($1),
- TableName: model.NewCIStr($3),
- QBName: model.NewCIStr($4),
- PartitionList: $5,
- }
- }
- /**
- * HintIndexList:
- *
- * [@query_block_name] tbl_name [index_name [, index_name] ...]
- * tbl_name@query_block_name [index_name [, index_name] ...]
- */
- HintIndexList:
- QueryBlockOpt HintTable CommaOpt IndexNameListOpt
- {
- h := $4
- h.Tables = []ast.HintTable{$2}
- h.QBName = model.NewCIStr($1)
- $$ = h
- }
- IndexNameListOpt:
- /* empty */
- {
- $$ = &ast.TableOptimizerHint{}
- }
- | IndexNameList
- IndexNameList:
- Identifier
- {
- $$ = &ast.TableOptimizerHint{
- Indexes: []model.CIStr{model.NewCIStr($1)},
- }
- }
- | IndexNameList ',' Identifier
- {
- h := $1
- h.Indexes = append(h.Indexes, model.NewCIStr($3))
- $$ = h
- }
- /**
- * Miscellaneous rules
- */
- SubqueryStrategiesOpt:
- /* empty */
- {}
- | SubqueryStrategies
- SubqueryStrategies:
- SubqueryStrategy
- {}
- | SubqueryStrategies ',' SubqueryStrategy
- Value:
- hintStringLit
- | Identifier
- | hintIntLit
- {
- $$ = strconv.FormatUint($1, 10)
- }
- UnitOfBytes:
- "MB"
- {
- $$ = 1024 * 1024
- }
- | "GB"
- {
- $$ = 1024 * 1024 * 1024
- }
- HintTrueOrFalse:
- "TRUE"
- {
- $$ = &ast.TableOptimizerHint{HintData: true}
- }
- | "FALSE"
- {
- $$ = &ast.TableOptimizerHint{HintData: false}
- }
- JoinOrderOptimizerHintName:
- "JOIN_ORDER"
- | "JOIN_PREFIX"
- | "JOIN_SUFFIX"
- UnsupportedTableLevelOptimizerHintName:
- "BKA"
- | "NO_BKA"
- | "BNL"
- | "NO_BNL"
- /* HASH_JOIN is supported by TiDB */
- | "NO_HASH_JOIN"
- | "MERGE"
- | "NO_MERGE"
- SupportedTableLevelOptimizerHintName:
- "MERGE_JOIN"
- | "BROADCAST_JOIN"
- | "BROADCAST_JOIN_LOCAL"
- | "INL_JOIN"
- | "INL_HASH_JOIN"
- | "SWAP_JOIN_INPUTS"
- | "NO_SWAP_JOIN_INPUTS"
- | "INL_MERGE_JOIN"
- | "HASH_JOIN"
- UnsupportedIndexLevelOptimizerHintName:
- "INDEX_MERGE"
- /* NO_INDEX_MERGE is currently a nullary hint in TiDB */
- | "MRR"
- | "NO_MRR"
- | "NO_ICP"
- | "NO_RANGE_OPTIMIZATION"
- | "SKIP_SCAN"
- | "NO_SKIP_SCAN"
- SupportedIndexLevelOptimizerHintName:
- "USE_INDEX"
- | "IGNORE_INDEX"
- | "USE_INDEX_MERGE"
- | "FORCE_INDEX"
- SubqueryOptimizerHintName:
- "SEMIJOIN"
- | "NO_SEMIJOIN"
- SubqueryStrategy:
- "DUPSWEEDOUT"
- | "FIRSTMATCH"
- | "LOOSESCAN"
- | "MATERIALIZATION"
- BooleanHintName:
- "USE_TOJA"
- | "USE_CASCADES"
- NullaryHintName:
- "USE_PLAN_CACHE"
- | "HASH_AGG"
- | "STREAM_AGG"
- | "AGG_TO_COP"
- | "LIMIT_TO_COP"
- | "NO_INDEX_MERGE"
- | "READ_CONSISTENT_REPLICA"
- | "IGNORE_PLAN_CACHE"
- HintQueryType:
- "OLAP"
- | "OLTP"
- HintStorageType:
- "TIKV"
- | "TIFLASH"
- Identifier:
- hintIdentifier
- /* MySQL 8.0 hint names */
- | "JOIN_FIXED_ORDER"
- | "JOIN_ORDER"
- | "JOIN_PREFIX"
- | "JOIN_SUFFIX"
- | "BKA"
- | "NO_BKA"
- | "BNL"
- | "NO_BNL"
- | "HASH_JOIN"
- | "NO_HASH_JOIN"
- | "MERGE"
- | "NO_MERGE"
- | "INDEX_MERGE"
- | "NO_INDEX_MERGE"
- | "MRR"
- | "NO_MRR"
- | "NO_ICP"
- | "NO_RANGE_OPTIMIZATION"
- | "SKIP_SCAN"
- | "NO_SKIP_SCAN"
- | "SEMIJOIN"
- | "NO_SEMIJOIN"
- | "MAX_EXECUTION_TIME"
- | "SET_VAR"
- | "RESOURCE_GROUP"
- | "QB_NAME"
- /* TiDB hint names */
- | "AGG_TO_COP"
- | "LIMIT_TO_COP"
- | "IGNORE_PLAN_CACHE"
- | "HASH_AGG"
- | "IGNORE_INDEX"
- | "INL_HASH_JOIN"
- | "INL_JOIN"
- | "INL_MERGE_JOIN"
- | "MEMORY_QUOTA"
- | "NO_SWAP_JOIN_INPUTS"
- | "QUERY_TYPE"
- | "READ_CONSISTENT_REPLICA"
- | "READ_FROM_STORAGE"
- | "MERGE_JOIN"
- | "BROADCAST_JOIN"
- | "BROADCAST_JOIN_LOCAL"
- | "STREAM_AGG"
- | "SWAP_JOIN_INPUTS"
- | "USE_INDEX_MERGE"
- | "USE_INDEX"
- | "USE_PLAN_CACHE"
- | "USE_TOJA"
- | "TIME_RANGE"
- | "USE_CASCADES"
- | "NTH_PLAN"
- | "FORCE_INDEX"
- /* other keywords */
- | "OLAP"
- | "OLTP"
- | "TIKV"
- | "TIFLASH"
- | "FALSE"
- | "TRUE"
- | "MB"
- | "GB"
- | "DUPSWEEDOUT"
- | "FIRSTMATCH"
- | "LOOSESCAN"
- | "MATERIALIZATION"
- %%
|