1 #ifndef PARTITION_INFO_INCLUDED
2 #define PARTITION_INFO_INCLUDED
3
4 /* Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License, version 2.0,
8 as published by the Free Software Foundation.
9
10 This program is also distributed with certain software (including
11 but not limited to OpenSSL) that is licensed under separate terms,
12 as designated in a particular file or component or in included license
13 documentation. The authors of MySQL hereby grant you an additional
14 permission to link the program and your derivative works with the
15 separately licensed software that they have included with MySQL.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License, version 2.0, for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
25
26 #include <stddef.h>
27 #include <sys/types.h>
28
29 #include "my_bitmap.h"
30 #include "my_inttypes.h"
31 #include "sql/lock.h" // Tablespace_hash_set
32 #include "sql/partition_element.h"
33 #include "sql/sql_bitmap.h" // Bitmap
34 #include "sql/sql_data_change.h" // enum_duplicates
35 #include "sql/sql_list.h"
36
37 class Field;
38 class Item;
39 class Partition_handler;
40 class String;
41 class THD;
42 class handler;
43 struct HA_CREATE_INFO;
44 struct TABLE;
45 struct handlerton;
46
47 #define NOT_A_PARTITION_ID UINT_MAX32
48
49 class Create_field;
50 class partition_info;
51 struct PARTITION_ITERATOR;
52 struct TABLE_LIST;
53
54 /**
55 A "Get next" function for partition iterator.
56
57
58 Depending on whether partitions or sub-partitions are iterated, the
59 function returns next subpartition id/partition number. The sequence of
60 returned numbers is not ordered and may contain duplicates.
61
62 When the end of sequence is reached, NOT_A_PARTITION_ID is returned, and
63 the iterator resets itself (so next get_next() call will start to
64 enumerate the set all over again).
65
66 @param[in,out] part_iter Partition iterator, you call only
67 "iter.get_next(&iter)"
68
69 @return Partition id
70 @retval NOT_A_PARTITION_ID if there are no more partitions.
71 @retval [sub]partition_id of the next partition
72 */
73 typedef uint32 (*partition_iter_func)(PARTITION_ITERATOR *part_iter);
74
75 /**
76 Partition set iterator. Used to enumerate a set of [sub]partitions
77 obtained in partition interval analysis (see get_partitions_in_range_iter).
78
79 For the user, the only meaningful field is get_next, which may be used as
80 follows:
81 part_iterator.get_next(&part_iterator);
82
83 Initialization is done by any of the following calls:
84 - get_partitions_in_range_iter-type function call
85 - init_single_partition_iterator()
86 - init_all_partitions_iterator()
87 Cleanup is not needed.
88 */
89
90 struct PARTITION_ITERATOR {
91 partition_iter_func get_next;
92 /*
93 Valid for "Interval mapping" in LIST partitioning: if true, let the
94 iterator also produce id of the partition that contains NULL value.
95 */
96 bool ret_null_part, ret_null_part_orig;
97 struct st_part_num_range {
98 uint32 start;
99 uint32 cur;
100 uint32 end;
101 };
102
103 struct st_field_value_range {
104 ulonglong start;
105 ulonglong cur;
106 ulonglong end;
107 };
108
109 union {
110 struct st_part_num_range part_nums;
111 struct st_field_value_range field_vals;
112 };
113 partition_info *part_info;
114 };
115
116 typedef struct {
117 longlong list_value;
118 uint32 partition_id;
119 } LIST_PART_ENTRY;
120
121 /* Some function typedefs */
122 typedef int (*get_part_id_func)(partition_info *part_info, uint32 *part_id,
123 longlong *func_value);
124 typedef int (*get_subpart_id_func)(partition_info *part_info, uint32 *part_id);
125
126 /**
127 Get an iterator for set of partitions that match given field-space interval.
128
129 Functions with this signature are used to perform "Partitioning Interval
130 Analysis". This analysis is applicable for any type of [sub]partitioning
131 by some function of a single fieldX. The idea is as follows:
132 Given an interval "const1 <=? fieldX <=? const2", find a set of partitions
133 that may contain records with value of fieldX within the given interval.
134
135 The min_val, max_val and flags parameters specify the interval.
136 The set of partitions is returned by initializing an iterator in *part_iter
137
138 @note
139 There are currently three functions of this type:
140 - get_part_iter_for_interval_via_walking
141 - get_part_iter_for_interval_cols_via_map
142 - get_part_iter_for_interval_via_mapping
143
144 @param part_info Partitioning info
145 @param is_subpart When true, act for sub partitions. When false, act
146 for partitions.
147 @param store_length_array Length of fields packed in opt_range_key format
148 @param min_val Left edge, field value in opt_range_key format
149 @param max_val Right edge, field value in opt_range_key format
150 @param min_len Length of minimum value
151 @param max_len Length of maximum value
152 @param flags Some combination of NEAR_MIN, NEAR_MAX,
153 NO_MIN_RANGE, NO_MAX_RANGE
154 @param part_iter Iterator structure to be initialized
155
156 @return Operation status
157 @retval 0 No matching partitions, iterator not initialized
158 @retval 1 Some partitions would match, iterator intialized for traversing
159 them
160 @retval -1 All partitions would match, iterator not initialized
161 */
162
163 typedef int (*get_partitions_in_range_iter)(
164 partition_info *part_info, bool is_subpart, uint32 *store_length_array,
165 uchar *min_val, uchar *max_val, uint min_len, uint max_len, uint flags,
166 PARTITION_ITERATOR *part_iter);
167 /**
168 PARTITION BY KEY ALGORITHM=N
169 Which algorithm to use for hashing the fields.
170 N = 1 - Use 5.1 hashing (numeric fields are hashed as binary)
171 N = 2 - Use 5.5 hashing (numeric fields are hashed like latin1 bytes)
172 */
173 enum class enum_key_algorithm {
174 KEY_ALGORITHM_NONE = 0,
175 KEY_ALGORITHM_51 = 1,
176 KEY_ALGORITHM_55 = 2
177 };
178
179 class Parser_partition_info {
180 public:
181 partition_info *const part_info;
182 partition_element *const current_partition; // partition
183 partition_element *const curr_part_elem; // part or sub part
184 part_elem_value *curr_list_val;
185 uint curr_list_object;
186 uint count_curr_subparts;
187
188 public:
Parser_partition_info(partition_info * const part_info,partition_element * const current_partition,partition_element * const curr_part_elem,part_elem_value * curr_list_val,uint curr_list_object)189 Parser_partition_info(partition_info *const part_info,
190 partition_element *const current_partition,
191 partition_element *const curr_part_elem,
192 part_elem_value *curr_list_val, uint curr_list_object)
193 : part_info(part_info),
194 current_partition(current_partition),
195 curr_part_elem(curr_part_elem),
196 curr_list_val(curr_list_val),
197 curr_list_object(curr_list_object),
198 count_curr_subparts(0) {}
199
200 void init_col_val(part_column_list_val *col_val, Item *item);
201 part_column_list_val *add_column_value();
202 bool add_max_value();
203 bool reorganize_into_single_field_col_val();
204 bool init_column_part();
205 bool add_column_list_value(THD *thd, Item *item);
206 };
207
208 class partition_info {
209 public:
210 /*
211 * Here comes a set of definitions needed for partitioned table handlers.
212 */
213 List<partition_element> partitions;
214 List<partition_element> temp_partitions;
215
216 List<char> part_field_list;
217 List<char> subpart_field_list;
218
219 /*
220 If there is no subpartitioning, use only this func to get partition ids.
221
222 If there is subpartitioning use this to get the partition_id which will
223 consider the subpartition as well. See the below example
224
225 A table with 3 partition and 0 subpartition then the return value will
226 lie in the range of [0, 2]
227
228 A table with 3 partition and 3 subpartition then the return value will
229 lie in the range of [0, 8(no of partition X no of sub_partition -1)].
230 */
231 get_part_id_func get_partition_id;
232
233 /* Get partition id when we don't have subpartitioning
234 OR
235 Have both partition and subpartition fields but we don't want to consider
236 the subpartitions.
237 For example:
238 A table with 3 partition and 3 subpartition then the return value will
239 lie in the range of [0, 2].
240 */
241 get_part_id_func get_part_partition_id;
242
243 /*
244 Get subpartition id when we have don't have partition fields by we do
245 have subpartition ids.
246 Mikael said that for given constant tuple
247 {subpart_field1, ..., subpart_fieldN} the subpartition id will be the
248 same in all subpartitions
249 */
250 get_subpart_id_func get_subpartition_id;
251
252 /*
253 When we have various string fields we might need some preparation
254 before and clean-up after calling the get_part_id_func's. We need
255 one such method for get_part_partition_id and one for
256 get_subpartition_id.
257 */
258 get_part_id_func get_part_partition_id_charset;
259 get_subpart_id_func get_subpartition_id_charset;
260
261 /* NULL-terminated array of fields used in partitioned expression */
262 Field **part_field_array;
263 Field **subpart_field_array;
264 Field **part_charset_field_array;
265 Field **subpart_charset_field_array;
266 /*
267 Array of all fields used in partition and subpartition expression,
268 without duplicates, NULL-terminated.
269 */
270 Field **full_part_field_array;
271 /*
272 Set of all fields used in partition and subpartition expression.
273 Required for testing of partition fields in write_set when
274 updating. We need to set all bits in read_set because the row may
275 need to be inserted in a different [sub]partition.
276 */
277 MY_BITMAP full_part_field_set;
278
279 /*
280 When we have a field that requires transformation before calling the
281 partition functions we must allocate field buffers for the field of
282 the fields in the partition function.
283 */
284 uchar **part_field_buffers;
285 uchar **subpart_field_buffers;
286 uchar **restore_part_field_ptrs;
287 uchar **restore_subpart_field_ptrs;
288
289 Item *part_expr;
290 Item *subpart_expr;
291
292 Item *item_list;
293
294 /*
295 Bitmaps of partitions used by the current query.
296 * read_partitions - partitions to be used for reading.
297 * lock_partitions - partitions that must be locked (read or write).
298 Usually read_partitions is the same set as lock_partitions, but
299 in case of UPDATE the WHERE clause can limit the read_partitions set,
300 but not neccesarily the lock_partitions set.
301 Usage pattern:
302 * Initialized in ha_partition::open().
303 * read+lock_partitions is set according to explicit PARTITION,
304 WL#5217, in open_and_lock_tables().
305 * Bits in read_partitions can be cleared in prune_partitions()
306 in the optimizing step.
307 (WL#4443 is about allowing prune_partitions() to affect lock_partitions
308 and be done before locking too).
309 * When the partition enabled handler get an external_lock call it locks
310 all partitions in lock_partitions (and remembers which partitions it
311 locked, so that it can unlock them later). In case of LOCK TABLES it will
312 lock all partitions, and keep them locked while lock_partitions can
313 change for each statement under LOCK TABLES.
314 * Freed at the same time item_list is freed.
315 */
316 MY_BITMAP read_partitions;
317 MY_BITMAP lock_partitions;
318 bool bitmaps_are_initialized;
319 // TODO: Add first_read_partition and num_read_partitions?
320
321 union {
322 longlong *range_int_array;
323 LIST_PART_ENTRY *list_array;
324 part_column_list_val *range_col_array;
325 part_column_list_val *list_col_array;
326 };
327
328 /********************************************
329 * INTERVAL ANALYSIS
330 ********************************************/
331 /*
332 Partitioning interval analysis function for partitioning, or NULL if
333 interval analysis is not supported for this kind of partitioning.
334 */
335 get_partitions_in_range_iter get_part_iter_for_interval;
336 /*
337 Partitioning interval analysis function for subpartitioning, or NULL if
338 interval analysis is not supported for this kind of partitioning.
339 */
340 get_partitions_in_range_iter get_subpart_iter_for_interval;
341
342 /********************************************
343 * INTERVAL ANALYSIS ENDS
344 ********************************************/
345
346 longlong err_value;
347
348 char *part_func_string; //!< Partition expression as string
349 char *subpart_func_string; //!< Subpartition expression as string
350
351 uint num_columns;
352
353 TABLE *table;
354 /*
355 These Key_maps are used for Partitioning to enable quick decisions
356 on whether we can derive more information about which partition to
357 scan just by looking at what index is used.
358 */
359 Key_map all_fields_in_PF, all_fields_in_PPF, all_fields_in_SPF;
360 Key_map some_fields_in_PF;
361
362 handlerton *default_engine_type;
363 partition_type part_type;
364 partition_type subpart_type;
365
366 size_t part_func_len;
367 size_t subpart_func_len;
368
369 uint num_parts;
370 uint num_subparts;
371
372 uint num_list_values;
373
374 uint num_part_fields;
375 uint num_subpart_fields;
376 uint num_full_part_fields;
377
378 uint has_null_part_id;
379 /*
380 This variable is used to calculate the partition id when using
381 LINEAR KEY/HASH. This functionality is kept in the MySQL Server
382 but mainly of use to handlers supporting partitioning.
383 */
384 uint16 linear_hash_mask;
385
386 enum_key_algorithm key_algorithm;
387
388 /* Only the number of partitions defined (uses default names and options). */
389 bool use_default_partitions;
390 bool use_default_num_partitions;
391 /* Only the number of subpartitions defined (uses default names etc.). */
392 bool use_default_subpartitions;
393 bool use_default_num_subpartitions;
394 bool default_partitions_setup;
395 bool defined_max_value;
396 bool list_of_part_fields; // KEY or COLUMNS PARTITIONING
397 bool list_of_subpart_fields; // KEY SUBPARTITIONING
398 bool linear_hash_ind; // LINEAR HASH/KEY
399 bool fixed;
400 bool is_auto_partitioned;
401 bool has_null_value;
402 bool column_list; // COLUMNS PARTITIONING, 5.5+
403 /**
404 True if pruning has been completed and can not be pruned any further,
405 even if there are subqueries or stored programs in the condition.
406
407 Some times it is needed to run prune_partitions() a second time to prune
408 read partitions after tables are locked, when subquery and
409 stored functions might have been evaluated.
410 */
411 bool is_pruning_completed;
412
partition_info()413 partition_info()
414 : get_partition_id(nullptr),
415 get_part_partition_id(nullptr),
416 get_subpartition_id(nullptr),
417 part_field_array(nullptr),
418 subpart_field_array(nullptr),
419 part_charset_field_array(nullptr),
420 subpart_charset_field_array(nullptr),
421 full_part_field_array(nullptr),
422 part_field_buffers(nullptr),
423 subpart_field_buffers(nullptr),
424 restore_part_field_ptrs(nullptr),
425 restore_subpart_field_ptrs(nullptr),
426 part_expr(nullptr),
427 subpart_expr(nullptr),
428 item_list(nullptr),
429 bitmaps_are_initialized(false),
430 list_array(nullptr),
431 err_value(0),
432 part_func_string(nullptr),
433 subpart_func_string(nullptr),
434 num_columns(0),
435 table(nullptr),
436 default_engine_type(nullptr),
437 part_type(partition_type::NONE),
438 subpart_type(partition_type::NONE),
439 part_func_len(0),
440 subpart_func_len(0),
441 num_parts(0),
442 num_subparts(0),
443 num_list_values(0),
444 num_part_fields(0),
445 num_subpart_fields(0),
446 num_full_part_fields(0),
447 has_null_part_id(0),
448 linear_hash_mask(0),
449 key_algorithm(enum_key_algorithm::KEY_ALGORITHM_NONE),
450 use_default_partitions(true),
451 use_default_num_partitions(true),
452 use_default_subpartitions(true),
453 use_default_num_subpartitions(true),
454 default_partitions_setup(false),
455 defined_max_value(false),
456 list_of_part_fields(false),
457 list_of_subpart_fields(false),
458 linear_hash_ind(false),
459 fixed(false),
460 is_auto_partitioned(false),
461 has_null_value(false),
462 column_list(false),
463 is_pruning_completed(false) {
464 partitions.empty();
465 temp_partitions.empty();
466 part_field_list.empty();
467 subpart_field_list.empty();
468 }
469
470 partition_info *get_clone(THD *thd, bool reset = false);
471 partition_info *get_full_clone(THD *thd);
472 bool set_named_partition_bitmap(const char *part_name, size_t length);
473 bool set_partition_bitmaps(TABLE_LIST *table_list);
474 bool set_read_partitions(List<String> *partition_names);
475 /* Answers the question if subpartitioning is used for a certain table */
is_sub_partitioned()476 inline bool is_sub_partitioned() const {
477 return subpart_type != partition_type::NONE;
478 }
479
480 /* Returns the total number of partitions on the leaf level */
get_tot_partitions()481 inline uint get_tot_partitions() const {
482 return num_parts * (is_sub_partitioned() ? num_subparts : 1);
483 }
484
485 bool set_up_defaults_for_partitioning(Partition_handler *part_handler,
486 HA_CREATE_INFO *info, uint start_no);
487 char *find_duplicate_field();
488 const char *find_duplicate_name();
489 bool check_engine_mix(handlerton *engine_type, bool default_engine);
490 bool check_range_constants(THD *thd);
491 bool check_list_constants(THD *thd);
492 bool check_partition_info(THD *thd, handlerton **eng_type, handler *file,
493 HA_CREATE_INFO *info,
494 bool check_partition_function);
495 void print_no_partition_found(THD *thd, TABLE *table);
496 void print_debug(const char *str, uint *);
497 Item *get_column_item(Item *item, Field *field);
498 bool fix_partition_values(part_elem_value *val, partition_element *part_elem,
499 uint part_id);
500 bool fix_column_value_functions(THD *thd, part_elem_value *val, uint part_id);
501 bool fix_parser_data(THD *thd);
502 bool set_part_expr(char *start_token, Item *item_ptr, char *end_token,
503 bool is_subpart);
504 static bool compare_column_values(const part_column_list_val *a,
505 const part_column_list_val *b);
506 bool set_up_charset_field_preps();
507 bool check_partition_field_length();
508 void set_show_version_string(String *packet);
509 partition_element *get_part_elem(const char *partition_name, uint32 *part_id);
510 void report_part_expr_error(bool use_subpart_expr);
511 bool set_used_partition(List<Item> &fields, List<Item> &values,
512 COPY_INFO &info, bool copy_default_values,
513 MY_BITMAP *used_partitions);
514 /**
515 PRUNE_NO - Unable to prune.
516 PRUNE_DEFAULTS - Partitioning field is only set to
517 DEFAULT values, only need to check
518 pruning for one row where the DEFAULTS
519 values are set.
520 PRUNE_YES - Pruning is possible, calculate the used partition set
521 by evaluate the partition_id on row by row basis.
522 */
523 enum enum_can_prune { PRUNE_NO = 0, PRUNE_DEFAULTS, PRUNE_YES };
524 bool can_prune_insert(THD *thd, enum_duplicates duplic, COPY_INFO &update,
525 List<Item> &update_fields, List<Item> &fields,
526 bool empty_values, enum_can_prune *can_prune_partitions,
527 bool *prune_needs_default_values,
528 MY_BITMAP *used_partitions);
529 bool has_same_partitioning(partition_info *new_part_info);
is_partition_used(uint part_id)530 inline bool is_partition_used(uint part_id) const {
531 return bitmap_is_set(&read_partitions, part_id);
532 }
is_partition_locked(uint part_id)533 inline bool is_partition_locked(uint part_id) const {
534 return bitmap_is_set(&lock_partitions, part_id);
535 }
num_partitions_used()536 inline uint num_partitions_used() {
537 return bitmap_bits_set(&read_partitions);
538 }
get_first_used_partition()539 inline uint get_first_used_partition() const {
540 return bitmap_get_first_set(&read_partitions);
541 }
get_next_used_partition(uint part_id)542 inline uint get_next_used_partition(uint part_id) const {
543 return bitmap_get_next_set(&read_partitions, part_id);
544 }
545 bool same_key_column_order(List<Create_field> *create_list);
546
547 /**
548 Allocate memory for one partitions bitmap and initialize it.
549
550 @param bitmap Bitmap instance to initialize.
551 @param mem_root Memory root to use for bitmap buffer allocation.
552
553 @retval true Memory allocation failure
554 @retval false Success
555 */
556 bool init_partition_bitmap(MY_BITMAP *bitmap, MEM_ROOT *mem_root);
557
558 private:
559 bool set_up_default_partitions(Partition_handler *part_handler,
560 HA_CREATE_INFO *info, uint start_no);
561 bool set_up_default_subpartitions(Partition_handler *part_handler,
562 HA_CREATE_INFO *info);
563 char *create_default_partition_names(uint num_parts, uint start_no);
564 char *create_default_subpartition_name(uint subpart_no,
565 const char *part_name);
566 bool add_named_partition(const char *part_name, size_t length);
567 bool is_fields_in_part_expr(List<Item> &fields);
568 bool is_full_part_expr_in_fields(List<Item> &fields);
569 };
570
571 uint32 get_next_partition_id_range(PARTITION_ITERATOR *part_iter);
572 bool check_partition_dirs(partition_info *part_info);
573
574 /* Initialize the iterator to return a single partition with given part_id */
575
init_single_partition_iterator(uint32 part_id,PARTITION_ITERATOR * part_iter)576 static inline void init_single_partition_iterator(
577 uint32 part_id, PARTITION_ITERATOR *part_iter) {
578 part_iter->part_nums.start = part_iter->part_nums.cur = part_id;
579 part_iter->part_nums.end = part_id + 1;
580 part_iter->ret_null_part = part_iter->ret_null_part_orig = false;
581 part_iter->get_next = get_next_partition_id_range;
582 }
583
584 /* Initialize the iterator to enumerate all partitions */
init_all_partitions_iterator(partition_info * part_info,PARTITION_ITERATOR * part_iter)585 static inline void init_all_partitions_iterator(partition_info *part_info,
586 PARTITION_ITERATOR *part_iter) {
587 part_iter->part_nums.start = part_iter->part_nums.cur = 0;
588 part_iter->part_nums.end = part_info->num_parts;
589 part_iter->ret_null_part = part_iter->ret_null_part_orig = false;
590 part_iter->get_next = get_next_partition_id_range;
591 }
592
593 bool fill_partition_tablespace_names(partition_info *part_info,
594 Tablespace_hash_set *tablespace_set);
595
596 /**
597 Check if all tablespace names specified for partitions have a valid length.
598
599 @param part_info Partition info that could be using tablespaces.
600
601 @return true One of the tablespace names specified has invalid length
602 and an error is reported.
603 @return false All the tablespace names specified for partitions have
604 a valid length.
605 */
606
607 bool validate_partition_tablespace_name_lengths(partition_info *part_info);
608
609 /**
610 Check if all tablespace names specified for partitions are valid.
611
612 Do the validation by invoking the SE specific validation function.
613
614 @param part_info Partition info that could be using tablespaces.
615 @param default_engine Table level engine.
616
617 @return true One of the tablespace names specified is invalid
618 and an error is reported.
619 @return false All the tablespace names specified for
620 partitions are valid.
621 */
622
623 bool validate_partition_tablespace_names(partition_info *part_info,
624 const handlerton *default_engine);
625
626 /**
627 Predicate which returns true if any partition or subpartition uses
628 an external data directory or external index directory.
629
630 @param pi partitioning information
631 @retval true if any partition or subpartition has an external
632 data directory or external index directory.
633 @retval false otherwise
634 */
635 bool has_external_data_or_index_dir(partition_info &pi);
636
637 #endif /* PARTITION_INFO_INCLUDED */
638