1 /***************************************************************************** 2 3 Copyright (c) 1997, 2014, Oracle and/or its affiliates. All Rights Reserved. 4 Copyright (c) 2017, 2019, MariaDB Corporation. 5 6 This program is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free Software 8 Foundation; version 2 of the License. 9 10 This program is distributed in the hope that it will be useful, but WITHOUT 11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License along with 15 this program; if not, write to the Free Software Foundation, Inc., 16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA 17 18 *****************************************************************************/ 19 20 /****************************************************** 21 SQL parser: input file for the GNU Bison parser generator 22 23 Look from pars0lex.l for instructions how to generate the C files for 24 the InnoDB parser. 25 26 Created 12/14/1997 Heikki Tuuri 27 *******************************************************/ 28 29 %{ 30 /* The value of the semantic attribute is a pointer to a query tree node 31 que_node_t */ 32 33 #include "univ.i" 34 #include <math.h> 35 #include "pars0pars.h" 36 #include "mem0mem.h" 37 #include "que0types.h" 38 #include "que0que.h" 39 #include "row0sel.h" 40 41 #if defined __GNUC__ && (!defined __clang_major__ || __clang_major__ > 11) 42 #pragma GCC diagnostic ignored "-Wfree-nonheap-object" 43 #endif 44 45 #define YYSTYPE que_node_t* 46 47 /* #define __STDC__ */ 48 int 49 yylex(void); 50 %} 51 52 %token PARS_INT_LIT 53 %token PARS_FLOAT_LIT 54 %token PARS_STR_LIT 55 %token PARS_NULL_LIT 56 %token PARS_ID_TOKEN 57 %token PARS_AND_TOKEN 58 %token PARS_OR_TOKEN 59 %token PARS_NOT_TOKEN 60 %token PARS_GE_TOKEN 61 %token PARS_LE_TOKEN 62 %token PARS_NE_TOKEN 63 %token PARS_PROCEDURE_TOKEN 64 %token PARS_IN_TOKEN 65 %token PARS_INT_TOKEN 66 %token PARS_CHAR_TOKEN 67 %token PARS_IS_TOKEN 68 %token PARS_BEGIN_TOKEN 69 %token PARS_END_TOKEN 70 %token PARS_IF_TOKEN 71 %token PARS_THEN_TOKEN 72 %token PARS_ELSE_TOKEN 73 %token PARS_ELSIF_TOKEN 74 %token PARS_LOOP_TOKEN 75 %token PARS_WHILE_TOKEN 76 %token PARS_RETURN_TOKEN 77 %token PARS_SELECT_TOKEN 78 %token PARS_COUNT_TOKEN 79 %token PARS_FROM_TOKEN 80 %token PARS_WHERE_TOKEN 81 %token PARS_FOR_TOKEN 82 %token PARS_DDOT_TOKEN 83 %token PARS_ORDER_TOKEN 84 %token PARS_BY_TOKEN 85 %token PARS_ASC_TOKEN 86 %token PARS_DESC_TOKEN 87 %token PARS_INSERT_TOKEN 88 %token PARS_INTO_TOKEN 89 %token PARS_VALUES_TOKEN 90 %token PARS_UPDATE_TOKEN 91 %token PARS_SET_TOKEN 92 %token PARS_DELETE_TOKEN 93 %token PARS_CURRENT_TOKEN 94 %token PARS_OF_TOKEN 95 %token PARS_CREATE_TOKEN 96 %token PARS_TABLE_TOKEN 97 %token PARS_INDEX_TOKEN 98 %token PARS_UNIQUE_TOKEN 99 %token PARS_CLUSTERED_TOKEN 100 %token PARS_ON_TOKEN 101 %token PARS_ASSIGN_TOKEN 102 %token PARS_DECLARE_TOKEN 103 %token PARS_CURSOR_TOKEN 104 %token PARS_SQL_TOKEN 105 %token PARS_OPEN_TOKEN 106 %token PARS_FETCH_TOKEN 107 %token PARS_CLOSE_TOKEN 108 %token PARS_NOTFOUND_TOKEN 109 %token PARS_TO_BINARY_TOKEN 110 %token PARS_SUBSTR_TOKEN 111 %token PARS_CONCAT_TOKEN 112 %token PARS_INSTR_TOKEN 113 %token PARS_LENGTH_TOKEN 114 %token PARS_COMMIT_TOKEN 115 %token PARS_ROLLBACK_TOKEN 116 %token PARS_WORK_TOKEN 117 %token PARS_EXIT_TOKEN 118 %token PARS_FUNCTION_TOKEN 119 %token PARS_LOCK_TOKEN 120 %token PARS_SHARE_TOKEN 121 %token PARS_MODE_TOKEN 122 %token PARS_LIKE_TOKEN 123 %token PARS_LIKE_TOKEN_EXACT 124 %token PARS_LIKE_TOKEN_PREFIX 125 %token PARS_LIKE_TOKEN_SUFFIX 126 %token PARS_LIKE_TOKEN_SUBSTR 127 %token PARS_TABLE_NAME_TOKEN 128 %token PARS_BIGINT_TOKEN 129 130 %left PARS_AND_TOKEN PARS_OR_TOKEN 131 %left PARS_NOT_TOKEN 132 %left '=' '<' '>' PARS_GE_TOKEN PARS_LE_TOKEN 133 %left '-' '+' 134 %left '*' '/' 135 %left NEG /* negation--unary minus */ 136 %left '%' 137 138 %expect 41 139 140 /* Grammar follows */ 141 %% 142 143 top_statement: 144 procedure_definition ';' 145 146 statement: 147 stored_procedure_call 148 | while_statement ';' 149 | for_statement ';' 150 | exit_statement ';' 151 | if_statement ';' 152 | return_statement ';' 153 | assignment_statement ';' 154 | select_statement ';' 155 | insert_statement ';' 156 | delete_statement_searched ';' 157 | delete_statement_positioned ';' 158 | update_statement_searched ';' 159 | update_statement_positioned ';' 160 | open_cursor_statement ';' 161 | fetch_statement ';' 162 | close_cursor_statement ';' 163 | commit_statement ';' 164 | rollback_statement ';' 165 | create_table ';' 166 | create_index ';' 167 ; 168 169 statement_list: 170 statement { $$ = que_node_list_add_last(NULL, $1); } 171 | statement_list statement 172 { $$ = que_node_list_add_last($1, $2); } 173 ; 174 175 exp: 176 PARS_ID_TOKEN { $$ = $1;} 177 | function_name '(' exp_list ')' 178 { $$ = pars_func($1, $3); } 179 | PARS_INT_LIT { $$ = $1;} 180 | PARS_FLOAT_LIT { $$ = $1;} 181 | PARS_STR_LIT { $$ = $1;} 182 | PARS_NULL_LIT { $$ = $1;} 183 | PARS_SQL_TOKEN { $$ = $1;} 184 | exp '+' exp { $$ = pars_op('+', $1, $3); } 185 | exp '-' exp { $$ = pars_op('-', $1, $3); } 186 | exp '*' exp { $$ = pars_op('*', $1, $3); } 187 | exp '/' exp { $$ = pars_op('/', $1, $3); } 188 | '-' exp %prec NEG { $$ = pars_op('-', $2, NULL); } 189 | '(' exp ')' { $$ = $2; } 190 | exp '=' exp { $$ = pars_op('=', $1, $3); } 191 | exp PARS_LIKE_TOKEN PARS_STR_LIT 192 { $$ = pars_op(PARS_LIKE_TOKEN, $1, $3); } 193 | exp '<' exp { $$ = pars_op('<', $1, $3); } 194 | exp '>' exp { $$ = pars_op('>', $1, $3); } 195 | exp PARS_GE_TOKEN exp { $$ = pars_op(PARS_GE_TOKEN, $1, $3); } 196 | exp PARS_LE_TOKEN exp { $$ = pars_op(PARS_LE_TOKEN, $1, $3); } 197 | exp PARS_NE_TOKEN exp { $$ = pars_op(PARS_NE_TOKEN, $1, $3); } 198 | exp PARS_AND_TOKEN exp{ $$ = pars_op(PARS_AND_TOKEN, $1, $3); } 199 | exp PARS_OR_TOKEN exp { $$ = pars_op(PARS_OR_TOKEN, $1, $3); } 200 | PARS_NOT_TOKEN exp { $$ = pars_op(PARS_NOT_TOKEN, $2, NULL); } 201 | PARS_ID_TOKEN '%' PARS_NOTFOUND_TOKEN 202 { $$ = pars_op(PARS_NOTFOUND_TOKEN, $1, NULL); } 203 | PARS_SQL_TOKEN '%' PARS_NOTFOUND_TOKEN 204 { $$ = pars_op(PARS_NOTFOUND_TOKEN, $1, NULL); } 205 ; 206 207 function_name: 208 PARS_TO_BINARY_TOKEN { $$ = &pars_to_binary_token; } 209 | PARS_SUBSTR_TOKEN { $$ = &pars_substr_token; } 210 | PARS_CONCAT_TOKEN { $$ = &pars_concat_token; } 211 | PARS_INSTR_TOKEN { $$ = &pars_instr_token; } 212 | PARS_LENGTH_TOKEN { $$ = &pars_length_token; } 213 ; 214 215 question_mark_list: 216 /* Nothing */ 217 | '?' 218 | question_mark_list ',' '?' 219 ; 220 221 stored_procedure_call: 222 '{' PARS_ID_TOKEN '(' question_mark_list ')' '}' 223 { $$ = pars_stored_procedure_call( 224 static_cast<sym_node_t*>($2)); } 225 ; 226 227 user_function_call: 228 PARS_ID_TOKEN '(' ')' { $$ = $1; } 229 ; 230 231 table_list: 232 table_name { $$ = que_node_list_add_last(NULL, $1); } 233 | table_list ',' table_name 234 { $$ = que_node_list_add_last($1, $3); } 235 ; 236 237 variable_list: 238 /* Nothing */ { $$ = NULL; } 239 | PARS_ID_TOKEN { $$ = que_node_list_add_last(NULL, $1); } 240 | variable_list ',' PARS_ID_TOKEN 241 { $$ = que_node_list_add_last($1, $3); } 242 ; 243 244 exp_list: 245 /* Nothing */ { $$ = NULL; } 246 | exp { $$ = que_node_list_add_last(NULL, $1);} 247 | exp_list ',' exp { $$ = que_node_list_add_last($1, $3); } 248 ; 249 250 select_item: 251 exp { $$ = $1; } 252 | PARS_COUNT_TOKEN '(' '*' ')' 253 { $$ = pars_func(&pars_count_token, 254 que_node_list_add_last(NULL, 255 sym_tab_add_int_lit( 256 pars_sym_tab_global, 1))); } 257 ; 258 259 select_item_list: 260 /* Nothing */ { $$ = NULL; } 261 | select_item { $$ = que_node_list_add_last(NULL, $1); } 262 | select_item_list ',' select_item 263 { $$ = que_node_list_add_last($1, $3); } 264 ; 265 266 select_list: 267 '*' { $$ = pars_select_list(&pars_star_denoter, 268 NULL); } 269 | select_item_list PARS_INTO_TOKEN variable_list 270 { $$ = pars_select_list( 271 $1, static_cast<sym_node_t*>($3)); } 272 | select_item_list { $$ = pars_select_list($1, NULL); } 273 ; 274 275 search_condition: 276 /* Nothing */ { $$ = NULL; } 277 | PARS_WHERE_TOKEN exp { $$ = $2; } 278 ; 279 280 for_update_clause: 281 /* Nothing */ { $$ = NULL; } 282 | PARS_FOR_TOKEN PARS_UPDATE_TOKEN 283 { $$ = &pars_update_token; } 284 ; 285 286 lock_shared_clause: 287 /* Nothing */ { $$ = NULL; } 288 | PARS_LOCK_TOKEN PARS_IN_TOKEN PARS_SHARE_TOKEN PARS_MODE_TOKEN 289 { $$ = &pars_share_token; } 290 ; 291 292 order_direction: 293 /* Nothing */ { $$ = &pars_asc_token; } 294 | PARS_ASC_TOKEN { $$ = &pars_asc_token; } 295 | PARS_DESC_TOKEN { $$ = &pars_desc_token; } 296 ; 297 298 order_by_clause: 299 /* Nothing */ { $$ = NULL; } 300 | PARS_ORDER_TOKEN PARS_BY_TOKEN PARS_ID_TOKEN order_direction 301 { $$ = pars_order_by( 302 static_cast<sym_node_t*>($3), 303 static_cast<pars_res_word_t*>($4)); } 304 ; 305 306 select_statement: 307 PARS_SELECT_TOKEN select_list 308 PARS_FROM_TOKEN table_list 309 search_condition 310 for_update_clause 311 lock_shared_clause 312 order_by_clause { $$ = pars_select_statement( 313 static_cast<sel_node_t*>($2), 314 static_cast<sym_node_t*>($4), 315 static_cast<que_node_t*>($5), 316 static_cast<pars_res_word_t*>($6), 317 static_cast<pars_res_word_t*>($7), 318 static_cast<order_node_t*>($8)); } 319 ; 320 321 insert_statement_start: 322 PARS_INSERT_TOKEN PARS_INTO_TOKEN 323 table_name { $$ = $3; } 324 ; 325 326 insert_statement: 327 insert_statement_start PARS_VALUES_TOKEN '(' exp_list ')' 328 { $$ = pars_insert_statement( 329 static_cast<sym_node_t*>($1), $4, NULL); } 330 | insert_statement_start select_statement 331 { $$ = pars_insert_statement( 332 static_cast<sym_node_t*>($1), 333 NULL, 334 static_cast<sel_node_t*>($2)); } 335 ; 336 337 column_assignment: 338 PARS_ID_TOKEN '=' exp { $$ = pars_column_assignment( 339 static_cast<sym_node_t*>($1), 340 static_cast<que_node_t*>($3)); } 341 ; 342 343 column_assignment_list: 344 column_assignment { $$ = que_node_list_add_last(NULL, $1); } 345 | column_assignment_list ',' column_assignment 346 { $$ = que_node_list_add_last($1, $3); } 347 ; 348 349 cursor_positioned: 350 PARS_WHERE_TOKEN 351 PARS_CURRENT_TOKEN PARS_OF_TOKEN 352 PARS_ID_TOKEN { $$ = $4; } 353 ; 354 355 update_statement_start: 356 PARS_UPDATE_TOKEN table_name 357 PARS_SET_TOKEN 358 column_assignment_list { $$ = pars_update_statement_start( 359 FALSE, 360 static_cast<sym_node_t*>($2), 361 static_cast<col_assign_node_t*>($4)); } 362 ; 363 364 update_statement_searched: 365 update_statement_start 366 search_condition { $$ = pars_update_statement( 367 static_cast<upd_node_t*>($1), 368 NULL, 369 static_cast<que_node_t*>($2)); } 370 ; 371 372 update_statement_positioned: 373 update_statement_start 374 cursor_positioned { $$ = pars_update_statement( 375 static_cast<upd_node_t*>($1), 376 static_cast<sym_node_t*>($2), 377 NULL); } 378 ; 379 380 delete_statement_start: 381 PARS_DELETE_TOKEN PARS_FROM_TOKEN 382 table_name { $$ = pars_update_statement_start( 383 TRUE, 384 static_cast<sym_node_t*>($3), NULL); } 385 ; 386 387 delete_statement_searched: 388 delete_statement_start 389 search_condition { $$ = pars_update_statement( 390 static_cast<upd_node_t*>($1), 391 NULL, 392 static_cast<que_node_t*>($2)); } 393 ; 394 395 delete_statement_positioned: 396 delete_statement_start 397 cursor_positioned { $$ = pars_update_statement( 398 static_cast<upd_node_t*>($1), 399 static_cast<sym_node_t*>($2), 400 NULL); } 401 ; 402 403 assignment_statement: 404 PARS_ID_TOKEN PARS_ASSIGN_TOKEN exp 405 { $$ = pars_assignment_statement( 406 static_cast<sym_node_t*>($1), 407 static_cast<que_node_t*>($3)); } 408 ; 409 410 elsif_element: 411 PARS_ELSIF_TOKEN 412 exp PARS_THEN_TOKEN statement_list 413 { $$ = pars_elsif_element($2, $4); } 414 ; 415 416 elsif_list: 417 elsif_element { $$ = que_node_list_add_last(NULL, $1); } 418 | elsif_list elsif_element 419 { $$ = que_node_list_add_last($1, $2); } 420 ; 421 422 else_part: 423 /* Nothing */ { $$ = NULL; } 424 | PARS_ELSE_TOKEN statement_list 425 { $$ = $2; } 426 | elsif_list { $$ = $1; } 427 ; 428 429 if_statement: 430 PARS_IF_TOKEN exp PARS_THEN_TOKEN statement_list 431 else_part 432 PARS_END_TOKEN PARS_IF_TOKEN 433 { $$ = pars_if_statement($2, $4, $5); } 434 ; 435 436 while_statement: 437 PARS_WHILE_TOKEN exp PARS_LOOP_TOKEN statement_list 438 PARS_END_TOKEN PARS_LOOP_TOKEN 439 { $$ = pars_while_statement($2, $4); } 440 ; 441 442 for_statement: 443 PARS_FOR_TOKEN PARS_ID_TOKEN PARS_IN_TOKEN 444 exp PARS_DDOT_TOKEN exp 445 PARS_LOOP_TOKEN statement_list 446 PARS_END_TOKEN PARS_LOOP_TOKEN 447 { $$ = pars_for_statement( 448 static_cast<sym_node_t*>($2), 449 $4, $6, $8); } 450 ; 451 452 exit_statement: 453 PARS_EXIT_TOKEN { $$ = pars_exit_statement(); } 454 ; 455 456 return_statement: 457 PARS_RETURN_TOKEN { $$ = pars_return_statement(); } 458 ; 459 460 open_cursor_statement: 461 PARS_OPEN_TOKEN PARS_ID_TOKEN 462 { $$ = pars_open_statement( 463 ROW_SEL_OPEN_CURSOR, 464 static_cast<sym_node_t*>($2)); } 465 ; 466 467 close_cursor_statement: 468 PARS_CLOSE_TOKEN PARS_ID_TOKEN 469 { $$ = pars_open_statement( 470 ROW_SEL_CLOSE_CURSOR, 471 static_cast<sym_node_t*>($2)); } 472 ; 473 474 fetch_statement: 475 PARS_FETCH_TOKEN PARS_ID_TOKEN PARS_INTO_TOKEN variable_list 476 { $$ = pars_fetch_statement( 477 static_cast<sym_node_t*>($2), 478 static_cast<sym_node_t*>($4), NULL); } 479 | PARS_FETCH_TOKEN PARS_ID_TOKEN PARS_INTO_TOKEN user_function_call 480 { $$ = pars_fetch_statement( 481 static_cast<sym_node_t*>($2), 482 NULL, 483 static_cast<sym_node_t*>($4)); } 484 ; 485 486 column_def: 487 PARS_ID_TOKEN type_name opt_column_len opt_not_null 488 { $$ = pars_column_def( 489 static_cast<sym_node_t*>($1), 490 static_cast<pars_res_word_t*>($2), 491 static_cast<sym_node_t*>($3), 492 $4); } 493 ; 494 495 column_def_list: 496 column_def { $$ = que_node_list_add_last(NULL, $1); } 497 | column_def_list ',' column_def 498 { $$ = que_node_list_add_last($1, $3); } 499 ; 500 501 opt_column_len: 502 /* Nothing */ { $$ = NULL; } 503 | '(' PARS_INT_LIT ')' 504 { $$ = $2; } 505 ; 506 507 opt_not_null: 508 /* Nothing */ { $$ = NULL; } 509 | PARS_NOT_TOKEN PARS_NULL_LIT 510 { $$ = &pars_int_token; 511 /* pass any non-NULL pointer */ } 512 ; 513 514 create_table: 515 PARS_CREATE_TOKEN PARS_TABLE_TOKEN 516 table_name '(' column_def_list ')' 517 { $$ = pars_create_table( 518 static_cast<sym_node_t*>($3), 519 static_cast<sym_node_t*>($5)); } 520 ; 521 522 column_list: 523 PARS_ID_TOKEN { $$ = que_node_list_add_last(NULL, $1); } 524 | column_list ',' PARS_ID_TOKEN 525 { $$ = que_node_list_add_last($1, $3); } 526 ; 527 528 unique_def: 529 /* Nothing */ { $$ = NULL; } 530 | PARS_UNIQUE_TOKEN { $$ = &pars_unique_token; } 531 ; 532 533 clustered_def: 534 /* Nothing */ { $$ = NULL; } 535 | PARS_CLUSTERED_TOKEN { $$ = &pars_clustered_token; } 536 ; 537 538 create_index: 539 PARS_CREATE_TOKEN unique_def 540 clustered_def 541 PARS_INDEX_TOKEN 542 PARS_ID_TOKEN PARS_ON_TOKEN 543 table_name 544 '(' column_list ')' { $$ = pars_create_index( 545 static_cast<pars_res_word_t*>($2), 546 static_cast<pars_res_word_t*>($3), 547 static_cast<sym_node_t*>($5), 548 static_cast<sym_node_t*>($7), 549 static_cast<sym_node_t*>($9)); } 550 ; 551 552 table_name: 553 PARS_ID_TOKEN { $$ = $1; } 554 | PARS_TABLE_NAME_TOKEN { $$ = $1; } 555 ; 556 557 commit_statement: 558 PARS_COMMIT_TOKEN PARS_WORK_TOKEN 559 { $$ = pars_commit_statement(); } 560 ; 561 562 rollback_statement: 563 PARS_ROLLBACK_TOKEN PARS_WORK_TOKEN 564 { $$ = pars_rollback_statement(); } 565 ; 566 567 type_name: 568 PARS_INT_TOKEN { $$ = &pars_int_token; } 569 | PARS_BIGINT_TOKEN { $$ = &pars_bigint_token; } 570 | PARS_CHAR_TOKEN { $$ = &pars_char_token; } 571 ; 572 573 variable_declaration: 574 PARS_ID_TOKEN type_name ';' 575 { $$ = pars_variable_declaration( 576 static_cast<sym_node_t*>($1), 577 static_cast<pars_res_word_t*>($2)); } 578 ; 579 580 variable_declaration_list: 581 /* Nothing */ 582 | variable_declaration 583 | variable_declaration_list variable_declaration 584 ; 585 586 cursor_declaration: 587 PARS_DECLARE_TOKEN PARS_CURSOR_TOKEN PARS_ID_TOKEN 588 PARS_IS_TOKEN select_statement ';' 589 { $$ = pars_cursor_declaration( 590 static_cast<sym_node_t*>($3), 591 static_cast<sel_node_t*>($5)); } 592 ; 593 594 function_declaration: 595 PARS_DECLARE_TOKEN PARS_FUNCTION_TOKEN PARS_ID_TOKEN ';' 596 { $$ = pars_function_declaration( 597 static_cast<sym_node_t*>($3)); } 598 ; 599 600 declaration: 601 cursor_declaration 602 | function_declaration 603 ; 604 605 declaration_list: 606 /* Nothing */ 607 | declaration 608 | declaration_list declaration 609 ; 610 611 procedure_definition: 612 PARS_PROCEDURE_TOKEN PARS_ID_TOKEN '(' ')' 613 PARS_IS_TOKEN 614 variable_declaration_list 615 declaration_list 616 PARS_BEGIN_TOKEN 617 statement_list 618 PARS_END_TOKEN { $$ = pars_procedure_definition( 619 static_cast<sym_node_t*>($2), $9); } 620 ; 621 622 %% 623