MySQL  8.0.18
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 "lex_string.h"
32 #include "libbinlogevents/include/binlog_event.h" // UNDEFINED_SERVER_VERSION
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 namespace {
185 
186 template <typename Context, typename Node>
187 bool contextualize_safe(Context *pc, Node node) {
188  if (node == nullptr) return false;
189  return node->contextualize(pc);
190 }
191 
192 /**
193  Convenience function that calls Parse_tree_node::contextualize() on each of
194  the nodes that are non-NULL, stopping when a call returns true.
195 */
196 template <typename Context, typename Node, typename... Nodes>
197 bool contextualize_safe(Context *pc, Node node, Nodes... nodes) {
198  return contextualize_safe(pc, node) || contextualize_safe(pc, nodes...);
199 }
200 
201 } // namespace
202 
203 /**
204  Parse context for the table DDL (ALTER TABLE and CREATE TABLE) nodes.
205 
206  For internal use in the contextualization code.
207 */
209  Table_ddl_parse_context(THD *thd_arg, SELECT_LEX *select_arg,
211  : Parse_context(thd_arg, select_arg),
212  create_info(thd_arg->lex->create_info),
214  key_create_info(&thd_arg->lex->key_create_info) {}
215 
219 };
220 
221 /**
222  Base class for all table DDL (ALTER TABLE and CREATE TABLE) nodes.
223 */
225 
226 /**
227  Convenience function that calls Item::itemize() on the item if it's
228  non-NULL.
229 */
230 inline bool itemize_safe(Parse_context *pc, Item **item) {
231  if (*item == NULL) return false;
232  return (*item)->itemize(pc, item);
233 }
234 
235 class PT_order_expr : public Parse_tree_node, public ORDER {
237 
238  public:
239  PT_order_expr(Item *item_arg, enum_order dir) {
240  item_ptr = item_arg;
241  direction = (dir == ORDER_DESC) ? ORDER_DESC : ORDER_ASC;
242  }
243 
244  bool contextualize(Parse_context *pc) override {
245  return super::contextualize(pc) || item_ptr->itemize(pc, &item_ptr);
246  }
247 };
248 
251 
252  public:
254 
255  public:
256  bool contextualize(Parse_context *pc) override {
257  if (super::contextualize(pc)) return true;
258  for (ORDER *o = value.first; o != NULL; o = o->next) {
259  if (static_cast<PT_order_expr *>(o)->contextualize(pc)) return true;
260  }
261  return false;
262  }
263 
264  void push_back(PT_order_expr *order) {
265  order->item = &order->item_ptr;
266  order->used_alias = false;
267  order->used = 0;
268  order->is_position = false;
269  value.link_in_list(order, &order->next);
270  }
271 };
272 
275 
276  public:
277  bool contextualize(Parse_context *pc) override {
278  return super::contextualize(pc);
279  }
280 };
281 
282 /**
283  Represents an element of the WITH list:
284  WITH [...], [...] SELECT ...,
285  ^ or ^
286  i.e. a Common Table Expression (CTE, or Query Name in SQL99 terms).
287 */
290 
291  public:
292  explicit PT_common_table_expr(const LEX_STRING &name,
293  const LEX_STRING &subq_text,
294  uint subq_text_offset, PT_subquery *sn,
296  MEM_ROOT *mem_root);
297 
298  /// The name after AS
299  const LEX_STRING &name() const { return m_name; }
300  /**
301  @param thd Thread handler
302  @param[out] node PT_subquery
303  @returns a PT_subquery to attach to a table reference for this CTE
304  */
305  bool make_subquery_node(THD *thd, PT_subquery **node);
306  /**
307  @param tl Table reference to match
308  @param in_self If this is a recursive reference
309  @param[out] found Is set to true/false if matches or not
310  @returns true if error
311  */
312  bool match_table_ref(TABLE_LIST *tl, bool in_self, bool *found);
313  /**
314  @returns true if 'other' is the same instance as 'this'
315  */
316  bool is(const Common_table_expr *other) const {
317  return other == &m_postparse;
318  }
319  void print(const THD *thd, String *str, enum_query_type query_type);
320 
321  private:
323  /// Raw text of query expression (including parentheses)
325  /**
326  Offset in bytes of m_subq_text in original statement which had the WITH
327  clause.
328  */
330  /// Parsed version of subq_text
332  /// List of explicitely specified column names; if empty, no list.
334  /**
335  A TABLE_LIST representing a CTE needs access to the WITH list
336  element it derives from. However, in order to:
337  - limit the members which TABLE_LIST can access
338  - avoid including this header file everywhere TABLE_LIST needs to access
339  these members,
340  these members are relocated into a separate inferior object whose
341  declaration is in table.h, like that of TABLE_LIST. It's the "postparse"
342  part. TABLE_LIST accesses this inferior object only.
343  */
345 
347 };
348 
349 /**
350  Represents the WITH list.
351  WITH [...], [...] SELECT ...,
352  ^^^^^^^^^^^^
353 */
356 
357  public:
358  /// @param mem_root where interior objects are allocated
362  return m_elements;
363  }
364 
365  private:
367 };
368 
369 /**
370  Represents the WITH clause:
371  WITH [...], [...] SELECT ...,
372  ^^^^^^^^^^^^^^^^^
373 */
376 
377  public:
378  PT_with_clause(const PT_with_list *l, bool r)
379  : m_list(l), m_recursive(r), m_most_inner_in_parsing(nullptr) {}
380 
381  bool contextualize(Parse_context *pc) override {
382  if (super::contextualize(pc)) return true; /* purecov: inspected */
383  // WITH complements a query expression (a unit).
384  pc->select->master_unit()->m_with_clause = this;
385  return false;
386  }
387 
388  /**
389  Looks up a table reference into the list of CTEs.
390  @param tl Table reference to look up
391  @param[out] found Is set to true/false if found or not
392  @returns true if error
393  */
394  bool lookup(TABLE_LIST *tl, PT_common_table_expr **found);
395  /**
396  Call this to record in the WITH clause that we are contextualizing the
397  CTE definition inserted in table reference 'tl'.
398  @returns information which the caller must provide to
399  leave_parsing_definition().
400  */
402  auto old = m_most_inner_in_parsing;
404  return old;
405  }
408  }
409  void print(const THD *thd, String *str, enum_query_type query_type);
410 
411  private:
412  /// All CTEs of this clause
413  const PT_with_list *const m_list;
414  /// True if the user has specified the RECURSIVE keyword.
415  const bool m_recursive;
416  /**
417  The innermost CTE reference which we're parsing at the
418  moment. Used to detect forward references, loops and recursiveness.
419  */
421 
423 };
424 
427 
428  public:
429  bool contextualize(Parse_context *pc) override {
430  if (super::contextualize(pc)) return true;
431 
432  pc->select->item_list = value;
433  return false;
434  }
435 };
436 
439 
441 
442  public:
443  PT_limit_clause(const Limit_options &limit_options_arg)
444  : limit_options(limit_options_arg) {}
445 
446  bool contextualize(Parse_context *pc) override {
447  if (super::contextualize(pc)) return true;
448 
451  return true;
452 
453  if (limit_options.limit->itemize(pc, &limit_options.limit)) return true;
454 
457  return true;
458 
461  pc->select->explicit_limit = true;
462 
464  return false;
465  }
466 };
467 
468 class PT_cross_join;
469 class PT_joined_table;
470 
472  public:
474 
475  /**
476  Lets us build a parse tree top-down, which is necessary due to the
477  context-dependent nature of the join syntax. This function adds
478  the `<table_ref>` cross join as the left-most leaf in this join tree
479  rooted at this node.
480 
481  @todo: comment on non-join PT_table_reference objects
482 
483  @param cj This `<table ref>` will be added if it represents a cross join.
484 
485  @return The new top-level join.
486  */
488 };
489 
492 
495  const char *const opt_table_alias;
497 
498  public:
500  List<String> *opt_use_partition_arg,
501  const LEX_CSTRING &opt_table_alias_arg,
502  List<Index_hint> *opt_key_definition_arg)
503  : table_ident(table_ident_arg),
504  opt_use_partition(opt_use_partition_arg),
505  opt_table_alias(opt_table_alias_arg.str),
506  opt_key_definition(opt_key_definition_arg) {}
507 
508  bool contextualize(Parse_context *pc) override {
509  if (super::contextualize(pc)) return true;
510 
511  THD *thd = pc->thd;
512  Yacc_state *yyps = &thd->m_parser_state->m_yacc;
513 
515  thd, table_ident, opt_table_alias, 0, yyps->m_lock_type,
516  yyps->m_mdl_type, opt_key_definition, opt_use_partition, nullptr, pc);
517  if (value == NULL) return true;
518  if (pc->select->add_joined_table(value)) return true;
519  return false;
520  }
521 };
522 
524  public:
525  virtual Json_table_column *get_column() = 0;
526 };
527 
530 
531  public:
534  const LEX_STRING &table_alias)
535  : m_expr(expr),
536  m_path(path),
537  m_nested_columns(nested_cols),
538  m_table_alias(table_alias) {}
539 
540  bool contextualize(Parse_context *pc) override;
541 
542  private:
547 };
548 
551 
553 
554  public:
557  : table_list(table_list) {}
558 
559  bool contextualize(Parse_context *pc) override {
561  return true;
562 
563  DBUG_ASSERT(table_list.size() >= 2);
564  value = pc->select->nest_last_join(pc->thd, table_list.size());
565  return value == NULL;
566  }
567 };
568 
571 
572  public:
573  PT_derived_table(bool lateral, PT_subquery *subquery,
574  const LEX_CSTRING &table_alias,
576 
577  bool contextualize(Parse_context *pc) override;
578 
579  private:
580  bool m_lateral;
582  const char *const m_table_alias;
583  /// List of explicitely specified column names; if empty, no list.
585 };
586 
589 
590  public:
592  : m_joined_table(joined_table) {}
593 
594  bool contextualize(Parse_context *pc) override;
595 
596  private:
598 };
599 
602 
603  protected:
608 
611 
612  public:
613  PT_joined_table(PT_table_reference *tab1_node_arg, const POS &join_pos_arg,
615  : tab1_node(tab1_node_arg),
616  join_pos(join_pos_arg),
617  m_type(type),
618  tab2_node(tab2_node_arg),
619  tr1(NULL),
620  tr2(NULL) {
621  static_assert(is_single_bit(JTT_INNER), "not a single bit");
622  static_assert(is_single_bit(JTT_STRAIGHT), "not a single bit");
623  static_assert(is_single_bit(JTT_NATURAL), "not a single bit");
624  static_assert(is_single_bit(JTT_LEFT), "not a single bit");
625  static_assert(is_single_bit(JTT_RIGHT), "not a single bit");
626 
629  type == JTT_NATURAL_RIGHT || type == JTT_LEFT ||
630  type == JTT_RIGHT);
631  }
632 
633  /**
634  Adds the cross join to this join operation. The cross join is nested as
635  the table reference on the left-hand side.
636  */
639  return this;
640  }
641 
642  /// Adds the table reference as the right-hand side of this join.
645  tab2_node = table;
646  }
647 
648  bool contextualize(Parse_context *pc) override {
649  if (super::contextualize(pc) || contextualize_tabs(pc)) return true;
650 
651  if (m_type & (JTT_LEFT | JTT_RIGHT)) {
652  if (m_type & JTT_LEFT)
654  else {
655  TABLE_LIST *inner_table = pc->select->convert_right_join();
656  if (inner_table == NULL) return true;
657  /* swap tr1 and tr2 */
658  DBUG_ASSERT(inner_table == tr1);
659  tr1 = tr2;
660  tr2 = inner_table;
661  }
662  }
663 
665 
666  if (m_type & JTT_STRAIGHT) tr2->straight = true;
667 
668  return false;
669  }
670 
671  /// This class is being inherited, it should thus be abstract.
672  ~PT_joined_table() override = 0;
673 
674  protected:
676  if (tr1 != NULL) return false; // already done
677 
679  return true;
680 
681  tr1 = tab1_node->value;
682  tr2 = tab2_node->value;
683 
684  if (tr1 == NULL || tr2 == NULL) {
685  error(pc, join_pos);
686  return true;
687  }
688  return false;
689  }
690 };
691 
693 
696 
697  public:
698  PT_cross_join(PT_table_reference *tab1_node_arg, const POS &join_pos_arg,
699  PT_joined_table_type Type_arg,
700  PT_table_reference *tab2_node_arg)
701  : PT_joined_table(tab1_node_arg, join_pos_arg, Type_arg, tab2_node_arg) {}
702 
703  bool contextualize(Parse_context *pc) override {
704  if (super::contextualize(pc)) return true;
705  value = pc->select->nest_last_join(pc->thd);
706  return value == NULL;
707  }
708 };
709 
713 
714  public:
715  PT_joined_table_on(PT_table_reference *tab1_node_arg, const POS &join_pos_arg,
717  PT_table_reference *tab2_node_arg, Item *on_arg)
718  : super(tab1_node_arg, join_pos_arg, type, tab2_node_arg), on(on_arg) {}
719 
720  bool contextualize(Parse_context *pc) override {
721  if (this->contextualize_tabs(pc)) return true;
722 
723  if (push_new_name_resolution_context(pc, this->tr1, this->tr2)) {
724  this->error(pc, this->join_pos);
725  return true;
726  }
727 
728  SELECT_LEX *sel = pc->select;
729  sel->parsing_place = CTX_ON;
730 
731  if (super::contextualize(pc) || on->itemize(pc, &on)) return true;
732  if (!on->is_bool_func()) {
733  on = make_condition(pc, on);
734  if (on == nullptr) return true;
735  }
736  DBUG_ASSERT(sel == pc->select);
737 
738  add_join_on(this->tr2, on);
739  pc->thd->lex->pop_context();
741  sel->parsing_place = CTX_NONE;
742  value = pc->select->nest_last_join(pc->thd);
743  return value == NULL;
744  }
745 };
746 
750 
751  public:
753  const POS &join_pos_arg, PT_joined_table_type type,
754  PT_table_reference *tab2_node_arg,
755  List<String> *using_fields_arg)
756  : super(tab1_node_arg, join_pos_arg, type, tab2_node_arg),
757  using_fields(using_fields_arg) {}
758 
759  /// A PT_joined_table_using without a list of columns denotes a natural join.
761  const POS &join_pos_arg, PT_joined_table_type type,
762  PT_table_reference *tab2_node_arg)
763  : PT_joined_table_using(tab1_node_arg, join_pos_arg, type, tab2_node_arg,
764  NULL) {}
765 
766  bool contextualize(Parse_context *pc) override {
767  if (super::contextualize(pc)) return true;
768 
770  value = pc->select->nest_last_join(pc->thd);
771  if (value == NULL) return true;
773 
774  return false;
775  }
776 };
777 
778 class PT_group : public Parse_tree_node {
780 
783 
784  public:
785  PT_group(PT_order_list *group_list_arg, olap_type olap_arg)
786  : group_list(group_list_arg), olap(olap_arg) {}
787 
788  bool contextualize(Parse_context *pc) override;
789 };
790 
791 class PT_order : public Parse_tree_node {
793 
795 
796  public:
797  explicit PT_order(PT_order_list *order_list_arg)
798  : order_list(order_list_arg) {}
799 
800  bool contextualize(Parse_context *pc) override;
801 };
802 
804  public:
807 
808  bool contextualize(Parse_context *pc) override final;
809 
810  virtual bool set_lock_for_tables(Parse_context *pc) = 0;
811 
812  virtual bool is_legacy_syntax() const = 0;
813 
815 
816  protected:
818  thr_lock_type lock_type = TL_IGNORE;
819  switch (m_lock_strength) {
821  lock_type = TL_WRITE;
822  break;
824  lock_type = TL_READ_WITH_SHARED_LOCKS;
825  break;
826  }
827 
828  return {lock_type, static_cast<thr_locked_row_action>(action())};
829  }
830 
831  private:
834 };
835 
837  public:
840  : PT_locking_clause(strength, action),
841  m_is_legacy_syntax(strength == Lock_strength::UPDATE &&
843 
847 
848  bool set_lock_for_tables(Parse_context *pc) override;
849 
850  bool is_legacy_syntax() const override { return m_is_legacy_syntax; }
851 
852  private:
854 };
855 
857  public:
859 
863  : PT_locking_clause(strength, action), m_tables(tables) {}
864 
865  bool set_lock_for_tables(Parse_context *pc) override;
866 
867  bool is_legacy_syntax() const override { return false; }
868 
869  private:
870  /// @todo Move this function to Table_ident?
871  void print_table_ident(const THD *thd, const Table_ident *ident, String *s) {
872  LEX_CSTRING db = ident->db;
873  LEX_CSTRING table = ident->table;
874  if (db.length > 0) {
875  append_identifier(thd, s, db.str, db.length);
876  s->append('.');
877  }
878  append_identifier(thd, s, table.str, table.length);
879  }
880 
881  bool raise_error(THD *thd, const Table_ident *name, int error) {
882  String s;
883  print_table_ident(thd, name, &s);
884  my_error(error, MYF(0), s.ptr());
885  return true;
886  }
887 
888  bool raise_error(int error) {
889  my_error(error, MYF(0));
890  return true;
891  }
892 
894 };
895 
897  public:
900  }
901 
902  bool push_back(PT_locking_clause *locking_clause) {
903  return m_locking_clauses.push_back(locking_clause);
904  }
905 
906  bool is_legacy_syntax() const {
907  return m_locking_clauses.size() == 1 &&
908  m_locking_clauses[0]->is_legacy_syntax();
909  }
910 
911  bool contextualize(Parse_context *pc) override {
912  for (auto locking_clause : m_locking_clauses)
913  if (locking_clause->contextualize(pc)) return true;
914  return false;
915  }
916 
917  private:
919 };
920 
922  public:
923  virtual bool is_union() const = 0;
924 
925  /**
926  True if this query expression can absorb an extraneous order by/limit
927  clause. The `ORDER BY`/`LIMIT` syntax is mostly consistestent, i.e. a
928  trailing clause may not refer to the tables in the `<query primary>`, with
929  one glaring exception:
930 
931  (...( SELECT ... )...) ORDER BY ...
932 
933  If the nested query expression doesn't contain `ORDER BY`, the statement
934  is interpreted as if the `ORDER BY` was absorbed by the innermost query
935  expression, i.e.:
936 
937  (...( SELECT ... ORDER BY ... )...)
938 
939  There is no rewriting of the parse tree nor AST happening here, the
940  transformation is done by the contextualizer (see
941  PT_query_expression::contextualize_order_and_limit), which interprets the
942  parse tree, and builds the AST according to this interpretation. This
943  interpretation is governed by the following rule: An `ORDER BY` can be
944  absorbed if none the nested query expressions contains an `ORDER BY` *or*
945  `LIMIT`. The rule is complex, so here are some examples for illustration:
946 
947  In these cases the `ORDER BY` *is* absorbed:
948 
949  ( SELECT * FROM t1 ) ORDER BY t1.a;
950  (( SELECT * FROM t1 )) ORDER BY t1.a;
951 
952  In these cases the ORDER BY is *not* absorbed:
953 
954  ( SELECT * FROM t1 ORDER BY 1 ) ORDER BY t1.a;
955  (( SELECT * FROM t1 ) ORDER BY 1 ) ORDER BY t1.a;
956  ( SELECT * FROM t1 LIMIT 1 ) ORDER BY t1.a;
957  (( SELECT * FROM t1 ) LIMIT 1 ) ORDER BY t1.a;
958 
959  The same happens with `LIMIT`, obviously, but the optimizer is freeer to
960  choose when to apply the limit, and there are name no resolution issues
961  involved.
962  */
963  virtual bool can_absorb_order_and_limit() const = 0;
964  virtual bool has_into_clause() const = 0;
965 };
966 
968  public:
970 };
971 
974 
976 
977  public:
978  PT_internal_variable_name_1d(LEX_CSTRING ident_arg) : ident(ident_arg) {}
979 
980  bool contextualize(Parse_context *pc) override;
981 };
982 
983 /**
984  Parse tree node class for 2-dimentional variable names (example: \@global.x)
985 */
988 
989  public:
990  const POS pos;
991 
992  private:
995 
996  public:
998  LEX_CSTRING ident2_arg)
999  : pos(pos), ident1(ident1_arg), ident2(ident2_arg) {}
1000 
1001  bool contextualize(Parse_context *pc) override;
1002 };
1003 
1006 
1008 
1009  public:
1011  : ident(ident_arg) {}
1012 
1013  bool contextualize(Parse_context *pc) override {
1014  if (super::contextualize(pc)) return true;
1015 
1016  sys_var *tmp = find_sys_var(pc->thd, ident.str, ident.length);
1017  if (!tmp) return true;
1018  if (!tmp->is_struct()) {
1019  my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), ident.str);
1020  return true;
1021  }
1022  value.var = tmp;
1023  value.base_name.str = "default";
1024  value.base_name.length = 7;
1025  return false;
1026  }
1027 };
1028 
1031 
1035 
1036  public:
1038  PT_internal_variable_name *name_arg,
1039  Item *opt_expr_arg)
1040  : pos(pos), name(name_arg), opt_expr(opt_expr_arg) {}
1041 
1042  bool contextualize(Parse_context *pc) override {
1043  if (super::contextualize(pc) || name->contextualize(pc) ||
1044  (opt_expr != NULL && opt_expr->itemize(pc, &opt_expr)))
1045  return true;
1046 
1048  /* It is a system variable. */
1049  if (set_system_variable(pc->thd, &name->value, pc->thd->lex->option_type,
1050  opt_expr))
1051  return true;
1052  } else {
1053  /*
1054  Not in trigger assigning value to new row,
1055  and option_type preceding local variable is illegal.
1056  */
1057  error(pc, pos);
1058  return true;
1059  }
1060  return false;
1061  }
1062 };
1063 
1065 
1069 
1073 
1074  public:
1076  Item *opt_expr_arg,
1077  const POS &expr_pos_arg)
1078  : name(name_arg), opt_expr(opt_expr_arg), expr_pos(expr_pos_arg) {}
1079 
1080  bool contextualize(Parse_context *pc) override;
1081 };
1082 
1086 
1089 
1090  public:
1092  Item *expr_arg)
1093  : name(name_arg), expr(expr_arg) {}
1094 
1095  bool contextualize(Parse_context *pc) override {
1096  if (super::contextualize(pc) || expr->itemize(pc, &expr)) return true;
1097 
1098  THD *thd = pc->thd;
1099  Item_func_set_user_var *item;
1100  item = new (pc->mem_root) Item_func_set_user_var(name, expr, false);
1101  if (item == NULL) return true;
1102  set_var_user *var = new (thd->mem_root) set_var_user(item);
1103  if (var == NULL) return true;
1104  thd->lex->var_list.push_back(var);
1105  return false;
1106  }
1107 };
1108 
1112 
1116 
1117  public:
1119  PT_internal_variable_name *name_arg,
1120  Item *opt_expr_arg)
1121  : type(type_arg), name(name_arg), opt_expr(opt_expr_arg) {}
1122 
1123  bool contextualize(Parse_context *pc) override {
1124  if (super::contextualize(pc) || name->contextualize(pc) ||
1125  (opt_expr != NULL && opt_expr->itemize(pc, &opt_expr)))
1126  return true;
1127 
1128  THD *thd = pc->thd;
1129  struct sys_var_with_base tmp = name->value;
1130  if (tmp.var == trg_new_row_fake_var) {
1131  error(pc, down_cast<PT_internal_variable_name_2d *>(name)->pos);
1132  return true;
1133  }
1134  /* Lookup if necessary: must be a system variable. */
1135  if (tmp.var == NULL) {
1136  if (find_sys_var_null_base(thd, &tmp)) return true;
1137  }
1138  if (set_system_variable(thd, &tmp, type, opt_expr)) return true;
1139  return false;
1140  }
1141 };
1142 
1146 
1148 
1149  public:
1151  : opt_charset(opt_charset_arg) {}
1152 
1153  bool contextualize(Parse_context *pc) override;
1154 };
1155 
1159 
1161 
1162  public:
1164 
1165  bool contextualize(Parse_context *pc) override;
1166 };
1167 
1170 
1173 
1174  public:
1175  PT_set_names(const CHARSET_INFO *opt_charset_arg,
1176  const CHARSET_INFO *opt_collation_arg)
1177  : opt_charset(opt_charset_arg), opt_collation(opt_collation_arg) {}
1178 
1179  bool contextualize(Parse_context *pc) override;
1180 };
1181 
1183 
1185  : public PT_start_option_value_list {
1187 
1188  const char *password;
1189  const char *current_password;
1193 
1194  public:
1196  const char *current_password_arg,
1197  bool retain_current,
1198  bool random_password,
1199  const POS &expr_pos_arg)
1200  : password(password_arg),
1201  current_password(current_password_arg),
1202  retain_current_password(retain_current),
1203  random_password_generator(random_password),
1204  expr_pos(expr_pos_arg) {}
1205 
1206  bool contextualize(Parse_context *pc) override;
1207 };
1208 
1210  : public PT_start_option_value_list {
1212 
1214  const char *password;
1215  const char *current_password;
1219 
1220  public:
1222  const char *password_arg,
1223  const char *current_password_arg,
1224  bool retain_current,
1225  bool random_pass,
1226  const POS &expr_pos_arg)
1227  : user(user_arg),
1228  password(password_arg),
1229  current_password(current_password_arg),
1230  retain_current_password(retain_current),
1231  random_password_generator(random_pass),
1232  expr_pos(expr_pos_arg) {}
1233 
1234  bool contextualize(Parse_context *pc) override;
1235 };
1236 
1239 
1242 
1243  public:
1246  : type(type_arg), value(value_arg) {}
1247 
1248  bool contextualize(Parse_context *pc) override {
1249  pc->thd->lex->option_type = type;
1250  return super::contextualize(pc) || value->contextualize(pc);
1251  }
1252 };
1253 
1256 
1260 
1261  public:
1262  PT_option_value_list_head(const POS &delimiter_pos_arg,
1263  Parse_tree_node *value_arg,
1264  const POS &value_pos_arg)
1265  : delimiter_pos(delimiter_pos_arg),
1266  value(value_arg),
1267  value_pos(value_pos_arg) {}
1268 
1269  bool contextualize(Parse_context *pc) override {
1270  if (super::contextualize(pc)) return true;
1271 
1272  THD *thd = pc->thd;
1273 #ifndef DBUG_OFF
1274  LEX *old_lex = thd->lex;
1275 #endif // DBUG_OFF
1276 
1278  DBUG_ASSERT(thd->lex->select_lex == thd->lex->current_select());
1279  Parse_context inner_pc(pc->thd, thd->lex->select_lex);
1280 
1281  if (value->contextualize(&inner_pc)) return true;
1282 
1283  if (sp_create_assignment_instr(pc->thd, value_pos.raw.end)) return true;
1284  DBUG_ASSERT(thd->lex == old_lex &&
1285  thd->lex->current_select() == pc->select);
1286 
1287  return false;
1288  }
1289 };
1290 
1293 
1295 
1296  public:
1298  const POS &delimiter_pos_arg, Parse_tree_node *tail,
1299  const POS &tail_pos)
1300  : super(delimiter_pos_arg, tail, tail_pos), head(head_arg) {}
1301 
1302  bool contextualize(Parse_context *pc) override {
1303  return head->contextualize(pc) || super::contextualize(pc);
1304  }
1305 };
1306 
1309 
1313 
1314  public:
1316  const POS &head_pos_arg,
1317  PT_option_value_list_head *tail_arg)
1318  : head(head_arg), head_pos(head_pos_arg), tail(tail_arg) {}
1319 
1320  bool contextualize(Parse_context *pc) override {
1321  if (super::contextualize(pc) || head->contextualize(pc)) return true;
1322 
1323  if (sp_create_assignment_instr(pc->thd, head_pos.raw.end)) return true;
1324  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1325  pc->select = pc->thd->lex->select_lex;
1326 
1327  if (tail != NULL && tail->contextualize(pc)) return true;
1328 
1329  return false;
1330  }
1331 };
1332 
1335 
1336  const char *name;
1338 
1339  public:
1340  PT_transaction_characteristic(const char *name_arg, int32 value_arg)
1341  : name(name_arg), value(value_arg) {}
1342 
1343  bool contextualize(Parse_context *pc) override {
1344  if (super::contextualize(pc)) return true;
1345 
1346  THD *thd = pc->thd;
1347  LEX *lex = thd->lex;
1348  Item *item = new (pc->mem_root) Item_int(value);
1349  if (item == NULL) return true;
1350  set_var *var = new (thd->mem_root)
1351  set_var(lex->option_type, find_sys_var(thd, name), NULL_CSTR, item);
1352  if (var == NULL) return true;
1353  lex->var_list.push_back(var);
1354  return false;
1355  }
1356 };
1357 
1360 
1361  public:
1362  explicit PT_transaction_access_mode(bool is_read_only)
1363  : super("transaction_read_only", (int32)is_read_only) {}
1364 };
1365 
1368 
1369  public:
1371  : super("transaction_isolation", (int32)level) {}
1372 };
1373 
1376 
1379 
1380  public:
1382  PT_transaction_characteristic *opt_tail_arg)
1383  : head(head_arg), opt_tail(opt_tail_arg) {}
1384 
1385  bool contextualize(Parse_context *pc) override {
1386  return (super::contextualize(pc) || head->contextualize(pc) ||
1387  (opt_tail != NULL && opt_tail->contextualize(pc)));
1388  }
1389 };
1390 
1392  : public PT_start_option_value_list {
1394 
1397 
1398  public:
1400  PT_transaction_characteristics *characteristics_arg,
1401  const POS &end_pos_arg)
1402  : characteristics(characteristics_arg), end_pos(end_pos_arg) {}
1403 
1404  bool contextualize(Parse_context *pc) override {
1405  if (super::contextualize(pc)) return true;
1406 
1407  THD *thd = pc->thd;
1408  thd->lex->option_type = OPT_DEFAULT;
1409  if (characteristics->contextualize(pc)) return true;
1410 
1411  if (sp_create_assignment_instr(thd, end_pos.raw.end)) return true;
1412  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1413  pc->select = pc->thd->lex->select_lex;
1414 
1415  return false;
1416  }
1417 };
1418 
1420  : public Parse_tree_node {};
1421 
1425 
1429 
1430  public:
1432  PT_option_value_following_option_type *head_arg, const POS &head_pos_arg,
1433  PT_option_value_list_head *opt_tail_arg)
1434  : head(head_arg), head_pos(head_pos_arg), opt_tail(opt_tail_arg) {}
1435 
1436  bool contextualize(Parse_context *pc) override {
1437  if (super::contextualize(pc) || head->contextualize(pc)) return true;
1438 
1439  if (sp_create_assignment_instr(pc->thd, head_pos.raw.end)) return true;
1440  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1441  pc->select = pc->thd->lex->select_lex;
1442 
1443  if (opt_tail != NULL && opt_tail->contextualize(pc)) return true;
1444 
1445  return false;
1446  }
1447 };
1448 
1452 
1455 
1456  public:
1458  PT_transaction_characteristics *characteristics_arg,
1459  const POS &characteristics_pos_arg)
1460  : characteristics(characteristics_arg),
1461  characteristics_pos(characteristics_pos_arg) {}
1462 
1463  bool contextualize(Parse_context *pc) override {
1465  return true;
1466 
1468  return true;
1469  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1470  pc->select = pc->thd->lex->select_lex;
1471 
1472  return false;
1473  }
1474 };
1475 
1478 
1481 
1482  public:
1484  enum_var_type type_arg,
1486  : type(type_arg), list(list_arg) {}
1487 
1488  bool contextualize(Parse_context *pc) override {
1489  pc->thd->lex->option_type = type;
1490  return super::contextualize(pc) || list->contextualize(pc);
1491  }
1492 };
1493 
1494 class PT_set : public Parse_tree_node {
1496 
1499 
1500  public:
1501  PT_set(const POS &set_pos_arg, PT_start_option_value_list *list_arg)
1502  : set_pos(set_pos_arg), list(list_arg) {}
1503 
1504  bool contextualize(Parse_context *pc) override {
1505  if (super::contextualize(pc)) return true;
1506 
1507  THD *thd = pc->thd;
1508  LEX *lex = thd->lex;
1510  lex->option_type = OPT_SESSION;
1511  lex->var_list.empty();
1512  lex->autocommit = false;
1513 
1515  DBUG_ASSERT(pc->thd->lex->select_lex == pc->thd->lex->current_select());
1516  pc->select = pc->thd->lex->select_lex;
1517 
1518  return list->contextualize(pc);
1519  }
1520 };
1521 
1525 
1526  protected:
1528 
1529  public:
1530  bool contextualize(Parse_context *pc) override {
1531  if (super::contextualize(pc)) return true;
1532 
1533  LEX *lex = pc->thd->lex;
1535  if (lex->sql_command == SQLCOM_SHOW_CREATE ||
1537  my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "INTO");
1538  else
1539  error(pc, m_pos);
1540  return true;
1541  }
1542  return false;
1543  }
1544 };
1545 
1548 
1549  public:
1550  PT_into_destination_outfile(const POS &pos, const LEX_STRING &file_name_arg,
1551  const CHARSET_INFO *charset_arg,
1552  const Field_separators &field_term_arg,
1553  const Line_separators &line_term_arg)
1554  : PT_into_destination(pos), m_exchange(file_name_arg.str, false) {
1555  m_exchange.cs = charset_arg;
1556  m_exchange.field.merge_field_separators(field_term_arg);
1557  m_exchange.line.merge_line_separators(line_term_arg);
1558  }
1559 
1560  bool contextualize(Parse_context *pc) override {
1561  if (super::contextualize(pc)) return true;
1562 
1563  LEX *lex = pc->thd->lex;
1565  if (!(lex->result =
1567  return true;
1568 
1569  return false;
1570  }
1571 
1572  private:
1574 };
1575 
1578 
1579  public:
1580  PT_into_destination_dumpfile(const POS &pos, const LEX_STRING &file_name_arg)
1581  : PT_into_destination(pos), m_exchange(file_name_arg.str, true) {}
1582 
1583  bool contextualize(Parse_context *pc) override {
1584  if (super::contextualize(pc)) return true;
1585 
1586  LEX *lex = pc->thd->lex;
1587  if (!lex->is_explain()) {
1589  if (!(lex->result =
1590  new (pc->thd->mem_root) Query_result_dump(&m_exchange)))
1591  return true;
1592  }
1593  return false;
1594  }
1595 
1596  private:
1598 };
1599 
1601  public:
1603 
1604  explicit PT_select_var(const LEX_STRING &name_arg) : name(name_arg) {}
1605 
1606  virtual bool is_local() const { return false; }
1607  virtual uint get_offset() const {
1608  DBUG_ASSERT(0);
1609  return 0;
1610  }
1611 };
1612 
1615 
1617 
1618 #ifndef DBUG_OFF
1619  /*
1620  Routine to which this Item_splocal belongs. Used for checking if correct
1621  runtime context is used for variable handling.
1622  */
1624 #endif
1625 
1626  public:
1627  PT_select_sp_var(const LEX_STRING &name_arg) : super(name_arg) {}
1628 
1629  bool is_local() const override { return true; }
1630  uint get_offset() const override { return offset; }
1631 
1632  bool contextualize(Parse_context *pc) override;
1633 };
1634 
1637 
1638  public:
1640 
1642 
1643  bool contextualize(Parse_context *pc) override {
1644  if (super::contextualize(pc)) return true;
1645 
1647  PT_select_var *var;
1648  while ((var = it++)) {
1649  if (var->contextualize(pc)) return true;
1650  }
1651 
1652  LEX *const lex = pc->thd->lex;
1653  if (lex->is_explain()) return false;
1654 
1655  Query_dumpvar *dumpvar = new (pc->mem_root) Query_dumpvar();
1656  if (dumpvar == NULL) return true;
1657 
1658  dumpvar->var_list = value;
1659  lex->result = dumpvar;
1661 
1662  return false;
1663  }
1664 
1665  bool push_back(PT_select_var *var) { return value.push_back(var); }
1666 };
1667 
1668 /**
1669  Parse tree node for a single of a window extent's borders,
1670  cf. <window frame extent> in SQL 2003.
1671 */
1672 class PT_border : public Parse_tree_node {
1673  friend class Window;
1674  Item *m_value{nullptr}; ///< only relevant iff m_border_type == WBT_VALUE_*
1675  public:
1677  const bool m_date_time;
1679 
1680  ///< For unbounded border
1684  }
1685 
1686  ///< For bounded non-temporal border, e.g. 2 PRECEDING: 'value' is 2.
1689 
1690  ///< For bounded INTERVAL 2 DAYS, 'value' is 2, int_type is DAYS.
1692  : m_value(value),
1694  m_date_time(true),
1695  m_int_type(int_type) {}
1696 
1697  ///< @returns the '2' in '2 PRECEDING' or 'INTERVAL 2 DAYS PRECEDING'
1698  Item *border() const { return m_value; }
1699  /// Need such low-level access so that fix_fields updates the right pointer
1700  Item **border_ptr() { return &m_value; }
1701 
1702  /**
1703  @returns Addition operator for computation of frames, nullptr if error.
1704  @param order_expr Expression to add/substract to
1705  @param prec true if PRECEDING
1706  @param asc true if ASC
1707  @param window only used for error generation
1708  */
1709  Item *build_addop(Item_cache *order_expr, bool prec, bool asc,
1710  const Window *window);
1711 };
1712 
1713 /**
1714  Parse tree node for one or both of a window extent's borders, cf.
1715  <window frame extent> in SQL 2003.
1716 */
1717 class PT_borders : public Parse_tree_node {
1719  friend class PT_frame;
1720 
1721  public:
1722  /**
1723  Constructor.
1724 
1725  Frames of the form "frame_start no_frame_end" are translated during
1726  parsing to "BETWEEN frame_start AND CURRENT ROW". So both 'start' and
1727  'end' are non-nullptr.
1728  */
1730  m_borders[0] = start;
1731  m_borders[1] = end;
1732  }
1733 };
1734 
1735 /**
1736  Parse tree node for a window frame's exclusions, cf. the
1737  <window frame exclusion> clause in SQL 2003.
1738 */
1741 
1742  public:
1744  // enum_window_frame_exclusion exclusion() { return m_exclusion; }
1745 };
1746 
1747 /**
1748  Parse tree node for a window's frame, cf. the <window frame clause>
1749  in SQL 2003.
1750 */
1751 class PT_frame : public Parse_tree_node {
1752  public:
1754 
1757 
1759 
1760  /// If true, this is an artificial frame, not specified by the user
1761  bool m_originally_absent = false;
1762 
1764  PT_exclusion *exclusion)
1765  : m_unit(unit),
1766  m_from(from_to->m_borders[0]),
1767  m_to(from_to->m_borders[1]),
1768  m_exclusion(exclusion) {}
1769 };
1770 
1771 /**
1772  Parse tree node for a window; just a shallow wrapper for
1773  class Window, q.v.
1774 */
1775 class PT_window : public Parse_tree_node, public Window {
1777 
1778  public:
1779  PT_window(PT_order_list *partition_by, PT_order_list *order_by,
1780  PT_frame *frame)
1781  : Window(partition_by, order_by, frame) {}
1782 
1783  PT_window(PT_order_list *partition_by, PT_order_list *order_by,
1784  PT_frame *frame, Item_string *inherit)
1785  : Window(partition_by, order_by, frame, inherit) {}
1786 
1788 
1789  bool contextualize(Parse_context *pc) override;
1790 };
1791 
1792 /**
1793  Parse tree node for a list of window definitions corresponding
1794  to a <window clause> in SQL 2003.
1795 */
1799 
1800  public:
1802 
1803  bool contextualize(Parse_context *pc) override;
1804 
1805  bool push_back(PT_window *w) { return m_windows.push_back(w); }
1806 };
1807 
1809  public:
1810  virtual bool has_into_clause() const = 0;
1811  virtual bool is_union() const = 0;
1812  virtual bool can_absorb_order_and_limit() const = 0;
1813 };
1814 
1817 
1827 
1828  public:
1830  PT_hint_list *opt_hints_arg, const Query_options &options_arg,
1831  PT_item_list *item_list_arg, PT_into_destination *opt_into1_arg,
1832  const Mem_root_array_YY<PT_table_reference *> &from_clause_arg,
1833  Item *opt_where_clause_arg, PT_group *opt_group_clause_arg,
1834  Item *opt_having_clause_arg, PT_window_list *opt_window_clause_arg)
1835  : opt_hints(opt_hints_arg),
1836  options(options_arg),
1837  item_list(item_list_arg),
1838  opt_into1(opt_into1_arg),
1839  from_clause(from_clause_arg),
1840  opt_where_clause(opt_where_clause_arg),
1841  opt_group_clause(opt_group_clause_arg),
1842  opt_having_clause(opt_having_clause_arg),
1843  opt_window_clause(opt_window_clause_arg) {}
1844 
1846  const Query_options &options_arg, PT_item_list *item_list_arg,
1847  const Mem_root_array_YY<PT_table_reference *> &from_clause_arg,
1848  Item *opt_where_clause_arg)
1849  : opt_hints(NULL),
1850  options(options_arg),
1851  item_list(item_list_arg),
1852  opt_into1(NULL),
1853  from_clause(from_clause_arg),
1854  opt_where_clause(opt_where_clause_arg),
1858 
1859  explicit PT_query_specification(const Query_options &options_arg,
1860  PT_item_list *item_list_arg)
1861  : opt_hints(NULL),
1862  options(options_arg),
1863  item_list(item_list_arg),
1864  opt_into1(NULL),
1870  }
1871 
1872  bool contextualize(Parse_context *pc) override;
1873 
1874  bool has_into_clause() const override { return opt_into1 != nullptr; }
1875 
1876  bool is_union() const override { return false; }
1877 
1878  bool can_absorb_order_and_limit() const override { return true; }
1879 };
1880 
1882  public:
1885  PT_limit_clause *limit,
1886  PT_locking_clause_list *locking_clauses)
1887  : contextualized(false),
1888  m_body(body),
1889  m_order(order),
1890  m_limit(limit),
1891  m_locking_clauses(locking_clauses),
1892  m_with_clause(with_clause) {}
1893 
1895  PT_limit_clause *limit,
1896  PT_locking_clause_list *locking_clauses)
1897  : PT_query_expression(nullptr, body, order, limit, locking_clauses) {}
1898 
1901 
1902  bool contextualize(Parse_context *pc) override {
1903  if (contextualize_safe(pc, m_with_clause))
1904  return true; /* purecov: inspected */
1905 
1907  return true;
1908 
1909  if (contextualize_order_and_limit(pc)) return true;
1910 
1911  if (contextualize_safe(pc, m_locking_clauses)) return true;
1912 
1913  return false;
1914  }
1915 
1916  /// Called by the Bison parser.
1918 
1919  /// Called by the Bison parser.
1920  bool is_union() const { return m_body->is_union(); }
1921 
1922  /// Called by the Bison parser.
1923  bool has_into_clause() const { return m_body->has_into_clause(); }
1924 
1926  return !m_body->is_union() && m_order == nullptr && m_limit == nullptr;
1927  }
1928 
1929  private:
1930  /**
1931  Contextualizes the order and limit clauses, re-interpreting them according
1932  to the rules. If the `<query expression body>` can absorb the clauses,
1933  they are simply contextualized into the current SELECT_LEX. If not, we
1934  have to create the "fake" SELECT_LEX unless there is one already
1935  (SELECT_LEX_UNIT::new_union_query() is known to do this.)
1936 
1937  @see PT_query_expression::can_absorb_order_and_limit()
1938  */
1940 
1947 };
1948 
1951 
1955 
1956  public:
1958 
1959  PT_subquery(POS p, PT_query_expression *query_expression)
1960  : qe(query_expression),
1961  pos(p),
1962  select_lex(NULL),
1964 
1965  bool contextualize(Parse_context *pc) override {
1966  if (super::contextualize(pc)) return true;
1967 
1968  LEX *lex = pc->thd->lex;
1969  if (!lex->expr_allows_subselect || lex->sql_command == (int)SQLCOM_PURGE) {
1970  error(pc, pos);
1971  return true;
1972  }
1973 
1974  // Create a SELECT_LEX_UNIT and SELECT_LEX for the subquery's query
1975  // expression.
1976  SELECT_LEX *child = lex->new_query(pc->select);
1977  if (child == NULL) return true;
1978 
1979  Parse_context inner_pc(pc->thd, child);
1980 
1982 
1983  if (qe->contextualize(&inner_pc)) return true;
1984 
1985  select_lex = inner_pc.select->master_unit()->first_select();
1986 
1987  lex->pop_context();
1988  pc->select->n_child_sum_items += child->n_sum_items;
1989 
1990  /*
1991  A subquery (and all the subsequent query blocks in a UNION) can add
1992  columns to an outer query block. Reserve space for them.
1993  */
1994  for (SELECT_LEX *temp = child; temp != nullptr;
1995  temp = temp->next_select()) {
1996  pc->select->select_n_where_fields += temp->select_n_where_fields;
1997  pc->select->select_n_having_items += temp->select_n_having_items;
1998  }
1999 
2000  return false;
2001  }
2002 
2003  SELECT_LEX *value() { return select_lex; }
2004 };
2005 
2007  public:
2009  : m_query_primary(query_primary) {}
2010 
2011  bool contextualize(Parse_context *pc) override {
2014  return true;
2015  return false;
2016  }
2017 
2018  bool is_union() const override { return m_query_primary->is_union(); }
2019 
2020  bool has_into_clause() const override {
2021  return m_query_primary->has_into_clause();
2022  }
2023 
2024  bool can_absorb_order_and_limit() const override {
2026  }
2027 
2028  private:
2030 };
2031 
2033  public:
2034  PT_union(PT_query_expression *lhs, const POS &lhs_pos, bool is_distinct,
2035  PT_query_primary *rhs)
2036  : m_lhs(lhs),
2037  m_lhs_pos(lhs_pos),
2038  m_is_distinct(is_distinct),
2039  m_rhs(rhs) {}
2040 
2041  bool contextualize(Parse_context *pc) override;
2042 
2043  bool is_union() const override { return true; }
2044 
2045  bool has_into_clause() const override {
2046  return m_lhs->has_into_clause() || m_rhs->has_into_clause();
2047  }
2048 
2049  bool can_absorb_order_and_limit() const override { return false; }
2050 
2051  private:
2057 };
2058 
2061 
2062  public:
2064 
2065  bool contextualize(Parse_context *pc) override {
2066  if (super::contextualize(pc)) return true;
2067 
2068  bool result = m_qe->contextualize(pc);
2069 
2070  return result;
2071  }
2072 
2073  bool is_union() const override { return m_qe->is_union(); }
2074 
2075  bool has_into_clause() const override { return m_qe->has_into_clause(); }
2076 
2077  bool can_absorb_order_and_limit() const override {
2078  return m_qe->can_absorb_order_and_limit();
2079  }
2080 
2081  private:
2083 };
2084 
2087 
2088  public:
2089  /**
2090  @param qe The query expression.
2091  @param sql_command The type of SQL command.
2092  */
2094  : m_sql_command(sql_command), m_qe(qe), m_into(NULL) {}
2095 
2096  /**
2097  Creates a SELECT command. Only SELECT commands can have into.
2098 
2099  @param qe The query expression.
2100  @param into The trailing INTO destination.
2101  */
2103  : m_sql_command(SQLCOM_SELECT), m_qe(qe), m_into(into) {}
2104 
2106 
2107  Sql_cmd *make_cmd(THD *thd) override;
2108 
2109  private:
2113 };
2114 
2115 /**
2116  Top-level node for the DELETE statement
2117 
2118  @ingroup ptn_stmt
2119 */
2121  private:
2126  const char *const opt_table_alias;
2134 
2135  public:
2136  // single-table DELETE node constructor:
2137  PT_delete(PT_with_clause *with_clause_arg, PT_hint_list *opt_hints_arg,
2138  int opt_delete_options_arg, Table_ident *table_ident_arg,
2139  const LEX_CSTRING &opt_table_alias_arg,
2140  List<String> *opt_use_partition_arg, Item *opt_where_clause_arg,
2141  PT_order *opt_order_clause_arg, Item *opt_delete_limit_clause_arg)
2142  : m_with_clause(with_clause_arg),
2143  opt_hints(opt_hints_arg),
2144  opt_delete_options(opt_delete_options_arg),
2145  table_ident(table_ident_arg),
2146  opt_table_alias(opt_table_alias_arg.str),
2147  opt_use_partition(opt_use_partition_arg),
2148  opt_where_clause(opt_where_clause_arg),
2149  opt_order_clause(opt_order_clause_arg),
2150  opt_delete_limit_clause(opt_delete_limit_clause_arg) {
2153  }
2154 
2155  // multi-table DELETE node constructor:
2156  PT_delete(PT_with_clause *with_clause_arg, PT_hint_list *opt_hints_arg,
2157  int opt_delete_options_arg,
2158  const Mem_root_array_YY<Table_ident *> &table_list_arg,
2159  const Mem_root_array_YY<PT_table_reference *> &join_table_list_arg,
2160  Item *opt_where_clause_arg)
2161  : m_with_clause(with_clause_arg),
2162  opt_hints(opt_hints_arg),
2163  opt_delete_options(opt_delete_options_arg),
2164  table_ident(NULL),
2165  opt_table_alias(nullptr),
2166  table_list(table_list_arg),
2168  join_table_list(join_table_list_arg),
2169  opt_where_clause(opt_where_clause_arg),
2172 
2173  Sql_cmd *make_cmd(THD *thd) override;
2174 
2175  private:
2176  bool is_multitable() const {
2177  DBUG_ASSERT((table_ident != NULL) ^ (table_list.size() > 0));
2178  return table_ident == NULL;
2179  }
2180 
2181  bool add_table(Parse_context *pc, Table_ident *table);
2182 };
2183 
2184 /**
2185  Top-level node for the UPDATE statement
2186 
2187  @ingroup ptn_stmt
2188 */
2189 class PT_update : public Parse_tree_root {
2200 
2201  public:
2202  PT_update(PT_with_clause *with_clause_arg, PT_hint_list *opt_hints_arg,
2203  thr_lock_type opt_low_priority_arg, bool opt_ignore_arg,
2204  const Mem_root_array_YY<PT_table_reference *> &join_table_list_arg,
2205  PT_item_list *column_list_arg, PT_item_list *value_list_arg,
2206  Item *opt_where_clause_arg, PT_order *opt_order_clause_arg,
2207  Item *opt_limit_clause_arg)
2208  : m_with_clause(with_clause_arg),
2209  opt_hints(opt_hints_arg),
2210  opt_low_priority(opt_low_priority_arg),
2211  opt_ignore(opt_ignore_arg),
2212  join_table_list(join_table_list_arg),
2213  column_list(column_list_arg),
2214  value_list(value_list_arg),
2215  opt_where_clause(opt_where_clause_arg),
2216  opt_order_clause(opt_order_clause_arg),
2217  opt_limit_clause(opt_limit_clause_arg) {}
2218 
2219  Sql_cmd *make_cmd(THD *thd) override;
2220 };
2221 
2224 
2226 
2227  public:
2228  bool contextualize(Parse_context *pc) override;
2229 
2230  bool push_back(List<Item> *x) { return many_values.push_back(x); }
2231 
2234  return many_values;
2235  }
2236 };
2237 
2238 /**
2239  Top-level node for the INSERT statement
2240 
2241  @ingroup ptn_stmt
2242 */
2244  const bool is_replace;
2247  const bool ignore;
2255 
2256  public:
2257  PT_insert(bool is_replace_arg, PT_hint_list *opt_hints_arg,
2258  thr_lock_type lock_option_arg, bool ignore_arg,
2259  Table_ident *table_ident_arg, List<String> *opt_use_partition_arg,
2260  PT_item_list *column_list_arg,
2261  PT_insert_values_list *row_value_list_arg,
2262  PT_query_expression *insert_query_expression_arg,
2263  PT_item_list *opt_on_duplicate_column_list_arg,
2264  PT_item_list *opt_on_duplicate_value_list_arg)
2265  : is_replace(is_replace_arg),
2266  opt_hints(opt_hints_arg),
2267  lock_option(lock_option_arg),
2268  ignore(ignore_arg),
2269  table_ident(table_ident_arg),
2270  opt_use_partition(opt_use_partition_arg),
2271  column_list(column_list_arg),
2272  row_value_list(row_value_list_arg),
2273  insert_query_expression(insert_query_expression_arg),
2274  opt_on_duplicate_column_list(opt_on_duplicate_column_list_arg),
2275  opt_on_duplicate_value_list(opt_on_duplicate_value_list_arg) {
2276  // REPLACE statement can't have IGNORE flag:
2278  // REPLACE statement can't have ON DUPLICATE KEY UPDATE clause:
2280  // INSERT/REPLACE ... SELECT can't have VALUES clause:
2282  // ON DUPLICATE KEY UPDATE: column and value arrays must have same sizes:
2287  }
2288 
2289  Sql_cmd *make_cmd(THD *thd) override;
2290 
2291  private:
2292  bool has_select() const { return insert_query_expression != NULL; }
2293 };
2294 
2298 
2299  public:
2300  PT_call(sp_name *proc_name_arg, PT_item_list *opt_expr_list_arg)
2301  : proc_name(proc_name_arg), opt_expr_list(opt_expr_list_arg) {}
2302 
2303  Sql_cmd *make_cmd(THD *thd) override;
2304 };
2305 
2306 /**
2307  Top-level node for the SHUTDOWN statement
2308 
2309  @ingroup ptn_stmt
2310 */
2313 
2314  public:
2315  Sql_cmd *make_cmd(THD *) override { return &sql_cmd; }
2316 };
2317 
2318 /**
2319  Top-level node for the CREATE [OR REPLACE] SPATIAL REFERENCE SYSTEM statement.
2320 
2321  @ingroup ptn_stmt
2322 */
2324  /// The SQL command object.
2326  /// Whether OR REPLACE is specified.
2328  /// Whether IF NOT EXISTS is specified.
2330  /// SRID of the SRS to create.
2331  ///
2332  /// The range is larger than that of gis::srid_t, so it must be
2333  /// verified to be less than the uint32 maximum value.
2334  unsigned long long m_srid;
2335  /// All attributes except SRID.
2337 
2338  /// Check if a UTF-8 string contains control characters.
2339  ///
2340  /// @note This function only checks single byte control characters (U+0000 to
2341  /// U+001F, and U+007F). There are some control characters at U+0080 to U+00A0
2342  /// that are not detected by this function.
2343  ///
2344  /// @param str The string.
2345  /// @param length Length of the string.
2346  ///
2347  /// @retval false The string contains no control characters.
2348  /// @retval true The string contains at least one control character.
2349  bool contains_control_char(char *str, size_t length) {
2350  for (size_t pos = 0; pos < length; pos++) {
2351  if (std::iscntrl(str[pos])) return true;
2352  }
2353  return false;
2354  }
2355 
2356  public:
2357  PT_create_srs(unsigned long long srid,
2358  const Sql_cmd_srs_attributes &attributes, bool or_replace,
2359  bool if_not_exists)
2360  : m_or_replace(or_replace),
2361  m_if_not_exists(if_not_exists),
2362  m_srid(srid),
2363  m_attributes(attributes) {}
2364 
2365  Sql_cmd *make_cmd(THD *thd) override {
2366  // Note: This function hard-codes the maximum length of various
2367  // strings. These lengths must match those in
2368  // sql/dd/impl/tables/spatial_reference_systems.cc.
2369 
2371 
2372  if (m_srid > std::numeric_limits<gis::srid_t>::max()) {
2373  my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "SRID",
2374  m_or_replace ? "CREATE OR REPLACE SPATIAL REFERENCE SYSTEM"
2375  : "CREATE SPATIAL REFERENCE SYSTEM");
2376  return nullptr;
2377  }
2378  if (m_srid == 0) {
2379  my_error(ER_CANT_MODIFY_SRID_0, MYF(0));
2380  return nullptr;
2381  }
2382 
2383  if (m_attributes.srs_name.str == nullptr) {
2384  my_error(ER_SRS_MISSING_MANDATORY_ATTRIBUTE, MYF(0), "NAME");
2385  return nullptr;
2386  }
2387  MYSQL_LEX_STRING srs_name_utf8 = {nullptr, 0};
2388  if (thd->convert_string(&srs_name_utf8, &my_charset_utf8_bin,
2390  m_attributes.srs_name.length, thd->charset())) {
2391  /* purecov: begin inspected */
2392  my_error(ER_OOM, MYF(0));
2393  return nullptr;
2394  /* purecov: end */
2395  }
2396  if (srs_name_utf8.length == 0 || std::isspace(srs_name_utf8.str[0]) ||
2397  std::isspace(srs_name_utf8.str[srs_name_utf8.length - 1])) {
2398  my_error(ER_SRS_NAME_CANT_BE_EMPTY_OR_WHITESPACE, MYF(0));
2399  return nullptr;
2400  }
2401  if (contains_control_char(srs_name_utf8.str, srs_name_utf8.length)) {
2402  my_error(ER_SRS_INVALID_CHARACTER_IN_ATTRIBUTE, MYF(0), "NAME");
2403  return nullptr;
2404  }
2405  String srs_name_str(srs_name_utf8.str, srs_name_utf8.length,
2407  if (srs_name_str.numchars() > 80) {
2408  my_error(ER_SRS_ATTRIBUTE_STRING_TOO_LONG, MYF(0), "NAME", 80);
2409  return nullptr;
2410  }
2411 
2412  if (m_attributes.definition.str == nullptr) {
2413  my_error(ER_SRS_MISSING_MANDATORY_ATTRIBUTE, MYF(0), "DEFINITION");
2414  return nullptr;
2415  }
2416  MYSQL_LEX_STRING definition_utf8 = {nullptr, 0};
2417  if (thd->convert_string(&definition_utf8, &my_charset_utf8_bin,
2420  /* purecov: begin inspected */
2421  my_error(ER_OOM, MYF(0));
2422  return nullptr;
2423  /* purecov: end */
2424  }
2425  String definition_str(definition_utf8.str, definition_utf8.length,
2427  if (contains_control_char(definition_utf8.str, definition_utf8.length)) {
2428  my_error(ER_SRS_INVALID_CHARACTER_IN_ATTRIBUTE, MYF(0), "DEFINITION");
2429  return nullptr;
2430  }
2431  if (definition_str.numchars() > 4096) {
2432  my_error(ER_SRS_ATTRIBUTE_STRING_TOO_LONG, MYF(0), "DEFINITION", 4096);
2433  return nullptr;
2434  }
2435 
2436  MYSQL_LEX_STRING organization_utf8 = {nullptr, 0};
2437  if (m_attributes.organization.str != nullptr) {
2438  if (thd->convert_string(&organization_utf8, &my_charset_utf8_bin,
2441  thd->charset())) {
2442  /* purecov: begin inspected */
2443  my_error(ER_OOM, MYF(0));
2444  return nullptr;
2445  /* purecov: end */
2446  }
2447  if (organization_utf8.length == 0 ||
2448  std::isspace(organization_utf8.str[0]) ||
2449  std::isspace(organization_utf8.str[organization_utf8.length - 1])) {
2450  my_error(ER_SRS_ORGANIZATION_CANT_BE_EMPTY_OR_WHITESPACE, MYF(0));
2451  return nullptr;
2452  }
2453  String organization_str(organization_utf8.str, organization_utf8.length,
2455  if (contains_control_char(organization_utf8.str,
2456  organization_utf8.length)) {
2457  my_error(ER_SRS_INVALID_CHARACTER_IN_ATTRIBUTE, MYF(0), "ORGANIZATION");
2458  return nullptr;
2459  }
2460  if (organization_str.numchars() > 256) {
2461  my_error(ER_SRS_ATTRIBUTE_STRING_TOO_LONG, MYF(0), "ORGANIZATION", 256);
2462  return nullptr;
2463  }
2464 
2466  std::numeric_limits<gis::srid_t>::max()) {
2467  my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "IDENTIFIED BY",
2468  m_or_replace ? "CREATE OR REPLACE SPATIAL REFERENCE SYSTEM"
2469  : "CREATE SPATIAL REFERENCE SYSTEM");
2470  return nullptr;
2471  }
2472  }
2473 
2474  MYSQL_LEX_STRING description_utf8 = {nullptr, 0};
2475  if (m_attributes.description.str != nullptr) {
2476  if (thd->convert_string(&description_utf8, &my_charset_utf8_bin,
2479  thd->charset())) {
2480  /* purecov: begin inspected */
2481  my_error(ER_OOM, MYF(0));
2482  return nullptr;
2483  /* purecov: end */
2484  }
2485  String description_str(description_utf8.str, description_utf8.length,
2487  if (contains_control_char(description_utf8.str,
2488  description_utf8.length)) {
2489  my_error(ER_SRS_INVALID_CHARACTER_IN_ATTRIBUTE, MYF(0), "DESCRIPTION");
2490  return nullptr;
2491  }
2492  if (description_str.numchars() > 2048) {
2493  my_error(ER_SRS_ATTRIBUTE_STRING_TOO_LONG, MYF(0), "DESCRIPTION", 2048);
2494  return nullptr;
2495  }
2496  }
2497 
2498  sql_cmd.init(m_or_replace, m_if_not_exists, m_srid, srs_name_utf8,
2499  definition_utf8, organization_utf8,
2500  m_attributes.organization_coordsys_id, description_utf8);
2501  return &sql_cmd;
2502  }
2503 };
2504 
2505 /**
2506  Top-level node for the DROP SPATIAL REFERENCE SYSTEM statement.
2507 
2508  @ingroup ptn_stmt
2509 */
2511  /// The SQL command object.
2513  /// SRID of the SRS to drop.
2514  ///
2515  /// The range is larger than that of gis::srid_t, so it must be
2516  /// verified to be less than the uint32 maximum value.
2517  unsigned long long m_srid;
2518 
2519  public:
2520  PT_drop_srs(unsigned long long srid, bool if_exists)
2521  : sql_cmd(srid, if_exists), m_srid(srid) {}
2522 
2523  Sql_cmd *make_cmd(THD *thd) override {
2525 
2526  if (m_srid > std::numeric_limits<gis::srid_t>::max()) {
2527  my_error(ER_DATA_OUT_OF_RANGE, MYF(0), "SRID",
2528  "DROP SPATIAL REFERENCE SYSTEM");
2529  return nullptr;
2530  }
2531  if (m_srid == 0) {
2532  my_error(ER_CANT_MODIFY_SRID_0, MYF(0));
2533  return nullptr;
2534  }
2535 
2536  return &sql_cmd;
2537  }
2538 };
2539 
2540 /**
2541  Top-level node for the ALTER INSTANCE statement
2542 
2543  @ingroup ptn_stmt
2544 */
2547 
2548  public:
2550  enum alter_instance_action_enum alter_instance_action)
2551  : sql_cmd(alter_instance_action) {}
2552 
2553  Sql_cmd *make_cmd(THD *thd) override {
2554  thd->lex->no_write_to_binlog = false;
2555  return &sql_cmd;
2556  }
2557 };
2558 
2559 /**
2560  A template-free base class for index options that we can predeclare in
2561  sql_lex.h
2562 */
2564 
2565 /**
2566  A key part specification.
2567 
2568  This can either be a "normal" key part (a key part that points to a column),
2569  or this can be a functional key part (a key part that points to an
2570  expression).
2571 */
2574 
2575  public:
2576  /**
2577  Constructor for a functional key part.
2578 
2579  @param expression The expression to index.
2580  @param order The direction of the index.
2581  */
2582  PT_key_part_specification(Item *expression, enum_order order);
2583 
2584  /**
2585  Constructor for a "normal" key part. That is a key part that points to a
2586  column and not an expression.
2587 
2588  @param column_name The column name that this key part points to.
2589  @param order The direction of the index.
2590  @param prefix_length How many bytes or characters this key part should
2591  index, or zero if it should index the entire column.
2592  */
2593  PT_key_part_specification(const LEX_CSTRING &column_name, enum_order order,
2594  int prefix_length);
2595 
2596  /**
2597  Contextualize this key part specification. This will also call itemize on
2598  the indexed expression if this is a functional key part.
2599 
2600  @param pc The parse context
2601 
2602  @retval true on error
2603  @retval false on success
2604  */
2605  bool contextualize(Parse_context *pc) override;
2606 
2607  /**
2608  Get the indexed expression. The caller must ensure that has_expression()
2609  returns true before calling this.
2610 
2611  @returns The indexed expression
2612  */
2615  return m_expression;
2616  }
2617 
2618  /**
2619  @returns The direction of the index: ORDER_ASC, ORDER_DESC or
2620  ORDER_NOT_RELEVANT in case the user didn't explicitly specify a
2621  direction.
2622  */
2623  enum_order get_order() const { return m_order; }
2624 
2625  /**
2626  @retval true if the user explicitly specified a direction (asc/desc).
2627  @retval false if the user didn't explicitly specify a direction.
2628  */
2629  bool is_explicit() const { return get_order() != ORDER_NOT_RELEVANT; }
2630 
2631  /**
2632  @retval true if the key part contains an expression (and thus is a
2633  functional key part).
2634  @retval false if the key part doesn't contain an expression.
2635  */
2636  bool has_expression() const { return m_expression != nullptr; }
2637 
2638  /**
2639  Get the column that this key part points to. This is only valid if this
2640  key part isn't a functional index. The caller must thus check the return
2641  value of has_expression() before calling this function.
2642 
2643  @returns The column that this key part points to.
2644  */
2647  return m_column_name;
2648  }
2649 
2650  /**
2651  @returns The number of bytes that this key part should index. If the column
2652  this key part points to is a non-binary column, this is the number
2653  of characters. Returns zero if the entire column should be indexed.
2654  */
2655  int get_prefix_length() const { return m_prefix_length; }
2656 
2657  private:
2658  /**
2659  The indexed expression in case this is a functional key part. Only valid if
2660  has_expression() returns true.
2661  */
2663 
2664  /// The direction of the index.
2666 
2667  /// The name of the column that this key part indexes.
2669 
2670  /**
2671  If this is greater than zero, it represents how many bytes of the column
2672  that is indexed. Note that for non-binary columns (VARCHAR, TEXT etc), this
2673  is the number of characters.
2674  */
2676 };
2677 
2678 /**
2679  A template for options that set a single `<alter option>` value in
2680  thd->lex->key_create_info.
2681 
2682  @tparam Option_type The data type of the option.
2683  @tparam Property Pointer-to-member for the option of KEY_CREATE_INFO.
2684 */
2685 template <typename Option_type, Option_type KEY_CREATE_INFO::*Property>
2687  public:
2688  /// @param option_value The value of the option.
2690 
2693  return false;
2694  }
2695 
2696  private:
2697  Option_type m_option_value;
2698 };
2699 
2700 /**
2701  A template for options that set a single property in a KEY_CREATE_INFO, and
2702  also records if the option was explicitly set.
2703 */
2704 template <typename Option_type, Option_type KEY_CREATE_INFO::*Property,
2705  bool KEY_CREATE_INFO::*Property_is_explicit>
2707  public:
2710 
2713  pc->key_create_info->*Property_is_explicit = true;
2714  return false;
2715  }
2716 
2717  private:
2718  Option_type m_option_value;
2719 };
2720 
2728 
2729 /**
2730  The data structure (B-tree, Hash, etc) used for an index is called
2731  'index_type' in the manual. Internally, this is stored in
2732  KEY_CREATE_INFO::algorithm, while what the manual calls 'algorithm' is
2733  stored in partition_info::key_algorithm. In an `<create_index_stmt>`
2734  it's ignored. The terminology is somewhat confusing, but we stick to the
2735  manual in the parser.
2736 */
2740 
2742  public:
2744  const LEX_STRING &name_arg, PT_base_index_option *type,
2745  Table_ident *table_ident,
2751  m_keytype(type_par),
2752  m_name(name_arg),
2753  m_type(type),
2754  m_table_ident(table_ident),
2755  m_columns(cols),
2756  m_options(options),
2757  m_algo(algo),
2758  m_lock(lock) {}
2759 
2760  Sql_cmd *make_cmd(THD *thd) override;
2761 
2762  private:
2771 };
2772 
2773 /**
2774  Base class for column/constraint definitions in CREATE %TABLE
2775 
2776  @ingroup ptn_create_table_stuff
2777 */
2779 
2781 
2784 
2785  public:
2786  PT_inline_index_definition(keytype type_par, const LEX_STRING &name_arg,
2790  : m_keytype(type_par),
2791  m_name(name_arg),
2792  m_type(type),
2793  m_columns(cols),
2794  m_options(options) {}
2795 
2796  bool contextualize(Table_ddl_parse_context *pc) override;
2797 
2798  private:
2804 };
2805 
2808 
2809  public:
2810  PT_foreign_key_definition(const LEX_STRING &constraint_name,
2811  const LEX_STRING &key_name,
2813  Table_ident *referenced_table,
2814  List<Key_part_spec> *ref_list,
2815  fk_match_opt fk_match_option,
2816  fk_option fk_update_opt, fk_option fk_delete_opt)
2817  : m_constraint_name(constraint_name),
2818  m_key_name(key_name),
2819  m_columns(columns),
2820  m_referenced_table(referenced_table),
2821  m_ref_list(ref_list),
2822  m_fk_match_option(fk_match_option),
2823  m_fk_update_opt(fk_update_opt),
2824  m_fk_delete_opt(fk_delete_opt) {}
2825 
2826  bool contextualize(Table_ddl_parse_context *pc) override;
2827 
2828  private:
2837 };
2838 
2839 /**
2840  Common base class for CREATE TABLE and ALTER TABLE option nodes
2841 
2842  @ingroup ptn_create_or_alter_table_options
2843 */
2845  public:
2846  ~PT_ddl_table_option() override = 0; // Force abstract class declaration
2847 
2848  virtual bool is_rename_table() const { return false; }
2849 };
2850 
2852 
2853 /**
2854  Base class for CREATE TABLE option nodes
2855 
2856  @ingroup ptn_create_or_alter_table_options
2857 */
2860 
2861  public:
2862  ~PT_create_table_option() override = 0; // Force abstract class declaration
2863 
2865  if (super::contextualize(pc)) return true;
2867  return false;
2868  }
2869 };
2870 
2872 
2873 /**
2874  A template for options that set a single property in HA_CREATE_INFO, and
2875  also records if the option was explicitly set.
2876 */
2877 template <typename Option_type, Option_type HA_CREATE_INFO::*Property,
2878  ulong Property_flag>
2881 
2882  const Option_type value;
2883 
2884  public:
2886 
2888  if (super::contextualize(pc)) return true;
2889  pc->create_info->*Property = value;
2890  pc->create_info->used_fields |= Property_flag;
2891  return false;
2892  }
2893 };
2894 
2895 #define TYPE_AND_REF(x) decltype(x), &x
2896 
2897 /**
2898  Node for the @SQL{MAX_ROWS [=] @B{@<integer@>}} table option
2899 
2900  @ingroup ptn_create_or_alter_table_options
2901 */
2905 
2906 /**
2907  Node for the @SQL{MIN_ROWS [=] @B{@<integer@>}} table option
2908 
2909  @ingroup ptn_create_or_alter_table_options
2910 */
2914 
2915 /**
2916  Node for the @SQL{AVG_ROW_LENGTH_ROWS [=] @B{@<integer@>}} table option
2917 
2918  @ingroup ptn_create_or_alter_table_options
2919 */
2923 
2924 /**
2925  Node for the @SQL{PASSWORD [=] @B{@<string@>}} table option
2926 
2927  @ingroup ptn_create_or_alter_table_options
2928 */
2932 
2933 /**
2934  Node for the @SQL{COMMENT [=] @B{@<string@>}} table option
2935 
2936  @ingroup ptn_create_or_alter_table_options
2937 */
2941 
2942 /**
2943  Node for the @SQL{COMPRESSION [=] @B{@<string@>}} table option
2944 
2945  @ingroup ptn_create_or_alter_table_options
2946 */
2950 
2951 /**
2952  Node for the @SQL{ENGRYPTION [=] @B{@<string@>}} table option
2953 
2954  @ingroup ptn_create_or_alter_table_options
2955 */
2959 
2960 /**
2961  Node for the @SQL{AUTO_INCREMENT [=] @B{@<integer@>}} table option
2962 
2963  @ingroup ptn_create_or_alter_table_options
2964 */
2968 
2972 
2977 
2981 
2985 
2989 
2993 
2997 
2999 
3000 /**
3001  A template for options that set HA_CREATE_INFO::table_options and
3002  also records if the option was explicitly set.
3003 */
3004 template <ulong Property_flag, table_options_t Default, table_options_t Yes,
3005  table_options_t No>
3008 
3010 
3011  public:
3013  : value(value) {}
3014 
3016  if (super::contextualize(pc)) return true;
3017  pc->create_info->table_options &= ~(Yes | No);
3018  switch (value) {
3019  case Ternary_option::ON:
3020  pc->create_info->table_options |= Yes;
3021  break;
3022  case Ternary_option::OFF:
3023  pc->create_info->table_options |= No;
3024  break;
3026  break;
3027  default:
3028  DBUG_ASSERT(false);
3029  }
3030  pc->create_info->used_fields |= Property_flag;
3031  return false;
3032  }
3033 };
3034 
3035 /**
3036  Node for the @SQL{PACK_KEYS [=] @B{1|0|DEFAULT}} table option
3037 
3038  @ingroup ptn_create_or_alter_table_options
3039 
3040  PACK_KEYS | Constructor parameter
3041  ----------|----------------------
3042  1 | Ternary_option::ON
3043  0 | Ternary_option::OFF
3044  DEFAULT | Ternary_option::DEFAULT
3045 */
3047  0, // DEFAULT
3048  HA_OPTION_PACK_KEYS, // ON
3049  HA_OPTION_NO_PACK_KEYS> // OFF
3051 
3052 /**
3053  Node for the @SQL{STATS_PERSISTENT [=] @B{1|0|DEFAULT}} table option
3054 
3055  @ingroup ptn_create_or_alter_table_options
3056 
3057  STATS_PERSISTENT | Constructor parameter
3058  -----------------|----------------------
3059  1 | Ternary_option::ON
3060  0 | Ternary_option::OFF
3061  DEFAULT | Ternary_option::DEFAULT
3062 */
3064  0, // DEFAULT
3068 
3069 /**
3070  A template for options that set HA_CREATE_INFO::table_options and
3071  also records if the option was explicitly set.
3072 */
3073 template <ulong Property_flag, table_options_t Yes, table_options_t No>
3076 
3077  const bool value;
3078 
3079  public:
3081 
3083  if (super::contextualize(pc)) return true;
3084  pc->create_info->table_options &= ~(Yes | No);
3085  pc->create_info->table_options |= value ? Yes : No;
3086  pc->create_info->used_fields |= Property_flag;
3087  return false;
3088  }
3089 };
3090 
3091 /**
3092  Node for the @SQL{CHECKSUM|TABLE_CHECKSUM [=] @B{0|@<not 0@>}} table option
3093 
3094  @ingroup ptn_create_or_alter_table_options
3095 
3096  TABLE_CHECKSUM | Constructor parameter
3097  ---------------|----------------------
3098  0 | false
3099  not 0 | true
3100 */
3102  HA_OPTION_CHECKSUM, // ON
3103  HA_OPTION_NO_CHECKSUM // OFF
3104  >
3106 
3107 /**
3108  Node for the @SQL{DELAY_KEY_WRITE [=] @B{0|@<not 0@>}} table option
3109 
3110  @ingroup ptn_create_or_alter_table_options
3111 
3112  TABLE_CHECKSUM | Constructor parameter
3113  ---------------|----------------------
3114  0 | false
3115  not 0 | true
3116 */
3121 
3122 /**
3123  Node for the @SQL{ENGINE [=] @B{@<identifier@>|@<string@>}} table option
3124 
3125  @ingroup ptn_create_or_alter_table_options
3126 */
3129 
3131 
3132  public:
3133  /**
3134  @param engine Storage engine name.
3135  */
3137  : engine(engine) {}
3138 
3139  bool contextualize(Table_ddl_parse_context *pc) override;
3140 };
3141 
3142 /**
3143  Node for the @SQL{SECONDARY_ENGINE [=] @B{@<identifier@>|@<string@>|NULL}}
3144  table option.
3145 
3146  @ingroup ptn_create_or_alter_table_options
3147 */
3150 
3151  public:
3156 
3157  bool contextualize(Table_ddl_parse_context *pc) override;
3158 
3159  private:
3160  const LEX_CSTRING m_secondary_engine{nullptr, 0};
3161 };
3162 
3163 /**
3164  Node for the @SQL{STATS_AUTO_RECALC [=] @B{@<0|1|DEFAULT@>})} table option
3165 
3166  @ingroup ptn_create_or_alter_table_options
3167 */
3170 
3172 
3173  public:
3174  /**
3175  @param value
3176  STATS_AUTO_RECALC | value
3177  ------------------|----------------------
3178  1 | Ternary_option::ON
3179  0 | Ternary_option::OFF
3180  DEFAULT | Ternary_option::DEFAULT
3181  */
3183 
3184  bool contextualize(Table_ddl_parse_context *pc) override;
3185 };
3186 
3187 /**
3188  Node for the @SQL{STATS_SAMPLE_PAGES [=] @B{@<integer@>|DEFAULT}} table option
3189 
3190  @ingroup ptn_create_or_alter_table_options
3191 */
3195 
3197 
3198  public:
3199  /**
3200  Constructor for implicit number of pages
3201 
3202  @param value Nunber of pages, 1@<=N@<=65535.
3203  */
3205  DBUG_ASSERT(value != 0 && value <= 0xFFFF);
3206  }
3207  /**
3208  Constructor for the DEFAULT number of pages
3209  */
3211 
3212  bool contextualize(Table_ddl_parse_context *pc) override;
3213 };
3214 
3217 
3219 
3220  public:
3222  : tables(tables) {}
3223 
3224  bool contextualize(Table_ddl_parse_context *pc) override;
3225 };
3226 
3229 
3231 
3232  public:
3234 
3236  if (super::contextualize(pc)) return true;
3238  return false;
3239  }
3240 };
3241 
3244 
3246 
3247  public:
3249  : value(value) {
3250  DBUG_ASSERT(value != nullptr);
3251  }
3252 
3253  bool contextualize(Table_ddl_parse_context *pc) override;
3254 };
3255 
3258 
3260 
3261  public:
3263  : value(value) {
3264  DBUG_ASSERT(value != nullptr);
3265  }
3266 
3267  bool contextualize(Table_ddl_parse_context *pc) override;
3268 };
3269 
3273 
3274  public:
3275  explicit PT_check_constraint(LEX_STRING &name, Item *expr, bool is_enforced) {
3276  cc_spec.name = name;
3277  cc_spec.check_expr = expr;
3278  cc_spec.is_enforced = is_enforced;
3279  }
3281 
3283  if (super::contextualize(pc) ||
3285  return true;
3286 
3288  return true;
3289 
3291  return false;
3292  }
3293 };
3294 
3297 
3300  // Currently we ignore that constraint in the executor.
3302 
3303  const char *opt_place;
3304 
3305  public:
3308  const char *opt_place = NULL)
3312  opt_place(opt_place) {}
3313 
3314  bool contextualize(Table_ddl_parse_context *pc) override;
3315 };
3316 
3317 /**
3318  Top-level node for the CREATE %TABLE statement
3319 
3320  @ingroup ptn_create_table
3321 */
3332 
3334 
3335  public:
3336  /**
3337  @param mem_root MEM_ROOT to use for allocation
3338  @param is_temporary True if @SQL{CREATE @B{TEMPORARY} %TABLE}
3339  @param only_if_not_exists True if @SQL{CREATE %TABLE ... @B{IF NOT EXISTS}}
3340  @param table_name @SQL{CREATE %TABLE ... @B{@<table name@>}}
3341  @param opt_table_element_list NULL or a list of table column and
3342  constraint definitions.
3343  @param opt_create_table_options NULL or a list of
3344  @ref ptn_create_or_alter_table_options
3345  "table options".
3346  @param opt_partitioning NULL or the @SQL{PARTITION BY} clause.
3347  @param on_duplicate DUPLICATE, IGNORE or fail with an error
3348  on data duplication errors (relevant
3349  for @SQL{CREATE TABLE ... SELECT}
3350  statements).
3351  @param opt_query_expression NULL or the @SQL{@B{SELECT}} clause.
3352  */
3369  opt_like_clause(NULL) {}
3370  /**
3371  @param mem_root MEM_ROOT to use for allocation
3372  @param is_temporary True if @SQL{CREATE @B{TEMPORARY} %TABLE}.
3373  @param only_if_not_exists True if @SQL{CREATE %TABLE ... @B{IF NOT EXISTS}}.
3374  @param table_name @SQL{CREATE %TABLE ... @B{@<table name@>}}.
3375  @param opt_like_clause NULL or the @SQL{@B{LIKE @<table name@>}} clause.
3376  */
3390 
3391  Sql_cmd *make_cmd(THD *thd) override;
3392 };
3393 
3396 
3397  public:
3398  PT_create_role(bool if_not_exists, const List<LEX_USER> *roles)
3399  : sql_cmd(if_not_exists, roles) {}
3400 
3401  Sql_cmd *make_cmd(THD *thd) override {
3403  return &sql_cmd;
3404  }
3405 };
3406 
3409 
3410  public:
3411  explicit PT_drop_role(bool ignore_errors, const List<LEX_USER> *roles)
3412  : sql_cmd(ignore_errors, roles) {}
3413 
3414  Sql_cmd *make_cmd(THD *thd) override {
3416  return &sql_cmd;
3417  }
3418 };
3419 
3422 
3423  public:
3424  explicit PT_set_role(role_enum role_type,
3425  const List<LEX_USER> *opt_except_roles = NULL)
3426  : sql_cmd(role_type, opt_except_roles) {
3427  DBUG_ASSERT(role_type == role_enum::ROLE_ALL || opt_except_roles == NULL);
3428  }
3429  explicit PT_set_role(const List<LEX_USER> *roles) : sql_cmd(roles) {}
3430 
3431  Sql_cmd *make_cmd(THD *thd) override {
3433  return &sql_cmd;
3434  }
3435 };
3436 
3437 /**
3438  This class is used for representing both static and dynamic privileges on
3439  global as well as table and column level.
3440 */
3441 struct Privilege {
3443 
3446 
3449  : type(type), columns(columns) {}
3450 };
3451 
3452 struct Static_privilege : public Privilege {
3453  const uint grant;
3454 
3456  : Privilege(STATIC, columns_arg), grant(grant) {}
3457 };
3458 
3459 struct Dynamic_privilege : public Privilege {
3461 
3463  const Mem_root_array<LEX_CSTRING> *columns_arg)
3464  : Privilege(DYNAMIC, columns_arg), ident(ident) {}
3465 };
3466 
3468  private:
3470 
3471  public:
3472  explicit PT_role_or_privilege(const POS &pos) : pos(pos) {}
3473 
3474  virtual LEX_USER *get_user(THD *thd) {
3475  thd->syntax_error_at(pos, "Illegal authorization identifier");
3476  return NULL;
3477  }
3478  virtual Privilege *get_privilege(THD *thd) {
3479  thd->syntax_error_at(pos, "Illegal privilege identifier");
3480  return NULL;
3481  }
3482 };
3483 
3487 
3488  public:
3490  const LEX_STRING &host)
3492 
3493  LEX_USER *get_user(THD *thd) override {
3494  return LEX_USER::alloc(thd, &role, &host);
3495  }
3496 };
3497 
3500 
3501  public:
3504 
3505  LEX_USER *get_user(THD *thd) override {
3506  return LEX_USER::alloc(thd, &ident, NULL);
3507  }
3508 
3509  Privilege *get_privilege(THD *thd) override {
3510  return new (thd->mem_root) Dynamic_privilege(ident, NULL);
3511  }
3512 };
3513 
3515  const uint grant;
3517 
3518  public:
3522 
3523  Privilege *get_privilege(THD *thd) override {
3524  return new (thd->mem_root) Static_privilege(grant, columns);
3525  }
3526 };
3527 
3530 
3531  public:
3534 
3535  Privilege *get_privilege(THD *thd) override {
3536  return new (thd->mem_root) Dynamic_privilege(ident, nullptr);
3537  }
3538 };
3539 
3543  const bool with_admin_option;
3544 
3545  public:
3547  const List<LEX_USER> *users, bool with_admin_option)
3549 
3550  Sql_cmd *make_cmd(THD *thd) override {
3552 
3553  List<LEX_USER> *role_objects = new (thd->mem_root) List<LEX_USER>;
3554  if (role_objects == NULL) return NULL; // OOM
3555  for (PT_role_or_privilege *r : *roles) {
3556  LEX_USER *user = r->get_user(thd);
3557  if (r == NULL || role_objects->push_back(user)) return NULL;
3558  }
3559 
3560  return new (thd->mem_root)
3562  }
3563 };
3564 
3568 
3569  public:
3571  const List<LEX_USER> *users)
3572  : roles(roles), users(users) {}
3573 
3574  Sql_cmd *make_cmd(THD *thd) override {
3576 
3577  List<LEX_USER> *role_objects = new (thd->mem_root) List<LEX_USER>;
3578  if (role_objects == NULL) return NULL; // OOM
3579  for (PT_role_or_privilege *r : *roles) {
3580  LEX_USER *user = r->get_user(thd);
3581  if (r == NULL || role_objects->push_back(user)) return NULL;
3582  }
3583  return new (thd->mem_root) Sql_cmd_revoke_roles(role_objects, users);
3584  }
3585 };
3586 
3589 
3590  public:
3591  PT_alter_user_default_role(bool if_exists, const List<LEX_USER> *users,
3592  const List<LEX_USER> *roles,
3593  const role_enum role_type)
3594  : sql_cmd(if_exists, users, roles, role_type) {}
3595 
3596  Sql_cmd *make_cmd(THD *thd) override {
3598  return &sql_cmd;
3599  }
3600 };
3601 
3604 
3605  public:
3606  PT_show_grants(const LEX_USER *opt_for_user,
3607  const List<LEX_USER> *opt_using_users)
3608  : sql_cmd(opt_for_user, opt_using_users) {
3609  DBUG_ASSERT(opt_using_users == NULL || opt_for_user != NULL);
3610  }
3611 
3612  Sql_cmd *make_cmd(THD *thd) override {
3614  return &sql_cmd;
3615  }
3616 };
3617 
3618 /**
3619  Base class for Parse tree nodes of SHOW FIELDS/SHOW INDEX statements.
3620 */
3622  protected:
3624 
3626  const LEX_STRING &wild, Item *where_condition)
3627  : m_sql_cmd(static_cast<enum_sql_command>(type)),
3628  m_pos(pos),
3629  m_type(type),
3630  m_table_ident(table_ident),
3631  m_wild(wild),
3632  m_where_condition(where_condition) {
3633  DBUG_ASSERT(wild.str == nullptr || where_condition == nullptr);
3634  }
3635 
3636  public:
3637  Sql_cmd *make_cmd(THD *thd) override;
3638 
3639  private:
3640  // Sql_cmd for SHOW COLUMNS/SHOW INDEX statements.
3642 
3643  // Textual location of a token just parsed.
3645 
3646  // SHOW_FIELDS or SHOW_KEYS
3648 
3649  // Table used in the statement.
3651 
3652  // Wild or where clause used in the statement.
3655 };
3656 
3657 /**
3658  Parse tree node for SHOW FIELDS statement.
3659 */
3662 
3663  public:
3664  PT_show_fields(const POS &pos, Show_cmd_type show_cmd_type,
3665  Table_ident *table, const LEX_STRING &wild)
3666  : PT_show_fields_and_keys(pos, SHOW_FIELDS, table, wild, nullptr),
3667  m_show_cmd_type(show_cmd_type) {}
3668 
3669  PT_show_fields(const POS &pos, Show_cmd_type show_cmd_type,
3670  Table_ident *table_ident, Item *where_condition = nullptr)
3672  where_condition),
3673  m_show_cmd_type(show_cmd_type) {}
3674 
3675  Sql_cmd *make_cmd(THD *thd) override;
3676 
3677  private:
3679 };
3680 
3681 /**
3682  Parse tree node for SHOW INDEX statement.
3683 */
3685  public:
3686  PT_show_keys(const POS &pos, bool extended_show, Table_ident *table,
3687  Item *where_condition)
3689  where_condition),
3690  m_extended_show(extended_show) {}
3691 
3692  Sql_cmd *make_cmd(THD *thd) override;
3693 
3694  private:
3696 
3697  // Flag to indicate EXTENDED keyword usage in the statement.
3699 };
3700 
3703 
3704  protected:
3706  : flag(flag) {}
3707 
3708  public:
3710  if (super::contextualize(pc)) return true;
3711  pc->alter_info->flags |= flag;
3712  return false;
3713  }
3714 
3715  protected:
3716  /**
3717  A routine used by the parser to decide whether we are specifying a full
3718  partitioning or if only partitions to add or to reorganize.
3719 
3720  @retval true ALTER TABLE ADD/REORGANIZE PARTITION.
3721  @retval false Something else.
3722  */
3726  }
3727 
3728  public:
3730 };
3731 
3734 
3735  public:
3737  PT_field_def_base *field_def,
3738  PT_table_constraint_def *opt_column_constraint,
3739  const char *opt_place)
3740  : super(Alter_info::ALTER_ADD_COLUMN),
3741  m_column_def(field_ident, field_def, opt_column_constraint, opt_place) {
3742  }
3743 
3746  }
3747 
3748  private:
3750 };
3751 
3754 
3755  public:
3757  const Mem_root_array<PT_table_element *> *columns)
3758  : super(Alter_info::ALTER_ADD_COLUMN), m_columns(columns) {}
3759 
3761  if (super::contextualize(pc)) return true;
3762 
3763  for (auto *column : *m_columns)
3764  if (column->contextualize(pc)) return true;
3765 
3766  return false;
3767  }
3768 
3769  private:
3771 };
3772 
3775 
3776  public:
3778  : super(Alter_info::ALTER_ADD_INDEX), m_constraint(constraint) {}
3779 
3781  return super::contextualize(pc) || m_constraint->contextualize(pc);
3782  }
3783 
3784  private:
3786 };
3787 
3790 
3791  public:
3793  const LEX_STRING &new_name,
3794  PT_field_def_base *field_def,
3795  const char *opt_place)
3796  : super(Alter_info::ALTER_CHANGE_COLUMN),
3797  m_old_name(old_name),
3798  m_new_name(new_name),
3799  m_field_def(field_def),
3800  m_opt_place(opt_place) {}
3801 
3803  PT_field_def_base *field_def,
3804  const char *opt_place)
3805  : PT_alter_table_change_column(name, name, field_def, opt_place) {}
3806 
3807  bool contextualize(Table_ddl_parse_context *pc) override;
3808 
3809  private:
3813  const char *m_opt_place;
3814 };
3815 
3818 
3819  protected:
3821  Alter_info::Alter_info_flag alter_info_flag,
3822  const char *name)
3823  : super(alter_info_flag), m_alter_drop(drop_type, name) {}
3824 
3825  public:
3827  return (super::contextualize(pc) ||
3829  }
3830 
3831  private:
3833 };
3834 
3836  public:
3837  explicit PT_alter_table_drop_column(const char *name)
3838  : PT_alter_table_drop(Alter_drop::COLUMN, Alter_info::ALTER_DROP_COLUMN,
3839  name) {}
3840 };
3841 
3843  public:
3846  Alter_info::DROP_FOREIGN_KEY, name) {}
3847 };
3848 
3850  public:
3851  explicit PT_alter_table_drop_key(const char *name)
3852  : PT_alter_table_drop(Alter_drop::KEY, Alter_info::ALTER_DROP_INDEX,
3853  name) {}
3854 };
3855 
3857  public:
3859  : PT_alter_table_drop(Alter_drop::CHECK_CONSTRAINT,
3860  Alter_info::DROP_CHECK_CONSTRAINT, name) {}
3861 };
3862 
3865 
3866  public:
3867  explicit PT_alter_table_check_constraint(const char *name, bool state)
3868  : super(state ? Alter_info::ENFORCE_CHECK_CONSTRAINT
3869  : Alter_info::SUSPEND_CHECK_CONSTRAINT),
3870  cc_state(Alter_state::Type::CHECK_CONSTRAINT, name, state) {}
3871 
3873  return (super::contextualize(pc) ||
3875  }
3876 
3877  private:
3879 };
3880 
3883 
3884  public:
3885  explicit PT_alter_table_enable_keys(bool enable)
3886  : super(Alter_info::ALTER_KEYS_ONOFF), m_enable(enable) {}
3887 
3889  pc->alter_info->keys_onoff =
3891  return super::contextualize(pc);
3892  }
3893 
3894  private:
3895  bool m_enable;
3896 };
3897 
3900 
3901  public:
3902  PT_alter_table_set_default(const char *col_name, Item *opt_default_expr)
3903  : super(Alter_info::ALTER_CHANGE_COLUMN_DEFAULT),
3904  m_name(col_name),
3905  m_expr(opt_default_expr) {}
3906 
3908  if (super::contextualize(pc) || itemize_safe(pc, &m_expr)) return true;
3909  Alter_column *alter_column;
3910  if (m_expr == nullptr || m_expr->basic_const_item()) {
3911  alter_column = new (pc->mem_root) Alter_column(m_name, m_expr);
3912  } else {
3913  auto vg = new (pc->mem_root) Value_generator;
3914  if (vg == nullptr) return true; // OOM
3915  vg->expr_item = m_expr;
3916  vg->set_field_stored(true);
3917  alter_column = new (pc->mem_root) Alter_column(m_name, vg);
3918  }
3919  if (alter_column == nullptr ||
3920  pc->alter_info->alter_list.push_back(alter_column)) {
3921  return true; // OOM
3922  }
3923  return false;
3924  }
3925 
3926  private:
3927  const char *m_name;
3929 };
3930 
3933 
3934  public:
3935  PT_alter_table_index_visible(const char *name, bool visible)
3936  : super(Alter_info::ALTER_INDEX_VISIBILITY),
3937  m_alter_index_visibility(name, visible) {}
3938 
3940  return (super::contextualize(pc) ||
3943  }
3944 
3945  private:
3947 };
3948 
3951 
3952  public:
3953  explicit PT_alter_table_rename(const Table_ident *ident)
3954  : super(Alter_info::ALTER_RENAME), m_ident(ident) {}
3955 
3956  bool contextualize(Table_ddl_parse_context *pc) override;
3957 
3958  bool is_rename_table() const override { return true; }
3959 
3960  private:
3961  const Table_ident *const m_ident;
3962 };
3963 
3966 
3967  public:
3968  PT_alter_table_rename_key(const char *from, const char *to)
3969  : super(Alter_info::ALTER_RENAME_INDEX), m_rename_key(from, to) {}
3970 
3972  return super::contextualize(pc) ||
3974  }
3975 
3976  private:
3978 };
3979 
3982 
3983  public:
3984  PT_alter_table_rename_column(const char *from, const char *to)
3985  : super(Alter_info::ALTER_CHANGE_COLUMN), m_rename_column(from, to) {}
3986 
3988  return super::contextualize(pc) ||
3990  }
3991 
3992  private:
3994 };
3995 
3998 
3999  public:
4001  const CHARSET_INFO *opt_collation)
4002  : super(Alter_info::ALTER_OPTIONS),
4003  m_charset(charset),
4004  m_collation(opt_collation) {}
4005 
4006  bool contextualize(Table_ddl_parse_context *pc) override;
4007 
4008  private:
4009  const CHARSET_INFO *const m_charset;
4011 };
4012 
4015 
4016  public:
4017  PT_alter_table_force() : super(Alter_info::ALTER_RECREATE) {}
4018 };
4019 
4022 
4023  public:
4025  : super(Alter_info::ALTER_ORDER), m_order(order) {}
4026 
4028  if (super::contextualize(pc) || m_order->contextualize(pc)) return true;
4029  pc->select->order_list = m_order->value;
4030  return false;
4031  }
4032 
4033  private:
4035 };
4036 
4039 
4040  public:
4042  : super(Alter_info::ALTER_PARTITION), m_partition(partition) {}
4043 
4045  if (super::contextualize(pc) || m_partition->contextualize(pc)) return true;
4047  return false;
4048  }
4049 
4050  private:
4052 };
4053 
4056 
4057  public:
4059  : super(Alter_info::ALTER_REMOVE_PARTITIONING) {}
4060 };
4061 
4064 
4065  friend class PT_alter_table_standalone_stmt; // to access make_cmd()
4066 
4067  protected:
4069  : super(alter_info_flag) {}
4070 
4071  private:
4072  virtual Sql_cmd *make_cmd(Table_ddl_parse_context *pc) = 0;
4073 };
4074 
4075 /**
4076  Node for the @SQL{ALTER TABLE ADD PARTITION} statement
4077 
4078  @ingroup ptn_alter_table
4079 */
4082 
4083  public:
4084  explicit PT_alter_table_add_partition(bool no_write_to_binlog)
4085  : super(Alter_info::ALTER_ADD_PARTITION),
4086  m_no_write_to_binlog(no_write_to_binlog) {}
4087 
4089  if (super::contextualize(pc)) return true;
4090 
4091  LEX *const lex = pc->thd->lex;
4093  DBUG_ASSERT(lex->part_info == nullptr);
4094  lex->part_info = &m_part_info;
4095  return false;
4096  }
4097 
4099  return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
4100  }
4101 
4102  protected:
4104 
4105  private:
4107 };
4108 
4109 /**
4110  Node for the @SQL{ALTER TABLE ADD PARTITION (@<partition list@>)} statement
4111 
4112  @ingroup ptn_alter_table
4113 */
4115  : public PT_alter_table_add_partition {
4117 
4118  public:
4120  bool no_write_to_binlog,
4121  const Mem_root_array<PT_part_definition *> *def_list)
4122  : super(no_write_to_binlog), m_def_list(def_list) {}
4123 
4124  bool contextualize(Table_ddl_parse_context *pc) override;
4125 
4126  private:
4128 };
4129 
4130 /**
4131  Node for the @SQL{ALTER TABLE ADD PARTITION PARTITIONS (@<n>@)} statement
4132 
4133  @ingroup ptn_alter_table
4134 */
4136  : public PT_alter_table_add_partition {
4138 
4139  public:
4140  PT_alter_table_add_partition_num(bool no_write_to_binlog, uint num_parts)
4141  : super(no_write_to_binlog) {
4142  m_part_info.num_parts = num_parts;
4143  }
4144 };
4145 
4149 
4150  public:
4151  explicit PT_alter_table_drop_partition(const List<String> &partitions)
4152  : super(Alter_info::ALTER_DROP_PARTITION), m_partitions(partitions) {}
4153 
4155  if (super::contextualize(pc)) return true;
4156 
4159  return false;
4160  }
4161 
4163  return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
4164  }
4165 
4166  private:
4168 };
4169 
4173 
4174  public:
4176  Alter_info::Alter_info_flag alter_info_flag,
4177  const List<String> *opt_partition_list)
4178  : super(alter_info_flag), m_opt_partition_list(opt_partition_list) {}
4179 
4182  if (m_opt_partition_list == NULL)
4184  else
4186  return super::contextualize(pc);
4187  }
4188 
4189  private:
4191 };
4192 
4196 
4197  public:
4198  PT_alter_table_rebuild_partition(bool no_write_to_binlog,
4199  const List<String> *opt_partition_list)
4200  : super(Alter_info::ALTER_REBUILD_PARTITION, opt_partition_list),
4201  m_no_write_to_binlog(no_write_to_binlog) {}
4202 
4204  if (super::contextualize(pc)) return true;
4206  return false;
4207  }
4208 
4210  return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
4211  }
4212 
4213  private:
4215 };
4216 
4220 
4221  public:
4222  PT_alter_table_optimize_partition(bool no_write_to_binlog,
4223  const List<String> *opt_partition_list)
4224  : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
4225  m_no_write_to_binlog(no_write_to_binlog) {}
4226 
4228  if (super::contextualize(pc)) return true;
4230  pc->thd->lex->check_opt.init();
4231  return false;
4232  }
4233 
4235  return new (pc->mem_root)
4237  }
4238 
4239  private:
4241 };
4242 
4246 
4247  public:
4248  PT_alter_table_analyze_partition(bool no_write_to_binlog,
4249  const List<String> *opt_partition_list)
4250  : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
4251  m_no_write_to_binlog(no_write_to_binlog) {}
4252 
4254  if (super::contextualize(pc)) return true;
4256  pc->thd->lex->check_opt.init();
4257  return false;
4258  }
4259 
4261  return new (pc->mem_root)
4263  }
4264 
4265  private:
4267 };
4268 
4272 
4273  public:
4276  : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
4277  m_flags(flags),
4279 
4281  if (super::contextualize(pc)) return true;
4282 
4283  LEX *const lex = pc->thd->lex;
4284  lex->check_opt.init();
4285  lex->check_opt.flags |= m_flags;
4287  return false;
4288  }
4289 
4291  return new (pc->mem_root)
4293  }
4294 
4295  private:
4298 };
4299 
4303 
4304  public:
4305  PT_alter_table_repair_partition(bool no_write_to_binlog,
4306  const List<String> *opt_partition_list,
4308  : super(Alter_info::ALTER_ADMIN_PARTITION, opt_partition_list),
4309  m_no_write_to_binlog(no_write_to_binlog),
4310  m_flags(flags),
4312 
4314  if (super::contextualize(pc)) return true;
4315 
4316  LEX *const lex = pc->thd->lex;
4318 
4319  lex->check_opt.init();
4320  lex->check_opt.flags |= m_flags;
4322 
4323  return false;
4324  }
4325 
4327  return new (pc->mem_root)
4329  }
4330 
4331  private:
4335 };
4336 
4340 
4341  public:
4342  PT_alter_table_coalesce_partition(bool no_write_to_binlog, uint num_parts)
4343  : super(Alter_info::ALTER_COALESCE_PARTITION),
4344  m_no_write_to_binlog(no_write_to_binlog),
4345  m_num_parts(num_parts) {}
4346 
4348  if (super::contextualize(pc)) return true;
4349 
4352  return false;
4353  }
4354 
4356  return new (pc->mem_root) Sql_cmd_alter_table(pc->alter_info);
4357  }
4358 
4359  private:
4362 };
4363 
4367 
4368  public:
4370  const List<String> *opt_partition_list)
4371  : super(static_cast<Alter_info::Alter_info_flag>(
4372  Alter_info::ALTER_ADMIN_PARTITION |
4373  Alter_info::ALTER_TRUNCATE_PARTITION),
4374  opt_partition_list) {}
4375 
4377  if (super::contextualize(pc)) return true;
4378  pc->thd->lex->check_opt.init();
4379  return false;
4380  }
4381 
4383  return new (pc->mem_root)
4385  }
4386 };
438