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 &params_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= &params;
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