My Project
partition_info.h
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 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines