MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
partition_info.h
1 #ifndef PARTITION_INFO_INCLUDED
2 #define PARTITION_INFO_INCLUDED
3 
4 /* Copyright (c) 2006, 2013, 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 as published by
8  the Free Software Foundation; version 2 of the License.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
18 
19 #include "partition_element.h"
20 #include "sql_class.h" // enum_duplicates
21 
22 class partition_info;
23 class COPY_INFO;
24 struct TABLE_LIST;
25 
26 /* Some function typedefs */
27 typedef int (*get_part_id_func)(partition_info *part_info,
28  uint32 *part_id,
29  longlong *func_value);
30 typedef int (*get_subpart_id_func)(partition_info *part_info,
31  uint32 *part_id);
32 
34 
35 class partition_info : public Sql_alloc
36 {
37 public:
38  /*
39  * Here comes a set of definitions needed for partitioned table handlers.
40  */
41  List<partition_element> partitions;
42  List<partition_element> temp_partitions;
43 
44  List<char> part_field_list;
45  List<char> subpart_field_list;
46 
47  /*
48  If there is no subpartitioning, use only this func to get partition ids.
49  If there is subpartitioning, use the this func to get partition id when
50  you have both partition and subpartition fields.
51  */
52  get_part_id_func get_partition_id;
53 
54  /* Get partition id when we don't have subpartition fields */
55  get_part_id_func get_part_partition_id;
56 
57  /*
58  Get subpartition id when we have don't have partition fields by we do
59  have subpartition ids.
60  Mikael said that for given constant tuple
61  {subpart_field1, ..., subpart_fieldN} the subpartition id will be the
62  same in all subpartitions
63  */
64  get_subpart_id_func get_subpartition_id;
65 
66  /*
67  When we have various string fields we might need some preparation
68  before and clean-up after calling the get_part_id_func's. We need
69  one such method for get_part_partition_id and one for
70  get_subpartition_id.
71  */
72  get_part_id_func get_part_partition_id_charset;
73  get_subpart_id_func get_subpartition_id_charset;
74 
75  /* NULL-terminated array of fields used in partitioned expression */
76  Field **part_field_array;
77  Field **subpart_field_array;
78  Field **part_charset_field_array;
79  Field **subpart_charset_field_array;
80  /*
81  Array of all fields used in partition and subpartition expression,
82  without duplicates, NULL-terminated.
83  */
84  Field **full_part_field_array;
85  /*
86  Set of all fields used in partition and subpartition expression.
87  Required for testing of partition fields in write_set when
88  updating. We need to set all bits in read_set because the row may
89  need to be inserted in a different [sub]partition.
90  */
91  MY_BITMAP full_part_field_set;
92 
93  /*
94  When we have a field that requires transformation before calling the
95  partition functions we must allocate field buffers for the field of
96  the fields in the partition function.
97  */
98  uchar **part_field_buffers;
99  uchar **subpart_field_buffers;
100  uchar **restore_part_field_ptrs;
101  uchar **restore_subpart_field_ptrs;
102 
103  Item *part_expr;
104  Item *subpart_expr;
105 
106  Item *item_free_list;
107 
108  struct st_ddl_log_memory_entry *first_log_entry;
109  struct st_ddl_log_memory_entry *exec_log_entry;
110  struct st_ddl_log_memory_entry *frm_log_entry;
111 
112  /*
113  Bitmaps of partitions used by the current query.
114  * read_partitions - partitions to be used for reading.
115  * lock_partitions - partitions that must be locked (read or write).
116  Usually read_partitions is the same set as lock_partitions, but
117  in case of UPDATE the WHERE clause can limit the read_partitions set,
118  but not neccesarily the lock_partitions set.
119  Usage pattern:
120  * Initialized in ha_partition::open().
121  * read+lock_partitions is set according to explicit PARTITION,
122  WL#5217, in open_and_lock_tables().
123  * Bits in read_partitions can be cleared in prune_partitions()
124  in the optimizing step.
125  (WL#4443 is about allowing prune_partitions() to affect lock_partitions
126  and be done before locking too).
127  * When the partition enabled handler get an external_lock call it locks
128  all partitions in lock_partitions (and remembers which partitions it
129  locked, so that it can unlock them later). In case of LOCK TABLES it will
130  lock all partitions, and keep them locked while lock_partitions can
131  change for each statement under LOCK TABLES.
132  * Freed at the same time item_free_list is freed.
133  */
134  MY_BITMAP read_partitions;
135  MY_BITMAP lock_partitions;
136  bool bitmaps_are_initialized;
137 
138  union {
139  longlong *range_int_array;
140  LIST_PART_ENTRY *list_array;
141  part_column_list_val *range_col_array;
142  part_column_list_val *list_col_array;
143  };
144 
145  /********************************************
146  * INTERVAL ANALYSIS
147  ********************************************/
148  /*
149  Partitioning interval analysis function for partitioning, or NULL if
150  interval analysis is not supported for this kind of partitioning.
151  */
152  get_partitions_in_range_iter get_part_iter_for_interval;
153  /*
154  Partitioning interval analysis function for subpartitioning, or NULL if
155  interval analysis is not supported for this kind of partitioning.
156  */
157  get_partitions_in_range_iter get_subpart_iter_for_interval;
158 
159  /********************************************
160  * INTERVAL ANALYSIS ENDS
161  ********************************************/
162 
163  longlong err_value;
164  char* part_info_string;
165 
166  char *part_func_string;
167  char *subpart_func_string;
168 
169  partition_element *curr_part_elem; // part or sub part
170  partition_element *current_partition; // partition
171  part_elem_value *curr_list_val;
172  uint curr_list_object;
173  uint num_columns;
174 
175  TABLE *table;
176  /*
177  These key_map's are used for Partitioning to enable quick decisions
178  on whether we can derive more information about which partition to
179  scan just by looking at what index is used.
180  */
181  key_map all_fields_in_PF, all_fields_in_PPF, all_fields_in_SPF;
182  key_map some_fields_in_PF;
183 
184  handlerton *default_engine_type;
185  partition_type part_type;
186  partition_type subpart_type;
187 
188  uint part_info_len;
189  uint part_func_len;
190  uint subpart_func_len;
191 
192  uint num_parts;
193  uint num_subparts;
194  uint count_curr_subparts; // used during parsing
195 
196  uint num_list_values;
197 
198  uint num_part_fields;
199  uint num_subpart_fields;
200  uint num_full_part_fields;
201 
202  uint has_null_part_id;
203  /*
204  This variable is used to calculate the partition id when using
205  LINEAR KEY/HASH. This functionality is kept in the MySQL Server
206  but mainly of use to handlers supporting partitioning.
207  */
208  uint16 linear_hash_mask;
209  /*
210  PARTITION BY KEY ALGORITHM=N
211  Which algorithm to use for hashing the fields.
212  N = 1 - Use 5.1 hashing (numeric fields are hashed as binary)
213  N = 2 - Use 5.5 hashing (numeric fields are hashed like latin1 bytes)
214  */
215  enum enum_key_algorithm
216  {
217  KEY_ALGORITHM_NONE= 0,
218  KEY_ALGORITHM_51= 1,
219  KEY_ALGORITHM_55= 2
220  };
221  enum_key_algorithm key_algorithm;
222 
223  /* Only the number of partitions defined (uses default names and options). */
224  bool use_default_partitions;
225  bool use_default_num_partitions;
226  /* Only the number of subpartitions defined (uses default names etc.). */
227  bool use_default_subpartitions;
228  bool use_default_num_subpartitions;
229  bool default_partitions_setup;
230  bool defined_max_value;
231  bool list_of_part_fields; // KEY or COLUMNS PARTITIONING
232  bool list_of_subpart_fields; // KEY SUBPARTITIONING
233  bool linear_hash_ind; // LINEAR HASH/KEY
234  bool fixed;
235  bool is_auto_partitioned;
236  bool has_null_value;
237  bool column_list; // COLUMNS PARTITIONING, 5.5+
247 
249  : get_partition_id(NULL), get_part_partition_id(NULL),
250  get_subpartition_id(NULL),
251  part_field_array(NULL), subpart_field_array(NULL),
252  part_charset_field_array(NULL),
253  subpart_charset_field_array(NULL),
254  full_part_field_array(NULL),
255  part_field_buffers(NULL), subpart_field_buffers(NULL),
256  restore_part_field_ptrs(NULL), restore_subpart_field_ptrs(NULL),
257  part_expr(NULL), subpart_expr(NULL), item_free_list(NULL),
258  first_log_entry(NULL), exec_log_entry(NULL), frm_log_entry(NULL),
259  bitmaps_are_initialized(FALSE),
260  list_array(NULL), err_value(0),
261  part_info_string(NULL),
262  part_func_string(NULL), subpart_func_string(NULL),
263  curr_part_elem(NULL), current_partition(NULL),
264  curr_list_object(0), num_columns(0), table(NULL),
265  default_engine_type(NULL),
266  part_type(NOT_A_PARTITION), subpart_type(NOT_A_PARTITION),
267  part_info_len(0),
268  part_func_len(0), subpart_func_len(0),
269  num_parts(0), num_subparts(0),
270  count_curr_subparts(0),
271  num_list_values(0), num_part_fields(0), num_subpart_fields(0),
272  num_full_part_fields(0), has_null_part_id(0), linear_hash_mask(0),
273  key_algorithm(KEY_ALGORITHM_NONE),
274  use_default_partitions(TRUE), use_default_num_partitions(TRUE),
275  use_default_subpartitions(TRUE), use_default_num_subpartitions(TRUE),
276  default_partitions_setup(FALSE), defined_max_value(FALSE),
277  list_of_part_fields(FALSE), list_of_subpart_fields(FALSE),
278  linear_hash_ind(FALSE), fixed(FALSE),
279  is_auto_partitioned(FALSE),
280  has_null_value(FALSE), column_list(FALSE), is_pruning_completed(false)
281  {
282  partitions.empty();
283  temp_partitions.empty();
284  part_field_list.empty();
285  subpart_field_list.empty();
286  }
287  ~partition_info() {}
288 
289  partition_info *get_clone();
290  bool set_named_partition_bitmap(const char *part_name, uint length);
291  bool set_partition_bitmaps(TABLE_LIST *table_list);
292  /* Answers the question if subpartitioning is used for a certain table */
293  bool is_sub_partitioned()
294  {
295  return (subpart_type == NOT_A_PARTITION ? FALSE : TRUE);
296  }
297 
298  /* Returns the total number of partitions on the leaf level */
299  uint get_tot_partitions()
300  {
301  return num_parts * (is_sub_partitioned() ? num_subparts : 1);
302  }
303 
304  bool set_up_defaults_for_partitioning(handler *file, HA_CREATE_INFO *info,
305  uint start_no);
306  char *find_duplicate_field();
307  char *find_duplicate_name();
308  bool check_engine_mix(handlerton *engine_type, bool default_engine);
309  bool check_range_constants(THD *thd);
310  bool check_list_constants(THD *thd);
311  bool check_partition_info(THD *thd, handlerton **eng_type,
312  handler *file, HA_CREATE_INFO *info,
313  bool check_partition_function);
314  void print_no_partition_found(TABLE *table);
315  void print_debug(const char *str, uint*);
316  Item* get_column_item(Item *item, Field *field);
317  bool fix_partition_values(THD *thd,
318  part_elem_value *val,
319  partition_element *part_elem,
320  uint part_id);
321  bool fix_column_value_functions(THD *thd,
322  part_elem_value *val,
323  uint part_id);
324  bool fix_parser_data(THD *thd);
325  bool add_max_value();
326  void init_col_val(part_column_list_val *col_val, Item *item);
327  bool reorganize_into_single_field_col_val();
328  part_column_list_val *add_column_value();
329  bool set_part_expr(char *start_token, Item *item_ptr,
330  char *end_token, bool is_subpart);
331  static int compare_column_values(const void *a, const void *b);
332  bool set_up_charset_field_preps();
333  bool check_partition_field_length();
334  bool init_column_part();
335  bool add_column_list_value(THD *thd, Item *item);
336  void set_show_version_string(String *packet);
337  partition_element *get_part_elem(const char *partition_name,
338  char *file_name,
339  uint32 *part_id);
340  void report_part_expr_error(bool use_subpart_expr);
341  bool set_used_partition(List<Item> &fields,
342  List<Item> &values,
343  COPY_INFO &info,
344  bool copy_default_values,
345  MY_BITMAP *used_partitions);
355  enum enum_can_prune {PRUNE_NO=0, PRUNE_DEFAULTS, PRUNE_YES};
356  bool can_prune_insert(THD *thd,
357  enum_duplicates duplic,
358  COPY_INFO &update,
359  List<Item> &update_fields,
360  List<Item> &fields,
361  bool empty_values,
362  enum_can_prune *can_prune_partitions,
363  bool *prune_needs_default_values,
364  MY_BITMAP *used_partitions);
365  bool has_same_partitioning(partition_info *new_part_info);
366 private:
367  static int list_part_cmp(const void* a, const void* b);
368  bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info,
369  uint start_no);
370  bool set_up_default_subpartitions(handler *file, HA_CREATE_INFO *info);
371  char *create_default_partition_names(uint part_no, uint num_parts,
372  uint start_no);
373  char *create_default_subpartition_name(uint subpart_no,
374  const char *part_name);
375  bool prune_partition_bitmaps(TABLE_LIST *table_list);
376  bool add_named_partition(const char *part_name, uint length);
377  bool is_field_in_part_expr(List<Item> &fields);
378  bool is_full_part_expr_in_fields(List<Item> &fields);
379 };
380 
381 uint32 get_next_partition_id_range(struct st_partition_iter* part_iter);
382 bool check_partition_dirs(partition_info *part_info);
383 
384 /* Initialize the iterator to return a single partition with given part_id */
385 
386 static inline void init_single_partition_iterator(uint32 part_id,
387  PARTITION_ITERATOR *part_iter)
388 {
389  part_iter->part_nums.start= part_iter->part_nums.cur= part_id;
390  part_iter->part_nums.end= part_id+1;
391  part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
392  part_iter->get_next= get_next_partition_id_range;
393 }
394 
395 /* Initialize the iterator to enumerate all partitions */
396 static inline
397 void init_all_partitions_iterator(partition_info *part_info,
398  PARTITION_ITERATOR *part_iter)
399 {
400  part_iter->part_nums.start= part_iter->part_nums.cur= 0;
401  part_iter->part_nums.end= part_info->num_parts;
402  part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
403  part_iter->get_next= get_next_partition_id_range;
404 }
405 
406 #endif /* PARTITION_INFO_INCLUDED */