1/* 2 Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License, version 2.0, 6 as published by the Free Software Foundation. 7 8 This program is also distributed with certain software (including 9 but not limited to OpenSSL) that is licensed under separate terms, 10 as designated in a particular file or component or in included license 11 documentation. The authors of MySQL hereby grant you an additional 12 permission to link the program and your derivative works with the 13 separately licensed software that they have included with MySQL. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License, version 2.0, for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 23 24/* 25 Optimizer hint parser grammar 26*/ 27 28%{ 29#include "sql_class.h" 30#include "parse_tree_hints.h" 31#include "sql_lex_hints.h" 32#include "sql_const.h" 33 34#define NEW_PTN new (thd->mem_root) 35%} 36 37%pure-parser 38%yacc 39 40%parse-param { class THD *thd } 41%parse-param { class Hint_scanner *scanner } 42%parse-param { class PT_hint_list **ret } 43 44%lex-param { class Hint_scanner *scanner } 45 46%expect 0 47 48 49/* Hint keyword tokens */ 50 51%token MAX_EXECUTION_TIME_HINT 52 53%token BKA_HINT 54%token BNL_HINT 55%token DUPSWEEDOUT_HINT 56%token FIRSTMATCH_HINT 57%token INTOEXISTS_HINT 58%token LOOSESCAN_HINT 59%token MATERIALIZATION_HINT 60%token NO_BKA_HINT 61%token NO_BNL_HINT 62%token NO_ICP_HINT 63%token NO_MRR_HINT 64%token NO_RANGE_OPTIMIZATION_HINT 65%token NO_SEMIJOIN_HINT 66%token MRR_HINT 67%token QB_NAME_HINT 68%token SEMIJOIN_HINT 69%token SUBQUERY_HINT 70 71/* Other tokens */ 72 73%token HINT_ARG_NUMBER 74%token HINT_ARG_IDENT 75%token HINT_ARG_QB_NAME 76 77%token HINT_CLOSE 78%token HINT_ERROR 79 80/* Types */ 81%type <hint_type> 82 key_level_hint_type_on 83 key_level_hint_type_off 84 table_level_hint_type_on 85 table_level_hint_type_off 86 87%type <hint> 88 hint 89 max_execution_time_hint 90 index_level_hint 91 table_level_hint 92 qb_level_hint 93 qb_name_hint 94 95%type <hint_list> hint_list 96 97%type <hint_string> hint_param_index 98 99%type <hint_param_index_list> hint_param_index_list opt_hint_param_index_list 100 101%type <hint_param_table> 102 hint_param_table 103 hint_param_table_ext 104 hint_param_table_empty_qb 105 106%type <hint_param_table_list> 107 hint_param_table_list 108 opt_hint_param_table_list 109 hint_param_table_list_empty_qb 110 opt_hint_param_table_list_empty_qb 111 112%type <hint_string> 113 HINT_ARG_IDENT 114 HINT_ARG_NUMBER 115 HINT_ARG_QB_NAME 116 opt_qb_name 117 118%type <ulong_num> 119 semijoin_strategy semijoin_strategies 120 subquery_strategy 121%% 122 123 124start: 125 hint_list HINT_CLOSE 126 { *ret= $1; } 127 | hint_list error HINT_CLOSE 128 { *ret= $1; } 129 | error HINT_CLOSE 130 { *ret= NULL; } 131 ; 132 133hint_list: 134 hint 135 { 136 $$= NEW_PTN PT_hint_list(thd->mem_root); 137 if ($$ == NULL || $$->push_back($1)) 138 YYABORT; // OOM 139 } 140 | hint_list hint 141 { 142 $1->push_back($2); 143 $$= $1; 144 } 145 ; 146 147hint: 148 index_level_hint 149 | table_level_hint 150 | qb_level_hint 151 | qb_name_hint 152 | max_execution_time_hint 153 ; 154 155 156max_execution_time_hint: 157 MAX_EXECUTION_TIME_HINT '(' HINT_ARG_NUMBER ')' 158 { 159 int error; 160 char *end= const_cast<char *>($3.str + $3.length); 161 longlong n= my_strtoll10($3.str, &end, &error); 162 if (error != 0 || end != $3.str + $3.length || n > UINT_MAX32) 163 { 164 scanner->syntax_warning(ER_THD(thd, 165 ER_WARN_BAD_MAX_EXECUTION_TIME)); 166 $$= NULL; 167 } 168 else 169 { 170 $$= NEW_PTN PT_hint_max_execution_time(n); 171 if ($$ == NULL) 172 YYABORT; // OOM 173 } 174 } 175 ; 176 177 178opt_hint_param_table_list: 179 /* empty */ { $$.init(thd->mem_root); } 180 | hint_param_table_list 181 ; 182 183hint_param_table_list: 184 hint_param_table 185 { 186 $$.init(thd->mem_root); 187 if ($$.push_back($1)) 188 YYABORT; // OOM 189 } 190 | hint_param_table_list ',' hint_param_table 191 { 192 if ($1.push_back($3)) 193 YYABORT; // OOM 194 $$= $1; 195 } 196 ; 197 198opt_hint_param_table_list_empty_qb: 199 /* empty */ { $$.init(thd->mem_root); } 200 | hint_param_table_list_empty_qb 201 ; 202 203hint_param_table_list_empty_qb: 204 hint_param_table_empty_qb 205 { 206 $$.init(thd->mem_root); 207 if ($$.push_back($1)) 208 YYABORT; // OOM 209 } 210 | hint_param_table_list_empty_qb ',' hint_param_table_empty_qb 211 { 212 if ($1.push_back($3)) 213 YYABORT; // OOM 214 $$= $1; 215 } 216 ; 217 218opt_hint_param_index_list: 219 /* empty */ { $$.init(thd->mem_root); } 220 | hint_param_index_list 221 ; 222 223hint_param_index_list: 224 hint_param_index 225 { 226 $$.init(thd->mem_root); 227 if ($$.push_back($1)) 228 YYABORT; // OOM 229 } 230 | hint_param_index_list ',' hint_param_index 231 { 232 if ($1.push_back($3)) 233 YYABORT; // OOM 234 $$= $1; 235 } 236 ; 237 238hint_param_index: 239 HINT_ARG_IDENT 240 ; 241 242hint_param_table_empty_qb: 243 HINT_ARG_IDENT 244 { 245 $$.table= $1; 246 $$.opt_query_block= NULL_CSTR; 247 } 248 ; 249 250hint_param_table: 251 HINT_ARG_IDENT opt_qb_name 252 { 253 $$.table= $1; 254 $$.opt_query_block= $2; 255 } 256 ; 257 258hint_param_table_ext: 259 hint_param_table 260 | HINT_ARG_QB_NAME HINT_ARG_IDENT 261 { 262 $$.table= $2; 263 $$.opt_query_block= $1; 264 } 265 ; 266 267opt_qb_name: 268 /* empty */ { $$= NULL_CSTR; } 269 | HINT_ARG_QB_NAME 270 ; 271 272qb_level_hint: 273 SEMIJOIN_HINT '(' opt_qb_name semijoin_strategies ')' 274 { 275 $$= NEW_PTN PT_qb_level_hint($3, TRUE, SEMIJOIN_HINT_ENUM, $4); 276 if ($$ == NULL) 277 YYABORT; // OOM 278 } 279 | 280 NO_SEMIJOIN_HINT '(' opt_qb_name semijoin_strategies ')' 281 { 282 $$= NEW_PTN PT_qb_level_hint($3, FALSE, SEMIJOIN_HINT_ENUM, $4); 283 if ($$ == NULL) 284 YYABORT; // OOM 285 } 286 | 287 SUBQUERY_HINT '(' opt_qb_name subquery_strategy ')' 288 { 289 $$= NEW_PTN PT_qb_level_hint($3, TRUE, SUBQUERY_HINT_ENUM, $4); 290 if ($$ == NULL) 291 YYABORT; // OOM 292 } 293 ; 294 295semijoin_strategies: 296 /* empty */ { $$= 0; } 297 | semijoin_strategy 298 { 299 $$= $1; 300 } 301 | semijoin_strategies ',' semijoin_strategy 302 { 303 $$= $1 | $3; 304 } 305 ; 306 307semijoin_strategy: 308 FIRSTMATCH_HINT { $$= OPTIMIZER_SWITCH_FIRSTMATCH; } 309 | LOOSESCAN_HINT { $$= OPTIMIZER_SWITCH_LOOSE_SCAN; } 310 | MATERIALIZATION_HINT { $$= OPTIMIZER_SWITCH_MATERIALIZATION; } 311 | DUPSWEEDOUT_HINT { $$= OPTIMIZER_SWITCH_DUPSWEEDOUT; } 312 ; 313 314subquery_strategy: 315 MATERIALIZATION_HINT { $$= 316 Item_exists_subselect::EXEC_MATERIALIZATION; } 317 | INTOEXISTS_HINT { $$= Item_exists_subselect::EXEC_EXISTS; } 318 ; 319 320 321table_level_hint: 322 table_level_hint_type_on '(' opt_hint_param_table_list ')' 323 { 324 $$= NEW_PTN PT_table_level_hint(NULL_CSTR, $3, TRUE, $1); 325 if ($$ == NULL) 326 YYABORT; // OOM 327 } 328 | table_level_hint_type_on 329 '(' HINT_ARG_QB_NAME opt_hint_param_table_list_empty_qb ')' 330 { 331 $$= NEW_PTN PT_table_level_hint($3, $4, TRUE, $1); 332 if ($$ == NULL) 333 YYABORT; // OOM 334 } 335 | table_level_hint_type_off '(' opt_hint_param_table_list ')' 336 { 337 $$= NEW_PTN PT_table_level_hint(NULL_CSTR, $3, FALSE, $1); 338 if ($$ == NULL) 339 YYABORT; // OOM 340 } 341 | table_level_hint_type_off 342 '(' HINT_ARG_QB_NAME opt_hint_param_table_list_empty_qb ')' 343 { 344 $$= NEW_PTN PT_table_level_hint($3, $4, FALSE, $1); 345 if ($$ == NULL) 346 YYABORT; // OOM 347 } 348 ; 349 350index_level_hint: 351 key_level_hint_type_on 352 '(' hint_param_table_ext opt_hint_param_index_list ')' 353 { 354 $$= NEW_PTN PT_key_level_hint($3, $4, TRUE, $1); 355 if ($$ == NULL) 356 YYABORT; // OOM 357 } 358 | key_level_hint_type_off 359 '(' hint_param_table_ext opt_hint_param_index_list ')' 360 { 361 $$= NEW_PTN PT_key_level_hint($3, $4, FALSE, $1); 362 if ($$ == NULL) 363 YYABORT; // OOM 364 } 365 ; 366 367table_level_hint_type_on: 368 BKA_HINT 369 { 370 $$= BKA_HINT_ENUM; 371 } 372 | BNL_HINT 373 { 374 $$= BNL_HINT_ENUM; 375 } 376 ; 377 378table_level_hint_type_off: 379 NO_BKA_HINT 380 { 381 $$= BKA_HINT_ENUM; 382 } 383 | NO_BNL_HINT 384 { 385 $$= BNL_HINT_ENUM; 386 } 387 ; 388 389key_level_hint_type_on: 390 MRR_HINT 391 { 392 $$= MRR_HINT_ENUM; 393 } 394 | NO_RANGE_OPTIMIZATION_HINT 395 { 396 $$= NO_RANGE_HINT_ENUM; 397 } 398 ; 399 400key_level_hint_type_off: 401 NO_ICP_HINT 402 { 403 $$= ICP_HINT_ENUM; 404 } 405 | NO_MRR_HINT 406 { 407 $$= MRR_HINT_ENUM; 408 } 409 ; 410 411qb_name_hint: 412 QB_NAME_HINT '(' HINT_ARG_IDENT ')' 413 { 414 $$= NEW_PTN PT_hint_qb_name($3); 415 if ($$ == NULL) 416 YYABORT; // OOM 417 } 418 ; 419