~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to sql/partition_info.h

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2006-2008 MySQL AB, 2008 Sun Microsystems, Inc.
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
15
 
 
16
#ifdef USE_PRAGMA_INTERFACE
 
17
#pragma interface                       /* gcc class implementation */
 
18
#endif
 
19
 
 
20
#include "partition_element.h"
 
21
 
 
22
class partition_info;
 
23
 
 
24
/* Some function typedefs */
 
25
typedef int (*get_part_id_func)(partition_info *part_info,
 
26
                                 uint32 *part_id,
 
27
                                 longlong *func_value);
 
28
typedef int (*get_subpart_id_func)(partition_info *part_info,
 
29
                                   uint32 *part_id);
 
30
 
 
31
struct st_ddl_log_memory_entry;
 
32
 
 
33
class partition_info : public Sql_alloc
 
34
{
 
35
public:
 
36
  /*
 
37
   * Here comes a set of definitions needed for partitioned table handlers.
 
38
   */
 
39
  List<partition_element> partitions;
 
40
  List<partition_element> temp_partitions;
 
41
 
 
42
  List<char> part_field_list;
 
43
  List<char> subpart_field_list;
 
44
  
 
45
  /* 
 
46
    If there is no subpartitioning, use only this func to get partition ids.
 
47
    If there is subpartitioning, use the this func to get partition id when
 
48
    you have both partition and subpartition fields.
 
49
  */
 
50
  get_part_id_func get_partition_id;
 
51
 
 
52
  /* Get partition id when we don't have subpartition fields */
 
53
  get_part_id_func get_part_partition_id;
 
54
 
 
55
  /* 
 
56
    Get subpartition id when we have don't have partition fields by we do
 
57
    have subpartition ids.
 
58
    Mikael said that for given constant tuple 
 
59
    {subpart_field1, ..., subpart_fieldN} the subpartition id will be the
 
60
    same in all subpartitions
 
61
  */
 
62
  get_subpart_id_func get_subpartition_id;
 
63
 
 
64
  /*
 
65
    When we have various string fields we might need some preparation
 
66
    before and clean-up after calling the get_part_id_func's. We need
 
67
    one such method for get_partition_id and one for
 
68
    get_part_partition_id and one for get_subpartition_id.
 
69
  */
 
70
  get_part_id_func get_partition_id_charset;
 
71
  get_part_id_func get_part_partition_id_charset;
 
72
  get_subpart_id_func get_subpartition_id_charset;
 
73
 
 
74
  /* NULL-terminated array of fields used in partitioned expression */
 
75
  Field **part_field_array;
 
76
  Field **subpart_field_array;
 
77
  Field **part_charset_field_array;
 
78
  Field **subpart_charset_field_array;
 
79
  /* 
 
80
    Array of all fields used in partition and subpartition expression,
 
81
    without duplicates, NULL-terminated.
 
82
  */
 
83
  Field **full_part_field_array;
 
84
  Field **full_part_charset_field_array;
 
85
  /*
 
86
    Set of all fields used in partition and subpartition expression.
 
87
    Required for testing of partition fields in write_set when
 
88
    updating. We need to set all bits in read_set because the row may
 
89
    need to be inserted in a different [sub]partition.
 
90
  */
 
91
  MY_BITMAP full_part_field_set;
 
92
 
 
93
  /*
 
94
    When we have a field that requires transformation before calling the
 
95
    partition functions we must allocate field buffers for the field of
 
96
    the fields in the partition function.
 
97
  */
 
98
  uchar **part_field_buffers;
 
99
  uchar **subpart_field_buffers;
 
100
  uchar **full_part_field_buffers;
 
101
  uchar **restore_part_field_ptrs;
 
102
  uchar **restore_subpart_field_ptrs;
 
103
  uchar **restore_full_part_field_ptrs;
 
104
 
 
105
  Item *part_expr;
 
106
  Item *subpart_expr;
 
107
 
 
108
  Item *item_free_list;
 
109
 
 
110
  struct st_ddl_log_memory_entry *first_log_entry;
 
111
  struct st_ddl_log_memory_entry *exec_log_entry;
 
112
  struct st_ddl_log_memory_entry *frm_log_entry;
 
113
 
 
114
  /* 
 
115
    A bitmap of partitions used by the current query. 
 
116
    Usage pattern:
 
117
    * The handler->extra(HA_EXTRA_RESET) call at query start/end sets all
 
118
      partitions to be unused.
 
119
    * Before index/rnd_init(), partition pruning code sets the bits for used
 
120
      partitions.
 
121
  */
 
122
  MY_BITMAP used_partitions;
 
123
 
 
124
  union {
 
125
    longlong *range_int_array;
 
126
    LIST_PART_ENTRY *list_array;
 
127
  };
 
128
  
 
129
  /********************************************
 
130
   * INTERVAL ANALYSIS
 
131
   ********************************************/
 
132
  /*
 
133
    Partitioning interval analysis function for partitioning, or NULL if 
 
134
    interval analysis is not supported for this kind of partitioning.
 
135
  */
 
136
  get_partitions_in_range_iter get_part_iter_for_interval;
 
137
  /*
 
138
    Partitioning interval analysis function for subpartitioning, or NULL if
 
139
    interval analysis is not supported for this kind of partitioning.
 
140
  */
 
141
  get_partitions_in_range_iter get_subpart_iter_for_interval;
 
142
  
 
143
  /********************************************
 
144
   * INTERVAL ANALYSIS ENDS 
 
145
   ********************************************/
 
146
 
 
147
  longlong err_value;
 
148
  char* part_info_string;
 
149
 
 
150
  char *part_func_string;
 
151
  char *subpart_func_string;
 
152
 
 
153
  const char *part_state;
 
154
 
 
155
  partition_element *curr_part_elem;
 
156
  partition_element *current_partition;
 
157
  /*
 
158
    These key_map's are used for Partitioning to enable quick decisions
 
159
    on whether we can derive more information about which partition to
 
160
    scan just by looking at what index is used.
 
161
  */
 
162
  key_map all_fields_in_PF, all_fields_in_PPF, all_fields_in_SPF;
 
163
  key_map some_fields_in_PF;
 
164
 
 
165
  handlerton *default_engine_type;
 
166
  Item_result part_result_type;
 
167
  partition_type part_type;
 
168
  partition_type subpart_type;
 
169
 
 
170
  uint part_info_len;
 
171
  uint part_state_len;
 
172
  uint part_func_len;
 
173
  uint subpart_func_len;
 
174
 
 
175
  uint no_parts;
 
176
  uint no_subparts;
 
177
  uint count_curr_subparts;
 
178
 
 
179
  uint part_error_code;
 
180
 
 
181
  uint no_list_values;
 
182
 
 
183
  uint no_part_fields;
 
184
  uint no_subpart_fields;
 
185
  uint no_full_part_fields;
 
186
 
 
187
  uint has_null_part_id;
 
188
  /*
 
189
    This variable is used to calculate the partition id when using
 
190
    LINEAR KEY/HASH. This functionality is kept in the MySQL Server
 
191
    but mainly of use to handlers supporting partitioning.
 
192
  */
 
193
  uint16 linear_hash_mask;
 
194
 
 
195
  bool use_default_partitions;
 
196
  bool use_default_no_partitions;
 
197
  bool use_default_subpartitions;
 
198
  bool use_default_no_subpartitions;
 
199
  bool default_partitions_setup;
 
200
  bool defined_max_value;
 
201
  bool list_of_part_fields;
 
202
  bool list_of_subpart_fields;
 
203
  bool linear_hash_ind;
 
204
  bool fixed;
 
205
  bool is_auto_partitioned;
 
206
  bool from_openfrm;
 
207
  bool has_null_value;
 
208
 
 
209
 
 
210
  partition_info()
 
211
  : get_partition_id(NULL), get_part_partition_id(NULL),
 
212
    get_subpartition_id(NULL),
 
213
    part_field_array(NULL), subpart_field_array(NULL),
 
214
    part_charset_field_array(NULL),
 
215
    subpart_charset_field_array(NULL),
 
216
    full_part_field_array(NULL),
 
217
    full_part_charset_field_array(NULL),
 
218
    part_field_buffers(NULL), subpart_field_buffers(NULL),
 
219
    full_part_field_buffers(NULL),
 
220
    restore_part_field_ptrs(NULL), restore_subpart_field_ptrs(NULL),
 
221
    restore_full_part_field_ptrs(NULL),
 
222
    part_expr(NULL), subpart_expr(NULL), item_free_list(NULL),
 
223
    first_log_entry(NULL), exec_log_entry(NULL), frm_log_entry(NULL),
 
224
    list_array(NULL), err_value(0),
 
225
    part_info_string(NULL),
 
226
    part_func_string(NULL), subpart_func_string(NULL),
 
227
    part_state(NULL),
 
228
    curr_part_elem(NULL), current_partition(NULL),
 
229
    default_engine_type(NULL),
 
230
    part_result_type(INT_RESULT),
 
231
    part_type(NOT_A_PARTITION), subpart_type(NOT_A_PARTITION),
 
232
    part_info_len(0), part_state_len(0),
 
233
    part_func_len(0), subpart_func_len(0),
 
234
    no_parts(0), no_subparts(0),
 
235
    count_curr_subparts(0), part_error_code(0),
 
236
    no_list_values(0), no_part_fields(0), no_subpart_fields(0),
 
237
    no_full_part_fields(0), has_null_part_id(0), linear_hash_mask(0),
 
238
    use_default_partitions(TRUE), use_default_no_partitions(TRUE),
 
239
    use_default_subpartitions(TRUE), use_default_no_subpartitions(TRUE),
 
240
    default_partitions_setup(FALSE), defined_max_value(FALSE),
 
241
    list_of_part_fields(FALSE), list_of_subpart_fields(FALSE),
 
242
    linear_hash_ind(FALSE), fixed(FALSE),
 
243
    is_auto_partitioned(FALSE), from_openfrm(FALSE),
 
244
    has_null_value(FALSE)
 
245
  {
 
246
    all_fields_in_PF.clear_all();
 
247
    all_fields_in_PPF.clear_all();
 
248
    all_fields_in_SPF.clear_all();
 
249
    some_fields_in_PF.clear_all();
 
250
    partitions.empty();
 
251
    temp_partitions.empty();
 
252
    part_field_list.empty();
 
253
    subpart_field_list.empty();
 
254
  }
 
255
  ~partition_info() {}
 
256
 
 
257
  partition_info *get_clone();
 
258
  /* Answers the question if subpartitioning is used for a certain table */
 
259
  bool is_sub_partitioned()
 
260
  {
 
261
    return (subpart_type == NOT_A_PARTITION ?  FALSE : TRUE);
 
262
  }
 
263
 
 
264
  /* Returns the total number of partitions on the leaf level */
 
265
  uint get_tot_partitions()
 
266
  {
 
267
    return no_parts * (is_sub_partitioned() ? no_subparts : 1);
 
268
  }
 
269
 
 
270
  bool set_up_defaults_for_partitioning(handler *file, HA_CREATE_INFO *info,
 
271
                                        uint start_no);
 
272
  char *has_unique_names();
 
273
  bool check_engine_mix(handlerton *engine_type, bool default_engine);
 
274
  bool check_range_constants();
 
275
  bool check_list_constants();
 
276
  bool check_partition_info(THD *thd, handlerton **eng_type,
 
277
                            handler *file, HA_CREATE_INFO *info,
 
278
                            bool check_partition_function);
 
279
  void print_no_partition_found(TABLE *table);
 
280
  bool set_up_charset_field_preps();
 
281
private:
 
282
  static int list_part_cmp(const void* a, const void* b);
 
283
  static int list_part_cmp_unsigned(const void* a, const void* b);
 
284
  bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info,
 
285
                                 uint start_no);
 
