1 /* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License, version 2.0, 5 as published by the Free Software Foundation. 6 7 This program is also distributed with certain software (including 8 but not limited to OpenSSL) that is licensed under separate terms, 9 as designated in a particular file or component or in included license 10 documentation. The authors of MySQL hereby grant you an additional 11 permission to link the program and your derivative works with the 12 separately licensed software that they have included with MySQL. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License, version 2.0, for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 22 23 #ifndef PARSE_TREE_NODES_INCLUDED 24 #define PARSE_TREE_NODES_INCLUDED 25 26 #include "my_global.h" 27 #include "parse_tree_helpers.h" // PT_item_list 28 #include "parse_tree_hints.h" 29 #include "sp_head.h" // sp_head 30 #include "sql_class.h" // THD 31 #include "sql_lex.h" // LEX 32 #include "sql_parse.h" // add_join_natural 33 #include "sql_update.h" // Sql_cmd_update 34 #include "sql_admin.h" // Sql_cmd_shutdown etc. 35 36 37 template<enum_parsing_context Context> class PTI_context; 38 39 40 class PT_statement : public Parse_tree_node 41 { 42 public: 43 virtual Sql_cmd *make_cmd(THD *thd)= 0; 44 }; 45 46 47 class PT_select_lex : public Parse_tree_node 48 { 49 public: 50 SELECT_LEX *value; 51 }; 52 53 54 class PT_subselect : public PT_select_lex 55 { 56 typedef PT_select_lex super; 57 58 POS pos; 59 PT_select_lex *query_expression_body; 60 61 public: PT_subselect(const POS & pos,PT_select_lex * query_expression_body_arg)62 explicit PT_subselect(const POS &pos, 63 PT_select_lex *query_expression_body_arg) 64 : pos(pos), query_expression_body(query_expression_body_arg) 65 {} 66 contextualize(Parse_context * pc)67 virtual bool contextualize(Parse_context *pc) 68 { 69 if (super::contextualize(pc)) 70 return true; 71 72 LEX *lex= pc->thd->lex; 73 if (!lex->expr_allows_subselect || 74 lex->sql_command == (int)SQLCOM_PURGE) 75 { 76 error(pc, pos); 77 return true; 78 } 79 /* 80 we are making a "derived table" for the parenthesis 81 as we need to have a lex level to fit the union 82 after the parenthesis, e.g. 83 (SELECT .. ) UNION ... becomes 84 SELECT * FROM ((SELECT ...) UNION ...) 85 */ 86 SELECT_LEX *child= lex->new_query(pc->select); 87 if (child == NULL) 88 return true; 89 90 Parse_context inner_pc(pc->thd, child); 91 if (query_expression_body->contextualize(&inner_pc)) 92 return true; 93 94 lex->pop_context(); 95 pc->select->n_child_sum_items += child->n_sum_items; 96 /* 97 A subquery (and all the subsequent query blocks in a UNION) can add 98 columns to an outer query block. Reserve space for them. 99 */ 100 for (SELECT_LEX *temp = child; temp != NULL; 101 temp = temp->next_select()) 102 { 103 pc->select->select_n_where_fields+= temp->select_n_where_fields; 104 pc->select->select_n_having_items+= temp->select_n_having_items; 105 } 106 value= query_expression_body->value; 107 return false; 108 } 109 }; 110 111 112 class PT_order_expr : public Parse_tree_node, public ORDER 113 { 114 typedef Parse_tree_node super; 115 116 public: PT_order_expr(Item * item_arg,bool is_asc)117 PT_order_expr(Item *item_arg, bool is_asc) 118 { 119 item_ptr= item_arg; 120 direction= is_asc ? ORDER::ORDER_ASC : ORDER::ORDER_DESC; 121 } 122 contextualize(Parse_context * pc)123 virtual bool contextualize(Parse_context *pc) 124 { 125 return super::contextualize(pc) || item_ptr->itemize(pc, &item_ptr); 126 } 127 }; 128 129 130 class PT_order_list : public Parse_tree_node 131 { 132 typedef Parse_tree_node super; 133 134 public: 135 SQL_I_List<ORDER> value; 136 137 public: contextualize(Parse_context * pc)138 virtual bool contextualize(Parse_context *pc) 139 { 140 if (super::contextualize(pc)) 141 return true; 142 for (ORDER *o= value.first; o != NULL; o= o->next) 143 { 144 if (static_cast<PT_order_expr *>(o)->contextualize(pc)) 145 return true; 146 } 147 return false; 148 } 149 push_back(PT_order_expr * order)150 void push_back(PT_order_expr *order) 151 { 152 order->item= &order->item_ptr; 153 order->used_alias= false; 154 order->used= 0; 155 order->is_position= false; 156 value.link_in_list(order, &order->next); 157 } 158 }; 159 160 161 class PT_gorder_list : public PT_order_list 162 { 163 typedef PT_order_list super; 164 165 public: contextualize(Parse_context * pc)166 virtual bool contextualize(Parse_context *pc) 167 { 168 SELECT_LEX *sel= pc->select; 169 if (sel->linkage != GLOBAL_OPTIONS_TYPE && 170 sel->olap != UNSPECIFIED_OLAP_TYPE && 171 (sel->linkage != UNION_TYPE || sel->braces)) 172 { 173 my_error(ER_WRONG_USAGE, MYF(0), 174 "CUBE/ROLLUP", "ORDER BY"); 175 return true; 176 } 177 178 return super::contextualize(pc); 179 } 180 }; 181 182 183 class PT_select_item_list : public PT_item_list 184 { 185 typedef PT_item_list super; 186 187 public: contextualize(Parse_context * pc)188 virtual bool contextualize(Parse_context *pc) 189 { 190 if (super::contextualize(pc)) 191 return true; 192 193 pc->select->item_list= value; 194 return false; 195 } 196 }; 197 198 199 class PT_limit_clause : public Parse_tree_node 200 { 201 typedef Parse_tree_node super; 202 203 Limit_options limit_options; 204 205 public: PT_limit_clause(const Limit_options & limit_options_arg)206 PT_limit_clause(const Limit_options &limit_options_arg) 207 : limit_options(limit_options_arg) 208 {} 209 contextualize(Parse_context * pc)210 virtual bool contextualize(Parse_context *pc) 211 { 212 if (super::contextualize(pc)) 213 return true; 214 215 if (pc->select->master_unit()->is_union() && !pc->select->braces) 216 { 217 pc->select= pc->select->master_unit()->fake_select_lex; 218 DBUG_ASSERT(pc->select != NULL); 219 } 220 221 if (limit_options.is_offset_first && limit_options.opt_offset != NULL && 222 limit_options.opt_offset->itemize(pc, &limit_options.opt_offset)) 223 return true; 224 225 if (limit_options.limit->itemize(pc, &limit_options.limit)) 226 return true; 227 228 if (!limit_options.is_offset_first && limit_options.opt_offset != NULL && 229 limit_options.opt_offset->itemize(pc, &limit_options.opt_offset)) 230 return true; 231 232 pc->select->select_limit= limit_options.limit; 233 pc->select->offset_limit= limit_options.opt_offset; 234 pc->select->explicit_limit= true; 235 236 pc->thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT); 237 return false; 238 } 239 }; 240 241 242 class PT_table_list : public Parse_tree_node 243 { 244 public: 245 TABLE_LIST *value; 246 }; 247 248 249 class PT_table_factor_table_ident : public PT_table_list 250 { 251 typedef PT_table_list super; 252 253 Table_ident *table_ident; 254 List<String> *opt_use_partition; 255 LEX_STRING *opt_table_alias; 256 List<Index_hint> *opt_key_definition; 257 258 public: PT_table_factor_table_ident(Table_ident * table_ident_arg,List<String> * opt_use_partition_arg,LEX_STRING * opt_table_alias_arg,List<Index_hint> * opt_key_definition_arg)259 PT_table_factor_table_ident(Table_ident *table_ident_arg, 260 List<String> *opt_use_partition_arg, 261 LEX_STRING *opt_table_alias_arg, 262 List<Index_hint> *opt_key_definition_arg) 263 : table_ident(table_ident_arg), 264 opt_use_partition(opt_use_partition_arg), 265 opt_table_alias(opt_table_alias_arg), 266 opt_key_definition(opt_key_definition_arg) 267 {} 268 contextualize(Parse_context * pc)269 virtual bool contextualize(Parse_context *pc) 270 { 271 if (super::contextualize(pc)) 272 return true; 273 274 THD *thd= pc->thd; 275 Yacc_state *yyps= &thd->m_parser_state->m_yacc; 276 277 value= pc->select->add_table_to_list(thd, table_ident, opt_table_alias, 0, 278 yyps->m_lock_type, 279 yyps->m_mdl_type, 280 opt_key_definition, 281 opt_use_partition); 282 if (value == NULL) 283 return true; 284 pc->select->add_joined_table(value); 285 return false; 286 } 287 }; 288 289 290 enum PT_join_table_type 291 { 292 JTT_NORMAL = 0x01, 293 JTT_STRAIGHT = 0x02, 294 JTT_NATURAL = 0x04, 295 JTT_LEFT = 0x08, 296 JTT_RIGHT = 0x10, 297 298 JTT_NATURAL_LEFT = JTT_NATURAL | JTT_LEFT, 299 JTT_NATURAL_RIGHT = JTT_NATURAL | JTT_RIGHT 300 }; 301 302 303 template<PT_join_table_type Type> 304 class PT_join_table : public Parse_tree_node 305 { 306 typedef Parse_tree_node super; 307 308 protected: 309 PT_table_list *tab1_node; 310 POS join_pos; 311 PT_table_list *tab2_node; 312 313 TABLE_LIST *tr1; 314 TABLE_LIST *tr2; 315 316 317 public: PT_join_table(PT_table_list * tab1_node_arg,const POS & join_pos_arg,PT_table_list * tab2_node_arg)318 PT_join_table(PT_table_list *tab1_node_arg, const POS &join_pos_arg, 319 PT_table_list *tab2_node_arg) 320 : tab1_node(tab1_node_arg), join_pos(join_pos_arg), tab2_node(tab2_node_arg), 321 tr1(NULL), tr2(NULL) 322 { 323 DBUG_ASSERT(dbug_exclusive_flags(JTT_NORMAL | JTT_STRAIGHT | JTT_NATURAL)); 324 DBUG_ASSERT(dbug_exclusive_flags(JTT_LEFT | JTT_RIGHT)); 325 } 326 327 #ifndef DBUG_OFF dbug_exclusive_flags(unsigned int mask)328 bool dbug_exclusive_flags(unsigned int mask) 329 { 330 #ifdef __GNUC__ 331 return __builtin_popcount(Type & mask) <= 1; 332 #else 333 return true; 334 #endif 335 } 336 #endif 337 contextualize(Parse_context * pc)338 virtual bool contextualize(Parse_context *pc) 339 { 340 if (super::contextualize(pc) || contextualize_tabs(pc)) 341 return true; 342 343 if (Type & (JTT_LEFT | JTT_RIGHT)) 344 { 345 if (Type & JTT_LEFT) 346 tr2->outer_join|= JOIN_TYPE_LEFT; 347 else 348 { 349 TABLE_LIST *inner_table= pc->select->convert_right_join(); 350 /* swap tr1 and tr2 */ 351 DBUG_ASSERT(inner_table == tr1); 352 tr1= tr2; 353 tr2= inner_table; 354 } 355 } 356 357 if (Type & JTT_NATURAL) 358 add_join_natural(tr1, tr2, NULL, pc->select); 359 360 if (Type & JTT_STRAIGHT) 361 tr2->straight= true; 362 363 return false; 364 } 365 366 protected: contextualize_tabs(Parse_context * pc)367 bool contextualize_tabs(Parse_context *pc) 368 { 369 if (tr1 != NULL) 370 return false; // already done 371 372 if (tab1_node->contextualize(pc) || tab2_node->contextualize(pc)) 373 return true; 374 375 tr1= tab1_node->value; 376 tr2= tab2_node->value; 377 378 if (tr1 == NULL || tr2 == NULL) 379 { 380 error(pc, join_pos); 381 return true; 382 } 383 return false; 384 } 385 }; 386 387 388 template<PT_join_table_type Type> 389 class PT_join_table_on : public PT_join_table<Type> 390 { 391 typedef PT_join_table<Type> super; 392 393 Item *on; 394 395 public: PT_join_table_on(PT_table_list * tab1_node_arg,const POS & join_pos_arg,PT_table_list * tab2_node_arg,Item * on_arg)396 PT_join_table_on(PT_table_list *tab1_node_arg, const POS &join_pos_arg, 397 PT_table_list *tab2_node_arg, Item *on_arg) 398 : super(tab1_node_arg, join_pos_arg, tab2_node_arg), on(on_arg) 399 {} 400 contextualize(Parse_context * pc)401 virtual bool contextualize(Parse_context *pc) 402 { 403 if (this->contextualize_tabs(pc)) 404 return true; 405 406 if (push_new_name_resolution_context(pc, this->tr1, this->tr2)) 407 { 408 this->error(pc, this->join_pos); 409 return true; 410 } 411 412 SELECT_LEX *sel= pc->select; 413 sel->parsing_place= CTX_ON; 414 415 if (super::contextualize(pc) || on->itemize(pc, &on)) 416 return true; 417 DBUG_ASSERT(sel == pc->select); 418 419 add_join_on(this->tr2, on); 420 pc->thd->lex->pop_context(); 421 DBUG_ASSERT(sel->parsing_place == CTX_ON); 422 sel->parsing_place= CTX_NONE; 423 return false; 424 } 425 }; 426 427 428 template<PT_join_table_type Type> 429 class PT_join_table_using : public PT_join_table<Type> 430 { 431 typedef PT_join_table<Type> super; 432 433 List<String> *using_fields; 434 435 public: PT_join_table_using(PT_table_list * tab1_node_arg,const POS & join_pos_arg,PT_table_list * tab2_node_arg,List<String> * using_fields_arg)436 PT_join_table_using(PT_table_list *tab1_node_arg, const POS &join_pos_arg, 437 PT_table_list *tab2_node_arg, 438 List<String> *using_fields_arg) 439 : super(tab1_node_arg, join_pos_arg, tab2_node_arg), 440 using_fields(using_fields_arg) 441 {} 442 contextualize(Parse_context * pc)443 virtual bool contextualize(Parse_context *pc) 444 { 445 if (super::contextualize(pc)) 446 return true; 447 448 add_join_natural(this->tr1, this->tr2, using_fields, pc->select); 449 return false; 450 } 451 }; 452 453 454 class PT_table_ref_join_table : public PT_table_list 455 { 456 typedef PT_table_list super; 457 458 Parse_tree_node *join_table; 459 460 public: PT_table_ref_join_table(Parse_tree_node * join_table_arg)461 explicit PT_table_ref_join_table(Parse_tree_node *join_table_arg) 462 : join_table(join_table_arg) 463 {} 464 contextualize(Parse_context * pc)465 virtual bool contextualize(Parse_context *pc) 466 { 467 if (super::contextualize(pc) || join_table->contextualize(pc)) 468 return true; 469 470 value= pc->select->nest_last_join(pc->thd); 471 return value == NULL; 472 } 473 }; 474 475 476 class PT_select_part2_derived : public Parse_tree_node 477 { 478 typedef Parse_tree_node super; 479 480 ulonglong opt_query_spec_options; 481 PT_item_list *select_item_list; 482 483 public: PT_select_part2_derived(ulonglong opt_query_spec_options_arg,PT_item_list * select_item_list_arg)484 PT_select_part2_derived(ulonglong opt_query_spec_options_arg, 485 PT_item_list *select_item_list_arg) 486 : opt_query_spec_options(opt_query_spec_options_arg), 487 select_item_list(select_item_list_arg) 488 {} 489 contextualize(Parse_context * pc)490 virtual bool contextualize(Parse_context *pc) 491 { 492 if (super::contextualize(pc)) 493 return true; 494 495 THD *thd= pc->thd; 496 SELECT_LEX *select= pc->select; 497 498 select->parsing_place= CTX_SELECT_LIST; 499 500 if (select->validate_base_options(thd->lex, opt_query_spec_options)) 501 return true; 502 select->set_base_options(opt_query_spec_options); 503 if (opt_query_spec_options & SELECT_HIGH_PRIORITY) 504 { 505 Yacc_state *yyps= &thd->m_parser_state->m_yacc; 506 yyps->m_lock_type= TL_READ_HIGH_PRIORITY; 507 yyps->m_mdl_type= MDL_SHARED_READ; 508 } 509 510 if (select_item_list->contextualize(pc)) 511 return true; 512 DBUG_ASSERT(select == pc->select); 513 514 // Ensure we're resetting parsing place of the right select 515 DBUG_ASSERT(select->parsing_place == CTX_SELECT_LIST); 516 select->parsing_place= CTX_NONE; 517 return false; 518 } 519 }; 520 521 522 class PT_group : public Parse_tree_node 523 { 524 typedef Parse_tree_node super; 525 526 PT_order_list *group_list; 527 olap_type olap; 528 529 public: PT_group(PT_order_list * group_list_arg,olap_type olap_arg)530 PT_group(PT_order_list *group_list_arg, olap_type olap_arg) 531 : group_list(group_list_arg), olap(olap_arg) 532 {} 533 534 virtual bool contextualize(Parse_context *pc); 535 }; 536 537 538 class PT_order : public Parse_tree_node 539 { 540 typedef Parse_tree_node super; 541 542 PT_order_list *order_list; 543 544 public: 545 PT_order(PT_order_list * order_list_arg)546 explicit PT_order(PT_order_list *order_list_arg) 547 : order_list(order_list_arg) 548 {} 549 550 virtual bool contextualize(Parse_context *pc); 551 }; 552 553 554 class PT_procedure_analyse : public Parse_tree_node 555 { 556 typedef Parse_tree_node super; 557 558 Proc_analyse_params params; 559 560 public: PT_procedure_analyse(const Proc_analyse_params & params_arg)561 PT_procedure_analyse(const Proc_analyse_params ¶ms_arg) 562 : params(params_arg) 563 {} 564 contextualize(Parse_context * pc)565 virtual bool contextualize(Parse_context *pc) 566 { 567 if (super::contextualize(pc)) 568 return true; 569 570 THD *thd= pc->thd; 571 LEX *lex= thd->lex; 572 573 if (!lex->parsing_options.allows_select_procedure) 574 { 575 my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "PROCEDURE"); 576 return true; 577 } 578 579 if (lex->select_lex != pc->select) 580 { 581 my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery"); 582 return true; 583 } 584 585 lex->proc_analyse= ¶ms; 586 lex->set_uncacheable(pc->select, UNCACHEABLE_SIDEEFFECT); 587 return false; 588 } 589 }; 590 591 592 class PT_order_or_limit_order : public Parse_tree_node 593 { 594 typedef Parse_tree_node super; 595 596 PT_order *order; 597 PT_limit_clause *opt_limit; 598 599 public: PT_order_or_limit_order(PT_order * order_arg,PT_limit_clause * opt_limit_arg)600 PT_order_or_limit_order(PT_order *order_arg, PT_limit_clause *opt_limit_arg) 601 : order(order_arg), opt_limit(opt_limit_arg) 602 {} 603 contextualize(Parse_context * pc)604 virtual bool contextualize(Parse_context *pc) 605 { 606 return super::contextualize(pc) || order->contextualize(pc) || 607 (opt_limit != NULL && opt_limit->contextualize(pc)); 608 } 609 }; 610 611 612 class PT_union_order_or_limit : public Parse_tree_node 613 { 614 typedef Parse_tree_node super; 615 616 Parse_tree_node *order_or_limit; 617 618 public: PT_union_order_or_limit(Parse_tree_node * order_or_limit_arg)619 PT_union_order_or_limit(Parse_tree_node *order_or_limit_arg) 620 : order_or_limit(order_or_limit_arg) 621 {} 622 contextualize(Parse_context * pc)623 virtual bool contextualize(Parse_context *pc) 624 { 625 if (super::contextualize(pc)) 626 return true; 627 628 DBUG_ASSERT(pc->select->linkage != GLOBAL_OPTIONS_TYPE); 629 SELECT_LEX *fake= pc->select->master_unit()->fake_select_lex; 630 if (fake) 631 { 632 fake->no_table_names_allowed= true; 633 pc->select= fake; 634 } 635 pc->thd->where= "global ORDER clause"; 636 637 if (order_or_limit->contextualize(pc)) 638 return true; 639 640 pc->select->no_table_names_allowed= 0; 641 pc->thd->where= ""; 642 return false; 643 } 644 }; 645 646 647 class PT_table_expression : public Parse_tree_node 648 { 649 typedef Parse_tree_node super; 650 651 Parse_tree_node *opt_from_clause; 652 Item *opt_where; 653 PT_group *opt_group; 654 Item *opt_having; 655 PT_order *opt_order; 656 PT_limit_clause *opt_limit; 657 PT_procedure_analyse *opt_procedure_analyse; 658 Select_lock_type opt_select_lock_type; 659 660 public: PT_table_expression(Parse_tree_node * opt_from_clause_arg,Item * opt_where_arg,PT_group * opt_group_arg,Item * opt_having_arg,PT_order * opt_order_arg,PT_limit_clause * opt_limit_arg,PT_procedure_analyse * opt_procedure_analyse_arg,const Select_lock_type & opt_select_lock_type_arg)661 PT_table_expression(Parse_tree_node *opt_from_clause_arg, 662 Item *opt_where_arg, 663 PT_group *opt_group_arg, 664 Item *opt_having_arg, 665 PT_order *opt_order_arg, 666 PT_limit_clause *opt_limit_arg, 667 PT_procedure_analyse *opt_procedure_analyse_arg, 668 const Select_lock_type &opt_select_lock_type_arg) 669 : opt_from_clause(opt_from_clause_arg), 670 opt_where(opt_where_arg), 671 opt_group(opt_group_arg), 672 opt_having(opt_having_arg), 673 opt_order(opt_order_arg), 674 opt_limit(opt_limit_arg), 675 opt_procedure_analyse(opt_procedure_analyse_arg), 676 opt_select_lock_type(opt_select_lock_type_arg) 677 {} 678 contextualize(Parse_context * pc)679 virtual bool contextualize(Parse_context *pc) 680 { 681 if (super::contextualize(pc) || 682 (opt_from_clause != NULL && opt_from_clause->contextualize(pc)) || 683 (opt_where != NULL && opt_where->itemize(pc, &opt_where)) || 684 (opt_group != NULL && opt_group->contextualize(pc)) || 685 (opt_having != NULL && opt_having->itemize(pc, &opt_having))) 686 return true; 687 688 pc->select->set_where_cond(opt_where); 689 pc->select->set_having_cond(opt_having); 690 691 if ((opt_order != NULL && opt_order->contextualize(pc)) || 692 (opt_limit != NULL && opt_limit->contextualize(pc)) || 693 (opt_procedure_analyse != NULL && 694 opt_procedure_analyse->contextualize(pc))) 695 return true; 696 697 /* 698 @todo: explain should not affect how we construct the query data 699 structure. Instead, consider to let lock_tables() adjust lock 700 requests according to the explain flag. 701 */ 702 if (opt_select_lock_type.is_set && !pc->thd->lex->is_explain()) 703 { 704 pc->select->set_lock_for_tables(opt_select_lock_type.lock_type); 705 pc->thd->lex->safe_to_cache_query= 706 opt_select_lock_type.is_safe_to_cache_query; 707 } 708 return false; 709 } 710 }; 711 712 713 class PT_table_factor_select_sym : public PT_table_list 714 { 715 typedef PT_table_list super; 716 717 POS pos; 718 PT_hint_list *opt_hint_list; 719 Query_options select_options; 720 PT_item_list *select_item_list; 721 PT_table_expression *table_expression; 722 723 public: PT_table_factor_select_sym(const POS & pos,PT_hint_list * opt_hint_list_arg,Query_options select_options_arg,PT_item_list * select_item_list_arg,PT_table_expression * table_expression_arg)724 PT_table_factor_select_sym(const POS &pos, 725 PT_hint_list *opt_hint_list_arg, 726 Query_options select_options_arg, 727 PT_item_list *select_item_list_arg, 728 PT_table_expression *table_expression_arg) 729 : pos(pos), 730 opt_hint_list(opt_hint_list_arg), 731 select_options(select_options_arg), 732 select_item_list(select_item_list_arg), 733 table_expression(table_expression_arg) 734 {} 735 736 virtual bool contextualize(Parse_context *pc); 737 }; 738 739 740 class PT_select_derived_union_select : public PT_table_list 741 { 742 typedef PT_table_list super; 743 744 PT_table_list *select_derived; 745 Parse_tree_node *opt_union_order_or_limit; 746 POS union_or_limit_pos; 747 748 public: PT_select_derived_union_select(PT_table_list * select_derived_arg,Parse_tree_node * opt_union_order_or_limit_arg,const POS & union_or_limit_pos_arg)749 PT_select_derived_union_select(PT_table_list *select_derived_arg, 750 Parse_tree_node *opt_union_order_or_limit_arg, 751 const POS &union_or_limit_pos_arg) 752 : select_derived(select_derived_arg), 753 opt_union_order_or_limit(opt_union_order_or_limit_arg), 754 union_or_limit_pos(union_or_limit_pos_arg) 755 {} 756 757 contextualize(Parse_context * pc)758 virtual bool contextualize(Parse_context *pc) 759 { 760 if (super::contextualize(pc) || 761 select_derived->contextualize(pc) || 762 (opt_union_order_or_limit != NULL && 763 opt_union_order_or_limit->contextualize(pc))) 764 return true; 765 766 if (select_derived->value != NULL && opt_union_order_or_limit != NULL) 767 { 768 error(pc, union_or_limit_pos); 769 return true; 770 } 771 772 value= select_derived->value; 773 return false; 774 } 775 }; 776 777 778 class PT_select_derived_union_union : public PT_table_list 779 { 780 typedef PT_table_list super; 781 782 PT_table_list *select_derived_union; 783 POS union_pos; 784 bool is_distinct; 785 PT_select_lex *query_specification; 786 787 public: 788 PT_select_derived_union_union(PT_table_list * select_derived_union_arg,const POS & union_pos_arg,bool is_distinct_arg,PT_select_lex * query_specification_arg)789 PT_select_derived_union_union(PT_table_list *select_derived_union_arg, 790 const POS &union_pos_arg, 791 bool is_distinct_arg, 792 PT_select_lex *query_specification_arg) 793 : select_derived_union(select_derived_union_arg), 794 union_pos(union_pos_arg), 795 is_distinct(is_distinct_arg), 796 query_specification(query_specification_arg) 797 {} 798 contextualize(Parse_context * pc)799 virtual bool contextualize(Parse_context *pc) 800 { 801 if (super::contextualize(pc) || select_derived_union->contextualize(pc)) 802 return true; 803 804 pc->select= pc->thd->lex->new_union_query(pc->select, is_distinct); 805 if (pc->select == NULL) 806 return true; 807 808 if (query_specification->contextualize(pc)) 809 return true; 810 811 /* 812 Remove from the name resolution context stack the context of the 813 last query block in the union. 814 */ 815 pc->thd->lex->pop_context(); 816 817 if (select_derived_union->value != NULL) 818 { 819 error(pc, union_pos); 820 return true; 821 } 822 value= NULL; 823 return false; 824 } 825 }; 826 827 828 class PT_table_factor_parenthesis : public PT_table_list 829 { 830 typedef PT_table_list super; 831 832 PT_table_list *select_derived_union; 833 LEX_STRING *opt_table_alias; 834 POS alias_pos; 835 836 public: 837 PT_table_factor_parenthesis(PT_table_list * select_derived_union_arg,LEX_STRING * opt_table_alias_arg,const POS & alias_pos_arg)838 PT_table_factor_parenthesis(PT_table_list *select_derived_union_arg, 839 LEX_STRING *opt_table_alias_arg, 840 const POS &alias_pos_arg) 841 : select_derived_union(select_derived_union_arg), 842 opt_table_alias(opt_table_alias_arg), 843 alias_pos(alias_pos_arg) 844 {} 845 846 virtual bool contextualize(Parse_context *pc); 847 }; 848 849 850 class PT_derived_table_list : public PT_table_list 851 { 852 typedef PT_table_list super; 853 854 POS pos; 855 PT_table_list *head; 856 PT_table_list *tail; 857 858 public: PT_derived_table_list(const POS & pos,PT_table_list * head_arg,PT_table_list * tail_arg)859 PT_derived_table_list(const POS &pos, 860 PT_table_list *head_arg, PT_table_list *tail_arg) 861 : pos(pos), head(head_arg), tail(tail_arg) 862 {} 863 contextualize(Parse_context * pc)864 virtual bool contextualize(Parse_context *pc) 865 { 866 if (super::contextualize(pc) || 867 head->contextualize(pc) || tail->contextualize(pc)) 868 return true; 869 870 if (head->value == NULL || tail->value == NULL) 871 { 872 error(pc, pos); 873 return true; 874 } 875 value= tail->value; 876 return false; 877 } 878 }; 879 880 881 class PT_select_derived : public PT_table_list 882 { 883 typedef PT_table_list super; 884 885 POS pos; 886 PT_table_list *derived_table_list; 887 888 public: 889 PT_select_derived(const POS & pos,PT_table_list * derived_table_list_arg)890 PT_select_derived(const POS &pos, PT_table_list *derived_table_list_arg) 891 : pos(pos), derived_table_list(derived_table_list_arg) 892 {} 893 contextualize(Parse_context * pc)894 virtual bool contextualize(Parse_context *pc) 895 { 896 if (super::contextualize(pc)) 897 return true; 898 899 SELECT_LEX * const outer_select= pc->select; 900 901 if (outer_select->init_nested_join(pc->thd)) 902 return true; 903 904 if (derived_table_list->contextualize(pc)) 905 return true; 906 907 /* 908 for normal joins, derived_table_list->value != NULL and 909 end_nested_join() != NULL, for derived tables, both must equal NULL 910 */ 911 912 value= outer_select->end_nested_join(pc->thd); 913 914 if (value == NULL && derived_table_list->value != NULL) 915 { 916 error(pc, pos); 917 return true; 918 } 919 920 if (derived_table_list->value == NULL && value != NULL) 921 { 922 error(pc, pos); 923 return true; 924 } 925 return false; 926 } 927 }; 928 929 930 class PT_join_table_list : public PT_table_list 931 { 932 typedef PT_table_list super; 933 934 POS pos; 935 PT_table_list *derived_table_list; 936 937 public: PT_join_table_list(const POS & pos,PT_table_list * derived_table_list_arg)938 PT_join_table_list(const POS &pos, PT_table_list *derived_table_list_arg) 939 : pos(pos), derived_table_list(derived_table_list_arg) 940 {} 941 contextualize(Parse_context * pc)942 virtual bool contextualize(Parse_context *pc) 943 { 944 if (super::contextualize(pc) || derived_table_list->contextualize(pc)) 945 return true; 946 947 if (derived_table_list->value == NULL) 948 { 949 error(pc, pos); 950 return true; 951 } 952 value= derived_table_list->value; 953 return false; 954 } 955 }; 956 957 958 class PT_table_reference_list : public Parse_tree_node 959 { 960 typedef Parse_tree_node super; 961 962 PT_join_table_list *join_table_list; 963 964 public: PT_table_reference_list(PT_join_table_list * join_table_list_arg)965 PT_table_reference_list(PT_join_table_list *join_table_list_arg) 966 : join_table_list(join_table_list_arg) 967 {} 968 contextualize(Parse_context * pc)969 virtual bool contextualize(Parse_context *pc) 970 { 971 if (super::contextualize(pc) || join_table_list->contextualize(pc)) 972 return true; 973 974 SELECT_LEX *sel= pc->select; 975 sel->context.table_list= 976 sel->context.first_name_resolution_table= 977 sel->table_list.first; 978 return false; 979 } 980 }; 981 982 983 class PT_query_specification_select : public PT_select_lex 984 { 985 typedef Parse_tree_node super; 986 987 PT_hint_list *opt_hint_list; 988 PT_select_part2_derived *select_part2_derived; 989 PT_table_expression *table_expression; 990 991 public: PT_query_specification_select(PT_hint_list * opt_hint_list_arg,PT_select_part2_derived * select_part2_derived_arg,PT_table_expression * table_expression_arg)992 PT_query_specification_select( 993 PT_hint_list *opt_hint_list_arg, 994 PT_select_part2_derived *select_part2_derived_arg, 995 PT_table_expression *table_expression_arg) 996 : opt_hint_list(opt_hint_list_arg), 997 select_part2_derived(select_part2_derived_arg), 998 table_expression(table_expression_arg) 999 {} 1000 contextualize(Parse_context * pc)1001 virtual bool contextualize(Parse_context *pc) 1002 { 1003 if (super::contextualize(pc) || select_part2_derived->contextualize(pc)) 1004 return true; 1005 1006 // Parentheses carry no meaning here. 1007 pc->select->set_braces(false); 1008 1009 if (table_expression->contextualize(pc)) 1010 return true; 1011 1012 value= pc->select->master_unit()->first_select(); 1013 1014 if (opt_hint_list != NULL && opt_hint_list->contextualize(pc)) 1015 return true; 1016 1017 return false; 1018 } 1019 }; 1020 1021 1022 class PT_select_paren_derived : public Parse_tree_node 1023 { 1024 typedef Parse_tree_node super; 1025 1026 PT_hint_list *opt_hint_list; 1027 PT_select_part2_derived *select_part2_derived; 1028 PT_table_expression *table_expression; 1029 1030 public: PT_select_paren_derived(PT_hint_list * opt_hint_list_arg,PT_select_part2_derived * select_part2_derived_arg,PT_table_expression * table_expression_arg)1031 PT_select_paren_derived(PT_hint_list *opt_hint_list_arg, 1032 PT_select_part2_derived *select_part2_derived_arg, 1033 PT_table_expression *table_expression_arg) 1034 : opt_hint_list(opt_hint_list_arg), 1035 select_part2_derived(select_part2_derived_arg), 1036 table_expression(table_expression_arg) 1037 {} 1038 contextualize(Parse_context * pc)1039 virtual bool contextualize(Parse_context *pc) 1040 { 1041 if (super::contextualize(pc)) 1042 return true; 1043 1044 pc->select->set_braces(true); 1045 1046 if (select_part2_derived->contextualize(pc) || 1047 table_expression->contextualize(pc)) 1048 return true; 1049 1050 if (setup_select_in_parentheses(pc->select)) 1051 return true; 1052 1053 if (opt_hint_list != NULL && opt_hint_list->contextualize(pc)) 1054 return true; 1055 1056 return false; 1057 } 1058 }; 1059 1060 1061 class PT_query_specification_parenthesis : public PT_select_lex 1062 { 1063 typedef PT_select_lex super; 1064 1065 PT_select_paren_derived *select_paren_derived; 1066 Parse_tree_node *opt_union_order_or_limit; 1067 1068 public: PT_query_specification_parenthesis(PT_select_paren_derived * select_paren_derived_arg,Parse_tree_node * opt_union_order_or_limit_arg)1069 PT_query_specification_parenthesis( 1070 PT_select_paren_derived *select_paren_derived_arg, 1071 Parse_tree_node *opt_union_order_or_limit_arg) 1072 : select_paren_derived(select_paren_derived_arg), 1073 opt_union_order_or_limit(opt_union_order_or_limit_arg) 1074 {} 1075 1076 contextualize(Parse_context * pc)1077 virtual bool contextualize(Parse_context *pc) 1078 { 1079 if (super::contextualize(pc) || 1080 select_paren_derived->contextualize(pc) || 1081 (opt_union_order_or_limit != NULL && 1082 opt_union_order_or_limit->contextualize(pc))) 1083 return true; 1084 1085 value= pc->select->master_unit()->first_select(); 1086 return false; 1087 } 1088 }; 1089 1090 1091 class PT_query_expression_body_union : public PT_select_lex 1092 { 1093 typedef PT_select_lex super; 1094 1095 POS pos; 1096 PT_select_lex *query_expression_body; 1097 bool is_distinct; 1098 PT_select_lex *query_specification; 1099 1100 public: PT_query_expression_body_union(const POS & pos,PT_select_lex * query_expression_body_arg,bool is_distinct_arg,PT_select_lex * query_specification_arg)1101 PT_query_expression_body_union(const POS &pos, 1102 PT_select_lex *query_expression_body_arg, 1103 bool is_distinct_arg, 1104 PT_select_lex *query_specification_arg) 1105 : pos(pos), 1106 query_expression_body(query_expression_body_arg), 1107 is_distinct(is_distinct_arg), 1108 query_specification(query_specification_arg) 1109 {} 1110 contextualize(Parse_context * pc)1111 virtual bool contextualize(Parse_context *pc) 1112 { 1113 if (super::contextualize(pc) || query_expression_body->contextualize(pc)) 1114 return true; 1115 1116 LEX *lex= pc->thd->lex; 1117 1118 if (pc->select->linkage == GLOBAL_OPTIONS_TYPE) 1119 { 1120 error(pc, pos); 1121 return true; 1122 } 1123 pc->select= lex->new_union_query(pc->select, is_distinct); 1124 if (pc->select == NULL) 1125 return true; 1126 1127 if (query_specification->contextualize(pc)) 1128 return true; 1129 1130 lex->pop_context(); 1131 value= query_expression_body->value; 1132 return false; 1133 } 1134 }; 1135 1136 1137 class PT_internal_variable_name : public Parse_tree_node 1138 { 1139 public: 1140 sys_var_with_base value; 1141 }; 1142 1143 1144 class PT_internal_variable_name_1d : public PT_internal_variable_name 1145 { 1146 typedef PT_internal_variable_name super; 1147 1148 LEX_STRING ident; 1149 1150 public: PT_internal_variable_name_1d(const LEX_STRING & ident_arg)1151 PT_internal_variable_name_1d(const LEX_STRING &ident_arg) 1152 : ident(ident_arg) 1153 {} 1154 contextualize(Parse_context * pc)1155 virtual bool contextualize(Parse_context *pc) 1156 { 1157 if (super::contextualize(pc)) 1158 return true; 1159 1160 THD *thd= pc->thd; 1161 LEX *lex= thd->lex; 1162 sp_pcontext *pctx= lex->get_sp_current_parsing_ctx(); 1163 sp_variable *spv; 1164 1165 value.var= NULL; 1166 value.base_name= ident; 1167 1168 /* Best effort lookup for system variable. */ 1169 if (!pctx || !(spv= pctx->find_variable(ident, false))) 1170 { 1171 /* Not an SP local variable */ 1172 if (find_sys_var_null_base(thd, &value)) 1173 return true; 1174 } 1175 else 1176 { 1177 /* 1178 Possibly an SP local variable (or a shadowed sysvar). 1179 Will depend on the context of the SET statement. 1180 */ 1181 } 1182 return false; 1183 } 1184 }; 1185 1186 1187 /** 1188 Parse tree node class for 2-dimentional variable names (example: @global.x) 1189 */ 1190 class PT_internal_variable_name_2d : public PT_internal_variable_name 1191 { 1192 typedef PT_internal_variable_name super; 1193 1194 public: 1195 const POS pos; 1196 private: 1197 LEX_STRING ident1; 1198 LEX_STRING ident2; 1199 1200 public: PT_internal_variable_name_2d(const POS & pos,const LEX_STRING & ident1_arg,const LEX_STRING & ident2_arg)1201 PT_internal_variable_name_2d(const POS &pos, 1202 const LEX_STRING &ident1_arg, 1203 const LEX_STRING &ident2_arg) 1204 : pos(pos), ident1(ident1_arg), ident2(ident2_arg) 1205 {} 1206 1207 virtual bool contextualize(Parse_context *pc); 1208 }; 1209 1210 1211 class PT_internal_variable_name_default : public PT_internal_variable_name 1212 { 1213 typedef PT_internal_variable_name super; 1214 1215 LEX_STRING ident; 1216 1217 public: PT_internal_variable_name_default(const LEX_STRING & ident_arg)1218 PT_internal_variable_name_default(const LEX_STRING &ident_arg) 1219 : ident(ident_arg) 1220 {} 1221 contextualize(Parse_context * pc)1222 virtual bool contextualize(Parse_context *pc) 1223 { 1224 if (super::contextualize(pc)) 1225 return true; 1226 1227 sys_var *tmp=find_sys_var(pc->thd, ident.str, ident.length); 1228 if (!tmp) 1229 return true; 1230 if (!tmp->is_struct()) 1231 { 1232 my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), ident.str); 1233 return true; 1234 } 1235 value.var= tmp; 1236 value.base_name.str= (char*) "default"; 1237 value.base_name.length= 7; 1238 return false; 1239 } 1240 }; 1241 1242 1243 class PT_option_value_following_option_type : public Parse_tree_node 1244 { 1245 typedef Parse_tree_node super; 1246 1247 POS pos; 1248 PT_internal_variable_name *name; 1249 Item *opt_expr; 1250 1251 public: PT_option_value_following_option_type(const POS & pos,PT_internal_variable_name * name_arg,Item * opt_expr_arg)1252 PT_option_value_following_option_type(const POS &pos, 1253 PT_internal_variable_name *name_arg, 1254 Item *opt_expr_arg) 1255 : pos(pos), name(name_arg), opt_expr(opt_expr_arg) 1256 {} 1257 contextualize(Parse_context * pc)1258 virtual bool contextualize(Parse_context *pc) 1259 { 1260 if (super::contextualize(pc) || name->contextualize(pc) || 1261 (opt_expr != NULL && opt_expr->itemize(pc, &opt_expr))) 1262 return true; 1263 1264 if (name->value.var && name->value.var != trg_new_row_fake_var) 1265 { 1266 /* It is a system variable. */ 1267 if (set_system_variable(pc->thd, &name->value, pc->thd->lex->option_type, 1268 opt_expr)) 1269 return true; 1270 } 1271 else 1272 { 1273 /* 1274 Not in trigger assigning value to new row, 1275 and option_type preceding local variable is illegal. 1276 */ 1277 error(pc, pos); 1278 return true; 1279 } 1280 return false; 1281 } 1282 }; 1283 1284 1285 class PT_option_value_no_option_type : public Parse_tree_node {}; 1286 1287 1288 class PT_option_value_no_option_type_internal : 1289 public PT_option_value_no_option_type 1290 { 1291 typedef PT_option_value_no_option_type super; 1292 1293 PT_internal_variable_name *name; 1294 Item *opt_expr; 1295 POS expr_pos; 1296 1297 public: PT_option_value_no_option_type_internal(PT_internal_variable_name * name_arg,Item * opt_expr_arg,const POS & expr_pos_arg)1298 PT_option_value_no_option_type_internal(PT_internal_variable_name *name_arg, 1299 Item *opt_expr_arg, 1300 const POS &expr_pos_arg) 1301 : name(name_arg), opt_expr(opt_expr_arg), expr_pos(expr_pos_arg) 1302 {} 1303 1304 virtual bool contextualize(Parse_context *pc); 1305 }; 1306 1307 1308 class PT_option_value_no_option_type_user_var : 1309 public PT_option_value_no_option_type 1310 { 1311 typedef PT_option_value_no_option_type super; 1312 1313 LEX_STRING name; 1314 Item *expr; 1315 1316 public: PT_option_value_no_option_type_user_var(const LEX_STRING & name_arg,Item * expr_arg)1317 PT_option_value_no_option_type_user_var(const LEX_STRING &name_arg, 1318 Item *expr_arg) 1319 : name(name_arg), expr(expr_arg) 1320 {} 1321 contextualize(Parse_context * pc)1322 virtual bool contextualize(Parse_context *pc) 1323 { 1324 if (super::contextualize(pc) || expr->itemize(pc, &expr)) 1325 return true; 1326 1327 THD *thd= pc->thd; 1328 Item_func_set_user_var *item; 1329 item= new (pc->mem_root) Item_func_set_user_var(name, expr, false); 1330 if (item == NULL) 1331 return true; 1332 set_var_user *var= new set_var_user(item); 1333 if (var == NULL) 1334 return true; 1335 thd->lex->var_list.push_back(var); 1336 return false; 1337 } 1338 }; 1339 1340 1341 class PT_option_value_no_option_type_sys_var : 1342 public PT_option_value_no_option_type 1343 { 1344 typedef PT_option_value_no_option_type super; 1345 1346 enum_var_type type; 1347 PT_internal_variable_name *name; 1348 Item *opt_expr; 1349 1350 public: PT_option_value_no_option_type_sys_var(enum_var_type type_arg,PT_internal_variable_name * name_arg,Item * opt_expr_arg)1351 PT_option_value_no_option_type_sys_var(enum_var_type type_arg, 1352 PT_internal_variable_name *name_arg, 1353 Item *opt_expr_arg) 1354 : type(type_arg), name(name_arg), opt_expr(opt_expr_arg) 1355 {} 1356 contextualize(Parse_context * pc)1357 virtual bool contextualize(Parse_context *pc) 1358 { 1359 if (super::contextualize(pc) || name->contextualize(pc) || 1360 (opt_expr != NULL && opt_expr->itemize(pc, &opt_expr))) 1361 return true; 1362 1363 THD *thd= pc->thd; 1364 struct sys_var_with_base tmp= name->value; 1365 if (tmp.var == trg_new_row_fake_var) 1366 { 1367 error(pc, down_cast<PT_internal_variable_name_2d *>(name)->pos); 1368 return true; 1369 } 1370 /* Lookup if necessary: must be a system variable. */ 1371 if (tmp.var == NULL) 1372 { 1373 if (find_sys_var_null_base(thd, &tmp)) 1374 return true; 1375 } 1376 if (set_system_variable(thd, &tmp, type, opt_expr)) 1377 return true; 1378 return false; 1379 } 1380 }; 1381 1382 1383 class PT_option_value_no_option_type_charset : 1384 public PT_option_value_no_option_type 1385 { 1386 typedef PT_option_value_no_option_type super; 1387 1388 const CHARSET_INFO *opt_charset; 1389 1390 public: PT_option_value_no_option_type_charset(const CHARSET_INFO * opt_charset_arg)1391 PT_option_value_no_option_type_charset(const CHARSET_INFO *opt_charset_arg) 1392 : opt_charset(opt_charset_arg) 1393 {} 1394 contextualize(Parse_context * pc)1395 virtual bool contextualize(Parse_context *pc) 1396 { 1397 if (super::contextualize(pc)) 1398 return true; 1399 1400 THD *thd= pc->thd; 1401 LEX *lex= thd->lex; 1402 int flags= opt_charset ? 0 : set_var_collation_client::SET_CS_DEFAULT; 1403 const CHARSET_INFO *cs2; 1404 cs2= opt_charset ? opt_charset 1405 : global_system_variables.character_set_client; 1406 set_var_collation_client *var; 1407 var= new set_var_collation_client(flags, 1408 cs2, 1409 thd->variables.collation_database, 1410 cs2); 1411 if (var == NULL) 1412 return true; 1413 lex->var_list.push_back(var); 1414 return false; 1415 } 1416 }; 1417 1418 1419 class PT_option_value_no_option_type_names : 1420 public PT_option_value_no_option_type 1421 { 1422 typedef PT_option_value_no_option_type super; 1423 1424 POS pos; 1425 1426 public: PT_option_value_no_option_type_names(const POS & pos)1427 explicit PT_option_value_no_option_type_names(const POS &pos) : pos(pos) {} 1428 contextualize(Parse_context * pc)1429 virtual bool contextualize(Parse_context *pc) 1430 { 1431 if (super::contextualize(pc)) 1432 return true; 1433 1434 THD *thd= pc->thd; 1435 LEX *lex= thd->lex; 1436 sp_pcontext *pctx= lex->get_sp_current_parsing_ctx(); 1437 LEX_STRING names= { C_STRING_WITH_LEN("names") }; 1438 1439 if (pctx && pctx->find_variable(names, false)) 1440 my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str); 1441 else 1442 error(pc, pos); 1443 1444 return true; // alwais fails with an error 1445 } 1446 }; 1447 1448 1449 class PT_option_value_no_option_type_names_charset : 1450 public PT_option_value_no_option_type 1451 { 1452 typedef PT_option_value_no_option_type super; 1453 1454 const CHARSET_INFO *opt_charset; 1455 const CHARSET_INFO *opt_collation; 1456 1457 public: PT_option_value_no_option_type_names_charset(const CHARSET_INFO * opt_charset_arg,const CHARSET_INFO * opt_collation_arg)1458 PT_option_value_no_option_type_names_charset( 1459 const CHARSET_INFO *opt_charset_arg, 1460 const CHARSET_INFO *opt_collation_arg) 1461 : opt_charset(opt_charset_arg), opt_collation(opt_collation_arg) 1462 {} 1463 contextualize(Parse_context * pc)1464 virtual bool contextualize(Parse_context *pc) 1465 { 1466 if (super::contextualize(pc)) 1467 return true; 1468 1469 THD *thd= pc->thd; 1470 LEX *lex= thd->lex; 1471 const CHARSET_INFO *cs2; 1472 const CHARSET_INFO *cs3; 1473 int flags= set_var_collation_client::SET_CS_NAMES 1474 | (opt_charset ? 0 : set_var_collation_client::SET_CS_DEFAULT) 1475 | (opt_collation ? set_var_collation_client::SET_CS_COLLATE : 0); 1476 cs2= opt_charset ? opt_charset 1477 : global_system_variables.character_set_client; 1478 cs3= opt_collation ? opt_collation : cs2; 1479 if (!my_charset_same(cs2, cs3)) 1480 { 1481 my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), 1482 cs3->name, cs2->csname); 1483 return true; 1484 } 1485 set_var_collation_client *var; 1486 var= new set_var_collation_client(flags, cs3, cs3, cs3); 1487 if (var == NULL) 1488 return true; 1489 lex->var_list.push_back(var); 1490 return false; 1491 } 1492 }; 1493 1494 1495 class PT_start_option_value_list : public Parse_tree_node {}; 1496 1497 1498 class PT_option_value_no_option_type_password : 1499 public PT_start_option_value_list 1500 { 1501 typedef PT_start_option_value_list super; 1502 1503 const char *password; 1504 POS expr_pos; 1505 1506 public: PT_option_value_no_option_type_password(const char * password_arg,const POS & expr_pos_arg)1507 explicit PT_option_value_no_option_type_password(const char *password_arg, 1508 const POS &expr_pos_arg) 1509 : password(password_arg), expr_pos(expr_pos_arg) 1510 {} 1511 1512 virtual bool contextualize(Parse_context *pc); 1513 }; 1514 1515 1516 class PT_option_value_no_option_type_password_for : 1517 public PT_start_option_value_list 1518 { 1519 typedef PT_start_option_value_list super; 1520 1521 LEX_USER *user; 1522 const char *password; 1523 POS expr_pos; 1524 1525 public: PT_option_value_no_option_type_password_for(LEX_USER * user_arg,const char * password_arg,const POS & expr_pos_arg)1526 PT_option_value_no_option_type_password_for(LEX_USER *user_arg, 1527 const char *password_arg, 1528 const POS &expr_pos_arg) 1529 : user(user_arg), password(password_arg), expr_pos(expr_pos_arg) 1530 {} 1531 contextualize(Parse_context * pc)1532 virtual bool contextualize(Parse_context *pc) 1533 { 1534 if (super::contextualize(pc)) 1535 return true; 1536 1537 THD *thd= pc->thd; 1538 LEX *lex= thd->lex; 1539 set_var_password *var; 1540 1541 /* 1542 In case of anonymous user, user->user is set to empty string with 1543 length 0. But there might be case when user->user.str could be NULL. 1544 For Ex: "set password for current_user() = password('xyz');". 1545 In this case, set user information as of the current user. 1546 */ 1547 if (!user->user.str) 1548 { 1549 LEX_CSTRING sctx_priv_user= thd->security_context()->priv_user(); 1550 DBUG_ASSERT(sctx_priv_user.str); 1551 user->user.str= sctx_priv_user.str; 1552 user->user.length= sctx_priv_user.length; 1553 } 1554 if (!user->host.str) 1555 { 1556 LEX_CSTRING sctx_priv_host= thd->security_context()->priv_host(); 1557 DBUG_ASSERT(sctx_priv_host.str); 1558 user->host.str= (char *) sctx_priv_host.str; 1559 user->host.length= sctx_priv_host.length; 1560 } 1561 1562 var= new set_var_password(user, const_cast<char *>(password)); 1563 if (var == NULL) 1564 return true; 1565 lex->var_list.push_back(var); 1566 lex->autocommit= TRUE; 1567 lex->is_set_password_sql= true; 1568 if (lex->sphead) 1569 lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; 1570 if (sp_create_assignment_instr(pc->thd, expr_pos.raw.end)) 1571 return true; 1572 return false; 1573 } 1574 }; 1575 1576 1577 class PT_option_value_type : public Parse_tree_node 1578 { 1579 typedef Parse_tree_node super; 1580 1581 enum_var_type type; 1582 PT_option_value_following_option_type *value; 1583 1584 public: PT_option_value_type(enum_var_type type_arg,PT_option_value_following_option_type * value_arg)1585 PT_option_value_type(enum_var_type type_arg, 1586 PT_option_value_following_option_type *value_arg) 1587 : type(type_arg), value(value_arg) 1588 {} 1589 contextualize(Parse_context * pc)1590 virtual bool contextualize(Parse_context *pc) 1591 { 1592 pc->thd->lex->option_type= type; 1593 return super::contextualize(pc) || value->contextualize(pc); 1594 } 1595 }; 1596 1597 1598 class PT_option_value_list_head : public Parse_tree_node 1599 { 1600 typedef Parse_tree_node super; 1601 1602 POS delimiter_pos; 1603 Parse_tree_node *value; 1604 POS value_pos; 1605 1606 public: PT_option_value_list_head(const POS & delimiter_pos_arg,Parse_tree_node * value_arg,const POS & value_pos_arg)1607 PT_option_value_list_head(const POS &delimiter_pos_arg, 1608 Parse_tree_node *value_arg, 1609 const POS &value_pos_arg) 1610 : delimiter_pos(delimiter_pos_arg), value(value_arg), value_pos(value_pos_arg) 1611 {} 1612 contextualize(Parse_context * pc)1613 virtual bool contextualize(Parse_context *pc) 1614 { 1615 if (super::contextualize(pc)) 1616 return true; 1617 1618 THD *thd= pc->thd; 1619 #ifndef DBUG_OFF 1620 LEX *old_lex= thd->lex; 1621 #endif//DBUG_OFF 1622 1623 sp_create_assignment_lex(thd, delimiter_pos.raw.end); 1624 DBUG_ASSERT(thd->lex->select_lex == thd->lex->current_select()); 1625 Parse_context inner_pc(pc->thd, thd->lex->select_lex); 1626 1627 if (value->contextualize(&inner_pc)) 1628 return true; 1629 1630 if (sp_create_assignment_instr(pc->thd, value_pos.raw.end)) 1631 return true; 1632 DBUG_ASSERT(thd->lex == old_lex && 1633 thd->lex->current_select() == pc->select); 1634 1635 return false; 1636 } 1637 }; 1638 1639 1640 class PT_option_value_list : public PT_option_value_list_head 1641 { 1642 typedef PT_option_value_list_head super; 1643 1644 PT_option_value_list_head *head; 1645 1646 public: PT_option_value_list(PT_option_value_list_head * head_arg,const POS & delimiter_pos_arg,Parse_tree_node * tail,const POS & tail_pos)1647 PT_option_value_list(PT_option_value_list_head *head_arg, 1648 const POS &delimiter_pos_arg, 1649 Parse_tree_node *tail, const POS &tail_pos) 1650 : super(delimiter_pos_arg, tail, tail_pos), head(head_arg) 1651 {} 1652 contextualize(Parse_context * pc)1653 virtual bool contextualize(Parse_context *pc) 1654 { 1655 return head->contextualize(pc) || super::contextualize(pc); 1656 } 1657 }; 1658 1659 1660 class PT_start_option_value_list_no_type : public PT_start_option_value_list 1661 { 1662 typedef PT_start_option_value_list super; 1663 1664 PT_option_value_no_option_type *head; 1665 POS head_pos; 1666 PT_option_value_list_head *tail; 1667 1668 public: PT_start_option_value_list_no_type(PT_option_value_no_option_type * head_arg,const POS & head_pos_arg,PT_option_value_list_head * tail_arg)1669 PT_start_option_value_list_no_type(PT_option_value_no_option_type *head_arg, 1670 const POS &head_pos_arg, 1671 PT_option_value_list_head *tail_arg) 1672 : head(head_arg), head_pos(head_pos_arg), tail(tail_arg) 1673 {} 1674 contextualize(Parse_context * pc)1675 virtual bool contextualize(Parse_context *pc) 1676 { 1677 if (super::contextualize(pc) || head->contextualize(pc)) 1678 return true; 1679 1680 if (sp_create_assignment_instr(pc->thd, head_pos.raw.end)) 1681 return true; 1682 DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select()); 1683 pc->select= pc->thd->lex->select_lex; 1684 1685 if (tail != NULL && tail->contextualize(pc)) 1686 return true; 1687 1688 return false; 1689 } 1690 }; 1691 1692 1693 class PT_transaction_characteristic : public Parse_tree_node 1694 { 1695 typedef Parse_tree_node super; 1696 1697 const char *name; 1698 int32 value; 1699 1700 public: PT_transaction_characteristic(const char * name_arg,int32 value_arg)1701 PT_transaction_characteristic(const char *name_arg, int32 value_arg) 1702 : name(name_arg), value(value_arg) 1703 {} 1704 contextualize(Parse_context * pc)1705 virtual bool contextualize(Parse_context *pc) 1706 { 1707 if (super::contextualize(pc)) 1708 return true; 1709 1710 THD *thd= pc->thd; 1711 LEX *lex= thd->lex; 1712 Item *item= new (pc->mem_root) Item_int(value); 1713 if (item == NULL) 1714 return true; 1715 set_var *var= new set_var(lex->option_type, 1716 find_sys_var(thd, name), 1717 &null_lex_str, 1718 item); 1719 if (var == NULL) 1720 return true; 1721 lex->var_list.push_back(var); 1722 return false; 1723 } 1724 1725 }; 1726 1727 1728 class PT_transaction_access_mode : public PT_transaction_characteristic 1729 { 1730 typedef PT_transaction_characteristic super; 1731 1732 public: PT_transaction_access_mode(bool is_read_only)1733 explicit PT_transaction_access_mode(bool is_read_only) 1734 : super("transaction_read_only", (int32) is_read_only) 1735 {} 1736 }; 1737 1738 1739 class PT_isolation_level : public PT_transaction_characteristic 1740 { 1741 typedef PT_transaction_characteristic super; 1742 1743 public: PT_isolation_level(enum_tx_isolation level)1744 explicit PT_isolation_level(enum_tx_isolation level) 1745 : super("transaction_isolation", (int32) level) 1746 {} 1747 }; 1748 1749 1750 class PT_transaction_characteristics : public Parse_tree_node 1751 { 1752 typedef Parse_tree_node super; 1753 1754 PT_transaction_characteristic *head; 1755 PT_transaction_characteristic *opt_tail; 1756 1757 public: PT_transaction_characteristics(PT_transaction_characteristic * head_arg,PT_transaction_characteristic * opt_tail_arg)1758 PT_transaction_characteristics(PT_transaction_characteristic *head_arg, 1759 PT_transaction_characteristic *opt_tail_arg) 1760 : head(head_arg), opt_tail(opt_tail_arg) 1761 {} 1762 contextualize(Parse_context * pc)1763 virtual bool contextualize(Parse_context *pc) 1764 { 1765 return (super::contextualize(pc) || head->contextualize(pc) || 1766 (opt_tail != NULL && opt_tail->contextualize(pc))); 1767 } 1768 }; 1769 1770 1771 class PT_start_option_value_list_transaction : 1772 public PT_start_option_value_list 1773 { 1774 typedef PT_start_option_value_list super; 1775 1776 PT_transaction_characteristics * characteristics; 1777 POS end_pos; 1778 1779 public: PT_start_option_value_list_transaction(PT_transaction_characteristics * characteristics_arg,const POS & end_pos_arg)1780 PT_start_option_value_list_transaction( 1781 PT_transaction_characteristics * characteristics_arg, 1782 const POS &end_pos_arg) 1783 : characteristics(characteristics_arg), end_pos(end_pos_arg) 1784 {} 1785 contextualize(Parse_context * pc)1786 virtual bool contextualize(Parse_context *pc) 1787 { 1788 if (super::contextualize(pc)) 1789 return true; 1790 1791 THD *thd= pc->thd; 1792 thd->lex->option_type= OPT_DEFAULT; 1793 if (characteristics->contextualize(pc)) 1794 return true; 1795 1796 if (sp_create_assignment_instr(thd, end_pos.raw.end)) 1797 return true; 1798 DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select()); 1799 pc->select= pc->thd->lex->select_lex; 1800 1801 return false; 1802 } 1803 }; 1804 1805 1806 class PT_start_option_value_list_following_option_type : 1807 public Parse_tree_node 1808 {}; 1809 1810 1811 class PT_start_option_value_list_following_option_type_eq : 1812 public PT_start_option_value_list_following_option_type 1813 { 1814 typedef PT_start_option_value_list_following_option_type super; 1815 1816 PT_option_value_following_option_type *head; 1817 POS head_pos; 1818 PT_option_value_list_head *opt_tail; 1819 1820 public: PT_start_option_value_list_following_option_type_eq(PT_option_value_following_option_type * head_arg,const POS & head_pos_arg,PT_option_value_list_head * opt_tail_arg)1821 PT_start_option_value_list_following_option_type_eq( 1822 PT_option_value_following_option_type *head_arg, 1823 const POS &head_pos_arg, 1824 PT_option_value_list_head *opt_tail_arg) 1825 : head(head_arg), head_pos(head_pos_arg), opt_tail(opt_tail_arg) 1826 {} 1827 contextualize(Parse_context * pc)1828 virtual bool contextualize(Parse_context *pc) 1829 { 1830 if (super::contextualize(pc) || head->contextualize(pc)) 1831 return true; 1832 1833 if (sp_create_assignment_instr(pc->thd, head_pos.raw.end)) 1834 return true; 1835 DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select()); 1836 pc->select= pc->thd->lex->select_lex; 1837 1838 if (opt_tail != NULL && opt_tail->contextualize(pc)) 1839 return true; 1840 1841 return false; 1842 } 1843 }; 1844 1845 1846 class PT_start_option_value_list_following_option_type_transaction : 1847 public PT_start_option_value_list_following_option_type 1848 { 1849 typedef PT_start_option_value_list_following_option_type super; 1850 1851 PT_transaction_characteristics *characteristics; 1852 POS characteristics_pos; 1853 1854 public: PT_start_option_value_list_following_option_type_transaction(PT_transaction_characteristics * characteristics_arg,const POS & characteristics_pos_arg)1855 PT_start_option_value_list_following_option_type_transaction( 1856 PT_transaction_characteristics *characteristics_arg, 1857 const POS &characteristics_pos_arg) 1858 : characteristics(characteristics_arg), 1859 characteristics_pos(characteristics_pos_arg) 1860 {} 1861 contextualize(Parse_context * pc)1862 virtual bool contextualize(Parse_context *pc) 1863 { 1864 if (super::contextualize(pc) || characteristics->contextualize(pc)) 1865 return true; 1866 1867 if (sp_create_assignment_instr(pc->thd, characteristics_pos.raw.end)) 1868 return true; 1869 DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select()); 1870 pc->select= pc->thd->lex->select_lex; 1871 1872 return false; 1873 } 1874 }; 1875 1876 1877 class PT_start_option_value_list_type : public PT_start_option_value_list 1878 { 1879 typedef PT_start_option_value_list super; 1880 1881 enum_var_type type; 1882 PT_start_option_value_list_following_option_type *list; 1883 1884 public: PT_start_option_value_list_type(enum_var_type type_arg,PT_start_option_value_list_following_option_type * list_arg)1885 PT_start_option_value_list_type( 1886 enum_var_type type_arg, 1887 PT_start_option_value_list_following_option_type *list_arg) 1888 : type(type_arg), list(list_arg) 1889 {} 1890 contextualize(Parse_context * pc)1891 virtual bool contextualize(Parse_context *pc) 1892 { 1893 pc->thd->lex->option_type= type; 1894 return super::contextualize(pc) || list->contextualize(pc); 1895 } 1896 }; 1897 1898 1899 class PT_set : public Parse_tree_node 1900 { 1901 typedef Parse_tree_node super; 1902 1903 POS set_pos; 1904 PT_start_option_value_list *list; 1905 1906 public: PT_set(const POS & set_pos_arg,PT_start_option_value_list * list_arg)1907 PT_set(const POS &set_pos_arg, PT_start_option_value_list *list_arg) 1908 : set_pos(set_pos_arg), list(list_arg) 1909 {} 1910 contextualize(Parse_context * pc)1911 virtual bool contextualize(Parse_context *pc) 1912 { 1913 if (super::contextualize(pc)) 1914 return true; 1915 1916 THD *thd= pc->thd; 1917 LEX *lex= thd->lex; 1918 lex->sql_command= SQLCOM_SET_OPTION; 1919 lex->option_type= OPT_SESSION; 1920 lex->var_list.empty(); 1921 lex->autocommit= false; 1922 1923 sp_create_assignment_lex(thd, set_pos.raw.end); 1924 DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select()); 1925 pc->select= pc->thd->lex->select_lex; 1926 1927 return list->contextualize(pc); 1928 } 1929 }; 1930 1931 1932 class PT_select_init : public Parse_tree_node {}; 1933 1934 1935 class PT_union_list : public Parse_tree_node 1936 { 1937 typedef Parse_tree_node super; 1938 1939 bool is_distinct; 1940 PT_select_init *select_init; 1941 1942 public: PT_union_list(bool is_distinct_arg,PT_select_init * select_init_arg)1943 PT_union_list(bool is_distinct_arg, PT_select_init *select_init_arg) 1944 : is_distinct(is_distinct_arg), select_init(select_init_arg) 1945 {} 1946 contextualize(Parse_context * pc)1947 virtual bool contextualize(Parse_context *pc) 1948 { 1949 if (super::contextualize(pc)) 1950 return true; 1951 1952 pc->select= pc->thd->lex->new_union_query(pc->select, is_distinct); 1953 if (pc->select == NULL) 1954 return true; 1955 1956 if (select_init->contextualize(pc)) 1957 return true; 1958 /* 1959 Remove from the name resolution context stack the context of the 1960 last query block in the union. 1961 */ 1962 pc->thd->lex->pop_context(); 1963 return false; 1964 } 1965 }; 1966 1967 1968 class PT_into_destination : public Parse_tree_node 1969 { 1970 typedef Parse_tree_node super; 1971 1972 public: contextualize(Parse_context * pc)1973 virtual bool contextualize(Parse_context *pc) 1974 { 1975 if (super::contextualize(pc)) 1976 return true; 1977 1978 if (!pc->thd->lex->parsing_options.allows_select_into) 1979 { 1980 my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "INTO"); 1981 return true; 1982 } 1983 return false; 1984 } 1985 }; 1986 1987 1988 class PT_into_destination_outfile : public PT_into_destination 1989 { 1990 typedef PT_into_destination super; 1991 1992 const char *file_name; 1993 const CHARSET_INFO *charset; 1994 const Field_separators field_term; 1995 const Line_separators line_term; 1996 1997 public: PT_into_destination_outfile(const LEX_STRING & file_name_arg,const CHARSET_INFO * charset_arg,const Field_separators & field_term_arg,const Line_separators & line_term_arg)1998 PT_into_destination_outfile(const LEX_STRING &file_name_arg, 1999 const CHARSET_INFO *charset_arg, 2000 const Field_separators &field_term_arg, 2001 const Line_separators &line_term_arg) 2002 : file_name(file_name_arg.str), 2003 charset(charset_arg), 2004 field_term(field_term_arg), 2005 line_term(line_term_arg) 2006 {} 2007 contextualize(Parse_context * pc)2008 virtual bool contextualize(Parse_context *pc) 2009 { 2010 if (super::contextualize(pc)) 2011 return true; 2012 2013 LEX *lex= pc->thd->lex; 2014 lex->set_uncacheable(pc->select, UNCACHEABLE_SIDEEFFECT); 2015 if (!(lex->exchange= new sql_exchange(file_name, 0)) || 2016 !(lex->result= new Query_result_export(lex->exchange))) 2017 return true; 2018 2019 lex->exchange->cs= charset; 2020 lex->exchange->field.merge_field_separators(field_term); 2021 lex->exchange->line.merge_line_separators(line_term); 2022 return false; 2023 } 2024 }; 2025 2026 2027 class PT_into_destination_dumpfile : public PT_into_destination 2028 { 2029 typedef PT_into_destination super; 2030 2031 const char *file_name; 2032 2033 public: PT_into_destination_dumpfile(const LEX_STRING & file_name_arg)2034 explicit PT_into_destination_dumpfile(const LEX_STRING &file_name_arg) 2035 : file_name(file_name_arg.str) 2036 {} 2037 contextualize(Parse_context * pc)2038 virtual bool contextualize(Parse_context *pc) 2039 { 2040 if (super::contextualize(pc)) 2041 return true; 2042 2043 LEX *lex= pc->thd->lex; 2044 if (!lex->describe) 2045 { 2046 lex->set_uncacheable(pc->select, UNCACHEABLE_SIDEEFFECT); 2047 if (!(lex->exchange= new sql_exchange(file_name, 1))) 2048 return true; 2049 if (!(lex->result= new Query_result_dump(lex->exchange))) 2050 return true; 2051 } 2052 return false; 2053 } 2054 }; 2055 2056 2057 class PT_select_var : public Parse_tree_node 2058 { 2059 public: 2060 const LEX_STRING name; 2061 PT_select_var(const LEX_STRING & name_arg)2062 explicit PT_select_var(const LEX_STRING &name_arg) : name(name_arg) {} 2063 is_local()2064 virtual bool is_local() const { return false; } get_offset()2065 virtual uint get_offset() const { DBUG_ASSERT(0); return 0; } 2066 }; 2067 2068 2069 class PT_select_sp_var : public PT_select_var 2070 { 2071 typedef PT_select_var super; 2072 2073 uint offset; 2074 2075 #ifndef DBUG_OFF 2076 /* 2077 Routine to which this Item_splocal belongs. Used for checking if correct 2078 runtime context is used for variable handling. 2079 */ 2080 sp_head *sp; 2081 #endif 2082 2083 public: PT_select_sp_var(const LEX_STRING & name_arg)2084 PT_select_sp_var(const LEX_STRING &name_arg) : super(name_arg) {} 2085 is_local()2086 virtual bool is_local() const { return true; } get_offset()2087 virtual uint get_offset() const { return offset; } 2088 contextualize(Parse_context * pc)2089 virtual bool contextualize(Parse_context *pc) 2090 { 2091 if (super::contextualize(pc)) 2092 return true; 2093 2094 LEX *lex= pc->thd->lex; 2095 #ifndef DBUG_OFF 2096 sp= lex->sphead; 2097 #endif 2098 sp_pcontext *pctx= lex->get_sp_current_parsing_ctx(); 2099 sp_variable *spv; 2100 2101 if (!pctx || !(spv= pctx->find_variable(name, false))) 2102 { 2103 my_error(ER_SP_UNDECLARED_VAR, MYF(0), name.str); 2104 return true; 2105 } 2106 2107 offset= spv->offset; 2108 2109 return false; 2110 } 2111 }; 2112 2113 2114 class PT_select_var_list : public PT_into_destination 2115 { 2116 typedef PT_into_destination super; 2117 2118 public: 2119 List<PT_select_var> value; 2120 contextualize(Parse_context * pc)2121 virtual bool contextualize(Parse_context *pc) 2122 { 2123 if (super::contextualize(pc)) 2124 return true; 2125 2126 List_iterator<PT_select_var> it(value); 2127 PT_select_var *var; 2128 while ((var= it++)) 2129 { 2130 if (var->contextualize(pc)) 2131 return true; 2132 } 2133 2134 LEX * const lex= pc->thd->lex; 2135 if (lex->describe) 2136 return false; 2137 2138 Query_dumpvar *dumpvar= new (pc->mem_root) Query_dumpvar; 2139 if (dumpvar == NULL) 2140 return true; 2141 2142 dumpvar->var_list= value; 2143 lex->result= dumpvar; 2144 lex->set_uncacheable(pc->select, UNCACHEABLE_SIDEEFFECT); 2145 2146 return false; 2147 } 2148 push_back(PT_select_var * var)2149 bool push_back(PT_select_var *var) { return value.push_back(var); } 2150 }; 2151 2152 2153 class PT_select_options_and_item_list : public Parse_tree_node 2154 { 2155 typedef Parse_tree_node super; 2156 2157 Query_options options; 2158 PT_item_list *item_list; 2159 2160 public: PT_select_options_and_item_list(const Query_options & options_arg,PT_item_list * item_list_arg)2161 PT_select_options_and_item_list(const Query_options &options_arg, 2162 PT_item_list *item_list_arg) 2163 : options(options_arg), item_list(item_list_arg) 2164 {} 2165 contextualize(Parse_context * pc)2166 virtual bool contextualize(Parse_context *pc) 2167 { 2168 if (super::contextualize(pc)) 2169 return true; 2170 2171 pc->select->parsing_place= CTX_SELECT_LIST; 2172 2173 if (options.query_spec_options & SELECT_HIGH_PRIORITY) 2174 { 2175 Yacc_state *yyps= &pc->thd->m_parser_state->m_yacc; 2176 yyps->m_lock_type= TL_READ_HIGH_PRIORITY; 2177 yyps->m_mdl_type= MDL_SHARED_READ; 2178 } 2179 if (options.save_to(pc)) 2180 return true; 2181 2182 if (item_list->contextualize(pc)) 2183 return true; 2184 2185 // Ensure we're resetting parsing place of the right select 2186 DBUG_ASSERT(pc->select->parsing_place == CTX_SELECT_LIST); 2187 pc->select->parsing_place= CTX_NONE; 2188 return false; 2189 } 2190 }; 2191 2192 2193 class PT_select_part2 : public Parse_tree_node 2194 { 2195 typedef Parse_tree_node super; 2196 2197 PT_select_options_and_item_list *select_options_and_item_list; 2198 PT_into_destination *opt_into1; 2199 PT_table_reference_list *from_clause; // actually is optional (NULL) for DUAL 2200 Item *opt_where_clause; 2201 PT_group *opt_group_clause; 2202 Item *opt_having_clause; 2203 PT_order *opt_order_clause; 2204 PT_limit_clause *opt_limit_clause; 2205 PT_procedure_analyse *opt_procedure_analyse_clause; 2206 PT_into_destination *opt_into2; 2207 Select_lock_type opt_select_lock_type; 2208 2209 public: PT_select_part2(PT_select_options_and_item_list * select_options_and_item_list_arg,PT_into_destination * opt_into1_arg,PT_table_reference_list * from_clause_arg,Item * opt_where_clause_arg,PT_group * opt_group_clause_arg,Item * opt_having_clause_arg,PT_order * opt_order_clause_arg,PT_limit_clause * opt_limit_clause_arg,PT_procedure_analyse * opt_procedure_analyse_clause_arg,PT_into_destination * opt_into2_arg,const Select_lock_type & opt_select_lock_type_arg)2210 PT_select_part2( 2211 PT_select_options_and_item_list *select_options_and_item_list_arg, 2212 PT_into_destination *opt_into1_arg, 2213 PT_table_reference_list *from_clause_arg, 2214 Item *opt_where_clause_arg, 2215 PT_group *opt_group_clause_arg, 2216 Item *opt_having_clause_arg, 2217 PT_order *opt_order_clause_arg, 2218 PT_limit_clause *opt_limit_clause_arg, 2219 PT_procedure_analyse *opt_procedure_analyse_clause_arg, 2220 PT_into_destination *opt_into2_arg, 2221 const Select_lock_type &opt_select_lock_type_arg) 2222 : select_options_and_item_list(select_options_and_item_list_arg), 2223 opt_into1(opt_into1_arg), 2224 from_clause(from_clause_arg), 2225 opt_where_clause(opt_where_clause_arg), 2226 opt_group_clause(opt_group_clause_arg), 2227 opt_having_clause(opt_having_clause_arg), 2228 opt_order_clause(opt_order_clause_arg), 2229 opt_limit_clause(opt_limit_clause_arg), 2230 opt_procedure_analyse_clause(opt_procedure_analyse_clause_arg), 2231 opt_into2(opt_into2_arg), 2232 opt_select_lock_type(opt_select_lock_type_arg) 2233 {} PT_select_part2(PT_select_options_and_item_list * select_options_and_item_list_arg)2234 explicit PT_select_part2( 2235 PT_select_options_and_item_list *select_options_and_item_list_arg) 2236 : select_options_and_item_list(select_options_and_item_list_arg), 2237 opt_into1(NULL), 2238 from_clause(NULL), 2239 opt_where_clause(NULL), 2240 opt_group_clause(NULL), 2241 opt_having_clause(NULL), 2242 opt_order_clause(NULL), 2243 opt_limit_clause(NULL), 2244 opt_procedure_analyse_clause(NULL), 2245 opt_into2(NULL), 2246 opt_select_lock_type() 2247 {} 2248 contextualize(Parse_context * pc)2249 virtual bool contextualize(Parse_context *pc) 2250 { 2251 if (super::contextualize(pc) || 2252 select_options_and_item_list->contextualize(pc) || 2253 (opt_into1 != NULL && 2254 opt_into1->contextualize(pc)) || 2255 (from_clause != NULL && 2256 from_clause->contextualize(pc)) || 2257 (opt_where_clause != NULL && 2258 opt_where_clause->itemize(pc, &opt_where_clause)) || 2259 (opt_group_clause != NULL && 2260 opt_group_clause->contextualize(pc)) || 2261 (opt_having_clause != NULL && 2262 opt_having_clause->itemize(pc, &opt_having_clause))) 2263 return true; 2264 2265 pc->select->set_where_cond(opt_where_clause); 2266 pc->select->set_having_cond(opt_having_clause); 2267 2268 if ((opt_order_clause != NULL && 2269 opt_order_clause->contextualize(pc)) || 2270 (opt_limit_clause != NULL && 2271 opt_limit_clause->contextualize(pc)) || 2272 (opt_procedure_analyse_clause != NULL && 2273 opt_procedure_analyse_clause->contextualize(pc)) || 2274 (opt_into2 != NULL && 2275 opt_into2->contextualize(pc))) 2276 return true; 2277 2278 DBUG_ASSERT(opt_into1 == NULL || opt_into2 == NULL); 2279 DBUG_ASSERT(opt_procedure_analyse_clause == NULL || 2280 (opt_into1 == NULL && opt_into2 == NULL)); 2281 2282 /* 2283 @todo: explain should not affect how we construct the query data 2284 structure. Instead, consider to let lock_tables() adjust lock 2285 requests according to the explain flag. 2286 */ 2287 if (opt_select_lock_type.is_set && !pc->thd->lex->is_explain()) 2288 { 2289 pc->select->set_lock_for_tables(opt_select_lock_type.lock_type); 2290 pc->thd->lex->safe_to_cache_query= 2291 opt_select_lock_type.is_safe_to_cache_query; 2292 } 2293 return false; 2294 } 2295 }; 2296 2297 2298 class PT_select_paren : public Parse_tree_node 2299 { 2300 typedef Parse_tree_node super; 2301 2302 PT_hint_list *opt_hint_list; 2303 PT_select_part2 *select_part2; 2304 2305 public: PT_select_paren(PT_hint_list * opt_hint_list_arg,PT_select_part2 * select_part2_arg)2306 PT_select_paren(PT_hint_list *opt_hint_list_arg, 2307 PT_select_part2 *select_part2_arg) 2308 : opt_hint_list(opt_hint_list_arg), select_part2(select_part2_arg) 2309 {} 2310 contextualize(Parse_context * pc)2311 virtual bool contextualize(Parse_context *pc) 2312 { 2313 if (super::contextualize(pc)) 2314 return true; 2315 2316 /* 2317 In order to correctly process UNION's global ORDER BY we need to 2318 set braces before parsing the clause. 2319 */ 2320 pc->select->set_braces(true); 2321 2322 if (select_part2->contextualize(pc)) 2323 return true; 2324 2325 if (setup_select_in_parentheses(pc->select)) 2326 return true; 2327 2328 if (opt_hint_list != NULL && opt_hint_list->contextualize(pc)) 2329 return true; 2330 2331 return false; 2332 } 2333 }; 2334 2335 2336 class PT_select_init_parenthesis : public PT_select_init 2337 { 2338 typedef PT_select_init super; 2339 2340 PT_select_paren *select_paren; 2341 Parse_tree_node *union_opt; 2342 2343 public: PT_select_init_parenthesis(PT_select_paren * select_paren_arg,Parse_tree_node * union_opt_arg)2344 PT_select_init_parenthesis(PT_select_paren *select_paren_arg, 2345 Parse_tree_node *union_opt_arg) 2346 : select_paren(select_paren_arg), union_opt(union_opt_arg) 2347 {} 2348 contextualize(Parse_context * pc)2349 virtual bool contextualize(Parse_context *pc) 2350 { 2351 return (super::contextualize(pc) || select_paren->contextualize(pc) || 2352 (union_opt != NULL && union_opt->contextualize(pc))); 2353 } 2354 }; 2355 2356 2357 class PT_select_init2 : public PT_select_init 2358 { 2359 typedef PT_select_init super; 2360 2361 PT_hint_list *opt_hint_list; 2362 PT_select_part2 *select_part2; 2363 PT_union_list *opt_union_clause; 2364 2365 public: PT_select_init2(PT_hint_list * opt_hint_list_arg,PT_select_part2 * select_part2_arg,PT_union_list * opt_union_clause_arg)2366 PT_select_init2(PT_hint_list *opt_hint_list_arg, 2367 PT_select_part2 *select_part2_arg, 2368 PT_union_list *opt_union_clause_arg) 2369 : opt_hint_list(opt_hint_list_arg), 2370 select_part2(select_part2_arg), 2371 opt_union_clause(opt_union_clause_arg) 2372 {} 2373 contextualize(Parse_context * pc)2374 virtual bool contextualize(Parse_context *pc) 2375 { 2376 if (super::contextualize(pc) || 2377 select_part2->contextualize(pc)) 2378 return true; 2379 2380 // Parentheses carry no meaning here. 2381 pc->select->set_braces(false); 2382 2383 if (opt_hint_list != NULL && opt_hint_list->contextualize(pc)) 2384 return true; 2385 2386 if (opt_union_clause != NULL && opt_union_clause->contextualize(pc)) 2387 return true; 2388 2389 return false; 2390 } 2391 }; 2392 2393 2394 class PT_select : public Parse_tree_node 2395 { 2396 typedef Parse_tree_node super; 2397 2398 PT_select_init *select_init; 2399 enum_sql_command sql_command; 2400 2401 public: PT_select(PT_select_init * select_init_arg,enum_sql_command sql_command_arg)2402 explicit PT_select(PT_select_init *select_init_arg, 2403 enum_sql_command sql_command_arg) 2404 : select_init(select_init_arg), sql_command(sql_command_arg) 2405 {} 2406 contextualize(Parse_context * pc)2407 virtual bool contextualize(Parse_context *pc) 2408 { 2409 if (super::contextualize(pc)) 2410 return true; 2411 2412 pc->thd->lex->sql_command= sql_command; 2413 2414 if (select_init->contextualize(pc)) 2415 return true; 2416 2417 return false; 2418 } 2419 }; 2420 2421 2422 class PT_delete : public PT_statement 2423 { 2424 typedef PT_statement super; 2425 2426 PT_hint_list *opt_hints; 2427 const int opt_delete_options; 2428 Table_ident *table_ident; 2429 Mem_root_array_YY<Table_ident *> table_list; 2430 List<String> *opt_use_partition; 2431 PT_join_table_list *join_table_list; 2432 Item *opt_where_clause; 2433 PT_order *opt_order_clause; 2434 Item *opt_delete_limit_clause; 2435 2436 public: 2437 // single-table DELETE node constructor: PT_delete(MEM_ROOT * mem_root,PT_hint_list * opt_hints_arg,int opt_delete_options_arg,Table_ident * table_ident_arg,List<String> * opt_use_partition_arg,Item * opt_where_clause_arg,PT_order * opt_order_clause_arg,Item * opt_delete_limit_clause_arg)2438 PT_delete(MEM_ROOT *mem_root, 2439 PT_hint_list *opt_hints_arg, 2440 int opt_delete_options_arg, 2441 Table_ident *table_ident_arg, 2442 List<String> *opt_use_partition_arg, 2443 Item *opt_where_clause_arg, 2444 PT_order *opt_order_clause_arg, 2445 Item *opt_delete_limit_clause_arg) 2446 : opt_hints(opt_hints_arg), 2447 opt_delete_options(opt_delete_options_arg), 2448 table_ident(table_ident_arg), 2449 opt_use_partition(opt_use_partition_arg), 2450 join_table_list(NULL), 2451 opt_where_clause(opt_where_clause_arg), 2452 opt_order_clause(opt_order_clause_arg), 2453 opt_delete_limit_clause(opt_delete_limit_clause_arg) 2454 { 2455 table_list.init(mem_root); 2456 } 2457 2458 // multi-table DELETE node constructor: PT_delete(PT_hint_list * opt_hints_arg,int opt_delete_options_arg,const Mem_root_array_YY<Table_ident * > & table_list_arg,PT_join_table_list * join_table_list_arg,Item * opt_where_clause_arg)2459 PT_delete(PT_hint_list *opt_hints_arg, 2460 int opt_delete_options_arg, 2461 const Mem_root_array_YY<Table_ident *> &table_list_arg, 2462 PT_join_table_list *join_table_list_arg, 2463 Item *opt_where_clause_arg) 2464 : opt_hints(opt_hints_arg), 2465 opt_delete_options(opt_delete_options_arg), 2466 table_ident(NULL), 2467 table_list(table_list_arg), 2468 opt_use_partition(NULL), 2469 join_table_list(join_table_list_arg), 2470 opt_where_clause(opt_where_clause_arg), 2471 opt_order_clause(NULL), 2472 opt_delete_limit_clause(NULL) 2473 {} 2474 2475 virtual bool contextualize(Parse_context *pc); 2476 2477 virtual Sql_cmd *make_cmd(THD *thd); 2478 is_multitable()2479 bool is_multitable() const 2480 { 2481 DBUG_ASSERT((table_ident != NULL) ^ (table_list.size() > 0)); 2482 return table_ident == NULL; 2483 } 2484 2485 private: 2486 bool add_table(Parse_context *pc, Table_ident *table); 2487 }; 2488 2489 2490 class PT_update : public PT_statement 2491 { 2492 typedef PT_statement super; 2493 2494 PT_hint_list *opt_hints; 2495 thr_lock_type opt_low_priority; 2496 bool opt_ignore; 2497 PT_join_table_list *join_table_list; 2498 PT_item_list *column_list; 2499 PT_item_list *value_list; 2500 Item *opt_where_clause; 2501 PT_order *opt_order_clause; 2502 Item *opt_limit_clause; 2503 2504 Sql_cmd_update sql_cmd; 2505 2506 public: PT_update(PT_hint_list * opt_hints_arg,thr_lock_type opt_low_priority_arg,bool opt_ignore_arg,PT_join_table_list * join_table_list_arg,PT_item_list * column_list_arg,PT_item_list * value_list_arg,Item * opt_where_clause_arg,PT_order * opt_order_clause_arg,Item * opt_limit_clause_arg)2507 PT_update(PT_hint_list *opt_hints_arg, 2508 thr_lock_type opt_low_priority_arg, 2509 bool opt_ignore_arg, 2510 PT_join_table_list *join_table_list_arg, 2511 PT_item_list *column_list_arg, 2512 PT_item_list *value_list_arg, 2513 Item *opt_where_clause_arg, 2514 PT_order *opt_order_clause_arg, 2515 Item *opt_limit_clause_arg) 2516 : opt_hints(opt_hints_arg), 2517 opt_low_priority(opt_low_priority_arg), 2518 opt_ignore(opt_ignore_arg), 2519 join_table_list(join_table_list_arg), 2520 column_list(column_list_arg), 2521 value_list(value_list_arg), 2522 opt_where_clause(opt_where_clause_arg), 2523 opt_order_clause(opt_order_clause_arg), 2524 opt_limit_clause(opt_limit_clause_arg) 2525 {} 2526 2527 virtual bool contextualize(Parse_context *pc); 2528 2529 virtual Sql_cmd *make_cmd(THD *thd); 2530 }; 2531 2532 2533 class PT_create_select : public Parse_tree_node 2534 { 2535 typedef Parse_tree_node super; 2536 2537 PT_hint_list *opt_hints; 2538 Query_options options; 2539 PT_item_list *item_list; 2540 PT_table_expression *table_expression; 2541 2542 public: PT_create_select(PT_hint_list * opt_hints_arg,const Query_options & options_arg,PT_item_list * item_list_arg,PT_table_expression * table_expression_arg)2543 PT_create_select(PT_hint_list *opt_hints_arg, 2544 const Query_options &options_arg, 2545 PT_item_list *item_list_arg, 2546 PT_table_expression *table_expression_arg) 2547 : opt_hints(opt_hints_arg), 2548 options(options_arg), 2549 item_list(item_list_arg), 2550 table_expression(table_expression_arg) 2551 {} 2552 2553 virtual bool contextualize(Parse_context *pc); 2554 }; 2555 2556 2557 class PT_insert_values_list : public Parse_tree_node 2558 { 2559 typedef Parse_tree_node super; 2560 2561 List<List_item> many_values; 2562 2563 public: 2564 virtual bool contextualize(Parse_context *pc); 2565 push_back(List<Item> * x)2566 bool push_back(List<Item> *x) { return many_values.push_back(x); } 2567 get_many_values()2568 virtual List<List_item> &get_many_values() 2569 { 2570 DBUG_ASSERT(is_contextualized()); 2571 return many_values; 2572 } 2573 }; 2574 2575 2576 class PT_insert_query_expression : public Parse_tree_node 2577 { 2578 typedef Parse_tree_node super; 2579 2580 bool braces; 2581 PT_create_select *create_select; 2582 Parse_tree_node * opt_union; 2583 2584 public: PT_insert_query_expression(bool braces_arg,PT_create_select * create_select_arg,Parse_tree_node * opt_union_arg)2585 PT_insert_query_expression(bool braces_arg, 2586 PT_create_select *create_select_arg, 2587 Parse_tree_node * opt_union_arg) 2588 : braces(braces_arg), 2589 create_select(create_select_arg), 2590 opt_union(opt_union_arg) 2591 {} 2592 2593 virtual bool contextualize(Parse_context *pc); 2594 }; 2595 2596 2597 class PT_insert : public PT_statement 2598 { 2599 typedef PT_statement super; 2600 2601 const bool is_replace; 2602 PT_hint_list *opt_hints; 2603 const thr_lock_type lock_option; 2604 const bool ignore; 2605 Table_ident * const table_ident; 2606 List<String> * const opt_use_partition; 2607 PT_item_list * const column_list; 2608 PT_insert_values_list * const row_value_list; 2609 PT_insert_query_expression * const insert_query_expression; 2610 PT_item_list * const opt_on_duplicate_column_list; 2611 PT_item_list * const opt_on_duplicate_value_list; 2612 2613 public: PT_insert(bool is_replace_arg,PT_hint_list * opt_hints_arg,thr_lock_type lock_option_arg,bool ignore_arg,Table_ident * table_ident_arg,List<String> * opt_use_partition_arg,PT_item_list * column_list_arg,PT_insert_values_list * row_value_list_arg,PT_insert_query_expression * insert_query_expression_arg,PT_item_list * opt_on_duplicate_column_list_arg,PT_item_list * opt_on_duplicate_value_list_arg)2614 PT_insert(bool is_replace_arg, 2615 PT_hint_list *opt_hints_arg, 2616 thr_lock_type lock_option_arg, 2617 bool ignore_arg, 2618 Table_ident *table_ident_arg, 2619 List<String> *opt_use_partition_arg, 2620 PT_item_list *column_list_arg, 2621 PT_insert_values_list *row_value_list_arg, 2622 PT_insert_query_expression *insert_query_expression_arg, 2623 PT_item_list *opt_on_duplicate_column_list_arg, 2624 PT_item_list *opt_on_duplicate_value_list_arg) 2625 : is_replace(is_replace_arg), 2626 opt_hints(opt_hints_arg), 2627 lock_option(lock_option_arg), 2628 ignore(ignore_arg), 2629 table_ident(table_ident_arg), 2630 opt_use_partition(opt_use_partition_arg), 2631 column_list(column_list_arg), 2632 row_value_list(row_value_list_arg), 2633 insert_query_expression(insert_query_expression_arg), 2634 opt_on_duplicate_column_list(opt_on_duplicate_column_list_arg), 2635 opt_on_duplicate_value_list(opt_on_duplicate_value_list_arg) 2636 { 2637 // REPLACE statement can't have IGNORE flag: 2638 DBUG_ASSERT(!is_replace || !ignore); 2639 // REPLACE statement can't have ON DUPLICATE KEY UPDATE clause: 2640 DBUG_ASSERT(!is_replace || opt_on_duplicate_column_list == NULL); 2641 // INSERT/REPLACE ... SELECT can't have VALUES clause: 2642 DBUG_ASSERT((row_value_list != NULL) ^ (insert_query_expression != NULL)); 2643 // ON DUPLICATE KEY UPDATE: column and value arrays must have same sizes: 2644 DBUG_ASSERT((opt_on_duplicate_column_list == NULL && 2645 opt_on_duplicate_value_list == NULL) || 2646 (opt_on_duplicate_column_list->elements() == 2647 opt_on_duplicate_value_list->elements())); 2648 } 2649 2650 virtual bool contextualize(Parse_context *pc); 2651 2652 virtual Sql_cmd *make_cmd(THD *thd); 2653 2654 private: has_select()2655 bool has_select() const { return insert_query_expression != NULL; } 2656 }; 2657 2658 2659 class PT_shutdown : public PT_statement 2660 { 2661 Sql_cmd_shutdown sql_cmd; 2662 2663 public: make_cmd(THD *)2664 virtual Sql_cmd *make_cmd(THD *) { return &sql_cmd; } 2665 }; 2666 2667 2668 class PT_alter_instance : public PT_statement 2669 { 2670 typedef PT_statement super; 2671 2672 Sql_cmd_alter_instance sql_cmd; 2673 2674 public: PT_alter_instance(enum alter_instance_action_enum alter_instance_action)2675 explicit PT_alter_instance(enum alter_instance_action_enum alter_instance_action) 2676 : sql_cmd(alter_instance_action) 2677 {} 2678 2679 virtual Sql_cmd *make_cmd(THD *thd); 2680 virtual bool contextualize(Parse_context *pc); 2681 }; 2682 2683 #endif /* PARSE_TREE_NODES_INCLUDED */ 2684