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