1 /* Copyright (c) 2013, 2020, 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 <stddef.h>
27 #include <sys/types.h>
28 #include <cctype>  // std::isspace
29 #include <memory>
30 
31 #include "lex_string.h"
32 #include "my_alloc.h"
33 #include "my_base.h"
34 #include "my_bit.h"  // is_single_bit
35 #include "my_dbug.h"
36 #include "my_inttypes.h"
37 #include "my_sqlcommand.h"
38 #include "my_sys.h"
39 #include "my_thread_local.h"
40 #include "my_time.h"
41 #include "mysqld_error.h"
42 #include "sql/enum_query_type.h"
43 #include "sql/handler.h"
44 #include "sql/key_spec.h"
45 #include "sql/mem_root_array.h"
46 #include "sql/opt_explain.h"         // Sql_cmd_explain_other_thread
47 #include "sql/parse_tree_helpers.h"  // PT_item_list
48 #include "sql/parse_tree_node_base.h"
49 #include "sql/parser_yystype.h"
50 #include "sql/partition_info.h"
51 #include "sql/resourcegroups/resource_group_basic_types.h"
52 #include "sql/resourcegroups/resource_group_sql_cmd.h"
53 #include "sql/set_var.h"
54 #include "sql/sql_admin.h"  // Sql_cmd_shutdown etc.
55 #include "sql/sql_alter.h"
56 #include "sql/sql_check_constraint.h"  // Sql_check_constraint_spec
57 #include "sql/sql_cmd_srs.h"
58 #include "sql/sql_exchange.h"
59 #include "sql/sql_lex.h"  // LEX
60 #include "sql/sql_list.h"
61 #include "sql/sql_load.h"  // Sql_cmd_load_table
62 #include "sql/sql_partition_admin.h"
63 #include "sql/sql_restart_server.h"  // Sql_cmd_restart_server
64 #include "sql/sql_tablespace.h"      // Tablespace_options
65 #include "sql/sql_truncate.h"        // Sql_cmd_truncate_table
66 #include "sql/table.h"               // Common_table_expr
67 #include "sql/window.h"              // Window
68 #include "sql/window_lex.h"
69 #include "thr_lock.h"
70 
71 class Item;
72 class Item_cache;
73 class Item_string;
74 class Json_table_column;
75 class PT_field_def_base;
76 class PT_hint_list;
77 class PT_part_definition;
78 class PT_partition;
79 class PT_subquery;
80 class PT_type;
81 class sp_head;
82 class sp_name;
83 class Sql_cmd;
84 class String;
85 class THD;
86 struct CHARSET_INFO;
87 
88 /**
89   @defgroup ptn  Parse tree nodes
90   @ingroup  Parser
91 */
92 /**
93   @defgroup ptn_stmt  Nodes representing SQL statements
94   @ingroup  ptn
95 */
96 /**
97   @defgroup ptn_create_table  CREATE TABLE statement
98   @ingroup  ptn_stmt
99 */
100 /**
101   @defgroup ptn_alter_table  ALTER TABLE statement
102   @ingroup  ptn_stmt
103 */
104 /**
105   @defgroup ptn_create_table_stuff  Clauses of CREATE TABLE statement
106   @ingroup  ptn_create_table
107 */
108 /**
109   @defgroup ptn_partitioning CREATE/ALTER TABLE partitioning-related stuff
110   @ingroup  ptn_create_table ptn_alter_table
111 */
112 /**
113   @defgroup ptn_part_options Partition options in CREATE/ALTER TABLE
114   @ingroup  ptn_partitioning
115 */
116 /**
117   @defgroup ptn_create_or_alter_table_options  Table options of CREATE/ALTER
118   TABLE
119   @anchor   ptn_create_or_alter_table_options
120   @ingroup  ptn_create_table ptn_alter_table
121 */
122 /**
123   @defgroup ptn_col_types  Column types in CREATE/ALTER TABLE
124   @ingroup  ptn_create_table ptn_alter_table
125 */
126 /**
127   @defgroup ptn_col_attrs  Column attributes in CREATE/ALTER TABLE
128   @ingroup  ptn_create_table ptn_alter_table
129 */
130 /**
131   @defgroup ptn_not_gcol_attr Non-generated column attributes in CREATE/ALTER
132   TABLE
133   @ingroup ptn_col_attrs ptn_alter_table
134 */
135 
136 /**
137   Calls contextualize() on every node in the array.
138 */
139 template <class Node_type, class Parse_context_type>
contextualize_nodes(Mem_root_array_YY<Node_type * > nodes,Parse_context_type * pc)140 bool contextualize_nodes(Mem_root_array_YY<Node_type *> nodes,
141                          Parse_context_type *pc) {
142   for (Node_type *i : nodes)
143     if (i->contextualize(pc)) return true;
144   return false;
145 }
146 
147 /**
148   Base class for all top-level nodes of SQL statements
149 
150   @ingroup ptn_stmt
151 */
152 class Parse_tree_root {
153   Parse_tree_root(const Parse_tree_root &) = delete;
154   void operator=(const Parse_tree_root &) = delete;
155 
156  protected:
~Parse_tree_root()157   virtual ~Parse_tree_root() {}
Parse_tree_root()158   Parse_tree_root() {}
159 
160  public:
161   virtual Sql_cmd *make_cmd(THD *thd) = 0;
162 };
163 
164 class PT_table_ddl_stmt_base : public Parse_tree_root {
165  public:
PT_table_ddl_stmt_base(MEM_ROOT * mem_root)166   explicit PT_table_ddl_stmt_base(MEM_ROOT *mem_root)
167       : m_alter_info(mem_root) {}
168 
169   virtual ~PT_table_ddl_stmt_base() = 0;  // force abstract class
170 
171  protected:
172   Alter_info m_alter_info;
173 };
174 
~PT_table_ddl_stmt_base()175 inline PT_table_ddl_stmt_base::~PT_table_ddl_stmt_base() {}
176 
177 /**
178   Parse context for the table DDL (ALTER TABLE and CREATE TABLE) nodes.
179 
180   For internal use in the contextualization code.
181 */
182 struct Table_ddl_parse_context final : public Parse_context {
183   Table_ddl_parse_context(THD *thd_arg, SELECT_LEX *select_arg,
184                           Alter_info *alter_info);
185   HA_CREATE_INFO *const create_info;
186   Alter_info *const alter_info;
187   KEY_CREATE_INFO *const key_create_info;
188 };
189 
190 /**
191   Base class for all table DDL (ALTER TABLE and CREATE TABLE) nodes.
192 */
193 typedef Parse_tree_node_tmpl<Table_ddl_parse_context> Table_ddl_node;
194 
195 class PT_order_expr : public Parse_tree_node, public ORDER {
196   typedef Parse_tree_node super;
197 
198  public:
PT_order_expr(Item * item_arg,enum_order dir)199   PT_order_expr(Item *item_arg, enum_order dir) {
200     item_ptr = item_arg;
201     direction = (dir == ORDER_DESC) ? ORDER_DESC : ORDER_ASC;
202   }
203 
204   bool contextualize(Parse_context *pc) override;
205 };
206 
207 class PT_order_list : public Parse_tree_node {
208   typedef Parse_tree_node super;
209 
210  public:
211   SQL_I_List<ORDER> value;
212 
213  public:
contextualize(Parse_context * pc)214   bool contextualize(Parse_context *pc) override {
215     if (super::contextualize(pc)) return true;
216     for (ORDER *o = value.first; o != nullptr; o = o->next) {
217       if (static_cast<PT_order_expr *>(o)->contextualize(pc)) return true;
218     }
219     return false;
220   }
221 
push_back(PT_order_expr * order)222   void push_back(PT_order_expr *order) {
223     order->item = &order->item_ptr;
224     order->used_alias = false;
225     order->used = 0;
226     order->is_position = false;
227     value.link_in_list(order, &order->next);
228   }
229 };
230 
231 class PT_gorder_list : public PT_order_list {
232   typedef PT_order_list super;
233 
234  public:
contextualize(Parse_context * pc)235   bool contextualize(Parse_context *pc) override {
236     return super::contextualize(pc);
237   }
238 };
239 
240 /**
241   Represents an element of the WITH list:
242   WITH [...], [...] SELECT ...,
243          ^  or  ^
244   i.e. a Common Table Expression (CTE, or Query Name in SQL99 terms).
245 */
246 class PT_common_table_expr : public Parse_tree_node {
247   typedef Parse_tree_node super;
248 
249  public:
250   explicit PT_common_table_expr(const LEX_STRING &name,
251                                 const LEX_STRING &subq_text,
252                                 uint subq_text_offset, PT_subquery *sn,
253                                 const Create_col_name_list *column_names,
254                                 MEM_ROOT *mem_root);
255 
256   /// The name after AS
name()257   const LEX_STRING &name() const { return m_name; }
258   /**
259     @param      thd  Thread handler
260     @param[out] node PT_subquery
261     @returns a PT_subquery to attach to a table reference for this CTE
262   */
263   bool make_subquery_node(THD *thd, PT_subquery **node);
264   /**
265     @param tl  Table reference to match
266     @param in_self  If this is a recursive reference
267     @param[out]  found Is set to true/false if matches or not
268     @returns true if error
269   */
270   bool match_table_ref(TABLE_LIST *tl, bool in_self, bool *found);
271   /**
272     @returns true if 'other' is the same instance as 'this'
273   */
is(const Common_table_expr * other)274   bool is(const Common_table_expr *other) const {
275     return other == &m_postparse;
276   }
277   void print(const THD *thd, String *str, enum_query_type query_type);
278 
279  private:
280   LEX_STRING m_name;
281   /// Raw text of query expression (including parentheses)
282   const LEX_STRING m_subq_text;
283   /**
284     Offset in bytes of m_subq_text in original statement which had the WITH
285     clause.
286   */
287   uint m_subq_text_offset;
288   /// Parsed version of subq_text
289   PT_subquery *const m_subq_node;
290   /// List of explicitely specified column names; if empty, no list.
291   const Create_col_name_list m_column_names;
292   /**
293     A TABLE_LIST representing a CTE needs access to the WITH list
294     element it derives from. However, in order to:
295     - limit the members which TABLE_LIST can access
296     - avoid including this header file everywhere TABLE_LIST needs to access
297     these members,
298     these members are relocated into a separate inferior object whose
299     declaration is in table.h, like that of TABLE_LIST. It's the "postparse"
300     part. TABLE_LIST accesses this inferior object only.
301   */
302   Common_table_expr m_postparse;
303 
304   friend bool SELECT_LEX_UNIT::clear_correlated_query_blocks();
305 };
306 
307 /**
308    Represents the WITH list.
309    WITH [...], [...] SELECT ...,
310         ^^^^^^^^^^^^
311 */
312 class PT_with_list : public Parse_tree_node {
313   typedef Parse_tree_node super;
314 
315  public:
316   /// @param mem_root where interior objects are allocated
PT_with_list(MEM_ROOT * mem_root)317   explicit PT_with_list(MEM_ROOT *mem_root) : m_elements(mem_root) {}
318   bool push_back(PT_common_table_expr *el);
elements()319   const Mem_root_array<PT_common_table_expr *> &elements() const {
320     return m_elements;
321   }
322 
323  private:
324   Mem_root_array<PT_common_table_expr *> m_elements;
325 };
326 
327 /**
328   Represents the WITH clause:
329   WITH [...], [...] SELECT ...,
330   ^^^^^^^^^^^^^^^^^
331 */
332 class PT_with_clause : public Parse_tree_node {
333   typedef Parse_tree_node super;
334 
335  public:
PT_with_clause(const PT_with_list * l,bool r)336   PT_with_clause(const PT_with_list *l, bool r)
337       : m_list(l), m_recursive(r), m_most_inner_in_parsing(nullptr) {}
338 
339   bool contextualize(Parse_context *pc) override;
340 
341   /**
342     Looks up a table reference into the list of CTEs.
343     @param      tl    Table reference to look up
344     @param[out] found Is set to true/false if found or not
345     @returns true if error
346   */
347   bool lookup(TABLE_LIST *tl, PT_common_table_expr **found);
348   /**
349     Call this to record in the WITH clause that we are contextualizing the
350     CTE definition inserted in table reference 'tl'.
351     @returns information which the caller must provide to
352     leave_parsing_definition().
353   */
enter_parsing_definition(TABLE_LIST * tl)354   const TABLE_LIST *enter_parsing_definition(TABLE_LIST *tl) {
355     auto old = m_most_inner_in_parsing;
356     m_most_inner_in_parsing = tl;
357     return old;
358   }
leave_parsing_definition(const TABLE_LIST * old)359   void leave_parsing_definition(const TABLE_LIST *old) {
360     m_most_inner_in_parsing = old;
361   }
362   void print(const THD *thd, String *str, enum_query_type query_type);
363 
364  private:
365   /// All CTEs of this clause
366   const PT_with_list *const m_list;
367   /// True if the user has specified the RECURSIVE keyword.
368   const bool m_recursive;
369   /**
370     The innermost CTE reference which we're parsing at the
371     moment. Used to detect forward references, loops and recursiveness.
372   */
373   const TABLE_LIST *m_most_inner_in_parsing;
374 
375   friend bool SELECT_LEX_UNIT::clear_correlated_query_blocks();
376 };
377 
378 class PT_select_item_list : public PT_item_list {
379   typedef PT_item_list super;
380 
381  public:
382   bool contextualize(Parse_context *pc) override;
383 };
384 
385 class PT_limit_clause : public Parse_tree_node {
386   typedef Parse_tree_node super;
387 
388   Limit_options limit_options;
389 
390  public:
PT_limit_clause(const Limit_options & limit_options_arg)391   PT_limit_clause(const Limit_options &limit_options_arg)
392       : limit_options(limit_options_arg) {}
393 
394   bool contextualize(Parse_context *pc) override;
395 };
396 
397 class PT_cross_join;
398 class PT_joined_table;
399 
400 class PT_table_reference : public Parse_tree_node {
401  public:
402   TABLE_LIST *value;
403 
404   /**
405     Lets us build a parse tree top-down, which is necessary due to the
406     context-dependent nature of the join syntax. This function adds
407     the @<table_ref@> cross join as the left-most leaf in this join tree
408     rooted at this node.
409 
410     @todo: comment on non-join PT_table_reference objects
411 
412     @param cj This @<table ref@> will be added if it represents a cross join.
413 
414     @return The new top-level join.
415   */
416   virtual PT_joined_table *add_cross_join(PT_cross_join *cj);
417 };
418 
419 class PT_table_factor_table_ident : public PT_table_reference {
420   typedef PT_table_reference super;
421 
422   Table_ident *table_ident;
423   List<String> *opt_use_partition;
424   const char *const opt_table_alias;
425   List<Index_hint> *opt_key_definition;
426 
427  public:
PT_table_factor_table_ident(Table_ident * table_ident_arg,List<String> * opt_use_partition_arg,const LEX_CSTRING & opt_table_alias_arg,List<Index_hint> * opt_key_definition_arg)428   PT_table_factor_table_ident(Table_ident *table_ident_arg,
429                               List<String> *opt_use_partition_arg,
430                               const LEX_CSTRING &opt_table_alias_arg,
431                               List<Index_hint> *opt_key_definition_arg)
432       : table_ident(table_ident_arg),
433         opt_use_partition(opt_use_partition_arg),
434         opt_table_alias(opt_table_alias_arg.str),
435         opt_key_definition(opt_key_definition_arg) {}
436 
437   bool contextualize(Parse_context *pc) override;
438 };
439 
440 class PT_json_table_column : public Parse_tree_node {
441  public:
442   virtual Json_table_column *get_column() = 0;
443 };
444 
445 class PT_table_factor_function : public PT_table_reference {
446   typedef PT_table_reference super;
447 
448  public:
PT_table_factor_function(Item * expr,Item * path,Mem_root_array<PT_json_table_column * > * nested_cols,const LEX_STRING & table_alias)449   PT_table_factor_function(Item *expr, Item *path,
450                            Mem_root_array<PT_json_table_column *> *nested_cols,
451                            const LEX_STRING &table_alias)
452       : m_expr(expr),
453         m_path(path),
454         m_nested_columns(nested_cols),
455         m_table_alias(table_alias) {}
456 
457   bool contextualize(Parse_context *pc) override;
458 
459  private:
460   Item *m_expr;
461   Item *m_path;
462   Mem_root_array<PT_json_table_column *> *m_nested_columns;
463   const LEX_STRING m_table_alias;
464 };
465 
466 class PT_table_reference_list_parens : public PT_table_reference {
467   typedef PT_table_reference super;
468 
469   Mem_root_array_YY<PT_table_reference *> table_list;
470 
471  public:
PT_table_reference_list_parens(const Mem_root_array_YY<PT_table_reference * > table_list)472   explicit PT_table_reference_list_parens(
473       const Mem_root_array_YY<PT_table_reference *> table_list)
474       : table_list(table_list) {}
475 
476   bool contextualize(Parse_context *pc) override;
477 };
478 
479 class PT_derived_table : public PT_table_reference {
480   typedef PT_table_reference super;
481 
482  public:
483   PT_derived_table(bool lateral, PT_subquery *subquery,
484                    const LEX_CSTRING &table_alias,
485                    Create_col_name_list *column_names);
486 
487   bool contextualize(Parse_context *pc) override;
488 
489  private:
490   bool m_lateral;
491   PT_subquery *m_subquery;
492   const char *const m_table_alias;
493   /// List of explicitely specified column names; if empty, no list.
494   const Create_col_name_list column_names;
495 };
496 
497 class PT_table_factor_joined_table : public PT_table_reference {
498   typedef PT_table_reference super;
499 
500  public:
PT_table_factor_joined_table(PT_joined_table * joined_table)501   PT_table_factor_joined_table(PT_joined_table *joined_table)
502       : m_joined_table(joined_table) {}
503 
504   bool contextualize(Parse_context *pc) override;
505 
506  private:
507   PT_joined_table *m_joined_table;
508 };
509 
510 class PT_joined_table : public PT_table_reference {
511   typedef PT_table_reference super;
512 
513  protected:
514   PT_table_reference *tab1_node;
515   POS join_pos;
516   PT_joined_table_type m_type;
517   PT_table_reference *tab2_node;
518 
519   TABLE_LIST *tr1;
520   TABLE_LIST *tr2;
521 
522  public:
PT_joined_table(PT_table_reference * tab1_node_arg,const POS & join_pos_arg,PT_joined_table_type type,PT_table_reference * tab2_node_arg)523   PT_joined_table(PT_table_reference *tab1_node_arg, const POS &join_pos_arg,
524                   PT_joined_table_type type, PT_table_reference *tab2_node_arg)
525       : tab1_node(tab1_node_arg),
526         join_pos(join_pos_arg),
527         m_type(type),
528         tab2_node(tab2_node_arg),
529         tr1(nullptr),
530         tr2(nullptr) {
531     static_assert(is_single_bit(JTT_INNER), "not a single bit");
532     static_assert(is_single_bit(JTT_STRAIGHT), "not a single bit");
533     static_assert(is_single_bit(JTT_NATURAL), "not a single bit");
534     static_assert(is_single_bit(JTT_LEFT), "not a single bit");
535     static_assert(is_single_bit(JTT_RIGHT), "not a single bit");
536 
537     DBUG_ASSERT(type == JTT_INNER || type == JTT_STRAIGHT_INNER ||
538                 type == JTT_NATURAL_INNER || type == JTT_NATURAL_LEFT ||
539                 type == JTT_NATURAL_RIGHT || type == JTT_LEFT ||
540                 type == JTT_RIGHT);
541   }
542 
543   /**
544     Adds the cross join to this join operation. The cross join is nested as
545     the table reference on the left-hand side.
546   */
add_cross_join(PT_cross_join * cj)547   PT_joined_table *add_cross_join(PT_cross_join *cj) override {
548     tab1_node = tab1_node->add_cross_join(cj);
549     return this;
550   }
551 
552   /// Adds the table reference as the right-hand side of this join.
add_rhs(PT_table_reference * table)553   void add_rhs(PT_table_reference *table) {
554     DBUG_ASSERT(tab2_node == nullptr);
555     tab2_node = table;
556   }
557 
558   bool contextualize(Parse_context *pc) override;
559 
560   /// This class is being inherited, it should thus be abstract.
561   ~PT_joined_table() override = 0;
562 
563  protected:
contextualize_tabs(Parse_context * pc)564   bool contextualize_tabs(Parse_context *pc) {
565     if (tr1 != nullptr) return false;  // already done
566 
567     if (tab1_node->contextualize(pc) || tab2_node->contextualize(pc))
568       return true;
569 
570     tr1 = tab1_node->value;
571     tr2 = tab2_node->value;
572 
573     if (tr1 == nullptr || tr2 == nullptr) {
574       error(pc, join_pos);
575       return true;
576     }
577     return false;
578   }
579 };
580 
~PT_joined_table()581 inline PT_joined_table::~PT_joined_table() {}
582 
583 class PT_cross_join : public PT_joined_table {
584   typedef PT_joined_table super;
585 
586  public:
PT_cross_join(PT_table_reference * tab1_node_arg,const POS & join_pos_arg,PT_joined_table_type Type_arg,PT_table_reference * tab2_node_arg)587   PT_cross_join(PT_table_reference *tab1_node_arg, const POS &join_pos_arg,
588                 PT_joined_table_type Type_arg,
589                 PT_table_reference *tab2_node_arg)
590       : PT_joined_table(tab1_node_arg, join_pos_arg, Type_arg, tab2_node_arg) {}
591 
592   bool contextualize(Parse_context *pc) override;
593 };
594 
595 class PT_joined_table_on : public PT_joined_table {
596   typedef PT_joined_table super;
597   Item *on;
598 
599  public:
PT_joined_table_on(PT_table_reference * tab1_node_arg,const POS & join_pos_arg,PT_joined_table_type type,PT_table_reference * tab2_node_arg,Item * on_arg)600   PT_joined_table_on(PT_table_reference *tab1_node_arg, const POS &join_pos_arg,
601                      PT_joined_table_type type,
602                      PT_table_reference *tab2_node_arg, Item *on_arg)
603       : super(tab1_node_arg, join_pos_arg, type, tab2_node_arg), on(on_arg) {}
604 
605   bool contextualize(Parse_context *pc) override;
606 };
607 
608 class PT_joined_table_using : public PT_joined_table {
609   typedef PT_joined_table super;
610   List<String> *using_fields;
611 
612  public:
PT_joined_table_using(PT_table_reference * tab1_node_arg,const POS & join_pos_arg,PT_joined_table_type type,PT_table_reference * tab2_node_arg,List<String> * using_fields_arg)613   PT_joined_table_using(PT_table_reference *tab1_node_arg,
614                         const POS &join_pos_arg, PT_joined_table_type type,
615                         PT_table_reference *tab2_node_arg,
616                         List<String> *using_fields_arg)
617       : super(tab1_node_arg, join_pos_arg, type, tab2_node_arg),
618         using_fields(using_fields_arg) {}
619 
620   /// A PT_joined_table_using without a list of columns denotes a natural join.
PT_joined_table_using(PT_table_reference * tab1_node_arg,const POS & join_pos_arg,PT_joined_table_type type,PT_table_reference * tab2_node_arg)621   PT_joined_table_using(PT_table_reference *tab1_node_arg,
622                         const POS &join_pos_arg, PT_joined_table_type type,
623                         PT_table_reference *tab2_node_arg)
624       : PT_joined_table_using(tab1_node_arg, join_pos_arg, type, tab2_node_arg,
625                               nullptr) {}
626 
627   bool contextualize(Parse_context *pc) override;
628 };
629 
630 class PT_group : public Parse_tree_node {
631   typedef Parse_tree_node super;
632 
633   PT_order_list *group_list;
634   olap_type olap;
635 
636  public:
PT_group(PT_order_list * group_list_arg,olap_type olap_arg)637   PT_group(PT_order_list *group_list_arg, olap_type olap_arg)
638       : group_list(group_list_arg), olap(olap_arg) {}
639 
640   bool contextualize(Parse_context *pc) override;
641 };
642 
643 class PT_order : public Parse_tree_node {
644   typedef Parse_tree_node super;
645 
646   PT_order_list *order_list;
647 
648  public:
PT_order(PT_order_list * order_list_arg)649   explicit PT_order(PT_order_list *order_list_arg)
650       : order_list(order_list_arg) {}
651 
652   bool contextualize(Parse_context *pc) override;
653 };
654 
655 class PT_locking_clause : public Parse_tree_node {
656  public:
PT_locking_clause(Lock_strength strength,Locked_row_action action)657   PT_locking_clause(Lock_strength strength, Locked_row_action action)
658       : m_lock_strength(strength), m_locked_row_action(action) {}
659 
660   bool contextualize(Parse_context *pc) override final;
661 
662   virtual bool set_lock_for_tables(Parse_context *pc) = 0;
663 
action()664   Locked_row_action action() const { return m_locked_row_action; }
665 
666  protected:
get_lock_descriptor()667   Lock_descriptor get_lock_descriptor() const {
668     thr_lock_type lock_type = TL_IGNORE;
669     switch (m_lock_strength) {
670       case Lock_strength::UPDATE:
671         lock_type = TL_WRITE;
672         break;
673       case Lock_strength::SHARE:
674         lock_type = TL_READ_WITH_SHARED_LOCKS;
675         break;
676     }
677 
678     return {lock_type, static_cast<thr_locked_row_action>(action())};
679   }
680 
681  private:
682   Lock_strength m_lock_strength;
683   Locked_row_action m_locked_row_action;
684 };
685 
686 class PT_query_block_locking_clause : public PT_locking_clause {
687  public:
688   explicit PT_query_block_locking_clause(
689       Lock_strength strength,
690       Locked_row_action action = Locked_row_action::WAIT)
PT_locking_clause(strength,action)691       : PT_locking_clause(strength, action) {}
692 
693   bool set_lock_for_tables(Parse_context *pc) override;
694 };
695 
696 class PT_table_locking_clause : public PT_locking_clause {
697  public:
698   typedef Mem_root_array_YY<Table_ident *> Table_ident_list;
699 
PT_table_locking_clause(Lock_strength strength,Mem_root_array_YY<Table_ident * > tables,Locked_row_action action)700   PT_table_locking_clause(Lock_strength strength,
701                           Mem_root_array_YY<Table_ident *> tables,
702                           Locked_row_action action)
703       : PT_locking_clause(strength, action), m_tables(tables) {}
704 
705   bool set_lock_for_tables(Parse_context *pc) override;
706 
707  private:
708   /// @todo Move this function to Table_ident?
709   void print_table_ident(const THD *thd, const Table_ident *ident, String *s);
710 
711   bool raise_error(THD *thd, const Table_ident *name, int error);
712 
713   bool raise_error(int error);
714 
715   Table_ident_list m_tables;
716 };
717 
718 class PT_locking_clause_list : public Parse_tree_node {
719  public:
PT_locking_clause_list(MEM_ROOT * mem_root)720   PT_locking_clause_list(MEM_ROOT *mem_root) {
721     m_locking_clauses.init(mem_root);
722   }
723 
push_back(PT_locking_clause * locking_clause)724   bool push_back(PT_locking_clause *locking_clause) {
725     return m_locking_clauses.push_back(locking_clause);
726   }
727 
contextualize(Parse_context * pc)728   bool contextualize(Parse_context *pc) override {
729     for (auto locking_clause : m_locking_clauses)
730       if (locking_clause->contextualize(pc)) return true;
731     return false;
732   }
733 
734  private:
735   Mem_root_array_YY<PT_locking_clause *> m_locking_clauses;
736 };
737 
738 class PT_query_expression_body : public Parse_tree_node {
739  public:
740   virtual bool is_union() const = 0;
741 
742   /**
743     True if this query expression can absorb an extraneous order by/limit
744     clause. The `ORDER BY`/`LIMIT` syntax is mostly consistestent, i.e. a
745     trailing clause may not refer to the tables in the `<query primary>`, with
746     one glaring exception:
747 
748         (...( SELECT ... )...) ORDER BY ...
749 
750     If the nested query expression doesn't contain `ORDER BY`, the statement
751     is interpreted as if the `ORDER BY` was absorbed by the innermost query
752     expression, i.e.:
753 
754         (...( SELECT ... ORDER BY ... )...)
755 
756     There is no rewriting of the parse tree nor AST happening here, the
757     transformation is done by the contextualizer (see
758     PT_query_expression::contextualize_order_and_limit), which interprets the
759     parse tree, and builds the AST according to this interpretation. This
760     interpretation is governed by the following rule: An `ORDER BY` can be
761     absorbed if none the nested query expressions contains an `ORDER BY` *or*
762     `LIMIT`. The rule is complex, so here are some examples for illustration:
763 
764     In these cases the `ORDER BY` *is* absorbed:
765 
766         ( SELECT * FROM t1 ) ORDER BY t1.a;
767         (( SELECT * FROM t1 )) ORDER BY t1.a;
768 
769     In these cases the ORDER BY is *not* absorbed:
770 
771         ( SELECT * FROM t1 ORDER BY 1 ) ORDER BY t1.a;
772         (( SELECT * FROM t1 ) ORDER BY 1 ) ORDER BY t1.a;
773         ( SELECT * FROM t1 LIMIT 1 ) ORDER BY t1.a;
774         (( SELECT * FROM t1 ) LIMIT 1 ) ORDER BY t1.a;
775 
776     The same happens with `LIMIT`, obviously, but the optimizer is freeer to
777     choose when to apply the limit, and there are name no resolution issues
778     involved.
779 
780     @param order  True if the outer query block has the ORDER BY clause.
781     @param limit  True if the outer query block has the LIMIT clause.
782   */
783   virtual bool can_absorb_order_and_limit(bool order, bool limit) const = 0;
784   virtual bool has_into_clause() const = 0;
785   virtual bool has_trailing_into_clause() const = 0;
786 
787   virtual bool is_table_value_constructor() const = 0;
788   virtual PT_insert_values_list *get_row_value_list() const = 0;
789 };
790 
791 class PT_internal_variable_name : public Parse_tree_node {
792  public:
793   sys_var_with_base value;
794 };
795 
796 class PT_internal_variable_name_1d : public PT_internal_variable_name {
797   typedef PT_internal_variable_name super;
798 
799   LEX_CSTRING ident;
800 
801  public:
PT_internal_variable_name_1d(LEX_CSTRING ident_arg)802   PT_internal_variable_name_1d(LEX_CSTRING ident_arg) : ident(ident_arg) {}
803 
804   bool contextualize(Parse_context *pc) override;
805 };
806 
807 /**
808   Parse tree node class for 2-dimentional variable names (example: \@global.x)
809 */
810 class PT_internal_variable_name_2d : public PT_internal_variable_name {
811   typedef PT_internal_variable_name super;
812 
813  public:
814   const POS pos;
815 
816  private:
817   LEX_CSTRING ident1;
818   LEX_CSTRING ident2;
819 
820  public:
PT_internal_variable_name_2d(const POS & pos,LEX_CSTRING ident1_arg,LEX_CSTRING ident2_arg)821   PT_internal_variable_name_2d(const POS &pos, LEX_CSTRING ident1_arg,
822                                LEX_CSTRING ident2_arg)
823       : pos(pos), ident1(ident1_arg), ident2(ident2_arg) {}
824 
825   bool contextualize(Parse_context *pc) override;
826 };
827 
828 class PT_internal_variable_name_default : public PT_internal_variable_name {
829   typedef PT_internal_variable_name super;
830 
831   LEX_STRING ident;
832 
833  public:
PT_internal_variable_name_default(const LEX_STRING & ident_arg)834   PT_internal_variable_name_default(const LEX_STRING &ident_arg)
835       : ident(ident_arg) {}
836 
837   bool contextualize(Parse_context *pc) override;
838 };
839 
840 class PT_option_value_following_option_type : public Parse_tree_node {
841   typedef Parse_tree_node super;
842 
843   POS pos;
844   PT_internal_variable_name *name;
845   Item *opt_expr;
846 
847  public:
PT_option_value_following_option_type(const POS & pos,PT_internal_variable_name * name_arg,Item * opt_expr_arg)848   PT_option_value_following_option_type(const POS &pos,
849                                         PT_internal_variable_name *name_arg,
850                                         Item *opt_expr_arg)
851       : pos(pos), name(name_arg), opt_expr(opt_expr_arg) {}
852 
853   bool contextualize(Parse_context *pc) override;
854 };
855 
856 class PT_option_value_no_option_type : public Parse_tree_node {};
857 
858 class PT_option_value_no_option_type_internal
859     : public PT_option_value_no_option_type {
860   typedef PT_option_value_no_option_type super;
861 
862   PT_internal_variable_name *name;
863   Item *opt_expr;
864   POS expr_pos;
865 
866  public:
PT_option_value_no_option_type_internal(PT_internal_variable_name * name_arg,Item * opt_expr_arg,const POS & expr_pos_arg)867   PT_option_value_no_option_type_internal(PT_internal_variable_name *name_arg,
868                                           Item *opt_expr_arg,
869                                           const POS &expr_pos_arg)
870       : name(name_arg), opt_expr(opt_expr_arg), expr_pos(expr_pos_arg) {}
871 
872   bool contextualize(Parse_context *pc) override;
873 };
874 
875 class PT_option_value_no_option_type_user_var
876     : public PT_option_value_no_option_type {
877   typedef PT_option_value_no_option_type super;
878 
879   LEX_STRING name;
880   Item *expr;
881 
882  public:
PT_option_value_no_option_type_user_var(const LEX_STRING & name_arg,Item * expr_arg)883   PT_option_value_no_option_type_user_var(const LEX_STRING &name_arg,
884                                           Item *expr_arg)
885       : name(name_arg), expr(expr_arg) {}
886 
887   bool contextualize(Parse_context *pc) override;
888 };
889 
890 class PT_option_value_no_option_type_sys_var
891     : public PT_option_value_no_option_type {
892   typedef PT_option_value_no_option_type super;
893 
894   enum_var_type type;
895   PT_internal_variable_name *name;
896   Item *opt_expr;
897 
898  public:
PT_option_value_no_option_type_sys_var(enum_var_type type_arg,PT_internal_variable_name * name_arg,Item * opt_expr_arg)899   PT_option_value_no_option_type_sys_var(enum_var_type type_arg,
900                                          PT_internal_variable_name *name_arg,
901                                          Item *opt_expr_arg)
902       : type(type_arg), name(name_arg), opt_expr(opt_expr_arg) {}
903 
904   bool contextualize(Parse_context *pc) override;
905 };
906 
907 class PT_option_value_no_option_type_charset
908     : public PT_option_value_no_option_type {
909   typedef PT_option_value_no_option_type super;
910 
911   const CHARSET_INFO *opt_charset;
912 
913  public:
PT_option_value_no_option_type_charset(const CHARSET_INFO * opt_charset_arg)914   PT_option_value_no_option_type_charset(const CHARSET_INFO *opt_charset_arg)
915       : opt_charset(opt_charset_arg) {}
916 
917   bool contextualize(Parse_context *pc) override;
918 };
919 
920 class PT_option_value_no_option_type_names
921     : public PT_option_value_no_option_type {
922   typedef PT_option_value_no_option_type super;
923 
924   POS pos;
925 
926  public:
PT_option_value_no_option_type_names(const POS & pos)927   explicit PT_option_value_no_option_type_names(const POS &pos) : pos(pos) {}
928 
929   bool contextualize(Parse_context *pc) override;
930 };
931 
932 class PT_set_names : public PT_option_value_no_option_type {
933   typedef PT_option_value_no_option_type super;
934 
935   const CHARSET_INFO *opt_charset;
936   const CHARSET_INFO *opt_collation;
937 
938  public:
PT_set_names(const CHARSET_INFO * opt_charset_arg,const CHARSET_INFO * opt_collation_arg)939   PT_set_names(const CHARSET_INFO *opt_charset_arg,
940                const CHARSET_INFO *opt_collation_arg)
941       : opt_charset(opt_charset_arg), opt_collation(opt_collation_arg) {}
942 
943   bool contextualize(Parse_context *pc) override;
944 };
945 
946 class PT_start_option_value_list : public Parse_tree_node {};
947 
948 class PT_option_value_no_option_type_password
949     : public PT_start_option_value_list {
950   typedef PT_start_option_value_list super;
951 
952   const char *password;
953   const char *current_password;
954   bool retain_current_password;
955   bool random_password_generator;
956   POS expr_pos;
957 
958  public:
PT_option_value_no_option_type_password(const char * password_arg,const char * current_password_arg,bool retain_current,bool random_password,const POS & expr_pos_arg)959   PT_option_value_no_option_type_password(const char *password_arg,
960                                           const char *current_password_arg,
961                                           bool retain_current,
962                                           bool random_password,
963                                           const POS &expr_pos_arg)
964       : password(password_arg),
965         current_password(current_password_arg),
966         retain_current_password(retain_current),
967         random_password_generator(random_password),
968         expr_pos(expr_pos_arg) {}
969 
970   bool contextualize(Parse_context *pc) override;
971 };
972 
973 class PT_option_value_no_option_type_password_for
974     : public PT_start_option_value_list {
975   typedef PT_start_option_value_list super;
976 
977   LEX_USER *user;
978   const char *password;
979   const char *current_password;
980   bool retain_current_password;
981   bool random_password_generator;
982   POS expr_pos;
983 
984  public:
PT_option_value_no_option_type_password_for(LEX_USER * user_arg,const char * password_arg,const char * current_password_arg,bool retain_current,bool random_pass,const POS & expr_pos_arg)985   PT_option_value_no_option_type_password_for(LEX_USER *user_arg,
986                                               const char *password_arg,
987                                               const char *current_password_arg,
988                                               bool retain_current,
989                                               bool random_pass,
990                                               const POS &expr_pos_arg)
991       : user(user_arg),
992         password(password_arg),
993         current_password(current_password_arg),
994         retain_current_password(retain_current),
995         random_password_generator(random_pass),
996         expr_pos(expr_pos_arg) {}
997 
998   bool contextualize(Parse_context *pc) override;
999 };
1000 
1001 class PT_option_value_type : public Parse_tree_node {
1002   typedef Parse_tree_node super;
1003 
1004   enum_var_type type;
1005   PT_option_value_following_option_type *value;
1006 
1007  public:
PT_option_value_type(enum_var_type type_arg,PT_option_value_following_option_type * value_arg)1008   PT_option_value_type(enum_var_type type_arg,
1009                        PT_option_value_following_option_type *value_arg)
1010       : type(type_arg), value(value_arg) {}
1011 
1012   bool contextualize(Parse_context *pc) override;
1013 };
1014 
1015 class PT_option_value_list_head : public Parse_tree_node {
1016   typedef Parse_tree_node super;
1017 
1018   POS delimiter_pos;
1019   Parse_tree_node *value;
1020   POS value_pos;
1021 
1022  public:
PT_option_value_list_head(const POS & delimiter_pos_arg,Parse_tree_node * value_arg,const POS & value_pos_arg)1023   PT_option_value_list_head(const POS &delimiter_pos_arg,
1024                             Parse_tree_node *value_arg,
1025                             const POS &value_pos_arg)
1026       : delimiter_pos(delimiter_pos_arg),
1027         value(value_arg),
1028         value_pos(value_pos_arg) {}
1029 
1030   bool contextualize(Parse_context *pc) override;
1031 };
1032 
1033 class PT_option_value_list : public PT_option_value_list_head {
1034   typedef PT_option_value_list_head super;
1035 
1036   PT_option_value_list_head *head;
1037 
1038  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)1039   PT_option_value_list(PT_option_value_list_head *head_arg,
1040                        const POS &delimiter_pos_arg, Parse_tree_node *tail,
1041                        const POS &tail_pos)
1042       : super(delimiter_pos_arg, tail, tail_pos), head(head_arg) {}
1043 
contextualize(Parse_context * pc)1044   bool contextualize(Parse_context *pc) override {
1045     return head->contextualize(pc) || super::contextualize(pc);
1046   }
1047 };
1048 
1049 class PT_start_option_value_list_no_type : public PT_start_option_value_list {
1050   typedef PT_start_option_value_list super;
1051 
1052   PT_option_value_no_option_type *head;
1053   POS head_pos;
1054   PT_option_value_list_head *tail;
1055 
1056  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)1057   PT_start_option_value_list_no_type(PT_option_value_no_option_type *head_arg,
1058                                      const POS &head_pos_arg,
1059                                      PT_option_value_list_head *tail_arg)
1060       : head(head_arg), head_pos(head_pos_arg), tail(tail_arg) {}
1061 
1062   bool contextualize(Parse_context *pc) override;
1063 };
1064 
1065 class PT_transaction_characteristic : public Parse_tree_node {
1066   typedef Parse_tree_node super;
1067 
1068   const char *name;
1069   int32 value;
1070 
1071  public:
PT_transaction_characteristic(const char * name_arg,int32 value_arg)1072   PT_transaction_characteristic(const char *name_arg, int32 value_arg)
1073       : name(name_arg), value(value_arg) {}
1074 
1075   bool contextualize(Parse_context *pc) override;
1076 };
1077 
1078 class PT_transaction_access_mode : public PT_transaction_characteristic {
1079   typedef PT_transaction_characteristic super;
1080 
1081  public:
PT_transaction_access_mode(bool is_read_only)1082   explicit PT_transaction_access_mode(bool is_read_only)
1083       : super("transaction_read_only", (int32)is_read_only) {}
1084 };
1085 
1086 class PT_isolation_level : public PT_transaction_characteristic {
1087   typedef PT_transaction_characteristic super;
1088 
1089  public:
PT_isolation_level(enum_tx_isolation level)1090   explicit PT_isolation_level(enum_tx_isolation level)
1091       : super("transaction_isolation", (int32)level) {}
1092 };
1093 
1094 class PT_transaction_characteristics : public Parse_tree_node {
1095   typedef Parse_tree_node super;
1096 
1097   PT_transaction_characteristic *head;
1098   PT_transaction_characteristic *opt_tail;
1099 
1100  public:
PT_transaction_characteristics(PT_transaction_characteristic * head_arg,PT_transaction_characteristic * opt_tail_arg)1101   PT_transaction_characteristics(PT_transaction_characteristic *head_arg,
1102                                  PT_transaction_characteristic *opt_tail_arg)
1103       : head(head_arg), opt_tail(opt_tail_arg) {}
1104 
contextualize(Parse_context * pc)1105   bool contextualize(Parse_context *pc) override {
1106     return (super::contextualize(pc) || head->contextualize(pc) ||
1107             (opt_tail != nullptr && opt_tail->contextualize(pc)));
1108   }
1109 };
1110 
1111 class PT_start_option_value_list_transaction
1112     : public PT_start_option_value_list {
1113   typedef PT_start_option_value_list super;
1114 
1115   PT_transaction_characteristics *characteristics;
1116   POS end_pos;
1117 
1118  public:
PT_start_option_value_list_transaction(PT_transaction_characteristics * characteristics_arg,const POS & end_pos_arg)1119   PT_start_option_value_list_transaction(
1120       PT_transaction_characteristics *characteristics_arg,
1121       const POS &end_pos_arg)
1122       : characteristics(characteristics_arg), end_pos(end_pos_arg) {}
1123 
1124   bool contextualize(Parse_context *pc) override;
1125 };
1126 
1127 class PT_start_option_value_list_following_option_type
1128     : public Parse_tree_node {};
1129 
1130 class PT_start_option_value_list_following_option_type_eq
1131     : public PT_start_option_value_list_following_option_type {
1132   typedef PT_start_option_value_list_following_option_type super;
1133 
1134   PT_option_value_following_option_type *head;
1135   POS head_pos;
1136   PT_option_value_list_head *opt_tail;
1137 
1138  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)1139   PT_start_option_value_list_following_option_type_eq(
1140       PT_option_value_following_option_type *head_arg, const POS &head_pos_arg,
1141       PT_option_value_list_head *opt_tail_arg)
1142       : head(head_arg), head_pos(head_pos_arg), opt_tail(opt_tail_arg) {}
1143 
1144   bool contextualize(Parse_context *pc) override;
1145 };
1146 
1147 class PT_start_option_value_list_following_option_type_transaction
1148     : public PT_start_option_value_list_following_option_type {
1149   typedef PT_start_option_value_list_following_option_type super;
1150 
1151   PT_transaction_characteristics *characteristics;
1152   POS characteristics_pos;
1153 
1154  public:
PT_start_option_value_list_following_option_type_transaction(PT_transaction_characteristics * characteristics_arg,const POS & characteristics_pos_arg)1155   PT_start_option_value_list_following_option_type_transaction(
1156       PT_transaction_characteristics *characteristics_arg,
1157       const POS &characteristics_pos_arg)
1158       : characteristics(characteristics_arg),
1159         characteristics_pos(characteristics_pos_arg) {}
1160 
1161   bool contextualize(Parse_context *pc) override;
1162 };
1163 
1164 class PT_start_option_value_list_type : public PT_start_option_value_list {
1165   typedef PT_start_option_value_list super;
1166 
1167   enum_var_type type;
1168   PT_start_option_value_list_following_option_type *list;
1169 
1170  public:
PT_start_option_value_list_type(enum_var_type type_arg,PT_start_option_value_list_following_option_type * list_arg)1171   PT_start_option_value_list_type(
1172       enum_var_type type_arg,
1173       PT_start_option_value_list_following_option_type *list_arg)
1174       : type(type_arg), list(list_arg) {}
1175 
1176   bool contextualize(Parse_context *pc) override;
1177 };
1178 
1179 class PT_set : public Parse_tree_node {
1180   typedef Parse_tree_node super;
1181 
1182   POS set_pos;
1183   PT_start_option_value_list *list;
1184 
1185  public:
PT_set(const POS & set_pos_arg,PT_start_option_value_list * list_arg)1186   PT_set(const POS &set_pos_arg, PT_start_option_value_list *list_arg)
1187       : set_pos(set_pos_arg), list(list_arg) {}
1188 
1189   bool contextualize(Parse_context *pc) override;
1190 };
1191 
1192 class PT_into_destination : public Parse_tree_node {
1193   typedef Parse_tree_node super;
1194   POS m_pos;
1195 
1196  protected:
PT_into_destination(const POS & pos)1197   PT_into_destination(const POS &pos) : m_pos(pos) {}
1198 
1199  public:
1200   bool contextualize(Parse_context *pc) override;
1201 };
1202 
1203 class PT_into_destination_outfile final : public PT_into_destination {
1204   typedef PT_into_destination super;
1205 
1206  public:
PT_into_destination_outfile(const POS & pos,const LEX_STRING & file_name_arg,const CHARSET_INFO * charset_arg,const Field_separators & field_term_arg,const Line_separators & line_term_arg)1207   PT_into_destination_outfile(const POS &pos, const LEX_STRING &file_name_arg,
1208                               const CHARSET_INFO *charset_arg,
1209                               const Field_separators &field_term_arg,
1210                               const Line_separators &line_term_arg)
1211       : PT_into_destination(pos), m_exchange(file_name_arg.str, false) {
1212     m_exchange.cs = charset_arg;
1213     m_exchange.field.merge_field_separators(field_term_arg);
1214     m_exchange.line.merge_line_separators(line_term_arg);
1215   }
1216 
1217   bool contextualize(Parse_context *pc) override;
1218 
1219  private:
1220   sql_exchange m_exchange;
1221 };
1222 
1223 class PT_into_destination_dumpfile final : public PT_into_destination {
1224   typedef PT_into_destination super;
1225 
1226  public:
PT_into_destination_dumpfile(const POS & pos,const LEX_STRING & file_name_arg)1227   PT_into_destination_dumpfile(const POS &pos, const LEX_STRING &file_name_arg)
1228       : PT_into_destination(pos), m_exchange(file_name_arg.str, true) {}
1229 
1230   bool contextualize(Parse_context *pc) override;
1231 
1232  private:
1233   sql_exchange m_exchange;
1234 };
1235 
1236 class PT_select_var : public Parse_tree_node {
1237  public:
1238   const LEX_STRING name;
1239 
PT_select_var(const LEX_STRING & name_arg)1240   explicit PT_select_var(const LEX_STRING &name_arg) : name(name_arg) {}
1241 
is_local()1242   virtual bool is_local() const { return false; }
get_offset()1243   virtual uint get_offset() const {
1244     DBUG_ASSERT(0);
1245     return 0;
1246   }
1247 };
1248 
1249 class PT_select_sp_var : public PT_select_var {
1250   typedef PT_select_var super;
1251 
1252   uint offset;
1253 
1254 #ifndef DBUG_OFF
1255   /*
1256     Routine to which this Item_splocal belongs. Used for checking if correct
1257     runtime context is used for variable handling.
1258   */
1259   sp_head *sp;
1260 #endif
1261 
1262  public:
PT_select_sp_var(const LEX_STRING & name_arg)1263   PT_select_sp_var(const LEX_STRING &name_arg) : super(name_arg) {}
1264 
is_local()1265   bool is_local() const override { return true; }
get_offset()1266   uint get_offset() const override { return offset; }
1267 
1268   bool contextualize(Parse_context *pc) override;
1269 };
1270 
1271 class PT_select_var_list : public PT_into_destination {
1272   typedef PT_into_destination super;
1273 
1274  public:
PT_select_var_list(const POS & pos)1275   explicit PT_select_var_list(const POS &pos) : PT_into_destination(pos) {}
1276 
1277   List<PT_select_var> value;
1278 
1279   bool contextualize(Parse_context *pc) override;
1280 
push_back(PT_select_var * var)1281   bool push_back(PT_select_var *var) { return value.push_back(var); }
1282 };
1283 
1284 /**
1285   Parse tree node for a single of a window extent's borders,
1286   cf. \<window frame extent\> in SQL 2003.
1287 */
1288 class PT_border : public Parse_tree_node {
1289   friend class Window;
1290   Item *m_value{nullptr};  ///< only relevant iff m_border_type == WBT_VALUE_*
1291  public:
1292   enum_window_border_type m_border_type;
1293   const bool m_date_time;
1294   interval_type m_int_type;
1295 
1296   ///< For unbounded border
PT_border(enum_window_border_type type)1297   PT_border(enum_window_border_type type)
1298       : m_border_type(type), m_date_time(false) {
1299     DBUG_ASSERT(type != WBT_VALUE_PRECEDING && type != WBT_VALUE_FOLLOWING);
1300   }
1301 
1302   ///< For bounded non-temporal border, e.g. 2 PRECEDING: 'value' is 2.
PT_border(enum_window_border_type type,Item * value)1303   PT_border(enum_window_border_type type, Item *value)
1304       : m_value(value), m_border_type(type), m_date_time(false) {}
1305 
1306   ///< For bounded INTERVAL 2 DAYS, 'value' is 2, int_type is DAYS.
PT_border(enum_window_border_type type,Item * value,interval_type int_type)1307   PT_border(enum_window_border_type type, Item *value, interval_type int_type)
1308       : m_value(value),
1309         m_border_type(type),
1310         m_date_time(true),
1311         m_int_type(int_type) {}
1312 
1313   ///< @returns the '2' in '2 PRECEDING' or 'INTERVAL 2 DAYS PRECEDING'
border()1314   Item *border() const { return m_value; }
1315   /// Need such low-level access so that fix_fields updates the right pointer
border_ptr()1316   Item **border_ptr() { return &m_value; }
1317 
1318   /**
1319     @returns Addition operator for computation of frames, nullptr if error.
1320     @param  order_expr  Expression to add/substract to
1321     @param  prec    true if PRECEDING
1322     @param  asc     true if ASC
1323     @param  window  only used for error generation
1324   */
1325   Item *build_addop(Item_cache *order_expr, bool prec, bool asc,
1326                     const Window *window);
1327 };
1328 
1329 /**
1330   Parse tree node for one or both of a window extent's borders, cf.
1331   \<window frame extent\> in SQL 2003.
1332 */
1333 class PT_borders : public Parse_tree_node {
1334   PT_border *m_borders[2];
1335   friend class PT_frame;
1336 
1337  public:
1338   /**
1339     Constructor.
1340 
1341     Frames of the form "frame_start no_frame_end" are translated during
1342     parsing to "BETWEEN frame_start AND CURRENT ROW". So both 'start' and
1343     'end' are non-nullptr.
1344   */
PT_borders(PT_border * start,PT_border * end)1345   PT_borders(PT_border *start, PT_border *end) {
1346     m_borders[0] = start;
1347     m_borders[1] = end;
1348   }
1349 };
1350 
1351 /**
1352   Parse tree node for a window frame's exclusions, cf. the
1353   \<window frame exclusion\> clause in SQL 2003.
1354 */
1355 class PT_exclusion : public Parse_tree_node {
1356   enum_window_frame_exclusion m_exclusion;
1357 
1358  public:
PT_exclusion(enum_window_frame_exclusion e)1359   PT_exclusion(enum_window_frame_exclusion e) : m_exclusion(e) {}
1360   // enum_window_frame_exclusion exclusion() { return m_exclusion; }
1361 };
1362 
1363 /**
1364   Parse tree node for a window's frame, cf. the \<window frame clause\>
1365   in SQL 2003.
1366 */
1367 class PT_frame : public Parse_tree_node {
1368  public:
1369   enum_window_frame_unit m_unit;
1370 
1371   PT_border *m_from;
1372   PT_border *m_to;
1373 
1374   PT_exclusion *m_exclusion;
1375 
1376   /// If true, this is an artificial frame, not specified by the user
1377   bool m_originally_absent = false;
1378 
PT_frame(enum_window_frame_unit unit,PT_borders * from_to,PT_exclusion * exclusion)1379   PT_frame(enum_window_frame_unit unit, PT_borders *from_to,
1380            PT_exclusion *exclusion)
1381       : m_unit(unit),
1382         m_from(from_to->m_borders[0]),
1383         m_to(from_to->m_borders[1]),
1384         m_exclusion(exclusion) {}
1385 };
1386 
1387 /**
1388   Parse tree node for a window; just a shallow wrapper for
1389   class Window, q.v.
1390 */
1391 class PT_window : public Parse_tree_node, public Window {
1392   typedef Parse_tree_node super;
1393 
1394  public:
PT_window(PT_order_list * partition_by,PT_order_list * order_by,PT_frame * frame)1395   PT_window(PT_order_list *partition_by, PT_order_list *order_by,
1396             PT_frame *frame)
1397       : Window(partition_by, order_by, frame) {}
1398 
PT_window(PT_order_list * partition_by,PT_order_list * order_by,PT_frame * frame,Item_string * inherit)1399   PT_window(PT_order_list *partition_by, PT_order_list *order_by,
1400             PT_frame *frame, Item_string *inherit)
1401       : Window(partition_by, order_by, frame, inherit) {}
1402 
PT_window(Item_string * name)1403   PT_window(Item_string *name) : Window(name) {}
1404 
1405   bool contextualize(Parse_context *pc) override;
1406 };
1407 
1408 /**
1409   Parse tree node for a list of window definitions corresponding
1410   to a \<window clause\> in SQL 2003.
1411 */
1412 class PT_window_list : public Parse_tree_node {
1413   typedef Parse_tree_node super;
1414   List<Window> m_windows;
1415 
1416  public:
PT_window_list()1417   PT_window_list() {}
1418 
1419   bool contextualize(Parse_context *pc) override;
1420 
push_back(PT_window * w)1421   bool push_back(PT_window *w) { return m_windows.push_back(w); }
1422 };
1423 
1424 class PT_query_primary : public PT_query_expression_body {};
1425 
1426 class PT_query_specification : public PT_query_primary {
1427   typedef PT_query_primary super;
1428 
1429   PT_hint_list *opt_hints;
1430   Query_options options;
1431   PT_item_list *item_list;
1432   PT_into_destination *opt_into1;
1433   const bool m_is_from_clause_implicit;
1434   Mem_root_array_YY<PT_table_reference *> from_clause;  // empty list for DUAL
1435   Item *opt_where_clause;
1436   PT_group *opt_group_clause;
1437   Item *opt_having_clause;
1438   PT_window_list *opt_window_clause;
1439 
1440  public:
PT_query_specification(PT_hint_list * opt_hints_arg,const Query_options & options_arg,PT_item_list * item_list_arg,PT_into_destination * opt_into1_arg,const Mem_root_array_YY<PT_table_reference * > & from_clause_arg,Item * opt_where_clause_arg,PT_group * opt_group_clause_arg,Item * opt_having_clause_arg,PT_window_list * opt_window_clause_arg,bool implicit_from_clause)1441   PT_query_specification(
1442       PT_hint_list *opt_hints_arg, const Query_options &options_arg,
1443       PT_item_list *item_list_arg, PT_into_destination *opt_into1_arg,
1444       const Mem_root_array_YY<PT_table_reference *> &from_clause_arg,
1445       Item *opt_where_clause_arg, PT_group *opt_group_clause_arg,
1446       Item *opt_having_clause_arg, PT_window_list *opt_window_clause_arg,
1447       bool implicit_from_clause)
1448       : opt_hints(opt_hints_arg),
1449         options(options_arg),
1450         item_list(item_list_arg),
1451         opt_into1(opt_into1_arg),
1452         m_is_from_clause_implicit{implicit_from_clause},
1453         from_clause(from_clause_arg),
1454         opt_where_clause(opt_where_clause_arg),
1455         opt_group_clause(opt_group_clause_arg),
1456         opt_having_clause(opt_having_clause_arg),
1457         opt_window_clause(opt_window_clause_arg) {
1458     DBUG_ASSERT(implicit_from_clause ? from_clause.empty() : true);
1459   }
1460 
PT_query_specification(const Query_options & options_arg,PT_item_list * item_list_arg,const Mem_root_array_YY<PT_table_reference * > & from_clause_arg,Item * opt_where_clause_arg)1461   PT_query_specification(
1462       const Query_options &options_arg, PT_item_list *item_list_arg,
1463       const Mem_root_array_YY<PT_table_reference *> &from_clause_arg,
1464       Item *opt_where_clause_arg)
1465       : opt_hints(nullptr),
1466         options(options_arg),
1467         item_list(item_list_arg),
1468         opt_into1(nullptr),
1469         m_is_from_clause_implicit{true},
1470         from_clause(from_clause_arg),
1471         opt_where_clause(opt_where_clause_arg),
1472         opt_group_clause(nullptr),
1473         opt_having_clause(nullptr),
1474         opt_window_clause(nullptr) {}
1475 
PT_query_specification(const Query_options & options_arg,PT_item_list * item_list_arg)1476   PT_query_specification(const Query_options &options_arg,
1477                          PT_item_list *item_list_arg)
1478       : opt_hints(nullptr),
1479         options(options_arg),
1480         item_list(item_list_arg),
1481         opt_into1(nullptr),
1482         m_is_from_clause_implicit{false},
1483         from_clause{},
1484         opt_where_clause(nullptr),
1485         opt_group_clause(nullptr),
1486         opt_having_clause(nullptr),
1487         opt_window_clause(nullptr) {}
1488 
1489   bool contextualize(Parse_context *pc) override;
1490 
has_into_clause()1491   bool has_into_clause() const override { return opt_into1 != nullptr; }
has_trailing_into_clause()1492   bool has_trailing_into_clause() const override {
1493     return (has_into_clause() && is_implicit_from_clause() &&
1494             opt_where_clause == nullptr && opt_group_clause == nullptr &&
1495             opt_having_clause == nullptr && opt_window_clause == nullptr);
1496   }
1497 
is_union()1498   bool is_union() const override { return false; }
1499 
can_absorb_order_and_limit(bool,bool)1500   bool can_absorb_order_and_limit(bool, bool) const override { return true; }
1501 
is_table_value_constructor()1502   bool is_table_value_constructor() const override { return false; }
get_row_value_list()1503   PT_insert_values_list *get_row_value_list() const override { return nullptr; }
1504 
1505  private:
is_implicit_from_clause()1506   bool is_implicit_from_clause() const { return m_is_from_clause_implicit; }
1507 };
1508 
1509 class PT_table_value_constructor : public PT_query_primary {
1510   typedef PT_query_primary super;
1511 
1512   PT_insert_values_list *const row_value_list;
1513 
1514  public:
PT_table_value_constructor(PT_insert_values_list * row_value_list_arg)1515   explicit PT_table_value_constructor(PT_insert_values_list *row_value_list_arg)
1516       : row_value_list(row_value_list_arg) {}
1517 
1518   bool contextualize(Parse_context *pc) override;
1519 
has_into_clause()1520   bool has_into_clause() const override { return false; }
has_trailing_into_clause()1521   bool has_trailing_into_clause() const override { return false; }
1522 
is_union()1523   bool is_union() const override { return false; }
1524 
can_absorb_order_and_limit(bool,bool)1525   bool can_absorb_order_and_limit(bool, bool) const override { return true; }
1526 
is_table_value_constructor()1527   bool is_table_value_constructor() const override { return true; }
1528 
get_row_value_list()1529   PT_insert_values_list *get_row_value_list() const override {
1530     return row_value_list;
1531   }
1532 };
1533 
1534 class PT_explicit_table : public PT_query_specification {
1535   using super = PT_query_specification;
1536 
1537  public:
PT_explicit_table(const Query_options & options_arg,PT_item_list * item_list_arg,const Mem_root_array_YY<PT_table_reference * > & from_clause_arg)1538   PT_explicit_table(
1539       const Query_options &options_arg, PT_item_list *item_list_arg,
1540       const Mem_root_array_YY<PT_table_reference *> &from_clause_arg)
1541       : super(options_arg, item_list_arg, from_clause_arg, nullptr) {}
1542 };
1543 
1544 class PT_query_expression final : public PT_query_primary {
1545  public:
PT_query_expression(PT_with_clause * with_clause,PT_query_expression_body * body,PT_order * order,PT_limit_clause * limit)1546   PT_query_expression(PT_with_clause *with_clause,
1547                       PT_query_expression_body *body, PT_order *order,
1548                       PT_limit_clause *limit)
1549       : m_body(body),
1550         m_order(order),
1551         m_limit(limit),
1552         m_with_clause(with_clause) {}
1553 
PT_query_expression(PT_query_expression_body * body,PT_order * order,PT_limit_clause * limit)1554   PT_query_expression(PT_query_expression_body *body, PT_order *order,
1555                       PT_limit_clause *limit)
1556       : PT_query_expression(nullptr, body, order, limit) {}
1557 
PT_query_expression(PT_query_expression_body * body)1558   explicit PT_query_expression(PT_query_expression_body *body)
1559       : PT_query_expression(body, nullptr, nullptr) {}
1560 
1561   bool contextualize(Parse_context *pc) override;
1562 
is_union()1563   bool is_union() const override { return m_body->is_union(); }
1564 
has_into_clause()1565   bool has_into_clause() const override { return m_body->has_into_clause(); }
has_trailing_into_clause()1566   bool has_trailing_into_clause() const override {
1567     return (m_body->has_trailing_into_clause() && m_order == nullptr &&
1568             m_limit == nullptr);
1569   }
1570 
can_absorb_order_and_limit(bool order,bool limit)1571   bool can_absorb_order_and_limit(bool order, bool limit) const override {
1572     if (m_body->is_union()) {
1573       return false;
1574     }
1575     if (m_order == nullptr && m_limit == nullptr) {
1576       /*
1577         It is safe to push ORDER and/or LIMIT down in:
1578 
1579           (SELECT ...<no order or limit clauses>) ORDER BY ... LIMIT ...;
1580           (SELECT ...<no order or limit clauses>) ORDER BY ...;
1581           (SELECT ...<no order or limit clauses>)              LIMIT ...;
1582       */
1583       return true;
1584     }
1585     if (m_limit != nullptr && !order && limit) {
1586       /*
1587         In MySQL, it is ok(*) to push LIMIT down in:
1588 
1589           (SELECT ... [ORDER BY ...] LIMIT a) LIMIT b;
1590 
1591         *) MySQL doesn't follow the standard when overwriting `LIMIT a` with
1592            `LIMIT b` if a < b.  Moreover, the result of:
1593 
1594              (SELECT ... ORDER BY order1 LIMIT a) ORDER BY order1 LIMIT b; (1)
1595 
1596            can diverge from:
1597 
1598              (SELECT ... ORDER BY order1 LIMIT a) LIMIT b;                  (2)
1599 
1600            since the example (1) never overwrites `LIMIT a` with `LIMIT b`,
1601            while the example (2) does overwrite.
1602 
1603            TODO: add a warning, deprecate and replace this behavior with the
1604                  standard one.
1605       */
1606       return true;
1607     }
1608     return false;
1609   }
1610 
is_table_value_constructor()1611   bool is_table_value_constructor() const override {
1612     return m_body->is_table_value_constructor();
1613   }
1614 
get_row_value_list()1615   PT_insert_values_list *get_row_value_list() const override {
1616     return m_body->get_row_value_list();
1617   }
1618 
1619  private:
1620   /**
1621     Contextualizes the order and limit clauses, re-interpreting them according
1622     to the rules. If the `<query expression body>` can absorb the clauses,
1623     they are simply contextualized into the current SELECT_LEX. If not, we
1624     have to create the "fake" SELECT_LEX unless there is one already
1625     (SELECT_LEX_UNIT::new_union_query() is known to do this.)
1626 
1627     @see PT_query_expression::can_absorb_order_and_limit()
1628   */
1629   bool contextualize_order_and_limit(Parse_context *pc);
1630 
1631   PT_query_expression_body *m_body;
1632   PT_order *m_order;
1633   PT_limit_clause *m_limit;
1634   PT_with_clause *m_with_clause;
1635 };
1636 
1637 /*
1638   After the removal of the `... <locking_clause> <into_clause>` syntax
1639   PT_locking will disappear.
1640 */
1641 class PT_locking final : public PT_query_primary {
1642   using super = PT_query_primary;
1643 
1644  public:
PT_locking(PT_query_expression_body * qe,PT_locking_clause_list * locking_clauses)1645   PT_locking(PT_query_expression_body *qe,
1646              PT_locking_clause_list *locking_clauses)
1647       : m_query_expression{qe}, m_locking_clauses{locking_clauses} {}
1648 
contextualize(Parse_context * pc)1649   bool contextualize(Parse_context *pc) override {
1650     return (super::contextualize(pc) || m_query_expression->contextualize(pc) ||
1651             m_locking_clauses->contextualize(pc));
1652   }
1653 
is_union()1654   bool is_union() const override { return m_query_expression->is_union(); }
1655 
has_into_clause()1656   bool has_into_clause() const override {
1657     return m_query_expression->has_into_clause();
1658   }
has_trailing_into_clause()1659   bool has_trailing_into_clause() const override { return false; }
1660 
can_absorb_order_and_limit(bool order,bool limit)1661   bool can_absorb_order_and_limit(bool order, bool limit) const override {
1662     return m_query_expression->can_absorb_order_and_limit(order, limit);
1663   }
1664 
is_table_value_constructor()1665   bool is_table_value_constructor() const override {
1666     return m_query_expression->is_table_value_constructor();
1667   }
1668 
get_row_value_list()1669   PT_insert_values_list *get_row_value_list() const override {
1670     return m_query_expression->get_row_value_list();
1671   }
1672 
1673  private:
1674   PT_query_expression_body *const m_query_expression;
1675   PT_locking_clause_list *const m_locking_clauses;
1676 };
1677 
1678 class PT_subquery : public Parse_tree_node {
1679   typedef Parse_tree_node super;
1680 
1681   PT_query_primary *qe;
1682   POS pos;
1683   SELECT_LEX *select_lex;
1684 
1685  public:
1686   bool m_is_derived_table;
1687 
PT_subquery(POS p,PT_query_primary * query_expression)1688   PT_subquery(POS p, PT_query_primary *query_expression)
1689       : qe(query_expression),
1690         pos(p),
1691         select_lex(nullptr),
1692         m_is_derived_table(false) {}
1693 
1694   bool contextualize(Parse_context *pc) override;
1695 
value()1696   SELECT_LEX *value() { return select_lex; }
1697 };
1698 
1699 class PT_union : public PT_query_expression_body {
1700  public:
1701   PT_union(PT_query_expression_body *lhs, const POS &lhs_pos, bool is_distinct,
1702            PT_query_primary *rhs, bool is_rhs_in_parentheses = false)
m_lhs(lhs)1703       : m_lhs(lhs),
1704         m_lhs_pos(lhs_pos),
1705         m_is_distinct(is_distinct),
1706         m_rhs(rhs),
1707         m_is_rhs_in_parentheses{is_rhs_in_parentheses} {}
1708 
1709   bool contextualize(Parse_context *pc) override;
1710 
is_union()1711   bool is_union() const override { return true; }
1712 
has_into_clause()1713   bool has_into_clause() const override {
1714     return m_lhs->has_into_clause() || m_rhs->has_into_clause();
1715   }
has_trailing_into_clause()1716   bool has_trailing_into_clause() const override {
1717     return !m_is_rhs_in_parentheses && m_rhs->has_trailing_into_clause();
1718   }
1719 
can_absorb_order_and_limit(bool,bool)1720   bool can_absorb_order_and_limit(bool, bool) const override { return false; }
1721 
is_table_value_constructor()1722   bool is_table_value_constructor() const override { return false; }
get_row_value_list()1723   PT_insert_values_list *get_row_value_list() const override { return nullptr; }
1724 
1725  private:
1726   PT_query_expression_body *m_lhs;
1727   POS m_lhs_pos;
1728   bool m_is_distinct;
1729   PT_query_primary *m_rhs;
1730   PT_into_destination *m_into;
1731   const bool m_is_rhs_in_parentheses;
1732 };
1733 
1734 class PT_select_stmt : public Parse_tree_root {
1735   typedef Parse_tree_root super;
1736 
1737  public:
1738   /**
1739     @param qe The query expression.
1740     @param sql_command The type of SQL command.
1741   */
PT_select_stmt(enum_sql_command sql_command,PT_query_expression_body * qe)1742   PT_select_stmt(enum_sql_command sql_command, PT_query_expression_body *qe)
1743       : m_sql_command(sql_command),
1744         m_qe(qe),
1745         m_into(nullptr),
1746         m_has_trailing_locking_clauses{false} {}
1747 
1748   /**
1749     Creates a SELECT command. Only SELECT commands can have into.
1750 
1751     @param qe                           The query expression.
1752     @param into                         The own INTO destination.
1753     @param has_trailing_locking_clauses True if there are locking clauses (like
1754                                         `FOR UPDATE`) at the end of the
1755                                         statement.
1756   */
1757   explicit PT_select_stmt(PT_query_expression_body *qe,
1758                           PT_into_destination *into = nullptr,
1759                           bool has_trailing_locking_clauses = false)
1760       : m_sql_command{SQLCOM_SELECT},
1761         m_qe{qe},
1762         m_into{into},
1763         m_has_trailing_locking_clauses{has_trailing_locking_clauses} {}
1764 
1765   Sql_cmd *make_cmd(THD *thd) override;
1766 
1767  private:
1768   enum_sql_command m_sql_command;
1769   PT_query_expression_body *m_qe;
1770   PT_into_destination *m_into;
1771   const bool m_has_trailing_locking_clauses;
1772 };
1773 
1774 /**
1775   Top-level node for the DELETE statement
1776 
1777   @ingroup ptn_stmt
1778 */
1779 class PT_delete final : public Parse_tree_root {
1780  private:
1781   PT_with_clause *m_with_clause;
1782   PT_hint_list *opt_hints;
1783   const int opt_delete_options;
1784   Table_ident *table_ident;
1785   const char *const opt_table_alias;
1786   Mem_root_array_YY<Table_ident *> table_list;
1787   List<String> *opt_use_partition;
1788   Mem_root_array_YY<PT_table_reference *> join_table_list;
1789   Item *opt_where_clause;
1790   PT_order *opt_order_clause;
1791   Item *opt_delete_limit_clause;
1792   SQL_I_List<TABLE_LIST> delete_tables;
1793 
1794  public:
1795   // single-table DELETE node constructor:
PT_delete(PT_with_clause * with_clause_arg,PT_hint_list * opt_hints_arg,int opt_delete_options_arg,Table_ident * table_ident_arg,const LEX_CSTRING & opt_table_alias_arg,List<String> * opt_use_partition_arg,Item * opt_where_clause_arg,PT_order * opt_order_clause_arg,Item * opt_delete_limit_clause_arg)1796   PT_delete(PT_with_clause *with_clause_arg, PT_hint_list *opt_hints_arg,
1797             int opt_delete_options_arg, Table_ident *table_ident_arg,
1798             const LEX_CSTRING &opt_table_alias_arg,
1799             List<String> *opt_use_partition_arg, Item *opt_where_clause_arg,
1800             PT_order *opt_order_clause_arg, Item *opt_delete_limit_clause_arg)
1801       : m_with_clause(with_clause_arg),
1802         opt_hints(opt_hints_arg),
1803         opt_delete_options(opt_delete_options_arg),
1804         table_ident(table_ident_arg),
1805         opt_table_alias(opt_table_alias_arg.str),
1806         opt_use_partition(opt_use_partition_arg),
1807         opt_where_clause(opt_where_clause_arg),
1808         opt_order_clause(opt_order_clause_arg),
1809         opt_delete_limit_clause(opt_delete_limit_clause_arg) {
1810     table_list.init_empty_const();
1811     join_table_list.init_empty_const();
1812   }
1813 
1814   // multi-table DELETE node constructor:
PT_delete(PT_with_clause * with_clause_arg,PT_hint_list * opt_hints_arg,int opt_delete_options_arg,const Mem_root_array_YY<Table_ident * > & table_list_arg,const Mem_root_array_YY<PT_table_reference * > & join_table_list_arg,Item * opt_where_clause_arg)1815   PT_delete(PT_with_clause *with_clause_arg, PT_hint_list *opt_hints_arg,
1816             int opt_delete_options_arg,
1817             const Mem_root_array_YY<Table_ident *> &table_list_arg,
1818             const Mem_root_array_YY<PT_table_reference *> &join_table_list_arg,
1819             Item *opt_where_clause_arg)
1820       : m_with_clause(with_clause_arg),
1821         opt_hints(opt_hints_arg),
1822         opt_delete_options(opt_delete_options_arg),
1823         table_ident(nullptr),
1824         opt_table_alias(nullptr),
1825         table_list(table_list_arg),
1826         opt_use_partition(nullptr),
1827         join_table_list(join_table_list_arg),
1828         opt_where_clause(opt_where_clause_arg),
1829         opt_order_clause(nullptr),
1830         opt_delete_limit_clause(nullptr) {}
1831 
1832   Sql_cmd *make_cmd(THD *thd) override;
1833 
1834  private:
is_multitable()1835   bool is_multitable() const {
1836     DBUG_ASSERT((table_ident != nullptr) ^ (table_list.size() > 0));
1837     return table_ident == nullptr;
1838   }
1839 
1840   bool add_table(Parse_context *pc, Table_ident *table);
1841 };
1842 
1843 /**
1844   Top-level node for the UPDATE statement
1845 
1846   @ingroup ptn_stmt
1847 */
1848 class PT_update : public Parse_tree_root {
1849   PT_with_clause *m_with_clause;
1850   PT_hint_list *opt_hints;
1851   thr_lock_type opt_low_priority;
1852   bool opt_ignore;
1853   Mem_root_array_YY<PT_table_reference *> join_table_list;
1854   PT_item_list *column_list;
1855   PT_item_list *value_list;
1856   Item *opt_where_clause;
1857   PT_order *opt_order_clause;
1858   Item *opt_limit_clause;
1859 
1860  public:
PT_update(PT_with_clause * with_clause_arg,PT_hint_list * opt_hints_arg,thr_lock_type opt_low_priority_arg,bool opt_ignore_arg,const Mem_root_array_YY<PT_table_reference * > & 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)1861   PT_update(PT_with_clause *with_clause_arg, PT_hint_list *opt_hints_arg,
1862             thr_lock_type opt_low_priority_arg, bool opt_ignore_arg,
1863             const Mem_root_array_YY<PT_table_reference *> &join_table_list_arg,
1864             PT_item_list *column_list_arg, PT_item_list *value_list_arg,
1865             Item *opt_where_clause_arg, PT_order *opt_order_clause_arg,
1866             Item *opt_limit_clause_arg)
1867       : m_with_clause(with_clause_arg),
1868         opt_hints(opt_hints_arg),
1869         opt_low_priority(opt_low_priority_arg),
1870         opt_ignore(opt_ignore_arg),
1871         join_table_list(join_table_list_arg),
1872         column_list(column_list_arg),
1873         value_list(value_list_arg),
1874         opt_where_clause(opt_where_clause_arg),
1875         opt_order_clause(opt_order_clause_arg),
1876         opt_limit_clause(opt_limit_clause_arg) {}
1877 
1878   Sql_cmd *make_cmd(THD *thd) override;
1879 };
1880 
1881 class PT_insert_values_list : public Parse_tree_node {
1882   typedef Parse_tree_node super;
1883 
1884   List<List_item> many_values;
1885 
1886  public:
1887   bool contextualize(Parse_context *pc) override;
1888 
push_back(List<Item> * x)1889   bool push_back(List<Item> *x) { return many_values.push_back(x); }
1890 
get_many_values()1891   virtual List<List_item> &get_many_values() {
1892     DBUG_ASSERT(is_contextualized());
1893     return many_values;
1894   }
1895 };
1896 
1897 /**
1898   Top-level node for the INSERT statement
1899 
1900   @ingroup ptn_stmt
1901 */
1902 class PT_insert final : public Parse_tree_root {
1903   const bool is_replace;
1904   PT_hint_list *opt_hints;
1905   const thr_lock_type lock_option;
1906   const bool ignore;
1907   Table_ident *const table_ident;
1908   List<String> *const opt_use_partition;
1909   PT_item_list *const column_list;
1910   PT_insert_values_list *row_value_list;
1911   PT_query_primary *insert_query_expression;
1912   const char *const opt_values_table_alias;
1913   Create_col_name_list *const opt_values_column_list;
1914   PT_item_list *const opt_on_duplicate_column_list;
1915   PT_item_list *const opt_on_duplicate_value_list;
1916 
1917  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_query_primary * insert_query_expression_arg,const LEX_CSTRING & opt_values_table_alias_arg,Create_col_name_list * opt_values_column_list_arg,PT_item_list * opt_on_duplicate_column_list_arg,PT_item_list * opt_on_duplicate_value_list_arg)1918   PT_insert(bool is_replace_arg, PT_hint_list *opt_hints_arg,
1919             thr_lock_type lock_option_arg, bool ignore_arg,
1920             Table_ident *table_ident_arg, List<String> *opt_use_partition_arg,
1921             PT_item_list *column_list_arg,
1922             PT_insert_values_list *row_value_list_arg,
1923             PT_query_primary *insert_query_expression_arg,
1924             const LEX_CSTRING &opt_values_table_alias_arg,
1925             Create_col_name_list *opt_values_column_list_arg,
1926             PT_item_list *opt_on_duplicate_column_list_arg,
1927             PT_item_list *opt_on_duplicate_value_list_arg)
1928       : is_replace(is_replace_arg),
1929         opt_hints(opt_hints_arg),
1930         lock_option(lock_option_arg),
1931         ignore(ignore_arg),
1932         table_ident(table_ident_arg),
1933         opt_use_partition(opt_use_partition_arg),
1934         column_list(column_list_arg),
1935         row_value_list(row_value_list_arg),
1936         insert_query_expression(insert_query_expression_arg),
1937         opt_values_table_alias(opt_values_table_alias_arg.str),
1938         opt_values_column_list(opt_values_column_list_arg),
1939         opt_on_duplicate_column_list(opt_on_duplicate_column_list_arg),
1940         opt_on_duplicate_value_list(opt_on_duplicate_value_list_arg) {
1941     // REPLACE statement can't have IGNORE flag:
1942     DBUG_ASSERT(!is_replace || !ignore);
1943     // REPLACE statement can't have ON DUPLICATE KEY UPDATE clause:
1944     DBUG_ASSERT(!is_replace || opt_on_duplicate_column_list == nullptr);
1945     // INSERT/REPLACE ... SELECT can't have VALUES clause:
1946     DBUG_ASSERT((row_value_list != nullptr) ^
1947                 (insert_query_expression != nullptr));
1948     // ON DUPLICATE KEY UPDATE: column and value arrays must have same sizes:
1949     DBUG_ASSERT((opt_on_duplicate_column_list == nullptr &&
1950                  opt_on_duplicate_value_list == nullptr) ||
1951                 (opt_on_duplicate_column_list->elements() ==
1952                  opt_on_duplicate_value_list->elements()));
1953   }
1954 
1955   Sql_cmd *make_cmd(THD *thd) override;
1956 
1957  private:
has_select()1958   bool has_select() const { return insert_query_expression != nullptr; }
1959 };
1960 
1961 class PT_call final : public Parse_tree_root {
1962   sp_name *proc_name;
1963   PT_item_list *opt_expr_list;
1964 
1965  public:
PT_call(sp_name * proc_name_arg,PT_item_list * opt_expr_list_arg)1966   PT_call(sp_name *proc_name_arg, PT_item_list *opt_expr_list_arg)
1967       : proc_name(proc_name_arg), opt_expr_list(opt_expr_list_arg) {}
1968 
1969   Sql_cmd *make_cmd(THD *thd) override;
1970 };
1971 
1972 /**
1973   Top-level node for the SHUTDOWN statement
1974 
1975   @ingroup ptn_stmt
1976 */
1977 class PT_shutdown final : public Parse_tree_root {
1978   Sql_cmd_shutdown sql_cmd;
1979 
1980  public:
make_cmd(THD *)1981   Sql_cmd *make_cmd(THD *) override { return &sql_cmd; }
1982 };
1983 
1984 /**
1985   Top-level node for the CREATE [OR REPLACE] SPATIAL REFERENCE SYSTEM statement.
1986 
1987   @ingroup ptn_stmt
1988 */
1989 class PT_create_srs final : public Parse_tree_root {
1990   /// The SQL command object.
1991   Sql_cmd_create_srs sql_cmd;
1992   /// Whether OR REPLACE is specified.
1993   bool m_or_replace;
1994   /// Whether IF NOT EXISTS is specified.
1995   bool m_if_not_exists;
1996   /// SRID of the SRS to create.
1997   ///
1998   /// The range is larger than that of gis::srid_t, so it must be
1999   /// verified to be less than the uint32 maximum value.
2000   unsigned long long m_srid;
2001   /// All attributes except SRID.
2002   const Sql_cmd_srs_attributes m_attributes;
2003 
2004   /// Check if a UTF-8 string contains control characters.
2005   ///
2006   /// @note This function only checks single byte control characters (U+0000 to
2007   /// U+001F, and U+007F). There are some control characters at U+0080 to U+00A0
2008   /// that are not detected by this function.
2009   ///
2010   /// @param str The string.
2011   /// @param length Length of the string.
2012   ///
2013   /// @retval false The string contains no control characters.
2014   /// @retval true The string contains at least one control character.
contains_control_char(char * str,size_t length)2015   bool contains_control_char(char *str, size_t length) {
2016     for (size_t pos = 0; pos < length; pos++) {
2017       if (std::iscntrl(str[pos])) return true;
2018     }
2019     return false;
2020   }
2021 
2022  public:
PT_create_srs(unsigned long long srid,const Sql_cmd_srs_attributes & attributes,bool or_replace,bool if_not_exists)2023   PT_create_srs(unsigned long long srid,
2024                 const Sql_cmd_srs_attributes &attributes, bool or_replace,
2025                 bool if_not_exists)
2026       : m_or_replace(or_replace),
2027         m_if_not_exists(if_not_exists),
2028         m_srid(srid),
2029         m_attributes(attributes) {}
2030 
2031   Sql_cmd *make_cmd(THD *thd) override;
2032 };
2033 
2034 /**
2035   Top-level node for the DROP SPATIAL REFERENCE SYSTEM statement.
2036 
2037   @ingroup ptn_stmt
2038 */
2039 class PT_drop_srs final : public Parse_tree_root {
2040   /// The SQL command object.
2041   Sql_cmd_drop_srs sql_cmd;
2042   /// SRID of the SRS to drop.
2043   ///
2044   /// The range is larger than that of gis::srid_t, so it must be
2045   /// verified to be less than the uint32 maximum value.
2046   unsigned long long m_srid;
2047 
2048  public:
PT_drop_srs(unsigned long long srid,bool if_exists)2049   PT_drop_srs(unsigned long long srid, bool if_exists)
2050       : sql_cmd(srid, if_exists), m_srid(srid) {}
2051 
2052   Sql_cmd *make_cmd(THD *thd) override;
2053 };
2054 
2055 /**
2056   Top-level node for the ALTER INSTANCE statement
2057 
2058   @ingroup ptn_stmt
2059 */
2060 class PT_alter_instance final : public Parse_tree_root {
2061   Sql_cmd_alter_instance sql_cmd;
2062 
2063  public:
PT_alter_instance(enum alter_instance_action_enum alter_instance_action,const LEX_CSTRING & channel)2064   explicit PT_alter_instance(
2065       enum alter_instance_action_enum alter_instance_action,
2066       const LEX_CSTRING &channel)
2067       : sql_cmd(alter_instance_action, channel) {}
2068 
2069   Sql_cmd *make_cmd(THD *thd) override;
2070 };
2071 
2072 /**
2073   A template-free base class for index options that we can predeclare in
2074   sql_lex.h
2075 */
2076 class PT_base_index_option : public Table_ddl_node {};
2077 
2078 /**
2079   A key part specification.
2080 
2081   This can either be a "normal" key part (a key part that points to a column),
2082   or this can be a functional key part (a key part that points to an
2083   expression).
2084 */
2085 class PT_key_part_specification : public Parse_tree_node {
2086   typedef Parse_tree_node super;
2087 
2088  public:
2089   /**
2090     Constructor for a functional key part.
2091 
2092     @param expression The expression to index.
2093     @param order The direction of the index.
2094   */
2095   PT_key_part_specification(Item *expression, enum_order order);
2096 
2097   /**
2098     Constructor for a "normal" key part. That is a key part that points to a
2099     column and not an expression.
2100 
2101     @param column_name The column name that this key part points to.
2102     @param order The direction of the index.
2103     @param prefix_length How many bytes or characters this key part should
2104            index, or zero if it should index the entire column.
2105   */
2106   PT_key_part_specification(const LEX_CSTRING &column_name, enum_order order,
2107                             int prefix_length);
2108 
2109   /**
2110     Contextualize this key part specification. This will also call itemize on
2111     the indexed expression if this is a functional key part.
2112 
2113     @param pc The parse context
2114 
2115     @retval true on error
2116     @retval false on success
2117   */
2118   bool contextualize(Parse_context *pc) override;
2119 
2120   /**
2121     Get the indexed expression. The caller must ensure that has_expression()
2122     returns true before calling this.
2123 
2124     @returns The indexed expression
2125   */
get_expression()2126   Item *get_expression() const {
2127     DBUG_ASSERT(has_expression());
2128     return m_expression;
2129   }
2130 
2131   /**
2132     @returns The direction of the index: ORDER_ASC, ORDER_DESC or
2133              ORDER_NOT_RELEVANT in case the user didn't explicitly specify a
2134              direction.
2135   */
get_order()2136   enum_order get_order() const { return m_order; }
2137 
2138   /**
2139     @retval true if the user explicitly specified a direction (asc/desc).
2140     @retval false if the user didn't explicitly specify a direction.
2141   */
is_explicit()2142   bool is_explicit() const { return get_order() != ORDER_NOT_RELEVANT; }
2143 
2144   /**
2145     @retval true if the key part contains an expression (and thus is a
2146             functional key part).
2147     @retval false if the key part doesn't contain an expression.
2148   */
has_expression()2149   bool has_expression() const { return m_expression != nullptr; }
2150 
2151   /**
2152     Get the column that this key part points to. This is only valid if this
2153     key part isn't a functional index. The caller must thus check the return
2154     value of has_expression() before calling this function.
2155 
2156     @returns The column that this key part points to.
2157   */
get_column_name()2158   LEX_CSTRING get_column_name() const {
2159     DBUG_ASSERT(!has_expression());
2160     return m_column_name;
2161   }
2162 
2163   /**
2164     @returns The number of bytes that this key part should index. If the column
2165              this key part points to is a non-binary column, this is the number
2166              of characters. Returns zero if the entire column should be indexed.
2167   */
get_prefix_length()2168   int get_prefix_length() const { return m_prefix_length; }
2169 
2170  private:
2171   /**
2172     The indexed expression in case this is a functional key part. Only valid if
2173     has_expression() returns true.
2174   */
2175   Item *m_expression;
2176 
2177   /// The direction of the index.
2178   enum_order m_order;
2179 
2180   /// The name of the column that this key part indexes.
2181   LEX_CSTRING m_column_name;
2182 
2183   /**
2184     If this is greater than zero, it represents how many bytes of the column
2185     that is indexed. Note that for non-binary columns (VARCHAR, TEXT etc), this
2186     is the number of characters.
2187   */
2188   int m_prefix_length;
2189 };
2190 
2191 /**
2192   A template for options that set a single `<alter option>` value in
2193   thd->lex->key_create_info.
2194 
2195   @tparam Option_type The data type of the option.
2196   @tparam Property Pointer-to-member for the option of KEY_CREATE_INFO.
2197 */
2198 template <typename Option_type, Option_type KEY_CREATE_INFO::*Property>
2199 class PT_index_option : public PT_base_index_option {
2200  public:
2201   /// @param option_value The value of the option.
PT_index_option(Option_type option_value)2202   PT_index_option(Option_type option_value) : m_option_value(option_value) {}
2203 
contextualize(Table_ddl_parse_context * pc)2204   bool contextualize(Table_ddl_parse_context *pc) override {
2205     pc->key_create_info->*Property = m_option_value;
2206     return false;
2207   }
2208 
2209  private:
2210   Option_type m_option_value;
2211 };
2212 
2213 /**
2214   A template for options that set a single property in a KEY_CREATE_INFO, and
2215   also records if the option was explicitly set.
2216 */
2217 template <typename Option_type, Option_type KEY_CREATE_INFO::*Property,
2218           bool KEY_CREATE_INFO::*Property_is_explicit>
2219 class PT_traceable_index_option : public PT_base_index_option {
2220  public:
PT_traceable_index_option(Option_type option_value)2221   PT_traceable_index_option(Option_type option_value)
2222       : m_option_value(option_value) {}
2223 
contextualize(Table_ddl_parse_context * pc)2224   bool contextualize(Table_ddl_parse_context *pc) override {
2225     pc->key_create_info->*Property = m_option_value;
2226     pc->key_create_info->*Property_is_explicit = true;
2227     return false;
2228   }
2229 
2230  private:
2231   Option_type m_option_value;
2232 };
2233 
2234 typedef Mem_root_array_YY<PT_base_index_option *> Index_options;
2235 typedef PT_index_option<ulong, &KEY_CREATE_INFO::block_size> PT_block_size;
2236 typedef PT_index_option<LEX_CSTRING, &KEY_CREATE_INFO::comment>
2237     PT_index_comment;
2238 typedef PT_index_option<LEX_CSTRING, &KEY_CREATE_INFO::parser_name>
2239     PT_fulltext_index_parser_name;
2240 typedef PT_index_option<bool, &KEY_CREATE_INFO::is_visible> PT_index_visibility;
2241 
2242 /**
2243   The data structure (B-tree, Hash, etc) used for an index is called
2244   'index_type' in the manual. Internally, this is stored in
2245   KEY_CREATE_INFO::algorithm, while what the manual calls 'algorithm' is
2246   stored in partition_info::key_algorithm. In an `<create_index_stmt>`
2247   it's ignored. The terminology is somewhat confusing, but we stick to the
2248   manual in the parser.
2249 */
2250 typedef PT_traceable_index_option<ha_key_alg, &KEY_CREATE_INFO::algorithm,
2251                                   &KEY_CREATE_INFO::is_algorithm_explicit>
2252     PT_index_type;
2253 
2254 class PT_create_index_stmt final : public PT_table_ddl_stmt_base {
2255  public:
PT_create_index_stmt(MEM_ROOT * mem_root,keytype type_par,const LEX_STRING & name_arg,PT_base_index_option * type,Table_ident * table_ident,List<PT_key_part_specification> * cols,Index_options options,Alter_info::enum_alter_table_algorithm algo,Alter_info::enum_alter_table_lock lock)2256   PT_create_index_stmt(MEM_ROOT *mem_root, keytype type_par,
2257                        const LEX_STRING &name_arg, PT_base_index_option *type,
2258                        Table_ident *table_ident,
2259                        List<PT_key_part_specification> *cols,
2260                        Index_options options,
2261                        Alter_info::enum_alter_table_algorithm algo,
2262                        Alter_info::enum_alter_table_lock lock)
2263       : PT_table_ddl_stmt_base(mem_root),
2264         m_keytype(type_par),
2265         m_name(name_arg),
2266         m_type(type),
2267         m_table_ident(table_ident),
2268         m_columns(cols),
2269         m_options(options),
2270         m_algo(algo),
2271         m_lock(lock) {}
2272 
2273   Sql_cmd *make_cmd(THD *thd) override;
2274 
2275  private:
2276   keytype m_keytype;
2277   LEX_STRING m_name;
2278   PT_base_index_option *m_type;
2279   Table_ident *m_table_ident;
2280   List<PT_key_part_specification> *m_columns;
2281   Index_options m_options;
2282   const Alter_info::enum_alter_table_algorithm m_algo;
2283   const Alter_info::enum_alter_table_lock m_lock;
2284 };
2285 
2286 /**
2287   Base class for column/constraint definitions in CREATE %TABLE
2288 
2289   @ingroup ptn_create_table_stuff
2290 */
2291 class PT_table_element : public Table_ddl_node {};
2292 
2293 class PT_table_constraint_def : public PT_table_element {};
2294 
2295 class PT_inline_index_definition : public PT_table_constraint_def {
2296   typedef PT_table_constraint_def super;
2297 
2298  public:
PT_inline_index_definition(keytype type_par,const LEX_STRING & name_arg,PT_base_index_option * type,List<PT_key_part_specification> * cols,Index_options options)2299   PT_inline_index_definition(keytype type_par, const LEX_STRING &name_arg,
2300                              PT_base_index_option *type,
2301                              List<PT_key_part_specification> *cols,
2302                              Index_options options)
2303       : m_keytype(type_par),
2304         m_name(name_arg),
2305         m_type(type),
2306         m_columns(cols),
2307         m_options(options) {}
2308 
2309   bool contextualize(Table_ddl_parse_context *pc) override;
2310 
2311  private:
2312   keytype m_keytype;
2313   const LEX_STRING m_name;
2314   PT_base_index_option *m_type;
2315   List<PT_key_part_specification> *m_columns;
2316   Index_options m_options;
2317 };
2318 
2319 class PT_foreign_key_definition : public PT_table_constraint_def {
2320   typedef PT_table_constraint_def super;
2321 
2322  public:
PT_foreign_key_definition(const LEX_STRING & constraint_name,const LEX_STRING & key_name,List<PT_key_part_specification> * columns,Table_ident * referenced_table,List<Key_part_spec> * ref_list,fk_match_opt fk_match_option,fk_option fk_update_opt,fk_option fk_delete_opt)2323   PT_foreign_key_definition(const LEX_STRING &constraint_name,
2324                             const LEX_STRING &key_name,
2325                             List<PT_key_part_specification> *columns,
2326                             Table_ident *referenced_table,
2327                             List<Key_part_spec> *ref_list,
2328                             fk_match_opt fk_match_option,
2329                             fk_option fk_update_opt, fk_option fk_delete_opt)
2330       : m_constraint_name(constraint_name),
2331         m_key_name(key_name),
2332         m_columns(columns),
2333         m_referenced_table(referenced_table),
2334         m_ref_list(ref_list),
2335         m_fk_match_option(fk_match_option),
2336         m_fk_update_opt(fk_update_opt),
2337         m_fk_delete_opt(fk_delete_opt) {}
2338 
2339   bool contextualize(Table_ddl_parse_context *pc) override;
2340 
2341  private:
2342   const LEX_STRING m_constraint_name;
2343   const LEX_STRING m_key_name;
2344   List<PT_key_part_specification> *m_columns;
2345   Table_ident *m_referenced_table;
2346   List<Key_part_spec> *m_ref_list;
2347   fk_match_opt m_fk_match_option;
2348   fk_option m_fk_update_opt;
2349   fk_option m_fk_delete_opt;
2350 };
2351 
2352 /**
2353   Common base class for CREATE TABLE and ALTER TABLE option nodes
2354 
2355   @ingroup ptn_create_or_alter_table_options
2356 */
2357 class PT_ddl_table_option : public Table_ddl_node {
2358  public:
2359   ~PT_ddl_table_option() override = 0;  // Force abstract class declaration
2360 
is_rename_table()2361   virtual bool is_rename_table() const { return false; }
2362 };
2363 
~PT_ddl_table_option()2364 inline PT_ddl_table_option::~PT_ddl_table_option() {}
2365 
2366 /**
2367   Base class for CREATE TABLE option nodes
2368 
2369   @ingroup ptn_create_or_alter_table_options
2370 */
2371 class PT_create_table_option : public PT_ddl_table_option {
2372   typedef PT_ddl_table_option super;
2373 
2374  public:
2375   ~PT_create_table_option() override = 0;  // Force abstract class declaration
2376 
contextualize(Table_ddl_parse_context * pc)2377   bool contextualize(Table_ddl_parse_context *pc) override {
2378     if (super::contextualize(pc)) return true;
2379     pc->alter_info->flags |= Alter_info::ALTER_OPTIONS;
2380     return false;
2381   }
2382 };
2383 
~PT_create_table_option()2384 inline PT_create_table_option::~PT_create_table_option() {}
2385 
2386 /**
2387   A template for options that set a single property in HA_CREATE_INFO, and
2388   also records if the option was explicitly set.
2389 */
2390 template <typename Option_type, Option_type HA_CREATE_INFO::*Property,
2391           ulong Property_flag>
2392 class PT_traceable_create_table_option : public PT_create_table_option {
2393   typedef PT_create_table_option super;
2394 
2395   const Option_type value;
2396 
2397  public:
PT_traceable_create_table_option(Option_type value)2398   explicit PT_traceable_create_table_option(Option_type value) : value(value) {}
2399 
contextualize(Table_ddl_parse_context * pc)2400   bool contextualize(Table_ddl_parse_context *pc) override {
2401     if (super::contextualize(pc)) return true;
2402     pc->create_info->*Property = value;
2403     pc->create_info->used_fields |= Property_flag;
2404     return false;
2405   }
2406 };
2407 
2408 #define TYPE_AND_REF(x) decltype(x), &x
2409 
2410 /**
2411   Node for the @SQL{MAX_ROWS [=] @B{@<integer@>}} table option
2412 
2413   @ingroup ptn_create_or_alter_table_options
2414 */
2415 typedef PT_traceable_create_table_option<TYPE_AND_REF(HA_CREATE_INFO::max_rows),
2416                                          HA_CREATE_USED_MAX_ROWS>
2417     PT_create_max_rows_option;
2418 
2419 /**
2420   Node for the @SQL{MIN_ROWS [=] @B{@<integer@>}} table option
2421 
2422   @ingroup ptn_create_or_alter_table_options
2423 */
2424 typedef PT_traceable_create_table_option<TYPE_AND_REF(HA_CREATE_INFO::min_rows),
2425                                          HA_CREATE_USED_MIN_ROWS>
2426     PT_create_min_rows_option;
2427 
2428 /**
2429   Node for the @SQL{AVG_ROW_LENGTH_ROWS [=] @B{@<integer@>}} table option
2430 
2431   @ingroup ptn_create_or_alter_table_options
2432 */
2433 typedef PT_traceable_create_table_option<
2434     TYPE_AND_REF(HA_CREATE_INFO::avg_row_length), HA_CREATE_USED_AVG_ROW_LENGTH>
2435     PT_create_avg_row_length_option;
2436 
2437 /**
2438   Node for the @SQL{PASSWORD [=] @B{@<string@>}} table option
2439 
2440   @ingroup ptn_create_or_alter_table_options
2441 */
2442 typedef PT_traceable_create_table_option<TYPE_AND_REF(HA_CREATE_INFO::password),
2443                                          HA_CREATE_USED_PASSWORD>
2444     PT_create_password_option;
2445 
2446 /**
2447   Node for the @SQL{COMMENT [=] @B{@<string@>}} table option
2448 
2449   @ingroup ptn_create_or_alter_table_options
2450 */
2451 typedef PT_traceable_create_table_option<TYPE_AND_REF(HA_CREATE_INFO::comment),
2452                                          HA_CREATE_USED_COMMENT>
2453     PT_create_commen_option;
2454 
2455 /**
2456   Node for the @SQL{COMPRESSION [=] @B{@<string@>}} table option
2457 
2458   @ingroup ptn_create_or_alter_table_options
2459 */
2460 typedef PT_traceable_create_table_option<TYPE_AND_REF(HA_CREATE_INFO::compress),
2461                                          HA_CREATE_USED_COMPRESS>
2462     PT_create_compress_option;
2463 
2464 /**
2465   Node for the @SQL{ENGRYPTION [=] @B{@<string@>}} table option
2466 
2467   @ingroup ptn_create_or_alter_table_options
2468 */
2469 typedef PT_traceable_create_table_option<
2470     TYPE_AND_REF(HA_CREATE_INFO::encrypt_type), HA_CREATE_USED_ENCRYPT>
2471     PT_create_encryption_option;
2472 
2473 /**
2474   Node for the @SQL{AUTO_INCREMENT [=] @B{@<integer@>}} table option
2475 
2476   @ingroup ptn_create_or_alter_table_options
2477 */
2478 typedef PT_traceable_create_table_option<
2479     TYPE_AND_REF(HA_CREATE_INFO::auto_increment_value), HA_CREATE_USED_AUTO>
2480     PT_create_auto_increment_option;
2481 
2482 typedef PT_traceable_create_table_option<TYPE_AND_REF(HA_CREATE_INFO::row_type),
2483                                          HA_CREATE_USED_ROW_FORMAT>
2484     PT_create_row_format_option;
2485 
2486 typedef PT_traceable_create_table_option<
2487     TYPE_AND_REF(HA_CREATE_INFO::merge_insert_method),
2488     HA_CREATE_USED_INSERT_METHOD>
2489     PT_create_insert_method_option;
2490 
2491 typedef PT_traceable_create_table_option<
2492     TYPE_AND_REF(HA_CREATE_INFO::data_file_name), HA_CREATE_USED_DATADIR>
2493     PT_create_data_directory_option;
2494 
2495 typedef PT_traceable_create_table_option<
2496     TYPE_AND_REF(HA_CREATE_INFO::index_file_name), HA_CREATE_USED_INDEXDIR>
2497     PT_create_index_directory_option;
2498 
2499 typedef PT_traceable_create_table_option<
2500     TYPE_AND_REF(HA_CREATE_INFO::tablespace), HA_CREATE_USED_TABLESPACE>
2501     PT_create_tablespace_option;
2502 
2503 typedef PT_traceable_create_table_option<
2504     TYPE_AND_REF(HA_CREATE_INFO::connect_string), HA_CREATE_USED_CONNECTION>
2505     PT_create_connection_option;
2506 
2507 typedef PT_traceable_create_table_option<
2508     TYPE_AND_REF(HA_CREATE_INFO::key_block_size), HA_CREATE_USED_KEY_BLOCK_SIZE>
2509     PT_create_key_block_size_option;
2510 
2511 typedef PT_traceable_create_table_option<
2512     TYPE_AND_REF(HA_CREATE_INFO::m_transactional_ddl),
2513     HA_CREATE_USED_START_TRANSACTION>
2514     PT_create_start_transaction_option;
2515 
2516 typedef decltype(HA_CREATE_INFO::table_options) table_options_t;
2517 
2518 /**
2519   A template for options that set HA_CREATE_INFO::table_options and
2520   also records if the option was explicitly set.
2521 */
2522 template <ulong Property_flag, table_options_t Default, table_options_t Yes,
2523           table_options_t No>
2524 class PT_ternary_create_table_option : public PT_create_table_option {
2525   typedef PT_create_table_option super;
2526 
2527   const Ternary_option value;
2528 
2529  public:
PT_ternary_create_table_option(Ternary_option value)2530   explicit PT_ternary_create_table_option(Ternary_option value)
2531       : value(value) {}
2532 
contextualize(Table_ddl_parse_context * pc)2533   bool contextualize(Table_ddl_parse_context *pc) override {
2534     if (super::contextualize(pc)) return true;
2535     pc->create_info->table_options &= ~(Yes | No);
2536     switch (value) {
2537       case Ternary_option::ON:
2538         pc->create_info->table_options |= Yes;
2539         break;
2540       case Ternary_option::OFF:
2541         pc->create_info->table_options |= No;
2542         break;
2543       case Ternary_option::DEFAULT:
2544         break;
2545       default:
2546         DBUG_ASSERT(false);
2547     }
2548     pc->create_info->used_fields |= Property_flag;
2549     return false;
2550   }
2551 };
2552 
2553 /**
2554   Node for the @SQL{PACK_KEYS [=] @B{1|0|DEFAULT}} table option
2555 
2556   @ingroup ptn_create_or_alter_table_options
2557 
2558   PACK_KEYS | Constructor parameter
2559   ----------|----------------------
2560   1         | Ternary_option::ON
2561   0         | Ternary_option::OFF
2562   DEFAULT   | Ternary_option::DEFAULT
2563 */
2564 typedef PT_ternary_create_table_option<HA_CREATE_USED_PACK_KEYS,  // flag
2565                                        0,                         // DEFAULT
2566                                        HA_OPTION_PACK_KEYS,       // ON
2567                                        HA_OPTION_NO_PACK_KEYS>    // OFF
2568     PT_create_pack_keys_option;
2569 
2570 /**
2571   Node for the @SQL{STATS_PERSISTENT [=] @B{1|0|DEFAULT}} table option
2572 
2573   @ingroup ptn_create_or_alter_table_options
2574 
2575   STATS_PERSISTENT | Constructor parameter
2576   -----------------|----------------------
2577   1                | Ternary_option::ON
2578   0                | Ternary_option::OFF
2579   DEFAULT          | Ternary_option::DEFAULT
2580 */
2581 typedef PT_ternary_create_table_option<HA_CREATE_USED_STATS_PERSISTENT,  // flag
2582                                        0,                           // DEFAULT
2583                                        HA_OPTION_STATS_PERSISTENT,  // ON
2584                                        HA_OPTION_NO_STATS_PERSISTENT>  // OFF
2585     PT_create_stats_persistent_option;
2586 
2587 /**
2588   A template for options that set HA_CREATE_INFO::table_options and
2589   also records if the option was explicitly set.
2590 */
2591 template <ulong Property_flag, table_options_t Yes, table_options_t No>
2592 class PT_bool_create_table_option : public PT_create_table_option {
2593   typedef PT_create_table_option super;
2594 
2595   const bool value;
2596 
2597  public:
PT_bool_create_table_option(bool value)2598   explicit PT_bool_create_table_option(bool value) : value(value) {}
2599 
contextualize(Table_ddl_parse_context * pc)2600   bool contextualize(Table_ddl_parse_context *pc) override {
2601     if (super::contextualize(pc)) return true;
2602     pc->create_info->table_options &= ~(Yes | No);
2603     pc->create_info->table_options |= value ? Yes : No;
2604     pc->create_info->used_fields |= Property_flag;
2605     return false;
2606   }
2607 };
2608 
2609 /**
2610   Node for the @SQL{CHECKSUM|TABLE_CHECKSUM [=] @B{0|@<not 0@>}} table option
2611 
2612   @ingroup ptn_create_or_alter_table_options
2613 
2614   TABLE_CHECKSUM | Constructor parameter
2615   ---------------|----------------------
2616   0              | false
2617   not 0          | true
2618 */
2619 typedef PT_bool_create_table_option<HA_CREATE_USED_CHECKSUM,  // flag
2620                                     HA_OPTION_CHECKSUM,       // ON
2621                                     HA_OPTION_NO_CHECKSUM     // OFF
2622                                     >
2623     PT_create_checksum_option;
2624 
2625 /**
2626   Node for the @SQL{DELAY_KEY_WRITE [=] @B{0|@<not 0@>}} table option
2627 
2628   @ingroup ptn_create_or_alter_table_options
2629 
2630   TABLE_CHECKSUM | Constructor parameter
2631   ---------------|----------------------
2632   0              | false
2633   not 0          | true
2634 */
2635 typedef PT_bool_create_table_option<HA_CREATE_USED_DELAY_KEY_WRITE,  // flag
2636                                     HA_OPTION_DELAY_KEY_WRITE,       // ON
2637                                     HA_OPTION_NO_DELAY_KEY_WRITE>    // OFF
2638     PT_create_delay_key_write_option;
2639 
2640 /**
2641   Node for the @SQL{ENGINE [=] @B{@<identifier@>|@<string@>}} table option
2642 
2643   @ingroup ptn_create_or_alter_table_options
2644 */
2645 class PT_create_table_engine_option : public PT_create_table_option {
2646   typedef PT_create_table_option super;
2647 
2648   const LEX_CSTRING engine;
2649 
2650  public:
2651   /**
2652     @param engine       Storage engine name.
2653   */
PT_create_table_engine_option(const LEX_CSTRING & engine)2654   explicit PT_create_table_engine_option(const LEX_CSTRING &engine)
2655       : engine(engine) {}
2656 
2657   bool contextualize(Table_ddl_parse_context *pc) override;
2658 };
2659 
2660 /**
2661   Node for the @SQL{SECONDARY_ENGINE [=] @B{@<identifier@>|@<string@>|NULL}}
2662   table option.
2663 
2664   @ingroup ptn_create_or_alter_table_options
2665 */
2666 class PT_create_table_secondary_engine_option : public PT_create_table_option {
2667   using super = PT_create_table_option;
2668 
2669  public:
PT_create_table_secondary_engine_option()2670   explicit PT_create_table_secondary_engine_option() {}
PT_create_table_secondary_engine_option(const LEX_CSTRING & secondary_engine)2671   explicit PT_create_table_secondary_engine_option(
2672       const LEX_CSTRING &secondary_engine)
2673       : m_secondary_engine(secondary_engine) {}
2674 
2675   bool contextualize(Table_ddl_parse_context *pc) override;
2676 
2677  private:
2678   const LEX_CSTRING m_secondary_engine{nullptr, 0};
2679 };
2680 
2681 /**
2682   Node for the @SQL{STATS_AUTO_RECALC [=] @B{@<0|1|DEFAULT@>})} table option
2683 
2684   @ingroup ptn_create_or_alter_table_options
2685 */
2686 class PT_create_stats_auto_recalc_option : public PT_create_table_option {
2687   typedef PT_create_table_option super;
2688 
2689   const Ternary_option value;
2690 
2691  public:
2692   /**
2693     @param value
2694       STATS_AUTO_RECALC | value
2695       ------------------|----------------------
2696       1                 | Ternary_option::ON
2697       0                 | Ternary_option::OFF
2698       DEFAULT           | Ternary_option::DEFAULT
2699   */
PT_create_stats_auto_recalc_option(Ternary_option value)2700   PT_create_stats_auto_recalc_option(Ternary_option value) : value(value) {}
2701 
2702   bool contextualize(Table_ddl_parse_context *pc) override;
2703 };
2704 
2705 /**
2706   Node for the @SQL{STATS_SAMPLE_PAGES [=] @B{@<integer@>|DEFAULT}} table option
2707 
2708   @ingroup ptn_create_or_alter_table_options
2709 */
2710 class PT_create_stats_stable_pages : public PT_create_table_option {
2711   typedef PT_create_table_option super;
2712   typedef decltype(HA_CREATE_INFO::stats_sample_pages) value_t;
2713 
2714   const value_t value;
2715 
2716  public:
2717   /**
2718     Constructor for implicit number of pages
2719 
2720     @param value       Nunber of pages, 1@<=N@<=65535.
2721   */
PT_create_stats_stable_pages(value_t value)2722   explicit PT_create_stats_stable_pages(value_t value) : value(value) {
2723     DBUG_ASSERT(value != 0 && value <= 0xFFFF);
2724   }
2725   /**
2726     Constructor for the DEFAULT number of pages
2727   */
PT_create_stats_stable_pages()2728   PT_create_stats_stable_pages() : value(0) {}  // DEFAULT
2729 
2730   bool contextualize(Table_ddl_parse_context *pc) override;
2731 };
2732 
2733 class PT_create_union_option : public PT_create_table_option {
2734   typedef PT_create_table_option super;
2735 
2736   const Mem_root_array<Table_ident *> *tables;
2737 
2738  public:
PT_create_union_option(const Mem_root_array<Table_ident * > * tables)2739   explicit PT_create_union_option(const Mem_root_array<Table_ident *> *tables)
2740       : tables(tables) {}
2741 
2742   bool contextualize(Table_ddl_parse_context *pc) override;
2743 };
2744 
2745 class PT_create_storage_option : public PT_create_table_option {
2746   typedef PT_create_table_option super;
2747 
2748   const ha_storage_media value;
2749 
2750  public:
PT_create_storage_option(ha_storage_media value)2751   explicit PT_create_storage_option(ha_storage_media value) : value(value) {}
2752 
contextualize(Table_ddl_parse_context * pc)2753   bool contextualize(Table_ddl_parse_context *pc) override {
2754     if (super::contextualize(pc)) return true;
2755     pc->create_info->storage_media = value;
2756     return false;
2757   }
2758 };
2759 
2760 class PT_create_table_default_charset : public PT_create_table_option {
2761   typedef PT_create_table_option super;
2762 
2763   const CHARSET_INFO *value;
2764 
2765  public:
PT_create_table_default_charset(const CHARSET_INFO * value)2766   explicit PT_create_table_default_charset(const CHARSET_INFO *value)
2767       : value(value) {
2768     DBUG_ASSERT(value != nullptr);
2769   }
2770 
2771   bool contextualize(Table_ddl_parse_context *pc) override;
2772 };
2773 
2774 class PT_create_table_default_collation : public PT_create_table_option {
2775   typedef PT_create_table_option super;
2776 
2777   const CHARSET_INFO *value;
2778 
2779  public:
PT_create_table_default_collation(const CHARSET_INFO * value)2780   explicit PT_create_table_default_collation(const CHARSET_INFO *value)
2781       : value(value) {
2782     DBUG_ASSERT(value != nullptr);
2783   }
2784 
2785   bool contextualize(Table_ddl_parse_context *pc) override;
2786 };
2787 
2788 class PT_check_constraint final : public PT_table_constraint_def {
2789   typedef PT_table_constraint_def super;
2790   Sql_check_constraint_spec cc_spec;
2791 
2792  public:
PT_check_constraint(LEX_STRING & name,Item * expr,bool is_enforced)2793   explicit PT_check_constraint(LEX_STRING &name, Item *expr, bool is_enforced) {
2794     cc_spec.name = name;
2795     cc_spec.check_expr = expr;
2796     cc_spec.is_enforced = is_enforced;
2797   }
set_column_name(const LEX_STRING & name)2798   void set_column_name(const LEX_STRING &name) { cc_spec.column_name = name; }
2799 
2800   bool contextualize(Table_ddl_parse_context *pc) override;
2801 };
2802 
2803 class PT_column_def : public PT_table_element {
2804   typedef PT_table_element super;
2805 
2806   const LEX_STRING field_ident;
2807   PT_field_def_base *field_def;
2808   // Currently we ignore that constraint in the executor.
2809   PT_table_constraint_def *opt_column_constraint;
2810 
2811   const char *opt_place;
2812 
2813  public:
2814   PT_column_def(const LEX_STRING &field_ident, PT_field_def_base *field_def,
2815                 PT_table_constraint_def *opt_column_constraint,
2816                 const char *opt_place = nullptr)
field_ident(field_ident)2817       : field_ident(field_ident),
2818         field_def(field_def),
2819         opt_column_constraint(opt_column_constraint),
2820         opt_place(opt_place) {}
2821 
2822   bool contextualize(Table_ddl_parse_context *pc) override;
2823 };
2824 
2825 /**
2826   Top-level node for the CREATE %TABLE statement
2827 
2828   @ingroup ptn_create_table
2829 */
2830 class PT_create_table_stmt final : public PT_table_ddl_stmt_base {
2831   bool is_temporary;
2832   bool only_if_not_exists;
2833   Table_ident *table_name;
2834   const Mem_root_array<PT_table_element *> *opt_table_element_list;
2835   const Mem_root_array<PT_create_table_option *> *opt_create_table_options;
2836   PT_partition *opt_partitioning;
2837   On_duplicate on_duplicate;
2838   PT_query_primary *opt_query_expression;
2839   Table_ident *opt_like_clause;
2840 
2841   HA_CREATE_INFO m_create_info;
2842 
2843  public:
2844   /**
2845     @param mem_root                   MEM_ROOT to use for allocation
2846     @param is_temporary               True if @SQL{CREATE @B{TEMPORARY} %TABLE}
2847     @param only_if_not_exists  True if @SQL{CREATE %TABLE ... @B{IF NOT EXISTS}}
2848     @param table_name                 @SQL{CREATE %TABLE ... @B{@<table name@>}}
2849     @param opt_table_element_list     NULL or a list of table column and
2850                                       constraint definitions.
2851     @param opt_create_table_options   NULL or a list of
2852                                       @ref ptn_create_or_alter_table_options
2853                                       "table options".
2854     @param opt_partitioning           NULL or the @SQL{PARTITION BY} clause.
2855     @param on_duplicate               DUPLICATE, IGNORE or fail with an error
2856                                       on data duplication errors (relevant
2857                                       for @SQL{CREATE TABLE ... SELECT}
2858                                       statements).
2859     @param opt_query_expression       NULL or the @SQL{@B{SELECT}} clause.
2860   */
PT_create_table_stmt(MEM_ROOT * mem_root,bool is_temporary,bool only_if_not_exists,Table_ident * table_name,const Mem_root_array<PT_table_element * > * opt_table_element_list,const Mem_root_array<PT_create_table_option * > * opt_create_table_options,PT_partition * opt_partitioning,On_duplicate on_duplicate,PT_query_primary * opt_query_expression)2861   PT_create_table_stmt(
2862       MEM_ROOT *mem_root, bool is_temporary, bool only_if_not_exists,
2863       Table_ident *table_name,
2864       const Mem_root_array<PT_table_element *> *opt_table_element_list,
2865       const Mem_root_array<PT_create_table_option *> *opt_create_table_options,
2866       PT_partition *opt_partitioning, On_duplicate on_duplicate,
2867       PT_query_primary *opt_query_expression)
2868       : PT_table_ddl_stmt_base(mem_root),
2869         is_temporary(is_temporary),
2870         only_if_not_exists(only_if_not_exists),
2871         table_name(table_name),
2872         opt_table_element_list(opt_table_element_list),
2873         opt_create_table_options(opt_create_table_options),
2874         opt_partitioning(opt_partitioning),
2875         on_duplicate(on_duplicate),
2876         opt_query_expression(opt_query_expression),
2877         opt_like_clause(nullptr) {}
2878   /**
2879     @param mem_root           MEM_ROOT to use for allocation
2880     @param is_temporary       True if @SQL{CREATE @B{TEMPORARY} %TABLE}.
2881     @param only_if_not_exists True if @SQL{CREATE %TABLE ... @B{IF NOT EXISTS}}.
2882     @param table_name         @SQL{CREATE %TABLE ... @B{@<table name@>}}.
2883     @param opt_like_clause    NULL or the @SQL{@B{LIKE @<table name@>}} clause.
2884   */
PT_create_table_stmt(MEM_ROOT * mem_root,bool is_temporary,bool only_if_not_exists,Table_ident * table_name,Table_ident * opt_like_clause)2885   PT_create_table_stmt(MEM_ROOT *mem_root, bool is_temporary,
2886                        bool only_if_not_exists, Table_ident *table_name,
2887                        Table_ident *opt_like_clause)
2888       : PT_table_ddl_stmt_base(mem_root),
2889         is_temporary(is_temporary),
2890         only_if_not_exists(only_if_not_exists),
2891         table_name(table_name),
2892         opt_table_element_list(nullptr),
2893         opt_create_table_options(nullptr),
2894         opt_partitioning(nullptr),
2895         on_duplicate(On_duplicate::ERROR),
2896         opt_query_expression(nullptr),
2897         opt_like_clause(opt_like_clause) {}
2898 
2899   Sql_cmd *make_cmd(THD *thd) override;
2900 };
2901 
2902 class PT_create_role final : public Parse_tree_root {
2903   Sql_cmd_create_role sql_cmd;
2904 
2905  public:
PT_create_role(bool if_not_exists,const List<LEX_USER> * roles)2906   PT_create_role(bool if_not_exists, const List<LEX_USER> *roles)
2907       : sql_cmd(if_not_exists, roles) {}
2908 
2909   Sql_cmd *make_cmd(THD *thd) override;
2910 };
2911 
2912 class PT_drop_role final : public Parse_tree_root {
2913   Sql_cmd_drop_role sql_cmd;
2914 
2915  public:
PT_drop_role(bool ignore_errors,const List<LEX_USER> * roles)2916   explicit PT_drop_role(bool ignore_errors, const List<LEX_USER> *roles)
2917       : sql_cmd(ignore_errors, roles) {}
2918 
2919   Sql_cmd *make_cmd(THD *thd) override;
2920 };
2921 
2922 class PT_set_role : public Parse_tree_root {
2923   Sql_cmd_set_role sql_cmd;
2924 
2925  public:
2926   explicit PT_set_role(role_enum role_type,
2927                        const List<LEX_USER> *opt_except_roles = nullptr)
sql_cmd(role_type,opt_except_roles)2928       : sql_cmd(role_type, opt_except_roles) {
2929     DBUG_ASSERT(role_type == role_enum::ROLE_ALL ||
2930                 opt_except_roles == nullptr);
2931   }
PT_set_role(const List<LEX_USER> * roles)2932   explicit PT_set_role(const List<LEX_USER> *roles) : sql_cmd(roles) {}
2933 
2934   Sql_cmd *make_cmd(THD *thd) override;
2935 };
2936 
2937 /**
2938   This class is used for representing both static and dynamic privileges on
2939   global as well as table and column level.
2940 */
2941 struct Privilege {
2942   enum privilege_type { STATIC, DYNAMIC };
2943 
2944   privilege_type type;
2945   const Mem_root_array<LEX_CSTRING> *columns;
2946 
PrivilegePrivilege2947   explicit Privilege(privilege_type type,
2948                      const Mem_root_array<LEX_CSTRING> *columns)
2949       : type(type), columns(columns) {}
2950 };
2951 
2952 struct Static_privilege : public Privilege {
2953   const uint grant;
2954 
Static_privilegeStatic_privilege2955   Static_privilege(uint grant, const Mem_root_array<LEX_CSTRING> *columns_arg)
2956       : Privilege(STATIC, columns_arg), grant(grant) {}
2957 };
2958 
2959 struct Dynamic_privilege : public Privilege {
2960   const LEX_STRING ident;
2961 
Dynamic_privilegeDynamic_privilege2962   Dynamic_privilege(const LEX_STRING &ident,
2963                     const Mem_root_array<LEX_CSTRING> *columns_arg)
2964       : Privilege(DYNAMIC, columns_arg), ident(ident) {}
2965 };
2966 
2967 class PT_role_or_privilege : public Parse_tree_node {
2968  private:
2969   POS pos;
2970 
2971  public:
PT_role_or_privilege(const POS & pos)2972   explicit PT_role_or_privilege(const POS &pos) : pos(pos) {}
2973   virtual LEX_USER *get_user(THD *thd);
2974   virtual Privilege *get_privilege(THD *thd);
2975 };
2976 
2977 class PT_role_at_host final : public PT_role_or_privilege {
2978   LEX_STRING role;
2979   LEX_STRING host;
2980 
2981  public:
PT_role_at_host(const POS & pos,const LEX_STRING & role,const LEX_STRING & host)2982   PT_role_at_host(const POS &pos, const LEX_STRING &role,
2983                   const LEX_STRING &host)
2984       : PT_role_or_privilege(pos), role(role), host(host) {}
2985 
2986   LEX_USER *get_user(THD *thd) override;
2987 };
2988 
2989 class PT_role_or_dynamic_privilege final : public PT_role_or_privilege {
2990   LEX_STRING ident;
2991 
2992  public:
PT_role_or_dynamic_privilege(const POS & pos,const LEX_STRING & ident)2993   PT_role_or_dynamic_privilege(const POS &pos, const LEX_STRING &ident)
2994       : PT_role_or_privilege(pos), ident(ident) {}
2995 
2996   LEX_USER *get_user(THD *thd) override;
2997   Privilege *get_privilege(THD *thd) override;
2998 };
2999 
3000 class PT_static_privilege final : public PT_role_or_privilege {
3001   const uint grant;
3002   const Mem_root_array<LEX_CSTRING> *columns;
3003 
3004  public:
3005   PT_static_privilege(const POS &pos, uint grant,
3006                       const Mem_root_array<LEX_CSTRING> *columns = nullptr)
PT_role_or_privilege(pos)3007       : PT_role_or_privilege(pos), grant(grant), columns(columns) {}
3008 
3009   Privilege *get_privilege(THD *thd) override;
3010 };
3011 
3012 class PT_dynamic_privilege final : public PT_role_or_privilege {
3013   LEX_STRING ident;
3014 
3015  public:
PT_dynamic_privilege(const POS & pos,const LEX_STRING & ident)3016   PT_dynamic_privilege(const POS &pos, const LEX_STRING &ident)
3017       : PT_role_or_privilege(pos), ident(ident) {}
3018 
3019   Privilege *get_privilege(THD *thd) override;
3020 };
3021 
3022 class PT_grant_roles final : public Parse_tree_root {
3023   const Mem_root_array<PT_role_or_privilege *> *roles;
3024   const List<LEX_USER> *users;
3025   const bool with_admin_option;
3026 
3027  public:
PT_grant_roles(const Mem_root_array<PT_role_or_privilege * > * roles,const List<LEX_USER> * users,bool with_admin_option)3028   PT_grant_roles(const Mem_root_array<PT_role_or_privilege *> *roles,
3029                  const List<LEX_USER> *users, bool with_admin_option)
3030       : roles(roles), users(users), with_admin_option(with_admin_option) {}
3031 
3032   Sql_cmd *make_cmd(THD *thd) override;
3033 };
3034 
3035 class PT_revoke_roles final : public Parse_tree_root {
3036   const Mem_root_array<PT_role_or_privilege *> *roles;
3037   const List<LEX_USER> *users;
3038 
3039  public:
PT_revoke_roles(Mem_root_array<PT_role_or_privilege * > * roles,const List<LEX_USER> * users)3040   PT_revoke_roles(Mem_root_array<PT_role_or_privilege *> *roles,
3041                   const List<LEX_USER> *users)
3042       : roles(roles), users(users) {}
3043 
3044   Sql_cmd *make_cmd(THD *thd) override;
3045 };
3046 
3047 class PT_alter_user_default_role final : public Parse_tree_root {
3048   Sql_cmd_alter_user_default_role sql_cmd;
3049 
3050  public:
PT_alter_user_default_role(bool if_exists,const List<LEX_USER> * users,const List<LEX_USER> * roles,const role_enum role_type)3051   PT_alter_user_default_role(bool if_exists, const List<LEX_USER> *users,
3052                              const List<LEX_USER> *roles,
3053                              const role_enum role_type)
3054       : sql_cmd(if_exists, users, roles, role_type) {}
3055 
3056   Sql_cmd *make_cmd(THD *thd) override;
3057 };
3058 
3059 class PT_show_grants final : public Parse_tree_root {
3060   Sql_cmd_show_grants sql_cmd;
3061 
3062  public:
PT_show_grants(const LEX_USER * opt_for_user,const List<LEX_USER> * opt_using_users)3063   PT_show_grants(const LEX_USER *opt_for_user,
3064                  const List<LEX_USER> *opt_using_users)
3065       : sql_cmd(opt_for_user, opt_using_users) {
3066     DBUG_ASSERT(opt_using_users == nullptr || opt_for_user != nullptr);
3067   }
3068 
3069   Sql_cmd *make_cmd(THD *thd) override;
3070 };
3071 
3072 /**
3073   Base class for Parse tree nodes of SHOW FIELDS/SHOW INDEX statements.
3074 */
3075 class PT_show_fields_and_keys : public Parse_tree_root {
3076  protected:
3077   enum Type { SHOW_FIELDS = SQLCOM_SHOW_FIELDS, SHOW_KEYS = SQLCOM_SHOW_KEYS };
3078 
PT_show_fields_and_keys(const POS & pos,Type type,Table_ident * table_ident,const LEX_STRING & wild,Item * where_condition)3079   PT_show_fields_and_keys(const POS &pos, Type type, Table_ident *table_ident,
3080                           const LEX_STRING &wild, Item *where_condition)
3081       : m_sql_cmd(static_cast<enum_sql_command>(type)),
3082         m_pos(pos),
3083         m_type(type),
3084         m_table_ident(table_ident),
3085         m_wild(wild),
3086         m_where_condition(where_condition) {
3087     DBUG_ASSERT(wild.str == nullptr || where_condition == nullptr);
3088   }
3089 
3090  public:
3091   Sql_cmd *make_cmd(THD *thd) override;
3092 
3093  private:
3094   // Sql_cmd for SHOW COLUMNS/SHOW INDEX statements.
3095   Sql_cmd_show m_sql_cmd;
3096 
3097   // Textual location of a token just parsed.
3098   POS m_pos;
3099 
3100   // SHOW_FIELDS or SHOW_KEYS
3101   Type m_type;
3102 
3103   // Table used in the statement.
3104   Table_ident *m_table_ident;
3105 
3106   // Wild or where clause used in the statement.
3107   LEX_STRING m_wild;
3108   Item *m_where_condition;
3109 };
3110 
3111 /**
3112   Parse tree node for SHOW FIELDS statement.
3113 */
3114 class PT_show_fields final : public PT_show_fields_and_keys {
3115   typedef PT_show_fields_and_keys super;
3116 
3117  public:
PT_show_fields(const POS & pos,Show_cmd_type show_cmd_type,Table_ident * table,const LEX_STRING & wild)3118   PT_show_fields(const POS &pos, Show_cmd_type show_cmd_type,
3119                  Table_ident *table, const LEX_STRING &wild)
3120       : PT_show_fields_and_keys(pos, SHOW_FIELDS, table, wild, nullptr),
3121         m_show_cmd_type(show_cmd_type) {}
3122 
3123   PT_show_fields(const POS &pos, Show_cmd_type show_cmd_type,
3124                  Table_ident *table_ident, Item *where_condition = nullptr);
3125 
3126   Sql_cmd *make_cmd(THD *thd) override;
3127 
3128  private:
3129   Show_cmd_type m_show_cmd_type;
3130 };
3131 
3132 /**
3133   Parse tree node for SHOW INDEX statement.
3134 */
3135 class PT_show_keys final : public PT_show_fields_and_keys {
3136  public:
3137   PT_show_keys(const POS &pos, bool extended_show, Table_ident *table,
3138                Item *where_condition);
3139 
3140   Sql_cmd *make_cmd(THD *thd) override;
3141 
3142  private:
3143   typedef PT_show_fields_and_keys super;
3144 
3145   // Flag to indicate EXTENDED keyword usage in the statement.
3146   bool m_extended_show;
3147 };
3148 
3149 class PT_alter_table_action : public PT_ddl_table_option {
3150   typedef PT_ddl_table_option super;
3151 
3152  protected:
PT_alter_table_action(Alter_info::Alter_info_flag flag)3153   explicit PT_alter_table_action(Alter_info::Alter_info_flag flag)
3154       : flag(flag) {}
3155 
3156  public:
3157   bool contextualize(Table_ddl_parse_context *pc) override;
3158 
3159  protected:
3160   /**
3161     A routine used by the parser to decide whether we are specifying a full
3162     partitioning or if only partitions to add or to reorganize.
3163 
3164     @retval  true    ALTER TABLE ADD/REORGANIZE PARTITION.
3165     @retval  false   Something else.
3166   */
is_add_or_reorganize_partition()3167   bool is_add_or_reorganize_partition() const {
3168     return (flag == Alter_info::ALTER_ADD_PARTITION ||
3169             flag == Alter_info::ALTER_REORGANIZE_PARTITION);
3170   }
3171 
3172  public:
3173   const Alter_info::Alter_info_flag flag;
3174 };
3175 
3176 class PT_alter_table_add_column final : public PT_alter_table_action {
3177   typedef PT_alter_table_action super;
3178 
3179  public:
PT_alter_table_add_column(const LEX_STRING & field_ident,PT_field_def_base * field_def,PT_table_constraint_def * opt_column_constraint,const char * opt_place)3180   PT_alter_table_add_column(const LEX_STRING &field_ident,
3181                             PT_field_def_base *field_def,
3182                             PT_table_constraint_def *opt_column_constraint,
3183                             const char *opt_place)
3184       : super(Alter_info::ALTER_ADD_COLUMN),
3185         m_column_def(field_ident, field_def, opt_column_constraint, opt_place) {
3186   }
3187 
contextualize(Table_ddl_parse_context * pc)3188   bool contextualize(Table_ddl_parse_context *pc) override {
3189     return super::contextualize(pc) || m_column_def.contextualize(pc);
3190   }
3191 
3192  private:
3193   PT_column_def m_column_def;
3194 };
3195 
3196 class PT_alter_table_add_columns final : public PT_alter_table_action {
3197   typedef PT_alter_table_action super;
3198 
3199  public:
PT_alter_table_add_columns(const Mem_root_array<PT_table_element * > * columns)3200   explicit PT_alter_table_add_columns(
3201       const Mem_root_array<PT_table_element *> *columns)
3202       : super(Alter_info::ALTER_ADD_COLUMN), m_columns(columns) {}
3203 
contextualize(Table_ddl_parse_context * pc)3204   bool contextualize(Table_ddl_parse_context *pc) override {
3205     if (super::contextualize(pc)) return true;
3206 
3207     for (auto *column : *m_columns)
3208       if (column->contextualize(pc)) return true;
3209 
3210     return false;
3211   }
3212 
3213  private:
3214   const Mem_root_array<PT_table_element *> *m_columns;
3215 };
3216 
3217 class PT_alter_table_add_constraint final : public PT_alter_table_action {
3218   typedef PT_alter_table_action super;
3219 
3220  public:
PT_alter_table_add_constraint(PT_table_constraint_def * constraint)3221   explicit PT_alter_table_add_constraint(PT_table_constraint_def *constraint)
3222       : super(Alter_info::ALTER_ADD_INDEX), m_constraint(constraint) {}
3223 
contextualize(Table_ddl_parse_context * pc)3224   bool contextualize(Table_ddl_parse_context *pc) override {
3225     return super::contextualize(pc) || m_constraint->contextualize(pc);
3226   }
3227 
3228  private:
3229   PT_table_constraint_def *m_constraint;
3230 };
3231 
3232 class PT_alter_table_change_column final : public PT_alter_table_action {
3233   typedef PT_alter_table_action super;
3234 
3235  public:
PT_alter_table_change_column(const LEX_STRING & old_name,const LEX_STRING & new_name,PT_field_def_base * field_def,const char * opt_place)3236   PT_alter_table_change_column(const LEX_STRING &old_name,
3237                                const LEX_STRING &new_name,
3238                                PT_field_def_base *field_def,
3239                                const char *opt_place)
3240       : super(Alter_info::ALTER_CHANGE_COLUMN),
3241         m_old_name(old_name),
3242         m_new_name(new_name),
3243         m_field_def(field_def),
3244         m_opt_place(opt_place) {}
3245 
PT_alter_table_change_column(const LEX_STRING & name,PT_field_def_base * field_def,const char * opt_place)3246   PT_alter_table_change_column(const LEX_STRING &name,
3247                                PT_field_def_base *field_def,
3248                                const char *opt_place)
3249       : PT_alter_table_change_column(name, name, field_def, opt_place) {}
3250 
3251   bool contextualize(Table_ddl_parse_context *pc) override;
3252 
3253  private:
3254   const LEX_STRING m_old_name;
3255   const LEX_STRING m_new_name;
3256   PT_field_def_base *m_field_def;
3257   const char *m_opt_place;
3258 };
3259 
3260 class PT_alter_table_drop : public PT_alter_table_action {
3261   typedef PT_alter_table_action super;
3262 
3263  protected:
PT_alter_table_drop(Alter_drop::drop_type drop_type,Alter_info::Alter_info_flag alter_info_flag,const char * name)3264   PT_alter_table_drop(Alter_drop::drop_type drop_type,
3265                       Alter_info::Alter_info_flag alter_info_flag,
3266                       const char *name)
3267       : super(alter_info_flag), m_alter_drop(drop_type, name) {}
3268 
3269  public:
contextualize(Table_ddl_parse_context * pc)3270   bool contextualize(Table_ddl_parse_context *pc) override {
3271     return (super::contextualize(pc) ||
3272             pc->alter_info->drop_list.push_back(&m_alter_drop));
3273   }
3274 
3275  private:
3276   Alter_drop m_alter_drop;
3277 };
3278 
3279 class PT_alter_table_drop_column final : public PT_alter_table_drop {
3280  public:
PT_alter_table_drop_column(const char * name)3281   explicit PT_alter_table_drop_column(const char *name)
3282       : PT_alter_table_drop(Alter_drop::COLUMN, Alter_info::ALTER_DROP_COLUMN,
3283                             name) {}
3284 };
3285 
3286 class PT_alter_table_drop_foreign_key final : public PT_alter_table_drop {
3287  public:
PT_alter_table_drop_foreign_key(const char * name)3288   explicit PT_alter_table_drop_foreign_key(const char *name)
3289       : PT_alter_table_drop(Alter_drop::FOREIGN_KEY,
3290                             Alter_info::DROP_FOREIGN_KEY, name) {}
3291 };
3292 
3293 class PT_alter_table_drop_key final : public PT_alter_table_drop {
3294  public:
PT_alter_table_drop_key(const char * name)3295   explicit PT_alter_table_drop_key(const char *name)
3296       : PT_alter_table_drop(Alter_drop::KEY, Alter_info::ALTER_DROP_INDEX,
3297                             name) {}
3298 };
3299 
3300 class PT_alter_table_drop_check_constraint final : public PT_alter_table_drop {
3301  public:
PT_alter_table_drop_check_constraint(const char * name)3302   explicit PT_alter_table_drop_check_constraint(const char *name)
3303       : PT_alter_table_drop(Alter_drop::CHECK_CONSTRAINT,
3304                             Alter_info::DROP_CHECK_CONSTRAINT, name) {}
3305 };
3306 
3307 class PT_alter_table_drop_constraint final : public PT_alter_table_drop {
3308  public:
PT_alter_table_drop_constraint(const char * name)3309   explicit PT_alter_table_drop_constraint(const char *name)
3310       : PT_alter_table_drop(Alter_drop::ANY_CONSTRAINT,
3311                             Alter_info::DROP_ANY_CONSTRAINT, name) {}
3312 };
3313 
3314 class PT_alter_table_enforce_constraint : public PT_alter_table_action {
3315   typedef PT_alter_table_action super;
3316 
3317  protected:
PT_alter_table_enforce_constraint(Alter_constraint_enforcement::Type alter_type,Alter_info::Alter_info_flag alter_info_flag,const char * name,bool is_enforced)3318   PT_alter_table_enforce_constraint(
3319       Alter_constraint_enforcement::Type alter_type,
3320       Alter_info::Alter_info_flag alter_info_flag, const char *name,
3321       bool is_enforced)
3322       : super(alter_info_flag),
3323         m_constraint_enforcement(alter_type, name, is_enforced) {}
3324 
3325  public:
PT_alter_table_enforce_constraint(const char * name,bool is_enforced)3326   explicit PT_alter_table_enforce_constraint(const char *name, bool is_enforced)
3327       : super(is_enforced ? Alter_info::ENFORCE_ANY_CONSTRAINT
3328                           : Alter_info::SUSPEND_ANY_CONSTRAINT),
3329         m_constraint_enforcement(
3330             Alter_constraint_enforcement::Type::ANY_CONSTRAINT, name,
3331             is_enforced) {}
3332 
contextualize(Table_ddl_parse_context * pc)3333   bool contextualize(Table_ddl_parse_context *pc) override {
3334     return (super::contextualize(pc) ||
3335             pc->alter_info->alter_constraint_enforcement_list.push_back(
3336                 &m_constraint_enforcement));
3337   }
3338 
3339  private:
3340   Alter_constraint_enforcement m_constraint_enforcement;
3341 };
3342 
3343 class PT_alter_table_enforce_check_constraint final
3344     : public PT_alter_table_enforce_constraint {
3345  public:
PT_alter_table_enforce_check_constraint(const char * name,bool is_enforced)3346   explicit PT_alter_table_enforce_check_constraint(const char *name,
3347                                                    bool is_enforced)
3348       : PT_alter_table_enforce_constraint(
3349             Alter_constraint_enforcement::Type::CHECK_CONSTRAINT,
3350             is_enforced ? Alter_info::ENFORCE_CHECK_CONSTRAINT
3351                         : Alter_info::SUSPEND_CHECK_CONSTRAINT,
3352             name, is_enforced) {}
3353 };
3354 
3355 class PT_alter_table_enable_keys final : public PT_alter_table_action {
3356   typedef PT_alter_table_action super;
3357 
3358  public:
PT_alter_table_enable_keys(bool enable)3359   explicit PT_alter_table_enable_keys(bool enable)
3360       : super(Alter_info::ALTER_KEYS_ONOFF), m_enable(enable) {}
3361 
contextualize(Table_ddl_parse_context * pc)3362   bool contextualize(Table_ddl_parse_context *pc) override {
3363     pc->alter_info->keys_onoff =
3364         m_enable ? Alter_info::ENABLE : Alter_info::DISABLE;
3365     return super::contextualize(pc);
3366   }
3367 
3368  private:
3369   bool m_enable;
3370 };
3371 
3372 class PT_alter_table_set_default final : public PT_alter_table_action {
3373   typedef PT_alter_table_action super;
3374 
3375  public:
PT_alter_table_set_default(const char * col_name,Item * opt_default_expr)3376   PT_alter_table_set_default(const char *col_name, Item *opt_default_expr)
3377       : super(Alter_info::ALTER_CHANGE_COLUMN_DEFAULT),
3378         m_name(col_name),
3379         m_expr(opt_default_expr) {}
3380 
3381   bool contextualize(Table_ddl_parse_context *pc) override;
3382 
3383  private:
3384   const char *m_name;
3385   Item *m_expr;
3386 };
3387 
3388 class PT_alter_table_index_visible final : public PT_alter_table_action {
3389   typedef PT_alter_table_action super;
3390 
3391  public:
PT_alter_table_index_visible(const char * name,bool visible)3392   PT_alter_table_index_visible(const char *name, bool visible)
3393       : super(Alter_info::ALTER_INDEX_VISIBILITY),
3394         m_alter_index_visibility(name, visible) {}
3395 
contextualize(Table_ddl_parse_context * pc)3396   bool contextualize(Table_ddl_parse_context *pc) override {
3397     return (super::contextualize(pc) ||
3398             pc->alter_info->alter_index_visibility_list.push_back(
3399                 &m_alter_index_visibility));
3400   }
3401 
3402  private:
3403   Alter_index_visibility m_alter_index_visibility;
3404 };
3405 
3406 class PT_alter_table_rename final : public PT_alter_table_action {
3407   typedef PT_alter_table_action super;
3408 
3409  public:
PT_alter_table_rename(const Table_ident * ident)3410   explicit PT_alter_table_rename(const Table_ident *ident)
3411       : super(Alter_info::ALTER_RENAME), m_ident(ident) {}
3412 
3413   bool contextualize(Table_ddl_parse_context *pc) override;
3414 
is_rename_table()3415   bool is_rename_table() const override { return true; }
3416 
3417  private:
3418   const Table_ident *const m_ident;
3419 };
3420 
3421 class PT_alter_table_rename_key final : public PT_alter_table_action {
3422   typedef PT_alter_table_action super;
3423 
3424  public:
PT_alter_table_rename_key(const char * from,const char * to)3425   PT_alter_table_rename_key(const char *from, const char *to)
3426       : super(Alter_info::ALTER_RENAME_INDEX), m_rename_key(from, to) {}
3427 
contextualize(Table_ddl_parse_context * pc)3428   bool contextualize(Table_ddl_parse_context *pc) override {
3429     return super::contextualize(pc) ||
3430            pc->alter_info->alter_rename_key_list.push_back(&m_rename_key);
3431   }
3432 
3433  private:
3434   Alter_rename_key m_rename_key;
3435 };
3436 
3437 class PT_alter_table_rename_column final : public PT_alter_table_action {
3438   typedef PT_alter_table_action super;
3439 
3440  public:
PT_alter_table_rename_column(const char * from,const char * to)3441   PT_alter_table_rename_column(const char *from, const char *to)
3442       : super(Alter_info::ALTER_CHANGE_COLUMN), m_rename_column(from, to) {}
3443 
contextualize(Table_ddl_parse_context * pc)3444   bool contextualize(Table_ddl_parse_context *pc) override {
3445     return super::contextualize(pc) ||
3446            pc->alter_info->alter_list.push_back(&m_rename_column);
3447   }
3448 
3449  private:
3450   Alter_column m_rename_column;
3451 };
3452 
3453 class PT_alter_table_convert_to_charset final : public PT_alter_table_action {
3454   typedef PT_alter_table_action super;
3455 
3456  public:
PT_alter_table_convert_to_charset(const CHARSET_INFO * charset,const CHARSET_INFO * opt_collation)3457   PT_alter_table_convert_to_charset(const CHARSET_INFO *charset,
3458                                     const CHARSET_INFO *opt_collation)
3459       : super(Alter_info::ALTER_OPTIONS),
3460         m_charset(charset),
3461         m_collation(opt_collation) {}
3462 
3463   bool contextualize(Table_ddl_parse_context *pc) override;
3464 
3465  private:
3466   const CHARSET_INFO *const m_charset;
3467   const CHARSET_INFO *const m_collation;
3468 };
3469 
3470 class PT_alter_table_force final : public PT_alter_table_action {
3471   typedef PT_alter_table_action super;
3472 
3473  public:
PT_alter_table_force()3474   PT_alter_table_force() : super(Alter_info::ALTER_RECREATE) {}
3475 };
3476 
3477 class PT_alter_table_order final : public PT_alter_table_action {
3478   typedef PT_alter_table_action super;
3479 
3480  public:
PT_alter_table_order(PT_order_list * order)3481   explicit PT_alter_table_order(PT_order_list *order)
3482       : super(Alter_info::ALTER_ORDER), m_order(order) {}
3483 
3484   bool contextualize(Table_ddl_parse_context *pc) override;
3485 
3486  private:
3487   PT_order_list *const m_order;
3488 };
3489 
3490 class PT_alter_table_partition_by final : public PT_alter_table_action {
3491   typedef PT_alter_table_action super;
3492 
3493  public:
PT_alter_table_partition_by(PT_partition * partition)3494   explicit PT_alter_table_partition_by(PT_partition *partition)
3495       : super(Alter_info::ALTER_PARTITION), m_partition(partition) {}
3496 
3497   bool contextualize(Table_ddl_parse_context *pc) override;
3498 
3499  private:
3500   PT_partition *const m_partition;
3501 };
3502 
3503 class PT_alter_table_remove_partitioning : public PT_alter_table_action {
3504   typedef PT_alter_table_action super;
3505 
3506  public:
PT_alter_table_remove_partitioning()3507   PT_alter_table_remove_partitioning()
3508       : super(Alter_info::ALTER_REMOVE_PARTITIONING) {}
3509 };
3510 
3511 class PT_alter_table_standalone_action : public PT_alter_table_action {
3512   typedef PT_alter_table_action super;
3513 
3514   friend class PT_alter_table_standalone_stmt;  // to access make_cmd()
3515 
3516  protected:
PT_alter_table_standalone_action(Alter_info::Alter_info_flag alter_info_flag)3517   PT_alter_table_standalone_action(Alter_info::Alter_info_flag alter_info_flag)
3518       : super(alter_info_flag) {}
3519 
3520  private:
3521   virtual Sql_cmd *make_cmd(Table_ddl_parse_context *pc) = 0;
3522 };
3523 
3524 /**
3525   Node for the @SQL{ALTER TABLE ADD PARTITION} statement
3526 
3527   @ingroup ptn_alter_table
3528 */
3529 class PT_alter_table_add_partition : public PT_alter_table_standalone_action {
3530   typedef PT_alter_table_standalone_action super;
3531 
3532  public:
PT_alter_table_add_partition(bool no_write_to_binlog)3533   explicit PT_alter_table_add_partition(bool no_write_to_binlog)
3534       : super(Alter_info::ALTER_ADD_PARTITION),
3535         m_no_write_to_binlog(no_write_to_binlog) {}
3536 
3537   bool contextualize(Table_ddl_parse_context *pc) override;
3538 
make_cmd(Table_ddl_parse_context * pc)3539   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override final {
3540     return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
3541   }
3542 
3543  protected:
3544   partition_info m_part_info;
3545 
3546  private:
3547   const bool m_no_write_to_binlog;
3548 };
3549 
3550 /**
3551   Node for the @SQL{ALTER TABLE ADD PARTITION (@<partition list@>)} statement
3552 
3553   @ingroup ptn_alter_table
3554 */
3555 class PT_alter_table_add_partition_def_list final
3556     : public PT_alter_table_add_partition {
3557   typedef PT_alter_table_add_partition super;
3558 
3559  public:
PT_alter_table_add_partition_def_list(bool no_write_to_binlog,const Mem_root_array<PT_part_definition * > * def_list)3560   PT_alter_table_add_partition_def_list(
3561       bool no_write_to_binlog,
3562       const Mem_root_array<PT_part_definition *> *def_list)
3563       : super(no_write_to_binlog), m_def_list(def_list) {}
3564 
3565   bool contextualize(Table_ddl_parse_context *pc) override;
3566 
3567  private:
3568   const Mem_root_array<PT_part_definition *> *m_def_list;
3569 };
3570 
3571 /**
3572   Node for the @SQL{ALTER TABLE ADD PARTITION PARTITIONS (@<n>@)} statement
3573 
3574   @ingroup ptn_alter_table
3575 */
3576 class PT_alter_table_add_partition_num final
3577     : public PT_alter_table_add_partition {
3578   typedef PT_alter_table_add_partition super;
3579 
3580  public:
PT_alter_table_add_partition_num(bool no_write_to_binlog,uint num_parts)3581   PT_alter_table_add_partition_num(bool no_write_to_binlog, uint num_parts)
3582       : super(no_write_to_binlog) {
3583     m_part_info.num_parts = num_parts;
3584   }
3585 };
3586 
3587 class PT_alter_table_drop_partition final
3588     : public PT_alter_table_standalone_action {
3589   typedef PT_alter_table_standalone_action super;
3590 
3591  public:
PT_alter_table_drop_partition(const List<String> & partitions)3592   explicit PT_alter_table_drop_partition(const List<String> &partitions)
3593       : super(Alter_info::ALTER_DROP_PARTITION), m_partitions(partitions) {}
3594 
3595   bool contextualize(Table_ddl_parse_context *pc) override;
3596 
make_cmd(Table_ddl_parse_context * pc)3597   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override final {
3598     return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
3599   }
3600 
3601  private:
3602   const List<String> m_partitions;
3603 };
3604 
3605 class PT_alter_table_partition_list_or_all
3606     : public PT_alter_table_standalone_action {
3607   typedef PT_alter_table_standalone_action super;
3608 
3609  public:
PT_alter_table_partition_list_or_all(Alter_info::Alter_info_flag alter_info_flag,const List<String> * opt_partition_list)3610   explicit PT_alter_table_partition_list_or_all(
3611       Alter_info::Alter_info_flag alter_info_flag,
3612       const List<String> *opt_partition_list)
3613       : super(alter_info_flag), m_opt_partition_list(opt_partition_list) {}
3614 
contextualize(Table_ddl_parse_context * pc)3615   bool contextualize(Table_ddl_parse_context *pc) override {
3616     DBUG_ASSERT(pc->alter_info->partition_names.is_empty());
3617     if (m_opt_partition_list == nullptr)
3618       pc->alter_info->flags |= Alter_info::ALTER_ALL_PARTITION;
3619     else
3620       pc->alter_info->partition_names = *m_opt_partition_list;
3621     return super::contextualize(pc);
3622   }
3623 
3624  private:
3625   const List<String> *m_opt_partition_list;
3626 };
3627 
3628 class PT_alter_table_rebuild_partition final
3629     : public PT_alter_table_partition_list_or_all {
3630   typedef PT_alter_table_partition_list_or_all super;
3631 
3632  public:
PT_alter_table_rebuild_partition(bool no_write_to_binlog,const List<String> * opt_partition_list)3633   PT_alter_table_rebuild_partition(bool no_write_to_binlog,
3634                                    const List<String> *opt_partition_list)
3635       : super(Alter_info::ALTER_REBUILD_PARTITION, opt_partition_list),
3636         m_no_write_to_binlog(no_write_to_binlog) {}
3637 
3638   bool contextualize(Table_ddl_parse_context *pc) override;
3639 
make_cmd(Table_ddl_parse_context * pc)3640   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3641     return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
3642   }
3643 
3644  private:
3645   const bool m_no_write_to_binlog;
3646 };
3647 
3648 class PT_alter_table_optimize_partition final
3649     : public PT_alter_table_partition_list_or_all {
3650   typedef PT_alter_table_partition_list_or_all super;
3651 
3652  public:
PT_alter_table_optimize_partition(bool no_write_to_binlog,const List<String> * opt_partition_list)3653   PT_alter_table_optimize_partition(bool no_write_to_binlog,
3654                                     const List<String> *opt_partition_list)
3655       : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
3656         m_no_write_to_binlog(no_write_to_binlog) {}
3657 
3658   bool contextualize(Table_ddl_parse_context *pc) override;
3659 
make_cmd(Table_ddl_parse_context * pc)3660   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3661     return new (pc->mem_root)
3662         Sql_cmd_alter_table_optimize_partition(pc->alter_info);
3663   }
3664 
3665  private:
3666   const bool m_no_write_to_binlog;
3667 };
3668 
3669 class PT_alter_table_analyze_partition
3670     : public PT_alter_table_partition_list_or_all {
3671   typedef PT_alter_table_partition_list_or_all super;
3672 
3673  public:
PT_alter_table_analyze_partition(bool no_write_to_binlog,const List<String> * opt_partition_list)3674   PT_alter_table_analyze_partition(bool no_write_to_binlog,
3675                                    const List<String> *opt_partition_list)
3676       : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
3677         m_no_write_to_binlog(no_write_to_binlog) {}
3678 
3679   bool contextualize(Table_ddl_parse_context *pc) override;
make_cmd(Table_ddl_parse_context * pc)3680   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3681     return new (pc->mem_root)
3682         Sql_cmd_alter_table_analyze_partition(pc->thd, pc->alter_info);
3683   }
3684 
3685  private:
3686   const bool m_no_write_to_binlog;
3687 };
3688 
3689 class PT_alter_table_check_partition
3690     : public PT_alter_table_partition_list_or_all {
3691   typedef PT_alter_table_partition_list_or_all super;
3692 
3693  public:
PT_alter_table_check_partition(const List<String> * opt_partition_list,uint flags,uint sql_flags)3694   PT_alter_table_check_partition(const List<String> *opt_partition_list,
3695                                  uint flags, uint sql_flags)
3696       : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
3697         m_flags(flags),
3698         m_sql_flags(sql_flags) {}
3699 
3700   bool contextualize(Table_ddl_parse_context *pc) override;
3701 
make_cmd(Table_ddl_parse_context * pc)3702   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3703     return new (pc->mem_root)
3704         Sql_cmd_alter_table_check_partition(pc->alter_info);
3705   }
3706 
3707  private:
3708   uint m_flags;
3709   uint m_sql_flags;
3710 };
3711 
3712 class PT_alter_table_repair_partition
3713     : public PT_alter_table_partition_list_or_all {
3714   typedef PT_alter_table_partition_list_or_all super;
3715 
3716  public:
PT_alter_table_repair_partition(bool no_write_to_binlog,const List<String> * opt_partition_list,uint flags,uint sql_flags)3717   PT_alter_table_repair_partition(bool no_write_to_binlog,
3718                                   const List<String> *opt_partition_list,
3719                                   uint flags, uint sql_flags)
3720       : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
3721         m_no_write_to_binlog(no_write_to_binlog),
3722         m_flags(flags),
3723         m_sql_flags(sql_flags) {}
3724 
3725   bool contextualize(Table_ddl_parse_context *pc) override;
3726 
make_cmd(Table_ddl_parse_context * pc)3727   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3728     return new (pc->mem_root)
3729         Sql_cmd_alter_table_repair_partition(pc->alter_info);
3730   }
3731 
3732  private:
3733   const bool m_no_write_to_binlog;
3734   uint m_flags;
3735   uint m_sql_flags;
3736 };
3737 
3738 class PT_alter_table_coalesce_partition final
3739     : public PT_alter_table_standalone_action {
3740   typedef PT_alter_table_standalone_action super;
3741 
3742  public:
PT_alter_table_coalesce_partition(bool no_write_to_binlog,uint num_parts)3743   PT_alter_table_coalesce_partition(bool no_write_to_binlog, uint num_parts)
3744       : super(Alter_info::ALTER_COALESCE_PARTITION),
3745         m_no_write_to_binlog(no_write_to_binlog),
3746         m_num_parts(num_parts) {}
3747 
3748   bool contextualize(Table_ddl_parse_context *pc) override;
3749 
make_cmd(Table_ddl_parse_context * pc)3750   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3751     return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
3752   }
3753 
3754  private:
3755   const bool m_no_write_to_binlog;
3756   const uint m_num_parts;
3757 };
3758 
3759 class PT_alter_table_truncate_partition
3760     : public PT_alter_table_partition_list_or_all {
3761   typedef PT_alter_table_partition_list_or_all super;
3762 
3763  public:
PT_alter_table_truncate_partition(const List<String> * opt_partition_list)3764   explicit PT_alter_table_truncate_partition(
3765       const List<String> *opt_partition_list)
3766       : super(static_cast<Alter_info::Alter_info_flag>(
3767                   Alter_info::ALTER_ADMIN_PARTITION |
3768                   Alter_info::ALTER_TRUNCATE_PARTITION),
3769               opt_partition_list) {}
3770 
3771   bool contextualize(Table_ddl_parse_context *pc) override;
3772 
make_cmd(Table_ddl_parse_context * pc)3773   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3774     return new (pc->mem_root)
3775         Sql_cmd_alter_table_truncate_partition(pc->alter_info);
3776   }
3777 };
3778 
3779 class PT_alter_table_reorganize_partition final
3780     : public PT_alter_table_standalone_action {
3781   typedef PT_alter_table_standalone_action super;
3782 
3783  public:
PT_alter_table_reorganize_partition(bool no_write_to_binlog)3784   explicit PT_alter_table_reorganize_partition(bool no_write_to_binlog)
3785       : super(Alter_info::ALTER_TABLE_REORG),
3786         m_no_write_to_binlog(no_write_to_binlog) {}
3787 
3788   bool contextualize(Table_ddl_parse_context *pc) override;
3789 
make_cmd(Table_ddl_parse_context * pc)3790   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3791     return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
3792   }
3793 
3794  private:
3795   const bool m_no_write_to_binlog;
3796   partition_info m_partition_info;
3797 };
3798 
3799 class PT_alter_table_reorganize_partition_into final
3800     : public PT_alter_table_standalone_action {
3801   typedef PT_alter_table_standalone_action super;
3802 
3803  public:
PT_alter_table_reorganize_partition_into(bool no_write_to_binlog,const List<String> & partition_names,const Mem_root_array<PT_part_definition * > * into)3804   explicit PT_alter_table_reorganize_partition_into(
3805       bool no_write_to_binlog, const List<String> &partition_names,
3806       const Mem_root_array<PT_part_definition *> *into)
3807       : super(Alter_info::ALTER_REORGANIZE_PARTITION),
3808         m_no_write_to_binlog(no_write_to_binlog),
3809         m_partition_names(partition_names),
3810         m_into(into) {}
3811 
3812   bool contextualize(Table_ddl_parse_context *pc) override;
3813 
make_cmd(Table_ddl_parse_context * pc)3814   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3815     return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
3816   }
3817 
3818  private:
3819   const bool m_no_write_to_binlog;
3820   const List<String> m_partition_names;
3821   const Mem_root_array<PT_part_definition *> *m_into;
3822   partition_info m_partition_info;
3823 };
3824 
3825 class PT_alter_table_exchange_partition final
3826     : public PT_alter_table_standalone_action {
3827   typedef PT_alter_table_standalone_action super;
3828 
3829  public:
PT_alter_table_exchange_partition(const LEX_STRING & partition_name,Table_ident * table_name,Alter_info::enum_with_validation validation)3830   PT_alter_table_exchange_partition(const LEX_STRING &partition_name,
3831                                     Table_ident *table_name,
3832                                     Alter_info::enum_with_validation validation)
3833       : super(Alter_info::ALTER_EXCHANGE_PARTITION),
3834         m_partition_name(partition_name),
3835         m_table_name(table_name),
3836         m_validation(validation) {}
3837 
3838   bool contextualize(Table_ddl_parse_context *pc) override;
3839 
make_cmd(Table_ddl_parse_context * pc)3840   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3841     return new (pc->mem_root)
3842         Sql_cmd_alter_table_exchange_partition(pc->alter_info);
3843   }
3844 
3845  private:
3846   const LEX_STRING m_partition_name;
3847   Table_ident *m_table_name;
3848   const Alter_info::enum_with_validation m_validation;
3849 };
3850 
3851 class PT_alter_table_secondary_load final
3852     : public PT_alter_table_standalone_action {
3853   using super = PT_alter_table_standalone_action;
3854 
3855  public:
PT_alter_table_secondary_load()3856   explicit PT_alter_table_secondary_load()
3857       : super(Alter_info::ALTER_SECONDARY_LOAD) {}
3858 
make_cmd(Table_ddl_parse_context * pc)3859   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3860     return new (pc->mem_root) Sql_cmd_secondary_load_unload(pc->alter_info);
3861   }
3862 };
3863 
3864 class PT_alter_table_secondary_unload final
3865     : public PT_alter_table_standalone_action {
3866   using super = PT_alter_table_standalone_action;
3867 
3868  public:
PT_alter_table_secondary_unload()3869   explicit PT_alter_table_secondary_unload()
3870       : super(Alter_info::ALTER_SECONDARY_UNLOAD) {}
3871 
make_cmd(Table_ddl_parse_context * pc)3872   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3873     return new (pc->mem_root) Sql_cmd_secondary_load_unload(pc->alter_info);
3874   }
3875 };
3876 
3877 class PT_alter_table_discard_partition_tablespace final
3878     : public PT_alter_table_partition_list_or_all {
3879   typedef PT_alter_table_partition_list_or_all super;
3880 
3881  public:
PT_alter_table_discard_partition_tablespace(const List<String> * opt_partition_list)3882   explicit PT_alter_table_discard_partition_tablespace(
3883       const List<String> *opt_partition_list)
3884       : super(Alter_info::ALTER_DISCARD_TABLESPACE, opt_partition_list) {}
3885 
make_cmd(Table_ddl_parse_context * pc)3886   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3887     return new (pc->mem_root) Sql_cmd_discard_import_tablespace(pc->alter_info);
3888   }
3889 };
3890 
3891 class PT_alter_table_import_partition_tablespace final
3892     : public PT_alter_table_partition_list_or_all {
3893   typedef PT_alter_table_partition_list_or_all super;
3894 
3895  public:
PT_alter_table_import_partition_tablespace(const List<String> * opt_partition_list)3896   explicit PT_alter_table_import_partition_tablespace(
3897       const List<String> *opt_partition_list)
3898       : super(Alter_info::ALTER_IMPORT_TABLESPACE, opt_partition_list) {}
3899 
make_cmd(Table_ddl_parse_context * pc)3900   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3901     return new (pc->mem_root) Sql_cmd_discard_import_tablespace(pc->alter_info);
3902   }
3903 };
3904 
3905 class PT_alter_table_discard_tablespace final
3906     : public PT_alter_table_standalone_action {
3907   typedef PT_alter_table_standalone_action super;
3908 
3909  public:
PT_alter_table_discard_tablespace()3910   PT_alter_table_discard_tablespace()
3911       : super(Alter_info::ALTER_DISCARD_TABLESPACE) {}
3912 
make_cmd(Table_ddl_parse_context * pc)3913   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3914     return new (pc->mem_root) Sql_cmd_discard_import_tablespace(pc->alter_info);
3915   }
3916 };
3917 
3918 class PT_alter_table_import_tablespace final
3919     : public PT_alter_table_standalone_action {
3920   typedef PT_alter_table_standalone_action super;
3921 
3922  public:
PT_alter_table_import_tablespace()3923   PT_alter_table_import_tablespace()
3924       : super(Alter_info::ALTER_IMPORT_TABLESPACE) {}
3925 
make_cmd(Table_ddl_parse_context * pc)3926   Sql_cmd *make_cmd(Table_ddl_parse_context *pc) override {
3927     return new (pc->mem_root) Sql_cmd_discard_import_tablespace(pc->alter_info);
3928   }
3929 };
3930 
3931 class PT_alter_table_stmt final : public PT_table_ddl_stmt_base {
3932  public:
PT_alter_table_stmt(MEM_ROOT * mem_root,Table_ident * table_name,Mem_root_array<PT_ddl_table_option * > * opt_actions,Alter_info::enum_alter_table_algorithm algo,Alter_info::enum_alter_table_lock lock,Alter_info::enum_with_validation validation)3933   explicit PT_alter_table_stmt(
3934       MEM_ROOT *mem_root, Table_ident *table_name,
3935       Mem_root_array<PT_ddl_table_option *> *opt_actions,
3936       Alter_info::enum_alter_table_algorithm algo,
3937       Alter_info::enum_alter_table_lock lock,
3938       Alter_info::enum_with_validation validation)
3939       : PT_table_ddl_stmt_base(mem_root),
3940         m_table_name(table_name),
3941         m_opt_actions(opt_actions),
3942         m_algo(algo),
3943         m_lock(lock),
3944         m_validation(validation) {}
3945 
3946   Sql_cmd *make_cmd(THD *thd) override;
3947 
3948  private:
3949   Table_ident *const m_table_name;
3950   Mem_root_array<PT_ddl_table_option *> *const m_opt_actions;
3951   const Alter_info::enum_alter_table_algorithm m_algo;
3952   const Alter_info::enum_alter_table_lock m_lock;
3953   const Alter_info::enum_with_validation m_validation;
3954 
3955   HA_CREATE_INFO m_create_info;
3956 };
3957 
3958 class PT_alter_table_standalone_stmt final : public PT_table_ddl_stmt_base {
3959  public:
PT_alter_table_standalone_stmt(MEM_ROOT * mem_root,Table_ident * table_name,PT_alter_table_standalone_action * action,Alter_info::enum_alter_table_algorithm algo,Alter_info::enum_alter_table_lock lock,Alter_info::enum_with_validation validation)3960   explicit PT_alter_table_standalone_stmt(
3961       MEM_ROOT *mem_root, Table_ident *table_name,
3962       PT_alter_table_standalone_action *action,
3963       Alter_info::enum_alter_table_algorithm algo,
3964       Alter_info::enum_alter_table_lock lock,
3965       Alter_info::enum_with_validation validation)
3966       : PT_table_ddl_stmt_base(mem_root),
3967         m_table_name(table_name),
3968         m_action(action),
3969         m_algo(algo),
3970         m_lock(lock),
3971         m_validation(validation) {}
3972 
3973   Sql_cmd *make_cmd(THD *thd) override;
3974 
3975  private:
3976   Table_ident *const m_table_name;
3977   PT_alter_table_standalone_action *const m_action;
3978   const Alter_info::enum_alter_table_algorithm m_algo;
3979   const Alter_info::enum_alter_table_lock m_lock;
3980   const Alter_info::enum_with_validation m_validation;
3981 
3982   HA_CREATE_INFO m_create_info;
3983 };
3984 
3985 class PT_repair_table_stmt final : public PT_table_ddl_stmt_base {
3986  public:
PT_repair_table_stmt(MEM_ROOT * mem_root,bool no_write_to_binlog,Mem_root_array<Table_ident * > * table_list,decltype (HA_CHECK_OPT::flags)flags,decltype (HA_CHECK_OPT::sql_flags)sql_flags)3987   PT_repair_table_stmt(MEM_ROOT *mem_root, bool no_write_to_binlog,
3988                        Mem_root_array<Table_ident *> *table_list,
3989                        decltype(HA_CHECK_OPT::flags) flags,
3990                        decltype(HA_CHECK_OPT::sql_flags) sql_flags)
3991       : PT_table_ddl_stmt_base(mem_root),
3992         m_no_write_to_binlog(no_write_to_binlog),
3993         m_table_list(table_list),
3994         m_flags(flags),
3995         m_sql_flags(sql_flags) {}
3996 
3997   Sql_cmd *make_cmd(THD *thd) override;
3998 
3999  private:
4000   bool m_no_write_to_binlog;
4001   Mem_root_array<Table_ident *> *m_table_list;
4002   decltype(HA_CHECK_OPT::flags) m_flags;
4003   decltype(HA_CHECK_OPT::sql_flags) m_sql_flags;
4004 };
4005 
4006 class PT_analyze_table_stmt final : public PT_table_ddl_stmt_base {
4007  public:
PT_analyze_table_stmt(MEM_ROOT * mem_root,bool no_write_to_binlog,Mem_root_array<Table_ident * > * table_list,Sql_cmd_analyze_table::Histogram_command command,int num_buckets,List<String> * columns)4008   PT_analyze_table_stmt(MEM_ROOT *mem_root, bool no_write_to_binlog,
4009                         Mem_root_array<Table_ident *> *table_list,
4010                         Sql_cmd_analyze_table::Histogram_command command,
4011                         int num_buckets, List<String> *columns)
4012       : PT_table_ddl_stmt_base(mem_root),
4013         m_no_write_to_binlog(no_write_to_binlog),
4014         m_table_list(table_list),
4015         m_command(command),
4016         m_num_buckets(num_buckets),
4017         m_columns(columns) {}
4018 
4019   Sql_cmd *make_cmd(THD *thd) override;
4020 
4021  private:
4022   const bool m_no_write_to_binlog;
4023   const Mem_root_array<Table_ident *> *m_table_list;
4024   const Sql_cmd_analyze_table::Histogram_command m_command;
4025   const int m_num_buckets;
4026   List<String> *m_columns;
4027 };
4028 
4029 class PT_check_table_stmt final : public PT_table_ddl_stmt_base {
4030  public:
PT_check_table_stmt(MEM_ROOT * mem_root,Mem_root_array<Table_ident * > * table_list,decltype (HA_CHECK_OPT::flags)flags,decltype (HA_CHECK_OPT::sql_flags)sql_flags)4031   PT_check_table_stmt(MEM_ROOT *mem_root,
4032                       Mem_root_array<Table_ident *> *table_list,
4033                       decltype(HA_CHECK_OPT::flags) flags,
4034                       decltype(HA_CHECK_OPT::sql_flags) sql_flags)
4035       : PT_table_ddl_stmt_base(mem_root),
4036         m_table_list(table_list),
4037         m_flags(flags),
4038         m_sql_flags(sql_flags) {}
4039 
4040   Sql_cmd *make_cmd(THD *thd) override;
4041 
4042  private:
4043   Mem_root_array<Table_ident *> *m_table_list;
4044   decltype(HA_CHECK_OPT::flags) m_flags;
4045   decltype(HA_CHECK_OPT::sql_flags) m_sql_flags;
4046 };
4047 
4048 class PT_optimize_table_stmt final : public PT_table_ddl_stmt_base {
4049  public:
PT_optimize_table_stmt(MEM_ROOT * mem_root,bool no_write_to_binlog,Mem_root_array<Table_ident * > * table_list)4050   PT_optimize_table_stmt(MEM_ROOT *mem_root, bool no_write_to_binlog,
4051                          Mem_root_array<Table_ident *> *table_list)
4052       : PT_table_ddl_stmt_base(mem_root),
4053         m_no_write_to_binlog(no_write_to_binlog),
4054         m_table_list(table_list) {}
4055 
4056   Sql_cmd *make_cmd(THD *thd) override;
4057 
4058   bool m_no_write_to_binlog;
4059   Mem_root_array<Table_ident *> *m_table_list;
4060 };
4061 
4062 class PT_drop_index_stmt final : public PT_table_ddl_stmt_base {
4063  public:
PT_drop_index_stmt(MEM_ROOT * mem_root,const char * index_name,Table_ident * table,Alter_info::enum_alter_table_algorithm algo,Alter_info::enum_alter_table_lock lock)4064   PT_drop_index_stmt(MEM_ROOT *mem_root, const char *index_name,
4065                      Table_ident *table,
4066                      Alter_info::enum_alter_table_algorithm algo,
4067                      Alter_info::enum_alter_table_lock lock)
4068       : PT_table_ddl_stmt_base(mem_root),
4069         m_index_name(index_name),
4070         m_table(table),
4071         m_algo(algo),
4072         m_lock(lock),
4073         m_alter_drop(Alter_drop::KEY, m_index_name) {}
4074 
4075   Sql_cmd *make_cmd(THD *thd) override;
4076 
4077  private:
4078   const char *m_index_name;
4079   Table_ident *m_table;
4080   Alter_info::enum_alter_table_algorithm m_algo;
4081   Alter_info::enum_alter_table_lock m_lock;
4082 
4083   Alter_drop m_alter_drop;
4084 };
4085 
4086 class PT_truncate_table_stmt final : public Parse_tree_root {
4087  public:
PT_truncate_table_stmt(Table_ident * table)4088   explicit PT_truncate_table_stmt(Table_ident *table) : m_table(table) {}
4089 
4090   Sql_cmd *make_cmd(THD *thd) override;
4091 
4092  private:
4093   Table_ident *m_table;
4094 
4095   Sql_cmd_truncate_table m_cmd_truncate_table;
4096 };
4097 
4098 class PT_assign_to_keycache final : public Table_ddl_node {
4099   typedef Table_ddl_node super;
4100 
4101  public:
PT_assign_to_keycache(Table_ident * table,List<Index_hint> * index_hints)4102   PT_assign_to_keycache(Table_ident *table, List<Index_hint> *index_hints)
4103       : m_table(table), m_index_hints(index_hints) {}
4104 
4105   bool contextualize(Table_ddl_parse_context *pc) override;
4106 
4107  private:
4108   Table_ident *m_table;
4109   List<Index_hint> *m_index_hints;
4110 };
4111 
4112 class PT_adm_partition final : public Table_ddl_node {
4113   typedef Table_ddl_node super;
4114 
4115  public:
PT_adm_partition(List<String> * opt_partitions)4116   explicit PT_adm_partition(List<String> *opt_partitions)
4117       : m_opt_partitions(opt_partitions) {}
4118 
4119   bool contextualize(Table_ddl_parse_context *pc) override;
4120 
4121  private:
4122   List<String> *m_opt_partitions;
4123 };
4124 
4125 class PT_cache_index_stmt final : public PT_table_ddl_stmt_base {
4126  public:
PT_cache_index_stmt(MEM_ROOT * mem_root,Mem_root_array<PT_assign_to_keycache * > * tbl_index_lists,const LEX_CSTRING & key_cache_name)4127   PT_cache_index_stmt(MEM_ROOT *mem_root,
4128                       Mem_root_array<PT_assign_to_keycache *> *tbl_index_lists,
4129                       const LEX_CSTRING &key_cache_name)
4130       : PT_table_ddl_stmt_base(mem_root),
4131         m_tbl_index_lists(tbl_index_lists),
4132         m_key_cache_name(key_cache_name) {}
4133 
4134   Sql_cmd *make_cmd(THD *thd) override;
4135 
4136  private:
4137   Mem_root_array<PT_assign_to_keycache *> *m_tbl_index_lists;
4138   const LEX_CSTRING m_key_cache_name;
4139 };
4140 
4141 class PT_cache_index_partitions_stmt : public PT_table_ddl_stmt_base {
4142  public:
PT_cache_index_partitions_stmt(MEM_ROOT * mem_root,Table_ident * table,PT_adm_partition * partitions,List<Index_hint> * opt_key_usage_list,const LEX_CSTRING & key_cache_name)4143   PT_cache_index_partitions_stmt(MEM_ROOT *mem_root, Table_ident *table,
4144                                  PT_adm_partition *partitions,
4145                                  List<Index_hint> *opt_key_usage_list,
4146                                  const LEX_CSTRING &key_cache_name)
4147       : PT_table_ddl_stmt_base(mem_root),
4148         m_table(table),
4149         m_partitions(partitions),
4150         m_opt_key_usage_list(opt_key_usage_list),
4151         m_key_cache_name(key_cache_name) {}
4152 
4153   Sql_cmd *make_cmd(THD *thd) override;
4154 
4155  private:
4156   Table_ident *m_table;
4157   PT_adm_partition *m_partitions;
4158   List<Index_hint> *m_opt_key_usage_list;
4159   const LEX_CSTRING m_key_cache_name;
4160 };
4161 
4162 class PT_preload_keys final : public Table_ddl_node {
4163   typedef Table_ddl_node super;
4164 
4165  public:
PT_preload_keys(Table_ident * table,List<Index_hint> * opt_cache_key_list,bool ignore_leaves)4166   PT_preload_keys(Table_ident *table, List<Index_hint> *opt_cache_key_list,
4167                   bool ignore_leaves)
4168       : m_table(table),
4169         m_opt_cache_key_list(opt_cache_key_list),
4170         m_ignore_leaves(ignore_leaves) {}
4171 
4172   bool contextualize(Table_ddl_parse_context *pc) override;
4173 
4174  private:
4175   Table_ident *m_table;
4176   List<Index_hint> *m_opt_cache_key_list;
4177   bool m_ignore_leaves;
4178 };
4179 
4180 class PT_load_index_partitions_stmt final : public PT_table_ddl_stmt_base {
4181  public:
PT_load_index_partitions_stmt(MEM_ROOT * mem_root,Table_ident * table,PT_adm_partition * partitions,List<Index_hint> * opt_cache_key_list,bool ignore_leaves)4182   PT_load_index_partitions_stmt(MEM_ROOT *mem_root, Table_ident *table,
4183                                 PT_adm_partition *partitions,
4184                                 List<Index_hint> *opt_cache_key_list,
4185                                 bool ignore_leaves)
4186       : PT_table_ddl_stmt_base(mem_root),
4187         m_table(table),
4188         m_partitions(partitions),
4189         m_opt_cache_key_list(opt_cache_key_list),
4190         m_ignore_leaves(ignore_leaves) {}
4191 
4192   Sql_cmd *make_cmd(THD *thd) override;
4193 
4194  private:
4195   Table_ident *m_table;
4196   PT_adm_partition *m_partitions;
4197   List<Index_hint> *m_opt_cache_key_list;
4198   bool m_ignore_leaves;
4199 };
4200 
4201 class PT_load_index_stmt final : public PT_table_ddl_stmt_base {
4202  public:
PT_load_index_stmt(MEM_ROOT * mem_root,Mem_root_array<PT_preload_keys * > * preload_list)4203   PT_load_index_stmt(MEM_ROOT *mem_root,
4204                      Mem_root_array<PT_preload_keys *> *preload_list)
4205       : PT_table_ddl_stmt_base(mem_root), m_preload_list(preload_list) {}
4206 
4207   Sql_cmd *make_cmd(THD *thd) override;
4208 
4209  private:
4210   Mem_root_array<PT_preload_keys *> *m_preload_list;
4211 };
4212 
4213 /**
4214   Base class for Parse tree nodes of SHOW TABLES statements.
4215 */
4216 class PT_show_tables : public Parse_tree_root {
4217  public:
PT_show_tables(const POS & pos,Show_cmd_type show_cmd_type,char * opt_db,const LEX_STRING & wild,Item * where_condition)4218   PT_show_tables(const POS &pos, Show_cmd_type show_cmd_type, char *opt_db,
4219                  const LEX_STRING &wild, Item *where_condition)
4220       : m_pos(pos),
4221         m_sql_cmd(SQLCOM_SHOW_TABLES),
4222         m_opt_db(opt_db),
4223         m_wild(wild),
4224         m_where_condition(where_condition),
4225         m_show_cmd_type(show_cmd_type) {
4226     DBUG_ASSERT(m_wild.str == nullptr || m_where_condition == nullptr);
4227   }
4228 
4229  public:
4230   Sql_cmd *make_cmd(THD *thd) override;
4231 
4232  private:
4233   /// Textual location of a token just parsed.
4234   POS m_pos;
4235 
4236   /// Sql_cmd for SHOW TABLES statements.
4237   Sql_cmd_show m_sql_cmd;
4238 
4239   /// Optional schema name in FROM/IN clause.
4240   char *m_opt_db;
4241 
4242   /// Wild or where clause used in the statement.
4243   LEX_STRING m_wild;
4244   Item *m_where_condition;
4245 
4246   Show_cmd_type m_show_cmd_type;
4247 };
4248 
4249 class PT_json_table_column_for_ordinality final : public PT_json_table_column {
4250   typedef PT_json_table_column super;
4251 
4252  public:
4253   explicit PT_json_table_column_for_ordinality(LEX_STRING name);
4254   ~PT_json_table_column_for_ordinality() override;
4255   bool contextualize(Parse_context *pc) override;
get_column()4256   Json_table_column *get_column() override { return m_column.get(); }
4257 
4258  private:
4259   unique_ptr_destroy_only<Json_table_column> m_column;
4260   const char *m_name;
4261 };
4262 
4263 class PT_json_table_column_with_path final : public PT_json_table_column {
4264   typedef PT_json_table_column super;
4265 
4266  public:
4267   PT_json_table_column_with_path(
4268       unique_ptr_destroy_only<Json_table_column> column, LEX_STRING name,
4269       PT_type *type, const CHARSET_INFO *collation);
4270   ~PT_json_table_column_with_path() override;
4271 
4272   bool contextualize(Parse_context *pc) override;
4273 
get_column()4274   Json_table_column *get_column() override { return m_column.get(); }
4275 
4276  private:
4277   unique_ptr_destroy_only<Json_table_column> m_column;
4278   const char *m_name;
4279   PT_type *m_type;
4280   const CHARSET_INFO *m_collation;
4281 };
4282 
4283 class PT_json_table_column_with_nested_path final
4284     : public PT_json_table_column {
4285   typedef PT_json_table_column super;
4286 
4287  public:
PT_json_table_column_with_nested_path(Item * path,Mem_root_array<PT_json_table_column * > * nested_cols)4288   PT_json_table_column_with_nested_path(
4289       Item *path, Mem_root_array<PT_json_table_column *> *nested_cols)
4290       : m_path(path), m_nested_columns(nested_cols) {}
4291 
4292   bool contextualize(Parse_context *pc) override;
4293 
get_column()4294   Json_table_column *get_column() override { return m_column; }
4295 
4296  private:
4297   Item *m_path;
4298   const Mem_root_array<PT_json_table_column *> *m_nested_columns;
4299   Json_table_column *m_column{nullptr};
4300 };
4301 
4302 struct Alter_tablespace_parse_context : public Tablespace_options {
4303   THD *const thd;
4304   MEM_ROOT *const mem_root;
4305 
4306   explicit Alter_tablespace_parse_context(THD *thd);
4307 };
4308 
4309 typedef Parse_tree_node_tmpl<Alter_tablespace_parse_context>
4310     PT_alter_tablespace_option_base;
4311 
4312 template <typename Option_type, Option_type Tablespace_options::*Option>
4313 class PT_alter_tablespace_option final
4314     : public PT_alter_tablespace_option_base /* purecov: inspected */
4315 {
4316   typedef PT_alter_tablespace_option_base super;
4317 
4318  public:
PT_alter_tablespace_option(Option_type value)4319   explicit PT_alter_tablespace_option(Option_type value) : m_value(value) {}
4320 
contextualize(Alter_tablespace_parse_context * pc)4321   bool contextualize(Alter_tablespace_parse_context *pc) override {
4322     pc->*Option = m_value;
4323     return super::contextualize(pc);
4324   }
4325 
4326  private:
4327   const Option_type m_value;
4328 };
4329 
4330 typedef PT_alter_tablespace_option<decltype(
4331                                        Tablespace_options::autoextend_size),
4332                                    &Tablespace_options::autoextend_size>
4333     PT_alter_tablespace_option_autoextend_size;
4334 
4335 typedef PT_alter_tablespace_option<decltype(Tablespace_options::extent_size),
4336                                    &Tablespace_options::extent_size>
4337     PT_alter_tablespace_option_extent_size;
4338 
4339 typedef PT_alter_tablespace_option<decltype(Tablespace_options::initial_size),
4340                                    &Tablespace_options::initial_size>
4341     PT_alter_tablespace_option_initial_size;
4342 
4343 typedef PT_alter_tablespace_option<decltype(Tablespace_options::max_size),
4344                                    &Tablespace_options::max_size>
4345     PT_alter_tablespace_option_max_size;
4346 
4347 typedef PT_alter_tablespace_option<decltype(
4348                                        Tablespace_options::redo_buffer_size),
4349                                    &Tablespace_options::redo_buffer_size>
4350     PT_alter_tablespace_option_redo_buffer_size;
4351 
4352 typedef PT_alter_tablespace_option<decltype(
4353                                        Tablespace_options::undo_buffer_size),
4354                                    &Tablespace_options::undo_buffer_size>
4355     PT_alter_tablespace_option_undo_buffer_size;
4356 
4357 typedef PT_alter_tablespace_option<
4358     decltype(Tablespace_options::wait_until_completed),
4359     &Tablespace_options::wait_until_completed>
4360     PT_alter_tablespace_option_wait_until_completed;
4361 
4362 typedef PT_alter_tablespace_option<decltype(Tablespace_options::encryption),
4363                                    &Tablespace_options::encryption>
4364     PT_alter_tablespace_option_encryption;
4365 
4366 class PT_alter_tablespace_option_nodegroup final
4367     : public PT_alter_tablespace_option_base /* purecov: inspected */
4368 {
4369   typedef PT_alter_tablespace_option_base super;
4370   typedef decltype(Tablespace_options::nodegroup_id) option_type;
4371 
4372  public:
PT_alter_tablespace_option_nodegroup(option_type nodegroup_id)4373   explicit PT_alter_tablespace_option_nodegroup(option_type nodegroup_id)
4374       : m_nodegroup_id(nodegroup_id) {}
4375 
4376   bool contextualize(Alter_tablespace_parse_context *pc) override;
4377 
4378  private:
4379   const option_type m_nodegroup_id;
4380 };
4381 
4382 class PT_alter_tablespace_option_comment final
4383     : public PT_alter_tablespace_option_base /* purecov: inspected */
4384 {
4385   typedef PT_alter_tablespace_option_base super;
4386   typedef decltype(Tablespace_options::ts_comment) option_type;
4387 
4388  public:
PT_alter_tablespace_option_comment(option_type comment)4389   explicit PT_alter_tablespace_option_comment(option_type comment)
4390       : m_comment(comment) {}
4391 
contextualize(Alter_tablespace_parse_context * pc)4392   bool contextualize(Alter_tablespace_parse_context *pc) override {
4393     if (super::contextualize(pc)) return true; /* purecov: inspected */  // OOM
4394 
4395     if (pc->ts_comment.str) {
4396       my_error(ER_FILEGROUP_OPTION_ONLY_ONCE, MYF(0), "COMMENT");
4397       return true;
4398     }
4399     pc->ts_comment = m_comment;
4400     return false;
4401   }
4402 
4403  private:
4404   const option_type m_comment;
4405 };
4406 
4407 class PT_alter_tablespace_option_engine final
4408     : public PT_alter_tablespace_option_base /* purecov: inspected */
4409 {
4410   typedef PT_alter_tablespace_option_base super;
4411   typedef decltype(Tablespace_options::engine_name) option_type;
4412 
4413  public:
PT_alter_tablespace_option_engine(option_type engine_name)4414   explicit PT_alter_tablespace_option_engine(option_type engine_name)
4415       : m_engine_name(engine_name) {}
4416 
contextualize(Alter_tablespace_parse_context * pc)4417   bool contextualize(Alter_tablespace_parse_context *pc) override {
4418     if (super::contextualize(pc)) return true; /* purecov: inspected */  // OOM
4419 
4420     if (pc->engine_name.str) {
4421       my_error(ER_FILEGROUP_OPTION_ONLY_ONCE, MYF(0), "STORAGE ENGINE");
4422       return true;
4423     }
4424     pc->engine_name = m_engine_name;
4425     return false;
4426   }
4427 
4428  private:
4429   const option_type m_engine_name;
4430 };
4431 
4432 class PT_alter_tablespace_option_file_block_size final
4433     : public PT_alter_tablespace_option_base /* purecov: inspected */
4434 {
4435   typedef PT_alter_tablespace_option_base super;
4436   typedef decltype(Tablespace_options::file_block_size) option_type;
4437 
4438  public:
PT_alter_tablespace_option_file_block_size(option_type file_block_size)4439   explicit PT_alter_tablespace_option_file_block_size(
4440       option_type file_block_size)
4441       : m_file_block_size(file_block_size) {}
4442 
contextualize(Alter_tablespace_parse_context * pc)4443   bool contextualize(Alter_tablespace_parse_context *pc) override {
4444     if (super::contextualize(pc)) return true; /* purecov: inspected */  // OOM
4445 
4446     if (pc->file_block_size != 0) {
4447       my_error(ER_FILEGROUP_OPTION_ONLY_ONCE, MYF(0), "FILE_BLOCK_SIZE");
4448       return true;
4449     }
4450     pc->file_block_size = m_file_block_size;
4451     return false;
4452   }
4453 
4454  private:
4455   const option_type m_file_block_size;
4456 };
4457 
4458 /**
4459   Parse tree node for CREATE RESOURCE GROUP statement.
4460 */
4461 
4462 class PT_create_resource_group final : public Parse_tree_root {
4463   resourcegroups::Sql_cmd_create_resource_group sql_cmd;
4464   const bool has_priority;
4465 
4466  public:
PT_create_resource_group(const LEX_CSTRING & name,const resourcegroups::Type type,const Mem_root_array<resourcegroups::Range> * cpu_list,const Value_or_default<int> & opt_priority,bool enabled)4467   PT_create_resource_group(
4468       const LEX_CSTRING &name, const resourcegroups::Type type,
4469       const Mem_root_array<resourcegroups::Range> *cpu_list,
4470       const Value_or_default<int> &opt_priority, bool enabled)
4471       : sql_cmd(name, type, cpu_list,
4472                 opt_priority.is_default ? 0 : opt_priority.value, enabled),
4473         has_priority(!opt_priority.is_default) {}
4474 
4475   Sql_cmd *make_cmd(THD *thd) override;
4476 };
4477 
4478 /**
4479   Parse tree node for ALTER RESOURCE GROUP statement.
4480 */
4481 
4482 class PT_alter_resource_group final : public Parse_tree_root {
4483   resourcegroups::Sql_cmd_alter_resource_group sql_cmd;
4484 
4485  public:
PT_alter_resource_group(const LEX_CSTRING & name,const Mem_root_array<resourcegroups::Range> * cpu_list,const Value_or_default<int> & opt_priority,const Value_or_default<bool> & enable,bool force)4486   PT_alter_resource_group(const LEX_CSTRING &name,
4487                           const Mem_root_array<resourcegroups::Range> *cpu_list,
4488                           const Value_or_default<int> &opt_priority,
4489                           const Value_or_default<bool> &enable, bool force)
4490       : sql_cmd(name, cpu_list,
4491                 opt_priority.is_default ? 0 : opt_priority.value,
4492                 enable.is_default ? false : enable.value, force,
4493                 !enable.is_default) {}
4494 
4495   Sql_cmd *make_cmd(THD *thd) override;
4496 };
4497 
4498 /**
4499   Parse tree node for DROP RESOURCE GROUP statement.
4500 */
4501 
4502 class PT_drop_resource_group final : public Parse_tree_root {
4503   resourcegroups::Sql_cmd_drop_resource_group sql_cmd;
4504 
4505  public:
PT_drop_resource_group(const LEX_CSTRING & resource_group_name,bool force)4506   PT_drop_resource_group(const LEX_CSTRING &resource_group_name, bool force)
4507       : sql_cmd(resource_group_name, force) {}
4508 
4509   Sql_cmd *make_cmd(THD *thd) override;
4510 };
4511 
4512 /**
4513   Parse tree node for SET RESOURCE GROUP statement.
4514 */
4515 
4516 class PT_set_resource_group final : public Parse_tree_root {
4517   resourcegroups::Sql_cmd_set_resource_group sql_cmd;
4518 
4519  public:
PT_set_resource_group(const LEX_CSTRING & name,Mem_root_array<ulonglong> * thread_id_list)4520   PT_set_resource_group(const LEX_CSTRING &name,
4521                         Mem_root_array<ulonglong> *thread_id_list)
4522       : sql_cmd(name, thread_id_list) {}
4523 
4524   Sql_cmd *make_cmd(THD *thd) override;
4525 };
4526 
4527 class PT_explain_for_connection final : public Parse_tree_root {
4528  public:
PT_explain_for_connection(my_thread_id thread_id)4529   explicit PT_explain_for_connection(my_thread_id thread_id)
4530       : m_cmd(thread_id) {}
4531 
4532   Sql_cmd *make_cmd(THD *thd) override;
4533 
4534  private:
4535   Sql_cmd_explain_other_thread m_cmd;
4536 };
4537 
4538 class PT_explain final : public Parse_tree_root {
4539  public:
PT_explain(Explain_format_type format,Parse_tree_root * explainable_stmt)4540   PT_explain(Explain_format_type format, Parse_tree_root *explainable_stmt)
4541       : m_format(format), m_explainable_stmt(explainable_stmt) {}
4542 
4543   Sql_cmd *make_cmd(THD *thd) override;
4544 
4545  private:
4546   const Explain_format_type m_format;
4547   Parse_tree_root *const m_explainable_stmt;
4548 };
4549 
4550 class PT_load_table final : public Parse_tree_root {
4551  public:
PT_load_table(enum_filetype filetype,thr_lock_type lock_type,bool is_local_file,const LEX_STRING filename,On_duplicate on_duplicate,Table_ident * table,List<String> * opt_partitions,const CHARSET_INFO * opt_charset,String * opt_xml_rows_identified_by,const Field_separators & opt_field_separators,const Line_separators & opt_line_separators,ulong opt_ignore_lines,PT_item_list * opt_fields_or_vars,PT_item_list * opt_set_fields,PT_item_list * opt_set_exprs,List<String> * opt_set_expr_strings)4552   PT_load_table(enum_filetype filetype, thr_lock_type lock_type,
4553                 bool is_local_file, const LEX_STRING filename,
4554                 On_duplicate on_duplicate, Table_ident *table,
4555                 List<String> *opt_partitions, const CHARSET_INFO *opt_charset,
4556                 String *opt_xml_rows_identified_by,
4557                 const Field_separators &opt_field_separators,
4558                 const Line_separators &opt_line_separators,
4559                 ulong opt_ignore_lines, PT_item_list *opt_fields_or_vars,
4560                 PT_item_list *opt_set_fields, PT_item_list *opt_set_exprs,
4561                 List<String> *opt_set_expr_strings)
4562       : m_cmd(filetype, is_local_file, filename, on_duplicate, table,
4563               opt_partitions, opt_charset, opt_xml_rows_identified_by,
4564               opt_field_separators, opt_line_separators, opt_ignore_lines,
4565               opt_fields_or_vars ? &opt_fields_or_vars->value : nullptr,
4566               opt_set_fields ? &opt_set_fields->value : nullptr,
4567               opt_set_exprs ? &opt_set_exprs->value : nullptr,
4568               opt_set_expr_strings),
4569         m_lock_type(lock_type),
4570         m_opt_fields_or_vars(opt_fields_or_vars),
4571         m_opt_set_fields(opt_set_fields),
4572         m_opt_set_exprs(opt_set_exprs) {
4573     DBUG_ASSERT((opt_set_fields == nullptr) ^ (opt_set_exprs != nullptr));
4574     DBUG_ASSERT(opt_set_fields == nullptr || opt_set_fields->value.elements ==
4575                                                  opt_set_exprs->value.elements);
4576   }
4577 
4578   Sql_cmd *make_cmd(THD *thd) override;
4579 
4580  private:
4581   Sql_cmd_load_table m_cmd;
4582 
4583   const thr_lock_type m_lock_type;
4584   PT_item_list *m_opt_fields_or_vars;
4585   PT_item_list *m_opt_set_fields;
4586   PT_item_list *m_opt_set_exprs;
4587 };
4588 
4589 /**
4590   Top-level node for the SHUTDOWN statement
4591 
4592   @ingroup ptn_stmt
4593 */
4594 
4595 class PT_restart_server final : public Parse_tree_root {
4596  public:
4597   Sql_cmd *make_cmd(THD *thd) override;
4598 
4599  private:
4600   Sql_cmd_restart_server sql_cmd;
4601 };
4602 
4603 PT_alter_tablespace_option_base *make_tablespace_engine_attribute(MEM_ROOT *,
4604                                                                   LEX_CSTRING);
4605 
4606 PT_create_table_option *make_table_engine_attribute(MEM_ROOT *, LEX_CSTRING);
4607 PT_create_table_option *make_table_secondary_engine_attribute(MEM_ROOT *,
4608                                                               LEX_CSTRING);
4609 
4610 PT_column_attr_base *make_column_engine_attribute(MEM_ROOT *, LEX_CSTRING);
4611 PT_column_attr_base *make_column_secondary_engine_attribute(MEM_ROOT *,
4612                                                             LEX_CSTRING);
4613 
4614 PT_base_index_option *make_index_engine_attribute(MEM_ROOT *, LEX_CSTRING);
4615 PT_base_index_option *make_index_secondary_engine_attribute(MEM_ROOT *,
4616                                                             LEX_CSTRING);
4617 #endif /* PARSE_TREE_NODES_INCLUDED */
4618