1 /* Copyright (c) 2016, 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_PARTITIONS_INCLUDED
24 #define PARSE_TREE_PARTITIONS_INCLUDED
25 
26 #include <stddef.h>
27 #include <sys/types.h>
28 
29 #include "lex_string.h"
30 #include "my_base.h"
31 #include "my_inttypes.h"
32 #include "sql/mem_root_array.h"
33 #include "sql/parse_tree_helpers.h"
34 #include "sql/parse_tree_node_base.h"
35 #include "sql/partition_element.h"
36 #include "sql/partition_info.h"
37 
38 class Item;
39 class THD;
40 template <class T>
41 class List;
42 
43 /**
44   Parse context for partitioning-specific parse tree nodes.
45 
46   For internal use in the contextualization code.
47 
48   @ingroup ptn_partitioning
49 */
50 struct Partition_parse_context : public Parse_context,
51                                  public Parser_partition_info {
52   Partition_parse_context(THD *const thd, partition_info *part_info,
53                           partition_element *current_partition,
54                           partition_element *curr_part_elem,
55                           bool is_add_or_reorganize_partition);
56 
Partition_parse_contextPartition_parse_context57   Partition_parse_context(THD *thd_arg, partition_info *part_info_arg,
58                           bool is_add_or_reorganize_partition)
59       : Partition_parse_context(thd_arg, part_info_arg, nullptr, nullptr,
60                                 is_add_or_reorganize_partition) {}
61 
62   /**
63     True for "ALTER TABLE ADD PARTITION" and "ALTER TABLE REORGANIZE PARTITION"
64     statements, otherwise false.
65   */
66   const bool is_add_or_reorganize_partition;
67 };
68 
69 /**
70   Base class for all Partition_parse_context-dependent nodes
71 
72   @ingroup ptn_partitioning
73 */
74 typedef Parse_tree_node_tmpl<Partition_parse_context> Parse_tree_part_node;
75 
76 /**
77   Base class for all partition options
78 
79   @ingroup ptn_part_options
80 */
81 class PT_partition_option : public Parse_tree_part_node {};
82 
83 /**
84   Node for the @SQL{COMMENT [=] @<string@>} partition option
85 
86   @ingroup ptn_part_options
87 */
88 class PT_partition_comment : public PT_partition_option {
89   typedef PT_partition_option super;
90 
91   char *comment;
92 
93  public:
PT_partition_comment(char * comment)94   explicit PT_partition_comment(char *comment) : comment(comment) {}
95 
contextualize(Partition_parse_context * pc)96   bool contextualize(Partition_parse_context *pc) override {
97     if (super::contextualize(pc)) return true;
98 
99     pc->curr_part_elem->part_comment = comment;
100     return false;
101   }
102 };
103 
104 /**
105   Node for the @SQL{INDEX DIRECTORY [=] @<string@>} partition option
106 
107   @ingroup ptn_part_options
108 */
109 class PT_partition_index_directory : public PT_partition_option {
110   typedef PT_partition_option super;
111 
112   const char *index_directory;
113 
114  public:
PT_partition_index_directory(const char * index_directory)115   explicit PT_partition_index_directory(const char *index_directory)
116       : index_directory(index_directory) {}
117 
contextualize(Partition_parse_context * pc)118   bool contextualize(Partition_parse_context *pc) override {
119     if (super::contextualize(pc)) return true;
120 
121     pc->curr_part_elem->index_file_name = index_directory;
122     return false;
123   }
124 };
125 
126 /**
127   Node for the @SQL{DATA DIRECTORY [=] @<string@>} partition option
128 
129   @ingroup ptn_part_options
130 */
131 class PT_partition_data_directory : public PT_partition_option {
132   typedef PT_partition_option super;
133 
134   const char *data_directory;
135 
136  public:
PT_partition_data_directory(const char * data_directory)137   explicit PT_partition_data_directory(const char *data_directory)
138       : data_directory(data_directory) {}
139 
contextualize(Partition_parse_context * pc)140   bool contextualize(Partition_parse_context *pc) override {
141     if (super::contextualize(pc)) return true;
142 
143     pc->curr_part_elem->data_file_name = data_directory;
144     return false;
145   }
146 };
147 
148 /**
149   Node for the @SQL{MIN_ROWS [=] @<integer@>} partition option
150 
151   @ingroup ptn_part_options
152 */
153 class PT_partition_min_rows : public PT_partition_option {
154   typedef PT_partition_option super;
155 
156   ha_rows min_rows;
157 
158  public:
PT_partition_min_rows(ha_rows min_rows)159   explicit PT_partition_min_rows(ha_rows min_rows) : min_rows(min_rows) {}
160 
contextualize(Partition_parse_context * pc)161   bool contextualize(Partition_parse_context *pc) override {
162     if (super::contextualize(pc)) return true;
163 
164     pc->curr_part_elem->part_min_rows = min_rows;
165     return false;
166   }
167 };
168 
169 /**
170   Node for the @SQL{MAX_ROWS [=] @<integer@>} partition option
171 
172   @ingroup ptn_part_options
173 */
174 class PT_partition_max_rows : public PT_partition_option {
175   typedef PT_partition_option super;
176 
177   ha_rows max_rows;
178 
179  public:
PT_partition_max_rows(ha_rows max_rows)180   explicit PT_partition_max_rows(ha_rows max_rows) : max_rows(max_rows) {}
181 
contextualize(Partition_parse_context * pc)182   bool contextualize(Partition_parse_context *pc) override {
183     if (super::contextualize(pc)) return true;
184 
185     pc->curr_part_elem->part_max_rows = max_rows;
186     return false;
187   }
188 };
189 
190 /**
191   Node for the @SQL{NODEGROUP [=] @<integer@>} partition option
192 
193   @ingroup ptn_part_options
194 */
195 class PT_partition_nodegroup : public PT_partition_option {
196   typedef PT_partition_option super;
197 
198   uint16 nodegroup;
199 
200  public:
PT_partition_nodegroup(uint16 nodegroup)201   explicit PT_partition_nodegroup(uint16 nodegroup) : nodegroup(nodegroup) {}
202 
contextualize(Partition_parse_context * pc)203   bool contextualize(Partition_parse_context *pc) override {
204     if (super::contextualize(pc)) return true;
205 
206     pc->curr_part_elem->nodegroup_id = nodegroup;
207     return false;
208   }
209 };
210 
211 /**
212   Node for the @SQL{[STORAGE] ENGINE [=] @<identifier|string@>} partition option
213 
214   @ingroup ptn_part_options
215 */
216 class PT_partition_engine : public PT_partition_option {
217   typedef PT_partition_option super;
218 
219  public:
220   const LEX_CSTRING name;
221 
PT_partition_engine(const LEX_CSTRING & name)222   explicit PT_partition_engine(const LEX_CSTRING &name) : name(name) {}
223 
contextualize(Partition_parse_context * pc)224   bool contextualize(Partition_parse_context *pc) override {
225     if (super::contextualize(pc)) return true;
226 
227     return resolve_engine(pc->thd, name, false,  // partition can't be temporary
228                           false, &pc->curr_part_elem->engine_type);
229   }
230 };
231 
232 /**
233   Node for the @SQL{TABLESPACE [=] @<identifier@>} partition option
234 
235   @ingroup ptn_part_options
236 */
237 class PT_partition_tablespace : public PT_partition_option {
238   typedef PT_partition_option super;
239 
240   const char *tablespace;
241 
242  public:
PT_partition_tablespace(const char * tablespace)243   explicit PT_partition_tablespace(const char *tablespace)
244       : tablespace(tablespace) {}
245 
contextualize(Partition_parse_context * pc)246   bool contextualize(Partition_parse_context *pc) override {
247     if (super::contextualize(pc)) return true;
248 
249     pc->curr_part_elem->tablespace_name = tablespace;
250     return false;
251   }
252 };
253 
254 /**
255   Node for the @SQL{SUBRAPTITION} clause of @SQL{CREATE/ALTER TABLE}
256 
257   @ingroup ptn_partitioning
258 */
259 class PT_subpartition : public Parse_tree_part_node {
260   const POS pos;
261   const char *name;
262   const Mem_root_array<PT_partition_option *> *options;
263 
264  public:
PT_subpartition(const POS & pos,const char * name,Mem_root_array<PT_partition_option * > * options)265   PT_subpartition(const POS &pos, const char *name,
266                   Mem_root_array<PT_partition_option *> *options)
267       : pos(pos), name(name), options(options) {}
268 
269   bool contextualize(Partition_parse_context *pc) override;
270 };
271 
272 /**
273   Base class for partition value nodes: @SQL{MAX_VALUE} values or expressions
274 
275   @ingroup ptn_partitioning
276 */
277 class PT_part_value_item : public Parse_tree_part_node {};
278 
279 /**
280   Node for the @SQL{MAX_VALUE} partition value in @SQL{CREATE/ALTER TABLE}
281 
282   @ingroup ptn_partitioning
283 */
284 class PT_part_value_item_max : public PT_part_value_item {
285   typedef PT_part_value_item super;
286 
287   const POS pos;
288 
289  public:
PT_part_value_item_max(const POS & pos)290   explicit PT_part_value_item_max(const POS &pos) : pos(pos) {}
291 
292   bool contextualize(Partition_parse_context *pc) override;
293 };
294 
295 /**
296   Node for the partitioning expression in @SQL{CREATE/ALTER TABLE}
297 
298   @ingroup ptn_partitioning
299 */
300 class PT_part_value_item_expr : public PT_part_value_item {
301   typedef PT_part_value_item super;
302 
303   const POS pos;
304   Item *expr;
305 
306  public:
PT_part_value_item_expr(const POS & pos,Item * expr)307   explicit PT_part_value_item_expr(const POS &pos, Item *expr)
308       : pos(pos), expr(expr) {}
309 
310   bool contextualize(Partition_parse_context *pc) override;
311 };
312 
313 /**
314   Base class for @SQL{VALUES} partitioning clauses
315 
316   @ingroup ptn_partitioning
317 */
318 class PT_part_values : public Parse_tree_part_node {};
319 
320 /**
321   Node for a list of partitioning values in @SQL{VALUES} clauses
322 
323   @ingroup ptn_partitioning
324 */
325 class PT_part_value_item_list_paren : public PT_part_values {
326   typedef PT_part_values super;
327 
328   Mem_root_array<PT_part_value_item *> *values;
329   const POS paren_pos;
330 
331  public:
PT_part_value_item_list_paren(Mem_root_array<PT_part_value_item * > * values,const POS & paren_pos)332   explicit PT_part_value_item_list_paren(
333       Mem_root_array<PT_part_value_item *> *values, const POS &paren_pos)
334       : values(values), paren_pos(paren_pos) {}
335 
336   bool contextualize(Partition_parse_context *pc) override;
337 };
338 
339 /**
340   Node for a list of partitioning values in the @SQL{VALUES IN} clause
341 
342   @ingroup ptn_partitioning
343 */
344 class PT_part_values_in_item : public PT_part_values {
345   typedef PT_part_values super;
346 
347   const POS pos;
348   PT_part_value_item_list_paren *item;
349 
350  public:
PT_part_values_in_item(const POS & pos,PT_part_value_item_list_paren * item)351   explicit PT_part_values_in_item(const POS &pos,
352                                   PT_part_value_item_list_paren *item)
353       : pos(pos), item(item) {}
354 
355   bool contextualize(Partition_parse_context *pc) override;
356 };
357 
358 /**
359   Node for a list of partitioning values in the @SQL{VALUES IN} clause
360 
361   @ingroup ptn_partitioning
362 */
363 class PT_part_values_in_list : public PT_part_values {
364   typedef PT_part_values super;
365 
366   const POS pos;
367   Mem_root_array<PT_part_value_item_list_paren *> *list;
368 
369  public:
PT_part_values_in_list(const POS & pos,Mem_root_array<PT_part_value_item_list_paren * > * list)370   explicit PT_part_values_in_list(
371       const POS &pos, Mem_root_array<PT_part_value_item_list_paren *> *list)
372       : pos(pos), list(list) {}
373 
374   bool contextualize(Partition_parse_context *pc) override;
375 };
376 
377 /**
378   Node for the @SQL{PARTITION} clause of CREATE/ALTER TABLE
379 
380   @ingroup ptn_partitioning
381 */
382 class PT_part_definition : public Parse_tree_part_node {
383   typedef Parse_tree_part_node super;
384 
385   const POS pos;
386   const LEX_STRING name;
387   partition_type type;
388   PT_part_values *const opt_part_values;
389   const POS values_pos;
390   Mem_root_array<PT_partition_option *> *opt_part_options;
391   Mem_root_array<PT_subpartition *> *opt_sub_partitions;
392   const POS sub_partitions_pos;
393 
394  public:
PT_part_definition(const POS & pos,const LEX_STRING & name,partition_type type,PT_part_values * const opt_part_values,const POS & values_pos,Mem_root_array<PT_partition_option * > * opt_part_options,Mem_root_array<PT_subpartition * > * opt_sub_partitions,const POS & sub_partitions_pos)395   PT_part_definition(const POS &pos, const LEX_STRING &name,
396                      partition_type type, PT_part_values *const opt_part_values,
397                      const POS &values_pos,
398                      Mem_root_array<PT_partition_option *> *opt_part_options,
399                      Mem_root_array<PT_subpartition *> *opt_sub_partitions,
400                      const POS &sub_partitions_pos)
401       : pos(pos),
402         name(name),
403         type(type),
404         opt_part_values(opt_part_values),
405         values_pos(values_pos),
406         opt_part_options(opt_part_options),
407         opt_sub_partitions(opt_sub_partitions),
408         sub_partitions_pos(sub_partitions_pos) {}
409 
410   bool contextualize(Partition_parse_context *pc) override;
411 };
412 
413 /**
414   Base class for all subpartitioning clause nodes
415 
416   @ingroup ptn_partitioning
417 */
418 class PT_sub_partition : public Parse_tree_part_node {};
419 
420 /**
421   Node for the @SQL{SUBRAPTITION BY HASH} definition clause
422 
423   @ingroup ptn_partitioning
424 */
425 class PT_sub_partition_by_hash : public PT_sub_partition {
426   typedef PT_sub_partition super;
427 
428   const bool is_linear;
429   const POS hash_pos;
430   Item *hash;
431   const uint opt_num_subparts;
432 
433  public:
PT_sub_partition_by_hash(bool is_linear,const POS & hash_pos,Item * hash,uint opt_num_subparts)434   PT_sub_partition_by_hash(bool is_linear, const POS &hash_pos, Item *hash,
435                            uint opt_num_subparts)
436       : is_linear(is_linear),
437         hash_pos(hash_pos),
438         hash(hash),
439         opt_num_subparts(opt_num_subparts) {}
440 
441   bool contextualize(Partition_parse_context *pc) override;
442 };
443 
444 /**
445   Node for the @SQL{SUBRAPTITION BY KEY} definition clause
446 
447   @ingroup ptn_partitioning
448 */
449 class PT_sub_partition_by_key : public PT_sub_partition {
450   typedef PT_sub_partition super;
451 
452   const bool is_linear;
453   enum_key_algorithm key_algo;
454   List<char> *field_names;
455   const uint opt_num_subparts;
456 
457  public:
PT_sub_partition_by_key(bool is_linear,enum_key_algorithm key_algo,List<char> * field_names,const uint opt_num_subparts)458   PT_sub_partition_by_key(bool is_linear, enum_key_algorithm key_algo,
459                           List<char> *field_names, const uint opt_num_subparts)
460       : is_linear(is_linear),
461         key_algo(key_algo),
462         field_names(field_names),
463         opt_num_subparts(opt_num_subparts) {}
464 
465   bool contextualize(Partition_parse_context *pc) override;
466 };
467 
468 class PT_part_type_def : public Parse_tree_part_node {
469  protected:
470   bool set_part_field_list(Partition_parse_context *pc, List<char> *list);
471 
472   bool itemize_part_expr(Partition_parse_context *pc, const POS &pos,
473                          Item **item);
474 };
475 
476 /**
477   Node for the @SQL{PARTITION BY [LINEAR] KEY} type clause
478 
479   @ingroup ptn_partitioning
480 */
481 class PT_part_type_def_key : public PT_part_type_def {
482   typedef PT_part_type_def super;
483 
484   const bool is_linear;
485   const enum_key_algorithm key_algo;
486   List<char> *const opt_columns;
487 
488  public:
PT_part_type_def_key(bool is_linear,enum_key_algorithm key_algo,List<char> * opt_columns)489   PT_part_type_def_key(bool is_linear, enum_key_algorithm key_algo,
490                        List<char> *opt_columns)
491       : is_linear(is_linear), key_algo(key_algo), opt_columns(opt_columns) {}
492 
493   bool contextualize(Partition_parse_context *pc) override;
494 };
495 
496 /**
497   Node for the @SQL{PARTITION BY [LINEAR] HASH} type clause
498 
499   @ingroup ptn_partitioning
500 */
501 class PT_part_type_def_hash : public PT_part_type_def {
502   typedef PT_part_type_def super;
503 
504   const bool is_linear;
505   const POS expr_pos;
506   Item *expr;
507 
508  public:
PT_part_type_def_hash(bool is_linear,const POS & expr_pos,Item * expr)509   PT_part_type_def_hash(bool is_linear, const POS &expr_pos, Item *expr)
510       : is_linear(is_linear), expr_pos(expr_pos), expr(expr) {}
511 
512   bool contextualize(Partition_parse_context *pc) override;
513 };
514 
515 /**
516   Node for the @SQL{PARTITION BY RANGE (@<expression@>) } type clause
517 
518   @ingroup ptn_partitioning
519 */
520 class PT_part_type_def_range_expr : public PT_part_type_def {
521   typedef PT_part_type_def super;
522 
523   const POS expr_pos;
524   Item *expr;
525 
526  public:
PT_part_type_def_range_expr(const POS & expr_pos,Item * expr)527   PT_part_type_def_range_expr(const POS &expr_pos, Item *expr)
528       : expr_pos(expr_pos), expr(expr) {}
529 
530   bool contextualize(Partition_parse_context *pc) override;
531 };
532 
533 /**
534   Node for the @SQL{PARTITION BY RANGE COLUMNS (@<ident list@>) } type clause
535 
536   @ingroup ptn_partitioning
537 */
538 class PT_part_type_def_range_columns : public PT_part_type_def {
539   typedef PT_part_type_def super;
540 
541   List<char> *const columns;
542 
543  public:
PT_part_type_def_range_columns(List<char> * columns)544   explicit PT_part_type_def_range_columns(List<char> *columns)
545       : columns(columns) {}
546 
547   bool contextualize(Partition_parse_context *pc) override;
548 };
549 
550 /**
551   Node for the @SQL{PARTITION BY LIST (@<expression@>) } type clause
552 
553   @ingroup ptn_partitioning
554 */
555 class PT_part_type_def_list_expr : public PT_part_type_def {
556   typedef PT_part_type_def super;
557 
558   const POS expr_pos;
559   Item *expr;
560 
561  public:
PT_part_type_def_list_expr(const POS & expr_pos,Item * expr)562   PT_part_type_def_list_expr(const POS &expr_pos, Item *expr)
563       : expr_pos(expr_pos), expr(expr) {}
564 
565   bool contextualize(Partition_parse_context *pc) override;
566 };
567 
568 /**
569   Node for the @SQL{PARTITION BY LIST COLUMNS (@<ident list@>) } type clause
570 
571   @ingroup ptn_partitioning
572 */
573 class PT_part_type_def_list_columns : public PT_part_type_def {
574   typedef PT_part_type_def super;
575 
576   List<char> *const columns;
577 
578  public:
PT_part_type_def_list_columns(List<char> * columns)579   explicit PT_part_type_def_list_columns(List<char> *columns)
580       : columns(columns) {}
581 
582   bool contextualize(Partition_parse_context *pc) override;
583 };
584 
585 /**
586   Node for the @SQL{PARTITION} definition clause
587 
588   @ingroup ptn_partitioning
589 */
590 class PT_partition : public Parse_tree_node {
591   typedef Parse_tree_node super;
592 
593   PT_part_type_def *const part_type_def;
594   const uint opt_num_parts;
595   PT_sub_partition *const opt_sub_part;
596   const POS part_defs_pos;
597   Mem_root_array<PT_part_definition *> *part_defs;
598 
599  public:
600   partition_info part_info;
601 
602  public:
PT_partition(PT_part_type_def * part_type_def,uint opt_num_parts,PT_sub_partition * opt_sub_part,const POS & part_defs_pos,Mem_root_array<PT_part_definition * > * part_defs)603   PT_partition(PT_part_type_def *part_type_def, uint opt_num_parts,
604                PT_sub_partition *opt_sub_part, const POS &part_defs_pos,
605                Mem_root_array<PT_part_definition *> *part_defs)
606       : part_type_def(part_type_def),
607         opt_num_parts(opt_num_parts),
608         opt_sub_part(opt_sub_part),
609         part_defs_pos(part_defs_pos),
610         part_defs(part_defs) {}
611 
612   bool contextualize(Parse_context *pc) override;
613 };
614 
615 #endif /* PARSE_TREE_PARTITIONS_INCLUDED */
616