51 #include "sql_partition.h"
53 #include "sql_parse.h"
54 #include "sql_cache.h"
60 #include "transaction.h"
64 #include "sql_table.h"
68 #include "opt_range.h"
69 #include "sql_analyse.h"
70 #include "sql_alter.h"
76 #ifdef WITH_PARTITION_STORAGE_ENGINE
77 #include "ha_partition.h"
79 #define ERROR_INJECT_CRASH(code) \
80 DBUG_EVALUATE_IF(code, (DBUG_SUICIDE(), 0), 0)
81 #define ERROR_INJECT_ERROR(code) \
82 DBUG_EVALUATE_IF(code, (my_error(ER_UNKNOWN_ERROR, MYF(0)), TRUE), 0)
89 { C_STRING_WITH_LEN(
"HASH") },
90 { C_STRING_WITH_LEN(
"RANGE") },
91 { C_STRING_WITH_LEN(
"LIST") },
92 { C_STRING_WITH_LEN(
"KEY") },
93 { C_STRING_WITH_LEN(
"MAXVALUE") },
94 { C_STRING_WITH_LEN(
"LINEAR ") },
95 { C_STRING_WITH_LEN(
" COLUMNS") },
96 { C_STRING_WITH_LEN(
"ALGORITHM") }
99 static const char *part_str=
"PARTITION";
100 static const char *sub_str=
"SUB";
101 static const char *by_str=
"BY";
102 static const char *space_str=
" ";
103 static const char *equal_str=
"=";
104 static const char *end_paren_str=
")";
105 static const char *begin_paren_str=
"(";
106 static const char *comma_str=
",";
110 longlong *func_value);
113 longlong *func_value);
116 longlong *func_value);
119 longlong *func_value);
120 static int get_part_id_charset_func_part(
partition_info *part_info,
122 longlong *func_value);
123 static int get_part_id_charset_func_subpart(
partition_info *part_info,
127 longlong *func_value);
130 longlong *func_value);
133 longlong *func_value);
136 longlong *func_value);
139 longlong *func_value);
149 static void set_up_range_analysis_info(
partition_info *part_info);
155 int get_part_iter_for_interval_via_mapping(
partition_info *part_info,
157 uint32 *store_length_array,
158 uchar *min_value, uchar *max_value,
159 uint min_len, uint max_len,
162 int get_part_iter_for_interval_cols_via_map(
partition_info *part_info,
164 uint32 *store_length_array,
165 uchar *min_value, uchar *max_value,
166 uint min_len, uint max_len,
169 int get_part_iter_for_interval_via_walking(
partition_info *part_info,
171 uint32 *store_length_array,
172 uchar *min_value, uchar *max_value,
173 uint min_len, uint max_len,
177 #ifdef WITH_PARTITION_STORAGE_ENGINE
180 uint32 n_vals_in_rec,
181 bool is_left_endpoint,
182 bool include_endpoint);
200 THD *thd= current_thd;
203 const char *save_where= thd->where;
205 item= item->safe_charset_converter(cs);
206 context->table_list= NULL;
207 thd->where=
"convert character set partition constant";
208 if (!item || item->fix_fields(thd, (
Item**)NULL))
210 thd->where= save_where;
211 context->table_list= save_list;
230 uint num_names= list_names.elements;
235 char *list_name= names_it++;
236 if (!(my_strcasecmp(system_charset_info, name, list_name)))
238 }
while (++i < num_names);
260 bool is_create_table_ind,
261 const char *normalized_path)
263 DBUG_ENTER(
"partition_default_handling");
265 if (!is_create_table_ind)
267 if (part_info->use_default_num_partitions)
269 if (table->file->
get_no_parts(normalized_path, &part_info->num_parts))
274 else if (part_info->is_sub_partitioned() &&
275 part_info->use_default_num_subpartitions)
278 if (table->file->
get_no_parts(normalized_path, &num_parts))
282 DBUG_ASSERT(part_info->num_parts > 0);
283 DBUG_ASSERT((num_parts % part_info->num_parts) == 0);
284 part_info->num_subparts= num_parts / part_info->num_parts;
287 part_info->set_up_defaults_for_partitioning(table->file,
311 int get_parts_for_update(
const uchar *old_data, uchar *new_data,
313 uint32 *old_part_id, uint32 *new_part_id,
314 longlong *new_func_value)
316 Field **part_field_array= part_info->full_part_field_array;
318 longlong old_func_value;
319 DBUG_ENTER(
"get_parts_for_update");
321 DBUG_ASSERT(new_data == rec0);
322 set_field_ptr(part_field_array, old_data, rec0);
323 error= part_info->get_partition_id(part_info, old_part_id,
325 set_field_ptr(part_field_array, rec0, old_data);
332 if (new_data == rec0)
335 if (unlikely(error= part_info->get_partition_id(part_info,
350 set_field_ptr(part_field_array, new_data, rec0);
351 error= part_info->get_partition_id(part_info, new_part_id,
353 set_field_ptr(part_field_array, rec0, new_data);
385 int get_part_for_delete(
const uchar *
buf,
const uchar *rec0,
390 DBUG_ENTER(
"get_part_for_delete");
392 if (likely(buf == rec0))
394 if (unlikely((error= part_info->get_partition_id(part_info, part_id,
399 DBUG_PRINT(
"info", (
"Delete from partition %d", *part_id));
403 Field **part_field_array= part_info->full_part_field_array;
404 set_field_ptr(part_field_array, buf, rec0);
405 error= part_info->get_partition_id(part_info, part_id, &func_value);
406 set_field_ptr(part_field_array, rec0, buf);
411 DBUG_PRINT(
"info", (
"Delete from partition %d (path2)", *part_id));
459 static bool set_up_field_array(
TABLE *table,
462 Field **ptr, *field, **field_array;
464 uint size_field_array;
469 DBUG_ENTER(
"set_up_field_array");
472 while ((field= *(ptr++)))
474 if (field->flags & GET_FIXED_FIELDS_FLAG)
477 if (num_fields > MAX_REF_PARTS)
481 err_str= (
char*)
"subpartition function";
483 err_str= (
char*)
"partition function";
484 my_error(ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR, MYF(0), err_str);
492 DBUG_ASSERT(!is_sub_part);
495 size_field_array= (num_fields+1)*
sizeof(
Field*);
496 field_array= (
Field**)sql_calloc(size_field_array);
497 if (unlikely(!field_array))
499 mem_alloc_error(size_field_array);
503 while ((field= *(ptr++)))
505 if (field->flags & GET_FIXED_FIELDS_FLAG)
507 field->flags&= ~GET_FIXED_FIELDS_FLAG;
508 field->flags|= FIELD_IN_PART_FUNC_FLAG;
511 if (!is_sub_part && part_info->column_list)
516 DBUG_ASSERT(num_fields == part_info->part_field_list.elements);
521 if (!my_strcasecmp(system_charset_info,
525 }
while (++inx < num_fields);
526 if (inx == num_fields)
534 my_error(ER_FIELD_NOT_FOUND_PART_ERROR, MYF(0));
541 field_array[inx]= field;
552 if (unlikely(field->flags & BLOB_FLAG))
554 my_error(ER_BLOB_FIELD_IN_PART_FUNC_ERROR, MYF(0));
560 field_array[num_fields]= 0;
563 part_info->part_field_array= field_array;
564 part_info->num_part_fields= num_fields;
568 part_info->subpart_field_array= field_array;
569 part_info->num_subpart_fields= num_fields;
597 static bool create_full_part_field_array(THD *thd,
TABLE *table,
602 my_bitmap_map *bitmap_buf;
603 DBUG_ENTER(
"create_full_part_field_array");
605 if (!part_info->is_sub_partitioned())
607 part_info->full_part_field_array= part_info->part_field_array;
608 part_info->num_full_part_fields= part_info->num_part_fields;
612 Field *field, **field_array;
613 uint num_part_fields=0, size_field_array;
615 while ((field= *(ptr++)))
617 if (field->flags & FIELD_IN_PART_FUNC_FLAG)
620 size_field_array= (num_part_fields+1)*
sizeof(
Field*);
621 field_array= (
Field**)sql_calloc(size_field_array);
622 if (unlikely(!field_array))
624 mem_alloc_error(size_field_array);
630 while ((field= *(ptr++)))
632 if (field->flags & FIELD_IN_PART_FUNC_FLAG)
633 field_array[num_part_fields++]= field;
635 field_array[num_part_fields]=0;
636 part_info->full_part_field_array= field_array;
637 part_info->num_full_part_fields= num_part_fields;
646 if (!(bitmap_buf= (my_bitmap_map*)
647 thd->alloc(bitmap_buffer_size(table->s->fields))))
649 mem_alloc_error(bitmap_buffer_size(table->s->fields));
653 if (bitmap_init(&part_info->full_part_field_set, bitmap_buf,
654 table->s->fields, FALSE))
656 mem_alloc_error(table->s->fields);
664 if ((ptr= part_info->full_part_field_array))
666 bitmap_set_bit(&part_info->full_part_field_set, (*ptr)->field_index);
695 static void clear_indicator_in_key_fields(
KEY *key_info)
699 for (i= 0, key_part=key_info->key_part; i < key_parts; i++, key_part++)
700 key_part->field->flags&= (~GET_FIXED_FIELDS_FLAG);
715 static void set_indicator_in_key_fields(
KEY *key_info)
719 for (i= 0, key_part=key_info->key_part; i < key_parts; i++, key_part++)
720 key_part->field->flags|= GET_FIXED_FIELDS_FLAG;
738 static void check_fields_in_PF(
Field **ptr,
bool *all_fields,
741 DBUG_ENTER(
"check_fields_in_PF");
745 if ((!ptr) || !(*ptr))
753 if ((*ptr)->flags & GET_FIXED_FIELDS_FLAG)
774 static void clear_field_flag(
TABLE *table)
777 DBUG_ENTER(
"clear_field_flag");
779 for (ptr= table->field; *ptr; ptr++)
780 (*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
816 bool is_list_empty= TRUE;
817 DBUG_ENTER(
"handle_list_of_fields");
819 while ((field_name= it++))
821 is_list_empty= FALSE;
822 field= find_field_in_table_sef(table, field_name);
823 if (likely(field != 0))
824 field->flags|= GET_FIXED_FIELDS_FLAG;
827 my_error(ER_FIELD_NOT_FOUND_PART_ERROR, MYF(0));
828 clear_field_flag(table);
833 if (is_list_empty && part_info->part_type == HASH_PARTITION)
835 uint primary_key= table->s->primary_key;
836 if (primary_key != MAX_KEY)
842 for (i= 0; i < num_key_parts; i++)
844 Field *field= table->key_info[primary_key].key_part[
i].field;
845 field->flags|= GET_FIXED_FIELDS_FLAG;
850 if (table->s->db_type()->partition_flags &&
851 (table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION) &&
852 (table->s->db_type()->partition_flags() & HA_CAN_PARTITION))
864 my_error(ER_FIELD_NOT_FOUND_PART_ERROR, MYF(0));
869 result= set_up_field_array(table, is_sub_part);
892 if (part_info->part_type != HASH_PARTITION &&
893 part_info->part_expr->unsigned_flag)
900 if (part_elem->signed_flag)
902 my_error(ER_PARTITION_CONST_DOMAIN_ERROR, MYF(0));
903 error= ER_PARTITION_CONST_DOMAIN_ERROR;
906 }
while (++i < part_info->num_parts);
932 init_lex_with_single_table(THD *thd,
TABLE *table, LEX *lex)
935 Table_ident *table_ident;
936 SELECT_LEX *select_lex= &lex->select_lex;
949 if ((!(table_ident=
new Table_ident(thd,
950 table->s->table_name,
951 table->s->db, TRUE))) ||
952 (!(table_list= select_lex->add_table_to_list(thd,
957 context->resolve_in_table_list_only(table_list);
958 lex->use_only_table_context= TRUE;
960 table->get_fields_in_item_tree= TRUE;
961 table_list->table=
table;
962 table_list->cacheable_table=
false;
982 end_lex_with_single_table(THD *thd,
TABLE *table, LEX *old_lex)
986 table->get_fields_in_item_tree= FALSE;
1028 static bool fix_fields_part_func(THD *thd,
Item* func_expr,
TABLE *table,
1029 bool is_sub_part,
bool is_create_table_ind)
1034 LEX *old_lex= thd->lex;
1036 DBUG_ENTER(
"fix_fields_part_func");
1038 if (init_lex_with_single_table(thd, table, &lex))
1041 func_expr->walk(&Item::change_context_processor, 0,
1042 (uchar*) &lex.select_lex.context);
1043 thd->where=
"partition function";
1061 const bool save_agg_field= thd->lex->current_select->non_agg_field_used();
1062 const bool save_agg_func= thd->lex->current_select->agg_func_used();
1063 const nesting_map saved_allow_sum_func= thd->lex->allow_sum_func;
1064 thd->lex->allow_sum_func= 0;
1066 error= func_expr->fix_fields(thd, (
Item**)&func_expr);
1072 thd->lex->current_select->set_non_agg_field_used(save_agg_field);
1073 thd->lex->current_select->set_agg_func_used(save_agg_func);
1074 thd->lex->allow_sum_func= saved_allow_sum_func;
1076 if (unlikely(error))
1078 DBUG_PRINT(
"info", (
"Field in partition function not part of table"));
1079 clear_field_flag(table);
1082 if (unlikely(func_expr->const_item()))
1084 my_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0));
1085 clear_field_flag(table);
1096 if (func_expr->walk(&Item::check_valid_arguments_processor,
1099 if (is_create_table_ind)
1101 my_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0));
1105 push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
1106 ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR,
1107 ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR));
1110 if ((!is_sub_part) && (error= check_signed_flag(part_info)))
1112 result= set_up_field_array(table, is_sub_part);
1114 end_lex_with_single_table(thd, table, old_lex);
1115 #if !defined(DBUG_OFF)
1116 func_expr->walk(&Item::change_context_processor, 0,
1119 DBUG_RETURN(result);
1143 static bool check_primary_key(
TABLE *table)
1145 uint primary_key= table->s->primary_key;
1146 bool all_fields, some_fields;
1148 DBUG_ENTER(
"check_primary_key");
1150 if (primary_key < MAX_KEY)
1152 set_indicator_in_key_fields(table->key_info+primary_key);
1153 check_fields_in_PF(table->part_info->full_part_field_array,
1154 &all_fields, &some_fields);
1155 clear_indicator_in_key_fields(table->key_info+primary_key);
1156 if (unlikely(!all_fields))
1158 my_error(ER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF,MYF(0),
"PRIMARY KEY");
1162 DBUG_RETURN(result);
1186 static bool check_unique_keys(
TABLE *table)
1188 bool all_fields, some_fields;
1190 uint keys= table->s->keys;
1192 DBUG_ENTER(
"check_unique_keys");
1194 for (i= 0; i < keys; i++)
1196 if (table->key_info[i].
flags & HA_NOSAME)
1198 set_indicator_in_key_fields(table->key_info+i);
1199 check_fields_in_PF(table->part_info->full_part_field_array,
1200 &all_fields, &some_fields);
1201 clear_indicator_in_key_fields(table->key_info+i);
1202 if (unlikely(!all_fields))
1204 my_error(ER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF,MYF(0),
"UNIQUE INDEX");
1210 DBUG_RETURN(result);
1266 void check_range_capable_PF(
TABLE *table)
1268 DBUG_ENTER(
"check_range_capable_PF");
1288 static bool set_up_partition_bitmaps(THD *thd,
partition_info *part_info)
1291 uint bitmap_bits= part_info->num_subparts?
1292 (part_info->num_subparts* part_info->num_parts):
1293 part_info->num_parts;
1294 uint bitmap_bytes= bitmap_buffer_size(bitmap_bits);
1295 DBUG_ENTER(
"set_up_partition_bitmaps");
1297 DBUG_ASSERT(!part_info->bitmaps_are_initialized);
1300 if (!(bitmap_buf= (uint32*) alloc_root(&part_info->table->
mem_root,
1303 mem_alloc_error(bitmap_bytes * 2);
1306 bitmap_init(&part_info->read_partitions, bitmap_buf, bitmap_bits, FALSE);
1308 bitmap_init(&part_info->lock_partitions, bitmap_buf + (bitmap_bytes / 4),
1309 bitmap_bits, FALSE);
1310 part_info->bitmaps_are_initialized= TRUE;
1311 part_info->set_partition_bitmaps(NULL);
1340 static void set_up_partition_key_maps(
TABLE *table,
1343 uint keys= table->s->keys;
1345 bool all_fields, some_fields;
1346 DBUG_ENTER(
"set_up_partition_key_maps");
1348 part_info->all_fields_in_PF.clear_all();
1349 part_info->all_fields_in_PPF.clear_all();
1350 part_info->all_fields_in_SPF.clear_all();
1351 part_info->some_fields_in_PF.clear_all();
1352 for (i= 0; i < keys; i++)
1354 set_indicator_in_key_fields(table->key_info+i);
1355 check_fields_in_PF(part_info->full_part_field_array,
1356 &all_fields, &some_fields);
1358 part_info->all_fields_in_PF.set_bit(i);
1360 part_info->some_fields_in_PF.set_bit(i);
1361 if (part_info->is_sub_partitioned())
1363 check_fields_in_PF(part_info->part_field_array,
1364 &all_fields, &some_fields);
1366 part_info->all_fields_in_PPF.set_bit(i);
1367 check_fields_in_PF(part_info->subpart_field_array,
1368 &all_fields, &some_fields);
1370 part_info->all_fields_in_SPF.set_bit(i);
1372 clear_indicator_in_key_fields(table->key_info+i);
1395 static void set_up_partition_func_pointers(
partition_info *part_info)
1397 DBUG_ENTER(
"set_up_partition_func_pointers");
1399 if (part_info->is_sub_partitioned())
1401 part_info->get_partition_id= get_partition_id_with_sub;
1402 if (part_info->part_type == RANGE_PARTITION)
1404 if (part_info->column_list)
1405 part_info->get_part_partition_id= get_partition_id_range_col;
1407 part_info->get_part_partition_id= get_partition_id_range;
1408 if (part_info->list_of_subpart_fields)
1410 if (part_info->linear_hash_ind)
1411 part_info->get_subpartition_id= get_partition_id_linear_key_sub;
1413 part_info->get_subpartition_id= get_partition_id_key_sub;
1417 if (part_info->linear_hash_ind)
1418 part_info->get_subpartition_id= get_partition_id_linear_hash_sub;
1420 part_info->get_subpartition_id= get_partition_id_hash_sub;
1425 if (part_info->column_list)
1426 part_info->get_part_partition_id= get_partition_id_list_col;
1428 part_info->get_part_partition_id= get_partition_id_list;
1429 if (part_info->list_of_subpart_fields)
1431 if (part_info->linear_hash_ind)
1432 part_info->get_subpartition_id= get_partition_id_linear_key_sub;
1434 part_info->get_subpartition_id= get_partition_id_key_sub;
1438 if (part_info->linear_hash_ind)
1439 part_info->get_subpartition_id= get_partition_id_linear_hash_sub;
1441 part_info->get_subpartition_id= get_partition_id_hash_sub;
1447 part_info->get_part_partition_id= NULL;
1448 part_info->get_subpartition_id= NULL;
1449 if (part_info->part_type == RANGE_PARTITION)
1451 if (part_info->column_list)
1452 part_info->get_partition_id= get_partition_id_range_col;
1454 part_info->get_partition_id= get_partition_id_range;
1456 else if (part_info->part_type == LIST_PARTITION)
1458 if (part_info->column_list)
1459 part_info->get_partition_id= get_partition_id_list_col;
1461 part_info->get_partition_id= get_partition_id_list;
1465 if (part_info->list_of_part_fields)
1467 if (part_info->linear_hash_ind)
1468 part_info->get_partition_id= get_partition_id_linear_key_nosub;
1470 part_info->get_partition_id= get_partition_id_key_nosub;
1474 if (part_info->linear_hash_ind)
1475 part_info->get_partition_id= get_partition_id_linear_hash_nosub;
1477 part_info->get_partition_id= get_partition_id_hash_nosub;
1490 if (part_info->part_charset_field_array)
1492 if (part_info->is_sub_partitioned())
1494 DBUG_ASSERT(part_info->get_part_partition_id);
1495 if (!part_info->column_list)
1497 part_info->get_part_partition_id_charset=
1498 part_info->get_part_partition_id;
1499 part_info->get_part_partition_id= get_part_id_charset_func_part;
1504 DBUG_ASSERT(part_info->get_partition_id);
1505 if (!part_info->column_list)
1507 part_info->get_part_partition_id_charset= part_info->get_partition_id;
1508 part_info->get_part_partition_id= get_part_id_charset_func_part;
1512 if (part_info->subpart_charset_field_array)
1514 DBUG_ASSERT(part_info->get_subpartition_id);
1515 part_info->get_subpartition_id_charset=
1516 part_info->get_subpartition_id;
1517 part_info->get_subpartition_id= get_part_id_charset_func_subpart;
1536 void set_linear_hash_mask(
partition_info *part_info, uint num_parts)
1540 for (mask= 1; mask < num_parts; mask<<=1)
1542 part_info->linear_hash_mask= mask - 1;
1566 static uint32 get_part_id_from_linear_hash(longlong hash_value, uint mask,
1569 uint32 part_id= (uint32)(hash_value & mask);
1571 if (part_id >= num_parts)
1573 uint new_mask= ((mask + 1) >> 1) - 1;
1574 part_id= (uint32)(hash_value & new_mask);
1593 bool field_is_partition_charset(
Field *field)
1595 if (!(field->type() == MYSQL_TYPE_STRING) &&
1596 !(field->type() == MYSQL_TYPE_VARCHAR))
1600 if (!(field->type() == MYSQL_TYPE_STRING) ||
1601 !(cs->state & MY_CS_BINSORT))
1628 bool check_part_func_fields(
Field **ptr,
bool ok_with_charsets)
1631 DBUG_ENTER(
"check_part_func_fields");
1633 while ((field= *(ptr++)))
1640 if (field_is_partition_charset(field))
1643 if (!ok_with_charsets ||
1645 cs->strxfrm_multiply > 1)
1682 bool fix_partition_func(THD *thd,
TABLE *table,
1683 bool is_create_table_ind)
1687 enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
1688 DBUG_ENTER(
"fix_partition_func");
1690 if (part_info->fixed)
1694 thd->mark_used_columns= MARK_COLUMNS_NONE;
1695 DBUG_PRINT(
"info", (
"thd->mark_used_columns: %d", thd->mark_used_columns));
1697 if (!is_create_table_ind ||
1698 thd->lex->sql_command != SQLCOM_CREATE_TABLE)
1700 if (partition_default_handling(table, part_info,
1701 is_create_table_ind,
1702 table->s->normalized_path.str))
1707 if (part_info->is_sub_partitioned())
1709 DBUG_ASSERT(part_info->subpart_type == HASH_PARTITION);
1714 if (part_info->linear_hash_ind)
1715 set_linear_hash_mask(part_info, part_info->num_subparts);
1716 if (part_info->list_of_subpart_fields)
1719 if (unlikely(handle_list_of_fields(it, table, part_info, TRUE)))
1724 if (unlikely(fix_fields_part_func(thd, part_info->subpart_expr,
1725 table, TRUE, is_create_table_ind)))
1727 if (unlikely(part_info->subpart_expr->result_type() != INT_RESULT))
1729 part_info->report_part_expr_error(TRUE);
1734 DBUG_ASSERT(part_info->part_type != NOT_A_PARTITION);
1739 if (part_info->part_type == HASH_PARTITION)
1741 if (part_info->linear_hash_ind)
1742 set_linear_hash_mask(part_info, part_info->num_parts);
1743 if (part_info->list_of_part_fields)
1746 if (unlikely(handle_list_of_fields(it, table, part_info, FALSE)))
1751 if (unlikely(fix_fields_part_func(thd, part_info->part_expr,
1752 table, FALSE, is_create_table_ind)))
1754 if (unlikely(part_info->part_expr->result_type() != INT_RESULT))
1756 part_info->report_part_expr_error(FALSE);
1760 part_info->fixed= TRUE;
1764 const char *error_str;
1765 if (part_info->column_list)
1768 if (unlikely(handle_list_of_fields(it, table, part_info, FALSE)))
1773 if (unlikely(fix_fields_part_func(thd, part_info->part_expr,
1774 table, FALSE, is_create_table_ind)))
1777 part_info->fixed= TRUE;
1778 if (part_info->part_type == RANGE_PARTITION)
1780 error_str= partition_keywords[PKW_RANGE].str;
1781 if (unlikely(part_info->check_range_constants(thd)))
1784 else if (part_info->part_type == LIST_PARTITION)
1786 error_str= partition_keywords[PKW_LIST].str;
1787 if (unlikely(part_info->check_list_constants(thd)))
1793 my_error(ER_INCONSISTENT_PARTITION_INFO_ERROR, MYF(0));
1796 if (unlikely(part_info->num_parts < 1))
1798 my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), error_str);
1801 if (unlikely(!part_info->column_list &&
1802 part_info->part_expr->result_type() != INT_RESULT))
1804 part_info->report_part_expr_error(FALSE);
1808 if (((part_info->part_type != HASH_PARTITION ||
1809 part_info->list_of_part_fields == FALSE) &&
1810 !part_info->column_list &&
1811 check_part_func_fields(part_info->part_field_array, TRUE)) ||
1812 (part_info->list_of_subpart_fields == FALSE &&
1813 part_info->is_sub_partitioned() &&
1814 check_part_func_fields(part_info->subpart_field_array, TRUE)))
1820 my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
1823 if (unlikely(create_full_part_field_array(thd, table, part_info)))
1825 if (unlikely(check_primary_key(table)))
1827 if (unlikely((!(table->s->db_type()->partition_flags &&
1828 (table->s->db_type()->partition_flags() & HA_CAN_PARTITION_UNIQUE))) &&
1829 check_unique_keys(table)))
1831 if (unlikely(set_up_partition_bitmaps(thd, part_info)))
1833 if (unlikely(part_info->set_up_charset_field_preps()))
1835 my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
1838 if (unlikely(part_info->check_partition_field_length()))
1840 my_error(ER_PARTITION_FIELDS_TOO_LONG, MYF(0));
1843 check_range_capable_PF(table);
1844 set_up_partition_key_maps(table, part_info);
1845 set_up_partition_func_pointers(part_info);
1846 set_up_range_analysis_info(part_info);
1847 table->file->set_part_info(part_info, FALSE);
1850 thd->mark_used_columns= save_mark_used_columns;
1851 DBUG_PRINT(
"info", (
"thd->mark_used_columns: %d", thd->mark_used_columns));
1852 DBUG_RETURN(result);
1864 static int add_write(File fptr,
const char *buf, uint len)
1866 uint ret_code=
mysql_file_write(fptr, (
const uchar*)buf, len, MYF(MY_FNABP));
1868 if (likely(ret_code == 0))
1874 static int add_string_object(File fptr,
String *
string)
1876 return add_write(fptr, string->ptr(),
string->length());
1879 static int add_string(File fptr,
const char *
string)
1881 return add_write(fptr,
string, strlen(
string));
1884 static int add_string_len(File fptr,
const char *
string, uint len)
1886 return add_write(fptr,
string, len);
1889 static int add_space(File fptr)
1891 return add_string(fptr, space_str);
1894 static int add_comma(File fptr)
1896 return add_string(fptr, comma_str);
1899 static int add_equal(File fptr)
1901 return add_string(fptr, equal_str);
1904 static int add_end_parenthesis(File fptr)
1906 return add_string(fptr, end_paren_str);
1909 static int add_begin_parenthesis(File fptr)
1911 return add_string(fptr, begin_paren_str);
1914 static int add_part_key_word(File fptr,
const char *key_string)
1916 int err= add_string(fptr, key_string);
1917 err+= add_space(fptr);
1921 static int add_partition(File fptr)
1924 strxmov(buff, part_str, space_str, NullS);
1925 return add_string(fptr, buff);
1928 static int add_subpartition(File fptr)
1930 int err= add_string(fptr, sub_str);
1932 return err + add_partition(fptr);
1935 static int add_partition_by(File fptr)
1938 strxmov(buff, part_str, space_str, by_str, space_str, NullS);
1939 return add_string(fptr, buff);
1942 static int add_subpartition_by(File fptr)
1944 int err= add_string(fptr, sub_str);
1946 return err + add_partition_by(fptr);
1949 static int add_part_field_list(File fptr,
List<char> field_list)
1955 num_fields= field_list.elements;
1957 err+= add_begin_parenthesis(fptr);
1958 while (i < num_fields)
1961 String field_string(
"", 0, system_charset_info);
1962 THD *thd= current_thd;
1963 ulonglong save_options= thd->variables.option_bits;
1964 thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE;
1965 append_identifier(thd, &field_string, field_str,
1967 thd->variables.option_bits= save_options;
1968 err+= add_string_object(fptr, &field_string);
1969 if (i != (num_fields-1))
1970 err+= add_comma(fptr);
1973 err+= add_end_parenthesis(fptr);
1977 static int add_name_string(File fptr,
const char *name)
1980 String name_string(
"", 0, system_charset_info);
1981 THD *thd= current_thd;
1982 ulonglong save_options= thd->variables.option_bits;
1983 thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE;
1984 append_identifier(thd, &name_string, name,
1986 thd->variables.option_bits= save_options;
1987 err= add_string_object(fptr, &name_string);
1991 static int add_int(File fptr, longlong number)
1994 llstr(number, buff);
1995 return add_string(fptr, buff);
1998 static int add_uint(File fptr, ulonglong number)
2001 longlong2str(number, buff, 10);
2002 return add_string(fptr, buff);
2009 static int add_quoted_string(File fptr,
const char *quotestr)
2011 String orgstr(quotestr, system_charset_info);
2013 int err= add_string(fptr,
"'");
2014 err+= append_escaped(&escapedstr, &orgstr);
2015 err+= add_string(fptr, escapedstr.c_ptr_safe());
2016 return err + add_string(fptr,
"'");
2026 void truncate_partition_filename(
char *path)
2030 char* last_slash= strrchr(path, FN_LIBCHAR);
2033 last_slash= strrchr(path, FN_LIBCHAR2);
2038 for (
char* pound= strchr(last_slash,
'#');
2039 pound; pound = strchr(pound + 1,
'#'))
2041 if ((pound[1] ==
'P' || pound[1] ==
'p') && pound[2] ==
'#')
2043 last_slash[0] =
'\0';
2063 static int add_keyword_path(File fptr,
const char *keyword,
2066 int err= add_string(fptr, keyword);
2068 err+= add_space(fptr);
2069 err+= add_equal(fptr);
2070 err+= add_space(fptr);
2073 strcpy(temp_path, path);
2077 uint length= strlen(temp_path);
2078 for (pos= temp_path, end= pos+length ; pos < end ; pos++)
2089 truncate_partition_filename(temp_path);
2091 err+= add_quoted_string(fptr, temp_path);
2093 return err + add_space(fptr);
2096 static int add_keyword_string(File fptr,
const char *keyword,
2097 bool should_use_quotes,
2100 int err= add_string(fptr, keyword);
2102 err+= add_space(fptr);
2103 err+= add_equal(fptr);
2104 err+= add_space(fptr);
2105 if (should_use_quotes)
2106 err+= add_quoted_string(fptr, keystr);
2108 err+= add_string(fptr, keystr);
2109 return err + add_space(fptr);
2112 static int add_keyword_int(File fptr,
const char *keyword, longlong num)
2114 int err= add_string(fptr, keyword);
2116 err+= add_space(fptr);
2117 err+= add_equal(fptr);
2118 err+= add_space(fptr);
2119 err+= add_int(fptr, num);
2120 return err + add_space(fptr);
2123 static int add_engine(File fptr,
handlerton *engine_type)
2125 const char *engine_str= ha_resolve_storage_engine_name(engine_type);
2126 DBUG_PRINT(
"info", (
"ENGINE: %s", engine_str));
2127 int err= add_string(fptr,
"ENGINE = ");
2128 return err + add_string(fptr, engine_str);
2135 err+= add_space(fptr);
2136 if (p_elem->tablespace_name)
2137 err+= add_keyword_string(fptr,
"TABLESPACE", FALSE,
2138 p_elem->tablespace_name);
2139 if (p_elem->nodegroup_id != UNDEF_NODEGROUP)
2140 err+= add_keyword_int(fptr,
"NODEGROUP",(longlong)p_elem->nodegroup_id);
2141 if (p_elem->part_max_rows)
2142 err+= add_keyword_int(fptr,
"MAX_ROWS",(longlong)p_elem->part_max_rows);
2143 if (p_elem->part_min_rows)
2144 err+= add_keyword_int(fptr,
"MIN_ROWS",(longlong)p_elem->part_min_rows);
2145 if (!(current_thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
2147 if (p_elem->data_file_name)
2148 err+= add_keyword_path(fptr,
"DATA DIRECTORY", p_elem->data_file_name);
2149 if (p_elem->index_file_name)
2150 err+= add_keyword_path(fptr,
"INDEX DIRECTORY", p_elem->index_file_name);
2152 if (p_elem->part_comment)
2153 err+= add_keyword_string(fptr,
"COMMENT", TRUE, p_elem->part_comment);
2154 return err + add_engine(fptr,p_elem->engine_type);
2174 static int check_part_field(enum_field_types sql_type,
2175 const char *field_name,
2176 Item_result *result_type,
2177 bool *need_cs_check)
2179 if (sql_type >= MYSQL_TYPE_TINY_BLOB &&
2180 sql_type <= MYSQL_TYPE_BLOB)
2182 my_error(ER_BLOB_FIELD_IN_PART_FUNC_ERROR, MYF(0));
2187 case MYSQL_TYPE_TINY:
2188 case MYSQL_TYPE_SHORT:
2189 case MYSQL_TYPE_LONG:
2190 case MYSQL_TYPE_LONGLONG:
2191 case MYSQL_TYPE_INT24:
2192 *result_type= INT_RESULT;
2193 *need_cs_check= FALSE;
2195 case MYSQL_TYPE_NEWDATE:
2196 case MYSQL_TYPE_DATE:
2197 case MYSQL_TYPE_TIME:
2198 case MYSQL_TYPE_DATETIME:
2199 case MYSQL_TYPE_TIME2:
2200 case MYSQL_TYPE_DATETIME2:
2201 *result_type= STRING_RESULT;
2202 *need_cs_check= TRUE;
2204 case MYSQL_TYPE_VARCHAR:
2205 case MYSQL_TYPE_STRING:
2206 case MYSQL_TYPE_VAR_STRING:
2207 *result_type= STRING_RESULT;
2208 *need_cs_check= TRUE;
2210 case MYSQL_TYPE_NEWDECIMAL:
2211 case MYSQL_TYPE_DECIMAL:
2212 case MYSQL_TYPE_TIMESTAMP:
2213 case MYSQL_TYPE_TIMESTAMP2:
2214 case MYSQL_TYPE_NULL:
2215 case MYSQL_TYPE_FLOAT:
2216 case MYSQL_TYPE_DOUBLE:
2217 case MYSQL_TYPE_BIT:
2218 case MYSQL_TYPE_ENUM:
2219 case MYSQL_TYPE_SET:
2220 case MYSQL_TYPE_GEOMETRY:
2226 my_error(ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD, MYF(0),
2250 DBUG_ENTER(
"get_sql_field");
2252 while ((sql_field= it++))
2254 if (!(my_strcasecmp(system_charset_info,
2255 sql_field->field_name,
2258 DBUG_RETURN(sql_field);
2265 static int add_column_list_values(File fptr,
partition_info *part_info,
2273 uint num_elements= part_info->part_field_list.elements;
2274 bool use_parenthesis= (part_info->part_type == LIST_PARTITION &&
2275 part_info->num_columns > 1
U);
2277 if (use_parenthesis)
2278 err+= add_begin_parenthesis(fptr);
2279 for (i= 0; i < num_elements; i++)
2282 char *field_name= it++;
2283 if (col_val->max_value)
2284 err+= add_string(fptr, partition_keywords[PKW_MAXVALUE].str);
2285 else if (col_val->null_value)
2286 err+= add_string(fptr,
"NULL");
2289 char buffer[MAX_KEY_LENGTH];
2290 String str(buffer,
sizeof(buffer), &my_charset_bin);
2291 Item *item_expr= col_val->item_expression;
2292 if (item_expr->null_value)
2293 err+= add_string(fptr,
"NULL");
2298 bool need_cs_check= FALSE;
2299 Item_result result_type= STRING_RESULT;
2311 if (!(sql_field= get_sql_field(field_name,
2314 my_error(ER_FIELD_NOT_FOUND_PART_ERROR, MYF(0));
2317 if (check_part_field(sql_field->sql_type,
2318 sql_field->field_name,
2323 field_cs= get_sql_field_charset(sql_field, create_info);
2329 Field *field= part_info->part_field_array[
i];
2330 result_type= field->result_type();
2331 if (check_part_field(field->real_type(),
2336 DBUG_ASSERT(result_type == field->result_type());
2338 field_cs= field->charset();
2342 if (result_type != item_expr->result_type())
2344 my_error(ER_WRONG_TYPE_COLUMN_VALUE_ERROR, MYF(0));
2347 if (field_cs && field_cs != item_expr->collation.collation)
2349 if (!(item_expr= convert_charset_partition_constant(item_expr,
2352 my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
2358 val_conv.set_charset(system_charset_info);
2359 res= item_expr->val_str(&str);
2360 if (get_cs_converted_part_value_from_string(current_thd,
2362 &val_conv, field_cs,
2363 (
bool)(alter_info != NULL)))
2365 err+= add_string_object(fptr, &val_conv);
2369 if (i != (num_elements - 1))
2370 err+= add_string(fptr, comma_str);
2372 if (use_parenthesis)
2373 err+= add_end_parenthesis(fptr);
2377 static int add_partition_values(File fptr,
partition_info *part_info,
2384 if (part_info->part_type == RANGE_PARTITION)
2386 err+= add_string(fptr,
" VALUES LESS THAN ");
2387 if (part_info->column_list)
2391 err+= add_begin_parenthesis(fptr);
2392 err+= add_column_list_values(fptr, part_info, list_value,
2393 create_info, alter_info);
2394 err+= add_end_parenthesis(fptr);
2398 if (!p_elem->max_value)
2400 err+= add_begin_parenthesis(fptr);
2401 if (p_elem->signed_flag)
2402 err+= add_int(fptr, p_elem->range_value);
2404 err+= add_uint(fptr, p_elem->range_value);
2405 err+= add_end_parenthesis(fptr);
2408 err+= add_string(fptr, partition_keywords[PKW_MAXVALUE].str);
2411 else if (part_info->part_type == LIST_PARTITION)
2415 err+= add_string(fptr,
" VALUES IN ");
2416 uint num_items= p_elem->list_val_list.elements;
2418 err+= add_begin_parenthesis(fptr);
2419 if (p_elem->has_null_value)
2421 err+= add_string(fptr,
"NULL");
2424 err+= add_end_parenthesis(fptr);
2427 err+= add_comma(fptr);
2434 if (part_info->column_list)
2435 err+= add_column_list_values(fptr, part_info, list_value,
2436 create_info, alter_info);
2439 if (!list_value->unsigned_flag)
2440 err+= add_int(fptr, list_value->value);
2442 err+= add_uint(fptr, list_value->value);
2444 if (i != (num_items-1))
2445 err+= add_comma(fptr);
2446 }
while (++i < num_items);
2447 err+= add_end_parenthesis(fptr);
2467 static int add_key_with_algorithm(File fptr,
partition_info *part_info,
2468 const char *current_comment_start)
2471 err+= add_part_key_word(fptr, partition_keywords[PKW_KEY].str);
2478 if (part_info->key_algorithm == partition_info::KEY_ALGORITHM_51 ||
2479 (!current_comment_start &&
2480 (part_info->key_algorithm != partition_info::KEY_ALGORITHM_NONE)))
2483 if (current_comment_start)
2484 err+= add_string(fptr,
"*/ ");
2485 err+= add_string(fptr,
"/*!50611 ");
2486 err+= add_part_key_word(fptr, partition_keywords[PKW_ALGORITHM].str);
2487 err+= add_equal(fptr);
2488 err+= add_space(fptr);
2489 err+= add_int(fptr, part_info->key_algorithm);
2490 err+= add_space(fptr);
2491 err+= add_string(fptr,
"*/ ");
2492 if (current_comment_start)
2495 if (current_comment_start[0] ==
'\n')
2496 current_comment_start++;
2497 err+= add_string(fptr, current_comment_start);
2498 err+= add_space(fptr);
2547 bool show_partition_options,
2550 const char *current_comment_start)
2552 uint
i,j, tot_num_parts, num_subparts;
2554 ulonglong buffer_length;
2555 char path[FN_REFLEN];
2560 DBUG_ENTER(
"generate_partition_syntax");
2562 if (unlikely(((fptr= create_temp_file(path,mysql_tmpdir,
"psy",
2563 O_RDWR | O_BINARY | O_TRUNC |
2564 O_TEMPORARY, MYF(MY_WME)))) < 0))
2569 err+= add_space(fptr);
2570 err+= add_partition_by(fptr);
2571 switch (part_info->part_type)
2573 case RANGE_PARTITION:
2574 err+= add_part_key_word(fptr, partition_keywords[PKW_RANGE].str);
2576 case LIST_PARTITION:
2577 err+= add_part_key_word(fptr, partition_keywords[PKW_LIST].str);
2579 case HASH_PARTITION:
2580 if (part_info->linear_hash_ind)
2581 err+= add_string(fptr, partition_keywords[PKW_LINEAR].str);
2582 if (part_info->list_of_part_fields)
2584 err+= add_key_with_algorithm(fptr, part_info,
2585 current_comment_start);
2586 err+= add_part_field_list(fptr, part_info->part_field_list);
2589 err+= add_part_key_word(fptr, partition_keywords[PKW_HASH].str);
2594 my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
2597 if (part_info->part_expr)
2599 err+= add_begin_parenthesis(fptr);
2600 err+= add_string_len(fptr, part_info->part_func_string,
2601 part_info->part_func_len);
2602 err+= add_end_parenthesis(fptr);
2604 else if (part_info->column_list)
2606 err+= add_string(fptr, partition_keywords[PKW_COLUMNS].str);
2607 err+= add_part_field_list(fptr, part_info->part_field_list);
2609 if ((!part_info->use_default_num_partitions) &&
2610 part_info->use_default_partitions)
2612 err+= add_string(fptr,
"\n");
2613 err+= add_string(fptr,
"PARTITIONS ");
2614 err+= add_int(fptr, part_info->num_parts);
2616 if (part_info->is_sub_partitioned())
2618 err+= add_string(fptr,
"\n");
2619 err+= add_subpartition_by(fptr);
2621 if (part_info->linear_hash_ind)
2622 err+= add_string(fptr, partition_keywords[PKW_LINEAR].str);
2623 if (part_info->list_of_subpart_fields)
2625 err+= add_key_with_algorithm(fptr, part_info,
2626 current_comment_start);
2627 err+= add_part_field_list(fptr, part_info->subpart_field_list);
2630 err+= add_part_key_word(fptr, partition_keywords[PKW_HASH].str);
2631 if (part_info->subpart_expr)
2633 err+= add_begin_parenthesis(fptr);
2634 err+= add_string_len(fptr, part_info->subpart_func_string,
2635 part_info->subpart_func_len);
2636 err+= add_end_parenthesis(fptr);
2638 if ((!part_info->use_default_num_subpartitions) &&
2639 part_info->use_default_subpartitions)
2641 err+= add_string(fptr,
"\n");
2642 err+= add_string(fptr,
"SUBPARTITIONS ");
2643 err+= add_int(fptr, part_info->num_subparts);
2646 tot_num_parts= part_info->partitions.elements;
2647 num_subparts= part_info->num_subparts;
2649 if (!part_info->use_default_partitions)
2652 err+= add_string(fptr,
"\n");
2653 err+= add_begin_parenthesis(fptr);
2657 part_elem= part_it++;
2658 if (part_elem->part_state != PART_TO_BE_DROPPED &&
2659 part_elem->part_state != PART_REORGED_DROPPED)
2663 err+= add_comma(fptr);
2664 err+= add_string(fptr,
"\n");
2665 err+= add_space(fptr);
2668 err+= add_partition(fptr);
2669 err+= add_name_string(fptr, part_elem->partition_name);
2670 err+= add_partition_values(fptr, part_info, part_elem,
2671 create_info, alter_info);
2672 if (!part_info->is_sub_partitioned() ||
2673 part_info->use_default_subpartitions)
2675 if (show_partition_options)
2676 err+= add_partition_options(fptr, part_elem);
2680 err+= add_string(fptr,
"\n");
2681 err+= add_space(fptr);
2682 err+= add_begin_parenthesis(fptr);
2687 part_elem= sub_it++;
2688 err+= add_subpartition(fptr);
2689 err+= add_name_string(fptr, part_elem->partition_name);
2690 if (show_partition_options)
2691 err+= add_partition_options(fptr, part_elem);
2692 if (j != (num_subparts-1))
2694 err+= add_comma(fptr);
2695 err+= add_string(fptr,
"\n");
2696 err+= add_space(fptr);
2697 err+= add_space(fptr);
2700 err+= add_end_parenthesis(fptr);
2701 }
while (++j < num_subparts);
2704 if (i == (tot_num_parts-1))
2705 err+= add_end_parenthesis(fptr);
2706 }
while (++i < tot_num_parts);
2711 if (unlikely(buffer_length == MY_FILEPOS_ERROR))
2714 == MY_FILEPOS_ERROR))
2716 *buf_length= (uint)buffer_length;
2718 buf= (
char*) sql_alloc(*buf_length+1);
2720 buf= (
char*) my_malloc(*buf_length+1, MYF(MY_WME));
2732 buf[*buf_length]= 0;
2754 bool partition_key_modified(
TABLE *table,
const MY_BITMAP *fields)
2758 DBUG_ENTER(
"partition_key_modified");
2762 if (table->s->db_type()->partition_flags &&
2763 (table->s->db_type()->partition_flags() & HA_CAN_UPDATE_PARTITION_KEY))
2765 for (fld= part_info->full_part_field_array; *fld; fld++)
2766 if (bitmap_is_set(fields, (*fld)->field_index))
2785 static inline int part_val_int(
Item *item_expr, longlong *result)
2787 *result= item_expr->val_int();
2788 if (item_expr->null_value)
2790 if (current_thd->is_error())
2793 *result= LONGLONG_MIN;
2829 static uint32 get_part_id_for_sub(uint32 loc_part_id, uint32 sub_part_id,
2832 return (uint32)((loc_part_id * num_subparts) + sub_part_id);
2851 static int get_part_id_hash(uint num_parts,
2854 longlong *func_value)
2856 longlong int_hash_id;
2857 DBUG_ENTER(
"get_part_id_hash");
2859 if (part_val_int(part_expr, func_value))
2860 DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
2862 int_hash_id= *func_value % num_parts;
2864 *part_id= int_hash_id < 0 ? (uint32) -int_hash_id : (uint32) int_hash_id;
2890 longlong *func_value)
2892 DBUG_ENTER(
"get_part_id_linear_hash");
2894 if (part_val_int(part_expr, func_value))
2895 DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
2897 *part_id= get_part_id_from_linear_hash(*func_value,
2898 part_info->linear_hash_mask,
2917 Field **field_array,
2919 longlong *func_value)
2921 DBUG_ENTER(
"get_part_id_key");
2922 *func_value= file->calculate_key_hash_value(field_array);
2923 DBUG_RETURN((uint32) (*func_value % num_parts));
2943 Field **field_array,
2945 longlong *func_value)
2947 DBUG_ENTER(
"get_part_id_linear_key");
2949 *func_value= part_info->table->file->calculate_key_hash_value(field_array);
2950 DBUG_RETURN(get_part_id_from_linear_hash(*func_value,
2951 part_info->linear_hash_mask,
2974 static void copy_to_part_field_buffers(
Field **ptr,
2976 uchar **restore_ptr)
2979 while ((field= *(ptr++)))
2981 *restore_ptr= field->ptr;
2983 if (!field->maybe_null() || !field->is_null())
2986 uint max_len= field->pack_length();
2987 uint data_len= field->data_length();
2988 uchar *field_buf= *field_bufs;
2996 if (field->type() == MYSQL_TYPE_VARCHAR)
2999 my_strnxfrm(cs, field_buf + len_bytes, max_len,
3000 field->ptr + len_bytes, data_len);
3002 *field_buf= (uchar) data_len;
3004 int2store(field_buf, data_len);
3008 my_strnxfrm(cs, field_buf, max_len,
3009 field->ptr, max_len);
3011 field->ptr= field_buf;
3028 static void restore_part_field_pointers(
Field **ptr, uchar **restore_ptr)
3031 while ((field= *(ptr++)))
3033 field->ptr= *restore_ptr;
3111 static int get_part_id_charset_func_part(
partition_info *part_info,
3113 longlong *func_value)
3116 DBUG_ENTER(
"get_part_id_charset_func_part");
3118 copy_to_part_field_buffers(part_info->part_charset_field_array,
3119 part_info->part_field_buffers,
3120 part_info->restore_part_field_ptrs);
3121 res= part_info->get_part_partition_id_charset(part_info,
3122 part_id, func_value);
3123 restore_part_field_pointers(part_info->part_charset_field_array,
3124 part_info->restore_part_field_ptrs);
3129 static int get_part_id_charset_func_subpart(
partition_info *part_info,
3133 DBUG_ENTER(
"get_part_id_charset_func_subpart");
3135 copy_to_part_field_buffers(part_info->subpart_charset_field_array,
3136 part_info->subpart_field_buffers,
3137 part_info->restore_subpart_field_ptrs);
3138 res= part_info->get_subpartition_id_charset(part_info, part_id);
3139 restore_part_field_pointers(part_info->subpart_charset_field_array,
3140 part_info->restore_subpart_field_ptrs);
3146 longlong *func_value)
3149 uint num_columns= part_info->part_field_list.elements;
3150 int list_index, cmp;
3151 int min_list_index= 0;
3152 int max_list_index= part_info->num_list_values - 1;
3153 DBUG_ENTER(
"get_partition_id_list_col");
3155 while (max_list_index >= min_list_index)
3157 list_index= (max_list_index + min_list_index) >> 1;
3158 cmp= cmp_rec_and_tuple(list_col_array + list_index*num_columns,
3161 min_list_index= list_index + 1;
3166 max_list_index= list_index - 1;
3170 *part_id= (uint32)list_col_array[list_index*num_columns].partition_id;
3176 DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
3182 longlong *func_value)
3186 int min_list_index= 0;
3187 int max_list_index= part_info->num_list_values - 1;
3188 longlong part_func_value;
3189 int error= part_val_int(part_info->part_expr, &part_func_value);
3190 longlong list_value;
3191 bool unsigned_flag= part_info->part_expr->unsigned_flag;
3192 DBUG_ENTER(
"get_partition_id_list");
3197 if (part_info->part_expr->null_value)
3199 if (part_info->has_null_value)
3201 *part_id= part_info->has_null_part_id;
3206 *func_value= part_func_value;
3208 part_func_value-= 0x8000000000000000ULL;
3209 while (max_list_index >= min_list_index)
3211 list_index= (max_list_index + min_list_index) >> 1;
3212 list_value= list_array[list_index].list_value;
3213 if (list_value < part_func_value)
3214 min_list_index= list_index + 1;
3215 else if (list_value > part_func_value)
3219 max_list_index= list_index - 1;
3223 *part_id= (uint32)list_array[list_index].partition_id;
3229 DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
3233 uint32 get_partition_id_cols_list_for_endpoint(
partition_info *part_info,
3235 bool include_endpoint,
3239 uint num_columns= part_info->part_field_list.elements;
3241 uint min_list_index= 0;
3242 uint max_list_index= part_info->num_list_values;
3243 DBUG_ENTER(
"get_partition_id_cols_list_for_endpoint");
3249 list_index= (max_list_index + min_list_index) >> 1;
3250 if (cmp_rec_and_tuple_prune(list_col_array + list_index*num_columns,
3251 nparts, left_endpoint, include_endpoint) > 0)
3252 min_list_index= list_index + 1;
3254 max_list_index= list_index;
3255 }
while (max_list_index > min_list_index);
3256 list_index= max_list_index;
3259 DBUG_ASSERT(list_index == part_info->num_list_values ||
3260 (0 >= cmp_rec_and_tuple_prune(list_col_array +
3261 list_index*num_columns,
3262 nparts, left_endpoint,
3263 include_endpoint)));
3265 DBUG_ASSERT(list_index == 0 ||
3266 (0 < cmp_rec_and_tuple_prune(list_col_array +
3267 (list_index - 1)*num_columns,
3268 nparts, left_endpoint,
3269 include_endpoint)));
3274 if (list_index < part_info->num_parts)
3278 DBUG_RETURN(list_index);
3315 uint32 get_list_array_idx_for_endpoint_charset(
partition_info *part_info,
3317 bool include_endpoint)
3320 copy_to_part_field_buffers(part_info->part_field_array,
3321 part_info->part_field_buffers,
3322 part_info->restore_part_field_ptrs);
3323 res= get_list_array_idx_for_endpoint(part_info, left_endpoint,
3325 restore_part_field_pointers(part_info->part_field_array,
3326 part_info->restore_part_field_ptrs);
3330 uint32 get_list_array_idx_for_endpoint(
partition_info *part_info,
3332 bool include_endpoint)
3336 uint min_list_index= 0, max_list_index= part_info->num_list_values - 1;
3337 longlong list_value;
3339 longlong part_func_value=
3340 part_info->part_expr->val_int_endpoint(left_endpoint, &include_endpoint);
3341 bool unsigned_flag= part_info->part_expr->unsigned_flag;
3342 DBUG_ENTER(
"get_list_array_idx_for_endpoint");
3344 if (part_info->part_expr->null_value)
3354 enum_monotonicity_info monotonic;
3355 monotonic= part_info->part_expr->get_monotonicity_info();
3356 if (monotonic != MONOTONIC_INCREASING_NOT_NULL &&
3357 monotonic != MONOTONIC_STRICT_INCREASING_NOT_NULL)
3365 part_func_value-= 0x8000000000000000ULL;
3366 DBUG_ASSERT(part_info->num_list_values);
3369 list_index= (max_list_index + min_list_index) >> 1;
3370 list_value= list_array[list_index].list_value;
3371 if (list_value < part_func_value)
3372 min_list_index= list_index + 1;
3373 else if (list_value > part_func_value)
3377 max_list_index= list_index - 1;
3381 DBUG_RETURN(list_index +
test(left_endpoint ^ include_endpoint));
3383 }
while (max_list_index >= min_list_index);
3385 if (list_value < part_func_value)
3387 DBUG_RETURN(list_index);
3393 longlong *func_value)
3396 uint num_columns= part_info->part_field_list.elements;
3397 uint max_partition= part_info->num_parts - 1;
3398 uint min_part_id= 0;
3399 uint max_part_id= max_partition;
3401 DBUG_ENTER(
"get_partition_id_range_col");
3403 while (max_part_id > min_part_id)
3405 loc_part_id= (max_part_id + min_part_id + 1) >> 1;
3406 if (cmp_rec_and_tuple(range_col_array + loc_part_id*num_columns,
3408 min_part_id= loc_part_id + 1;
3410 max_part_id= loc_part_id - 1;
3412 loc_part_id= max_part_id;
3413 if (loc_part_id != max_partition)
3414 if (cmp_rec_and_tuple(range_col_array + loc_part_id*num_columns,
3417 *part_id= (uint32)loc_part_id;
3418 if (loc_part_id == max_partition &&
3419 (cmp_rec_and_tuple(range_col_array + loc_part_id*num_columns,
3421 DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
3423 DBUG_PRINT(
"exit",(
"partition: %d", *part_id));
3430 longlong *func_value)
3432 longlong *range_array= part_info->range_int_array;
3433 uint max_partition= part_info->num_parts - 1;
3434 uint min_part_id= 0;
3435 uint max_part_id= max_partition;
3437 longlong part_func_value;
3438 int error= part_val_int(part_info->part_expr, &part_func_value);
3439 bool unsigned_flag= part_info->part_expr->unsigned_flag;
3440 DBUG_ENTER(
"get_partition_id_range");
3443 DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
3445 if (part_info->part_expr->null_value)
3450 *func_value= part_func_value;
3452 part_func_value-= 0x8000000000000000ULL;
3454 while (max_part_id > min_part_id)
3456 loc_part_id= (max_part_id + min_part_id) / 2;
3457 if (range_array[loc_part_id] <= part_func_value)
3458 min_part_id= loc_part_id + 1;
3460 max_part_id= loc_part_id;
3462 loc_part_id= max_part_id;
3463 *part_id= (uint32)loc_part_id;
3464 if (loc_part_id == max_partition &&
3465 part_func_value >= range_array[loc_part_id] &&
3466 !part_info->defined_max_value)
3467 DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
3469 DBUG_PRINT(
"exit",(
"partition: %d", *part_id));
3516 get_partition_id_range_for_endpoint_charset(
partition_info *part_info,
3518 bool include_endpoint)
3521 copy_to_part_field_buffers(part_info->part_field_array,
3522 part_info->part_field_buffers,
3523 part_info->restore_part_field_ptrs);
3524 res= get_partition_id_range_for_endpoint(part_info, left_endpoint,
3526 restore_part_field_pointers(part_info->part_field_array,
3527 part_info->restore_part_field_ptrs);
3531 uint32 get_partition_id_range_for_endpoint(
partition_info *part_info,
3533 bool include_endpoint)
3535 longlong *range_array= part_info->range_int_array;
3536 longlong part_end_val;
3537 uint max_partition= part_info->num_parts - 1;
3538 uint min_part_id= 0, max_part_id= max_partition, loc_part_id;
3540 longlong part_func_value=
3541 part_info->part_expr->val_int_endpoint(left_endpoint, &include_endpoint);
3543 bool unsigned_flag= part_info->part_expr->unsigned_flag;
3544 DBUG_ENTER(
"get_partition_id_range_for_endpoint");
3546 if (part_info->part_expr->null_value)
3557 enum_monotonicity_info monotonic;
3558 monotonic= part_info->part_expr->get_monotonicity_info();
3559 if (monotonic != MONOTONIC_INCREASING_NOT_NULL &&
3560 monotonic != MONOTONIC_STRICT_INCREASING_NOT_NULL)
3563 if (!left_endpoint && include_endpoint)
3571 part_func_value-= 0x8000000000000000ULL;
3572 if (left_endpoint && !include_endpoint)
3579 while (max_part_id > min_part_id)
3581 loc_part_id= (max_part_id + min_part_id) / 2;
3582 if (range_array[loc_part_id] < part_func_value)
3583 min_part_id= loc_part_id + 1;
3585 max_part_id= loc_part_id;
3587 loc_part_id= max_part_id;
3590 part_end_val= range_array[loc_part_id];
3593 DBUG_ASSERT(part_func_value > part_end_val ?
3594 (loc_part_id == max_partition &&
3595 !part_info->defined_max_value) :
3603 if (part_func_value >= part_end_val &&
3604 (loc_part_id < max_partition || !part_info->defined_max_value))
3610 if (include_endpoint && loc_part_id < max_partition &&
3611 part_func_value == part_end_val)
3617 DBUG_RETURN(loc_part_id);
3623 longlong *func_value)
3625 return get_part_id_hash(part_info->num_parts, part_info->part_expr,
3626 part_id, func_value);
3630 int get_partition_id_linear_hash_nosub(
partition_info *part_info,
3632 longlong *func_value)
3634 return get_part_id_linear_hash(part_info, part_info->num_parts,
3635 part_info->part_expr, part_id, func_value);
3641 longlong *func_value)
3643 *part_id= get_part_id_key(part_info->table->file,
3644 part_info->part_field_array,
3645 part_info->num_parts, func_value);
3652 longlong *func_value)
3654 *part_id= get_part_id_linear_key(part_info,
3655 part_info->part_field_array,
3656 part_info->num_parts, func_value);
3663 longlong *func_value)
3665 uint32 loc_part_id, sub_part_id;
3668 DBUG_ENTER(
"get_partition_id_with_sub");
3670 if (unlikely((error= part_info->get_part_partition_id(part_info,
3676 num_subparts= part_info->num_subparts;
3677 if (unlikely((error= part_info->get_subpartition_id(part_info,
3682 *part_id= get_part_id_for_sub(loc_part_id, sub_part_id, num_subparts);
3714 longlong func_value;
3715 return get_part_id_hash(part_info->num_subparts, part_info->subpart_expr,
3716 part_id, &func_value);
3723 longlong func_value;
3724 return get_part_id_linear_hash(part_info, part_info->num_subparts,
3725 part_info->subpart_expr, part_id,
3733 longlong func_value;
3734 *part_id= get_part_id_key(part_info->table->file,
3735 part_info->subpart_field_array,
3736 part_info->num_subparts, &func_value);
3744 longlong func_value;
3745 *part_id= get_part_id_linear_key(part_info,
3746 part_info->subpart_field_array,
3747 part_info->num_subparts, &func_value);
3765 static bool set_PF_fields_in_key(
KEY *key_info, uint key_length)
3768 bool found_part_field= FALSE;
3769 DBUG_ENTER(
"set_PF_fields_in_key");
3771 for (key_part= key_info->key_part; (
int)key_length > 0; key_part++)
3773 if (key_part->null_bit)
3775 if (key_part->type == HA_KEYTYPE_BIT)
3777 if (((
Field_bit*)key_part->field)->bit_len)
3780 if (key_part->key_part_flag & (HA_BLOB_PART + HA_VAR_LENGTH_PART))
3782 key_length-= HA_KEY_BLOB_LENGTH;
3784 if (key_length < key_part->length)
3786 key_length-= key_part->length;
3787 if (key_part->field->flags & FIELD_IN_PART_FUNC_FLAG)
3789 found_part_field= TRUE;
3790 key_part->field->flags|= GET_FIXED_FIELDS_FLAG;
3793 DBUG_RETURN(found_part_field);
3810 static bool check_part_func_bound(
Field **ptr)
3813 DBUG_ENTER(
"check_part_func_bound");
3817 if (!((*ptr)->flags & GET_FIXED_FIELDS_FLAG))
3823 DBUG_RETURN(result);
3848 static int get_sub_part_id_from_key(
const TABLE *table,uchar *buf,
3853 uchar *rec0= table->record[0];
3856 DBUG_ENTER(
"get_sub_part_id_from_key");
3858 key_restore(buf, (uchar*)key_spec->key, key_info, key_spec->length);
3859 if (likely(rec0 == buf))
3861 res= part_info->get_subpartition_id(part_info, part_id);
3865 Field **part_field_array= part_info->subpart_field_array;
3866 set_field_ptr(part_field_array, buf, rec0);
3867 res= part_info->get_subpartition_id(part_info, part_id);
3868 set_field_ptr(part_field_array, rec0, buf);
3894 bool get_part_id_from_key(
const TABLE *table, uchar *buf,
KEY *key_info,
3895 const key_range *key_spec, uint32 *part_id)
3898 uchar *rec0= table->record[0];
3900 longlong func_value;
3901 DBUG_ENTER(
"get_part_id_from_key");
3903 key_restore(buf, (uchar*)key_spec->key, key_info, key_spec->length);
3904 if (likely(rec0 == buf))
3906 result= part_info->get_part_partition_id(part_info, part_id,
3911 Field **part_field_array= part_info->part_field_array;
3912 set_field_ptr(part_field_array, buf, rec0);
3913 result= part_info->get_part_partition_id(part_info, part_id,
3915 set_field_ptr(part_field_array, rec0, buf);
3917 DBUG_RETURN(result);
3941 void get_full_part_id_from_key(
const TABLE *table, uchar *buf,
3948 uchar *rec0= table->record[0];
3949 longlong func_value;
3950 DBUG_ENTER(
"get_full_part_id_from_key");
3952 key_restore(buf, (uchar*)key_spec->key, key_info, key_spec->length);
3953 if (likely(rec0 == buf))
3955 result= part_info->get_partition_id(part_info, &part_spec->start_part,
3960 Field **part_field_array= part_info->full_part_field_array;
3961 set_field_ptr(part_field_array, buf, rec0);
3962 result= part_info->get_partition_id(part_info, &part_spec->start_part,
3964 set_field_ptr(part_field_array, rec0, buf);
3966 part_spec->end_part= part_spec->start_part;
3967 if (unlikely(result))
3968 part_spec->start_part++;
3985 bool verify_data_with_partition(
TABLE *table,
TABLE *part_table,
3988 uint32 found_part_id;
3989 longlong func_value;
3994 DBUG_ENTER(
"verify_data_with_partition");
3995 DBUG_ASSERT(table && table->file && part_table && part_table->part_info &&
4010 part_info= part_table->part_info;
4011 bitmap_union(table->read_set, &part_info->full_part_field_set);
4012 old_rec= part_table->record[0];
4013 part_table->record[0]= table->record[0];
4014 set_field_ptr(part_info->full_part_field_array, table->record[0], old_rec);
4025 if (error == HA_ERR_RECORD_DELETED)
4027 if (error == HA_ERR_END_OF_FILE)
4033 if ((error= part_info->get_partition_id(part_info, &found_part_id,
4039 DEBUG_SYNC(current_thd,
"swap_partition_first_row_read");
4040 if (found_part_id != part_id)
4042 my_error(ER_ROW_DOES_NOT_MATCH_PARTITION, MYF(0));
4049 set_field_ptr(part_info->full_part_field_array, old_rec,
4051 part_table->record[0]= old_rec;
4078 int last_partition= -1;
4082 DBUG_ENTER(
"prune_partition_set");
4083 for (i= part_spec->start_part; i <= part_spec->end_part; i++)
4085 if (bitmap_is_set(&(part_info->read_partitions), i))
4087 DBUG_PRINT(
"info", (
"Partition %d is set", i));
4088 if (last_partition == -1)
4090 part_spec->start_part=
i;
4094 if (last_partition == -1)
4096 part_spec->start_part= part_spec->end_part + 1;
4098 part_spec->end_part= last_partition;
4128 void get_partition_set(
const TABLE *table, uchar *buf,
const uint
index,
4132 uint num_parts= part_info->get_tot_partitions();
4134 uint sub_part= num_parts;
4135 uint32 part_part= num_parts;
4136 KEY *key_info= NULL;
4137 bool found_part_field= FALSE;
4138 DBUG_ENTER(
"get_partition_set");
4140 part_spec->start_part= 0;
4141 part_spec->end_part= num_parts - 1;
4142 if ((index < MAX_KEY) &&
4143 key_spec && key_spec->flag == (uint)HA_READ_KEY_EXACT &&
4144 part_info->some_fields_in_PF.is_set(index))
4146 key_info= table->key_info+
index;
4151 if (key_spec->length == key_info->
key_length)
4159 if (part_info->all_fields_in_PF.is_set(index))
4165 get_full_part_id_from_key(table,buf,key_info,key_spec,part_spec);
4169 prune_partition_set(table, part_spec);
4172 else if (part_info->is_sub_partitioned())
4174 if (part_info->all_fields_in_SPF.is_set(index))
4176 if (get_sub_part_id_from_key(table, buf, key_info, key_spec, &sub_part))
4178 part_spec->start_part= num_parts;
4182 else if (part_info->all_fields_in_PPF.is_set(index))
4184 if (get_part_id_from_key(table,buf,key_info,
4185 key_spec,(uint32*)&part_part))
4192 part_spec->start_part= num_parts;
4207 if ((found_part_field= set_PF_fields_in_key(key_info,
4210 if (check_part_func_bound(part_info->full_part_field_array))
4216 get_full_part_id_from_key(table,buf,key_info,key_spec,part_spec);
4217 clear_indicator_in_key_fields(key_info);
4221 prune_partition_set(table, part_spec);
4224 else if (part_info->is_sub_partitioned())
4226 if (check_part_func_bound(part_info->subpart_field_array))
4228 if (get_sub_part_id_from_key(table, buf, key_info, key_spec, &sub_part))
4230 part_spec->start_part= num_parts;
4231 clear_indicator_in_key_fields(key_info);
4235 else if (check_part_func_bound(part_info->part_field_array))
4237 if (get_part_id_from_key(table,buf,key_info,key_spec,&part_part))
4239 part_spec->start_part= num_parts;
4240 clear_indicator_in_key_fields(key_info);
4260 if (!(part_part == num_parts && sub_part == num_parts))
4265 if (part_part != num_parts)
4271 DBUG_ASSERT(sub_part == num_parts);
4272 part_spec->start_part= part_part * part_info->num_subparts;
4273 part_spec->end_part= part_spec->start_part+part_info->num_subparts - 1;
4277 DBUG_ASSERT(sub_part != num_parts);
4278 part_spec->start_part= sub_part;
4279 part_spec->end_part=sub_part+
4280 (part_info->num_subparts*(part_info->num_parts-1));
4281 for (i= 0, part_id= sub_part; i < part_info->num_parts;
4282 i++, part_id+= part_info->num_subparts)
4286 if (found_part_field)
4287 clear_indicator_in_key_fields(key_info);
4291 prune_partition_set(table, part_spec);
4352 bool mysql_unpack_partition(THD *thd,
4353 char *part_buf, uint part_info_len,
4354 TABLE* table,
bool is_create_table_ind,
4356 bool *work_part_info_used)
4361 thd->variables.character_set_client;
4362 LEX *old_lex= thd->lex;
4364 PSI_statement_locker *parent_locker= thd->m_statement_psi;
4365 DBUG_ENTER(
"mysql_unpack_partition");
4367 thd->variables.character_set_client= system_charset_info;
4369 Parser_state parser_state;
4370 if (parser_state.init(thd, part_buf, part_info_len))
4373 if (init_lex_with_single_table(thd, table, &lex))
4385 *work_part_info_used= FALSE;
4392 part_info= lex.part_info;
4393 DBUG_PRINT(
"info", (
"Parse: %s", part_buf));
4395 thd->m_statement_psi= NULL;
4396 if (
parse_sql(thd, & parser_state, NULL) ||
4397 part_info->fix_parser_data(thd))
4400 thd->m_statement_psi= parent_locker;
4403 thd->m_statement_psi= parent_locker;
4419 DBUG_PRINT(
"info", (
"Successful parse"));
4420 DBUG_PRINT(
"info", (
"default engine = %s, default_db_type = %s",
4421 ha_resolve_storage_engine_name(part_info->default_engine_type),
4422 ha_resolve_storage_engine_name(default_db_type)));
4423 if (is_create_table_ind && old_lex->sql_command == SQLCOM_CREATE_TABLE)
4439 part_info= thd->work_part_info;
4440 *work_part_info_used=
true;
4442 table->part_info= part_info;
4443 part_info->table=
table;
4444 table->file->set_part_info(part_info, TRUE);
4445 if (!part_info->default_engine_type)
4446 part_info->default_engine_type= default_db_type;
4447 DBUG_ASSERT(part_info->default_engine_type == default_db_type);
4448 DBUG_ASSERT(part_info->default_engine_type->db_type != DB_TYPE_UNKNOWN);
4449 DBUG_ASSERT(part_info->default_engine_type != partition_hton);
4461 uint part_func_len= part_info->part_func_len;
4462 uint subpart_func_len= part_info->subpart_func_len;
4463 char *part_func_string= NULL;
4464 char *subpart_func_string= NULL;
4465 if ((part_func_len &&
4466 !((part_func_string= (
char*) thd->alloc(part_func_len)))) ||
4467 (subpart_func_len &&
4468 !((subpart_func_string= (
char*) thd->alloc(subpart_func_len)))))
4470 mem_alloc_error(part_func_len);
4475 memcpy(part_func_string, part_info->part_func_string, part_func_len);
4476 if (subpart_func_len)
4477 memcpy(subpart_func_string, part_info->subpart_func_string,
4479 part_info->part_func_string= part_func_string;
4480 part_info->subpart_func_string= subpart_func_string;
4485 end_lex_with_single_table(thd, table, old_lex);
4486 thd->variables.character_set_client= old_character_set_client;
4487 DBUG_RETURN(result);
4512 part_elem->engine_type= engine_type;
4513 if (part_info->is_sub_partitioned())
4522 sub_elem->engine_type= engine_type;
4523 }
while (++j < part_info->num_subparts);
4525 }
while (++i < part_info->num_parts);
4542 static int fast_end_partition(THD *thd, ulonglong copied,
4547 DBUG_ENTER(
"fast_end_partition");
4549 thd->proc_info=
"end";
4551 query_cache_invalidate3(thd, table_list, 0);
4553 my_snprintf(tmp_name,
sizeof(tmp_name), ER(ER_INSERT_INFO),
4554 (ulong) (copied + deleted),
4557 my_ok(thd, (ha_rows) (copied+deleted),0L, tmp_name);
4583 static bool check_native_partitioned(
HA_CREATE_INFO *create_info,
bool *ret_val,
4586 bool table_engine_set;
4587 handlerton *engine_type= part_info->default_engine_type;
4589 DBUG_ENTER(
"check_native_partitioned");
4591 if (create_info->used_fields & HA_CREATE_USED_ENGINE)
4593 table_engine_set= TRUE;
4594 engine_type= create_info->db_type;
4598 table_engine_set= FALSE;
4599 if (thd->lex->sql_command != SQLCOM_CREATE_TABLE)
4601 table_engine_set= TRUE;
4602 DBUG_ASSERT(engine_type && engine_type != partition_hton);
4605 DBUG_PRINT(
"info", (
"engine_type = %s, table_engine_set = %u",
4606 ha_resolve_storage_engine_name(engine_type),
4608 if (part_info->check_engine_mix(engine_type, table_engine_set))
4617 engine_type= old_engine_type;
4618 DBUG_PRINT(
"info", (
"engine_type = %s",
4619 ha_resolve_storage_engine_name(engine_type)));
4620 if (engine_type->partition_flags &&
4621 (engine_type->partition_flags() & HA_CAN_PARTITION))
4623 create_info->db_type= engine_type;
4624 DBUG_PRINT(
"info", (
"Changed to native partitioning"));
4633 my_error(ER_MIX_HANDLER_ERROR, MYF(0));
4652 enum partition_state part_state)
4655 uint num_parts_found= 0;
4661 if ((alter_info->flags & Alter_info::ALTER_ALL_PARTITION) ||
4662 (is_name_in_list(part_elem->partition_name,
4663 alter_info->partition_names)))
4671 part_elem->part_state= part_state;
4672 DBUG_PRINT(
"info", (
"Setting part_state to %u for partition %s",
4673 part_state, part_elem->partition_name));
4676 part_elem->part_state= PART_NORMAL;
4677 }
while (++part_count < tab_part_info->num_parts);
4679 if (num_parts_found != alter_info->partition_names.elements &&
4680 !(alter_info->flags & Alter_info::ALTER_ALL_PARTITION))
4688 part_elem->part_state= PART_NORMAL;
4689 }
while (++part_count < tab_part_info->num_parts);
4708 bool compare_partition_options(
HA_CREATE_INFO *table_create_info,
4711 #define MAX_COMPARE_PARTITION_OPTION_ERRORS 5
4712 const char *option_diffs[MAX_COMPARE_PARTITION_OPTION_ERRORS + 1];
4714 DBUG_ENTER(
"compare_partition_options");
4715 DBUG_ASSERT(!part_elem->tablespace_name &&
4716 !table_create_info->tablespace);
4722 if (part_elem->tablespace_name || table_create_info->tablespace)
4723 option_diffs[errors++]=
"TABLESPACE";
4724 if (part_elem->part_max_rows != table_create_info->max_rows)
4725 option_diffs[errors++]=
"MAX_ROWS";
4726 if (part_elem->part_min_rows != table_create_info->min_rows)
4727 option_diffs[errors++]=
"MIN_ROWS";
4728 if (part_elem->data_file_name || table_create_info->data_file_name)
4729 option_diffs[errors++]=
"DATA DIRECTORY";
4730 if (part_elem->index_file_name || table_create_info->index_file_name)
4731 option_diffs[errors++]=
"INDEX DIRECTORY";
4733 for (i= 0; i < errors; i++)
4734 my_error(ER_PARTITION_EXCHANGE_DIFFERENT_OPTION, MYF(0),
4736 DBUG_RETURN(errors != 0);
4766 uint prep_alter_part_table(THD *thd,
TABLE *table,
Alter_info *alter_info,
4769 bool *partition_changed,
4770 bool *fast_alter_table)
4772 DBUG_ENTER(
"prep_alter_part_table");
4775 if (table->part_info && (alter_info->flags & Alter_info::ADD_FOREIGN_KEY ||
4776 alter_info->flags & Alter_info::DROP_FOREIGN_KEY))
4778 my_error(ER_FOREIGN_KEY_ON_PARTITIONED, MYF(0));
4782 if (!table->part_info && (alter_info->flags &
4783 Alter_info::ALTER_REMOVE_PARTITIONING))
4785 my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
4789 thd->work_part_info= thd->lex->part_info;
4791 if (thd->work_part_info &&
4792 !(thd->work_part_info= thd->lex->part_info->get_clone()))
4796 DBUG_ASSERT(!(alter_info->flags & Alter_info::ALTER_ADMIN_PARTITION));
4798 if (alter_info->flags &
4799 (Alter_info::ALTER_ADD_PARTITION |
4800 Alter_info::ALTER_DROP_PARTITION |
4801 Alter_info::ALTER_COALESCE_PARTITION |
4802 Alter_info::ALTER_REORGANIZE_PARTITION |
4803 Alter_info::ALTER_TABLE_REORG |
4804 Alter_info::ALTER_REBUILD_PARTITION))
4809 bool is_last_partition_reorged= FALSE;
4812 longlong tab_max_range= 0, alt_max_range= 0;
4814 if (!table->part_info)
4816 my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
4826 DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE,
4828 alter_ctx->table_name,
4829 MDL_INTENTION_EXCLUSIVE));
4831 tab_part_info= table->part_info;
4833 if (alter_info->flags & Alter_info::ALTER_TABLE_REORG)
4835 uint new_part_no, curr_part_no;
4841 if (tab_part_info->part_type != HASH_PARTITION ||
4842 ((table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION) &&
4843 !tab_part_info->use_default_num_partitions) ||
4844 ((!(table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION)) &&
4845 tab_part_info->use_default_num_partitions))
4847 my_error(ER_REORG_NO_PARAM_ERROR, MYF(0));
4850 new_part_no= table->file->get_default_no_partitions(create_info);
4851 curr_part_no= tab_part_info->num_parts;
4852 if (new_part_no == curr_part_no)
4859 flags= table->file->alter_table_flags(alter_info->flags);
4860 if (flags & (HA_FAST_CHANGE_PARTITION | HA_PARTITION_ONE_PHASE))
4862 *fast_alter_table=
true;
4864 table->m_needs_reopen=
true;
4872 if (!(tab_part_info= tab_part_info->get_clone()))
4876 thd->work_part_info= tab_part_info;
4879 else if (new_part_no > curr_part_no)
4885 alter_info->flags|= Alter_info::ALTER_ADD_PARTITION;
4886 thd->work_part_info->num_parts= new_part_no - curr_part_no;
4894 alter_info->flags|= Alter_info::ALTER_COALESCE_PARTITION;
4895 alter_info->num_parts= curr_part_no - new_part_no;
4898 if (!(flags= table->file->alter_table_flags(alter_info->flags)))
4900 my_error(ER_PARTITION_FUNCTION_FAILURE, MYF(0));
4903 if ((flags & (HA_FAST_CHANGE_PARTITION | HA_PARTITION_ONE_PHASE)) != 0)
4911 *fast_alter_table=
true;
4912 table->m_needs_reopen=
true;
4923 if (!(tab_part_info= tab_part_info->get_clone()))
4926 DBUG_PRINT(
"info", (
"*fast_alter_table flags: 0x%x", flags));
4927 if ((alter_info->flags & Alter_info::ALTER_ADD_PARTITION) ||
4928 (alter_info->flags & Alter_info::ALTER_REORGANIZE_PARTITION))
4930 if (thd->work_part_info->part_type != tab_part_info->part_type)
4932 if (thd->work_part_info->part_type == NOT_A_PARTITION)
4934 if (tab_part_info->part_type == RANGE_PARTITION)
4936 my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0),
"RANGE");
4939 else if (tab_part_info->part_type == LIST_PARTITION)
4941 my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0),
"LIST");
4951 if (thd->work_part_info->part_type == RANGE_PARTITION)
4953 my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
4954 "RANGE",
"LESS THAN");
4956 else if (thd->work_part_info->part_type == LIST_PARTITION)
4958 DBUG_ASSERT(thd->work_part_info->part_type == LIST_PARTITION);
4959 my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
4962 else if (tab_part_info->part_type == RANGE_PARTITION)
4964 my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
4965 "RANGE",
"LESS THAN");
4969 DBUG_ASSERT(tab_part_info->part_type == LIST_PARTITION);
4970 my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
4976 if ((tab_part_info->column_list &&
4977 alt_part_info->num_columns != tab_part_info->num_columns) ||
4978 (!tab_part_info->column_list &&
4979 (tab_part_info->part_type == RANGE_PARTITION ||
4980 tab_part_info->part_type == LIST_PARTITION) &&
4981 alt_part_info->num_columns != 1
U) ||
4982 (!tab_part_info->column_list &&
4983 tab_part_info->part_type == HASH_PARTITION &&
4984 alt_part_info->num_columns != 0))
4986 my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0));
4989 alt_part_info->column_list= tab_part_info->column_list;
4990 if (alt_part_info->fix_parser_data(thd))
4995 if (alter_info->flags & Alter_info::ALTER_ADD_PARTITION)
5003 uint num_new_partitions= alt_part_info->num_parts;
5004 uint num_orig_partitions= tab_part_info->num_parts;
5005 uint check_total_partitions= num_new_partitions + num_orig_partitions;
5006 uint new_total_partitions= check_total_partitions;
5011 if (thd->lex->no_write_to_binlog &&
5012 tab_part_info->part_type != HASH_PARTITION)
5014 my_error(ER_NO_BINLOG_ERROR, MYF(0));
5017 if (tab_part_info->defined_max_value)
5019 my_error(ER_PARTITION_MAXVALUE_ERROR, MYF(0));
5022 if (num_new_partitions == 0)
5024 my_error(ER_ADD_PARTITION_NO_NEW_PARTITION, MYF(0));
5027 if (tab_part_info->is_sub_partitioned())
5029 if (alt_part_info->num_subparts == 0)
5030 alt_part_info->num_subparts= tab_part_info->num_subparts;
5031 else if (alt_part_info->num_subparts != tab_part_info->num_subparts)
5033 my_error(ER_ADD_PARTITION_SUBPART_ERROR, MYF(0));
5036 check_total_partitions= new_total_partitions*
5037 alt_part_info->num_subparts;
5039 if (check_total_partitions > MAX_PARTITIONS)
5041 my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
5044 alt_part_info->part_type= tab_part_info->part_type;
5045 alt_part_info->subpart_type= tab_part_info->subpart_type;
5046 if (alt_part_info->set_up_defaults_for_partitioning(table->file,
5048 tab_part_info->num_parts))
5114 if (*fast_alter_table &&
5115 tab_part_info->part_type == HASH_PARTITION)
5117 uint part_no= 0, start_part= 1, start_sec_part= 1;
5118 uint end_part= 0, end_sec_part= 0;
5119 uint upper_2n= tab_part_info->linear_hash_mask + 1;
5120 uint lower_2n= upper_2n >> 1;
5121 bool all_parts= TRUE;
5122 if (tab_part_info->linear_hash_ind &&
5123 num_new_partitions < upper_2n)
5160 if (num_new_partitions >= lower_2n)
5167 end_part= new_total_partitions - (upper_2n + 1);
5168 end_part= max(lower_2n - 1, end_part);
5170 else if (new_total_partitions <= upper_2n)
5176 start_part= num_orig_partitions - lower_2n;
5177 end_part= start_part + (num_new_partitions - 1);
5186 start_part= num_orig_partitions - lower_2n;
5187 end_part= upper_2n - 1;
5189 end_sec_part= new_total_partitions - (upper_2n + 1);
5198 (part_no >= start_part && part_no <= end_part) ||
5199 (part_no >= start_sec_part && part_no <= end_sec_part))
5201 p_elem->part_state= PART_CHANGED;
5203 }
while (++part_no < num_orig_partitions);
5219 if (*fast_alter_table)
5220 part_elem->part_state= PART_TO_BE_ADDED;
5221 if (tab_part_info->partitions.push_back(part_elem))
5226 }
while (++part_count < num_new_partitions);
5227 tab_part_info->num_parts+= num_new_partitions;
5235 if (!(alter_info->flags & Alter_info::ALTER_TABLE_REORG))
5237 if (!alt_part_info->use_default_partitions)
5239 DBUG_PRINT(
"info", (
"part_info: 0x%lx", (
long) tab_part_info));
5240 tab_part_info->use_default_partitions= FALSE;
5242 tab_part_info->use_default_num_partitions= FALSE;
5243 tab_part_info->is_auto_partitioned= FALSE;
5246 else if (alter_info->flags & Alter_info::ALTER_DROP_PARTITION)
5256 uint num_parts_dropped= alter_info->partition_names.elements;
5257 uint num_parts_found= 0;
5260 tab_part_info->is_auto_partitioned= FALSE;
5261 if (!(tab_part_info->part_type == RANGE_PARTITION ||
5262 tab_part_info->part_type == LIST_PARTITION))
5264 my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0),
"DROP");
5267 if (num_parts_dropped >= tab_part_info->num_parts)
5269 my_error(ER_DROP_LAST_PARTITION, MYF(0));
5275 if (is_name_in_list(part_elem->partition_name,
5276 alter_info->partition_names))
5282 part_elem->part_state= PART_TO_BE_DROPPED;
5284 }
while (++part_count < tab_part_info->num_parts);
5285 if (num_parts_found != num_parts_dropped)
5287 my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0),
"DROP");
5292 my_error(ER_ROW_IS_REFERENCED, MYF(0));
5295 tab_part_info->num_parts-= num_parts_dropped;
5297 else if (alter_info->flags & Alter_info::ALTER_REBUILD_PARTITION)
5299 if (set_part_state(alter_info, tab_part_info, PART_CHANGED))
5301 my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0),
"REBUILD");
5304 if (!(*fast_alter_table))
5306 table->file->
print_error(HA_ERR_WRONG_COMMAND, MYF(0));
5310 else if (alter_info->flags & Alter_info::ALTER_COALESCE_PARTITION)
5312 uint num_parts_coalesced= alter_info->num_parts;
5313 uint num_parts_remain= tab_part_info->num_parts - num_parts_coalesced;
5315 if (tab_part_info->part_type != HASH_PARTITION)
5317 my_error(ER_COALESCE_ONLY_ON_HASH_PARTITION, MYF(0));
5320 if (num_parts_coalesced == 0)
5322 my_error(ER_COALESCE_PARTITION_NO_PARTITION, MYF(0));
5325 if (num_parts_coalesced >= tab_part_info->num_parts)
5327 my_error(ER_DROP_LAST_PARTITION, MYF(0));
5364 uint part_count= 0, start_part= 1, start_sec_part= 1;
5365 uint end_part= 0, end_sec_part= 0;
5366 bool all_parts= TRUE;
5367 if (*fast_alter_table &&
5368 tab_part_info->linear_hash_ind)
5370 uint upper_2n= tab_part_info->linear_hash_mask + 1;
5371 uint lower_2n= upper_2n >> 1;
5373 if (num_parts_coalesced >= lower_2n)
5377 else if (num_parts_remain >= lower_2n)
5379 end_part= tab_part_info->num_parts - (lower_2n + 1);
5380 start_part= num_parts_remain - lower_2n;
5385 end_part= tab_part_info->num_parts - (lower_2n + 1);
5386 end_sec_part= (lower_2n >> 1) - 1;
5387 start_sec_part= end_sec_part - (lower_2n - (num_parts_remain + 1));
5393 if (*fast_alter_table &&
5395 (part_count >= start_part && part_count <= end_part) ||
5396 (part_count >= start_sec_part && part_count <= end_sec_part)))
5397 p_elem->part_state= PART_CHANGED;
5398 if (++part_count > num_parts_remain)
5400 if (*fast_alter_table)
5401 p_elem->part_state= PART_REORGED_DROPPED;
5405 }
while (part_count < tab_part_info->num_parts);
5406 tab_part_info->num_parts= num_parts_remain;
5408 if (!(alter_info->flags & Alter_info::ALTER_TABLE_REORG))
5410 tab_part_info->use_default_num_partitions= FALSE;
5411 tab_part_info->is_auto_partitioned= FALSE;
5414 else if (alter_info->flags & Alter_info::ALTER_REORGANIZE_PARTITION)
5427 uint num_parts_reorged= alter_info->partition_names.elements;
5428 uint num_parts_new= thd->work_part_info->partitions.elements;
5429 uint check_total_partitions;
5431 tab_part_info->is_auto_partitioned= FALSE;
5432 if (num_parts_reorged > tab_part_info->num_parts)
5434 my_error(ER_REORG_PARTITION_NOT_EXIST, MYF(0));
5437 if (!(tab_part_info->part_type == RANGE_PARTITION ||
5438 tab_part_info->part_type == LIST_PARTITION) &&
5439 (num_parts_new != num_parts_reorged))
5441 my_error(ER_REORG_HASH_ONLY_ON_SAME_NO, MYF(0));
5444 if (tab_part_info->is_sub_partitioned() &&
5445 alt_part_info->num_subparts &&
5446 alt_part_info->num_subparts != tab_part_info->num_subparts)
5448 my_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR, MYF(0));
5451 check_total_partitions= tab_part_info->num_parts + num_parts_new;
5452 check_total_partitions-= num_parts_reorged;
5453 if (check_total_partitions > MAX_PARTITIONS)
5455 my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
5458 alt_part_info->part_type= tab_part_info->part_type;
5459 alt_part_info->subpart_type= tab_part_info->subpart_type;
5460 alt_part_info->num_subparts= tab_part_info->num_subparts;
5461 DBUG_ASSERT(!alt_part_info->use_default_partitions);
5463 tab_part_info->use_default_partitions= FALSE;
5464 if (alt_part_info->set_up_defaults_for_partitioning(table->file,
5508 bool found_first= FALSE;
5509 bool found_last= FALSE;
5514 is_last_partition_reorged= FALSE;
5515 if (is_name_in_list(part_elem->partition_name,
5516 alter_info->partition_names))
5518 is_last_partition_reorged= TRUE;
5520 if (tab_part_info->column_list)
5523 tab_max_elem_val= p++;
5526 tab_max_range= part_elem->range_value;
5527 if (*fast_alter_table &&
5528 tab_part_info->temp_partitions.push_back(part_elem))
5533 if (*fast_alter_table)
5534 part_elem->part_state= PART_TO_BE_REORGED;
5537 uint alt_part_count= 0;
5540 alt_it(alt_part_info->partitions);
5544 alt_part_elem= alt_it++;
5545 if (tab_part_info->column_list)
5548 alt_max_elem_val= p++;
5551 alt_max_range= alt_part_elem->range_value;
5553 if (*fast_alter_table)
5554 alt_part_elem->part_state= PART_TO_BE_ADDED;
5555 if (alt_part_count == 0)
5556 tab_it.replace(alt_part_elem);
5558 tab_it.after(alt_part_elem);
5559 }
while (++alt_part_count < num_parts_new);
5561 else if (found_last)
5563 my_error(ER_CONSECUTIVE_REORG_PARTITIONS, MYF(0));
5574 }
while (++part_count < tab_part_info->num_parts);
5575 if (drop_count != num_parts_reorged)
5577 my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0),
"REORGANIZE");
5580 tab_part_info->num_parts= check_total_partitions;
5587 *partition_changed= TRUE;
5588 thd->work_part_info= tab_part_info;
5589 if (alter_info->flags & Alter_info::ALTER_ADD_PARTITION ||
5590 alter_info->flags & Alter_info::ALTER_REORGANIZE_PARTITION)
5592 if (tab_part_info->use_default_subpartitions &&
5593 !alt_part_info->use_default_subpartitions)
5595 tab_part_info->use_default_subpartitions= FALSE;
5596 tab_part_info->use_default_num_subpartitions= FALSE;
5598 if (tab_part_info->check_partition_info(thd, (
handlerton**)NULL,
5599 table->file, ULL(0), TRUE))
5608 if (alter_info->flags == Alter_info::ALTER_REORGANIZE_PARTITION &&
5609 tab_part_info->part_type == RANGE_PARTITION &&
5610 ((is_last_partition_reorged &&
5611 (tab_part_info->column_list ?
5612 (tab_part_info->compare_column_values(
5613 alt_max_elem_val->col_val_array,
5614 tab_max_elem_val->col_val_array) < 0) :
5615 alt_max_range < tab_max_range)) ||
5616 (!is_last_partition_reorged &&
5617 (tab_part_info->column_list ?
5618 (tab_part_info->compare_column_values(
5619 alt_max_elem_val->col_val_array,
5620 tab_max_elem_val->col_val_array) != 0) :
5621 alt_max_range != tab_max_range))))
5632 my_error(ER_REORG_OUTSIDE_RANGE, MYF(0));
5691 if (alter_info->flags & Alter_info::ALTER_REMOVE_PARTITIONING)
5693 DBUG_PRINT(
"info", (
"Remove partitioning"));
5694 if (!(create_info->used_fields & HA_CREATE_USED_ENGINE))
5696 DBUG_PRINT(
"info", (
"No explicit engine used"));
5697 create_info->db_type= tab_part_info->default_engine_type;
5699 DBUG_PRINT(
"info", (
"New engine type: %s",
5700 ha_resolve_storage_engine_name(create_info->db_type)));
5701 thd->work_part_info= NULL;
5702 *partition_changed= TRUE;
5704 else if (!thd->work_part_info)
5712 if (!(tab_part_info= tab_part_info->get_clone()))
5714 thd->work_part_info= tab_part_info;
5715 if (create_info->used_fields & HA_CREATE_USED_ENGINE &&
5716 create_info->db_type != tab_part_info->default_engine_type)
5721 DBUG_PRINT(
"info", (
"partition changed"));
5722 if (tab_part_info->is_auto_partitioned)
5728 thd->work_part_info= NULL;
5735 set_engine_all_partitions(thd->work_part_info,
5736 create_info->db_type);
5738 *partition_changed= TRUE;
5742 if (thd->work_part_info)
5745 bool is_native_partitioned= FALSE;
5750 if (part_info != tab_part_info)
5752 if (part_info->fix_parser_data(thd))
5762 if (alter_info->flags != Alter_info::ALTER_PARTITION ||
5763 !table->part_info ||
5764 alter_info->requested_algorithm !=
5765 Alter_info::ALTER_TABLE_ALGORITHM_INPLACE ||
5766 !table->part_info->has_same_partitioning(part_info))
5768 DBUG_PRINT(
"info", (
"partition changed"));
5769 *partition_changed=
true;
5776 if (create_info->used_fields & HA_CREATE_USED_ENGINE)
5777 part_info->default_engine_type= create_info->db_type;
5781 part_info->default_engine_type= tab_part_info->default_engine_type;
5783 part_info->default_engine_type= create_info->db_type;
5785 DBUG_ASSERT(part_info->default_engine_type &&
5786 part_info->default_engine_type != partition_hton);
5787 if (check_native_partitioned(create_info, &is_native_partitioned,
5792 if (!is_native_partitioned)
5794 DBUG_ASSERT(create_info->db_type);
5795 create_info->db_type= partition_hton;
5801 *fast_alter_table=
false;
5834 char path[FN_REFLEN+1];
5836 handler *file= lpt->table->file;
5838 DBUG_ENTER(
"mysql_change_partitions");
5840 build_table_filename(path,
sizeof(path) - 1, lpt->db, lpt->table_name,
"", 0);
5842 if(mysql_trans_prepare_alter_copy_data(thd))
5848 &lpt->deleted, lpt->pack_frm_data,
5849 lpt->pack_frm_len)))
5851 file->
print_error(error, MYF(error != ER_OUTOFMEMORY ? 0 : ME_FATALERROR));
5854 if (mysql_trans_commit_alter_copy_data(thd))
5857 DBUG_RETURN(
test(error));
5882 char path[FN_REFLEN+1];
5884 DBUG_ENTER(
"mysql_rename_partitions");
5886 build_table_filename(path,
sizeof(path) - 1, lpt->db, lpt->table_name,
"", 0);
5919 char path[FN_REFLEN+1];
5923 uint remove_count= 0;
5925 DBUG_ENTER(
"mysql_drop_partitions");
5927 DBUG_ASSERT(lpt->thd->mdl_context.is_lock_owner(MDL_key::TABLE,
5928 lpt->table->s->db.str,
5929 lpt->table->s->table_name.str,
5932 build_table_filename(path,
sizeof(path) - 1, lpt->db, lpt->table_name,
"", 0);
5941 if (part_elem->part_state == PART_IS_DROPPED)
5946 }
while (++i < part_info->num_parts);
5947 part_info->num_parts-= remove_count;
5961 static void insert_part_info_log_entry_list(
partition_info *part_info,
5964 log_entry->next_active_log_entry= part_info->first_log_entry;
5965 part_info->first_log_entry= log_entry;
5980 DBUG_ENTER(
"release_part_info_log_entries");
5984 release_ddl_log_memory_entry(log_entry);
5985 log_entry= log_entry->next_active_log_entry;
6011 const char *from_path,
6012 const char *to_path,
6017 DBUG_ENTER(
"write_log_replace_delete_frm");
6020 ddl_log_entry.action_type= DDL_LOG_REPLACE_ACTION;
6022 ddl_log_entry.action_type= DDL_LOG_DELETE_ACTION;
6023 ddl_log_entry.next_entry= next_entry;
6024 ddl_log_entry.handler_name= reg_ext;
6025 ddl_log_entry.name= to_path;
6027 ddl_log_entry.from_name= from_path;
6028 if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
6032 insert_part_info_log_entry_list(lpt->part_info, log_entry);
6060 uint *next_entry,
const char *path)
6065 char tmp_path[FN_REFLEN];
6066 char normal_path[FN_REFLEN];
6068 uint temp_partitions= part_info->temp_partitions.elements;
6069 uint num_elements= part_info->partitions.elements;
6071 DBUG_ENTER(
"write_log_changed_partitions");
6076 if (part_elem->part_state == PART_IS_CHANGED ||
6077 (part_elem->part_state == PART_IS_ADDED && temp_partitions))
6079 if (part_info->is_sub_partitioned())
6082 uint num_subparts= part_info->num_subparts;
6087 ddl_log_entry.next_entry= *next_entry;
6088 ddl_log_entry.handler_name=
6089 ha_resolve_storage_engine_name(sub_elem->engine_type);
6090 create_subpartition_name(tmp_path, path,
6091 part_elem->partition_name,
6092 sub_elem->partition_name,
6094 create_subpartition_name(normal_path, path,
6095 part_elem->partition_name,
6096 sub_elem->partition_name,
6098 ddl_log_entry.name= normal_path;
6099 ddl_log_entry.from_name= tmp_path;
6100 if (part_elem->part_state == PART_IS_CHANGED)
6101 ddl_log_entry.action_type= DDL_LOG_REPLACE_ACTION;
6103 ddl_log_entry.action_type= DDL_LOG_RENAME_ACTION;
6104 if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
6108 *next_entry= log_entry->entry_pos;
6109 sub_elem->log_entry= log_entry;
6110 insert_part_info_log_entry_list(part_info, log_entry);
6111 }
while (++j < num_subparts);
6115 ddl_log_entry.next_entry= *next_entry;
6116 ddl_log_entry.handler_name=
6117 ha_resolve_storage_engine_name(part_elem->engine_type);
6118 create_partition_name(tmp_path, path,
6119 part_elem->partition_name,
6120 TEMP_PART_NAME, TRUE);
6121 create_partition_name(normal_path, path,
6122 part_elem->partition_name,
6123 NORMAL_PART_NAME, TRUE);
6124 ddl_log_entry.name= normal_path;
6125 ddl_log_entry.from_name= tmp_path;
6126 if (part_elem->part_state == PART_IS_CHANGED)
6127 ddl_log_entry.action_type= DDL_LOG_REPLACE_ACTION;
6129 ddl_log_entry.action_type= DDL_LOG_RENAME_ACTION;
6130 if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
6134 *next_entry= log_entry->entry_pos;
6135 part_elem->log_entry= log_entry;
6136 insert_part_info_log_entry_list(part_info, log_entry);
6139 }
while (++i < num_elements);
6162 char tmp_path[FN_LEN];
6165 uint num_temp_partitions= part_info->temp_partitions.elements;
6166 uint num_elements= part_info->partitions.elements;
6167 DBUG_ENTER(
"write_log_dropped_partitions");
6169 ddl_log_entry.action_type= DDL_LOG_DELETE_ACTION;
6171 num_elements= num_temp_partitions;
6172 while (num_elements--)
6176 part_elem= temp_it++;
6178 part_elem= part_it++;
6179 if (part_elem->part_state == PART_TO_BE_DROPPED ||
6180 part_elem->part_state == PART_TO_BE_ADDED ||
6181 part_elem->part_state == PART_CHANGED)
6184 if (part_elem->part_state == PART_CHANGED ||
6185 (part_elem->part_state == PART_TO_BE_ADDED &&
6186 num_temp_partitions))
6187 name_variant= TEMP_PART_NAME;
6189 name_variant= NORMAL_PART_NAME;
6190 if (part_info->is_sub_partitioned())
6193 uint num_subparts= part_info->num_subparts;
6198 ddl_log_entry.next_entry= *next_entry;
6199 ddl_log_entry.handler_name=
6200 ha_resolve_storage_engine_name(sub_elem->engine_type);
6201 create_subpartition_name(tmp_path, path,
6202 part_elem->partition_name,
6203 sub_elem->partition_name,
6205 ddl_log_entry.name= tmp_path;
6206 if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
6210 *next_entry= log_entry->entry_pos;
6211 sub_elem->log_entry= log_entry;
6212 insert_part_info_log_entry_list(part_info, log_entry);
6213 }
while (++j < num_subparts);
6217 ddl_log_entry.next_entry= *next_entry;
6218 ddl_log_entry.handler_name=
6219 ha_resolve_storage_engine_name(part_elem->engine_type);
6220 create_partition_name(tmp_path, path,
6221 part_elem->partition_name,
6222 name_variant, TRUE);
6223 ddl_log_entry.name= tmp_path;
6224 if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
6228 *next_entry= log_entry->entry_pos;
6229 part_elem->log_entry= log_entry;
6230 insert_part_info_log_entry_list(part_info, log_entry);
6248 static void set_part_info_exec_log_entry(
partition_info *part_info,
6251 part_info->exec_log_entry= exec_log_entry;
6252 exec_log_entry->next_active_log_entry= NULL;
6277 char shadow_path[FN_REFLEN + 1];
6278 DBUG_ENTER(
"write_log_drop_shadow_frm");
6280 build_table_shadow_filename(shadow_path,
sizeof(shadow_path) - 1, lpt);
6282 if (write_log_replace_delete_frm(lpt, 0UL, NULL,
6283 (
const char*)shadow_path, FALSE))
6285 log_entry= part_info->first_log_entry;
6286 if (write_execute_ddl_log_entry(log_entry->entry_pos,
6287 FALSE, &exec_log_entry))
6290 set_part_info_exec_log_entry(part_info, exec_log_entry);
6294 release_part_info_log_entries(part_info->first_log_entry);
6296 part_info->first_log_entry= NULL;
6297 my_error(ER_DDL_LOG_ERROR, MYF(0));
6320 char path[FN_REFLEN + 1];
6321 char shadow_path[FN_REFLEN + 1];
6323 DBUG_ENTER(
"write_log_rename_frm");
6325 part_info->first_log_entry= NULL;
6326 build_table_filename(path,
sizeof(path) - 1, lpt->db,
6327 lpt->table_name,
"", 0);
6328 build_table_shadow_filename(shadow_path,
sizeof(shadow_path) - 1, lpt);
6330 if (write_log_replace_delete_frm(lpt, 0UL, shadow_path, path, TRUE))
6332 log_entry= part_info->first_log_entry;
6333 part_info->frm_log_entry= log_entry;
6334 if (write_execute_ddl_log_entry(log_entry->entry_pos,
6335 FALSE, &exec_log_entry))
6337 release_part_info_log_entries(old_first_log_entry);
6342 release_part_info_log_entries(part_info->first_log_entry);
6344 part_info->first_log_entry= old_first_log_entry;
6345 part_info->frm_log_entry= NULL;
6346 my_error(ER_DDL_LOG_ERROR, MYF(0));
6371 char tmp_path[FN_REFLEN + 1];
6372 char path[FN_REFLEN + 1];
6375 DBUG_ENTER(
"write_log_drop_partition");
6377 part_info->first_log_entry= NULL;
6378 build_table_filename(path,
sizeof(path) - 1, lpt->db,
6379 lpt->table_name,
"", 0);
6380 build_table_shadow_filename(tmp_path,
sizeof(tmp_path) - 1, lpt);
6382 if (write_log_dropped_partitions(lpt, &next_entry, (
const char*)path,
6385 if (write_log_replace_delete_frm(lpt, next_entry, (
const char*)tmp_path,
6386 (
const char*)path, TRUE))
6388 log_entry= part_info->first_log_entry;
6389 part_info->frm_log_entry= log_entry;
6390 if (write_execute_ddl_log_entry(log_entry->entry_pos,
6391 FALSE, &exec_log_entry))
6393 release_part_info_log_entries(old_first_log_entry);
6398 release_part_info_log_entries(part_info->first_log_entry);
6400 part_info->first_log_entry= old_first_log_entry;
6401 part_info->frm_log_entry= NULL;
6402 my_error(ER_DDL_LOG_ERROR, MYF(0));
6429 char tmp_path[FN_REFLEN + 1];
6430 char path[FN_REFLEN + 1];
6434 DBUG_ASSERT(old_first_log_entry);
6435 DBUG_ENTER(
"write_log_add_change_partition");
6437 build_table_filename(path,
sizeof(path) - 1, lpt->db,
6438 lpt->table_name,
"", 0);
6439 build_table_shadow_filename(tmp_path,
sizeof(tmp_path) - 1, lpt);
6443 if (old_first_log_entry)
6444 next_entry= old_first_log_entry->entry_pos;
6445 if (write_log_dropped_partitions(lpt, &next_entry, (
const char*)path,
6448 log_entry= part_info->first_log_entry;
6450 if (write_execute_ddl_log_entry(log_entry->entry_pos,
6456 set_part_info_exec_log_entry(part_info, exec_log_entry);
6460 release_part_info_log_entries(part_info->first_log_entry);
6462 part_info->first_log_entry= old_first_log_entry;
6463 my_error(ER_DDL_LOG_ERROR, MYF(0));
6495 char path[FN_REFLEN + 1];
6496 char shadow_path[FN_REFLEN + 1];
6499 DBUG_ENTER(
"write_log_final_change_partition");
6505 part_info->first_log_entry= NULL;
6506 build_table_filename(path,
sizeof(path) - 1, lpt->db,
6507 lpt->table_name,
"", 0);
6508 build_table_shadow_filename(shadow_path,
sizeof(shadow_path) - 1, lpt);
6510 if (write_log_changed_partitions(lpt, &next_entry, (
const char*)path))
6512 if (write_log_dropped_partitions(lpt, &next_entry, (
const char*)path,
6513 lpt->alter_info->flags &
6514 Alter_info::ALTER_REORGANIZE_PARTITION))
6516 if (write_log_replace_delete_frm(lpt, next_entry, shadow_path, path, TRUE))
6518 log_entry= part_info->first_log_entry;
6519 part_info->frm_log_entry= log_entry;
6521 if (write_execute_ddl_log_entry(log_entry->entry_pos,
6522 FALSE, &exec_log_entry))
6524 release_part_info_log_entries(old_first_log_entry);
6529 release_part_info_log_entries(part_info->first_log_entry);
6531 part_info->first_log_entry= old_first_log_entry;
6532 part_info->frm_log_entry= NULL;
6533 my_error(ER_DDL_LOG_ERROR, MYF(0));
6554 DBUG_ENTER(
"write_log_completed");
6556 DBUG_ASSERT(log_entry);
6558 if (write_execute_ddl_log_entry(0UL, TRUE, &log_entry))
6569 release_part_info_log_entries(part_info->first_log_entry);
6570 release_part_info_log_entries(part_info->exec_log_entry);
6572 part_info->exec_log_entry= NULL;
6573 part_info->first_log_entry= NULL;
6590 release_part_info_log_entries(part_info->first_log_entry);
6591 release_part_info_log_entries(part_info->exec_log_entry);
6593 part_info->first_log_entry= NULL;
6594 part_info->exec_log_entry= NULL;
6619 lpt->table_list->table= 0;
6620 if (thd->locked_tables_mode)
6625 if (thd->is_error())
6628 stmt_da= thd->get_stmt_da();
6629 thd->set_stmt_da(&tmp_stmt_da);
6632 if (thd->locked_tables_list.reopen_tables(thd))
6633 sql_print_warning(
"We failed to reacquire LOCKs in ALTER TABLE");
6636 thd->set_stmt_da(stmt_da);
6651 DBUG_ENTER(
"alter_close_table");
6653 if (lpt->table->db_stat)
6657 lpt->table->db_stat= 0;
6674 bool action_completed,
6675 bool drop_partition,
6681 TABLE *table= lpt->table;
6682 DBUG_ENTER(
"handle_alter_part_error");
6683 DBUG_ASSERT(table->m_needs_reopen);
6692 if (!thd->mdl_context.is_lock_owner(MDL_key::TABLE, lpt->db,
6699 goto err_exclusive_lock;
6703 part_info= lpt->part_info->get_clone();
6713 thd->locked_tables_list.unlink_from_list(thd,
6714 table->pos_in_locked_tables,
6721 part_info= lpt->part_info->get_clone();
6722 close_thread_table(thd, &thd->open_tables);
6723 lpt->table_list->table= NULL;
6726 if (part_info->first_log_entry &&
6727 execute_ddl_log_entry(thd, part_info->first_log_entry->entry_pos))
6733 write_log_completed(lpt, FALSE);
6734 release_log_entries(part_info);
6735 if (!action_completed)
6740 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, 1,
6742 "Operation was unsuccessful, table is still intact,",
6743 "but it is possible that a shadow frm file was left behind");
6747 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, 1,
6749 "Operation was unsuccessful, table is still intact,",
6750 "but it is possible that a shadow frm file was left behind.",
6751 "It is also possible that temporary partitions are left behind,",
6752 "these could be empty or more or less filled with records");
6763 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, 1,
6765 "Failed during alter of partitions, table is no longer intact.",
6766 "The frm file is in an unknown state, and a backup",
6769 else if (drop_partition)
6777 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, 1,
6779 "Failed during drop of partitions, table is intact.",
6780 "Manual drop of remaining partitions is required");
6789 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, 1,
6791 "Failed during renaming of partitions. We are now in a position",
6792 "where table is not reusable",
6793 "Table is disabled by writing ancient frm file version into it");
6799 release_log_entries(part_info);
6800 if (!action_completed)
6818 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, 1,
"%s %s",
6819 "Operation was successfully completed by failure handling,",
6820 "after failure of normal operation");
6824 if (thd->locked_tables_mode)
6829 if (thd->is_error())
6832 stmt_da= thd->get_stmt_da();
6833 thd->set_stmt_da(&tmp_stmt_da);
6836 if (thd->locked_tables_list.reopen_tables(thd))
6837 sql_print_warning(
"We failed to reacquire LOCKs in ALTER TABLE");
6840 thd->set_stmt_da(stmt_da);
6855 static void downgrade_mdl_if_lock_tables_mode(THD *thd,
MDL_ticket *ticket,
6858 if (thd->locked_tables_mode)
6884 uint fast_alter_partition_table(THD *thd,
TABLE *table,
6895 bool action_completed= FALSE;
6896 bool close_table_on_failure= FALSE;
6897 bool frm_install= FALSE;
6899 DBUG_ENTER(
"fast_alter_partition_table");
6900 DBUG_ASSERT(table->m_needs_reopen);
6902 part_info= table->part_info;
6904 lpt->table_list= table_list;
6905 lpt->part_info= part_info;
6906 lpt->alter_info= alter_info;
6907 lpt->create_info= create_info;
6908 lpt->db_options= create_info->table_options;
6909 if (create_info->
row_type == ROW_TYPE_DYNAMIC)
6910 lpt->db_options|= HA_OPTION_PACK_RECORD;
6912 lpt->key_info_buffer= 0;
6918 lpt->pack_frm_data= NULL;
6919 lpt->pack_frm_len= 0;
6921 if (table->file->alter_table_flags(alter_info->flags) &
6922 HA_PARTITION_ONE_PHASE)
6963 if (mysql_write_frm(lpt, WFRM_WRITE_SHADOW | WFRM_PACK_FRM) ||
6964 mysql_change_partitions(lpt))
6969 else if (alter_info->flags & Alter_info::ALTER_DROP_PARTITION)
7028 if (write_log_drop_shadow_frm(lpt) ||
7029 ERROR_INJECT_CRASH(
"crash_drop_partition_1") ||
7030 ERROR_INJECT_ERROR(
"fail_drop_partition_1") ||
7031 mysql_write_frm(lpt, WFRM_WRITE_SHADOW) ||
7032 ERROR_INJECT_CRASH(
"crash_drop_partition_2") ||
7033 ERROR_INJECT_ERROR(
"fail_drop_partition_2") ||
7035 ERROR_INJECT_CRASH(
"crash_drop_partition_3") ||
7036 ERROR_INJECT_ERROR(
"fail_drop_partition_3") ||
7037 (close_table_on_failure= TRUE, FALSE) ||
7038 write_log_drop_partition(lpt) ||
7039 (action_completed= TRUE, FALSE) ||
7040 ERROR_INJECT_CRASH(
"crash_drop_partition_4") ||
7041 ERROR_INJECT_ERROR(
"fail_drop_partition_4") ||
7042 alter_close_table(lpt) ||
7043 (close_table_on_failure= FALSE, FALSE) ||
7044 ERROR_INJECT_CRASH(
"crash_drop_partition_5") ||
7045 ERROR_INJECT_ERROR(
"fail_drop_partition_5") ||
7046 ((!thd->lex->no_write_to_binlog) &&
7047 (write_bin_log(thd, FALSE,
7048 thd->query(), thd->query_length()), FALSE)) ||
7049 ERROR_INJECT_CRASH(
"crash_drop_partition_6") ||
7050 ERROR_INJECT_ERROR(
"fail_drop_partition_6") ||
7051 (frm_install= TRUE, FALSE) ||
7052 mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) ||
7053 (frm_install= FALSE, FALSE) ||
7054 ERROR_INJECT_CRASH(
"crash_drop_partition_7") ||
7055 ERROR_INJECT_ERROR(
"fail_drop_partition_7") ||
7056 mysql_drop_partitions(lpt) ||
7057 ERROR_INJECT_CRASH(
"crash_drop_partition_8") ||
7058 ERROR_INJECT_ERROR(
"fail_drop_partition_8") ||
7059 (write_log_completed(lpt, FALSE), FALSE) ||
7060 ERROR_INJECT_CRASH(
"crash_drop_partition_9") ||
7061 ERROR_INJECT_ERROR(
"fail_drop_partition_9") ||
7062 (alter_partition_lock_handling(lpt), FALSE))
7064 handle_alter_part_error(lpt, action_completed, TRUE, frm_install,
7065 close_table_on_failure);
7069 else if ((alter_info->flags & Alter_info::ALTER_ADD_PARTITION) &&
7070 (part_info->part_type == RANGE_PARTITION ||
7071 part_info->part_type == LIST_PARTITION))
7102 if (write_log_drop_shadow_frm(lpt) ||
7103 ERROR_INJECT_CRASH(
"crash_add_partition_1") ||
7104 ERROR_INJECT_ERROR(
"fail_add_partition_1") ||
7105 mysql_write_frm(lpt, WFRM_WRITE_SHADOW) ||
7106 ERROR_INJECT_CRASH(
"crash_add_partition_2") ||
7107 ERROR_INJECT_ERROR(
"fail_add_partition_2") ||
7109 ERROR_INJECT_CRASH(
"crash_add_partition_3") ||
7110 ERROR_INJECT_ERROR(
"fail_add_partition_3") ||
7111 (close_table_on_failure= TRUE, FALSE) ||
7112 write_log_add_change_partition(lpt) ||
7113 ERROR_INJECT_CRASH(
"crash_add_partition_4") ||
7114 ERROR_INJECT_ERROR(
"fail_add_partition_4") ||
7115 mysql_change_partitions(lpt) ||
7116 ERROR_INJECT_CRASH(
"crash_add_partition_5") ||
7117 ERROR_INJECT_ERROR(
"fail_add_partition_5") ||
7118 (close_table_on_failure= FALSE, FALSE) ||
7119 alter_close_table(lpt) ||
7120 ERROR_INJECT_CRASH(
"crash_add_partition_6") ||
7121 ERROR_INJECT_ERROR(
"fail_add_partition_6") ||
7122 ((!thd->lex->no_write_to_binlog) &&
7123 (write_bin_log(thd, FALSE,
7124 thd->query(), thd->query_length()), FALSE)) ||
7125 ERROR_INJECT_CRASH(
"crash_add_partition_7") ||
7126 ERROR_INJECT_ERROR(
"fail_add_partition_7") ||
7127 write_log_rename_frm(lpt) ||
7128 (action_completed= TRUE, FALSE) ||
7129 ERROR_INJECT_CRASH(
"crash_add_partition_8") ||
7130 ERROR_INJECT_ERROR(
"fail_add_partition_8") ||
7131 (frm_install= TRUE, FALSE) ||
7132 mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) ||
7133 (frm_install= FALSE, FALSE) ||
7134 ERROR_INJECT_CRASH(
"crash_add_partition_9") ||
7135 ERROR_INJECT_ERROR(
"fail_add_partition_9") ||
7136 (write_log_completed(lpt, FALSE), FALSE) ||
7137 ERROR_INJECT_CRASH(
"crash_add_partition_10") ||
7138 ERROR_INJECT_ERROR(
"fail_add_partition_10") ||
7139 (alter_partition_lock_handling(lpt), FALSE))
7141 handle_alter_part_error(lpt, action_completed, FALSE, frm_install,
7142 close_table_on_failure);
7201 if (write_log_drop_shadow_frm(lpt) ||
7202 ERROR_INJECT_CRASH(
"crash_change_partition_1") ||
7203 ERROR_INJECT_ERROR(
"fail_change_partition_1") ||
7204 mysql_write_frm(lpt, WFRM_WRITE_SHADOW) ||
7205 ERROR_INJECT_CRASH(
"crash_change_partition_2") ||
7206 ERROR_INJECT_ERROR(
"fail_change_partition_2") ||
7207 (close_table_on_failure= TRUE, FALSE) ||
7208 write_log_add_change_partition(lpt) ||
7209 ERROR_INJECT_CRASH(
"crash_change_partition_3") ||
7210 ERROR_INJECT_ERROR(
"fail_change_partition_3") ||
7211 mysql_change_partitions(lpt) ||
7212 ERROR_INJECT_CRASH(
"crash_change_partition_4") ||
7213 ERROR_INJECT_ERROR(
"fail_change_partition_4") ||
7215 ERROR_INJECT_CRASH(
"crash_change_partition_5") ||
7216 ERROR_INJECT_ERROR(
"fail_change_partition_5") ||
7217 alter_close_table(lpt) ||
7218 (close_table_on_failure= FALSE, FALSE) ||
7219 ERROR_INJECT_CRASH(
"crash_change_partition_6") ||
7220 ERROR_INJECT_ERROR(
"fail_change_partition_6") ||
7221 write_log_final_change_partition(lpt) ||
7222 (action_completed= TRUE, FALSE) ||
7223 ERROR_INJECT_CRASH(
"crash_change_partition_7") ||
7224 ERROR_INJECT_ERROR(
"fail_change_partition_7") ||
7225 ((!thd->lex->no_write_to_binlog) &&
7226 (write_bin_log(thd, FALSE,
7227 thd->query(), thd->query_length()), FALSE)) ||
7228 ERROR_INJECT_CRASH(
"crash_change_partition_8") ||
7229 ERROR_INJECT_ERROR(
"fail_change_partition_8") ||
7230 ((frm_install= TRUE), FALSE) ||
7231 mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) ||
7232 (frm_install= FALSE, FALSE) ||
7233 ERROR_INJECT_CRASH(
"crash_change_partition_9") ||
7234 ERROR_INJECT_ERROR(
"fail_change_partition_9") ||
7235 mysql_drop_partitions(lpt) ||
7236 ERROR_INJECT_CRASH(
"crash_change_partition_10") ||
7237 ERROR_INJECT_ERROR(
"fail_change_partition_10") ||
7238 mysql_rename_partitions(lpt) ||
7239 ERROR_INJECT_CRASH(
"crash_change_partition_11") ||
7240 ERROR_INJECT_ERROR(
"fail_change_partition_11") ||
7241 (write_log_completed(lpt, FALSE), FALSE) ||
7242 ERROR_INJECT_CRASH(
"crash_change_partition_12") ||
7243 ERROR_INJECT_ERROR(
"fail_change_partition_12") ||
7244 (alter_partition_lock_handling(lpt), FALSE))
7246 handle_alter_part_error(lpt, action_completed, FALSE, frm_install,
7247 close_table_on_failure);
7251 downgrade_mdl_if_lock_tables_mode(thd, mdl_ticket, MDL_SHARED_NO_READ_WRITE);
7256 DBUG_RETURN(fast_end_partition(thd, lpt->copied, lpt->deleted, table_list));
7258 downgrade_mdl_if_lock_tables_mode(thd, mdl_ticket, MDL_SHARED_NO_READ_WRITE);
7282 void set_field_ptr(
Field **ptr,
const uchar *new_buf,
7283 const uchar *old_buf)
7285 my_ptrdiff_t diff= (new_buf - old_buf);
7286 DBUG_ENTER(
"set_field_ptr");
7290 (*ptr)->move_field_offset(diff);
7316 void set_key_field_ptr(
KEY *key_info,
const uchar *new_buf,
7317 const uchar *old_buf)
7322 my_ptrdiff_t diff= (new_buf - old_buf);
7323 DBUG_ENTER(
"set_key_field_ptr");
7327 key_part->field->move_field_offset(diff);
7329 }
while (++i < key_parts);
7349 void mem_alloc_error(
size_t size)
7351 my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR),
7352 static_cast<int>(size));
7355 #ifdef WITH_PARTITION_STORAGE_ENGINE
7376 uint partition_id= 0;
7380 if (part_info->is_sub_partitioned())
7383 while ((head_pe= it++))
7388 if (bitmap_is_set(&part_info->read_partitions, partition_id))
7391 if ((part_str.append(head_pe->partition_name,
7392 strlen(head_pe->partition_name),
7393 system_charset_info)) ||
7394 part_str.append(
'_') ||
7395 part_str.append(pe->partition_name,
7396 strlen(pe->partition_name),
7397 system_charset_info) ||
7398 parts->push_back(part_str.dup(current_thd->mem_root)))
7409 if (bitmap_is_set(&part_info->read_partitions, partition_id))
7412 if (part_str.append(pe->partition_name, strlen(pe->partition_name),
7413 system_charset_info) ||
7414 parts->push_back(part_str.dup(current_thd->mem_root)))
7463 #ifdef WITH_PARTITION_STORAGE_ENGINE
7464 static void set_up_range_analysis_info(
partition_info *part_info)
7467 part_info->get_part_iter_for_interval= NULL;
7468 part_info->get_subpart_iter_for_interval= NULL;
7474 switch (part_info->part_type) {
7475 case RANGE_PARTITION:
7476 case LIST_PARTITION:
7477 if (!part_info->column_list)
7479 if (part_info->part_expr->get_monotonicity_info() != NON_MONOTONIC)
7481 part_info->get_part_iter_for_interval=
7482 get_part_iter_for_interval_via_mapping;
7483 goto setup_subparts;
7488 part_info->get_part_iter_for_interval=
7489 get_part_iter_for_interval_cols_via_map;
7490 goto setup_subparts;
7500 if (part_info->num_part_fields == 1)
7502 Field *field= part_info->part_field_array[0];
7503 switch (field->type()) {
7504 case MYSQL_TYPE_TINY:
7505 case MYSQL_TYPE_SHORT:
7506 case MYSQL_TYPE_INT24:
7507 case MYSQL_TYPE_LONG:
7508 case MYSQL_TYPE_LONGLONG:
7509 part_info->get_part_iter_for_interval=
7510 get_part_iter_for_interval_via_walking;
7522 if (part_info->num_subpart_fields == 1)
7524 Field *field= part_info->subpart_field_array[0];
7525 switch (field->type()) {
7526 case MYSQL_TYPE_TINY:
7527 case MYSQL_TYPE_SHORT:
7528 case MYSQL_TYPE_LONG:
7529 case MYSQL_TYPE_LONGLONG:
7530 part_info->get_subpart_iter_for_interval=
7531 get_part_iter_for_interval_via_walking;
7556 uint32 store_tuple_to_record(
Field **pfield,
7557 uint32 *store_length_array,
7564 while (value < value_end)
7567 if ((*pfield)->real_maybe_null())
7570 (*pfield)->set_null();
7572 (*pfield)->set_notnull();
7575 uint len= (*pfield)->pack_length();
7576 (*pfield)->set_key_image(loc_value, len);
7577 value+= *store_length_array;
7578 store_length_array++;
7601 Field **field= part_info->part_field_array;
7602 Field **fields_end= field + nvals_in_rec;
7605 for (; field != fields_end; field++, val++)
7609 if ((*field)->is_null())
7611 if (val->null_value)
7615 if (val->null_value)
7617 res= (*field)->cmp((
const uchar*)val->column_value);
7643 uint32 n_vals_in_rec,
7644 bool is_left_endpoint,
7645 bool include_endpoint)
7649 if ((cmp= cmp_rec_and_tuple(val, n_vals_in_rec)))
7651 field= val->part_info->part_field_array + n_vals_in_rec;
7658 if (!is_left_endpoint && !include_endpoint)
7675 if (is_left_endpoint == include_endpoint)
7682 if (!is_left_endpoint && (val + n_vals_in_rec)->max_value)
7695 typedef uint32 (*get_endpoint_func)(
partition_info*,
bool left_endpoint,
7696 bool include_endpoint);
7698 typedef uint32 (*get_col_endpoint_func)(partition_info*,
bool left_endpoint,
7699 bool include_endpoint,
7716 uint32 get_partition_id_cols_range_for_endpoint(partition_info *part_info,
7717 bool is_left_endpoint,
7718 bool include_endpoint,
7721 uint min_part_id= 0, max_part_id= part_info->num_parts, loc_part_id;
7723 uint num_columns= part_info->part_field_list.elements;
7724 DBUG_ENTER(
"get_partition_id_cols_range_for_endpoint");
7730 loc_part_id= (max_part_id + min_part_id) >> 1;
7731 if (0 <= cmp_rec_and_tuple_prune(range_col_array +
7732 loc_part_id * num_columns,
7736 min_part_id= loc_part_id + 1;
7738 max_part_id= loc_part_id;
7739 }
while (max_part_id > min_part_id);
7740 loc_part_id= max_part_id;
7743 DBUG_ASSERT(loc_part_id == part_info->num_parts ||
7744 (0 > cmp_rec_and_tuple_prune(range_col_array +
7745 loc_part_id * num_columns,
7746 nparts, is_left_endpoint,
7747 include_endpoint)));
7749 DBUG_ASSERT(loc_part_id == 0 ||
7750 (0 <= cmp_rec_and_tuple_prune(range_col_array +
7751 (loc_part_id - 1) * num_columns,
7752 nparts, is_left_endpoint,
7753 include_endpoint)));
7755 if (!is_left_endpoint)
7758 if (loc_part_id < part_info->num_parts)
7761 DBUG_RETURN(loc_part_id);
7765 int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
7767 uint32 *store_length_array,
7768 uchar *min_value, uchar *max_value,
7769 uint min_len, uint max_len,
7774 get_col_endpoint_func get_col_endpoint;
7775 DBUG_ENTER(
"get_part_iter_for_interval_cols_via_map");
7777 if (part_info->part_type == RANGE_PARTITION)
7779 get_col_endpoint= get_partition_id_cols_range_for_endpoint;
7780 part_iter->get_next= get_next_partition_id_range;
7782 else if (part_info->part_type == LIST_PARTITION)
7784 get_col_endpoint= get_partition_id_cols_list_for_endpoint;
7785 part_iter->get_next= get_next_partition_id_list;
7786 part_iter->part_info= part_info;
7787 DBUG_ASSERT(part_info->num_list_values);
7792 if (flags & NO_MIN_RANGE)
7793 part_iter->part_nums.start= part_iter->part_nums.cur= 0;
7797 nparts= store_tuple_to_record(part_info->part_field_array,
7800 min_value + min_len);
7801 part_iter->part_nums.start= part_iter->part_nums.cur=
7802 get_col_endpoint(part_info, TRUE, !(flags & NEAR_MIN),
7805 if (flags & NO_MAX_RANGE)
7807 if (part_info->part_type == RANGE_PARTITION)
7808 part_iter->part_nums.end= part_info->num_parts;
7811 DBUG_ASSERT(part_info->part_type == LIST_PARTITION);
7812 part_iter->part_nums.end= part_info->num_list_values;
7818 nparts= store_tuple_to_record(part_info->part_field_array,
7821 max_value + max_len);
7822 part_iter->part_nums.end= get_col_endpoint(part_info, FALSE,
7823 !(flags & NEAR_MAX),
7826 if (part_iter->part_nums.start == part_iter->part_nums.end)
7866 int get_part_iter_for_interval_via_mapping(partition_info *part_info,
7868 uint32 *store_length_array,
7869 uchar *min_value, uchar *max_value,
7870 uint min_len, uint max_len,
7874 Field *field= part_info->part_field_array[0];
7875 uint32 UNINIT_VAR(max_endpoint_val);
7876 get_endpoint_func UNINIT_VAR(get_endpoint);
7877 bool can_match_multiple_values;
7878 uint field_len= field->pack_length_in_rec();
7880 bool check_zero_dates=
false;
7881 bool zero_in_start_date=
true;
7882 DBUG_ENTER(
"get_part_iter_for_interval_via_mapping");
7883 DBUG_ASSERT(!is_subpart);
7884 (void) store_length_array;
7887 part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
7889 if (part_info->part_type == RANGE_PARTITION)
7891 if (part_info->part_charset_field_array)
7892 get_endpoint= get_partition_id_range_for_endpoint_charset;
7894 get_endpoint= get_partition_id_range_for_endpoint;
7895 max_endpoint_val= part_info->num_parts;
7896 part_iter->get_next= get_next_partition_id_range;
7898 else if (part_info->part_type == LIST_PARTITION)
7901 if (part_info->part_charset_field_array)
7902 get_endpoint= get_list_array_idx_for_endpoint_charset;
7904 get_endpoint= get_list_array_idx_for_endpoint;
7905 max_endpoint_val= part_info->num_list_values;
7906 part_iter->get_next= get_next_partition_id_list;
7907 part_iter->part_info= part_info;
7908 if (max_endpoint_val == 0)
7915 part_iter->part_nums.start= part_iter->part_nums.end= 0;
7916 part_iter->part_nums.cur= 0;
7917 part_iter->ret_null_part= part_iter->ret_null_part_orig= TRUE;
7922 MY_ASSERT_UNREACHABLE();
7924 can_match_multiple_values= (flags || !min_value || !max_value ||
7925 memcmp(min_value, max_value, field_len));
7926 if (can_match_multiple_values &&
7927 (part_info->part_type == RANGE_PARTITION ||
7928 part_info->has_null_value))
7931 enum_monotonicity_info monotonic;
7932 monotonic= part_info->part_expr->get_monotonicity_info();
7933 if (monotonic == MONOTONIC_INCREASING_NOT_NULL ||
7934 monotonic == MONOTONIC_STRICT_INCREASING_NOT_NULL)
7937 part_iter->ret_null_part= part_iter->ret_null_part_orig= TRUE;
7938 check_zero_dates=
true;
7947 !(flags & (NO_MIN_RANGE | NEAR_MIN)) && *min_value)
7949 part_iter->ret_null_part= part_iter->ret_null_part_orig= TRUE;
7950 part_iter->part_nums.start= part_iter->part_nums.cur= 0;
7951 if (!(flags & NO_MAX_RANGE) && *max_value)
7954 part_iter->part_nums.end= 0;
7960 if (flags & NO_MIN_RANGE)
7961 part_iter->part_nums.start= part_iter->part_nums.cur= 0;
7970 store_key_image_to_rec(field, min_value, field_len);
7971 bool include_endp= !
test(flags & NEAR_MIN);
7972 part_iter->part_nums.start= get_endpoint(part_info, 1, include_endp);
7973 if (!can_match_multiple_values && part_info->part_expr->null_value)
7976 part_iter->part_nums.cur= part_iter->part_nums.start= 0;
7977 part_iter->part_nums.end= 0;
7978 part_iter->ret_null_part= part_iter->ret_null_part_orig= TRUE;
7981 part_iter->part_nums.cur= part_iter->part_nums.start;
7982 if (check_zero_dates && !part_info->part_expr->null_value)
7984 if (!(flags & NO_MAX_RANGE) &&
7985 (field->type() == MYSQL_TYPE_DATE ||
7986 field->type() == MYSQL_TYPE_DATETIME))
7989 zero_in_start_date= field->get_date(&start_date, 0);
7990 DBUG_PRINT(
"info", (
"zero start %u %04d-%02d-%02d",
7991 zero_in_start_date, start_date.year,
7992 start_date.month, start_date.day));
7995 if (part_iter->part_nums.start == max_endpoint_val)
8001 if (flags & NO_MAX_RANGE)
8002 part_iter->part_nums.end= max_endpoint_val;
8005 store_key_image_to_rec(field, max_value, field_len);
8006 bool include_endp= !
test(flags & NEAR_MAX);
8007 part_iter->part_nums.end= get_endpoint(part_info, 0, include_endp);
8008 if (check_zero_dates &&
8009 !zero_in_start_date &&
8010 !part_info->part_expr->null_value)
8013 bool zero_in_end_date= field->get_date(&end_date, 0);
8019 DBUG_PRINT(
"info", (
"zero end %u %04d-%02d-%02d",
8021 end_date.year, end_date.month, end_date.day));
8022 DBUG_ASSERT(!memcmp(((
Item_func*) part_info->part_expr)->func_name(),
8024 !memcmp(((
Item_func*) part_info->part_expr)->func_name(),
8026 if (!zero_in_end_date &&
8027 start_date.month == end_date.month &&
8028 start_date.year == end_date.year)
8029 part_iter->ret_null_part= part_iter->ret_null_part_orig=
false;
8031 if (part_iter->part_nums.start >= part_iter->part_nums.end &&
8032 !part_iter->ret_null_part)
8040 #define MAX_RANGE_TO_WALK 32
8082 int get_part_iter_for_interval_via_walking(partition_info *part_info,
8084 uint32 *store_length_array,
8085 uchar *min_value, uchar *max_value,
8086 uint min_len, uint max_len,
8092 partition_iter_func get_next_func;
8093 DBUG_ENTER(
"get_part_iter_for_interval_via_walking");
8094 (void)store_length_array;
8098 part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
8101 field= part_info->subpart_field_array[0];
8102 total_parts= part_info->num_subparts;
8103 get_next_func= get_next_subpartition_via_walking;
8107 field= part_info->part_field_array[0];
8108 total_parts= part_info->num_parts;
8109 get_next_func= get_next_partition_via_walking;
8113 if (field->
real_maybe_null() && !(flags & (NO_MIN_RANGE | NO_MAX_RANGE)) &&
8114 *min_value && *max_value)
8125 if (!part_info->get_subpartition_id(part_info, &part_id))
8127 init_single_partition_iterator(part_id, part_iter);
8134 int res= part_info->is_sub_partitioned() ?
8135 part_info->get_part_partition_id(part_info, &part_id,
8137 part_info->get_partition_id(part_info, &part_id, &dummy);
8140 init_single_partition_iterator(part_id, part_iter);
8148 ((!(flags & NO_MIN_RANGE) && *min_value) ||
8149 (!(flags & NO_MAX_RANGE) && *max_value))) ||
8150 (flags & (NO_MIN_RANGE | NO_MAX_RANGE)))
8157 uint len= field->pack_length_in_rec();
8158 store_key_image_to_rec(field, min_value, len);
8159 a= field->val_int();
8161 store_key_image_to_rec(field, max_value, len);
8162 b= field->val_int();
8170 if ((ulonglong)b - (ulonglong)a == ~0ULL)
8173 a +=
test(flags & NEAR_MIN);
8174 b +=
test(!(flags & NEAR_MAX));
8175 ulonglong n_values= b - a;
8193 if ((n_values > 2*total_parts) && n_values > MAX_RANGE_TO_WALK)
8196 part_iter->field_vals.start= part_iter->field_vals.cur= a;
8197 part_iter->field_vals.end= b;
8198 part_iter->part_info= part_info;
8199 part_iter->get_next= get_next_func;
8223 if (part_iter->part_nums.cur >= part_iter->part_nums.end)
8225 if (part_iter->ret_null_part)
8227 part_iter->ret_null_part= FALSE;
8230 part_iter->part_nums.cur= part_iter->part_nums.start;
8231 part_iter->ret_null_part= part_iter->ret_null_part_orig;
8232 return NOT_A_PARTITION_ID;
8235 return part_iter->part_nums.cur++;
8260 if (part_iter->part_nums.cur >= part_iter->part_nums.end)
8262 if (part_iter->ret_null_part)
8264 part_iter->ret_null_part= FALSE;
8265 return part_iter->part_info->has_null_part_id;
8267 part_iter->part_nums.cur= part_iter->part_nums.start;
8268 part_iter->ret_null_part= part_iter->ret_null_part_orig;
8269 return NOT_A_PARTITION_ID;
8273 partition_info *part_info= part_iter->part_info;
8274 uint32 num_part= part_iter->part_nums.cur++;
8275 if (part_info->column_list)
8277 uint num_columns= part_info->part_field_list.elements;
8278 return part_info->list_col_array[num_part*num_columns].partition_id;
8280 return part_info->list_array[num_part].partition_id;
8306 Field *field= part_iter->part_info->part_field_array[0];
8307 while (part_iter->field_vals.cur != part_iter->field_vals.end)
8310 field->store(part_iter->field_vals.cur++, field->flags & UNSIGNED_FLAG);
8311 if ((part_iter->part_info->is_sub_partitioned() &&
8312 !part_iter->part_info->get_part_partition_id(part_iter->part_info,
8313 &part_id, &dummy)) ||
8314 !part_iter->part_info->get_partition_id(part_iter->part_info,
8318 part_iter->field_vals.cur= part_iter->field_vals.start;
8319 return NOT_A_PARTITION_ID;
8327 Field *field= part_iter->part_info->subpart_field_array[0];
8329 if (part_iter->field_vals.cur == part_iter->field_vals.end)
8331 part_iter->field_vals.cur= part_iter->field_vals.start;
8332 return NOT_A_PARTITION_ID;
8334 field->store(part_iter->field_vals.cur++, field->flags & UNSIGNED_FLAG);
8335 if (part_iter->part_info->get_subpartition_id(part_iter->part_info,
8337 return NOT_A_PARTITION_ID;
8360 void create_partition_name(
char *out,
const char *in1,
8361 const char *in2, uint name_variant,
8364 char transl_part_name[FN_REFLEN];
8365 const char *transl_part;
8369 tablename_to_filename(in2, transl_part_name, FN_REFLEN);
8370 transl_part= transl_part_name;
8374 if (name_variant == NORMAL_PART_NAME)
8375 strxmov(out, in1,
"#P#", transl_part, NullS);
8376 else if (name_variant == TEMP_PART_NAME)
8377 strxmov(out, in1,
"#P#", transl_part,
"#TMP#", NullS);
8378 else if (name_variant == RENAMED_PART_NAME)
8379 strxmov(out, in1,
"#P#", transl_part,
"#REN#", NullS);
8402 void create_subpartition_name(
char *out,
const char *in1,
8403 const char *in2,
const char *in3,
8406 char transl_part_name[FN_REFLEN], transl_subpart_name[FN_REFLEN];
8408 tablename_to_filename(in2, transl_part_name, FN_REFLEN);
8409 tablename_to_filename(in3, transl_subpart_name, FN_REFLEN);
8410 if (name_variant == NORMAL_PART_NAME)
8411 strxmov(out, in1,
"#P#", transl_part_name,
8412 "#SP#", transl_subpart_name, NullS);
8413 else if (name_variant == TEMP_PART_NAME)
8414 strxmov(out, in1,
"#P#", transl_part_name,
8415 "#SP#", transl_subpart_name,
"#TMP#", NullS);
8416 else if (name_variant == RENAMED_PART_NAME)
8417 strxmov(out, in1,
"#P#", transl_part_name,
8418 "#SP#", transl_subpart_name,
"#REN#", NullS);
8421 uint get_partition_field_store_length(
Field *field)
8425 store_length= field->key_length();
8427 store_length+= HA_KEY_NULL_LENGTH;
8428 if (field->real_type() == MYSQL_TYPE_VARCHAR)
8429 store_length+= HA_KEY_BLOB_LENGTH;
8430 return store_length;