| 1 | #ifndef SQL_PARTITION_INCLUDED |
| 2 | #define SQL_PARTITION_INCLUDED |
| 3 | |
| 4 | /* Copyright (c) 2006, 2017, Oracle and/or its affiliates. |
| 5 | Copyright (c) 2011, 2017, MariaDB |
| 6 | |
| 7 | This program is free software; you can redistribute it and/or modify |
| 8 | it under the terms of the GNU General Public License as published by |
| 9 | the Free Software Foundation; version 2 of the License. |
| 10 | |
| 11 | This program is distributed in the hope that it will be useful, |
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | GNU General Public License for more details. |
| 15 | |
| 16 | You should have received a copy of the GNU General Public License |
| 17 | along with this program; if not, write to the Free Software |
| 18 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
| 19 | |
| 20 | #ifdef USE_PRAGMA_INTERFACE |
| 21 | #pragma interface /* gcc class implementation */ |
| 22 | #endif |
| 23 | |
| 24 | #include "sql_list.h" /* List */ |
| 25 | #include "table.h" /* TABLE_LIST */ |
| 26 | |
| 27 | class Alter_info; |
| 28 | class Alter_table_ctx; |
| 29 | class Field; |
| 30 | class String; |
| 31 | class handler; |
| 32 | class partition_info; |
| 33 | struct TABLE; |
| 34 | struct TABLE_LIST; |
| 35 | typedef struct st_bitmap MY_BITMAP; |
| 36 | typedef struct st_key KEY; |
| 37 | typedef struct st_key_range key_range; |
| 38 | |
| 39 | /* Flags for partition handlers */ |
| 40 | #define HA_CAN_PARTITION (1 << 0) /* Partition support */ |
| 41 | #define HA_CAN_UPDATE_PARTITION_KEY (1 << 1) |
| 42 | #define HA_CAN_PARTITION_UNIQUE (1 << 2) |
| 43 | #define HA_USE_AUTO_PARTITION (1 << 3) |
| 44 | #define HA_ONLY_VERS_PARTITION (1 << 4) |
| 45 | |
| 46 | #define NORMAL_PART_NAME 0 |
| 47 | #define TEMP_PART_NAME 1 |
| 48 | #define RENAMED_PART_NAME 2 |
| 49 | |
| 50 | typedef struct st_lock_param_type |
| 51 | { |
| 52 | TABLE_LIST *table_list; |
| 53 | ulonglong copied; |
| 54 | ulonglong deleted; |
| 55 | THD *thd; |
| 56 | HA_CREATE_INFO *create_info; |
| 57 | Alter_info *alter_info; |
| 58 | TABLE *table; |
| 59 | KEY *key_info_buffer; |
| 60 | LEX_CSTRING db; |
| 61 | LEX_CSTRING table_name; |
| 62 | uchar *pack_frm_data; |
| 63 | uint key_count; |
| 64 | uint db_options; |
| 65 | size_t pack_frm_len; |
| 66 | partition_info *part_info; |
| 67 | } ALTER_PARTITION_PARAM_TYPE; |
| 68 | |
| 69 | typedef struct { |
| 70 | longlong list_value; |
| 71 | uint32 partition_id; |
| 72 | } LIST_PART_ENTRY; |
| 73 | |
| 74 | typedef struct { |
| 75 | uint32 start_part; |
| 76 | uint32 end_part; |
| 77 | } part_id_range; |
| 78 | |
| 79 | class String_list; |
| 80 | struct st_partition_iter; |
| 81 | #define NOT_A_PARTITION_ID UINT_MAX32 |
| 82 | |
| 83 | bool is_partition_in_list(char *part_name, List<char> list_part_names); |
| 84 | char *are_partitions_in_table(partition_info *new_part_info, |
| 85 | partition_info *old_part_info); |
| 86 | bool check_reorganise_list(partition_info *new_part_info, |
| 87 | partition_info *old_part_info, |
| 88 | List<char> list_part_names); |
| 89 | handler *get_ha_partition(partition_info *part_info); |
| 90 | int get_part_for_buf(const uchar *buf, const uchar *rec0, |
| 91 | partition_info *part_info, uint32 *part_id); |
| 92 | void prune_partition_set(const TABLE *table, part_id_range *part_spec); |
| 93 | bool check_partition_info(partition_info *part_info,handlerton **eng_type, |
| 94 | TABLE *table, handler *file, HA_CREATE_INFO *info); |
| 95 | void set_linear_hash_mask(partition_info *part_info, uint num_parts); |
| 96 | bool fix_partition_func(THD *thd, TABLE *table, bool create_table_ind); |
| 97 | void get_partition_set(const TABLE *table, uchar *buf, const uint index, |
| 98 | const key_range *key_spec, |
| 99 | part_id_range *part_spec); |
| 100 | uint get_partition_field_store_length(Field *field); |
| 101 | int get_cs_converted_part_value_from_string(THD *thd, |
| 102 | Item *item, |
| 103 | String *input_str, |
| 104 | String *output_str, |
| 105 | CHARSET_INFO *cs, |
| 106 | bool use_hex); |
| 107 | void get_full_part_id_from_key(const TABLE *table, uchar *buf, |
| 108 | KEY *key_info, |
| 109 | const key_range *key_spec, |
| 110 | part_id_range *part_spec); |
| 111 | bool mysql_unpack_partition(THD *thd, char *part_buf, |
| 112 | uint part_info_len, |
| 113 | TABLE *table, bool is_create_table_ind, |
| 114 | handlerton *default_db_type, |
| 115 | bool *work_part_info_used); |
| 116 | void make_used_partitions_str(MEM_ROOT *mem_root, |
| 117 | partition_info *part_info, String *parts_str, |
| 118 | String_list &used_partitions_list); |
| 119 | uint32 get_list_array_idx_for_endpoint(partition_info *part_info, |
| 120 | bool left_endpoint, |
| 121 | bool include_endpoint); |
| 122 | uint32 get_partition_id_range_for_endpoint(partition_info *part_info, |
| 123 | bool left_endpoint, |
| 124 | bool include_endpoint); |
| 125 | bool check_part_func_fields(Field **ptr, bool ok_with_charsets); |
| 126 | bool field_is_partition_charset(Field *field); |
| 127 | Item* convert_charset_partition_constant(Item *item, CHARSET_INFO *cs); |
| 128 | /** |
| 129 | Append all fields in read_set to string |
| 130 | |
| 131 | @param[in,out] str String to append to. |
| 132 | @param[in] row Row to append. |
| 133 | @param[in] table Table containing read_set and fields for the row. |
| 134 | */ |
| 135 | void append_row_to_str(String &str, const uchar *row, TABLE *table); |
| 136 | void truncate_partition_filename(char *path); |
| 137 | |
| 138 | /* |
| 139 | A "Get next" function for partition iterator. |
| 140 | |
| 141 | SYNOPSIS |
| 142 | partition_iter_func() |
| 143 | part_iter Partition iterator, you call only "iter.get_next(&iter)" |
| 144 | |
| 145 | DESCRIPTION |
| 146 | Depending on whether partitions or sub-partitions are iterated, the |
| 147 | function returns next subpartition id/partition number. The sequence of |
| 148 | returned numbers is not ordered and may contain duplicates. |
| 149 | |
| 150 | When the end of sequence is reached, NOT_A_PARTITION_ID is returned, and |
| 151 | the iterator resets itself (so next get_next() call will start to |
| 152 | enumerate the set all over again). |
| 153 | |
| 154 | RETURN |
| 155 | NOT_A_PARTITION_ID if there are no more partitions. |
| 156 | [sub]partition_id of the next partition |
| 157 | */ |
| 158 | |
| 159 | typedef uint32 (*partition_iter_func)(st_partition_iter* part_iter); |
| 160 | |
| 161 | |
| 162 | /* |
| 163 | Partition set iterator. Used to enumerate a set of [sub]partitions |
| 164 | obtained in partition interval analysis (see get_partitions_in_range_iter). |
| 165 | |
| 166 | For the user, the only meaningful field is get_next, which may be used as |
| 167 | follows: |
| 168 | part_iterator.get_next(&part_iterator); |
| 169 | |
| 170 | Initialization is done by any of the following calls: |
| 171 | - get_partitions_in_range_iter-type function call |
| 172 | - init_single_partition_iterator() |
| 173 | - init_all_partitions_iterator() |
| 174 | Cleanup is not needed. |
| 175 | */ |
| 176 | |
| 177 | typedef struct st_partition_iter |
| 178 | { |
| 179 | partition_iter_func get_next; |
| 180 | /* |
| 181 | Valid for "Interval mapping" in LIST partitioning: if true, let the |
| 182 | iterator also produce id of the partition that contains NULL value. |
| 183 | */ |
| 184 | bool ret_null_part, ret_null_part_orig; |
| 185 | /* |
| 186 | We should return DEFAULT partition. |
| 187 | */ |
| 188 | bool ret_default_part, ret_default_part_orig; |
| 189 | struct st_part_num_range |
| 190 | { |
| 191 | uint32 start; |
| 192 | uint32 cur; |
| 193 | uint32 end; |
| 194 | }; |
| 195 | |
| 196 | struct st_field_value_range |
| 197 | { |
| 198 | longlong start; |
| 199 | longlong cur; |
| 200 | longlong end; |
| 201 | }; |
| 202 | |
| 203 | union |
| 204 | { |
| 205 | struct st_part_num_range part_nums; |
| 206 | struct st_field_value_range field_vals; |
| 207 | }; |
| 208 | partition_info *part_info; |
| 209 | } PARTITION_ITERATOR; |
| 210 | |
| 211 | |
| 212 | /* |
| 213 | Get an iterator for set of partitions that match given field-space interval |
| 214 | |
| 215 | SYNOPSIS |
| 216 | get_partitions_in_range_iter() |
| 217 | part_info Partitioning info |
| 218 | is_subpart |
| 219 | store_length_array Length of fields packed in opt_range_key format |
| 220 | min_val Left edge, field value in opt_range_key format |
| 221 | max_val Right edge, field value in opt_range_key format |
| 222 | min_len Length of minimum value |
| 223 | max_len Length of maximum value |
| 224 | flags Some combination of NEAR_MIN, NEAR_MAX, NO_MIN_RANGE, |
| 225 | NO_MAX_RANGE |
| 226 | part_iter Iterator structure to be initialized |
| 227 | |
| 228 | DESCRIPTION |
| 229 | Functions with this signature are used to perform "Partitioning Interval |
| 230 | Analysis". This analysis is applicable for any type of [sub]partitioning |
| 231 | by some function of a single fieldX. The idea is as follows: |
| 232 | Given an interval "const1 <=? fieldX <=? const2", find a set of partitions |
| 233 | that may contain records with value of fieldX within the given interval. |
| 234 | |
| 235 | The min_val, max_val and flags parameters specify the interval. |
| 236 | The set of partitions is returned by initializing an iterator in *part_iter |
| 237 | |
| 238 | NOTES |
| 239 | There are currently three functions of this type: |
| 240 | - get_part_iter_for_interval_via_walking |
| 241 | - get_part_iter_for_interval_cols_via_map |
| 242 | - get_part_iter_for_interval_via_mapping |
| 243 | |
| 244 | RETURN |
| 245 | 0 - No matching partitions, iterator not initialized |
| 246 | 1 - Some partitions would match, iterator intialized for traversing them |
| 247 | -1 - All partitions would match, iterator not initialized |
| 248 | */ |
| 249 | |
| 250 | typedef int (*get_partitions_in_range_iter)(partition_info *part_info, |
| 251 | bool is_subpart, |
| 252 | uint32 *store_length_array, |
| 253 | uchar *min_val, uchar *max_val, |
| 254 | uint min_len, uint max_len, |
| 255 | uint flags, |
| 256 | PARTITION_ITERATOR *part_iter); |
| 257 | |
| 258 | #include "partition_info.h" |
| 259 | |
| 260 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
| 261 | uint fast_alter_partition_table(THD *thd, TABLE *table, |
| 262 | Alter_info *alter_info, |
| 263 | HA_CREATE_INFO *create_info, |
| 264 | TABLE_LIST *table_list, |
| 265 | const LEX_CSTRING *db, |
| 266 | const LEX_CSTRING *table_name); |
| 267 | bool set_part_state(Alter_info *alter_info, partition_info *tab_part_info, |
| 268 | enum partition_state part_state); |
| 269 | uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, |
| 270 | HA_CREATE_INFO *create_info, |
| 271 | Alter_table_ctx *alter_ctx, |
| 272 | bool *partition_changed, |
| 273 | bool *fast_alter_table); |
| 274 | char *generate_partition_syntax(THD *thd, partition_info *part_info, |
| 275 | uint *buf_length, |
| 276 | bool show_partition_options, |
| 277 | HA_CREATE_INFO *create_info, |
| 278 | Alter_info *alter_info); |
| 279 | bool verify_data_with_partition(TABLE *table, TABLE *part_table, |
| 280 | uint32 part_id); |
| 281 | bool compare_partition_options(HA_CREATE_INFO *table_create_info, |
| 282 | partition_element *part_elem); |
| 283 | bool partition_key_modified(TABLE *table, const MY_BITMAP *fields); |
| 284 | #else |
| 285 | #define partition_key_modified(X,Y) 0 |
| 286 | #endif |
| 287 | |
| 288 | int __attribute__((warn_unused_result)) |
| 289 | create_partition_name(char *out, size_t outlen, const char *in1, const char |
| 290 | *in2, uint name_variant, bool translate); |
| 291 | int __attribute__((warn_unused_result)) |
| 292 | create_subpartition_name(char *out, size_t outlen, const char *in1, const |
| 293 | char *in2, const char *in3, uint name_variant); |
| 294 | |
| 295 | void set_key_field_ptr(KEY *key_info, const uchar *new_buf, |
| 296 | const uchar *old_buf); |
| 297 | |
| 298 | /** Set up table for creating a partition. |
| 299 | Copy info from partition to the table share so the created partition |
| 300 | has the correct info. |
| 301 | @param thd THD object |
| 302 | @param share Table share to be updated. |
| 303 | @param info Create info to be updated. |
| 304 | @param part_elem partition_element containing the info. |
| 305 | |
| 306 | @return status |
| 307 | @retval TRUE Error |
| 308 | @retval FALSE Success |
| 309 | |
| 310 | @details |
| 311 | Set up |
| 312 | 1) Comment on partition |
| 313 | 2) MAX_ROWS, MIN_ROWS on partition |
| 314 | 3) Index file name on partition |
| 315 | 4) Data file name on partition |
| 316 | */ |
| 317 | bool set_up_table_before_create(THD *thd, |
| 318 | TABLE_SHARE *share, |
| 319 | const char *partition_name_with_path, |
| 320 | HA_CREATE_INFO *info, |
| 321 | partition_element *part_elem); |
| 322 | |
| 323 | #endif /* SQL_PARTITION_INCLUDED */ |
| 324 | |
| 325 | |