My Project
|
00001 #ifndef PARTITION_INFO_INCLUDED 00002 #define PARTITION_INFO_INCLUDED 00003 00004 /* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; version 2 of the License. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00018 00019 #include "partition_element.h" 00020 #include "sql_class.h" // enum_duplicates 00021 00022 class partition_info; 00023 class COPY_INFO; 00024 struct TABLE_LIST; 00025 00026 /* Some function typedefs */ 00027 typedef int (*get_part_id_func)(partition_info *part_info, 00028 uint32 *part_id, 00029 longlong *func_value); 00030 typedef int (*get_subpart_id_func)(partition_info *part_info, 00031 uint32 *part_id); 00032 00033 struct st_ddl_log_memory_entry; 00034 00035 class partition_info : public Sql_alloc 00036 { 00037 public: 00038 /* 00039 * Here comes a set of definitions needed for partitioned table handlers. 00040 */ 00041 List<partition_element> partitions; 00042 List<partition_element> temp_partitions; 00043 00044 List<char> part_field_list; 00045 List<char> subpart_field_list; 00046 00047 /* 00048 If there is no subpartitioning, use only this func to get partition ids. 00049 If there is subpartitioning, use the this func to get partition id when 00050 you have both partition and subpartition fields. 00051 */ 00052 get_part_id_func get_partition_id; 00053 00054 /* Get partition id when we don't have subpartition fields */ 00055 get_part_id_func get_part_partition_id; 00056 00057 /* 00058 Get subpartition id when we have don't have partition fields by we do 00059 have subpartition ids. 00060 Mikael said that for given constant tuple 00061 {subpart_field1, ..., subpart_fieldN} the subpartition id will be the 00062 same in all subpartitions 00063 */ 00064 get_subpart_id_func get_subpartition_id; 00065 00066 /* 00067 When we have various string fields we might need some preparation 00068 before and clean-up after calling the get_part_id_func's. We need 00069 one such method for get_part_partition_id and one for 00070 get_subpartition_id. 00071 */ 00072 get_part_id_func get_part_partition_id_charset; 00073 get_subpart_id_func get_subpartition_id_charset; 00074 00075 /* NULL-terminated array of fields used in partitioned expression */ 00076 Field **part_field_array; 00077 Field **subpart_field_array; 00078 Field **part_charset_field_array; 00079 Field **subpart_charset_field_array; 00080 /* 00081 Array of all fields used in partition and subpartition expression, 00082 without duplicates, NULL-terminated. 00083 */ 00084 Field **full_part_field_array; 00085 /* 00086 Set of all fields used in partition and subpartition expression. 00087 Required for testing of partition fields in write_set when 00088 updating. We need to set all bits in read_set because the row may 00089 need to be inserted in a different [sub]partition. 00090 */ 00091 MY_BITMAP full_part_field_set; 00092 00093 /* 00094 When we have a field that requires transformation before calling the 00095 partition functions we must allocate field buffers for the field of 00096 the fields in the partition function. 00097 */ 00098 uchar **part_field_buffers; 00099 uchar **subpart_field_buffers; 00100 uchar **restore_part_field_ptrs; 00101 uchar **restore_subpart_field_ptrs; 00102 00103 Item *part_expr; 00104 Item *subpart_expr; 00105 00106 Item *item_free_list; 00107 00108 struct st_ddl_log_memory_entry *first_log_entry; 00109 struct st_ddl_log_memory_entry *exec_log_entry; 00110 struct st_ddl_log_memory_entry *frm_log_entry; 00111 00112 /* 00113 Bitmaps of partitions used by the current query. 00114 * read_partitions - partitions to be used for reading. 00115 * lock_partitions - partitions that must be locked (read or write). 00116 Usually read_partitions is the same set as lock_partitions, but 00117 in case of UPDATE the WHERE clause can limit the read_partitions set, 00118 but not neccesarily the lock_partitions set. 00119 Usage pattern: 00120 * Initialized in ha_partition::open(). 00121 * read+lock_partitions is set according to explicit PARTITION, 00122 WL#5217, in open_and_lock_tables(). 00123 * Bits in read_partitions can be cleared in prune_partitions() 00124 in the optimizing step. 00125 (WL#4443 is about allowing prune_partitions() to affect lock_partitions 00126 and be done before locking too). 00127 * When the partition enabled handler get an external_lock call it locks 00128 all partitions in lock_partitions (and remembers which partitions it 00129 locked, so that it can unlock them later). In case of LOCK TABLES it will 00130 lock all partitions, and keep them locked while lock_partitions can 00131 change for each statement under LOCK TABLES. 00132 * Freed at the same time item_free_list is freed. 00133 */ 00134 MY_BITMAP read_partitions; 00135 MY_BITMAP lock_partitions; 00136 bool bitmaps_are_initialized; 00137 00138 union { 00139 longlong *range_int_array; 00140 LIST_PART_ENTRY *list_array; 00141 part_column_list_val *range_col_array; 00142 part_column_list_val *list_col_array; 00143 }; 00144 00145 /******************************************** 00146 * INTERVAL ANALYSIS 00147 ********************************************/ 00148 /* 00149 Partitioning interval analysis function for partitioning, or NULL if 00150 interval analysis is not supported for this kind of partitioning. 00151 */ 00152 get_partitions_in_range_iter get_part_iter_for_interval; 00153 /* 00154 Partitioning interval analysis function for subpartitioning, or NULL if 00155 interval analysis is not supported for this kind of partitioning. 00156 */ 00157 get_partitions_in_range_iter get_subpart_iter_for_interval; 00158 00159 /******************************************** 00160 * INTERVAL ANALYSIS ENDS 00161 ********************************************/ 00162 00163 longlong err_value; 00164 char* part_info_string; 00165 00166 char *part_func_string; 00167 char *subpart_func_string; 00168 00169 partition_element *curr_part_elem; // part or sub part 00170 partition_element *current_partition; // partition 00171 part_elem_value *curr_list_val; 00172 uint curr_list_object; 00173 uint num_columns; 00174 00175 TABLE *table; 00176 /* 00177 These key_map's are used for Partitioning to enable quick decisions 00178 on whether we can derive more information about which partition to 00179 scan just by looking at what index is used. 00180 */ 00181 key_map all_fields_in_PF, all_fields_in_PPF, all_fields_in_SPF; 00182 key_map some_fields_in_PF; 00183 00184 handlerton *default_engine_type; 00185 partition_type part_type; 00186 partition_type subpart_type; 00187 00188 uint part_info_len; 00189 uint part_func_len; 00190 uint subpart_func_len; 00191 00192 uint num_parts; 00193 uint num_subparts; 00194 uint count_curr_subparts; // used during parsing 00195 00196 uint num_list_values; 00197 00198 uint num_part_fields; 00199 uint num_subpart_fields; 00200 uint num_full_part_fields; 00201 00202 uint has_null_part_id; 00203 /* 00204 This variable is used to calculate the partition id when using 00205 LINEAR KEY/HASH. This functionality is kept in the MySQL Server 00206 but mainly of use to handlers supporting partitioning. 00207 */ 00208 uint16 linear_hash_mask; 00209 /* 00210 PARTITION BY KEY ALGORITHM=N 00211 Which algorithm to use for hashing the fields. 00212 N = 1 - Use 5.1 hashing (numeric fields are hashed as binary) 00213 N = 2 - Use 5.5 hashing (numeric fields are hashed like latin1 bytes) 00214 */ 00215 enum enum_key_algorithm 00216 { 00217 KEY_ALGORITHM_NONE= 0, 00218 KEY_ALGORITHM_51= 1, 00219 KEY_ALGORITHM_55= 2 00220 }; 00221 enum_key_algorithm key_algorithm; 00222 00223 /* Only the number of partitions defined (uses default names and options). */ 00224 bool use_default_partitions; 00225 bool use_default_num_partitions; 00226 /* Only the number of subpartitions defined (uses default names etc.). */ 00227 bool use_default_subpartitions; 00228 bool use_default_num_subpartitions; 00229 bool default_partitions_setup; 00230 bool defined_max_value; 00231 bool list_of_part_fields; // KEY or COLUMNS PARTITIONING 00232 bool list_of_subpart_fields; // KEY SUBPARTITIONING 00233 bool linear_hash_ind; // LINEAR HASH/KEY 00234 bool fixed; 00235 bool is_auto_partitioned; 00236 bool has_null_value; 00237 bool column_list; // COLUMNS PARTITIONING, 5.5+ 00246 bool is_pruning_completed; 00247 00248 partition_info() 00249 : get_partition_id(NULL), get_part_partition_id(NULL), 00250 get_subpartition_id(NULL), 00251 part_field_array(NULL), subpart_field_array(NULL), 00252 part_charset_field_array(NULL), 00253 subpart_charset_field_array(NULL), 00254 full_part_field_array(NULL), 00255 part_field_buffers(NULL), subpart_field_buffers(NULL), 00256 restore_part_field_ptrs(NULL), restore_subpart_field_ptrs(NULL), 00257 part_expr(NULL), subpart_expr(NULL), item_free_list(NULL), 00258 first_log_entry(NULL), exec_log_entry(NULL), frm_log_entry(NULL), 00259 bitmaps_are_initialized(FALSE), 00260 list_array(NULL), err_value(0), 00261 part_info_string(NULL), 00262 part_func_string(NULL), subpart_func_string(NULL), 00263 curr_part_elem(NULL), current_partition(NULL), 00264 curr_list_object(0), num_columns(0), table(NULL), 00265 default_engine_type(NULL), 00266 part_type(NOT_A_PARTITION), subpart_type(NOT_A_PARTITION), 00267 part_info_len(0), 00268 part_func_len(0), subpart_func_len(0), 00269 num_parts(0), num_subparts(0), 00270 count_curr_subparts(0), 00271 num_list_values(0), num_part_fields(0), num_subpart_fields(0), 00272 num_full_part_fields(0), has_null_part_id(0), linear_hash_mask(0), 00273 key_algorithm(KEY_ALGORITHM_NONE), 00274 use_default_partitions(TRUE), use_default_num_partitions(TRUE), 00275 use_default_subpartitions(TRUE), use_default_num_subpartitions(TRUE), 00276 default_partitions_setup(FALSE), defined_max_value(FALSE), 00277 list_of_part_fields(FALSE), list_of_subpart_fields(FALSE), 00278 linear_hash_ind(FALSE), fixed(FALSE), 00279 is_auto_partitioned(FALSE), 00280 has_null_value(FALSE), column_list(FALSE), is_pruning_completed(false) 00281 { 00282 partitions.empty(); 00283 temp_partitions.empty(); 00284 part_field_list.empty(); 00285 subpart_field_list.empty(); 00286 } 00287 ~partition_info() {} 00288 00289 partition_info *get_clone(); 00290 partition_info *get_full_clone(); 00291 bool set_named_partition_bitmap(const char *part_name, uint length); 00292 bool set_partition_bitmaps(TABLE_LIST *table_list); 00293 /* Answers the question if subpartitioning is used for a certain table */ 00294 bool is_sub_partitioned() 00295 { 00296 return (subpart_type == NOT_A_PARTITION ? FALSE : TRUE); 00297 } 00298 00299 /* Returns the total number of partitions on the leaf level */ 00300 uint get_tot_partitions() 00301 { 00302 return num_parts * (is_sub_partitioned() ? num_subparts : 1); 00303 } 00304 00305 bool set_up_defaults_for_partitioning(handler *file, HA_CREATE_INFO *info, 00306 uint start_no); 00307 char *find_duplicate_field(); 00308 char *find_duplicate_name(); 00309 bool check_engine_mix(handlerton *engine_type, bool default_engine); 00310 bool check_range_constants(THD *thd); 00311 bool check_list_constants(THD *thd); 00312 bool check_partition_info(THD *thd, handlerton **eng_type, 00313 handler *file, HA_CREATE_INFO *info, 00314 bool check_partition_function); 00315 void print_no_partition_found(TABLE *table); 00316 void print_debug(const char *str, uint*); 00317 Item* get_column_item(Item *item, Field *field); 00318 bool fix_partition_values(THD *thd, 00319 part_elem_value *val, 00320 partition_element *part_elem, 00321 uint part_id); 00322 bool fix_column_value_functions(THD *thd, 00323 part_elem_value *val, 00324 uint part_id); 00325 bool fix_parser_data(THD *thd); 00326 bool add_max_value(); 00327 void init_col_val(part_column_list_val *col_val, Item *item); 00328 bool reorganize_into_single_field_col_val(); 00329 part_column_list_val *add_column_value(); 00330 bool set_part_expr(char *start_token, Item *item_ptr, 00331 char *end_token, bool is_subpart); 00332 static int compare_column_values(const void *a, const void *b); 00333 bool set_up_charset_field_preps(); 00334 bool check_partition_field_length(); 00335 bool init_column_part(); 00336 bool add_column_list_value(THD *thd, Item *item); 00337 void set_show_version_string(String *packet); 00338 partition_element *get_part_elem(const char *partition_name, 00339 char *file_name, 00340 uint32 *part_id); 00341 void report_part_expr_error(bool use_subpart_expr); 00342 bool set_used_partition(List<Item> &fields, 00343 List<Item> &values, 00344 COPY_INFO &info, 00345 bool copy_default_values, 00346 MY_BITMAP *used_partitions); 00356 enum enum_can_prune {PRUNE_NO=0, PRUNE_DEFAULTS, PRUNE_YES}; 00357 bool can_prune_insert(THD *thd, 00358 enum_duplicates duplic, 00359 COPY_INFO &update, 00360 List<Item> &update_fields, 00361 List<Item> &fields, 00362 bool empty_values, 00363 enum_can_prune *can_prune_partitions, 00364 bool *prune_needs_default_values, 00365 MY_BITMAP *used_partitions); 00366 bool has_same_partitioning(partition_info *new_part_info); 00367 private: 00368 static int list_part_cmp(const void* a, const void* b); 00369 bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info, 00370 uint start_no); 00371 bool set_up_default_subpartitions(handler *file, HA_CREATE_INFO *info); 00372 char *create_default_partition_names(uint part_no, uint num_parts, 00373 uint start_no); 00374 char *create_default_subpartition_name(uint subpart_no, 00375 const char *part_name); 00376 bool prune_partition_bitmaps(TABLE_LIST *table_list); 00377 bool add_named_partition(const char *part_name, uint length); 00378 bool is_field_in_part_expr(List<Item> &fields); 00379 bool is_full_part_expr_in_fields(List<Item> &fields); 00380 }; 00381 00382 uint32 get_next_partition_id_range(struct st_partition_iter* part_iter); 00383 bool check_partition_dirs(partition_info *part_info); 00384 00385 /* Initialize the iterator to return a single partition with given part_id */ 00386 00387 static inline void init_single_partition_iterator(uint32 part_id, 00388 PARTITION_ITERATOR *part_iter) 00389 { 00390 part_iter->part_nums.start= part_iter->part_nums.cur= part_id; 00391 part_iter->part_nums.end= part_id+1; 00392 part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE; 00393 part_iter->get_next= get_next_partition_id_range; 00394 } 00395 00396 /* Initialize the iterator to enumerate all partitions */ 00397 static inline 00398 void init_all_partitions_iterator(partition_info *part_info, 00399 PARTITION_ITERATOR *part_iter) 00400 { 00401 part_iter->part_nums.start= part_iter->part_nums.cur= 0; 00402 part_iter->part_nums.end= part_info->num_parts; 00403 part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE; 00404 part_iter->get_next= get_next_partition_id_range; 00405 } 00406 00407 #endif /* PARTITION_INFO_INCLUDED */