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