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