286
  bool set_up_default_subpartitions(handler *file, HA_CREATE_INFO *info);
 
287
  char *create_default_partition_names(uint part_no, uint no_parts,
 
288
                                       uint start_no);
 
289
  char *create_subpartition_name(uint subpart_no, const char *part_name);
 
290
  bool has_unique_name(partition_element *element);
 
291
};
 
292
 
 
293
uint32 get_next_partition_id_range(struct st_partition_iter* part_iter);
 
294
bool check_partition_dirs(partition_info *part_info);
 
295
 
 
296
/* Initialize the iterator to return a single partition with given part_id */
 
297
 
 
298
static inline void init_single_partition_iterator(uint32 part_id,
 
299
                                           PARTITION_ITERATOR *part_iter)
 
300
{
 
301
  part_iter->part_nums.start= part_iter->part_nums.cur= part_id;
 
302
  part_iter->part_nums.end= part_id+1;
 
303
  part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
 
304
  part_iter->get_next= get_next_partition_id_range;
 
305
}
 
306
 
 
307
/* Initialize the iterator to enumerate all partitions */
 
308
static inline
 
309
void init_all_partitions_iterator(partition_info *part_info,
 
310
                                  PARTITION_ITERATOR *part_iter)
 
311
{
 
312
  part_iter->part_nums.start= part_iter->part_nums.cur= 0;
 
313
  part_iter->part_nums.end= part_info->no_parts;
 
314
  part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
 
315
  part_iter->get_next= get_next_partition_id_range;
 
316
}