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-1335  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 char *generate_partition_syntax_for_frm(THD *thd, partition_info *part_info,
280                                         uint *buf_length,
281                                         HA_CREATE_INFO *create_info,
282                                         Alter_info *alter_info);
283 bool verify_data_with_partition(TABLE *table, TABLE *part_table,
284                                 uint32 part_id);
285 bool compare_partition_options(HA_CREATE_INFO *table_create_info,
286                                partition_element *part_elem);
287 bool partition_key_modified(TABLE *table, const MY_BITMAP *fields);
288 #else
289 #define partition_key_modified(X,Y) 0
290 #endif
291 
292 int __attribute__((warn_unused_result))
293   create_partition_name(char *out, size_t outlen, const char *in1, const char
294                         *in2, uint name_variant, bool translate);
295 int __attribute__((warn_unused_result))
296   create_subpartition_name(char *out, size_t outlen, const char *in1, const
297                            char *in2, const char *in3, uint name_variant);
298 
299 void set_key_field_ptr(KEY *key_info, const uchar *new_buf,
300                        const uchar *old_buf);
301 
302 /** Set up table for creating a partition.
303 Copy info from partition to the table share so the created partition
304 has the correct info.
305   @param thd               THD object
306   @param share             Table share to be updated.
307   @param info              Create info to be updated.
308   @param part_elem         partition_element containing the info.
309 
310   @return    status
311     @retval  TRUE  Error
312     @retval  FALSE Success
313 
314   @details
315     Set up
316     1) Comment on partition
317     2) MAX_ROWS, MIN_ROWS on partition
318     3) Index file name on partition
319     4) Data file name on partition
320 */
321 bool set_up_table_before_create(THD *thd,
322                                 TABLE_SHARE *share,
323                                 const char *partition_name_with_path,
324                                 HA_CREATE_INFO *info,
325                                 partition_element *part_elem);
326 
327 #endif /* SQL_PARTITION_INCLUDED */
328 
329