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