MySQL  8.0.17
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_cmpfunc.h" // make_condition
49 #include "sql/item_func.h"
50 #include "sql/key_spec.h"
51 #include "sql/mdl.h"
52 #include "sql/mem_root_array.h"
53 #include "sql/mysqld.h" // table_alias_charset
54 #include "sql/opt_explain.h" // Sql_cmd_explain_other_thread
55 #include "sql/parse_location.h"
56 #include "sql/parse_tree_helpers.h" // PT_item_list
59 #include "sql/partition_info.h"
60 #include "sql/query_result.h" // Query_result
63 #include "sql/set_var.h"
64 #include "sql/sp_head.h" // sp_head
65 #include "sql/sql_admin.h" // Sql_cmd_shutdown etc.
66 #include "sql/sql_alter.h"
67 #include "sql/sql_check_constraint.h" // Sql_check_constraint_spec
68 #include "sql/sql_class.h" // THD
69 #include "sql/sql_cmd_srs.h"
70 #include "sql/sql_exchange.h"
71 #include "sql/sql_lex.h" // LEX
72 #include "sql/sql_list.h"
73 #include "sql/sql_load.h" // Sql_cmd_load_table
74 #include "sql/sql_parse.h" // add_join_natural
76 #include "sql/sql_restart_server.h" // Sql_cmd_restart_server
77 #include "sql/sql_show.h"
78 #include "sql/sql_tablespace.h" // Tablespace_options
79 #include "sql/sql_truncate.h" // Sql_cmd_truncate_table
80 #include "sql/table.h" // Common_table_expr
81 #include "sql/table_function.h" // Json_table_column
82 #include "sql/window.h" // Window
83 #include "sql/window_lex.h"
84 #include "sql_string.h"
85 #include "thr_lock.h"
86 
87 class PT_field_def_base;
88 class PT_hint_list;
90 class PT_subquery;
91 class PT_type;
92 class Sql_cmd;
93 struct MEM_ROOT;
94 
95 /**
96  @defgroup ptn Parse tree nodes
97  @ingroup Parser
98 */
99 /**
100  @defgroup ptn_stmt Nodes representing SQL statements
101  @ingroup ptn
102 */
103 /**
104  @defgroup ptn_create_table CREATE TABLE statement
105  @ingroup ptn_stmt
106 */
107 /**
108  @defgroup ptn_alter_table ALTER TABLE statement
109  @ingroup ptn_stmt
110 */
111 /**
112  @defgroup ptn_create_table_stuff Clauses of CREATE TABLE statement
113  @ingroup ptn_create_table
114 */
115 /**
116  @defgroup ptn_partitioning CREATE/ALTER TABLE partitioning-related stuff
117  @ingroup ptn_create_table ptn_alter_table
118 */
119 /**
120  @defgroup ptn_part_options Partition options in CREATE/ALTER TABLE
121  @ingroup ptn_partitioning
122 */
123 /**
124  @defgroup ptn_create_or_alter_table_options Table options of CREATE/ALTER
125  TABLE
126  @anchor ptn_create_or_alter_table_options
127  @ingroup ptn_create_table ptn_alter_table
128 */
129 /**
130  @defgroup ptn_col_types Column types in CREATE/ALTER TABLE
131  @ingroup ptn_create_table ptn_alter_table
132 */
133 /**
134  @defgroup ptn_col_attrs Column attributes in CREATE/ALTER TABLE
135  @ingroup ptn_create_table ptn_alter_table
136 */
137 /**
138  @defgroup ptn_not_gcol_attr Non-generated column attributes in CREATE/ALTER
139  TABLE
140  @ingroup ptn_col_attrs ptn_alter_table
141 */
142 
143 /**
144  Calls contextualize() on every node in the array.
145 */
146 template <class Node_type, class Parse_context_type>
148  Parse_context_type *pc) {
149  for (Node_type *i : nodes)
150  if (i->contextualize(pc)) return true;
151  return false;
152 }
153 
154 /**
155  Base class for all top-level nodes of SQL statements
156 
157  @ingroup ptn_stmt
158 */
160  Parse_tree_root(const Parse_tree_root &) = delete;
161  void operator=(const Parse_tree_root &) = delete;
162 
163  protected:
164  virtual ~Parse_tree_root() {}
166 
167  public:
168  virtual Sql_cmd *make_cmd(THD *thd) = 0;
169 };
170 
172  public:
174  : m_alter_info(mem_root) {}
175 
176  virtual ~PT_table_ddl_stmt_base() = 0; // force abstract class
177 
178  protected:
180 };
181 
183 
184 /**
185  Convenience function that calls Parse_tree_node::contextualize() on the node
186  if it's non-NULL.
187 */
188 template <class Context, class Node>
189 bool contextualize_safe(Context *pc, Node *node) {
190  if (node == NULL) return false;
191 
192  return node->contextualize(pc);
193 }
194 
195 /**
196  Parse context for the table DDL (ALTER TABLE and CREATE TABLE) nodes.
197 
198  For internal use in the contextualization code.
199 */
201  Table_ddl_parse_context(THD *thd_arg, SELECT_LEX *select_arg,
203  : Parse_context(thd_arg, select_arg),
204  create_info(thd_arg->lex->create_info),
206  key_create_info(&thd_arg->lex->key_create_info) {}
207 
211 };
212 
213 /**
214  Base class for all table DDL (ALTER TABLE and CREATE TABLE) nodes.
215 */
217 
218 /**
219  Convenience function that calls Item::itemize() on the item if it's
220  non-NULL.
221 */
222 inline bool itemize_safe(Parse_context *pc, Item **item) {
223  if (*item == NULL) return false;
224  return (*item)->itemize(pc, item);
225 }
226 
227 class PT_order_expr : public Parse_tree_node, public ORDER {
229 
230  public:
231  PT_order_expr(Item *item_arg, enum_order dir) {
232  item_ptr = item_arg;
233  direction = (dir == ORDER_DESC) ? ORDER_DESC : ORDER_ASC;
234  }
235 
236  virtual bool contextualize(Parse_context *pc) {
237  return super::contextualize(pc) || item_ptr->itemize(pc, &item_ptr);
238  }
239 };
240 
243 
244  public:
246 
247  public:
248  virtual bool contextualize(Parse_context *pc) {
249  if (super::contextualize(pc)) return true;
250  for (ORDER *o = value.first; o != NULL; o = o->next) {
251  if (static_cast<PT_order_expr *>(o)->contextualize(pc)) return true;
252  }
253  return false;
254  }
255 
256  void push_back(PT_order_expr *order) {
257  order->item = &order->item_ptr;
258  order->used_alias = false;
259  order->used = 0;
260  order->is_position = false;
261  value.link_in_list(order, &order->next);
262  }
263 };
264 
267 
268  public:
269  virtual bool contextualize(Parse_context *pc) {
270  return super::contextualize(pc);
271  }
272 };
273 
274 /**
275  Represents an element of the WITH list:
276  WITH [...], [...] SELECT ...,
277  ^ or ^
278  i.e. a Common Table Expression (CTE, or Query Name in SQL99 terms).
279 */
282 
283  public:
284  explicit PT_common_table_expr(const LEX_STRING &name,
285  const LEX_STRING &subq_text,
286  uint subq_text_offset, PT_subquery *sn,
288  MEM_ROOT *mem_root);
289 
290  /// The name after AS
291  const LEX_STRING &name() const { return m_name; }
292  /**
293  @param thd Thread handler
294  @param[out] node PT_subquery
295  @returns a PT_subquery to attach to a table reference for this CTE
296  */
297  bool make_subquery_node(THD *thd, PT_subquery **node);
298  /**
299  @param tl Table reference to match
300  @param in_self If this is a recursive reference
301  @param[out] found Is set to true/false if matches or not
302  @returns true if error
303  */
304  bool match_table_ref(TABLE_LIST *tl, bool in_self, bool *found);
305  /**
306  @returns true if 'other' is the same instance as 'this'
307  */
308  bool is(const Common_table_expr *other) const {
309  return other == &m_postparse;
310  }
311  void print(const THD *thd, String *str, enum_query_type query_type);
312 
313  private:
315  /// Raw text of query expression (including parentheses)
317  /**
318  Offset in bytes of m_subq_text in original statement which had the WITH
319  clause.
320  */
322  /// Parsed version of subq_text
324  /// List of explicitely specified column names; if empty, no list.
326  /**
327  A TABLE_LIST representing a CTE needs access to the WITH list
328  element it derives from. However, in order to:
329  - limit the members which TABLE_LIST can access
330  - avoid including this header file everywhere TABLE_LIST needs to access
331  these members,
332  these members are relocated into a separate inferior object whose
333  declaration is in table.h, like that of TABLE_LIST. It's the "postparse"
334  part. TABLE_LIST accesses this inferior object only.
335  */
337 
338  friend bool SELECT_LEX_UNIT::clear_corr_ctes();
339 };
340 
341 /**
342  Represents the WITH list.
343  WITH [...], [...] SELECT ...,
344  ^^^^^^^^^^^^
345 */
348 
349  public:
350  /// @param mem_root where interior objects are allocated
354  return m_elements;
355  }
356 
357  private:
359 };
360 
361 /**
362  Represents the WITH clause:
363  WITH [...], [...] SELECT ...,
364  ^^^^^^^^^^^^^^^^^
365 */
368 
369  public:
370  PT_with_clause(const PT_with_list *l, bool r)
371  : m_list(l), m_recursive(r), m_most_inner_in_parsing(nullptr) {}
372 
373  virtual bool contextualize(Parse_context *pc) {
374  if (super::contextualize(pc)) return true; /* purecov: inspected */
375  // WITH complements a query expression (a unit).
376  pc->select->master_unit()->m_with_clause = this;
377  return false;
378  }
379 
380  /**
381  Looks up a table reference into the list of CTEs.
382  @param tl Table reference to look up
383  @param[out] found Is set to true/false if found or not
384  @returns true if error
385  */
386  bool lookup(TABLE_LIST *tl, PT_common_table_expr **found);
387  /**
388  Call this to record in the WITH clause that we are contextualizing the
389  CTE definition inserted in table reference 'tl'.
390  @returns information which the caller must provide to
391  leave_parsing_definition().
392  */
394  auto old = m_most_inner_in_parsing;
396  return old;
397  }
400  }
401  void print(const THD *thd, String *str, enum_query_type query_type);
402 
403  private:
404  /// All CTEs of this clause
405  const PT_with_list *const m_list;
406  /// True if the user has specified the RECURSIVE keyword.
407  const bool m_recursive;
408  /**
409  The innermost CTE reference which we're parsing at the
410  moment. Used to detect forward references, loops and recursiveness.
411  */
413 
414  friend bool SELECT_LEX_UNIT::clear_corr_ctes();
415 };
416 
419 
420  public:
421  virtual bool contextualize(Parse_context *pc) {
422  if (super::contextualize(pc)) return true;
423 
424  pc->select->item_list = value;
425  return false;
426  }
427 };
428 
431 
433 
434  public:
435  PT_limit_clause(const Limit_options &limit_options_arg)
436  : limit_options(limit_options_arg) {}
437 
438  virtual bool contextualize(Parse_context *pc) {
439  if (super::contextualize(pc)) return true;
440 
441  if (pc->select->master_unit()->is_union() && !pc->select->braces) {
443  DBUG_ASSERT(pc->select != NULL);
444  }
445 
448  return true;
449 
450  if (limit_options.limit->itemize(pc, &limit_options.limit)) return true;
451 
454  return true;
455 
458  pc->select->explicit_limit = true;
459 
461  return false;
462  }
463 };
464 
465 class PT_cross_join;
466 class PT_joined_table;
467 
469  public:
471 
472  /**
473  Lets us build a parse tree top-down, which is necessary due to the
474  context-dependent nature of the join syntax. This function adds
475  the `<table_ref>` cross join as the left-most leaf in this join tree
476  rooted at this node.
477 
478  @todo: comment on non-join PT_table_reference objects
479 
480  @param cj This `<table ref>` will be added if it represents a cross join.
481 
482  @return The new top-level join.
483  */
485 };
486 
489 
492  const char *const opt_table_alias;
494 
495  public:
497  List<String> *opt_use_partition_arg,
498  const LEX_CSTRING &opt_table_alias_arg,
499  List<Index_hint> *opt_key_definition_arg)
500  : table_ident(table_ident_arg),
501  opt_use_partition(opt_use_partition_arg),
502  opt_table_alias(opt_table_alias_arg.str),
503  opt_key_definition(opt_key_definition_arg) {}
504 
505  virtual bool contextualize(Parse_context *pc) {
506  if (super::contextualize(pc)) return true;
507 
508  THD *thd = pc->thd;
509  Yacc_state *yyps = &thd->m_parser_state->m_yacc;
510 
512  thd, table_ident, opt_table_alias, 0, yyps->m_lock_type,
513  yyps->m_mdl_type, opt_key_definition, opt_use_partition, nullptr, pc);
514  if (value == NULL) return true;
515  if (pc->select->add_joined_table(value)) return true;
516  return false;
517  }
518 };
519 
521  public:
522  virtual Json_table_column *get_column() = 0;
523 };
524 
527 
528  public:
531  const LEX_STRING &table_alias)
532  : m_expr(expr),
533  m_path(path),
534  m_nested_columns(nested_cols),
535  m_table_alias(table_alias) {}
536 
537  bool contextualize(Parse_context *pc) override;
538 
539  private:
544 };
545 
548 
550 
551  public:
554  : table_list(table_list) {}
555 
556  virtual bool contextualize(Parse_context *pc) {
558  return true;
559 
560  DBUG_ASSERT(table_list.size() >= 2);
561  value = pc->select->nest_last_join(pc->thd, table_list.size());
562  return value == NULL;
563  }
564 };
565 
568 
569  public:
570  PT_derived_table(bool lateral, PT_subquery *subquery,
571  const LEX_CSTRING &table_alias,
573 
574  virtual bool contextualize(Parse_context *pc);
575 
576  private:
577  bool m_lateral;
579  const char *const m_table_alias;
580  /// List of explicitely specified column names; if empty, no list.
582 };
583 
586 
587  public:
589  : m_joined_table(joined_table) {}
590 
591  virtual bool contextualize(Parse_context *pc);
592 
593  private:
595 };
596 
599 
600  protected:
605 
608 
609  public:
610  PT_joined_table(PT_table_reference *tab1_node_arg, const POS &join_pos_arg,
612  : tab1_node(tab1_node_arg),
613  join_pos(join_pos_arg),
614  m_type(type),
615  tab2_node(tab2_node_arg),
616  tr1(NULL),
617  tr2(NULL) {
618  static_assert(is_single_bit(JTT_INNER), "not a single bit");
619  static_assert(is_single_bit(JTT_STRAIGHT), "not a single bit");
620  static_assert(is_single_bit(JTT_NATURAL), "not a single bit");
621  static_assert(is_single_bit(JTT_LEFT), "not a single bit");
622  static_assert(is_single_bit(JTT_RIGHT), "not a single bit");
623 
626  type == JTT_NATURAL_RIGHT || type == JTT_LEFT ||
627  type == JTT_RIGHT);
628  }
629 
630  /**
631  Adds the cross join to this join operation. The cross join is nested as
632  the table reference on the left-hand side.
633  */
636  return this;
637  }
638 
639  /// Adds the table reference as the right-hand side of this join.
642  tab2_node = table;
643  }
644 
646  if (super::contextualize(pc) || contextualize_tabs(pc)) return true;
647 
648  if (m_type & (JTT_LEFT | JTT_RIGHT)) {
649  if (m_type & JTT_LEFT)
651  else {
652  TABLE_LIST *inner_table = pc->select->convert_right_join();
653  if (inner_table == NULL) return true;
654  /* swap tr1 and tr2 */
655  DBUG_ASSERT(inner_table == tr1);
656  tr1 = tr2;
657  tr2 = inner_table;
658  }
659  }
660 
662 
663  if (m_type & JTT_STRAIGHT) tr2->straight = true;
664 
665  return false;
666  }
667 
668  /// This class is being inherited, it should thus be abstract.
669  ~PT_joined_table() = 0;
670 
671  protected:
673  if (tr1 != NULL) return false; // already done
674 
676  return true;
677 
678  tr1 = tab1_node->value;
679  tr2 = tab2_node->value;
680 
681  if (tr1 == NULL || tr2 == NULL) {
682  error(pc, join_pos);
683  return true;
684  }
685  return false;
686  }
687 };
688 
690 
693 
694  public:
695  PT_cross_join(PT_table_reference *tab1_node_arg, const POS &join_pos_arg,
696  PT_joined_table_type Type_arg,
697  PT_table_reference *tab2_node_arg)
698  : PT_joined_table(tab1_node_arg, join_pos_arg, Type_arg, tab2_node_arg) {}
699 
700  virtual bool contextualize(Parse_context *pc) {
701  if (super::contextualize(pc)) return true;
702  value = pc->select->nest_last_join(pc->thd);
703  return value == NULL;
704  }
705 };
706 
710 
711  public:
712  PT_joined_table_on(PT_table_reference *tab1_node_arg, const POS &join_pos_arg,
714  PT_table_reference *tab2_node_arg, Item *on_arg)
715  : super(tab1_node_arg, join_pos_arg, type, tab2_node_arg), on(on_arg) {}
716 
717  virtual bool contextualize(Parse_context *pc) {
718  if (this->contextualize_tabs(pc)) return true;
719 
720  if (push_new_name_resolution_context(pc, this->tr1, this->tr2)) {
721  this->error(pc, this->join_pos);
722  return true;
723  }
724 
725  SELECT_LEX *sel = pc->select;
726  sel->parsing_place = CTX_ON;
727 
728  if (super::contextualize(pc) || on->itemize(pc, &on)) return true;
729  if (!on->is_bool_func()) {
730  on = make_condition(pc, on);
731  if (on == nullptr) return true;
732  }
733  DBUG_ASSERT(sel == pc->select);
734 
735  add_join_on(this->tr2, on);
736  pc->thd->lex->pop_context();
738  sel->parsing_place = CTX_NONE;
739  value = pc->select->nest_last_join(pc->thd);
740  return value == NULL;
741  }
742 };
743 
747 
748  public:
750  const POS &join_pos_arg, PT_joined_table_type type,
751  PT_table_reference *tab2_node_arg,
752  List<String> *using_fields_arg)
753  : super(tab1_node_arg, join_pos_arg, type, tab2_node_arg),
754  using_fields(using_fields_arg) {}
755 
756  /// A PT_joined_table_using without a list of columns denotes a natural join.
758  const POS &join_pos_arg, PT_joined_table_type type,
759  PT_table_reference *tab2_node_arg)
760  : PT_joined_table_using(tab1_node_arg, join_pos_arg, type, tab2_node_arg,
761  NULL) {}
762 
763  virtual bool contextualize(Parse_context *pc) {
764  if (super::contextualize(pc)) return true;
765 
767  value = pc->select->nest_last_join(pc->thd);
768  if (value == NULL) return true;
770 
771  return false;
772  }
773 };
774 
775 class PT_group : public Parse_tree_node {
777 
780 
781  public:
782  PT_group(PT_order_list *group_list_arg, olap_type olap_arg)
783  : group_list(group_list_arg), olap(olap_arg) {}
784 
785  virtual bool contextualize(Parse_context *pc);
786 };
787 
788 class PT_order : public Parse_tree_node {
790 
792 
793  public:
794  explicit PT_order(PT_order_list *order_list_arg)
795  : order_list(order_list_arg) {}
796 
797  virtual bool contextualize(Parse_context *pc);
798 };
799 
801  public:
804 
805  virtual bool contextualize(Parse_context *pc) final;
806 
807  virtual bool set_lock_for_tables(Parse_context *pc) = 0;
808 
809  virtual bool is_legacy_syntax() const = 0;
810 
812 
813  protected:
815  thr_lock_type lock_type = TL_IGNORE;
816  switch (m_lock_strength) {
818  lock_type = TL_WRITE;
819  break;
821  lock_type = TL_READ_WITH_SHARED_LOCKS;
822  break;
823  }
824 
825  return {lock_type, static_cast<thr_locked_row_action>(action())};
826  }
827 
828  private:
831 };
832 
834  public:
837  : PT_locking_clause(strength, action),
838  m_is_legacy_syntax(strength == Lock_strength::UPDATE &&
840 
844 
845  bool set_lock_for_tables(Parse_context *pc) override;
846 
847  bool is_legacy_syntax() const override { return m_is_legacy_syntax; }
848 
849  private:
851 };
852 
854  public:
856 
860  : PT_locking_clause(strength, action), m_tables(tables) {}
861 
862  bool set_lock_for_tables(Parse_context *pc) override;
863 
864  bool is_legacy_syntax() const override { return false; }
865 
866  private:
867  /// @todo Move this function to Table_ident?
868  void print_table_ident(const THD *thd, const Table_ident *ident, String *s) {
869  LEX_CSTRING db = ident->db;
870  LEX_CSTRING table = ident->table;
871  if (db.length > 0) {
872  append_identifier(thd, s, db.str, db.length);
873  s->append('.');
874  }
875  append_identifier(thd, s, table.str, table.length);
876  }
877 
878  bool raise_error(THD *thd, const Table_ident *name, int error) {
879  String s;
880  print_table_ident(thd, name, &s);
881  my_error(error, MYF(0), s.ptr());
882  return true;
883  }
884 
885  bool raise_error(int error) {
886  my_error(error, MYF(0));
887  return true;
888  }
889 
891 };
892 
894  public:
897  }
898 
899  bool push_back(PT_locking_clause *locking_clause) {
900  return m_locking_clauses.push_back(locking_clause);
901  }
902 
903  bool is_legacy_syntax() const {
904  return m_locking_clauses.size() == 1 &&
905  m_locking_clauses[0]->is_legacy_syntax();
906  }
907 
909  for (auto locking_clause : m_locking_clauses)
910  if (locking_clause->contextualize(pc)) return true;
911  return false;
912  }
913 
914  private:
916 };
917 
919  public:
920  virtual bool is_union() const = 0;
922  virtual bool has_into_clause() const = 0;
923 };
924 
926  public:
928 };
929 
932 
934 
935  public:
937  : ident(ident_arg) {}
938 
939  virtual bool contextualize(Parse_context *pc);
940 };
941 
942 /**
943  Parse tree node class for 2-dimentional variable names (example: \@global.x)
944 */
947 
948  public:
949  const POS pos;
950 
951  private:
954 
955  public:
956  PT_internal_variable_name_2d(const POS &pos, const LEX_STRING &ident1_arg,
957  const LEX_STRING &ident2_arg)
958  : pos(pos), ident1(ident1_arg), ident2(ident2_arg) {}
959 
960  virtual bool contextualize(Parse_context *pc);
961 };
962 
965 
967 
968  public:
970  : ident(ident_arg) {}
971 
972  virtual bool contextualize(Parse_context *pc) {
973  if (super::contextualize(pc)) return true;
974 
975  sys_var *tmp = find_sys_var(pc->thd, ident.str, ident.length);
976  if (!tmp) return true;
977  if (!tmp->is_struct()) {
978  my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), ident.str);
979  return true;
980  }
981  value.var = tmp;
982  value.base_name.str = const_cast<char *>("default");
983  value.base_name.length = 7;
984  return false;
985  }
986 };
987 
990 
994 
995  public:
997  PT_internal_variable_name *name_arg,
998  Item *opt_expr_arg)
999  : pos(pos), name(name_arg), opt_expr(opt_expr_arg) {}
1000 
1001  virtual bool contextualize(Parse_context *pc) {
1002  if (super::contextualize(pc) || name->contextualize(pc) ||
1003  (opt_expr != NULL && opt_expr->itemize(pc, &opt_expr)))
1004  return true;
1005 
1007  /* It is a system variable. */
1008  if (set_system_variable(pc->thd, &name->value, pc->thd->lex->option_type,
1009  opt_expr))
1010  return true;
1011  } else {
1012  /*
1013  Not in trigger assigning value to new row,
1014  and option_type preceding local variable is illegal.
1015  */
1016  error(pc, pos);
1017  return true;
1018  }
1019  return false;
1020  }
1021 };
1022 
1024 
1028 
1032 
1033  public:
1035  Item *opt_expr_arg,
1036  const POS &expr_pos_arg)
1037  : name(name_arg), opt_expr(opt_expr_arg), expr_pos(expr_pos_arg) {}
1038 
1039  virtual bool contextualize(Parse_context *pc);
1040 };
1041 
1045 
1048 
1049  public:
1051  Item *expr_arg)
1052  : name(name_arg), expr(expr_arg) {}
1053 
1054  virtual bool contextualize(Parse_context *pc) {
1055  if (super::contextualize(pc) || expr->itemize(pc, &expr)) return true;
1056 
1057  THD *thd = pc->thd;
1058  Item_func_set_user_var *item;
1059  item = new (pc->mem_root) Item_func_set_user_var(name, expr, false);
1060  if (item == NULL) return true;
1061  set_var_user *var = new (thd->mem_root) set_var_user(item);
1062  if (var == NULL) return true;
1063  thd->lex->var_list.push_back(var);
1064  return false;
1065  }
1066 };
1067 
1071 
1075 
1076  public:
1078  PT_internal_variable_name *name_arg,
1079  Item *opt_expr_arg)
1080  : type(type_arg), name(name_arg), opt_expr(opt_expr_arg) {}
1081 
1082  virtual bool contextualize(Parse_context *pc) {
1083  if (super::contextualize(pc) || name->contextualize(pc) ||
1084  (opt_expr != NULL && opt_expr->itemize(pc, &opt_expr)))
1085  return true;
1086 
1087  THD *thd = pc->thd;
1088  struct sys_var_with_base tmp = name->value;
1089  if (tmp.var == trg_new_row_fake_var) {
1090  error(pc, down_cast<PT_internal_variable_name_2d *>(name)->pos);
1091  return true;
1092  }
1093  /* Lookup if necessary: must be a system variable. */
1094  if (tmp.var == NULL) {
1095  if (find_sys_var_null_base(thd, &tmp)) return true;
1096  }
1097  if (set_system_variable(thd, &tmp, type, opt_expr)) return true;
1098  return false;
1099  }
1100 };
1101 
1105 
1107 
1108  public:
1110  : opt_charset(opt_charset_arg) {}
1111 
1112  virtual bool contextualize(Parse_context *pc);
1113 };
1114 
1118 
1120 
1121  public:
1123 
1124  virtual bool contextualize(Parse_context *pc);
1125 };
1126 
1129 
1132 
1133  public:
1134  PT_set_names(const CHARSET_INFO *opt_charset_arg,
1135  const CHARSET_INFO *opt_collation_arg)
1136  : opt_charset(opt_charset_arg), opt_collation(opt_collation_arg) {}
1137 
1138  virtual bool contextualize(Parse_context *pc);
1139 };
1140 
1142 
1144  : public PT_start_option_value_list {
1146 
1147  const char *password;
1148  const char *current_password;
1151 
1152  public:
1154  const char *current_password_arg,
1155  bool retain_current,
1156  const POS &expr_pos_arg)
1157  : password(password_arg),
1158  current_password(current_password_arg),
1159  retain_current_password(retain_current),
1160  expr_pos(expr_pos_arg) {}
1161 
1162  virtual bool contextualize(Parse_context *pc);
1163 };
1164 
1166  : public PT_start_option_value_list {
1168 
1170  const char *password;
1171  const char *current_password;
1174 
1175  public:
1177  const char *password_arg,
1178  const char *current_password_arg,
1179  bool retain_current,
1180  const POS &expr_pos_arg)
1181  : user(user_arg),
1182  password(password_arg),
1183  current_password(current_password_arg),
1184  retain_current_password(retain_current),
1185  expr_pos(expr_pos_arg) {}
1186 
1187  virtual bool contextualize(Parse_context *pc);
1188 };
1189 
1192 
1195 
1196  public:
1199  : type(type_arg), value(value_arg) {}
1200 
1201  virtual bool contextualize(Parse_context *pc) {
1202  pc->thd->lex->option_type = type;
1203  return super::contextualize(pc) || value->contextualize(pc);
1204  }
1205 };
1206 
1209 
1213 
1214  public:
1215  PT_option_value_list_head(const POS &delimiter_pos_arg,
1216  Parse_tree_node *value_arg,
1217  const POS &value_pos_arg)
1218  : delimiter_pos(delimiter_pos_arg),
1219  value(value_arg),
1220  value_pos(value_pos_arg) {}
1221 
1222  virtual bool contextualize(Parse_context *pc) {
1223  if (super::contextualize(pc)) return true;
1224 
1225  THD *thd = pc->thd;
1226 #ifndef DBUG_OFF
1227  LEX *old_lex = thd->lex;
1228 #endif // DBUG_OFF
1229 
1231  DBUG_ASSERT(thd->lex->select_lex == thd->lex->current_select());
1232  Parse_context inner_pc(pc->thd, thd->lex->select_lex);
1233 
1234  if (value->contextualize(&inner_pc)) return true;
1235 
1236  if (sp_create_assignment_instr(pc->thd, value_pos.raw.end)) return true;
1237  DBUG_ASSERT(thd->lex == old_lex &&
1238  thd->lex->current_select() == pc->select);
1239 
1240  return false;
1241  }
1242 };
1243 
1246 
1248 
1249  public:
1251  const POS &delimiter_pos_arg, Parse_tree_node *tail,
1252  const POS &tail_pos)
1253  : super(delimiter_pos_arg, tail, tail_pos), head(head_arg) {}
1254 
1255  virtual bool contextualize(Parse_context *pc) {
1256  return head->contextualize(pc) || super::contextualize(pc);
1257  }
1258 };
1259 
1262 
1266 
1267  public:
1269  const POS &head_pos_arg,
1270  PT_option_value_list_head *tail_arg)
1271  : head(head_arg), head_pos(head_pos_arg), tail(tail_arg) {}
1272 
1273  virtual bool contextualize(Parse_context *pc) {
1274  if (super::contextualize(pc) || head->contextualize(pc)) return true;
1275 
1276  if (sp_create_assignment_instr(pc->thd, head_pos.raw.end)) return true;
1277  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1278  pc->select = pc->thd->lex->select_lex;
1279 
1280  if (tail != NULL && tail->contextualize(pc)) return true;
1281 
1282  return false;
1283  }
1284 };
1285 
1288 
1289  const char *name;
1291 
1292  public:
1293  PT_transaction_characteristic(const char *name_arg, int32 value_arg)
1294  : name(name_arg), value(value_arg) {}
1295 
1296  virtual bool contextualize(Parse_context *pc) {
1297  if (super::contextualize(pc)) return true;
1298 
1299  THD *thd = pc->thd;
1300  LEX *lex = thd->lex;
1301  Item *item = new (pc->mem_root) Item_int(value);
1302  if (item == NULL) return true;
1303  set_var *var = new (thd->mem_root)
1304  set_var(lex->option_type, find_sys_var(thd, name), &null_lex_str, item);
1305  if (var == NULL) return true;
1306  lex->var_list.push_back(var);
1307  return false;
1308  }
1309 };
1310 
1313 
1314  public:
1315  explicit PT_transaction_access_mode(bool is_read_only)
1316  : super("transaction_read_only", (int32)is_read_only) {}
1317 };
1318 
1321 
1322  public:
1324  : super("transaction_isolation", (int32)level) {}
1325 };
1326 
1329 
1332 
1333  public:
1335  PT_transaction_characteristic *opt_tail_arg)
1336  : head(head_arg), opt_tail(opt_tail_arg) {}
1337 
1338  virtual bool contextualize(Parse_context *pc) {
1339  return (super::contextualize(pc) || head->contextualize(pc) ||
1340  (opt_tail != NULL && opt_tail->contextualize(pc)));
1341  }
1342 };
1343 
1345  : public PT_start_option_value_list {
1347 
1350 
1351  public:
1353  PT_transaction_characteristics *characteristics_arg,
1354  const POS &end_pos_arg)
1355  : characteristics(characteristics_arg), end_pos(end_pos_arg) {}
1356 
1357  virtual bool contextualize(Parse_context *pc) {
1358  if (super::contextualize(pc)) return true;
1359 
1360  THD *thd = pc->thd;
1361  thd->lex->option_type = OPT_DEFAULT;
1362  if (characteristics->contextualize(pc)) return true;
1363 
1364  if (sp_create_assignment_instr(thd, end_pos.raw.end)) return true;
1365  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1366  pc->select = pc->thd->lex->select_lex;
1367 
1368  return false;
1369  }
1370 };
1371 
1373  : public Parse_tree_node {};
1374 
1378 
1382 
1383  public:
1385  PT_option_value_following_option_type *head_arg, const POS &head_pos_arg,
1386  PT_option_value_list_head *opt_tail_arg)
1387  : head(head_arg), head_pos(head_pos_arg), opt_tail(opt_tail_arg) {}
1388 
1389  virtual bool contextualize(Parse_context *pc) {
1390  if (super::contextualize(pc) || head->contextualize(pc)) return true;
1391 
1392  if (sp_create_assignment_instr(pc->thd, head_pos.raw.end)) return true;
1393  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1394  pc->select = pc->thd->lex->select_lex;
1395 
1396  if (opt_tail != NULL && opt_tail->contextualize(pc)) return true;
1397 
1398  return false;
1399  }
1400 };
1401 
1405 
1408 
1409  public:
1411  PT_transaction_characteristics *characteristics_arg,
1412  const POS &characteristics_pos_arg)
1413  : characteristics(characteristics_arg),
1414  characteristics_pos(characteristics_pos_arg) {}
1415 
1416  virtual bool contextualize(Parse_context *pc) {
1418  return true;
1419 
1421  return true;
1422  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1423  pc->select = pc->thd->lex->select_lex;
1424 
1425  return false;
1426  }
1427 };
1428 
1431 
1434 
1435  public:
1437  enum_var_type type_arg,
1439  : type(type_arg), list(list_arg) {}
1440 
1441  virtual bool contextualize(Parse_context *pc) {
1442  pc->thd->lex->option_type = type;
1443  return super::contextualize(pc) || list->contextualize(pc);
1444  }
1445 };
1446 
1447 class PT_set : public Parse_tree_node {
1449 
1452 
1453  public:
1454  PT_set(const POS &set_pos_arg, PT_start_option_value_list *list_arg)
1455  : set_pos(set_pos_arg), list(list_arg) {}
1456 
1457  virtual bool contextualize(Parse_context *pc) {
1458  if (super::contextualize(pc)) return true;
1459 
1460  THD *thd = pc->thd;
1461  LEX *lex = thd->lex;
1463  lex->option_type = OPT_SESSION;
1464  lex->var_list.empty();
1465  lex->autocommit = false;
1466 
1468  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1469  pc->select = pc->thd->lex->select_lex;
1470 
1471  return list->contextualize(pc);
1472  }
1473 };
1474 
1478 
1479  protected:
1481 
1482  public:
1483  virtual bool contextualize(Parse_context *pc) {
1484  if (super::contextualize(pc)) return true;
1485 
1486  LEX *lex = pc->thd->lex;
1488  if (lex->sql_command == SQLCOM_SHOW_CREATE ||
1490  my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "INTO");
1491  else
1492  error(pc, m_pos);
1493  return true;
1494  }
1495  return false;
1496  }
1497 };
1498 
1501 
1502  public:
1503  PT_into_destination_outfile(const POS &pos, const LEX_STRING &file_name_arg,
1504  const CHARSET_INFO *charset_arg,
1505  const Field_separators &field_term_arg,
1506  const Line_separators &line_term_arg)
1507  : PT_into_destination(pos), m_exchange(file_name_arg.str, false) {
1508  m_exchange.cs = charset_arg;
1509  m_exchange.field.merge_field_separators(field_term_arg);
1510  m_exchange.line.merge_line_separators(line_term_arg);
1511  }
1512 
1513  bool contextualize(Parse_context *pc) override {
1514  if (super::contextualize(pc)) return true;
1515 
1516  LEX *lex = pc->thd->lex;
1518  if (!(lex->result =
1520  return true;
1521 
1522  return false;
1523  }
1524 
1525  private:
1527 };
1528 
1531 
1532  public:
1533  PT_into_destination_dumpfile(const POS &pos, const LEX_STRING &file_name_arg)
1534  : PT_into_destination(pos), m_exchange(file_name_arg.str, true) {}
1535 
1536  bool contextualize(Parse_context *pc) override {
1537  if (super::contextualize(pc)) return true;
1538 
1539  LEX *lex = pc->thd->lex;
1540  if (!lex->is_explain()) {
1542  if (!(lex->result =
1543  new (pc->thd->mem_root) Query_result_dump(&m_exchange)))
1544  return true;
1545  }
1546  return false;
1547  }
1548 
1549  private:
1551 };
1552 
1554  public:
1556 
1557  explicit PT_select_var(const LEX_STRING &name_arg) : name(name_arg) {}
1558 
1559  virtual bool is_local() const { return false; }
1560  virtual uint get_offset() const {
1561  DBUG_ASSERT(0);
1562  return 0;
1563  }
1564 };
1565 
1568 
1570 
1571 #ifndef DBUG_OFF
1572  /*
1573  Routine to which this Item_splocal belongs. Used for checking if correct
1574  runtime context is used for variable handling.
1575  */
1577 #endif
1578 
1579  public:
1580  PT_select_sp_var(const LEX_STRING &name_arg) : super(name_arg) {}
1581 
1582  virtual bool is_local() const { return true; }
1583  virtual uint get_offset() const { return offset; }
1584 
1585  virtual bool contextualize(Parse_context *pc);
1586 };
1587 
1590 
1591  public:
1593 
1595 
1596  virtual bool contextualize(Parse_context *pc) {
1597  if (super::contextualize(pc)) return true;
1598 
1600  PT_select_var *var;
1601  while ((var = it++)) {
1602  if (var->contextualize(pc)) return true;
1603  }
1604 
1605  LEX *const lex = pc->thd->lex;
1606  if (lex->is_explain()) return false;
1607 
1608  Query_dumpvar *dumpvar = new (pc->mem_root) Query_dumpvar();
1609  if (dumpvar == NULL) return true;
1610 
1611  dumpvar->var_list = value;
1612  lex->result = dumpvar;
1614 
1615  return false;
1616  }
1617 
1618  bool push_back(PT_select_var *var) { return value.push_back(var); }
1619 };
1620 
1621 /**
1622  Parse tree node for a single of a window extent's borders,
1623  cf. <window frame extent> in SQL 2003.
1624 */
1625 class PT_border : public Parse_tree_node {
1626  friend class Window;
1627  Item *m_value{nullptr}; ///< only relevant iff m_border_type == WBT_VALUE_*
1628  public:
1630  const bool m_date_time;
1632 
1633  ///< For unbounded border
1637  }
1638 
1639  ///< For bounded non-temporal border, e.g. 2 PRECEDING: 'value' is 2.
1642 
1643  ///< For bounded INTERVAL 2 DAYS, 'value' is 2, int_type is DAYS.
1645  : m_value(value),
1647  m_date_time(true),
1648  m_int_type(int_type) {}
1649 
1650  ///< @returns the '2' in '2 PRECEDING' or 'INTERVAL 2 DAYS PRECEDING'
1651  Item *border() const { return m_value; }
1652  /// Need such low-level access so that fix_fields updates the right pointer
1653  Item **border_ptr() { return &m_value; }
1654 
1655  /**
1656  @returns Addition operator for computation of frames, nullptr if error.
1657  @param order_expr Expression to add/substract to
1658  @param prec true if PRECEDING
1659  @param asc true if ASC
1660  @param window only used for error generation
1661  */
1662  Item *build_addop(Item_cache *order_expr, bool prec, bool asc,
1663  const Window *window);
1664 };
1665 
1666 /**
1667  Parse tree node for one or both of a window extent's borders, cf.
1668  <window frame extent> in SQL 2003.
1669 */
1670 class PT_borders : public Parse_tree_node {
1672  friend class PT_frame;
1673 
1674  public:
1675  /**
1676  Constructor.
1677 
1678  Frames of the form "frame_start no_frame_end" are translated during
1679  parsing to "BETWEEN frame_start AND CURRENT ROW". So both 'start' and
1680  'end' are non-nullptr.
1681  */
1683  m_borders[0] = start;
1684  m_borders[1] = end;
1685  }
1686 };
1687 
1688 /**
1689  Parse tree node for a window frame's exclusions, cf. the
1690  <window frame exclusion> clause in SQL 2003.
1691 */
1694 
1695  public:
1697  // enum_window_frame_exclusion exclusion() { return m_exclusion; }
1698 };
1699 
1700 /**
1701  Parse tree node for a window's frame, cf. the <window frame clause>
1702  in SQL 2003.
1703 */
1704 class PT_frame : public Parse_tree_node {
1705  public:
1707 
1710 
1712 
1713  /// If true, this is an artificial frame, not specified by the user
1714  bool m_originally_absent = false;
1715 
1717  PT_exclusion *exclusion)
1718  : m_unit(unit),
1719  m_from(from_to->m_borders[0]),
1720  m_to(from_to->m_borders[1]),
1721  m_exclusion(exclusion) {}
1722 };
1723 
1724 /**
1725  Parse tree node for a window; just a shallow wrapper for
1726  class Window, q.v.
1727 */
1728 class PT_window : public Parse_tree_node, public Window {
1730 
1731  public:
1733  PT_frame *frame)
1734  : Window(partition_by, order_by, frame) {}
1735 
1737  PT_frame *frame, Item_string *inherit)
1738  : Window(partition_by, order_by, frame, inherit) {}
1739 
1741 
1742  virtual bool contextualize(Parse_context *pc);
1743 };
1744 
1745 /**
1746  Parse tree node for a list of window definitions corresponding
1747  to a <window clause> in SQL 2003.
1748 */
1752 
1753  public:
1755 
1756  virtual bool contextualize(Parse_context *pc);
1757 
1758  bool push_back(PT_window *w) { return m_windows.push_back(w); }
1759 };
1760 
1762  public:
1763  virtual bool has_into_clause() const = 0;
1764  virtual bool is_union() const = 0;
1765 };
1766 
1769 
1779 
1780  public:
1782  PT_hint_list *opt_hints_arg, const Query_options &options_arg,
1783  PT_item_list *item_list_arg, PT_into_destination *opt_into1_arg,
1784  const Mem_root_array_YY<PT_table_reference *> &from_clause_arg,
1785  Item *opt_where_clause_arg, PT_group *opt_group_clause_arg,
1786  Item *opt_having_clause_arg, PT_window_list *opt_window_clause_arg)
1787  : opt_hints(opt_hints_arg),
1788  options(options_arg),
1789  item_list(item_list_arg),
1790  opt_into1(opt_into1_arg),
1791  from_clause(from_clause_arg),
1792  opt_where_clause(opt_where_clause_arg),
1793  opt_group_clause(opt_group_clause_arg),
1794  opt_having_clause(opt_having_clause_arg),
1795  opt_window_clause(opt_window_clause_arg) {}
1796 
1798  const Query_options &options_arg, PT_item_list *item_list_arg,
1799  const Mem_root_array_YY<PT_table_reference *> &from_clause_arg,
1800  Item *opt_where_clause_arg)
1801  : opt_hints(NULL),
1802  options(options_arg),
1803  item_list(item_list_arg),
1804  opt_into1(NULL),
1805  from_clause(from_clause_arg),
1806  opt_where_clause(opt_where_clause_arg),
1810 
1811  explicit PT_query_specification(const Query_options &options_arg,
1812  PT_item_list *item_list_arg)
1813  : opt_hints(NULL),
1814  options(options_arg),
1815  item_list(item_list_arg),
1816  opt_into1(NULL),
1822  }
1823 
1824  virtual bool contextualize(Parse_context *pc);
1825 
1826  virtual bool has_into_clause() const { return opt_into1 != NULL; }
1827 
1828  virtual bool is_union() const { return false; }
1829 };
1830 
1832  public:
1835  PT_limit_clause *limit,
1836  PT_locking_clause_list *locking_clauses)
1837  : contextualized(false),
1838  m_body(body),
1839  m_order(order),
1840  m_limit(limit),
1841  m_locking_clauses(locking_clauses),
1843  m_with_clause(with_clause) {}
1844 
1846  PT_limit_clause *limit,
1847  PT_locking_clause_list *locking_clauses)
1848  : PT_query_expression(nullptr, body, order, limit, locking_clauses) {}
1849 
1852 
1853  virtual bool contextualize(Parse_context *pc) {
1855  return true; /* purecov: inspected */
1856 
1858  m_body->set_containing_qe(this);
1859 
1861  return true;
1862 
1863  if (!contextualized && contextualize_order_and_limit(pc)) return true;
1864 
1865  if (contextualize_safe(pc, m_locking_clauses)) return true;
1866 
1867  return false;
1868  }
1869 
1871 
1872  bool has_order() const { return m_order != NULL; }
1873 
1874  bool has_limit() const { return m_limit != NULL; }
1875 
1876  bool is_union() const { return m_body->is_union(); }
1877 
1878  bool has_into_clause() const { return m_body->has_into_clause(); }
1879 
1880  /**
1881  Callback for deeper nested query expressions. It's mandatory for any
1882  derived class to call this member function during contextualize.
1883  */
1885  contextualized = true;
1886 
1887  /*
1888  We temporarily switch off 'braces' for contextualization of the limit
1889  and order clauses if this query expression is a
1890  union. PT_order::contextualize() and PT_limit_clause::contextualize()
1891  are still used by legacy code where 'braces' is used to communicate
1892  nesting information. It's not possible to express the difference between
1893 
1894  (SELECT ... UNION SELECT ...) ORDER BY ... LIMIT ...
1895 
1896  and
1897 
1898  SELECT ... UNION (SELECT ... ORDER BY ... LIMIT ...)
1899 
1900  in the SELECT_LEX structure. In other words, this structure does not
1901  know the difference between a surrounding union and a local
1902  union. Fortunately, the information is implicit in the parse tree
1903  structure: is_union() is true if this query expression is a union, but
1904  not true if it's nested within a union.
1905  */
1906  bool braces = pc->select->braces;
1907  if (is_union()) pc->select->braces = false;
1908  pc->thd->where = "global ORDER clause";
1909  bool res =
1911  pc->select->braces = braces;
1912  if (res) return true;
1913 
1914  pc->thd->where = THD::DEFAULT_WHERE;
1915  return false;
1916  }
1917 
1918  void set_parentheses() { m_parentheses = true; }
1919 
1920  bool has_parentheses() { return m_parentheses; }
1921 
1922  void remove_parentheses() { m_parentheses = false; }
1923 
1924  /**
1925  Called by the parser when it has decided that this query expression may
1926  not contain order or limit clauses because it is part of a union. For
1927  historical reasons, these clauses are not allowed in non-last branches of
1928  union expressions.
1929  */
1930  void ban_order_and_limit() const {
1931  if (m_order != NULL) my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY");
1932  if (m_limit != NULL) my_error(ER_WRONG_USAGE, MYF(0), "UNION", "LIMIT");
1933  }
1934 
1935  private:
1943 };
1944 
1947 
1951 
1952  public:
1954 
1955  PT_subquery(POS p, PT_query_expression *query_expression)
1956  : qe(query_expression),
1957  pos(p),
1958  select_lex(NULL),
1960 
1961  virtual bool contextualize(Parse_context *pc) {
1962  if (super::contextualize(pc)) return true;
1963 
1964  LEX *lex = pc->thd->lex;
1965  if (!lex->expr_allows_subselect || lex->sql_command == (int)SQLCOM_PURGE) {
1966  error(pc, pos);
1967  return true;
1968  }
1969 
1970  // Create a SELECT_LEX_UNIT and SELECT_LEX for the subquery's query
1971  // expression.
1972  SELECT_LEX *child = lex->new_query(pc->select);
1973  if (child == NULL) return true;
1974 
1975  Parse_context inner_pc(pc->thd, child);
1976 
1978 
1979  if (qe->contextualize(&inner_pc)) return true;
1980 
1981  select_lex = inner_pc.select->master_unit()->first_select();
1982 
1983  lex->pop_context();
1984  pc->select->n_child_sum_items += child->n_sum_items;
1985 
1986  /*
1987  A subquery (and all the subsequent query blocks in a UNION) can add
1988  columns to an outer query block. Reserve space for them.
1989  */
1990  for (SELECT_LEX *temp = child; temp != nullptr;
1991  temp = temp->next_select()) {
1992  pc->select->select_n_where_fields += temp->select_n_where_fields;
1993  pc->select->select_n_having_items += temp->select_n_having_items;
1994  }
1995 
1996  return false;
1997  }
1998 
2000 
2001  bool is_union() { return qe->is_union(); }
2002 
2003  SELECT_LEX *value() { return select_lex; }
2004 };
2005 
2007  public:
2009  : m_query_primary(query_primary) {}
2010 
2011  virtual bool contextualize(Parse_context *pc) {
2014  return true;
2015  return false;
2016  }
2017 
2018  virtual bool is_union() const { return m_query_primary->is_union(); }
2019 
2020  virtual bool has_into_clause() const {
2021  return m_query_primary->has_into_clause();
2022  }
2023 
2024  private:
2026 };
2027 
2029  public:
2030  PT_union(PT_query_expression *lhs, const POS &lhs_pos, bool is_distinct,
2031  PT_query_primary *rhs)
2032  : m_lhs(lhs),
2033  m_lhs_pos(lhs_pos),
2034  m_is_distinct(is_distinct),
2035  m_rhs(rhs),
2036  m_containing_qe(NULL) {}
2037 
2039  m_containing_qe = qe;
2040  }
2041 
2042  virtual bool contextualize(Parse_context *pc);
2043 
2044  virtual bool is_union() const { return true; }
2045 
2046  virtual bool has_into_clause() const {
2047  return m_lhs->has_into_clause() || m_rhs->has_into_clause();
2048  }
2049 
2050  private:
2057 };
2058 
2061 
2062  public:
2064 
2065  virtual bool contextualize(Parse_context *pc) {
2066  if (super::contextualize(pc)) return true;
2067 
2068  pc->select->set_braces(true);
2069  bool result = m_qe->contextualize(pc);
2070 
2071  return result;
2072  }
2073 
2074  bool is_union() const { return m_qe->is_union(); }
2075 
2076  bool has_into_clause() const { return m_qe->has_into_clause(); }
2077 
2078  private:
2080 };
2081 
2084 
2085  public:
2086  /**
2087  @param qe The query expression.
2088  @param sql_command The type of SQL command.
2089  */
2091  : m_sql_command(sql_command), m_qe(qe), m_into(NULL) {}
2092 
2093  /**
2094  Creates a SELECT command. Only SELECT commands can have into.
2095 
2096  @param qe The query expression.
2097  @param into The trailing INTO destination.
2098  */
2100  : m_sql_command(SQLCOM_SELECT), m_qe(qe), m_into(into) {}
2101 
2103 
2104  Sql_cmd *make_cmd(THD *thd) override;
2105 
2106  private:
2110 };
2111 
2112 /**
2113  Top-level node for the DELETE statement
2114 
2115  @ingroup ptn_stmt
2116 */
2118  private:
2123  const char *const opt_table_alias;
2131 
2132  public:
2133  // single-table DELETE node constructor:
2134  PT_delete(PT_with_clause *with_clause_arg, PT_hint_list *opt_hints_arg,
2135  int opt_delete_options_arg, Table_ident *table_ident_arg,
2136  const LEX_CSTRING &opt_table_alias_arg,
2137  List<String> *opt_use_partition_arg, Item *opt_where_clause_arg,
2138  PT_order *opt_order_clause_arg, Item *opt_delete_limit_clause_arg)
2139  : m_with_clause(with_clause_arg),
2140  opt_hints(opt_hints_arg),
2141  opt_delete_options(opt_delete_options_arg),
2142  table_ident(table_ident_arg),
2143  opt_table_alias(opt_table_alias_arg.str),
2144  opt_use_partition(opt_use_partition_arg),
2145  opt_where_clause(opt_where_clause_arg),
2146  opt_order_clause(opt_order_clause_arg),
2147  opt_delete_limit_clause(opt_delete_limit_clause_arg) {
2150  }
2151 
2152  // multi-table DELETE node constructor:
2153  PT_delete(PT_with_clause *with_clause_arg, PT_hint_list *opt_hints_arg,
2154  int opt_delete_options_arg,
2155  const Mem_root_array_YY<Table_ident *> &table_list_arg,
2156  const Mem_root_array_YY<PT_table_reference *> &join_table_list_arg,
2157  Item *opt_where_clause_arg)
2158  : m_with_clause(with_clause_arg),
2159  opt_hints(opt_hints_arg),
2160  opt_delete_options(opt_delete_options_arg),
2161  table_ident(NULL),
2162  opt_table_alias(nullptr),
2163  table_list(table_list_arg),
2165  join_table_list(join_table_list_arg),
2166  opt_where_clause(opt_where_clause_arg),
2169 
2170  Sql_cmd *make_cmd(THD *thd) override;
2171 
2172  private:
2173  bool is_multitable() const {
2174  DBUG_ASSERT((table_ident != NULL) ^ (table_list.size() > 0));
2175  return table_ident == NULL;
2176  }
2177 
2178  bool add_table(Parse_context *pc, Table_ident *table);
2179 };
2180 
2181 /**
2182  Top-level node for the UPDATE statement
2183 
2184  @ingroup ptn_stmt
2185 */
2186 class PT_update : public Parse_tree_root {
2197 
2198  public:
2199  PT_update(PT_with_clause *with_clause_arg, PT_hint_list *opt_hints_arg,
2200  thr_lock_type opt_low_priority_arg, bool opt_ignore_arg,
2201  const Mem_root_array_YY<PT_table_reference *> &join_table_list_arg,
2202  PT_item_list *column_list_arg, PT_item_list *value_list_arg,
2203  Item *opt_where_clause_arg, PT_order *opt_order_clause_arg,
2204  Item *opt_limit_clause_arg)
2205  : m_with_clause(with_clause_arg),
2206  opt_hints(opt_hints_arg),
2207  opt_low_priority(opt_low_priority_arg),
2208  opt_ignore(opt_ignore_arg),
2209  join_table_list(join_table_list_arg),
2210  column_list(column_list_arg),
2211  value_list(value_list_arg),
2212  opt_where_clause(opt_where_clause_arg),
2213  opt_order_clause(opt_order_clause_arg),
2214  opt_limit_clause(opt_limit_clause_arg) {}
2215 
2216  Sql_cmd *make_cmd(THD *thd) override;
2217 };
2218 
2221 
2223 
2224  public:
2225  virtual bool contextualize(Parse_context *pc);
2226 
2227  bool push_back(List<Item> *x) { return many_values.push_back(x); }
2228 
2231  return many_values;
2232  }
2233 };
2234 
2235 /**
2236  Top-level node for the INSERT statement
2237 
2238  @ingroup ptn_stmt
2239 */
2241  const bool is_replace;
2244  const bool ignore;
2252 
2253  public:
2254  PT_insert(bool is_replace_arg, PT_hint_list *opt_hints_arg,
2255  thr_lock_type lock_option_arg, bool ignore_arg,
2256  Table_ident *table_ident_arg, List<String> *opt_use_partition_arg,
2257  PT_item_list *column_list_arg,
2258  PT_insert_values_list *row_value_list_arg,
2259  PT_query_expression *insert_query_expression_arg,
2260  PT_item_list *opt_on_duplicate_column_list_arg,
2261  PT_item_list *opt_on_duplicate_value_list_arg)
2262  : is_replace(is_replace_arg),
2263  opt_hints(opt_hints_arg),
2264  lock_option(lock_option_arg),
2265  ignore(ignore_arg),
2266  table_ident(table_ident_arg),
2267  opt_use_partition(opt_use_partition_arg),
2268  column_list(column_list_arg),
2269  row_value_list(row_value_list_arg),
2270  insert_query_expression(insert_query_expression_arg),
2271  opt_on_duplicate_column_list(opt_on_duplicate_column_list_arg),
2272  opt_on_duplicate_value_list(opt_on_duplicate_value_list_arg) {
2273  // REPLACE statement can't have IGNORE flag:
2275  // REPLACE statement can't have ON DUPLICATE KEY UPDATE clause:
2277  // INSERT/REPLACE ... SELECT can't have VALUES clause:
2279  // ON DUPLICATE KEY UPDATE: column and value arrays must have same sizes:
2284  }
2285 
2286  virtual Sql_cmd *make_cmd(THD *thd);
2287 
2288  private:
2289  bool has_select() const { return insert_query_expression != NULL; }
2290 };
2291 
2295 
2296  public:
2297  PT_call(sp_name *proc_name_arg, PT_item_list *opt_expr_list_arg)
2298  : proc_name(proc_name_arg), opt_expr_list(opt_expr_list_arg) {}
2299 
2300  Sql_cmd *make_cmd(THD *thd) override;
2301 };
2302 
2303 /**
2304  Top-level node for the SHUTDOWN statement
2305 
2306  @ingroup ptn_stmt
2307 */
2310 
2311  public:
2312  Sql_cmd *make_cmd(THD *) override { return &sql_cmd; }
2313 };
2314 
2315 /**
2316  Top-level node for the CREATE [OR REPLACE] SPATIAL REFERENCE SYSTEM statement.
2317 
2318  @ingroup ptn_stmt
2319 */
2321  /// The SQL command object.
2323  /// Whether OR REPLACE is specified.
2325  /// Whether IF NOT EXISTS is specified.
2327  /// SRID of the SRS to create.
2328  ///
2329  /// The range is larger than that of gis::srid_t, so it must be
2330  /// verified to be less than the uint32 maximum value.
2331  unsigned long long m_srid;
2332  /// All attributes except SRID.
2334 
2335  /// Check if a UTF-8 string contains control characters.
2336  ///
2337  /// @note This function only checks single byte control characters (U+0000 to
2338  /// U+001F, and U+007F). There are some control characters at U+0080 to U+00A0
2339  /// that are not detected by this function.
2340  ///
2341  /// @param str The string.
2342  /// @param length Length of the string.
2343  ///
2344  /// @retval false The string contains no control characters.
2345  /// @retval true The string contains at least one control character.
2346  bool contains_control_char(char *str, size_t length) {
2347  for (size_t pos = 0; pos < length; pos++) {
2348  if (std::iscntrl(str[pos])) return true;
2349  }
2350  return false;
2351  }
2352 
2353  public:
2354  PT_create_srs(unsigned long long srid,
2355  const Sql_cmd_srs_attributes &attributes, bool or_replace,
2356  bool if_not_exists)
2357  : m_or_replace(or_replace),
2358  m_if_not_exists(if_not_exists),
2359  m_srid(srid),
2360  m_attributes(attributes) {}
2361 
2362  Sql_cmd *make_cmd(THD *thd) override {
2363  // Note: This function hard-codes the maximum length of various
2364  // strings. These lengths must match those in
2365  // sql/dd/impl/tables/spatial_reference_systems.cc.
2366 
2368 
2369  if (m_srid > std::numeric_limits<gis::srid_t>::max()) {
2370  my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "SRID",
2371  m_or_replace ? "CREATE OR REPLACE SPATIAL REFERENCE SYSTEM"
2372  : "CREATE SPATIAL REFERENCE SYSTEM");
2373  return nullptr;
2374  }
2375  if (m_srid == 0) {
2376  my_error(ER_CANT_MODIFY_SRID_0, MYF(0));
2377  return nullptr;
2378  }
2379 
2380  if (m_attributes.srs_name.str == nullptr) {
2381  my_error(ER_SRS_MISSING_MANDATORY_ATTRIBUTE, MYF(0), "NAME");
2382  return nullptr;
2383  }
2384  MYSQL_LEX_STRING srs_name_utf8 = {nullptr, 0};
2385  if (thd->convert_string(&srs_name_utf8, &my_charset_utf8_bin,
2387  m_attributes.srs_name.length, thd->charset())) {
2388  /* purecov: begin inspected */
2389  my_error(ER_OOM, MYF(0));
2390  return nullptr;
2391  /* purecov: end */
2392  }
2393  if (srs_name_utf8.length == 0 || std::isspace(srs_name_utf8.str[0]) ||
2394  std::isspace(srs_name_utf8.str[srs_name_utf8.length - 1])) {
2395  my_error(ER_SRS_NAME_CANT_BE_EMPTY_OR_WHITESPACE, MYF(0));
2396  return nullptr;
2397  }
2398  if (contains_control_char(srs_name_utf8.str, srs_name_utf8.length)) {
2399  my_error(ER_SRS_INVALID_CHARACTER_IN_ATTRIBUTE, MYF(0), "NAME");
2400  return nullptr;
2401  }
2402  String srs_name_str(srs_name_utf8.str, srs_name_utf8.length,
2404  if (srs_name_str.numchars() > 80) {
2405  my_error(ER_SRS_ATTRIBUTE_STRING_TOO_LONG, MYF(0), "NAME", 80);
2406  return nullptr;
2407  }
2408 
2409  if (m_attributes.definition.str == nullptr) {
2410  my_error(ER_SRS_MISSING_MANDATORY_ATTRIBUTE, MYF(0), "DEFINITION");
2411  return nullptr;
2412  }
2413  MYSQL_LEX_STRING definition_utf8 = {nullptr, 0};
2414  if (thd->convert_string(&definition_utf8, &my_charset_utf8_bin,
2417  /* purecov: begin inspected */
2418  my_error(ER_OOM, MYF(0));
2419  return nullptr;
2420  /* purecov: end */
2421  }
2422  String definition_str(definition_utf8.str, definition_utf8.length,
2424  if (contains_control_char(definition_utf8.str, definition_utf8.length)) {
2425  my_error(ER_SRS_INVALID_CHARACTER_IN_ATTRIBUTE, MYF(0), "DEFINITION");
2426  return nullptr;
2427  }
2428  if (definition_str.numchars() > 4096) {
2429  my_error(ER_SRS_ATTRIBUTE_STRING_TOO_LONG, MYF(0), "DEFINITION", 4096);
2430  return nullptr;
2431  }
2432 
2433  MYSQL_LEX_STRING organization_utf8 = {nullptr, 0};
2434  if (m_attributes.organization.str != nullptr) {
2435  if (thd->convert_string(&organization_utf8, &my_charset_utf8_bin,
2438  thd->charset())) {
2439  /* purecov: begin inspected */
2440  my_error(ER_OOM, MYF(0));
2441  return nullptr;
2442  /* purecov: end */
2443  }
2444  if (organization_utf8.length == 0 ||
2445  std::isspace(organization_utf8.str[0]) ||
2446  std::isspace(organization_utf8.str[organization_utf8.length - 1])) {
2447  my_error(ER_SRS_ORGANIZATION_CANT_BE_EMPTY_OR_WHITESPACE, MYF(0));
2448  return nullptr;
2449  }
2450  String organization_str(organization_utf8.str, organization_utf8.length,
2452  if (contains_control_char(organization_utf8.str,
2453  organization_utf8.length)) {
2454  my_error(ER_SRS_INVALID_CHARACTER_IN_ATTRIBUTE, MYF(0), "ORGANIZATION");
2455  return nullptr;
2456  }
2457  if (organization_str.numchars() > 256) {
2458  my_error(ER_SRS_ATTRIBUTE_STRING_TOO_LONG, MYF(0), "ORGANIZATION", 256);
2459  return nullptr;
2460  }
2461 
2463  std::numeric_limits<gis::srid_t>::max()) {
2464  my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "IDENTIFIED BY",
2465  m_or_replace ? "CREATE OR REPLACE SPATIAL REFERENCE SYSTEM"
2466  : "CREATE SPATIAL REFERENCE SYSTEM");
2467  return nullptr;
2468  }
2469  }
2470 
2471  MYSQL_LEX_STRING description_utf8 = {nullptr, 0};
2472  if (m_attributes.description.str != nullptr) {
2473  if (thd->convert_string(&description_utf8, &my_charset_utf8_bin,
2476  thd->charset())) {
2477  /* purecov: begin inspected */
2478  my_error(ER_OOM, MYF(0));
2479  return nullptr;
2480  /* purecov: end */
2481  }
2482  String description_str(description_utf8.str, description_utf8.length,
2484  if (contains_control_char(description_utf8.str,
2485  description_utf8.length)) {
2486  my_error(ER_SRS_INVALID_CHARACTER_IN_ATTRIBUTE, MYF(0), "DESCRIPTION");
2487  return nullptr;
2488  }
2489  if (description_str.numchars() > 2048) {
2490  my_error(ER_SRS_ATTRIBUTE_STRING_TOO_LONG, MYF(0), "DESCRIPTION", 2048);
2491  return nullptr;
2492  }
2493  }
2494 
2495  sql_cmd.init(m_or_replace, m_if_not_exists, m_srid, srs_name_utf8,
2496  definition_utf8, organization_utf8,
2497  m_attributes.organization_coordsys_id, description_utf8);
2498  return &sql_cmd;
2499  }
2500 };
2501 
2502 /**
2503  Top-level node for the DROP SPATIAL REFERENCE SYSTEM statement.
2504 
2505  @ingroup ptn_stmt
2506 */
2508  /// The SQL command object.
2510  /// SRID of the SRS to drop.
2511  ///
2512  /// The range is larger than that of gis::srid_t, so it must be
2513  /// verified to be less than the uint32 maximum value.
2514  unsigned long long m_srid;
2515 
2516  public:
2517  PT_drop_srs(unsigned long long srid, bool if_exists)
2518  : sql_cmd(srid, if_exists), m_srid(srid) {}
2519 
2520  Sql_cmd *make_cmd(THD *thd) override {
2522 
2523  if (m_srid > std::numeric_limits<gis::srid_t>::max()) {
2524  my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "SRID",
2525  "DROP SPATIAL REFERENCE SYSTEM");
2526  return nullptr;
2527  }
2528  if (m_srid == 0) {
2529  my_error(ER_CANT_MODIFY_SRID_0, MYF(0));
2530  return nullptr;
2531  }
2532 
2533  return &sql_cmd;
2534  }
2535 };
2536 
2537 /**
2538  Top-level node for the ALTER INSTANCE statement
2539 
2540  @ingroup ptn_stmt
2541 */
2544 
2545  public:
2547  enum alter_instance_action_enum alter_instance_action)
2548  : sql_cmd(alter_instance_action) {}
2549 
2550  Sql_cmd *make_cmd(THD *thd) override {
2551  thd->lex->no_write_to_binlog = false;
2552  return &sql_cmd;
2553  }
2554 };
2555 
2556 /**
2557  A template-free base class for index options that we can predeclare in
2558  sql_lex.h
2559 */
2561 
2562 /**
2563  A key part specification.
2564 
2565  This can either be a "normal" key part (a key part that points to a column),
2566  or this can be a functional key part (a key part that points to an
2567  expression).
2568 */
2571 
2572  public:
2573  /**
2574  Constructor for a functional key part.
2575 
2576  @param expression The expression to index.
2577  @param order The direction of the index.
2578  */
2579  PT_key_part_specification(Item *expression, enum_order order);
2580 
2581  /**
2582  Constructor for a "normal" key part. That is a key part that points to a
2583  column and not an expression.
2584 
2585  @param column_name The column name that this key part points to.
2586  @param order The direction of the index.
2587  @param prefix_length How many bytes or characters this key part should
2588  index, or zero if it should index the entire column.
2589  */
2590  PT_key_part_specification(const LEX_CSTRING &column_name, enum_order order,
2591  int prefix_length);
2592 
2593  /**
2594  Contextualize this key part specification. This will also call itemize on
2595  the indexed expression if this is a functional key part.
2596 
2597  @param pc The parse context
2598 
2599  @retval true on error
2600  @retval false on success
2601  */
2602  bool contextualize(Parse_context *pc) override;
2603 
2604  /**
2605  Get the indexed expression. The caller must ensure that has_expression()
2606  returns true before calling this.
2607 
2608  @returns The indexed expression
2609  */
2612  return m_expression;
2613  }
2614 
2615  /**
2616  @returns The direction of the index: ORDER_ASC, ORDER_DESC or
2617  ORDER_NOT_RELEVANT in case the user didn't explicitly specify a
2618  direction.
2619  */
2620  enum_order get_order() const { return m_order; }
2621 
2622  /**
2623  @retval true if the user explicitly specified a direction (asc/desc).
2624  @retval false if the user didn't explicitly specify a direction.
2625  */
2626  bool is_explicit() const { return get_order() != ORDER_NOT_RELEVANT; }
2627 
2628  /**
2629  @retval true if the key part contains an expression (and thus is a
2630  functional key part).
2631  @retval false if the key part doesn't contain an expression.
2632  */
2633  bool has_expression() const { return m_expression != nullptr; }
2634 
2635  /**
2636  Get the column that this key part points to. This is only valid if this
2637  key part isn't a functional index. The caller must thus check the return
2638  value of has_expression() before calling this function.
2639 
2640  @returns The column that this key part points to.
2641  */
2644  return m_column_name;
2645  }
2646 
2647  /**
2648  @returns The number of bytes that this key part should index. If the column
2649  this key part points to is a non-binary column, this is the number
2650  of characters. Returns zero if the entire column should be indexed.
2651  */
2652  int get_prefix_length() const { return m_prefix_length; }
2653 
2654  private:
2655  /**
2656  The indexed expression in case this is a functional key part. Only valid if
2657  has_expression() returns true.
2658  */
2660 
2661  /// The direction of the index.
2663 
2664  /// The name of the column that this key part indexes.
2666 
2667  /**
2668  If this is greater than zero, it represents how many bytes of the column
2669  that is indexed. Note that for non-binary columns (VARCHAR, TEXT etc), this
2670  is the number of characters.
2671  */
2673 };
2674 
2675 /**
2676  A template for options that set a single `<alter option>` value in
2677  thd->lex->key_create_info.
2678 
2679  @tparam Option_type The data type of the option.
2680  @tparam Property Pointer-to-member for the option of KEY_CREATE_INFO.
2681 */
2682 template <typename Option_type, Option_type KEY_CREATE_INFO::*Property>
2684  public:
2685  /// @param option_value The value of the option.
2687 
2690  return false;
2691  }
2692 
2693  private:
2694  Option_type m_option_value;
2695 };
2696 
2697 /**
2698  A template for options that set a single property in a KEY_CREATE_INFO, and
2699  also records if the option was explicitly set.
2700 */
2701 template <typename Option_type, Option_type KEY_CREATE_INFO::*Property,
2702  bool KEY_CREATE_INFO::*Property_is_explicit>
2704  public:
2707 
2710  pc->key_create_info->*Property_is_explicit = true;
2711  return false;
2712  }
2713 
2714  private:
2715  Option_type m_option_value;
2716 };
2717 
2725 
2726 /**
2727  The data structure (B-tree, Hash, etc) used for an index is called
2728  'index_type' in the manual. Internally, this is stored in
2729  KEY_CREATE_INFO::algorithm, while what the manual calls 'algorithm' is
2730  stored in partition_info::key_algorithm. In an `<create_index_stmt>`
2731  it's ignored. The terminology is somewhat confusing, but we stick to the
2732  manual in the parser.
2733 */
2737 
2739  public:
2741  const LEX_STRING &name_arg, PT_base_index_option *type,
2742  Table_ident *table_ident,
2748  m_keytype(type_par),
2749  m_name(name_arg),
2750  m_type(type),
2751  m_table_ident(table_ident),
2752  m_columns(cols),
2753  m_options(options),
2754  m_algo(algo),
2755  m_lock(lock) {}
2756 
2757  Sql_cmd *make_cmd(THD *thd) override;
2758 
2759  private:
2768 };
2769 
2770 /**
2771  Base class for column/constraint definitions in CREATE %TABLE
2772 
2773  @ingroup ptn_create_table_stuff
2774 */
2776 
2778 
2781 
2782  public:
2783  PT_inline_index_definition(keytype type_par, const LEX_STRING &name_arg,
2787  : m_keytype(type_par),
2788  m_name(name_arg),
2789  m_type(type),
2790  m_columns(cols),
2791  m_options(options) {}
2792 
2793  bool contextualize(Table_ddl_parse_context *pc) override;
2794 
2795  private:
2801 };
2802 
2805 
2806  public:
2807  PT_foreign_key_definition(const LEX_STRING &constraint_name,
2808  const LEX_STRING &key_name,
2810  Table_ident *referenced_table,
2811  List<Key_part_spec> *ref_list,
2812  fk_match_opt fk_match_option,
2813  fk_option fk_update_opt, fk_option fk_delete_opt)
2814  : m_constraint_name(constraint_name),
2815  m_key_name(key_name),
2816  m_columns(columns),
2817  m_referenced_table(referenced_table),
2818  m_ref_list(ref_list),
2819  m_fk_match_option(fk_match_option),
2820  m_fk_update_opt(fk_update_opt),
2821  m_fk_delete_opt(fk_delete_opt) {}
2822 
2824 
2825  private:
2834 };
2835 
2836 /**
2837  Common base class for CREATE TABLE and ALTER TABLE option nodes
2838 
2839  @ingroup ptn_create_or_alter_table_options
2840 */
2842  public:
2843  ~PT_ddl_table_option() override = 0; // Force abstract class declaration
2844 
2845  virtual bool is_rename_table() const { return false; }
2846 };
2847 
2849 
2850 /**
2851  Base class for CREATE TABLE option nodes
2852 
2853  @ingroup ptn_create_or_alter_table_options
2854 */
2857 
2858  public:
2859  ~PT_create_table_option() override = 0; // Force abstract class declaration
2860 
2862  if (super::contextualize(pc)) return true;
2864  return false;
2865  }
2866 };
2867 
2869 
2870 /**
2871  A template for options that set a single property in HA_CREATE_INFO, and
2872  also records if the option was explicitly set.
2873 */
2874 template <typename Option_type, Option_type HA_CREATE_INFO::*Property,
2875  ulong Property_flag>
2878 
2879  const Option_type value;
2880 
2881  public:
2883 
2885  if (super::contextualize(pc)) return true;
2886  pc->create_info->*Property = value;
2887  pc->create_info->used_fields |= Property_flag;
2888  return false;
2889  }
2890 };
2891 
2892 #define TYPE_AND_REF(x) decltype(x), &x
2893 
2894 /**
2895  Node for the @SQL{MAX_ROWS [=] @B{@<integer@>}} table option
2896 
2897  @ingroup ptn_create_or_alter_table_options
2898 */
2902 
2903 /**
2904  Node for the @SQL{MIN_ROWS [=] @B{@<integer@>}} table option
2905 
2906  @ingroup ptn_create_or_alter_table_options
2907 */
2911 
2912 /**
2913  Node for the @SQL{AVG_ROW_LENGTH_ROWS [=] @B{@<integer@>}} table option
2914 
2915  @ingroup ptn_create_or_alter_table_options
2916 */
2920 
2921 /**
2922  Node for the @SQL{PASSWORD [=] @B{@<string@>}} table option
2923 
2924  @ingroup ptn_create_or_alter_table_options
2925 */
2929 
2930 /**
2931  Node for the @SQL{COMMENT [=] @B{@<string@>}} table option
2932 
2933  @ingroup ptn_create_or_alter_table_options
2934 */
2938 
2939 /**
2940  Node for the @SQL{COMPRESSION [=] @B{@<string@>}} table option
2941 
2942  @ingroup ptn_create_or_alter_table_options
2943 */
2947 
2948 /**
2949  Node for the @SQL{ENGRYPTION [=] @B{@<string@>}} table option
2950 
2951  @ingroup ptn_create_or_alter_table_options
2952 */
2956 
2957 /**
2958  Node for the @SQL{AUTO_INCREMENT [=] @B{@<integer@>}} table option
2959 
2960  @ingroup ptn_create_or_alter_table_options
2961 */
2965 
2969 
2974 
2978 
2982 
2986 
2990 
2994 
2996 
2997 /**
2998  A template for options that set HA_CREATE_INFO::table_options and
2999  also records if the option was explicitly set.
3000 */
3001 template <ulong Property_flag, table_options_t Default, table_options_t Yes,
3002  table_options_t No>
3005 
3007 
3008  public:
3010  : value(value) {}
3011 
3013  if (super::contextualize(pc)) return true;
3014  pc->create_info->table_options &= ~(Yes | No);
3015  switch (value) {
3016  case Ternary_option::ON:
3017  pc->create_info->table_options |= Yes;
3018  break;
3019  case Ternary_option::OFF:
3020  pc->create_info->table_options |= No;
3021  break;
3023  break;
3024  default:
3025  DBUG_ASSERT(false);
3026  }
3027  pc->create_info->used_fields |= Property_flag;
3028  return false;
3029  }
3030 };
3031 
3032 /**
3033  Node for the @SQL{PACK_KEYS [=] @B{1|0|DEFAULT}} table option
3034 
3035  @ingroup ptn_create_or_alter_table_options
3036 
3037  PACK_KEYS | Constructor parameter
3038  ----------|----------------------
3039  1 | Ternary_option::ON
3040  0 | Ternary_option::OFF
3041  DEFAULT | Ternary_option::DEFAULT
3042 */
3044  0, // DEFAULT
3045  HA_OPTION_PACK_KEYS, // ON
3046  HA_OPTION_NO_PACK_KEYS> // OFF
3048 
3049 /**
3050  Node for the @SQL{STATS_PERSISTENT [=] @B{1|0|DEFAULT}} table option
3051 
3052  @ingroup ptn_create_or_alter_table_options
3053 
3054  STATS_PERSISTENT | Constructor parameter
3055  -----------------|----------------------
3056  1 | Ternary_option::ON
3057  0 | Ternary_option::OFF
3058  DEFAULT | Ternary_option::DEFAULT
3059 */
3061  0, // DEFAULT
3065 
3066 /**
3067  A template for options that set HA_CREATE_INFO::table_options and
3068  also records if the option was explicitly set.
3069 */
3070 template <ulong Property_flag, table_options_t Yes, table_options_t No>
3073 
3074  const bool value;
3075 
3076  public:
3078 
3080  if (super::contextualize(pc)) return true;
3081  pc->create_info->table_options &= ~(Yes | No);
3082  pc->create_info->table_options |= value ? Yes : No;
3083  pc->create_info->used_fields |= Property_flag;
3084  return false;
3085  }
3086 };
3087 
3088 /**
3089  Node for the @SQL{CHECKSUM|TABLE_CHECKSUM [=] @B{0|@<not 0@>}} table option
3090 
3091  @ingroup ptn_create_or_alter_table_options
3092 
3093  TABLE_CHECKSUM | Constructor parameter
3094  ---------------|----------------------
3095  0 | false
3096  not 0 | true
3097 */
3099  HA_OPTION_CHECKSUM, // ON
3100  HA_OPTION_NO_CHECKSUM // OFF
3101  >
3103 
3104 /**
3105  Node for the @SQL{DELAY_KEY_WRITE [=] @B{0|@<not 0@>}} table option
3106 
3107  @ingroup ptn_create_or_alter_table_options
3108 
3109  TABLE_CHECKSUM | Constructor parameter
3110  ---------------|----------------------
3111  0 | false
3112  not 0 | true
3113 */
3118 
3119 /**
3120  Node for the @SQL{ENGINE [=] @B{@<identifier@>|@<string@>}} table option
3121 
3122  @ingroup ptn_create_or_alter_table_options
3123 */
3126 
3128 
3129  public:
3130  /**
3131  @param engine Storage engine name.
3132  */
3134  : engine(engine) {}
3135 
3136  bool contextualize(Table_ddl_parse_context *pc) override;
3137 };
3138 
3139 /**
3140  Node for the @SQL{SECONDARY_ENGINE [=] @B{@<identifier@>|@<string@>|NULL}}
3141  table option.
3142 
3143  @ingroup ptn_create_or_alter_table_options
3144 */
3147 
3148  public:
3153 
3154  bool contextualize(Table_ddl_parse_context *pc) override;
3155 
3156  private:
3157  const LEX_CSTRING m_secondary_engine{nullptr, 0};
3158 };
3159 
3160 /**
3161  Node for the @SQL{STATS_AUTO_RECALC [=] @B{@<0|1|DEFAULT@>})} table option
3162 
3163  @ingroup ptn_create_or_alter_table_options
3164 */
3167 
3169 
3170  public:
3171  /**
3172  @param value
3173  STATS_AUTO_RECALC | value
3174  ------------------|----------------------
3175  1 | Ternary_option::ON
3176  0 | Ternary_option::OFF
3177  DEFAULT | Ternary_option::DEFAULT
3178  */
3180 
3181  bool contextualize(Table_ddl_parse_context *pc) override;
3182 };
3183 
3184 /**
3185  Node for the @SQL{STATS_SAMPLE_PAGES [=] @B{@<integer@>|DEFAULT}} table option
3186 
3187  @ingroup ptn_create_or_alter_table_options
3188 */
3192 
3194 
3195  public:
3196  /**
3197  Constructor for implicit number of pages
3198 
3199  @param value Nunber of pages, 1@<=N@<=65535.
3200  */
3202  DBUG_ASSERT(value != 0 && value <= 0xFFFF);
3203  }
3204  /**
3205  Constructor for the DEFAULT number of pages
3206  */
3208 
3209  bool contextualize(Table_ddl_parse_context *pc) override;
3210 };
3211 
3214 
3216 
3217  public:
3219  : tables(tables) {}
3220 
3221  bool contextualize(Table_ddl_parse_context *pc) override;
3222 };
3223 
3226 
3228 
3229  public:
3231 
3233  if (super::contextualize(pc)) return true;
3235  return false;
3236  }
3237 };
3238 
3241 
3243 
3244  public:
3246  : value(value) {
3247  DBUG_ASSERT(value != nullptr);
3248  }
3249 
3250  bool contextualize(Table_ddl_parse_context *pc) override;
3251 };
3252 
3255 
3257 
3258  public:
3260  : value(value) {
3261  DBUG_ASSERT(value != nullptr);
3262  }
3263 
3264  bool contextualize(Table_ddl_parse_context *pc) override;
3265 };
3266 
3270 
3271  public:
3272  explicit PT_check_constraint(LEX_STRING &name, Item *expr, bool is_enforced) {
3273  cc_spec.name = name;
3274  cc_spec.check_expr = expr;
3275  cc_spec.is_enforced = is_enforced;
3276  }
3278 
3280  if (super::contextualize(pc) ||
3282  return true;
3283 
3285  return true;
3286 
3288  return false;
3289  }
3290 };
3291 
3294 
3297  // Currently we ignore that constraint in the executor.
3299 
3300  const char *opt_place;
3301 
3302  public:
3305  const char *opt_place = NULL)
3309  opt_place(opt_place) {}
3310 
3311  bool contextualize(Table_ddl_parse_context *pc) override;
3312 };
3313 
3314 /**
3315  Top-level node for the CREATE %TABLE statement
3316 
3317  @ingroup ptn_create_table
3318 */
3329 
3331 
3332  public:
3333  /**
3334  @param mem_root MEM_ROOT to use for allocation
3335  @param is_temporary True if @SQL{CREATE @B{TEMPORARY} %TABLE}
3336  @param only_if_not_exists True if @SQL{CREATE %TABLE ... @B{IF NOT EXISTS}}
3337  @param table_name @SQL{CREATE %TABLE ... @B{@<table name@>}}
3338  @param opt_table_element_list NULL or a list of table column and
3339  constraint definitions.
3340  @param opt_create_table_options NULL or a list of
3341  @ref ptn_create_or_alter_table_options
3342  "table options".
3343  @param opt_partitioning NULL or the @SQL{PARTITION BY} clause.
3344  @param on_duplicate DUPLICATE, IGNORE or fail with an error
3345  on data duplication errors (relevant
3346  for @SQL{CREATE TABLE ... SELECT}
3347  statements).
3348  @param opt_query_expression NULL or the @SQL{@B{SELECT}} clause.
3349  */
3366  opt_like_clause(NULL) {}
3367  /**
3368  @param mem_root MEM_ROOT to use for allocation
3369  @param is_temporary True if @SQL{CREATE @B{TEMPORARY} %TABLE}.
3370  @param only_if_not_exists True if @SQL{CREATE %TABLE ... @B{IF NOT EXISTS}}.
3371  @param table_name @SQL{CREATE %TABLE ... @B{@<table name@>}}.
3372  @param opt_like_clause NULL or the @SQL{@B{LIKE @<table name@>}} clause.
3373  */
3387 
3388  Sql_cmd *make_cmd(THD *thd) override;
3389 };
3390 
3393 
3394  public:
3395  PT_create_role(bool if_not_exists, const List<LEX_USER> *roles)
3396  : sql_cmd(if_not_exists, roles) {}
3397 
3398  Sql_cmd *make_cmd(THD *thd) override {
3400  return &sql_cmd;
3401  }
3402 };
3403 
3406 
3407  public:
3408  explicit PT_drop_role(bool ignore_errors, const List<LEX_USER> *roles)
3409  : sql_cmd(ignore_errors, roles) {}
3410 
3411  Sql_cmd *make_cmd(THD *thd) override {
3413  return &sql_cmd;
3414  }
3415 };
3416 
3419 
3420  public:
3421  explicit PT_set_role(role_enum role_type,
3422  const List<LEX_USER> *opt_except_roles = NULL)
3423  : sql_cmd(role_type, opt_except_roles) {
3424  DBUG_ASSERT(role_type == role_enum::ROLE_ALL || opt_except_roles == NULL);
3425  }
3426  explicit PT_set_role(const List<LEX_USER> *roles) : sql_cmd(roles) {}
3427 
3428  Sql_cmd *make_cmd(THD *thd) override {
3430  return &sql_cmd;
3431  }
3432 };
3433 
3434 /**
3435  This class is used for representing both static and dynamic privileges on
3436  global as well as table and column level.
3437 */
3438 struct Privilege {
3440 
3443 
3446  : type(type), columns(columns) {}
3447 };
3448 
3449 struct Static_privilege : public Privilege {
3450  const uint grant;
3451 
3453  : Privilege(STATIC, columns_arg), grant(grant) {}
3454 };
3455 
3456 struct Dynamic_privilege : public Privilege {
3458 
3460  const Mem_root_array<LEX_CSTRING> *columns_arg)
3461  : Privilege(DYNAMIC, columns_arg), ident(ident) {}
3462 };
3463 
3465  private:
3467 
3468  public:
3469  explicit PT_role_or_privilege(const POS &pos) : pos(pos) {}
3470 
3471  virtual LEX_USER *get_user(THD *thd) {
3472  thd->syntax_error_at(pos, "Illegal authorization identifier");
3473  return NULL;
3474  }
3475  virtual Privilege *get_privilege(THD *thd) {
3476  thd->syntax_error_at(pos, "Illegal privilege identifier");
3477  return NULL;
3478  }
3479 };
3480 
3484 
3485  public:
3487  const LEX_STRING &host)
3489 
3490  LEX_USER *get_user(THD *thd) override {
3491  return LEX_USER::alloc(thd, &role, &host);
3492  }
3493 };
3494 
3497 
3498  public:
3501 
3502  LEX_USER *get_user(THD *thd) override {
3503  return LEX_USER::alloc(thd, &ident, NULL);
3504  }
3505 
3506  Privilege *get_privilege(THD *thd) override {
3507  return new (thd->mem_root) Dynamic_privilege(ident, NULL);
3508  }
3509 };
3510 
3512  const uint grant;
3514 
3515  public:
3519 
3520  Privilege *get_privilege(THD *thd) override {
3521  return new (thd->mem_root) Static_privilege(grant, columns);
3522  }
3523 };
3524 
3527 
3528  public:
3531 
3532  Privilege *get_privilege(THD *thd) override {
3533  return new (thd->mem_root) Dynamic_privilege(ident, nullptr);
3534  }
3535 };
3536 
3540  const bool with_admin_option;
3541 
3542  public:
3544  const List<LEX_USER> *users, bool with_admin_option)
3546 
3547  Sql_cmd *make_cmd(THD *thd) override {
3549 
3550  List<LEX_USER> *role_objects = new (thd->mem_root) List<LEX_USER>;
3551  if (role_objects == NULL) return NULL; // OOM
3552  for (PT_role_or_privilege *r : *roles) {
3553  LEX_USER *user = r->get_user(thd);
3554  if (r == NULL || role_objects->push_back(user)) return NULL;
3555  }
3556 
3557  return new (thd->mem_root)
3559  }
3560 };
3561 
3565 
3566  public:
3568  const List<LEX_USER> *users)
3569  : roles(roles), users(users) {}
3570 
3571  Sql_cmd *make_cmd(THD *thd) override {
3573 
3574  List<LEX_USER> *role_objects = new (thd->mem_root) List<LEX_USER>;
3575  if (role_objects == NULL) return NULL; // OOM
3576  for (PT_role_or_privilege *r : *roles) {
3577  LEX_USER *user = r->get_user(thd);
3578  if (r == NULL || role_objects->push_back(user)) return NULL;
3579  }
3580  return new (thd->mem_root) Sql_cmd_revoke_roles(role_objects, users);
3581  }
3582 };
3583 
3586 
3587  public:
3588  PT_alter_user_default_role(bool if_exists, const List<LEX_USER> *users,
3589  const List<LEX_USER> *roles,
3590  const role_enum role_type)
3591  : sql_cmd(if_exists, users, roles, role_type) {}
3592 
3593  Sql_cmd *make_cmd(THD *thd) override {
3595  return &sql_cmd;
3596  }
3597 };
3598 
3601 
3602  public:
3603  PT_show_grants(const LEX_USER *opt_for_user,
3604  const List<LEX_USER> *opt_using_users)
3605  : sql_cmd(opt_for_user, opt_using_users) {
3606  DBUG_ASSERT(opt_using_users == NULL || opt_for_user != NULL);
3607  }
3608 
3609  Sql_cmd *make_cmd(THD *thd) override {
3611  return &sql_cmd;
3612  }
3613 };
3614 
3615 /**
3616  Base class for Parse tree nodes of SHOW FIELDS/SHOW INDEX statements.
3617 */
3619  protected:
3621 
3623  const LEX_STRING &wild, Item *where_condition)
3624  : m_sql_cmd(static_cast<enum_sql_command>(type)),
3625  m_pos(pos),
3626  m_type(type),
3627  m_table_ident(table_ident),
3628  m_wild(wild),
3629  m_where_condition(where_condition) {
3630  DBUG_ASSERT(wild.str == nullptr || where_condition == nullptr);
3631  }
3632 
3633  public:
3634  Sql_cmd *make_cmd(THD *thd) override;
3635 
3636  private:
3637  // Sql_cmd for SHOW COLUMNS/SHOW INDEX statements.
3639 
3640  // Textual location of a token just parsed.
3642 
3643  // SHOW_FIELDS or SHOW_KEYS
3645 
3646  // Table used in the statement.
3648 
3649  // Wild or where clause used in the statement.
3652 };
3653 
3654 /**
3655  Parse tree node for SHOW FIELDS statement.
3656 */
3659 
3660  public:
3661  PT_show_fields(const POS &pos, Show_cmd_type show_cmd_type,
3662  Table_ident *table, const LEX_STRING &wild)
3663  : PT_show_fields_and_keys(pos, SHOW_FIELDS, table, wild, nullptr),
3664  m_show_cmd_type(show_cmd_type) {}
3665 
3666  PT_show_fields(const POS &pos, Show_cmd_type show_cmd_type,
3667  Table_ident *table_ident, Item *where_condition = nullptr)
3669  where_condition),
3670  m_show_cmd_type(show_cmd_type) {}
3671 
3672  Sql_cmd *make_cmd(THD *thd) override;
3673 
3674  private:
3676 };
3677 
3678 /**
3679  Parse tree node for SHOW INDEX statement.
3680 */
3682  public:
3683  PT_show_keys(const POS &pos, bool extended_show, Table_ident *table,
3684  Item *where_condition)
3686  where_condition),
3687  m_extended_show(extended_show) {}
3688 
3689  Sql_cmd *make_cmd(THD *thd) override;
3690 
3691  private:
3693 
3694  // Flag to indicate EXTENDED keyword usage in the statement.
3696 };
3697 
3700 
3701  protected:
3703  : flag(flag) {}
3704 
3705  public:
3707  if (super::contextualize(pc)) return true;
3708  pc->alter_info->flags |= flag;
3709  return false;
3710  }
3711 
3712  protected:
3713  /**
3714  A routine used by the parser to decide whether we are specifying a full
3715  partitioning or if only partitions to add or to reorganize.
3716 
3717  @retval true ALTER TABLE ADD/REORGANIZE PARTITION.
3718  @retval false Something else.
3719  */
3723  }
3724 
3725  public:
3727 };
3728 
3731 
3732  public:
3734  PT_field_def_base *field_def,
3735  PT_table_constraint_def *opt_column_constraint,
3736  const char *opt_place)
3737  : super(Alter_info::ALTER_ADD_COLUMN),
3738  m_column_def(field_ident, field_def, opt_column_constraint, opt_place) {
3739  }
3740 
3743  }
3744 
3745  private:
3747 };
3748 
3751 
3752  public:
3754  const Mem_root_array<PT_table_element *> *columns)
3755  : super(Alter_info::ALTER_ADD_COLUMN), m_columns(columns) {}
3756 
3758  if (super::contextualize(pc)) return true;
3759 
3760  for (auto *column : *m_columns)
3761  if (column->contextualize(pc)) return true;
3762 
3763  return false;
3764  }
3765 
3766  private:
3768 };
3769 
3772 
3773  public:
3775  : super(Alter_info::ALTER_ADD_INDEX), m_constraint(constraint) {}
3776 
3778  return super::contextualize(pc) || m_constraint->contextualize(pc);
3779  }
3780 
3781  private:
3783 };
3784 
3787 
3788  public:
3790  const LEX_STRING &new_name,
3791  PT_field_def_base *field_def,
3792  const char *opt_place)
3793  : super(Alter_info::ALTER_CHANGE_COLUMN),
3794  m_old_name(old_name),
3795  m_new_name(new_name),
3796  m_field_def(field_def),
3797  m_opt_place(opt_place) {}
3798 
3800  PT_field_def_base *field_def,
3801  const char *opt_place)
3802  : PT_alter_table_change_column(name, name, field_def, opt_place) {}
3803 
3804  bool contextualize(Table_ddl_parse_context *pc) override;
3805 
3806  private:
3810  const char *m_opt_place;
3811 };
3812 
3815 
3816  protected:
3818  Alter_info::Alter_info_flag alter_info_flag,
3819  const char *name)
3820  : super(alter_info_flag), m_alter_drop(drop_type, name) {}
3821 
3822  public:
3824  return (super::contextualize(pc) ||
3826  }
3827 
3828  private:
3830 };
3831 
3833  public:
3834  explicit PT_alter_table_drop_column(const char *name)
3835  : PT_alter_table_drop(Alter_drop::COLUMN, Alter_info::ALTER_DROP_COLUMN,
3836  name) {}
3837 };
3838 
3840  public:
3843  Alter_info::DROP_FOREIGN_KEY, name) {}
3844 };
3845 
3847  public:
3848  explicit PT_alter_table_drop_key(const char *name)
3849  : PT_alter_table_drop(Alter_drop::KEY, Alter_info::ALTER_DROP_INDEX,
3850  name) {}
3851 };
3852 
3854  public:
3856  : PT_alter_table_drop(Alter_drop::CHECK_CONSTRAINT,
3857  Alter_info::DROP_CHECK_CONSTRAINT, name) {}
3858 };
3859 
3862 
3863  public:
3864  explicit PT_alter_table_check_constraint(const char *name, bool state)
3865  : super(state ? Alter_info::ENFORCE_CHECK_CONSTRAINT
3866  : Alter_info::SUSPEND_CHECK_CONSTRAINT),
3867  cc_state(Alter_state::Type::CHECK_CONSTRAINT, name, state) {}
3868 
3870  return (super::contextualize(pc) ||
3872  }
3873 
3874  private:
3876 };
3877 
3880 
3881  public:
3882  explicit PT_alter_table_enable_keys(bool enable)
3883  : super(Alter_info::ALTER_KEYS_ONOFF), m_enable(enable) {}
3884 
3886  pc->alter_info->keys_onoff =
3888  return super::contextualize(pc);
3889  }
3890 
3891  private:
3892  bool m_enable;
3893 };
3894 
3897 
3898  public:
3899  PT_alter_table_set_default(const char *col_name, Item *opt_default_expr)
3900  : super(Alter_info::ALTER_CHANGE_COLUMN_DEFAULT),
3901  m_name(col_name),
3902  m_expr(opt_default_expr) {}
3903 
3905  if (super::contextualize(pc) || itemize_safe(pc, &m_expr)) return true;
3906  Alter_column *alter_column;
3907  if (m_expr == nullptr || m_expr->basic_const_item()) {
3908  alter_column = new (pc->mem_root) Alter_column(m_name, m_expr);
3909  } else {
3910  auto vg = new (pc->mem_root) Value_generator;
3911  if (vg == nullptr) return true; // OOM
3912  vg->expr_item = m_expr;
3913  vg->set_field_stored(true);
3914  alter_column = new (pc->mem_root) Alter_column(m_name, vg);
3915  }
3916  if (alter_column == nullptr ||
3917  pc->alter_info->alter_list.push_back(alter_column)) {
3918  return true; // OOM
3919  }
3920  return false;
3921  }
3922 
3923  private:
3924  const char *m_name;
3926 };
3927 
3930 
3931  public:
3932  PT_alter_table_index_visible(const char *name, bool visible)
3933  : super(Alter_info::ALTER_INDEX_VISIBILITY),
3934  m_alter_index_visibility(name, visible) {}
3935 
3937  return (super::contextualize(pc) ||
3940  }
3941 
3942  private:
3944 };
3945 
3948 
3949  public:
3950  explicit PT_alter_table_rename(const Table_ident *ident)
3951  : super(Alter_info::ALTER_RENAME), m_ident(ident) {}
3952 
3953  bool contextualize(Table_ddl_parse_context *pc) override;
3954 
3955  bool is_rename_table() const override { return true; }
3956 
3957  private:
3958  const Table_ident *const m_ident;
3959 };
3960 
3963 
3964  public:
3965  PT_alter_table_rename_key(const char *from, const char *to)
3966  : super(Alter_info::ALTER_RENAME_INDEX), m_rename_key(from, to) {}
3967 
3969  return super::contextualize(pc) ||
3971  }
3972 
3973  private:
3975 };
3976 
3979 
3980  public:
3981  PT_alter_table_rename_column(const char *from, const char *to)
3982  : super(Alter_info::ALTER_CHANGE_COLUMN), m_rename_column(from, to) {}
3983 
3985  return super::contextualize(pc) ||
3987  }
3988 
3989  private:
3991 };
3992 
3995 
3996  public:
3998  const CHARSET_INFO *opt_collation)
3999  : super(Alter_info::ALTER_OPTIONS),
4000  m_charset(charset),
4001  m_collation(opt_collation) {}
4002 
4003  bool contextualize(Table_ddl_parse_context *pc) override;
4004 
4005  private:
4006  const CHARSET_INFO *const m_charset;
4008 };
4009 
4012 
4013  public:
4014  PT_alter_table_force() : super(Alter_info::ALTER_RECREATE) {}
4015 };
4016 
4019 
4020  public:
4022  : super(Alter_info::ALTER_ORDER), m_order(order) {}
4023 
4025  if (super::contextualize(pc) || m_order->contextualize(pc)) return true;
4026  pc->select->order_list = m_order->value;
4027  return false;
4028  }
4029 
4030  private:
4032 };
4033 
4036 
4037  public:
4039  : super(Alter_info::ALTER_PARTITION), m_partition(partition) {}
4040 
4042  if (super::contextualize(pc) || m_partition->contextualize(pc)) return true;
4044  return false;
4045  }
4046 
4047  private:
4049 };
4050 
4053 
4054  public:
4056  : super(Alter_info::ALTER_REMOVE_PARTITIONING) {}
4057 };
4058 
4061 
4062  friend class PT_alter_table_standalone_stmt; // to access make_cmd()
4063 
4064  protected:
4066  : super(alter_info_flag) {}
4067 
4068  private:
4069  virtual Sql_cmd *make_cmd(Table_ddl_parse_context *pc) = 0;
4070 };
4071 
4072 /**
4073  Node for the @SQL{ALTER TABLE ADD PARTITION} statement
4074 
4075  @ingroup ptn_alter_table
4076 */
4079 
4080  public:
4081  explicit PT_alter_table_add_partition(bool no_write_to_binlog)
4082  : super(Alter_info::ALTER_ADD_PARTITION),
4083  m_no_write_to_binlog(no_write_to_binlog) {}
4084 
4086  if (super::contextualize(pc)) return true;
4087 
4088  LEX *const lex = pc->thd->lex;
4090  DBUG_ASSERT(lex->part_info == nullptr);
4091  lex->part_info = &m_part_info;
4092  return false;
4093  }
4094 
4096  return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
4097  }
4098 
4099  protected:
4101 
4102  private:
4104 };
4105 
4106 /**
4107  Node for the @SQL{ALTER TABLE ADD PARTITION (@<partition list@>)} statement
4108 
4109  @ingroup ptn_alter_table
4110 */
4112  : public PT_alter_table_add_partition {
4114 
4115  public:
4117  bool no_write_to_binlog,
4118  const Mem_root_array<PT_part_definition *> *def_list)
4119  : super(no_write_to_binlog), m_def_list(def_list) {}
4120 
4121  bool contextualize(Table_ddl_parse_context *pc) override;
4122 
4123  private:
4125 };
4126 
4127 /**
4128  Node for the @SQL{ALTER TABLE ADD PARTITION PARTITIONS (@<n>@)} statement
4129 
4130  @ingroup ptn_alter_table
4131 */
4133  : public PT_alter_table_add_partition {
4135 
4136  public:
4137  PT_alter_table_add_partition_num(bool no_write_to_binlog, uint num_parts)
4138  : super(no_write_to_binlog) {
4139  m_part_info.num_parts = num_parts;
4140  }
4141 };
4142 
4146 
4147  public:
4148  explicit PT_alter_table_drop_partition(const List<String> &partitions)
4149  : super(Alter_info::ALTER_DROP_PARTITION), m_partitions(partitions) {}
4150 
4152  if (super::contextualize(pc)) return true;
4153 
4156  return false;
4157  }
4158 
4160  return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
4161  }
4162 
4163  private:
4165 };
4166 
4170 
4171  public:
4173  Alter_info::Alter_info_flag alter_info_flag,
4174  const List<String> *opt_partition_list)
4175  : super(alter_info_flag), m_opt_partition_list(opt_partition_list) {}
4176 
4179  if (m_opt_partition_list == NULL)
4181  else
4183  return super::contextualize(pc);
4184  }
4185 
4186  private:
4188 };
4189 
4193 
4194  public:
4195  PT_alter_table_rebuild_partition(bool no_write_to_binlog,
4196  const List<String> *opt_partition_list)
4197  : super(Alter_info::ALTER_REBUILD_PARTITION, opt_partition_list),
4198  m_no_write_to_binlog(no_write_to_binlog) {}
4199 
4201  if (super::contextualize(pc)) return true;
4203  return false;
4204  }
4205 
4207  return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
4208  }
4209 
4210  private:
4212 };
4213 
4217 
4218  public:
4219  PT_alter_table_optimize_partition(bool no_write_to_binlog,
4220  const List<String> *opt_partition_list)
4221  : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
4222  m_no_write_to_binlog(no_write_to_binlog) {}
4223 
4225  if (super::contextualize(pc)) return true;
4227  pc->thd->lex->check_opt.init();
4228  return false;
4229  }
4230 
4232  return new (pc->mem_root)
4234  }
4235 
4236  private:
4238 };
4239 
4243 
4244  public:
4245  PT_alter_table_analyze_partition(bool no_write_to_binlog,
4246  const List<String> *opt_partition_list)
4247  : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
4248  m_no_write_to_binlog(no_write_to_binlog) {}
4249 
4251  if (super::contextualize(pc)) return true;
4253  pc->thd->lex->check_opt.init();
4254  return false;
4255  }
4256 
4258  return new (pc->mem_root)
4260  }
4261 
4262  private:
4264 };
4265 
4269 
4270  public:
4273  : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
4274  m_flags(flags),
4276 
4278  if (super::contextualize(pc)) return true;
4279 
4280  LEX *const lex = pc->thd->lex;
4281  lex->check_opt.init();
4282  lex->check_opt.flags |= m_flags;
4284  return false;
4285  }
4286 
4288  return new (pc->mem_root)
4290  }
4291 
4292  private:
4295 };
4296 
4300 
4301  public:
4302  PT_alter_table_repair_partition(bool no_write_to_binlog,
4303  const List<String> *opt_partition_list,
4305  : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
4306  m_no_write_to_binlog(no_write_to_binlog),
4307  m_flags(flags),
4309 
4311  if (super::contextualize(pc)) return true;
4312 
4313  LEX *const lex = pc->thd->lex;
4315 
4316  lex->check_opt.init();
4317  lex->check_opt.flags |= m_flags;
4319 
4320  return false;
4321  }
4322 
4324  return new (pc->mem_root)
4326  }
4327 
4328  private:
4332 };
4333 
4337 
4338  public:
4339  PT_alter_table_coalesce_partition(bool no_write_to_binlog, uint num_parts)
4340  : super(Alter_info::ALTER_COALESCE_PARTITION),
4341  m_no_write_to_binlog(no_write_to_binlog),
4342  m_num_parts(num_parts) {}
4343 
4345  if (super::contextualize(pc)) return true;
4346 
4349  return false;
4350  }
4351 
4353  return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
4354  }
4355 
4356  private:
4359 };
4360 
4363  typedef