MySQL  8.0.16
Source Code Documentation
parse_tree_nodes.h
Go to the documentation of this file.
1 /* Copyright (c) 2013, 2019, 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 <limits>
30 
31 #include "binlog_event.h" // UNDEFINED_SERVER_VERSION
32 #include "lex_string.h"
33 #include "m_ctype.h"
34 #include "my_base.h"
35 #include "my_bit.h" // is_single_bit
36 #include "my_dbug.h"
37 #include "my_inttypes.h"
38 #include "my_sqlcommand.h"
39 #include "my_sys.h"
40 #include "my_thread_local.h"
41 #include "my_time.h"
42 #include "mysql/mysql_lex_string.h"
43 #include "mysqld_error.h"
45 #include "sql/enum_query_type.h"
46 #include "sql/handler.h"
47 #include "sql/item.h"
48 #include "sql/item_func.h"
49 #include "sql/key_spec.h"
50 #include "sql/mdl.h"
51 #include "sql/mem_root_array.h"
52 #include "sql/mysqld.h" // table_alias_charset
53 #include "sql/opt_explain.h" // Sql_cmd_explain_other_thread
54 #include "sql/parse_location.h"
55 #include "sql/parse_tree_helpers.h" // PT_item_list
58 #include "sql/partition_info.h"
59 #include "sql/query_result.h" // Query_result
62 #include "sql/set_var.h"
63 #include "sql/sp_head.h" // sp_head
64 #include "sql/sql_admin.h" // Sql_cmd_shutdown etc.
65 #include "sql/sql_alter.h"
66 #include "sql/sql_check_constraint.h" // Sql_check_constraint_spec
67 #include "sql/sql_class.h" // THD
68 #include "sql/sql_cmd_srs.h"
69 #include "sql/sql_exchange.h"
70 #include "sql/sql_lex.h" // LEX
71 #include "sql/sql_list.h"
72 #include "sql/sql_load.h" // Sql_cmd_load_table
73 #include "sql/sql_parse.h" // add_join_natural
75 #include "sql/sql_restart_server.h" // Sql_cmd_restart_server
76 #include "sql/sql_show.h"
77 #include "sql/sql_tablespace.h" // Tablespace_options
78 #include "sql/sql_truncate.h" // Sql_cmd_truncate_table
79 #include "sql/table.h" // Common_table_expr
80 #include "sql/table_function.h" // Json_table_column
81 #include "sql/window.h" // Window
82 #include "sql/window_lex.h"
83 #include "sql_string.h"
84 #include "thr_lock.h"
85 
86 class PT_field_def_base;
87 class PT_hint_list;
89 class PT_subquery;
90 class PT_type;
91 class Sql_cmd;
92 struct MEM_ROOT;
93 
94 /**
95  @defgroup ptn Parse tree nodes
96  @ingroup Parser
97 */
98 /**
99  @defgroup ptn_stmt Nodes representing SQL statements
100  @ingroup ptn
101 */
102 /**
103  @defgroup ptn_create_table CREATE TABLE statement
104  @ingroup ptn_stmt
105 */
106 /**
107  @defgroup ptn_alter_table ALTER TABLE statement
108  @ingroup ptn_stmt
109 */
110 /**
111  @defgroup ptn_create_table_stuff Clauses of CREATE TABLE statement
112  @ingroup ptn_create_table
113 */
114 /**
115  @defgroup ptn_partitioning CREATE/ALTER TABLE partitioning-related stuff
116  @ingroup ptn_create_table ptn_alter_table
117 */
118 /**
119  @defgroup ptn_part_options Partition options in CREATE/ALTER TABLE
120  @ingroup ptn_partitioning
121 */
122 /**
123  @defgroup ptn_create_or_alter_table_options Table options of CREATE/ALTER
124  TABLE
125  @anchor ptn_create_or_alter_table_options
126  @ingroup ptn_create_table ptn_alter_table
127 */
128 /**
129  @defgroup ptn_col_types Column types in CREATE/ALTER TABLE
130  @ingroup ptn_create_table ptn_alter_table
131 */
132 /**
133  @defgroup ptn_col_attrs Column attributes in CREATE/ALTER TABLE
134  @ingroup ptn_create_table ptn_alter_table
135 */
136 /**
137  @defgroup ptn_not_gcol_attr Non-generated column attributes in CREATE/ALTER
138  TABLE
139  @ingroup ptn_col_attrs ptn_alter_table
140 */
141 
142 /**
143  Calls contextualize() on every node in the array.
144 */
145 template <class Node_type, class Parse_context_type>
147  Parse_context_type *pc) {
148  for (Node_type *i : nodes)
149  if (i->contextualize(pc)) return true;
150  return false;
151 }
152 
153 /**
154  Base class for all top-level nodes of SQL statements
155 
156  @ingroup ptn_stmt
157 */
159  Parse_tree_root(const Parse_tree_root &) = delete;
160  void operator=(const Parse_tree_root &) = delete;
161 
162  protected:
163  virtual ~Parse_tree_root() {}
165 
166  public:
167  virtual Sql_cmd *make_cmd(THD *thd) = 0;
168 };
169 
171  public:
173  : m_alter_info(mem_root) {}
174 
175  virtual ~PT_table_ddl_stmt_base() = 0; // force abstract class
176 
177  protected:
179 };
180 
182 
183 /**
184  Convenience function that calls Parse_tree_node::contextualize() on the node
185  if it's non-NULL.
186 */
187 template <class Context, class Node>
188 bool contextualize_safe(Context *pc, Node *node) {
189  if (node == NULL) return false;
190 
191  return node->contextualize(pc);
192 }
193 
194 /**
195  Parse context for the table DDL (ALTER TABLE and CREATE TABLE) nodes.
196 
197  For internal use in the contextualization code.
198 */
200  Table_ddl_parse_context(THD *thd_arg, SELECT_LEX *select_arg,
202  : Parse_context(thd_arg, select_arg),
203  create_info(thd_arg->lex->create_info),
205  key_create_info(&thd_arg->lex->key_create_info) {}
206 
210 };
211 
212 /**
213  Base class for all table DDL (ALTER TABLE and CREATE TABLE) nodes.
214 */
216 
217 /**
218  Convenience function that calls Item::itemize() on the item if it's
219  non-NULL.
220 */
221 inline bool itemize_safe(Parse_context *pc, Item **item) {
222  if (*item == NULL) return false;
223  return (*item)->itemize(pc, item);
224 }
225 
226 class PT_order_expr : public Parse_tree_node, public ORDER {
228 
229  public:
230  PT_order_expr(Item *item_arg, enum_order dir) {
231  item_ptr = item_arg;
232  direction = (dir == ORDER_DESC) ? ORDER_DESC : ORDER_ASC;
233  }
234 
235  virtual bool contextualize(Parse_context *pc) {
236  return super::contextualize(pc) || item_ptr->itemize(pc, &item_ptr);
237  }
238 };
239 
242 
243  public:
245 
246  public:
247  virtual bool contextualize(Parse_context *pc) {
248  if (super::contextualize(pc)) return true;
249  for (ORDER *o = value.first; o != NULL; o = o->next) {
250  if (static_cast<PT_order_expr *>(o)->contextualize(pc)) return true;
251  }
252  return false;
253  }
254 
255  void push_back(PT_order_expr *order) {
256  order->item = &order->item_ptr;
257  order->used_alias = false;
258  order->used = 0;
259  order->is_position = false;
260  value.link_in_list(order, &order->next);
261  }
262 };
263 
266 
267  public:
268  virtual bool contextualize(Parse_context *pc) {
269  return super::contextualize(pc);
270  }
271 };
272 
273 /**
274  Represents an element of the WITH list:
275  WITH [...], [...] SELECT ...,
276  ^ or ^
277  i.e. a Common Table Expression (CTE, or Query Name in SQL99 terms).
278 */
281 
282  public:
283  explicit PT_common_table_expr(const LEX_STRING &name,
284  const LEX_STRING &subq_text,
285  uint subq_text_offset, PT_subquery *sn,
287  MEM_ROOT *mem_root);
288 
289  /// The name after AS
290  const LEX_STRING &name() const { return m_name; }
291  /**
292  @param thd Thread handler
293  @param[out] node PT_subquery
294  @returns a PT_subquery to attach to a table reference for this CTE
295  */
296  bool make_subquery_node(THD *thd, PT_subquery **node);
297  /**
298  @param tl Table reference to match
299  @param in_self If this is a recursive reference
300  @param[out] found Is set to true/false if matches or not
301  @returns true if error
302  */
303  bool match_table_ref(TABLE_LIST *tl, bool in_self, bool *found);
304  /**
305  @returns true if 'other' is the same instance as 'this'
306  */
307  bool is(const Common_table_expr *other) const {
308  return other == &m_postparse;
309  }
310  void print(const THD *thd, String *str, enum_query_type query_type);
311 
312  private:
314  /// Raw text of query expression (including parentheses)
316  /**
317  Offset in bytes of m_subq_text in original statement which had the WITH
318  clause.
319  */
321  /// Parsed version of subq_text
323  /// List of explicitely specified column names; if empty, no list.
325  /**
326  A TABLE_LIST representing a CTE needs access to the WITH list
327  element it derives from. However, in order to:
328  - limit the members which TABLE_LIST can access
329  - avoid including this header file everywhere TABLE_LIST needs to access
330  these members,
331  these members are relocated into a separate inferior object whose
332  declaration is in table.h, like that of TABLE_LIST. It's the "postparse"
333  part. TABLE_LIST accesses this inferior object only.
334  */
336 
337  friend bool SELECT_LEX_UNIT::clear_corr_ctes();
338 };
339 
340 /**
341  Represents the WITH list.
342  WITH [...], [...] SELECT ...,
343  ^^^^^^^^^^^^
344 */
347 
348  public:
349  /// @param mem_root where interior objects are allocated
353  return m_elements;
354  }
355 
356  private:
358 };
359 
360 /**
361  Represents the WITH clause:
362  WITH [...], [...] SELECT ...,
363  ^^^^^^^^^^^^^^^^^
364 */
367 
368  public:
369  PT_with_clause(const PT_with_list *l, bool r)
370  : m_list(l), m_recursive(r), m_most_inner_in_parsing(nullptr) {}
371 
372  virtual bool contextualize(Parse_context *pc) {
373  if (super::contextualize(pc)) return true; /* purecov: inspected */
374  // WITH complements a query expression (a unit).
375  pc->select->master_unit()->m_with_clause = this;
376  return false;
377  }
378 
379  /**
380  Looks up a table reference into the list of CTEs.
381  @param tl Table reference to look up
382  @param[out] found Is set to true/false if found or not
383  @returns true if error
384  */
385  bool lookup(TABLE_LIST *tl, PT_common_table_expr **found);
386  /**
387  Call this to record in the WITH clause that we are contextualizing the
388  CTE definition inserted in table reference 'tl'.
389  @returns information which the caller must provide to
390  leave_parsing_definition().
391  */
393  auto old = m_most_inner_in_parsing;
395  return old;
396  }
399  }
400  void print(const THD *thd, String *str, enum_query_type query_type);
401 
402  private:
403  /// All CTEs of this clause
404  const PT_with_list *const m_list;
405  /// True if the user has specified the RECURSIVE keyword.
406  const bool m_recursive;
407  /**
408  The innermost CTE reference which we're parsing at the
409  moment. Used to detect forward references, loops and recursiveness.
410  */
412 
413  friend bool SELECT_LEX_UNIT::clear_corr_ctes();
414 };
415 
418 
419  public:
420  virtual bool contextualize(Parse_context *pc) {
421  if (super::contextualize(pc)) return true;
422 
423  pc->select->item_list = value;
424  return false;
425  }
426 };
427 
430 
432 
433  public:
434  PT_limit_clause(const Limit_options &limit_options_arg)
435  : limit_options(limit_options_arg) {}
436 
437  virtual bool contextualize(Parse_context *pc) {
438  if (super::contextualize(pc)) return true;
439 
440  if (pc->select->master_unit()->is_union() && !pc->select->braces) {
442  DBUG_ASSERT(pc->select != NULL);
443  }
444 
447  return true;
448 
449  if (limit_options.limit->itemize(pc, &limit_options.limit)) return true;
450 
453  return true;
454 
457  pc->select->explicit_limit = true;
458 
460  return false;
461  }
462 };
463 
464 class PT_cross_join;
465 class PT_joined_table;
466 
468  public:
470 
471  /**
472  Lets us build a parse tree top-down, which is necessary due to the
473  context-dependent nature of the join syntax. This function adds
474  the `<table_ref>` cross join as the left-most leaf in this join tree
475  rooted at this node.
476 
477  @todo: comment on non-join PT_table_reference objects
478 
479  @param cj This `<table ref>` will be added if it represents a cross join.
480 
481  @return The new top-level join.
482  */
484 };
485 
488 
491  const char *const opt_table_alias;
493 
494  public:
496  List<String> *opt_use_partition_arg,
497  const LEX_CSTRING &opt_table_alias_arg,
498  List<Index_hint> *opt_key_definition_arg)
499  : table_ident(table_ident_arg),
500  opt_use_partition(opt_use_partition_arg),
501  opt_table_alias(opt_table_alias_arg.str),
502  opt_key_definition(opt_key_definition_arg) {}
503 
504  virtual bool contextualize(Parse_context *pc) {
505  if (super::contextualize(pc)) return true;
506 
507  THD *thd = pc->thd;
508  Yacc_state *yyps = &thd->m_parser_state->m_yacc;
509 
511  thd, table_ident, opt_table_alias, 0, yyps->m_lock_type,
512  yyps->m_mdl_type, opt_key_definition, opt_use_partition, nullptr, pc);
513  if (value == NULL) return true;
514  if (pc->select->add_joined_table(value)) return true;
515  return false;
516  }
517 };
518 
520  public:
521  virtual Json_table_column *get_column() = 0;
522 };
523 
526 
527  public:
530  const LEX_STRING &table_alias)
531  : m_expr(expr),
532  m_path(path),
533  m_nested_columns(nested_cols),
534  m_table_alias(table_alias) {}
535 
536  bool contextualize(Parse_context *pc) override;
537 
538  private:
543 };
544 
547 
549 
550  public:
553  : table_list(table_list) {}
554 
555  virtual bool contextualize(Parse_context *pc) {
557  return true;
558 
559  DBUG_ASSERT(table_list.size() >= 2);
560  value = pc->select->nest_last_join(pc->thd, table_list.size());
561  return value == NULL;
562  }
563 };
564 
567 
568  public:
569  PT_derived_table(bool lateral, PT_subquery *subquery,
570  const LEX_CSTRING &table_alias,
572 
573  virtual bool contextualize(Parse_context *pc);
574 
575  private:
576  bool m_lateral;
578  const char *const m_table_alias;
579  /// List of explicitely specified column names; if empty, no list.
581 };
582 
585 
586  public:
588  : m_joined_table(joined_table) {}
589 
590  virtual bool contextualize(Parse_context *pc);
591 
592  private:
594 };
595 
598 
599  protected:
604 
607 
608  public:
609  PT_joined_table(PT_table_reference *tab1_node_arg, const POS &join_pos_arg,
611  : tab1_node(tab1_node_arg),
612  join_pos(join_pos_arg),
613  m_type(type),
614  tab2_node(tab2_node_arg),
615  tr1(NULL),
616  tr2(NULL) {
617  static_assert(is_single_bit(JTT_INNER), "not a single bit");
618  static_assert(is_single_bit(JTT_STRAIGHT), "not a single bit");
619  static_assert(is_single_bit(JTT_NATURAL), "not a single bit");
620  static_assert(is_single_bit(JTT_LEFT), "not a single bit");
621  static_assert(is_single_bit(JTT_RIGHT), "not a single bit");
622 
625  type == JTT_NATURAL_RIGHT || type == JTT_LEFT ||
626  type == JTT_RIGHT);
627  }
628 
629  /**
630  Adds the cross join to this join operation. The cross join is nested as
631  the table reference on the left-hand side.
632  */
635  return this;
636  }
637 
638  /// Adds the table reference as the right-hand side of this join.
641  tab2_node = table;
642  }
643 
645  if (super::contextualize(pc) || contextualize_tabs(pc)) return true;
646 
647  if (m_type & (JTT_LEFT | JTT_RIGHT)) {
648  if (m_type & JTT_LEFT)
650  else {
651  TABLE_LIST *inner_table = pc->select->convert_right_join();
652  if (inner_table == NULL) return true;
653  /* swap tr1 and tr2 */
654  DBUG_ASSERT(inner_table == tr1);
655  tr1 = tr2;
656  tr2 = inner_table;
657  }
658  }
659 
661 
662  if (m_type & JTT_STRAIGHT) tr2->straight = true;
663 
664  return false;
665  }
666 
667  /// This class is being inherited, it should thus be abstract.
668  ~PT_joined_table() = 0;
669 
670  protected:
672  if (tr1 != NULL) return false; // already done
673 
675  return true;
676 
677  tr1 = tab1_node->value;
678  tr2 = tab2_node->value;
679 
680  if (tr1 == NULL || tr2 == NULL) {
681  error(pc, join_pos);
682  return true;
683  }
684  return false;
685  }
686 };
687 
689 
692 
693  public:
694  PT_cross_join(PT_table_reference *tab1_node_arg, const POS &join_pos_arg,
695  PT_joined_table_type Type_arg,
696  PT_table_reference *tab2_node_arg)
697  : PT_joined_table(tab1_node_arg, join_pos_arg, Type_arg, tab2_node_arg) {}
698 
699  virtual bool contextualize(Parse_context *pc) {
700  if (super::contextualize(pc)) return true;
701  value = pc->select->nest_last_join(pc->thd);
702  return value == NULL;
703  }
704 };
705 
709 
710  public:
711  PT_joined_table_on(PT_table_reference *tab1_node_arg, const POS &join_pos_arg,
713  PT_table_reference *tab2_node_arg, Item *on_arg)
714  : super(tab1_node_arg, join_pos_arg, type, tab2_node_arg), on(on_arg) {}
715 
716  virtual bool contextualize(Parse_context *pc) {
717  if (this->contextualize_tabs(pc)) return true;
718 
719  if (push_new_name_resolution_context(pc, this->tr1, this->tr2)) {
720  this->error(pc, this->join_pos);
721  return true;
722  }
723 
724  SELECT_LEX *sel = pc->select;
725  sel->parsing_place = CTX_ON;
726 
727  if (super::contextualize(pc) || on->itemize(pc, &on)) return true;
728  DBUG_ASSERT(sel == pc->select);
729 
730  add_join_on(this->tr2, on);
731  pc->thd->lex->pop_context();
733  sel->parsing_place = CTX_NONE;
734  value = pc->select->nest_last_join(pc->thd);
735  return value == NULL;
736  }
737 };
738 
742 
743  public:
745  const POS &join_pos_arg, PT_joined_table_type type,
746  PT_table_reference *tab2_node_arg,
747  List<String> *using_fields_arg)
748  : super(tab1_node_arg, join_pos_arg, type, tab2_node_arg),
749  using_fields(using_fields_arg) {}
750 
751  /// A PT_joined_table_using without a list of columns denotes a natural join.
753  const POS &join_pos_arg, PT_joined_table_type type,
754  PT_table_reference *tab2_node_arg)
755  : PT_joined_table_using(tab1_node_arg, join_pos_arg, type, tab2_node_arg,
756  NULL) {}
757 
758  virtual bool contextualize(Parse_context *pc) {
759  if (super::contextualize(pc)) return true;
760 
762  value = pc->select->nest_last_join(pc->thd);
763  if (value == NULL) return true;
765 
766  return false;
767  }
768 };
769 
770 class PT_group : public Parse_tree_node {
772 
775 
776  public:
777  PT_group(PT_order_list *group_list_arg, olap_type olap_arg)
778  : group_list(group_list_arg), olap(olap_arg) {}
779 
780  virtual bool contextualize(Parse_context *pc);
781 };
782 
783 class PT_order : public Parse_tree_node {
785 
787 
788  public:
789  explicit PT_order(PT_order_list *order_list_arg)
790  : order_list(order_list_arg) {}
791 
792  virtual bool contextualize(Parse_context *pc);
793 };
794 
796  public:
799 
800  virtual bool contextualize(Parse_context *pc) final;
801 
802  virtual bool set_lock_for_tables(Parse_context *pc) = 0;
803 
804  virtual bool is_legacy_syntax() const = 0;
805 
807 
808  protected:
810  thr_lock_type lock_type = TL_IGNORE;
811  switch (m_lock_strength) {
813  lock_type = TL_WRITE;
814  break;
816  lock_type = TL_READ_WITH_SHARED_LOCKS;
817  break;
818  }
819 
820  return {lock_type, static_cast<thr_locked_row_action>(action())};
821  }
822 
823  private:
826 };
827 
829  public:
832  : PT_locking_clause(strength, action),
833  m_is_legacy_syntax(strength == Lock_strength::UPDATE &&
835 
839 
840  bool set_lock_for_tables(Parse_context *pc) override;
841 
842  bool is_legacy_syntax() const override { return m_is_legacy_syntax; }
843 
844  private:
846 };
847 
849  public:
851 
855  : PT_locking_clause(strength, action), m_tables(tables) {}
856 
857  bool set_lock_for_tables(Parse_context *pc) override;
858 
859  bool is_legacy_syntax() const override { return false; }
860 
861  private:
862  /// @todo Move this function to Table_ident?
863  void print_table_ident(const THD *thd, const Table_ident *ident, String *s) {
864  LEX_CSTRING db = ident->db;
865  LEX_CSTRING table = ident->table;
866  if (db.length > 0) {
867  append_identifier(thd, s, db.str, db.length);
868  s->append('.');
869  }
870  append_identifier(thd, s, table.str, table.length);
871  }
872 
873  bool raise_error(THD *thd, const Table_ident *name, int error) {
874  String s;
875  print_table_ident(thd, name, &s);
876  my_error(error, MYF(0), s.ptr());
877  return true;
878  }
879 
880  bool raise_error(int error) {
881  my_error(error, MYF(0));
882  return true;
883  }
884 
886 };
887 
889  public:
892  }
893 
894  bool push_back(PT_locking_clause *locking_clause) {
895  return m_locking_clauses.push_back(locking_clause);
896  }
897 
898  bool is_legacy_syntax() const {
899  return m_locking_clauses.size() == 1 &&
900  m_locking_clauses[0]->is_legacy_syntax();
901  }
902 
904  for (auto locking_clause : m_locking_clauses)
905  if (locking_clause->contextualize(pc)) return true;
906  return false;
907  }
908 
909  private:
911 };
912 
914  public:
915  virtual bool is_union() const = 0;
917  virtual bool has_into_clause() const = 0;
918 };
919 
921  public:
923 };
924 
927 
929 
930  public:
932  : ident(ident_arg) {}
933 
934  virtual bool contextualize(Parse_context *pc);
935 };
936 
937 /**
938  Parse tree node class for 2-dimentional variable names (example: \@global.x)
939 */
942 
943  public:
944  const POS pos;
945 
946  private:
949 
950  public:
951  PT_internal_variable_name_2d(const POS &pos, const LEX_STRING &ident1_arg,
952  const LEX_STRING &ident2_arg)
953  : pos(pos), ident1(ident1_arg), ident2(ident2_arg) {}
954 
955  virtual bool contextualize(Parse_context *pc);
956 };
957 
960 
962 
963  public:
965  : ident(ident_arg) {}
966 
967  virtual bool contextualize(Parse_context *pc) {
968  if (super::contextualize(pc)) return true;
969 
970  sys_var *tmp = find_sys_var(pc->thd, ident.str, ident.length);
971  if (!tmp) return true;
972  if (!tmp->is_struct()) {
973  my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), ident.str);
974  return true;
975  }
976  value.var = tmp;
977  value.base_name.str = (char *)"default";
978  value.base_name.length = 7;
979  return false;
980  }
981 };
982 
985 
989 
990  public:
992  PT_internal_variable_name *name_arg,
993  Item *opt_expr_arg)
994  : pos(pos), name(name_arg), opt_expr(opt_expr_arg) {}
995 
996  virtual bool contextualize(Parse_context *pc) {
997  if (super::contextualize(pc) || name->contextualize(pc) ||
998  (opt_expr != NULL && opt_expr->itemize(pc, &opt_expr)))
999  return true;
1000 
1002  /* It is a system variable. */
1003  if (set_system_variable(pc->thd, &name->value, pc->thd->lex->option_type,
1004  opt_expr))
1005  return true;
1006  } else {
1007  /*
1008  Not in trigger assigning value to new row,
1009  and option_type preceding local variable is illegal.
1010  */
1011  error(pc, pos);
1012  return true;
1013  }
1014  return false;
1015  }
1016 };
1017 
1019 
1023 
1027 
1028  public:
1030  Item *opt_expr_arg,
1031  const POS &expr_pos_arg)
1032  : name(name_arg), opt_expr(opt_expr_arg), expr_pos(expr_pos_arg) {}
1033 
1034  virtual bool contextualize(Parse_context *pc);
1035 };
1036 
1040 
1043 
1044  public:
1046  Item *expr_arg)
1047  : name(name_arg), expr(expr_arg) {}
1048 
1049  virtual bool contextualize(Parse_context *pc) {
1050  if (super::contextualize(pc) || expr->itemize(pc, &expr)) return true;
1051 
1052  THD *thd = pc->thd;
1053  Item_func_set_user_var *item;
1054  item = new (pc->mem_root) Item_func_set_user_var(name, expr, false);
1055  if (item == NULL) return true;
1056  set_var_user *var = new (thd->mem_root) set_var_user(item);
1057  if (var == NULL) return true;
1058  thd->lex->var_list.push_back(var);
1059  return false;
1060  }
1061 };
1062 
1066 
1070 
1071  public:
1073  PT_internal_variable_name *name_arg,
1074  Item *opt_expr_arg)
1075  : type(type_arg), name(name_arg), opt_expr(opt_expr_arg) {}
1076 
1077  virtual bool contextualize(Parse_context *pc) {
1078  if (super::contextualize(pc) || name->contextualize(pc) ||
1079  (opt_expr != NULL && opt_expr->itemize(pc, &opt_expr)))
1080  return true;
1081 
1082  THD *thd = pc->thd;
1083  struct sys_var_with_base tmp = name->value;
1084  if (tmp.var == trg_new_row_fake_var) {
1085  error(pc, down_cast<PT_internal_variable_name_2d *>(name)->pos);
1086  return true;
1087  }
1088  /* Lookup if necessary: must be a system variable. */
1089  if (tmp.var == NULL) {
1090  if (find_sys_var_null_base(thd, &tmp)) return true;
1091  }
1092  if (set_system_variable(thd, &tmp, type, opt_expr)) return true;
1093  return false;
1094  }
1095 };
1096 
1100 
1102 
1103  public:
1105  : opt_charset(opt_charset_arg) {}
1106 
1107  virtual bool contextualize(Parse_context *pc);
1108 };
1109 
1113 
1115 
1116  public:
1118 
1119  virtual bool contextualize(Parse_context *pc);
1120 };
1121 
1124 
1127 
1128  public:
1129  PT_set_names(const CHARSET_INFO *opt_charset_arg,
1130  const CHARSET_INFO *opt_collation_arg)
1131  : opt_charset(opt_charset_arg), opt_collation(opt_collation_arg) {}
1132 
1133  virtual bool contextualize(Parse_context *pc);
1134 };
1135 
1137 
1139  : public PT_start_option_value_list {
1141 
1142  const char *password;
1143  const char *current_password;
1146 
1147  public:
1149  const char *current_password_arg,
1150  bool retain_current,
1151  const POS &expr_pos_arg)
1152  : password(password_arg),
1153  current_password(current_password_arg),
1154  retain_current_password(retain_current),
1155  expr_pos(expr_pos_arg) {}
1156 
1157  virtual bool contextualize(Parse_context *pc);
1158 };
1159 
1161  : public PT_start_option_value_list {
1163 
1165  const char *password;
1166  const char *current_password;
1169 
1170  public:
1172  const char *password_arg,
1173  const char *current_password_arg,
1174  bool retain_current,
1175  const POS &expr_pos_arg)
1176  : user(user_arg),
1177  password(password_arg),
1178  current_password(current_password_arg),
1179  retain_current_password(retain_current),
1180  expr_pos(expr_pos_arg) {}
1181 
1182  virtual bool contextualize(Parse_context *pc);
1183 };
1184 
1187 
1190 
1191  public:
1194  : type(type_arg), value(value_arg) {}
1195 
1196  virtual bool contextualize(Parse_context *pc) {
1197  pc->thd->lex->option_type = type;
1198  return super::contextualize(pc) || value->contextualize(pc);
1199  }
1200 };
1201 
1204 
1208 
1209  public:
1210  PT_option_value_list_head(const POS &delimiter_pos_arg,
1211  Parse_tree_node *value_arg,
1212  const POS &value_pos_arg)
1213  : delimiter_pos(delimiter_pos_arg),
1214  value(value_arg),
1215  value_pos(value_pos_arg) {}
1216 
1217  virtual bool contextualize(Parse_context *pc) {
1218  if (super::contextualize(pc)) return true;
1219 
1220  THD *thd = pc->thd;
1221 #ifndef DBUG_OFF
1222  LEX *old_lex = thd->lex;
1223 #endif // DBUG_OFF
1224 
1226  DBUG_ASSERT(thd->lex->select_lex == thd->lex->current_select());
1227  Parse_context inner_pc(pc->thd, thd->lex->select_lex);
1228 
1229  if (value->contextualize(&inner_pc)) return true;
1230 
1231  if (sp_create_assignment_instr(pc->thd, value_pos.raw.end)) return true;
1232  DBUG_ASSERT(thd->lex == old_lex &&
1233  thd->lex->current_select() == pc->select);
1234 
1235  return false;
1236  }
1237 };
1238 
1241 
1243 
1244  public:
1246  const POS &delimiter_pos_arg, Parse_tree_node *tail,
1247  const POS &tail_pos)
1248  : super(delimiter_pos_arg, tail, tail_pos), head(head_arg) {}
1249 
1250  virtual bool contextualize(Parse_context *pc) {
1251  return head->contextualize(pc) || super::contextualize(pc);
1252  }
1253 };
1254 
1257 
1261 
1262  public:
1264  const POS &head_pos_arg,
1265  PT_option_value_list_head *tail_arg)
1266  : head(head_arg), head_pos(head_pos_arg), tail(tail_arg) {}
1267 
1268  virtual bool contextualize(Parse_context *pc) {
1269  if (super::contextualize(pc) || head->contextualize(pc)) return true;
1270 
1271  if (sp_create_assignment_instr(pc->thd, head_pos.raw.end)) return true;
1272  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1273  pc->select = pc->thd->lex->select_lex;
1274 
1275  if (tail != NULL && tail->contextualize(pc)) return true;
1276 
1277  return false;
1278  }
1279 };
1280 
1283 
1284  const char *name;
1285  int32 value;
1286 
1287  public:
1288  PT_transaction_characteristic(const char *name_arg, int32 value_arg)
1289  : name(name_arg), value(value_arg) {}
1290 
1291  virtual bool contextualize(Parse_context *pc) {
1292  if (super::contextualize(pc)) return true;
1293 
1294  THD *thd = pc->thd;
1295  LEX *lex = thd->lex;
1296  Item *item = new (pc->mem_root) Item_int(value);
1297  if (item == NULL) return true;
1298  set_var *var = new (thd->mem_root)
1299  set_var(lex->option_type, find_sys_var(thd, name), &null_lex_str, item);
1300  if (var == NULL) return true;
1301  lex->var_list.push_back(var);
1302  return false;
1303  }
1304 };
1305 
1308 
1309  public:
1310  explicit PT_transaction_access_mode(bool is_read_only)
1311  : super("transaction_read_only", (int32)is_read_only) {}
1312 };
1313 
1316 
1317  public:
1319  : super("transaction_isolation", (int32)level) {}
1320 };
1321 
1324 
1327 
1328  public:
1330  PT_transaction_characteristic *opt_tail_arg)
1331  : head(head_arg), opt_tail(opt_tail_arg) {}
1332 
1333  virtual bool contextualize(Parse_context *pc) {
1334  return (super::contextualize(pc) || head->contextualize(pc) ||
1335  (opt_tail != NULL && opt_tail->contextualize(pc)));
1336  }
1337 };
1338 
1340  : public PT_start_option_value_list {
1342 
1345 
1346  public:
1348  PT_transaction_characteristics *characteristics_arg,
1349  const POS &end_pos_arg)
1350  : characteristics(characteristics_arg), end_pos(end_pos_arg) {}
1351 
1352  virtual bool contextualize(Parse_context *pc) {
1353  if (super::contextualize(pc)) return true;
1354 
1355  THD *thd = pc->thd;
1356  thd->lex->option_type = OPT_DEFAULT;
1357  if (characteristics->contextualize(pc)) return true;
1358 
1359  if (sp_create_assignment_instr(thd, end_pos.raw.end)) return true;
1360  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1361  pc->select = pc->thd->lex->select_lex;
1362 
1363  return false;
1364  }
1365 };
1366 
1368  : public Parse_tree_node {};
1369 
1373 
1377 
1378  public:
1380  PT_option_value_following_option_type *head_arg, const POS &head_pos_arg,
1381  PT_option_value_list_head *opt_tail_arg)
1382  : head(head_arg), head_pos(head_pos_arg), opt_tail(opt_tail_arg) {}
1383 
1384  virtual bool contextualize(Parse_context *pc) {
1385  if (super::contextualize(pc) || head->contextualize(pc)) return true;
1386 
1387  if (sp_create_assignment_instr(pc->thd, head_pos.raw.end)) return true;
1388  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1389  pc->select = pc->thd->lex->select_lex;
1390 
1391  if (opt_tail != NULL && opt_tail->contextualize(pc)) return true;
1392 
1393  return false;
1394  }
1395 };
1396 
1400 
1403 
1404  public:
1406  PT_transaction_characteristics *characteristics_arg,
1407  const POS &characteristics_pos_arg)
1408  : characteristics(characteristics_arg),
1409  characteristics_pos(characteristics_pos_arg) {}
1410 
1411  virtual bool contextualize(Parse_context *pc) {
1413  return true;
1414 
1416  return true;
1417  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1418  pc->select = pc->thd->lex->select_lex;
1419 
1420  return false;
1421  }
1422 };
1423 
1426 
1429 
1430  public:
1432  enum_var_type type_arg,
1434  : type(type_arg), list(list_arg) {}
1435 
1436  virtual bool contextualize(Parse_context *pc) {
1437  pc->thd->lex->option_type = type;
1438  return super::contextualize(pc) || list->contextualize(pc);
1439  }
1440 };
1441 
1442 class PT_set : public Parse_tree_node {
1444 
1447 
1448  public:
1449  PT_set(const POS &set_pos_arg, PT_start_option_value_list *list_arg)
1450  : set_pos(set_pos_arg), list(list_arg) {}
1451 
1452  virtual bool contextualize(Parse_context *pc) {
1453  if (super::contextualize(pc)) return true;
1454 
1455  THD *thd = pc->thd;
1456  LEX *lex = thd->lex;
1458  lex->option_type = OPT_SESSION;
1459  lex->var_list.empty();
1460  lex->autocommit = false;
1461 
1463  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1464  pc->select = pc->thd->lex->select_lex;
1465 
1466  return list->contextualize(pc);
1467  }
1468 };
1469 
1473 
1474  protected:
1476 
1477  public:
1478  virtual bool contextualize(Parse_context *pc) {
1479  if (super::contextualize(pc)) return true;
1480 
1481  LEX *lex = pc->thd->lex;
1483  if (lex->sql_command == SQLCOM_SHOW_CREATE ||
1485  my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "INTO");
1486  else
1487  error(pc, m_pos);
1488  return true;
1489  }
1490  return false;
1491  }
1492 };
1493 
1496 
1497  public:
1498  PT_into_destination_outfile(const POS &pos, const LEX_STRING &file_name_arg,
1499  const CHARSET_INFO *charset_arg,
1500  const Field_separators &field_term_arg,
1501  const Line_separators &line_term_arg)
1502  : PT_into_destination(pos), m_exchange(file_name_arg.str, false) {
1503  m_exchange.cs = charset_arg;
1504  m_exchange.field.merge_field_separators(field_term_arg);
1505  m_exchange.line.merge_line_separators(line_term_arg);
1506  }
1507 
1508  bool contextualize(Parse_context *pc) override {
1509  if (super::contextualize(pc)) return true;
1510 
1511  LEX *lex = pc->thd->lex;
1513  if (!(lex->result =
1515  return true;
1516 
1517  return false;
1518  }
1519 
1520  private:
1522 };
1523 
1526 
1527  public:
1528  PT_into_destination_dumpfile(const POS &pos, const LEX_STRING &file_name_arg)
1529  : PT_into_destination(pos), m_exchange(file_name_arg.str, true) {}
1530 
1531  bool contextualize(Parse_context *pc) override {
1532  if (super::contextualize(pc)) return true;
1533 
1534  LEX *lex = pc->thd->lex;
1535  if (!lex->is_explain()) {
1537  if (!(lex->result =
1538  new (pc->thd->mem_root) Query_result_dump(&m_exchange)))
1539  return true;
1540  }
1541  return false;
1542  }
1543 
1544  private:
1546 };
1547 
1549  public:
1551 
1552  explicit PT_select_var(const LEX_STRING &name_arg) : name(name_arg) {}
1553 
1554  virtual bool is_local() const { return false; }
1555  virtual uint get_offset() const {
1556  DBUG_ASSERT(0);
1557  return 0;
1558  }
1559 };
1560 
1563 
1565 
1566 #ifndef DBUG_OFF
1567  /*
1568  Routine to which this Item_splocal belongs. Used for checking if correct
1569  runtime context is used for variable handling.
1570  */
1572 #endif
1573 
1574  public:
1575  PT_select_sp_var(const LEX_STRING &name_arg) : super(name_arg) {}
1576 
1577  virtual bool is_local() const { return true; }
1578  virtual uint get_offset() const { return offset; }
1579 
1580  virtual bool contextualize(Parse_context *pc);
1581 };
1582 
1585 
1586  public:
1588 
1590 
1591  virtual bool contextualize(Parse_context *pc) {
1592  if (super::contextualize(pc)) return true;
1593 
1595  PT_select_var *var;
1596  while ((var = it++)) {
1597  if (var->contextualize(pc)) return true;
1598  }
1599 
1600  LEX *const lex = pc->thd->lex;
1601  if (lex->is_explain()) return false;
1602 
1603  Query_dumpvar *dumpvar = new (pc->mem_root) Query_dumpvar();
1604  if (dumpvar == NULL) return true;
1605 
1606  dumpvar->var_list = value;
1607  lex->result = dumpvar;
1609 
1610  return false;
1611  }
1612 
1613  bool push_back(PT_select_var *var) { return value.push_back(var); }
1614 };
1615 
1616 /**
1617  Parse tree node for a single of a window extent's borders,
1618  cf. <window frame extent> in SQL 2003.
1619 */
1620 class PT_border : public Parse_tree_node {
1621  friend class Window;
1622  Item *m_value{nullptr}; ///< only relevant iff m_border_type == WBT_VALUE_*
1623  public:
1625  const bool m_date_time;
1627 
1628  ///< For unbounded border
1632  }
1633 
1634  ///< For bounded non-temporal border, e.g. 2 PRECEDING: 'value' is 2.
1637 
1638  ///< For bounded INTERVAL 2 DAYS, 'value' is 2, int_type is DAYS.
1640  : m_value(value),
1642  m_date_time(true),
1643  m_int_type(int_type) {}
1644 
1645  ///< @returns the '2' in '2 PRECEDING' or 'INTERVAL 2 DAYS PRECEDING'
1646  Item *border() const { return m_value; }
1647  /// Need such low-level access so that fix_fields updates the right pointer
1648  Item **border_ptr() { return &m_value; }
1649 
1650  /**
1651  @returns Addition operator for computation of frames, nullptr if error.
1652  @param order_expr Expression to add/substract to
1653  @param prec true if PRECEDING
1654  @param asc true if ASC
1655  @param window only used for error generation
1656  */
1657  Item *build_addop(Item_cache *order_expr, bool prec, bool asc,
1658  const Window *window);
1659 };
1660 
1661 /**
1662  Parse tree node for one or both of a window extent's borders, cf.
1663  <window frame extent> in SQL 2003.
1664 */
1665 class PT_borders : public Parse_tree_node {
1667  friend class PT_frame;
1668 
1669  public:
1670  /**
1671  Constructor.
1672 
1673  Frames of the form "frame_start no_frame_end" are translated during
1674  parsing to "BETWEEN frame_start AND CURRENT ROW". So both 'start' and
1675  'end' are non-nullptr.
1676  */
1678  m_borders[0] = start;
1679  m_borders[1] = end;
1680  }
1681 };
1682 
1683 /**
1684  Parse tree node for a window frame's exclusions, cf. the
1685  <window frame exclusion> clause in SQL 2003.
1686 */
1689 
1690  public:
1692  // enum_window_frame_exclusion exclusion() { return m_exclusion; }
1693 };
1694 
1695 /**
1696  Parse tree node for a window's frame, cf. the <window frame clause>
1697  in SQL 2003.
1698 */
1699 class PT_frame : public Parse_tree_node {
1700  public:
1702 
1705 
1707 
1708  /// If true, this is an artificial frame, not specified by the user
1709  bool m_originally_absent = false;
1710 
1712  PT_exclusion *exclusion)
1713  : m_unit(unit),
1714  m_from(from_to->m_borders[0]),
1715  m_to(from_to->m_borders[1]),
1716  m_exclusion(exclusion) {}
1717 };
1718 
1719 /**
1720  Parse tree node for a window; just a shallow wrapper for
1721  class Window, q.v.
1722 */
1723 class PT_window : public Parse_tree_node, public Window {
1725 
1726  public:
1728  PT_frame *frame)
1729  : Window(partition_by, order_by, frame) {}
1730 
1732  PT_frame *frame, Item_string *inherit)
1733  : Window(partition_by, order_by, frame, inherit) {}
1734 
1736 
1737  virtual bool contextualize(Parse_context *pc);
1738 };
1739 
1740 /**
1741  Parse tree node for a list of window definitions corresponding
1742  to a <window clause> in SQL 2003.
1743 */
1747 
1748  public:
1750 
1751  virtual bool contextualize(Parse_context *pc);
1752 
1753  bool push_back(PT_window *w) { return m_windows.push_back(w); }
1754 };
1755 
1757  public:
1758  virtual bool has_into_clause() const = 0;
1759  virtual bool is_union() const = 0;
1760 };
1761 
1764 
1774 
1775  public:
1777  PT_hint_list *opt_hints_arg, const Query_options &options_arg,
1778  PT_item_list *item_list_arg, PT_into_destination *opt_into1_arg,
1779  const Mem_root_array_YY<PT_table_reference *> &from_clause_arg,
1780  Item *opt_where_clause_arg, PT_group *opt_group_clause_arg,
1781  Item *opt_having_clause_arg, PT_window_list *opt_window_clause_arg)
1782  : opt_hints(opt_hints_arg),
1783  options(options_arg),
1784  item_list(item_list_arg),
1785  opt_into1(opt_into1_arg),
1786  from_clause(from_clause_arg),
1787  opt_where_clause(opt_where_clause_arg),
1788  opt_group_clause(opt_group_clause_arg),
1789  opt_having_clause(opt_having_clause_arg),
1790  opt_window_clause(opt_window_clause_arg) {}
1791 
1793  const Query_options &options_arg, PT_item_list *item_list_arg,
1794  const Mem_root_array_YY<PT_table_reference *> &from_clause_arg,
1795  Item *opt_where_clause_arg)
1796  : opt_hints(NULL),
1797  options(options_arg),
1798  item_list(item_list_arg),
1799  opt_into1(NULL),
1800  from_clause(from_clause_arg),
1801  opt_where_clause(opt_where_clause_arg),
1805 
1806  explicit PT_query_specification(const Query_options &options_arg,
1807  PT_item_list *item_list_arg)
1808  : opt_hints(NULL),
1809  options(options_arg),
1810  item_list(item_list_arg),
1811  opt_into1(NULL),
1817  }
1818 
1819  virtual bool contextualize(Parse_context *pc);
1820 
1821  virtual bool has_into_clause() const { return opt_into1 != NULL; }
1822 
1823  virtual bool is_union() const { return false; }
1824 };
1825 
1827  public:
1830  PT_limit_clause *limit,
1831  PT_locking_clause_list *locking_clauses)
1832  : contextualized(false),
1833  m_body(body),
1834  m_order(order),
1835  m_limit(limit),
1836  m_locking_clauses(locking_clauses),
1838  m_with_clause(with_clause) {}
1839 
1841  PT_limit_clause *limit,
1842  PT_locking_clause_list *locking_clauses)
1843  : PT_query_expression(nullptr, body, order, limit, locking_clauses) {}
1844 
1847 
1848  virtual bool contextualize(Parse_context *pc) {
1850  return true; /* purecov: inspected */
1851 
1853  m_body->set_containing_qe(this);
1854 
1856  return true;
1857 
1858  if (!contextualized && contextualize_order_and_limit(pc)) return true;
1859 
1860  if (contextualize_safe(pc, m_locking_clauses)) return true;
1861 
1862  return false;
1863  }
1864 
1866 
1867  bool has_order() const { return m_order != NULL; }
1868 
1869  bool has_limit() const { return m_limit != NULL; }
1870 
1871  bool is_union() const { return m_body->is_union(); }
1872 
1873  bool has_into_clause() const { return m_body->has_into_clause(); }
1874 
1875  /**
1876  Callback for deeper nested query expressions. It's mandatory for any
1877  derived class to call this member function during contextualize.
1878  */
1880  contextualized = true;
1881 
1882  /*
1883  We temporarily switch off 'braces' for contextualization of the limit
1884  and order clauses if this query expression is a
1885  union. PT_order::contextualize() and PT_limit_clause::contextualize()
1886  are still used by legacy code where 'braces' is used to communicate
1887  nesting information. It's not possible to express the difference between
1888 
1889  (SELECT ... UNION SELECT ...) ORDER BY ... LIMIT ...
1890 
1891  and
1892 
1893  SELECT ... UNION (SELECT ... ORDER BY ... LIMIT ...)
1894 
1895  in the SELECT_LEX structure. In other words, this structure does not
1896  know the difference between a surrounding union and a local
1897  union. Fortunately, the information is implicit in the parse tree
1898  structure: is_union() is true if this query expression is a union, but
1899  not true if it's nested within a union.
1900  */
1901  bool braces = pc->select->braces;
1902  if (is_union()) pc->select->braces = false;
1903  pc->thd->where = "global ORDER clause";
1904  bool res =
1906  pc->select->braces = braces;
1907  if (res) return true;
1908 
1909  pc->thd->where = THD::DEFAULT_WHERE;
1910  return false;
1911  }
1912 
1913  void set_parentheses() { m_parentheses = true; }
1914 
1915  bool has_parentheses() { return m_parentheses; }
1916 
1917  void remove_parentheses() { m_parentheses = false; }
1918 
1919  /**
1920  Called by the parser when it has decided that this query expression may
1921  not contain order or limit clauses because it is part of a union. For
1922  historical reasons, these clauses are not allowed in non-last branches of
1923  union expressions.
1924  */
1925  void ban_order_and_limit() const {
1926  if (m_order != NULL) my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY");
1927  if (m_limit != NULL) my_error(ER_WRONG_USAGE, MYF(0), "UNION", "LIMIT");
1928  }
1929 
1930  private:
1938 };
1939 
1942 
1946 
1947  public:
1949 
1950  PT_subquery(POS p, PT_query_expression *query_expression)
1951  : qe(query_expression),
1952  pos(p),
1953  select_lex(NULL),
1955 
1956  virtual bool contextualize(Parse_context *pc) {
1957  if (super::contextualize(pc)) return true;
1958 
1959  LEX *lex = pc->thd->lex;
1960  if (!lex->expr_allows_subselect || lex->sql_command == (int)SQLCOM_PURGE) {
1961  error(pc, pos);
1962  return true;
1963  }
1964 
1965  // Create a SELECT_LEX_UNIT and SELECT_LEX for the subquery's query
1966  // expression.
1967  SELECT_LEX *child = lex->new_query(pc->select);
1968  if (child == NULL) return true;
1969 
1970  Parse_context inner_pc(pc->thd, child);
1971 
1973 
1974  if (qe->contextualize(&inner_pc)) return true;
1975 
1976  select_lex = inner_pc.select->master_unit()->first_select();
1977 
1978  lex->pop_context();
1979  pc->select->n_child_sum_items += child->n_sum_items;
1980 
1981  /*
1982  A subquery (and all the subsequent query blocks in a UNION) can add
1983  columns to an outer query block. Reserve space for them.
1984  */
1985  for (SELECT_LEX *temp = child; temp != nullptr;
1986  temp = temp->next_select()) {
1987  pc->select->select_n_where_fields += temp->select_n_where_fields;
1988  pc->select->select_n_having_items += temp->select_n_having_items;
1989  }
1990 
1991  return false;
1992  }
1993 
1995 
1996  bool is_union() { return qe->is_union(); }
1997 
1998  SELECT_LEX *value() { return select_lex; }
1999 };
2000 
2002  public:
2004  : m_query_primary(query_primary) {}
2005 
2006  virtual bool contextualize(Parse_context *pc) {
2009  return true;
2010  return false;
2011  }
2012 
2013  virtual bool is_union() const { return m_query_primary->is_union(); }
2014 
2015  virtual bool has_into_clause() const {
2016  return m_query_primary->has_into_clause();
2017  }
2018 
2019  private:
2021 };
2022 
2024  public:
2025  PT_union(PT_query_expression *lhs, const POS &lhs_pos, bool is_distinct,
2026  PT_query_primary *rhs)
2027  : m_lhs(lhs),
2028  m_lhs_pos(lhs_pos),
2029  m_is_distinct(is_distinct),
2030  m_rhs(rhs),
2031  m_containing_qe(NULL) {}
2032 
2034  m_containing_qe = qe;
2035  }
2036 
2037  virtual bool contextualize(Parse_context *pc);
2038 
2039  virtual bool is_union() const { return true; }
2040 
2041  virtual bool has_into_clause() const {
2042  return m_lhs->has_into_clause() || m_rhs->has_into_clause();
2043  }
2044 
2045  private:
2052 };
2053 
2056 
2057  public:
2059 
2060  virtual bool contextualize(Parse_context *pc) {
2061  if (super::contextualize(pc)) return true;
2062 
2063  pc->select->set_braces(true);
2064  bool result = m_qe->contextualize(pc);
2065 
2066  return result;
2067  }
2068 
2069  bool is_union() const { return m_qe->is_union(); }
2070 
2071  bool has_into_clause() const { return m_qe->has_into_clause(); }
2072 
2073  private:
2075 };
2076 
2079 
2080  public:
2081  /**
2082  @param qe The query expression.
2083  @param sql_command The type of SQL command.
2084  */
2086  : m_sql_command(sql_command), m_qe(qe), m_into(NULL) {}
2087 
2088  /**
2089  Creates a SELECT command. Only SELECT commands can have into.
2090 
2091  @param qe The query expression.
2092  @param into The trailing INTO destination.
2093  */
2095  : m_sql_command(SQLCOM_SELECT), m_qe(qe), m_into(into) {}
2096 
2098 
2099  Sql_cmd *make_cmd(THD *thd) override;
2100 
2101  private:
2105 };
2106 
2107 /**
2108  Top-level node for the DELETE statement
2109 
2110  @ingroup ptn_stmt
2111 */
2113  private:
2118  const char *const opt_table_alias;
2126 
2127  public:
2128  // single-table DELETE node constructor:
2129  PT_delete(PT_with_clause *with_clause_arg, PT_hint_list *opt_hints_arg,
2130  int opt_delete_options_arg, Table_ident *table_ident_arg,
2131  const LEX_CSTRING &opt_table_alias_arg,
2132  List<String> *opt_use_partition_arg, Item *opt_where_clause_arg,
2133  PT_order *opt_order_clause_arg, Item *opt_delete_limit_clause_arg)
2134  : m_with_clause(with_clause_arg),
2135  opt_hints(opt_hints_arg),
2136  opt_delete_options(opt_delete_options_arg),
2137  table_ident(table_ident_arg),
2138  opt_table_alias(opt_table_alias_arg.str),
2139  opt_use_partition(opt_use_partition_arg),
2140  opt_where_clause(opt_where_clause_arg),
2141  opt_order_clause(opt_order_clause_arg),
2142  opt_delete_limit_clause(opt_delete_limit_clause_arg) {
2145  }
2146 
2147  // multi-table DELETE node constructor:
2148  PT_delete(PT_with_clause *with_clause_arg, PT_hint_list *opt_hints_arg,
2149  int opt_delete_options_arg,
2150  const Mem_root_array_YY<Table_ident *> &table_list_arg,
2151  const Mem_root_array_YY<PT_table_reference *> &join_table_list_arg,
2152  Item *opt_where_clause_arg)
2153  : m_with_clause(with_clause_arg),
2154  opt_hints(opt_hints_arg),
2155  opt_delete_options(opt_delete_options_arg),
2156  table_ident(NULL),
2157  opt_table_alias(nullptr),
2158  table_list(table_list_arg),
2160  join_table_list(join_table_list_arg),
2161  opt_where_clause(opt_where_clause_arg),
2164 
2165  Sql_cmd *make_cmd(THD *thd) override;
2166 
2167  private:
2168  bool is_multitable() const {
2169  DBUG_ASSERT((table_ident != NULL) ^ (table_list.size() > 0));
2170  return table_ident == NULL;
2171  }
2172 
2173  bool add_table(Parse_context *pc, Table_ident *table);
2174 };
2175 
2176 /**
2177  Top-level node for the UPDATE statement
2178 
2179  @ingroup ptn_stmt
2180 */
2181 class PT_update : public Parse_tree_root {
2192 
2193  public:
2194  PT_update(PT_with_clause *with_clause_arg, PT_hint_list *opt_hints_arg,
2195  thr_lock_type opt_low_priority_arg, bool opt_ignore_arg,
2196  const Mem_root_array_YY<PT_table_reference *> &join_table_list_arg,
2197  PT_item_list *column_list_arg, PT_item_list *value_list_arg,
2198  Item *opt_where_clause_arg, PT_order *opt_order_clause_arg,
2199  Item *opt_limit_clause_arg)
2200  : m_with_clause(with_clause_arg),
2201  opt_hints(opt_hints_arg),
2202  opt_low_priority(opt_low_priority_arg),
2203  opt_ignore(opt_ignore_arg),
2204  join_table_list(join_table_list_arg),
2205  column_list(column_list_arg),
2206  value_list(value_list_arg),
2207  opt_where_clause(opt_where_clause_arg),
2208  opt_order_clause(opt_order_clause_arg),
2209  opt_limit_clause(opt_limit_clause_arg) {}
2210 
2211  Sql_cmd *make_cmd(THD *thd) override;
2212 };
2213 
2216 
2218 
2219  public:
2220  virtual bool contextualize(Parse_context *pc);
2221 
2222  bool push_back(List<Item> *x) { return many_values.push_back(x); }
2223 
2226  return many_values;
2227  }
2228 };
2229 
2230 /**
2231  Top-level node for the INSERT statement
2232 
2233  @ingroup ptn_stmt
2234 */
2236  const bool is_replace;
2239  const bool ignore;
2247 
2248  public:
2249  PT_insert(bool is_replace_arg, PT_hint_list *opt_hints_arg,
2250  thr_lock_type lock_option_arg, bool ignore_arg,
2251  Table_ident *table_ident_arg, List<String> *opt_use_partition_arg,
2252  PT_item_list *column_list_arg,
2253  PT_insert_values_list *row_value_list_arg,
2254  PT_query_expression *insert_query_expression_arg,
2255  PT_item_list *opt_on_duplicate_column_list_arg,
2256  PT_item_list *opt_on_duplicate_value_list_arg)
2257  : is_replace(is_replace_arg),
2258  opt_hints(opt_hints_arg),
2259  lock_option(lock_option_arg),
2260  ignore(ignore_arg),
2261  table_ident(table_ident_arg),
2262  opt_use_partition(opt_use_partition_arg),
2263  column_list(column_list_arg),
2264  row_value_list(row_value_list_arg),
2265  insert_query_expression(insert_query_expression_arg),
2266  opt_on_duplicate_column_list(opt_on_duplicate_column_list_arg),
2267  opt_on_duplicate_value_list(opt_on_duplicate_value_list_arg) {
2268  // REPLACE statement can't have IGNORE flag:
2270  // REPLACE statement can't have ON DUPLICATE KEY UPDATE clause:
2272  // INSERT/REPLACE ... SELECT can't have VALUES clause:
2274  // ON DUPLICATE KEY UPDATE: column and value arrays must have same sizes:
2279  }
2280 
2281  virtual Sql_cmd *make_cmd(THD *thd);
2282 
2283  private:
2284  bool has_select() const { return insert_query_expression != NULL; }
2285 };
2286 
2290 
2291  public:
2292  PT_call(sp_name *proc_name_arg, PT_item_list *opt_expr_list_arg)
2293  : proc_name(proc_name_arg), opt_expr_list(opt_expr_list_arg) {}
2294 
2295  Sql_cmd *make_cmd(THD *thd) override;
2296 };
2297 
2298 /**
2299  Top-level node for the SHUTDOWN statement
2300 
2301  @ingroup ptn_stmt
2302 */
2305 
2306  public:
2307  Sql_cmd *make_cmd(THD *) override { return &sql_cmd; }
2308 };
2309 
2310 /**
2311  Top-level node for the CREATE [OR REPLACE] SPATIAL REFERENCE SYSTEM statement.
2312 
2313  @ingroup ptn_stmt
2314 */
2316  /// The SQL command object.
2318  /// Whether OR REPLACE is specified.
2320  /// Whether IF NOT EXISTS is specified.
2322  /// SRID of the SRS to create.
2323  ///
2324  /// The range is larger than that of gis::srid_t, so it must be
2325  /// verified to be less than the uint32 maximum value.
2326  unsigned long long m_srid;
2327  /// All attributes except SRID.
2329 
2330  /// Check if a UTF-8 string contains control characters.
2331  ///
2332  /// @note This function only checks single byte control characters (U+0000 to
2333  /// U+001F, and U+007F). There are some control characters at U+0080 to U+00A0
2334  /// that are not detected by this function.
2335  ///
2336  /// @param str The string.
2337  /// @param length Length of the string.
2338  ///
2339  /// @retval false The string contains no control characters.
2340  /// @retval true The string contains at least one control character.
2341  bool contains_control_char(char *str, size_t length) {
2342  for (size_t pos = 0; pos < length; pos++) {
2343  if (std::iscntrl(str[pos])) return true;
2344  }
2345  return false;
2346  }
2347 
2348  public:
2349  PT_create_srs(unsigned long long srid,
2350  const Sql_cmd_srs_attributes &attributes, bool or_replace,
2351  bool if_not_exists)
2352  : m_or_replace(or_replace),
2353  m_if_not_exists(if_not_exists),
2354  m_srid(srid),
2355  m_attributes(attributes) {}
2356 
2357  Sql_cmd *make_cmd(THD *thd) override {
2358  // Note: This function hard-codes the maximum length of various
2359  // strings. These lengths must match those in
2360  // sql/dd/impl/tables/spatial_reference_systems.cc.
2361 
2363 
2364  if (m_srid > std::numeric_limits<gis::srid_t>::max()) {
2365  my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "SRID",
2366  m_or_replace ? "CREATE OR REPLACE SPATIAL REFERENCE SYSTEM"
2367  : "CREATE SPATIAL REFERENCE SYSTEM");
2368  return nullptr;
2369  }
2370  if (m_srid == 0) {
2371  my_error(ER_CANT_MODIFY_SRID_0, MYF(0));
2372  return nullptr;
2373  }
2374 
2375  if (m_attributes.srs_name.str == nullptr) {
2376  my_error(ER_SRS_MISSING_MANDATORY_ATTRIBUTE, MYF(0), "NAME");
2377  return nullptr;
2378  }
2379  MYSQL_LEX_STRING srs_name_utf8 = {nullptr, 0};
2380  if (thd->convert_string(&srs_name_utf8, &my_charset_utf8_bin,
2382  m_attributes.srs_name.length, thd->charset())) {
2383  /* purecov: begin inspected */
2384  my_error(ER_OOM, MYF(0));
2385  return nullptr;
2386  /* purecov: end */
2387  }
2388  if (srs_name_utf8.length == 0 || std::isspace(srs_name_utf8.str[0]) ||
2389  std::isspace(srs_name_utf8.str[srs_name_utf8.length - 1])) {
2390  my_error(ER_SRS_NAME_CANT_BE_EMPTY_OR_WHITESPACE, MYF(0));
2391  return nullptr;
2392  }
2393  if (contains_control_char(srs_name_utf8.str, srs_name_utf8.length)) {
2394  my_error(ER_SRS_INVALID_CHARACTER_IN_ATTRIBUTE, MYF(0), "NAME");
2395  return nullptr;
2396  }
2397  String srs_name_str(srs_name_utf8.str, srs_name_utf8.length,
2399  if (srs_name_str.numchars() > 80) {
2400  my_error(ER_SRS_ATTRIBUTE_STRING_TOO_LONG, MYF(0), "NAME", 80);
2401  return nullptr;
2402  }
2403 
2404  if (m_attributes.definition.str == nullptr) {
2405  my_error(ER_SRS_MISSING_MANDATORY_ATTRIBUTE, MYF(0), "DEFINITION");
2406  return nullptr;
2407  }
2408  MYSQL_LEX_STRING definition_utf8 = {nullptr, 0};
2409  if (thd->convert_string(&definition_utf8, &my_charset_utf8_bin,
2412  /* purecov: begin inspected */
2413  my_error(ER_OOM, MYF(0));
2414  return nullptr;
2415  /* purecov: end */
2416  }
2417  String definition_str(definition_utf8.str, definition_utf8.length,
2419  if (contains_control_char(definition_utf8.str, definition_utf8.length)) {
2420  my_error(ER_SRS_INVALID_CHARACTER_IN_ATTRIBUTE, MYF(0), "DEFINITION");
2421  return nullptr;
2422  }
2423  if (definition_str.numchars() > 4096) {
2424  my_error(ER_SRS_ATTRIBUTE_STRING_TOO_LONG, MYF(0), "DEFINITION", 4096);
2425  return nullptr;
2426  }
2427 
2428  MYSQL_LEX_STRING organization_utf8 = {nullptr, 0};
2429  if (m_attributes.organization.str != nullptr) {
2430  if (thd->convert_string(&organization_utf8, &my_charset_utf8_bin,
2433  thd->charset())) {
2434  /* purecov: begin inspected */
2435  my_error(ER_OOM, MYF(0));
2436  return nullptr;
2437  /* purecov: end */
2438  }
2439  if (organization_utf8.length == 0 ||
2440  std::isspace(organization_utf8.str[0]) ||
2441  std::isspace(organization_utf8.str[organization_utf8.length - 1])) {
2442  my_error(ER_SRS_ORGANIZATION_CANT_BE_EMPTY_OR_WHITESPACE, MYF(0));
2443  return nullptr;
2444  }
2445  String organization_str(organization_utf8.str, organization_utf8.length,
2447  if (contains_control_char(organization_utf8.str,
2448  organization_utf8.length)) {
2449  my_error(ER_SRS_INVALID_CHARACTER_IN_ATTRIBUTE, MYF(0), "ORGANIZATION");
2450  return nullptr;
2451  }
2452  if (organization_str.numchars() > 256) {
2453  my_error(ER_SRS_ATTRIBUTE_STRING_TOO_LONG, MYF(0), "ORGANIZATION", 256);
2454  return nullptr;
2455  }
2456 
2458  std::numeric_limits<gis::srid_t>::max()) {
2459  my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "IDENTIFIED BY",
2460  m_or_replace ? "CREATE OR REPLACE SPATIAL REFERENCE SYSTEM"
2461  : "CREATE SPATIAL REFERENCE SYSTEM");
2462  return nullptr;
2463  }
2464  }
2465 
2466  MYSQL_LEX_STRING description_utf8 = {nullptr, 0};
2467  if (m_attributes.description.str != nullptr) {
2468  if (thd->convert_string(&description_utf8, &my_charset_utf8_bin,
2471  thd->charset())) {
2472  /* purecov: begin inspected */
2473  my_error(ER_OOM, MYF(0));
2474  return nullptr;
2475  /* purecov: end */
2476  }
2477  String description_str(description_utf8.str, description_utf8.length,
2479  if (contains_control_char(description_utf8.str,
2480  description_utf8.length)) {
2481  my_error(ER_SRS_INVALID_CHARACTER_IN_ATTRIBUTE, MYF(0), "DESCRIPTION");
2482  return nullptr;
2483  }
2484  if (description_str.numchars() > 2048) {
2485  my_error(ER_SRS_ATTRIBUTE_STRING_TOO_LONG, MYF(0), "DESCRIPTION", 2048);
2486  return nullptr;
2487  }
2488  }
2489 
2490  sql_cmd.init(m_or_replace, m_if_not_exists, m_srid, srs_name_utf8,
2491  definition_utf8, organization_utf8,
2492  m_attributes.organization_coordsys_id, description_utf8);
2493  return &sql_cmd;
2494  }
2495 };
2496 
2497 /**
2498  Top-level node for the DROP SPATIAL REFERENCE SYSTEM statement.
2499 
2500  @ingroup ptn_stmt
2501 */
2503  /// The SQL command object.
2505  /// SRID of the SRS to drop.
2506  ///
2507  /// The range is larger than that of gis::srid_t, so it must be
2508  /// verified to be less than the uint32 maximum value.
2509  unsigned long long m_srid;
2510 
2511  public:
2512  PT_drop_srs(unsigned long long srid, bool if_exists)
2513  : sql_cmd(srid, if_exists), m_srid(srid) {}
2514 
2515  Sql_cmd *make_cmd(THD *thd) override {
2517 
2518  if (m_srid > std::numeric_limits<gis::srid_t>::max()) {
2519  my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "SRID",
2520  "DROP SPATIAL REFERENCE SYSTEM");
2521  return nullptr;
2522  }
2523  if (m_srid == 0) {
2524  my_error(ER_CANT_MODIFY_SRID_0, MYF(0));
2525  return nullptr;
2526  }
2527 
2528  return &sql_cmd;
2529  }
2530 };
2531 
2532 /**
2533  Top-level node for the ALTER INSTANCE statement
2534 
2535  @ingroup ptn_stmt
2536 */
2539 
2540  public:
2542  enum alter_instance_action_enum alter_instance_action)
2543  : sql_cmd(alter_instance_action) {}
2544 
2545  Sql_cmd *make_cmd(THD *thd) override {
2546  thd->lex->no_write_to_binlog = false;
2547  return &sql_cmd;
2548  }
2549 };
2550 
2551 /**
2552  A template-free base class for index options that we can predeclare in
2553  sql_lex.h
2554 */
2556 
2557 /**
2558  A key part specification.
2559 
2560  This can either be a "normal" key part (a key part that points to a column),
2561  or this can be a functional key part (a key part that points to an
2562  expression).
2563 */
2566 
2567  public:
2568  /**
2569  Constructor for a functional key part.
2570 
2571  @param expression The expression to index.
2572  @param order The direction of the index.
2573  */
2574  PT_key_part_specification(Item *expression, enum_order order);
2575 
2576  /**
2577  Constructor for a "normal" key part. That is a key part that points to a
2578  column and not an expression.
2579 
2580  @param column_name The column name that this key part points to.
2581  @param order The direction of the index.
2582  @param prefix_length How many bytes or characters this key part should
2583  index, or zero if it should index the entire column.
2584  */
2585  PT_key_part_specification(const LEX_CSTRING &column_name, enum_order order,
2586  int prefix_length);
2587 
2588  /**
2589  Contextualize this key part specification. This will also call itemize on
2590  the indexed expression if this is a functional key part.
2591 
2592  @param pc The parse context
2593 
2594  @retval true on error
2595  @retval false on success
2596  */
2597  bool contextualize(Parse_context *pc) override;
2598 
2599  /**
2600  Get the indexed expression. The caller must ensure that has_expression()
2601  returns true before calling this.
2602 
2603  @returns The indexed expression
2604  */
2607  return m_expression;
2608  }
2609 
2610  /**
2611  @returns The direction of the index: ORDER_ASC, ORDER_DESC or
2612  ORDER_NOT_RELEVANT in case the user didn't explicitly specify a
2613  direction.
2614  */
2615  enum_order get_order() const { return m_order; }
2616 
2617  /**
2618  @retval true if the user explicitly specified a direction (asc/desc).
2619  @retval false if the user didn't explicitly specify a direction.
2620  */
2621  bool is_explicit() const { return get_order() != ORDER_NOT_RELEVANT; }
2622 
2623  /**
2624  @retval true if the key part contains an expression (and thus is a
2625  functional key part).
2626  @retval false if the key part doesn't contain an expression.
2627  */
2628  bool has_expression() const { return m_expression != nullptr; }
2629 
2630  /**
2631  Get the column that this key part points to. This is only valid if this
2632  key part isn't a functional index. The caller must thus check the return
2633  value of has_expression() before calling this function.
2634 
2635  @returns The column that this key part points to.
2636  */
2639  return m_column_name;
2640  }
2641 
2642  /**
2643  @returns The number of bytes that this key part should index. If the column
2644  this key part points to is a non-binary column, this is the number
2645  of characters. Returns zero if the entire column should be indexed.
2646  */
2647  int get_prefix_length() const { return m_prefix_length; }
2648 
2649  private:
2650  /**
2651  The indexed expression in case this is a functional key part. Only valid if
2652  has_expression() returns true.
2653  */
2655 
2656  /// The direction of the index.
2658 
2659  /// The name of the column that this key part indexes.
2661 
2662  /**
2663  If this is greater than zero, it represents how many bytes of the column
2664  that is indexed. Note that for non-binary columns (VARCHAR, TEXT etc), this
2665  is the number of characters.
2666  */
2668 };
2669 
2670 /**
2671  A template for options that set a single `<alter option>` value in
2672  thd->lex->key_create_info.
2673 
2674  @tparam Option_type The data type of the option.
2675  @tparam Property Pointer-to-member for the option of KEY_CREATE_INFO.
2676 */
2677 template <typename Option_type, Option_type KEY_CREATE_INFO::*Property>
2679  public:
2680  /// @param option_value The value of the option.
2682 
2685  return false;
2686  }
2687 
2688  private:
2689  Option_type m_option_value;
2690 };
2691 
2692 /**
2693  A template for options that set a single property in a KEY_CREATE_INFO, and
2694  also records if the option was explicitly set.
2695 */
2696 template <typename Option_type, Option_type KEY_CREATE_INFO::*Property,
2697  bool KEY_CREATE_INFO::*Property_is_explicit>
2699  public:
2702 
2705  pc->key_create_info->*Property_is_explicit = true;
2706  return false;
2707  }
2708 
2709  private:
2710  Option_type m_option_value;
2711 };
2712 
2720 
2721 /**
2722  The data structure (B-tree, Hash, etc) used for an index is called
2723  'index_type' in the manual. Internally, this is stored in
2724  KEY_CREATE_INFO::algorithm, while what the manual calls 'algorithm' is
2725  stored in partition_info::key_algorithm. In an `<create_index_stmt>`
2726  it's ignored. The terminology is somewhat confusing, but we stick to the
2727  manual in the parser.
2728 */
2732 
2734  public:
2736  const LEX_STRING &name_arg, PT_base_index_option *type,
2737  Table_ident *table_ident,
2743  m_keytype(type_par),
2744  m_name(name_arg),
2745  m_type(type),
2746  m_table_ident(table_ident),
2747  m_columns(cols),
2748  m_options(options),
2749  m_algo(algo),
2750  m_lock(lock) {}
2751 
2752  Sql_cmd *make_cmd(THD *thd) override;
2753 
2754  private:
2763 };
2764 
2765 /**
2766  Base class for column/constraint definitions in CREATE %TABLE
2767 
2768  @ingroup ptn_create_table_stuff
2769 */
2771 
2773 
2776 
2777  public:
2778  PT_inline_index_definition(keytype type_par, const LEX_STRING &name_arg,
2782  : m_keytype(type_par),
2783  m_name(name_arg),
2784  m_type(type),
2785  m_columns(cols),
2786  m_options(options) {}
2787 
2788  bool contextualize(Table_ddl_parse_context *pc) override;
2789 
2790  private:
2796 };
2797 
2800 
2801  public:
2802  PT_foreign_key_definition(const LEX_STRING &constraint_name,
2803  const LEX_STRING &key_name,
2805  Table_ident *referenced_table,
2806  List<Key_part_spec> *ref_list,
2807  fk_match_opt fk_match_option,
2808  fk_option fk_update_opt, fk_option fk_delete_opt)
2809  : m_constraint_name(constraint_name),
2810  m_key_name(key_name),
2811  m_columns(columns),
2812  m_referenced_table(referenced_table),
2813  m_ref_list(ref_list),
2814  m_fk_match_option(fk_match_option),
2815  m_fk_update_opt(fk_update_opt),
2816  m_fk_delete_opt(fk_delete_opt) {}
2817 
2819 
2820  private:
2829 };
2830 
2831 /**
2832  Common base class for CREATE TABLE and ALTER TABLE option nodes
2833 
2834  @ingroup ptn_create_or_alter_table_options
2835 */
2837  public:
2838  ~PT_ddl_table_option() override = 0; // Force abstract class declaration
2839 
2840  virtual bool is_rename_table() const { return false; }
2841 };
2842 
2844 
2845 /**
2846  Base class for CREATE TABLE option nodes
2847 
2848  @ingroup ptn_create_or_alter_table_options
2849 */
2852 
2853  public:
2854  ~PT_create_table_option() override = 0; // Force abstract class declaration
2855 
2857  if (super::contextualize(pc)) return true;
2859  return false;
2860  }
2861 };
2862 
2864 
2865 /**
2866  A template for options that set a single property in HA_CREATE_INFO, and
2867  also records if the option was explicitly set.
2868 */
2869 template <typename Option_type, Option_type HA_CREATE_INFO::*Property,
2870  ulong Property_flag>
2873 
2874  const Option_type value;
2875 
2876  public:
2878 
2880  if (super::contextualize(pc)) return true;
2881  pc->create_info->*Property = value;
2882  pc->create_info->used_fields |= Property_flag;
2883  return false;
2884  }
2885 };
2886 
2887 #define TYPE_AND_REF(x) decltype(x), &x
2888 
2889 /**
2890  Node for the @SQL{MAX_ROWS [=] @B{@<integer@>}} table option
2891 
2892  @ingroup ptn_create_or_alter_table_options
2893 */
2897 
2898 /**
2899  Node for the @SQL{MIN_ROWS [=] @B{@<integer@>}} table option
2900 
2901  @ingroup ptn_create_or_alter_table_options
2902 */
2906 
2907 /**
2908  Node for the @SQL{AVG_ROW_LENGTH_ROWS [=] @B{@<integer@>}} table option
2909 
2910  @ingroup ptn_create_or_alter_table_options
2911 */
2915 
2916 /**
2917  Node for the @SQL{PASSWORD [=] @B{@<string@>}} table option
2918 
2919  @ingroup ptn_create_or_alter_table_options
2920 */
2924 
2925 /**
2926  Node for the @SQL{COMMENT [=] @B{@<string@>}} table option
2927 
2928  @ingroup ptn_create_or_alter_table_options
2929 */
2933 
2934 /**
2935  Node for the @SQL{COMPRESSION [=] @B{@<string@>}} table option
2936 
2937  @ingroup ptn_create_or_alter_table_options
2938 */
2942 
2943 /**
2944  Node for the @SQL{ENGRYPTION [=] @B{@<string@>}} table option
2945 
2946  @ingroup ptn_create_or_alter_table_options
2947 */
2951 
2952 /**
2953  Node for the @SQL{AUTO_INCREMENT [=] @B{@<integer@>}} table option
2954 
2955  @ingroup ptn_create_or_alter_table_options
2956 */
2960 
2964 
2969 
2973 
2977 
2981 
2985 
2989 
2991 
2992 /**
2993  A template for options that set HA_CREATE_INFO::table_options and
2994  also records if the option was explicitly set.
2995 */
2996 template <ulong Property_flag, table_options_t Default, table_options_t Yes,
2997  table_options_t No>
3000 
3002 
3003  public:
3005  : value(value) {}
3006 
3008  if (super::contextualize(pc)) return true;
3009  pc->create_info->table_options &= ~(Yes | No);
3010  switch (value) {
3011  case Ternary_option::ON:
3012  pc->create_info->table_options |= Yes;
3013  break;
3014  case Ternary_option::OFF:
3015  pc->create_info->table_options |= No;
3016  break;
3018  break;
3019  default:
3020  DBUG_ASSERT(false);
3021  }
3022  pc->create_info->used_fields |= Property_flag;
3023  return false;
3024  }
3025 };
3026 
3027 /**
3028  Node for the @SQL{PACK_KEYS [=] @B{1|0|DEFAULT}} table option
3029 
3030  @ingroup ptn_create_or_alter_table_options
3031 
3032  PACK_KEYS | Constructor parameter
3033  ----------|----------------------
3034  1 | Ternary_option::ON
3035  0 | Ternary_option::OFF
3036  DEFAULT | Ternary_option::DEFAULT
3037 */
3039  0, // DEFAULT
3040  HA_OPTION_PACK_KEYS, // ON
3041  HA_OPTION_NO_PACK_KEYS> // OFF
3043 
3044 /**
3045  Node for the @SQL{STATS_PERSISTENT [=] @B{1|0|DEFAULT}} table option
3046 
3047  @ingroup ptn_create_or_alter_table_options
3048 
3049  STATS_PERSISTENT | Constructor parameter
3050  -----------------|----------------------
3051  1 | Ternary_option::ON
3052  0 | Ternary_option::OFF
3053  DEFAULT | Ternary_option::DEFAULT
3054 */
3056  0, // DEFAULT
3060 
3061 /**
3062  A template for options that set HA_CREATE_INFO::table_options and
3063  also records if the option was explicitly set.
3064 */
3065 template <ulong Property_flag, table_options_t Yes, table_options_t No>
3068 
3069  const bool value;
3070 
3071  public:
3073 
3075  if (super::contextualize(pc)) return true;
3076  pc->create_info->table_options &= ~(Yes | No);
3077  pc->create_info->table_options |= value ? Yes : No;
3078  pc->create_info->used_fields |= Property_flag;
3079  return false;
3080  }
3081 };
3082 
3083 /**
3084  Node for the @SQL{CHECKSUM|TABLE_CHECKSUM [=] @B{0|@<not 0@>}} table option
3085 
3086  @ingroup ptn_create_or_alter_table_options
3087 
3088  TABLE_CHECKSUM | Constructor parameter
3089  ---------------|----------------------
3090  0 | false
3091  not 0 | true
3092 */
3094  HA_OPTION_CHECKSUM, // ON
3095  HA_OPTION_NO_CHECKSUM // OFF
3096  >
3098 
3099 /**
3100  Node for the @SQL{DELAY_KEY_WRITE [=] @B{0|@<not 0@>}} table option
3101 
3102  @ingroup ptn_create_or_alter_table_options
3103 
3104  TABLE_CHECKSUM | Constructor parameter
3105  ---------------|----------------------
3106  0 | false
3107  not 0 | true
3108 */
3113 
3114 /**
3115  Node for the @SQL{ENGINE [=] @B{@<identifier@>|@<string@>}} table option
3116 
3117  @ingroup ptn_create_or_alter_table_options
3118 */
3121 
3123 
3124  public:
3125  /**
3126  @param engine Storage engine name.
3127  */
3129  : engine(engine) {}
3130 
3131  bool contextualize(Table_ddl_parse_context *pc) override;
3132 };
3133 
3134 /**
3135  Node for the @SQL{SECONDARY_ENGINE [=] @B{@<identifier@>|@<string@>|NULL}}
3136  table option.
3137 
3138  @ingroup ptn_create_or_alter_table_options
3139 */
3142 
3143  public:
3148 
3149  bool contextualize(Table_ddl_parse_context *pc) override;
3150 
3151  private:
3152  const LEX_STRING m_secondary_engine{nullptr, 0};
3153 };
3154 
3155 /**
3156  Node for the @SQL{STATS_AUTO_RECALC [=] @B{@<0|1|DEFAULT@>})} table option
3157 
3158  @ingroup ptn_create_or_alter_table_options
3159 */
3162 
3164 
3165  public:
3166  /**
3167  @param value
3168  STATS_AUTO_RECALC | value
3169  ------------------|----------------------
3170  1 | Ternary_option::ON
3171  0 | Ternary_option::OFF
3172  DEFAULT | Ternary_option::DEFAULT
3173  */
3175 
3176  bool contextualize(Table_ddl_parse_context *pc) override;
3177 };
3178 
3179 /**
3180  Node for the @SQL{STATS_SAMPLE_PAGES [=] @B{@<integer@>|DEFAULT}} table option
3181 
3182  @ingroup ptn_create_or_alter_table_options
3183 */
3187 
3189 
3190  public:
3191  /**
3192  Constructor for implicit number of pages
3193 
3194  @param value Nunber of pages, 1@<=N@<=65535.
3195  */
3197  DBUG_ASSERT(value != 0 && value <= 0xFFFF);
3198  }
3199  /**
3200  Constructor for the DEFAULT number of pages
3201  */
3203 
3204  bool contextualize(Table_ddl_parse_context *pc) override;
3205 };
3206 
3209 
3211 
3212  public:
3214  : tables(tables) {}
3215 
3216  bool contextualize(Table_ddl_parse_context *pc) override;
3217 };
3218 
3221 
3223 
3224  public:
3226 
3228  if (super::contextualize(pc)) return true;
3230  return false;
3231  }
3232 };
3233 
3236 
3238 
3239  public:
3241  : value(value) {
3242  DBUG_ASSERT(value != nullptr);
3243  }
3244 
3245  bool contextualize(Table_ddl_parse_context *pc) override;
3246 };
3247 
3250 
3252 
3253  public:
3255  : value(value) {
3256  DBUG_ASSERT(value != nullptr);
3257  }
3258 
3259  bool contextualize(Table_ddl_parse_context *pc) override;
3260 };
3261 
3265 
3266  public:
3267  explicit PT_check_constraint(LEX_STRING &name, Item *expr, bool is_enforced) {
3268  cc_spec.name = name;
3269  cc_spec.check_expr = expr;
3270  cc_spec.is_enforced = is_enforced;
3271  }
3273 
3275  if (super::contextualize(pc) ||
3277  return true;
3278 
3280  return true;
3281 
3283  return false;
3284  }
3285 };
3286 
3289 
3292  // Currently we ignore that constraint in the executor.
3294 
3295  const char *opt_place;
3296 
3297  public:
3300  const char *opt_place = NULL)
3304  opt_place(opt_place) {}
3305 
3306  bool contextualize(Table_ddl_parse_context *pc) override;
3307 };
3308 
3309 /**
3310  Top-level node for the CREATE %TABLE statement
3311 
3312  @ingroup ptn_create_table
3313 */
3324 
3326 
3327  public:
3328  /**
3329  @param mem_root MEM_ROOT to use for allocation
3330  @param is_temporary True if @SQL{CREATE @B{TEMPORARY} %TABLE}
3331  @param only_if_not_exists True if @SQL{CREATE %TABLE ... @B{IF NOT EXISTS}}
3332  @param table_name @SQL{CREATE %TABLE ... @B{@<table name@>}}
3333  @param opt_table_element_list NULL or a list of table column and
3334  constraint definitions.
3335  @param opt_create_table_options NULL or a list of
3336  @ref ptn_create_or_alter_table_options
3337  "table options".
3338  @param opt_partitioning NULL or the @SQL{PARTITION BY} clause.
3339  @param on_duplicate DUPLICATE, IGNORE or fail with an error
3340  on data duplication errors (relevant
3341  for @SQL{CREATE TABLE ... SELECT}
3342  statements).
3343  @param opt_query_expression NULL or the @SQL{@B{SELECT}} clause.
3344  */
3361  opt_like_clause(NULL) {}
3362  /**
3363  @param mem_root MEM_ROOT to use for allocation
3364  @param is_temporary True if @SQL{CREATE @B{TEMPORARY} %TABLE}.
3365  @param only_if_not_exists True if @SQL{CREATE %TABLE ... @B{IF NOT EXISTS}}.
3366  @param table_name @SQL{CREATE %TABLE ... @B{@<table name@>}}.
3367  @param opt_like_clause NULL or the @SQL{@B{LIKE @<table name@>}} clause.
3368  */
3382 
3383  Sql_cmd *make_cmd(THD *thd) override;
3384 };
3385 
3388 
3389  public:
3390  PT_create_role(bool if_not_exists, const List<LEX_USER> *roles)
3391  : sql_cmd(if_not_exists, roles) {}
3392 
3393  Sql_cmd *make_cmd(THD *thd) override {
3395  return &sql_cmd;
3396  }
3397 };
3398 
3401 
3402  public:
3403  explicit PT_drop_role(bool ignore_errors, const List<LEX_USER> *roles)
3404  : sql_cmd(ignore_errors, roles) {}
3405 
3406  Sql_cmd *make_cmd(THD *thd) override {
3408  return &sql_cmd;
3409  }
3410 };
3411 
3414 
3415  public:
3416  explicit PT_set_role(role_enum role_type,
3417  const List<LEX_USER> *opt_except_roles = NULL)
3418  : sql_cmd(role_type, opt_except_roles) {
3419  DBUG_ASSERT(role_type == role_enum::ROLE_ALL || opt_except_roles == NULL);
3420  }
3421  explicit PT_set_role(const List<LEX_USER> *roles) : sql_cmd(roles) {}
3422 
3423  Sql_cmd *make_cmd(THD *thd) override {
3425  return &sql_cmd;
3426  }
3427 };
3428 
3429 /**
3430  This class is used for representing both static and dynamic privileges on
3431  global as well as table and column level.
3432 */
3433 struct Privilege {
3435 
3438 
3441  : type(type), columns(columns) {}
3442 };
3443 
3444 struct Static_privilege : public Privilege {
3445  const uint grant;
3446 
3448  : Privilege(STATIC, columns_arg), grant(grant) {}
3449 };
3450 
3451 struct Dynamic_privilege : public Privilege {
3453 
3455  const Mem_root_array<LEX_CSTRING> *columns_arg)
3456  : Privilege(DYNAMIC, columns_arg), ident(ident) {}
3457 };
3458 
3460  private:
3462 
3463  public:
3464  explicit PT_role_or_privilege(const POS &pos) : pos(pos) {}
3465 
3466  virtual LEX_USER *get_user(THD *thd) {
3467  thd->syntax_error_at(pos, "Illegal authorization identifier");
3468  return NULL;
3469  }
3470  virtual Privilege *get_privilege(THD *thd) {
3471  thd->syntax_error_at(pos, "Illegal privilege identifier");
3472  return NULL;
3473  }
3474 };
3475 
3479 
3480  public:
3482  const LEX_STRING &host)
3484 
3485  LEX_USER *get_user(THD *thd) override {
3486  return LEX_USER::alloc(thd, &role, &host);
3487  }
3488 };
3489 
3492 
3493  public:
3496 
3497  LEX_USER *get_user(THD *thd) override {
3498  return LEX_USER::alloc(thd, &ident, NULL);
3499  }
3500 
3501  Privilege *get_privilege(THD *thd) override {
3502  return new (thd->mem_root) Dynamic_privilege(ident, NULL);
3503  }
3504 };
3505 
3507  const uint grant;
3509 
3510  public:
3514 
3515  Privilege *get_privilege(THD *thd) override {
3516  return new (thd->mem_root) Static_privilege(grant, columns);
3517  }
3518 };
3519 
3522 
3523  public:
3526 
3527  Privilege *get_privilege(THD *thd) override {
3528  return new (thd->mem_root) Dynamic_privilege(ident, nullptr);
3529  }
3530 };
3531 
3535  const bool with_admin_option;
3536 
3537  public:
3539  const List<LEX_USER> *users, bool with_admin_option)
3541 
3542  Sql_cmd *make_cmd(THD *thd) override {
3544 
3545  List<LEX_USER> *role_objects = new (thd->mem_root) List<LEX_USER>;
3546  if (role_objects == NULL) return NULL; // OOM
3547  for (PT_role_or_privilege *r : *roles) {
3548  LEX_USER *user = r->get_user(thd);
3549  if (r == NULL || role_objects->push_back(user)) return NULL;
3550  }
3551 
3552  return new (thd->mem_root)
3554  }
3555 };
3556 
3560 
3561  public:
3563  const List<LEX_USER> *users)
3564  : roles(roles), users(users) {}
3565 
3566  Sql_cmd *make_cmd(THD *thd) override {
3568 
3569  List<LEX_USER> *role_objects = new (thd->mem_root) List<LEX_USER>;
3570  if (role_objects == NULL) return NULL; // OOM
3571  for (PT_role_or_privilege *r : *roles) {
3572  LEX_USER *user = r->get_user(thd);
3573  if (r == NULL || role_objects->push_back(user)) return NULL;
3574  }
3575  return new (thd->mem_root) Sql_cmd_revoke_roles(role_objects, users);
3576  }
3577 };
3578 
3581 
3582  public:
3583  PT_alter_user_default_role(bool if_exists, const List<LEX_USER> *users,
3584  const List<LEX_USER> *roles,
3585  const role_enum role_type)
3586  : sql_cmd(if_exists, users, roles, role_type) {}
3587 
3588  Sql_cmd *make_cmd(THD *thd) override {
3590  return &sql_cmd;
3591  }
3592 };
3593 
3596 
3597  public:
3598  PT_show_grants(const LEX_USER *opt_for_user,
3599  const List<LEX_USER> *opt_using_users)
3600  : sql_cmd(opt_for_user, opt_using_users) {
3601  DBUG_ASSERT(opt_using_users == NULL || opt_for_user != NULL);
3602  }
3603 
3604  Sql_cmd *make_cmd(THD *thd) override {
3606  return &sql_cmd;
3607  }
3608 };
3609 
3610 /**
3611  Base class for Parse tree nodes of SHOW FIELDS/SHOW INDEX statements.
3612 */
3614  protected:
3616 
3618  const LEX_STRING &wild, Item *where_condition)
3619  : m_sql_cmd(static_cast<enum_sql_command>(type)),
3620  m_pos(pos),
3621  m_type(type),
3622  m_table_ident(table_ident),
3623  m_wild(wild),
3624  m_where_condition(where_condition) {
3625  DBUG_ASSERT(wild.str == nullptr || where_condition == nullptr);
3626  }
3627 
3628  public:
3629  Sql_cmd *make_cmd(THD *thd) override;
3630 
3631  private:
3632  // Sql_cmd for SHOW COLUMNS/SHOW INDEX statements.
3634 
3635  // Textual location of a token just parsed.
3637 
3638  // SHOW_FIELDS or SHOW_KEYS
3640 
3641  // Table used in the statement.
3643 
3644  // Wild or where clause used in the statement.
3647 };
3648 
3649 /**
3650  Parse tree node for SHOW FIELDS statement.
3651 */
3654 
3655  public:
3656  PT_show_fields(const POS &pos, Show_cmd_type show_cmd_type,
3657  Table_ident *table, const LEX_STRING &wild)
3658  : PT_show_fields_and_keys(pos, SHOW_FIELDS, table, wild, nullptr),
3659  m_show_cmd_type(show_cmd_type) {}
3660 
3661  PT_show_fields(const POS &pos, Show_cmd_type show_cmd_type,
3662  Table_ident *table_ident, Item *where_condition = nullptr)
3664  where_condition),
3665  m_show_cmd_type(show_cmd_type) {}
3666 
3667  Sql_cmd *make_cmd(THD *thd) override;
3668 
3669  private:
3671 };
3672 
3673 /**
3674  Parse tree node for SHOW INDEX statement.
3675 */
3677  public:
3678  PT_show_keys(const POS &pos, bool extended_show, Table_ident *table,
3679  Item *where_condition)
3681  where_condition),
3682  m_extended_show(extended_show) {}
3683 
3684  Sql_cmd *make_cmd(THD *thd) override;
3685 
3686  private:
3688 
3689  // Flag to indicate EXTENDED keyword usage in the statement.
3691 };
3692 
3695 
3696  protected:
3698  : flag(flag) {}
3699 
3700  public:
3702  if (super::contextualize(pc)) return true;
3703  pc->alter_info->flags |= flag;
3704  return false;
3705  }
3706 
3707  protected:
3708  /**
3709  A routine used by the parser to decide whether we are specifying a full
3710  partitioning or if only partitions to add or to reorganize.
3711 
3712  @retval true ALTER TABLE ADD/REORGANIZE PARTITION.
3713  @retval false Something else.
3714  */
3718  }
3719 
3720  public:
3722 };
3723 
3726 
3727  public:
3729  PT_field_def_base *field_def,
3730  PT_table_constraint_def *opt_column_constraint,
3731  const char *opt_place)
3732  : super(Alter_info::ALTER_ADD_COLUMN),
3733  m_column_def(field_ident, field_def, opt_column_constraint, opt_place) {
3734  }
3735 
3738  }
3739 
3740  private:
3742 };
3743 
3746 
3747  public:
3749  const Mem_root_array<PT_table_element *> *columns)
3750  : super(Alter_info::ALTER_ADD_COLUMN), m_columns(columns) {}
3751 
3753  if (super::contextualize(pc)) return true;
3754 
3755  for (auto *column : *m_columns)
3756  if (column->contextualize(pc)) return true;
3757 
3758  return false;
3759  }
3760 
3761  private:
3763 };
3764 
3767 
3768  public:
3770  : super(Alter_info::ALTER_ADD_INDEX), m_constraint(constraint) {}
3771 
3773  return super::contextualize(pc) || m_constraint->contextualize(pc);
3774  }
3775 
3776  private:
3778 };
3779 
3782 
3783  public:
3785  const LEX_STRING &new_name,
3786  PT_field_def_base *field_def,
3787  const char *opt_place)
3788  : super(Alter_info::ALTER_CHANGE_COLUMN),
3789  m_old_name(old_name),
3790  m_new_name(new_name),
3791  m_field_def(field_def),
3792  m_opt_place(opt_place) {}
3793 
3795  PT_field_def_base *field_def,
3796  const char *opt_place)
3797  : PT_alter_table_change_column(name, name, field_def, opt_place) {}
3798 
3799  bool contextualize(Table_ddl_parse_context *pc) override;
3800 
3801  private:
3805  const char *m_opt_place;
3806 };
3807 
3810 
3811  protected:
3813  Alter_info::Alter_info_flag alter_info_flag,
3814  const char *name)
3815  : super(alter_info_flag), m_alter_drop(drop_type, name) {}
3816 
3817  public:
3819  return (super::contextualize(pc) ||
3821  }
3822 
3823  private:
3825 };
3826 
3828  public:
3829  explicit PT_alter_table_drop_column(const char *name)
3830  : PT_alter_table_drop(Alter_drop::COLUMN, Alter_info::ALTER_DROP_COLUMN,
3831  name) {}
3832 };
3833 
3835  public:
3838  Alter_info::DROP_FOREIGN_KEY, name) {}
3839 };
3840 
3842  public:
3843  explicit PT_alter_table_drop_key(const char *name)
3844  : PT_alter_table_drop(Alter_drop::KEY, Alter_info::ALTER_DROP_INDEX,
3845  name) {}
3846 };
3847 
3849  public:
3851  : PT_alter_table_drop(Alter_drop::CHECK_CONSTRAINT,
3852  Alter_info::DROP_CHECK_CONSTRAINT, name) {}
3853 };
3854 
3857 
3858  public:
3859  explicit PT_alter_table_check_constraint(const char *name, bool state)
3860  : super(state ? Alter_info::ENFORCE_CHECK_CONSTRAINT
3861  : Alter_info::SUSPEND_CHECK_CONSTRAINT),
3862  cc_state(Alter_state::Type::CHECK_CONSTRAINT, name, state) {}
3863 
3865  return (super::contextualize(pc) ||
3867  }
3868 
3869  private:
3871 };
3872 
3875 
3876  public:
3877  explicit PT_alter_table_enable_keys(bool enable)
3878  : super(Alter_info::ALTER_KEYS_ONOFF), m_enable(enable) {}
3879 
3881  pc->alter_info->keys_onoff =
3883  return super::contextualize(pc);
3884  }
3885 
3886  private:
3887  bool m_enable;
3888 };
3889 
3892 
3893  public:
3894  PT_alter_table_set_default(const char *col_name, Item *opt_default_expr)
3895  : super(Alter_info::ALTER_CHANGE_COLUMN_DEFAULT),
3896  m_name(col_name),
3897  m_expr(opt_default_expr) {}
3898 
3900  if (super::contextualize(pc) || itemize_safe(pc, &m_expr)) return true;
3901  Alter_column *alter_column;
3902  if (m_expr == nullptr || m_expr->basic_const_item()) {
3903  alter_column = new (pc->mem_root) Alter_column(m_name, m_expr);
3904  } else {
3905  auto vg = new (pc->mem_root) Value_generator;
3906  if (vg == nullptr) return true; // OOM
3907  vg->expr_item = m_expr;
3908  vg->set_field_stored(true);
3909  alter_column = new (pc->mem_root) Alter_column(m_name, vg);
3910  }
3911  if (alter_column == nullptr ||
3912  pc->alter_info->alter_list.push_back(alter_column)) {
3913  return true; // OOM
3914  }
3915  return false;
3916  }
3917 
3918  private:
3919  const char *m_name;
3921 };
3922 
3925 
3926  public:
3927  PT_alter_table_index_visible(const char *name, bool visible)
3928  : super(Alter_info::ALTER_INDEX_VISIBILITY),
3929  m_alter_index_visibility(name, visible) {}
3930 
3932  return (super::contextualize(pc) ||
3935  }
3936 
3937  private:
3939 };
3940 
3943 
3944  public:
3945  explicit PT_alter_table_rename(const Table_ident *ident)
3946  : super(Alter_info::ALTER_RENAME), m_ident(ident) {}
3947 
3948  bool contextualize(Table_ddl_parse_context *pc) override;
3949 
3950  bool is_rename_table() const override { return true; }
3951 
3952  private:
3953  const Table_ident *const m_ident;
3954 };
3955 
3958 
3959  public:
3960  PT_alter_table_rename_key(const char *from, const char *to)
3961  : super(Alter_info::ALTER_RENAME_INDEX), m_rename_key(from, to) {}
3962 
3964  return super::contextualize(pc) ||
3966  }
3967 
3968  private:
3970 };
3971 
3974 
3975  public:
3976  PT_alter_table_rename_column(const char *from, const char *to)
3977  : super(Alter_info::ALTER_CHANGE_COLUMN), m_rename_column(from, to) {}
3978 
3980  return super::contextualize(pc) ||
3982  }
3983 
3984  private:
3986 };
3987 
3990 
3991  public:
3993  const CHARSET_INFO *opt_collation)
3994  : super(Alter_info::ALTER_OPTIONS),
3995  m_charset(charset),
3996  m_collation(opt_collation) {}
3997 
3998  bool contextualize(Table_ddl_parse_context *pc) override;
3999 
4000  private:
4001  const CHARSET_INFO *const m_charset;
4003 };
4004 
4007 
4008  public:
4009  PT_alter_table_force() : super(Alter_info::ALTER_RECREATE) {}
4010 };
4011 
4014 
4015  public:
4017  : super(Alter_info::ALTER_ORDER), m_order(order) {}
4018 
4020  if (super::contextualize(pc) || m_order->contextualize(pc)) return true;
4021  pc->select->order_list = m_order->value;
4022  return false;
4023  }
4024 
4025  private:
4027 };
4028 
4031 
4032  public:
4034  : super(Alter_info::ALTER_PARTITION), m_partition(partition) {}
4035 
4037  if (super::contextualize(pc) || m_partition->contextualize(pc)) return true;
4039  return false;
4040  }
4041 
4042  private:
4044 };
4045 
4048 
4049  public:
4051  : super(Alter_info::ALTER_REMOVE_PARTITIONING) {}
4052 };
4053 
4056 
4057  friend class PT_alter_table_standalone_stmt; // to access make_cmd()
4058 
4059  protected:
4061  : super(alter_info_flag) {}
4062 
4063  private:
4064  virtual Sql_cmd *make_cmd(Table_ddl_parse_context *pc) = 0;
4065 };
4066 
4067 /**
4068  Node for the @SQL{ALTER TABLE ADD PARTITION} statement
4069 
4070  @ingroup ptn_alter_table
4071 */
4074 
4075  public:
4076  explicit PT_alter_table_add_partition(bool no_write_to_binlog)
4077  : super(Alter_info::ALTER_ADD_PARTITION),
4078  m_no_write_to_binlog(no_write_to_binlog) {}
4079 
4081  if (super::contextualize(pc)) return true;
4082 
4083  LEX *const lex = pc->thd->lex;
4085  DBUG_ASSERT(lex->part_info == nullptr);
4086  lex->part_info = &m_part_info;
4087  return false;
4088  }
4089 
4091  return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
4092  }
4093 
4094  protected:
4096 
4097  private:
4099 };
4100 
4101 /**
4102  Node for the @SQL{ALTER TABLE ADD PARTITION (@<partition list@>)} statement
4103 
4104  @ingroup ptn_alter_table
4105 */
4107  : public PT_alter_table_add_partition {
4109 
4110  public:
4112  bool no_write_to_binlog,
4113  const Mem_root_array<PT_part_definition *> *def_list)
4114  : super(no_write_to_binlog), m_def_list(def_list) {}
4115 
4116  bool contextualize(Table_ddl_parse_context *pc) override;
4117 
4118  private:
4120 };
4121 
4122 /**
4123  Node for the @SQL{ALTER TABLE ADD PARTITION PARTITIONS (@<n>@)} statement
4124 
4125  @ingroup ptn_alter_table
4126 */
4128  : public PT_alter_table_add_partition {
4130 
4131  public:
4132  PT_alter_table_add_partition_num(bool no_write_to_binlog, uint num_parts)
4133  : super(no_write_to_binlog) {
4134  m_part_info.num_parts = num_parts;
4135  }
4136 };
4137 
4141 
4142  public:
4143  explicit PT_alter_table_drop_partition(const List<String> &partitions)
4144  : super(Alter_info::ALTER_DROP_PARTITION), m_partitions(partitions) {}
4145 
4147  if (super::contextualize(pc)) return true;
4148 
4151  return false;
4152  }
4153 
4155  return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
4156  }
4157 
4158  private:
4160 };
4161 
4165 
4166  public:
4168  Alter_info::Alter_info_flag alter_info_flag,
4169  const List<String> *opt_partition_list)
4170  : super(alter_info_flag), m_opt_partition_list(opt_partition_list) {}
4171 
4174  if (m_opt_partition_list == NULL)
4176  else
4178  return super::contextualize(pc);
4179  }
4180 
4181  private:
4183 };
4184 
4188 
4189  public:
4190  PT_alter_table_rebuild_partition(bool no_write_to_binlog,
4191  const List<String> *opt_partition_list)
4192  : super(Alter_info::ALTER_REBUILD_PARTITION, opt_partition_list),
4193  m_no_write_to_binlog(no_write_to_binlog) {}
4194 
4196  if (super::contextualize(pc)) return true;
4198  return false;
4199  }
4200 
4202  return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
4203  }
4204 
4205  private:
4207 };
4208 
4212 
4213  public:
4214  PT_alter_table_optimize_partition(bool no_write_to_binlog,
4215  const List<String> *opt_partition_list)
4216  : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
4217  m_no_write_to_binlog(no_write_to_binlog) {}
4218 
4220  if (super::contextualize(pc)) return true;
4222  pc->thd->lex->check_opt.init();
4223  return false;
4224  }
4225 
4227  return new (pc->mem_root)
4229  }
4230 
4231  private:
4233 };
4234 
4238 
4239  public:
4240  PT_alter_table_analyze_partition(bool no_write_to_binlog,
4241  const List<String> *opt_partition_list)
4242  : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
4243  m_no_write_to_binlog(no_write_to_binlog) {}
4244 
4246  if (super::contextualize(pc)) return true;
4248  pc->thd->lex->check_opt.init();
4249  return false;
4250  }
4251 
4253  return new (pc->mem_root)
4255  }
4256 
4257  private:
4259 };
4260 
4264 
4265  public:
4268  : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
4269  m_flags(flags),
4271 
4273  if (super::contextualize(pc)) return true;
4274 
4275  LEX *const lex = pc->thd->lex;
4276  lex->check_opt.init();
4277  lex->check_opt.flags |= m_flags;
4279  return false;
4280  }
4281 
4283  return new (pc->mem_root)
4285  }
4286 
4287  private:
4290 };
4291 
4295 
4296  public:
4297  PT_alter_table_repair_partition(bool no_write_to_binlog,
4298  const List<String> *opt_partition_list,
4300  : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
4301  m_no_write_to_binlog(no_write_to_binlog),
4302  m_flags(flags),
4304 
4306  if (super::contextualize(pc)) return true;
4307 
4308  LEX *const lex = pc->thd->lex;
4310 
4311  lex->check_opt.init();
4312  lex->check_opt.flags |= m_flags;
4314 
4315  return false;
4316  }
4317 
4319  return new (pc->mem_root)
4321  }
4322 
4323  private:
4327 };
4328 
4332 
4333  public:
4334  PT_alter_table_coalesce_partition(bool no_write_to_binlog, uint num_parts)
4335  : super(Alter_info::ALTER_COALESCE_PARTITION),
4336  m_no_write_to_binlog(no_write_to_binlog),
4337  m_num_parts(num_parts) {}
4338 
4340  if (super::contextualize(pc)) return true;
4341 
4344  return false;
4345  }
4346 
4348  return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
4349  }
4350 
4351  private:
4354 };
4355 
4359 
4360  public:
4362  const List<String> *opt_partition_list)
4363  : super(static_cast<Alter_info::Alter_info_flag>(
4364  Alter_info::ALTER_ADMIN_PARTITION |
4365  Alter_info::ALTE