53 #include "sql_parse.h"
56 #ifdef WITH_PARTITION_STORAGE_ENGINE
57 #include "ha_partition.h"
58 #include "sql_table.h"
60 #include "sql_plugin.h"
61 #include "sql_partition.h"
63 #include "sql_admin.h"
72 #define PAR_WORD_SIZE 4
74 #define PAR_CHECKSUM_OFFSET 4
76 #define PAR_NUM_PARTS_OFFSET 8
78 #define PAR_ENGINES_OFFSET 12
79 #define PARTITION_ENABLED_TABLE_FLAGS (HA_FILE_BASED | \
82 #define PARTITION_DISABLED_TABLE_FLAGS (HA_CAN_GEOMETRY | \
85 HA_CAN_SQL_HANDLER | \
86 HA_CAN_INSERT_DELAYED | \
87 HA_READ_BEFORE_WRITE_REMOVAL)
88 static const char *ha_par_ext=
".par";
97 static uint partition_flags();
98 static uint alter_table_flags(uint
flags);
100 #ifdef HAVE_PSI_INTERFACE
101 PSI_mutex_key key_partition_auto_inc_mutex;
103 static PSI_mutex_info all_partition_mutexes[]=
105 { &key_partition_auto_inc_mutex,
"Partition_share::auto_inc_mutex", 0}
108 static void init_partition_psi_keys(
void)
110 const char* category=
"partition";
113 count= array_elements(all_partition_mutexes);
118 static int partition_initialize(
void *p)
124 partition_hton->state= SHOW_OPTION_YES;
125 partition_hton->db_type= DB_TYPE_PARTITION_DB;
126 partition_hton->create= partition_create_handler;
127 partition_hton->partition_flags= partition_flags;
128 partition_hton->alter_table_flags= alter_table_flags;
129 partition_hton->flags= HTON_NOT_USER_SELECTABLE |
131 HTON_TEMPORARY_NOT_SUPPORTED;
132 #ifdef HAVE_PSI_INTERFACE
133 init_partition_psi_keys();
149 bool Partition_share::init(uint num_parts)
151 DBUG_ENTER(
"Partition_share::init");
155 auto_inc_initialized=
false;
186 if (file && file->initialize_partition(mem_root))
213 static uint partition_flags()
215 return HA_CAN_PARTITION;
218 static uint alter_table_flags(uint
flags __attribute__((unused)))
220 return (HA_PARTITION_FUNCTION_SUPPORTED |
221 HA_FAST_CHANGE_PARTITION);
224 const uint32 ha_partition::NO_CURRENT_PART_ID= NOT_A_PARTITION_ID;
240 DBUG_ENTER(
"ha_partition::ha_partition(table)");
241 init_handler_variables();
260 DBUG_ENTER(
"ha_partition::ha_partition(part_info)");
261 DBUG_ASSERT(part_info);
262 init_handler_variables();
263 m_part_info= part_info;
264 m_create_handler= TRUE;
265 m_is_sub_partitioned= m_part_info->is_sub_partitioned();
287 DBUG_ENTER(
"ha_partition::ha_partition(clone)");
288 init_handler_variables();
289 m_part_info= part_info_arg;
290 m_create_handler= TRUE;
291 m_is_sub_partitioned= m_part_info->is_sub_partitioned();
292 m_is_clone_of= clone_arg;
293 m_clone_mem_root= clone_mem_root_arg;
294 part_share= clone_arg->part_share;
295 m_tot_parts= clone_arg->m_tot_parts;
296 m_pkey_is_clustered= clone_arg->primary_key_is_clustered();
310 void ha_partition::init_handler_variables()
312 active_index= MAX_KEY;
316 m_name_buffer_ptr= NULL;
317 m_engine_array= NULL;
320 m_reorged_file= NULL;
325 m_pkey_is_clustered= 0;
326 m_part_spec.start_part= NO_CURRENT_PART_ID;
329 m_part_spec.end_part= NO_CURRENT_PART_ID;
330 m_index_scan_type= partition_no_index_scan;
331 m_start_key.key= NULL;
332 m_start_key.length= 0;
335 m_extra_cache= FALSE;
336 m_extra_cache_size= 0;
337 m_extra_prepare_for_update= FALSE;
338 m_extra_cache_part_id= NO_CURRENT_PART_ID;
339 m_handler_status= handler_not_initialized;
341 m_part_field_array= NULL;
342 m_ordered_rec_buffer= NULL;
343 m_top_entry= NO_CURRENT_PART_ID;
348 m_curr_key_info[0]= NULL;
349 m_curr_key_info[1]= NULL;
350 m_part_func_monotonicity_info= NON_MONOTONIC;
351 auto_increment_lock= FALSE;
352 auto_increment_safe_stmt_log_lock= FALSE;
358 m_create_handler= FALSE;
359 m_is_sub_partitioned= 0;
361 m_clone_mem_root= NULL;
363 m_new_partitions_share_refs.empty();
364 m_part_ids_sorted_by_num_of_records= NULL;
366 #ifdef DONT_HAVE_TO_BE_INITALIZED
390 ha_partition::~ha_partition()
392 DBUG_ENTER(
"ha_partition::~ha_partition()");
393 if (m_new_partitions_share_refs.elements)
394 m_new_partitions_share_refs.delete_elements();
398 for (i= 0; i < m_tot_parts; i++)
401 destroy_record_priority_queue();
402 my_free(m_part_ids_sorted_by_num_of_records);
404 clear_handler_file();
454 bool ha_partition::initialize_partition(
MEM_ROOT *mem_root)
457 ulonglong check_table_flags;
458 DBUG_ENTER(
"ha_partition::initialize_partition");
460 if (m_create_handler)
462 m_tot_parts= m_part_info->get_tot_partitions();
463 DBUG_ASSERT(m_tot_parts > 0);
464 if (new_handlers_from_part_info(mem_root))
467 else if (!table_share || !table_share->normalized_path.str)
475 else if (get_from_handler_file(table_share->normalized_path.str,
478 my_error(ER_FAILED_READ_FROM_PAR_FILE, MYF(0));
491 m_low_byte_first= m_file[0]->low_byte_first();
492 m_pkey_is_clustered= TRUE;
497 if (m_low_byte_first != file->low_byte_first())
500 my_error(ER_MIX_HANDLER_ERROR, MYF(0));
503 if (!file->primary_key_is_clustered())
504 m_pkey_is_clustered= FALSE;
507 my_error(ER_MIX_HANDLER_ERROR, MYF(0));
510 }
while (*(++file_array));
511 m_handler_status= handler_initialized;
547 DBUG_ENTER(
"ha_partition::delete_table");
549 DBUG_RETURN(del_ren_table(name, NULL));
577 DBUG_ENTER(
"ha_partition::rename_table");
579 DBUG_RETURN(del_ren_table(from, to));
603 int ha_partition::create_handler_files(
const char *path,
604 const char *old_path,
608 DBUG_ENTER(
"ha_partition::create_handler_files()");
614 if (action_flag == CHF_DELETE_FLAG ||
615 action_flag == CHF_RENAME_FLAG)
617 char name[FN_REFLEN];
618 char old_name[FN_REFLEN];
620 strxmov(name, path, ha_par_ext, NullS);
621 strxmov(old_name, old_path, ha_par_ext, NullS);
622 if ((action_flag == CHF_DELETE_FLAG &&
624 (action_flag == CHF_RENAME_FLAG &&
630 else if (action_flag == CHF_CREATE_FLAG)
632 if (create_handler_file(path))
634 my_error(ER_CANT_CREATE_HANDLER_FILE, MYF(0));
666 int ha_partition::create(
const char *name,
TABLE *table_arg,
670 char name_buff[FN_REFLEN], name_lc_buff[FN_REFLEN];
671 char *name_buffer_ptr;
677 DBUG_ENTER(
"ha_partition::create");
679 DBUG_ASSERT(*fn_rext((
char*)name) ==
'\0');
682 if (create_info && create_info->options & HA_LEX_CREATE_TMP_TABLE)
684 my_error(ER_PARTITION_NO_TEMPORARY, MYF(0));
688 if (get_from_handler_file(name, ha_thd()->mem_root,
false))
690 DBUG_ASSERT(m_file_buffer);
691 DBUG_PRINT(
"enter", (
"name: (%s)", name));
692 name_buffer_ptr= m_name_buffer_ptr;
702 for (i= 0; i < m_part_info->num_parts; i++)
704 part_elem= part_it++;
705 if (m_is_sub_partitioned)
709 for (j= 0; j < m_part_info->num_subparts; j++)
712 create_partition_name(name_buff, path, name_buffer_ptr,
713 NORMAL_PART_NAME, FALSE);
714 if ((error= set_up_table_before_create(table_arg, name_buff,
715 create_info, part_elem)) ||
716 ((error= (*file)->ha_create(name_buff, table_arg, create_info))))
719 name_buffer_ptr= strend(name_buffer_ptr) + 1;
725 create_partition_name(name_buff, path, name_buffer_ptr,
726 NORMAL_PART_NAME, FALSE);
727 if ((error= set_up_table_before_create(table_arg, name_buff,
728 create_info, part_elem)) ||
729 ((error= (*file)->ha_create(name_buff, table_arg, create_info))))
732 name_buffer_ptr= strend(name_buffer_ptr) + 1;
739 name_buffer_ptr= m_name_buffer_ptr;
740 for (abort_file= file, file= m_file; file < abort_file; file++)
742 create_partition_name(name_buff, path, name_buffer_ptr, NORMAL_PART_NAME,
744 (void) (*file)->ha_delete_table((
const char*) name_buff);
745 name_buffer_ptr= strend(name_buffer_ptr) + 1;
768 int ha_partition::drop_partitions(
const char *path)
771 char part_name_buff[FN_REFLEN];
772 uint num_parts= m_part_info->partitions.elements;
773 uint num_subparts= m_part_info->num_subparts;
778 DBUG_ENTER(
"ha_partition::drop_partitions");
789 if (part_elem->part_state == PART_TO_BE_DROPPED)
795 name_variant= NORMAL_PART_NAME;
796 if (m_is_sub_partitioned)
803 part= i * num_subparts + j;
804 create_subpartition_name(part_name_buff, path,
805 part_elem->partition_name,
806 sub_elem->partition_name, name_variant);
808 DBUG_PRINT(
"info", (
"Drop subpartition %s", part_name_buff));
811 if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos))
813 }
while (++j < num_subparts);
817 create_partition_name(part_name_buff, path,
818 part_elem->partition_name, name_variant,
821 DBUG_PRINT(
"info", (
"Drop partition %s", part_name_buff));
824 if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
827 if (part_elem->part_state == PART_IS_CHANGED)
828 part_elem->part_state= PART_NORMAL;
830 part_elem->part_state= PART_IS_DROPPED;
832 }
while (++i < num_parts);
833 (void) sync_ddl_log();
857 int ha_partition::rename_partitions(
const char *path)
861 char part_name_buff[FN_REFLEN];
862 char norm_name_buff[FN_REFLEN];
863 uint num_parts= m_part_info->partitions.elements;
865 uint num_subparts= m_part_info->num_subparts;
870 uint temp_partitions= m_part_info->temp_partitions.elements;
873 DBUG_ENTER(
"ha_partition::rename_partitions");
882 DEBUG_SYNC(ha_thd(),
"before_rename_partitions");
895 part_elem= temp_it++;
896 if (m_is_sub_partitioned)
903 file= m_reorged_file[part_count++];
904 create_subpartition_name(norm_name_buff, path,
905 part_elem->partition_name,
906 sub_elem->partition_name,
908 DBUG_PRINT(
"info", (
"Delete subpartition %s", norm_name_buff));
911 else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos))
914 sub_elem->log_entry= NULL;
915 }
while (++j < num_subparts);
919 file= m_reorged_file[part_count++];
920 create_partition_name(norm_name_buff, path,
921 part_elem->partition_name, NORMAL_PART_NAME,
923 DBUG_PRINT(
"info", (
"Delete partition %s", norm_name_buff));
926 else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
929 part_elem->log_entry= NULL;
931 }
while (++i < temp_partitions);
932 (void) sync_ddl_log();
957 part_elem= part_it++;
958 if (part_elem->part_state == PART_IS_CHANGED ||
959 part_elem->part_state == PART_TO_BE_DROPPED ||
960 (part_elem->part_state == PART_IS_ADDED && temp_partitions))
962 if (m_is_sub_partitioned)
971 part= i * num_subparts + j;
972 create_subpartition_name(norm_name_buff, path,
973 part_elem->partition_name,
974 sub_elem->partition_name,
976 if (part_elem->part_state == PART_IS_CHANGED)
978 file= m_reorged_file[part_count++];
979 DBUG_PRINT(
"info", (
"Delete subpartition %s", norm_name_buff));
982 else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos))
984 (void) sync_ddl_log();
986 file= m_new_file[part];
987 create_subpartition_name(part_name_buff, path,
988 part_elem->partition_name,
989 sub_elem->partition_name,
991 DBUG_PRINT(
"info", (
"Rename subpartition from %s to %s",
992 part_name_buff, norm_name_buff));
996 else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos))
999 sub_elem->log_entry= NULL;
1000 }
while (++j < num_subparts);
1004 create_partition_name(norm_name_buff, path,
1005 part_elem->partition_name, NORMAL_PART_NAME,
1007 if (part_elem->part_state == PART_IS_CHANGED)
1009 file= m_reorged_file[part_count++];
1010 DBUG_PRINT(
"info", (
"Delete partition %s", norm_name_buff));
1013 else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
1015 (void) sync_ddl_log();
1017 file= m_new_file[
i];
1018 create_partition_name(part_name_buff, path,
1019 part_elem->partition_name, TEMP_PART_NAME,
1021 DBUG_PRINT(
"info", (
"Rename partition from %s to %s",
1022 part_name_buff, norm_name_buff));
1026 else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
1029 part_elem->log_entry= NULL;
1032 }
while (++i < num_parts);
1033 (void) sync_ddl_log();
1038 #define OPTIMIZE_PARTS 1
1039 #define ANALYZE_PARTS 2
1040 #define CHECK_PARTS 3
1041 #define REPAIR_PARTS 4
1042 #define ASSIGN_KEYCACHE_PARTS 5
1043 #define PRELOAD_KEYS_PARTS 6
1045 static const char *opt_op_name[]= {NULL,
1046 "optimize",
"analyze",
"check",
"repair",
1047 "assign_to_keycache",
"preload_keys"};
1062 int ha_partition::optimize(THD *thd,
HA_CHECK_OPT *check_opt)
1064 DBUG_ENTER(
"ha_partition::optimize");
1066 DBUG_RETURN(handle_opt_partitions(thd, check_opt, OPTIMIZE_PARTS));
1083 int ha_partition::analyze(THD *thd,
HA_CHECK_OPT *check_opt)
1085 DBUG_ENTER(
"ha_partition::analyze");
1087 DBUG_RETURN(handle_opt_partitions(thd, check_opt, ANALYZE_PARTS));
1104 int ha_partition::check(THD *thd,
HA_CHECK_OPT *check_opt)
1106 DBUG_ENTER(
"ha_partition::check");
1108 DBUG_RETURN(handle_opt_partitions(thd, check_opt, CHECK_PARTS));
1127 DBUG_ENTER(
"ha_partition::repair");
1129 DBUG_RETURN(handle_opt_partitions(thd, check_opt, REPAIR_PARTS));
1143 int ha_partition::assign_to_keycache(THD *thd,
HA_CHECK_OPT *check_opt)
1145 DBUG_ENTER(
"ha_partition::assign_to_keycache");
1147 DBUG_RETURN(handle_opt_partitions(thd, check_opt, ASSIGN_KEYCACHE_PARTS));
1162 int ha_partition::preload_keys(THD *thd,
HA_CHECK_OPT *check_opt)
1164 DBUG_ENTER(
"ha_partition::preload_keys");
1166 DBUG_RETURN(handle_opt_partitions(thd, check_opt, PRELOAD_KEYS_PARTS));
1185 int ha_partition::handle_opt_part(THD *thd,
HA_CHECK_OPT *check_opt,
1186 uint part_id, uint flag)
1189 handler *file= m_file[part_id];
1190 DBUG_ENTER(
"handle_opt_part");
1191 DBUG_PRINT(
"enter", (
"flag = %u", flag));
1193 if (flag == OPTIMIZE_PARTS)
1195 else if (flag == ANALYZE_PARTS)
1197 else if (flag == CHECK_PARTS)
1199 error= file->
ha_check(thd, check_opt);
1201 error == HA_ADMIN_ALREADY_DONE ||
1202 error == HA_ADMIN_NOT_IMPLEMENTED)
1204 if (check_opt->flags & (T_MEDIUM | T_EXTEND))
1205 error= check_misplaced_rows(part_id,
false);
1208 else if (flag == REPAIR_PARTS)
1212 error == HA_ADMIN_ALREADY_DONE ||
1213 error == HA_ADMIN_NOT_IMPLEMENTED)
1215 if (check_opt->flags & (T_MEDIUM | T_EXTEND))
1216 error= check_misplaced_rows(part_id,
true);
1219 else if (flag == ASSIGN_KEYCACHE_PARTS)
1220 error= file->assign_to_keycache(thd, check_opt);
1221 else if (flag == PRELOAD_KEYS_PARTS)
1222 error= file->preload_keys(thd, check_opt);
1228 if (error == HA_ADMIN_ALREADY_DONE)
1239 static bool print_admin_msg(THD* thd, uint len,
1240 const char* msg_type,
1242 const char* op_name,
const char *
fmt, ...)
1243 ATTRIBUTE_FORMAT(printf, 7, 8);
1244 static
bool print_admin_msg(THD* thd, uint len,
1245 const
char* msg_type,
1246 const
char* db_name, const
char* table_name,
1247 const
char* op_name, const
char *fmt, ...)
1253 char name[NAME_LEN*2+2];
1257 if (!(msgbuf= (
char*) my_malloc(len, MYF(0))))
1259 va_start(args, fmt);
1260 msg_length= my_vsnprintf(msgbuf, len, fmt, args);
1262 if (msg_length >= (len - 1))
1264 msgbuf[len - 1] = 0;
1269 sql_print_error(
"%s", msgbuf);
1273 length=(uint) (strxmov(name, db_name,
".", table_name,NullS) -
name);
1282 DBUG_PRINT(
"info",(
"print_admin_msg: %s, %s, %s, %s", name, op_name,
1284 protocol->prepare_for_resend();
1285 protocol->
store(name, length, system_charset_info);
1286 protocol->
store(op_name, system_charset_info);
1287 protocol->
store(msg_type, system_charset_info);
1288 protocol->
store(msgbuf, msg_length, system_charset_info);
1289 if (protocol->write())
1291 sql_print_error(
"Failed on my_net_write, writing to stderr instead: %s\n",
1316 int ha_partition::handle_opt_partitions(THD *thd,
HA_CHECK_OPT *check_opt,
1320 uint num_parts= m_part_info->num_parts;
1321 uint num_subparts= m_part_info->num_subparts;
1324 DBUG_ENTER(
"ha_partition::handle_opt_partitions");
1325 DBUG_PRINT(
"enter", (
"flag= %u", flag));
1334 if (!(thd->lex->alter_info.flags & Alter_info::ALTER_ADMIN_PARTITION) ||
1335 part_elem->part_state == PART_ADMIN)
1337 if (m_is_sub_partitioned)
1344 sub_elem= subpart_it++;
1345 part= i * num_subparts + j;
1346 DBUG_PRINT(
"info", (
"Optimize subpartition %u (%s)",
1347 part, sub_elem->partition_name));
1348 if ((error= handle_opt_part(thd, check_opt, part, flag)))
1351 if (error != HA_ADMIN_NOT_IMPLEMENTED &&
1352 error != HA_ADMIN_ALREADY_DONE &&
1353 error != HA_ADMIN_TRY_ALTER)
1355 print_admin_msg(thd, MI_MAX_MSG_BUF,
"error",
1356 table_share->db.str,
table->alias,
1358 "Subpartition %s returned error",
1359 sub_elem->partition_name);
1364 if (part_elem->part_state == PART_ADMIN)
1365 part_elem->part_state= PART_NORMAL;
1366 }
while ((part_elem= part_it++));
1369 }
while (++j < num_subparts);
1373 DBUG_PRINT(
"info", (
"Optimize partition %u (%s)", i,
1374 part_elem->partition_name));
1375 if ((error= handle_opt_part(thd, check_opt, i, flag)))
1378 if (error != HA_ADMIN_NOT_IMPLEMENTED &&
1379 error != HA_ADMIN_ALREADY_DONE &&
1380 error != HA_ADMIN_TRY_ALTER)
1382 print_admin_msg(thd, MI_MAX_MSG_BUF,
"error",
1383 table_share->db.str,
table->alias,
1384 opt_op_name[flag],
"Partition %s returned error",
1385 part_elem->partition_name);
1390 if (part_elem->part_state == PART_ADMIN)
1391 part_elem->part_state= PART_NORMAL;
1392 }
while ((part_elem= part_it++));
1396 part_elem->part_state= PART_NORMAL;
1398 }
while (++i < num_parts);
1414 bool ha_partition::check_and_repair(THD *thd)
1417 DBUG_ENTER(
"ha_partition::check_and_repair");
1421 if ((*file)->ha_check_and_repair(thd))
1423 }
while (*(++file));
1435 bool ha_partition::auto_repair()
const
1437 DBUG_ENTER(
"ha_partition::auto_repair");
1443 DBUG_RETURN(m_file[0]->auto_repair());
1454 bool ha_partition::is_crashed()
const
1457 DBUG_ENTER(
"ha_partition::is_crashed");
1461 if ((*file)->is_crashed())
1463 }
while (*(++file));
1483 int ha_partition::prepare_new_partition(
TABLE *tbl,
1485 handler *file,
const char *part_name,
1489 DBUG_ENTER(
"prepare_new_partition");
1504 truncate_partition_filename(p_elem->data_file_name);
1505 truncate_partition_filename(p_elem->index_file_name);
1507 if ((error= set_up_table_before_create(tbl, part_name, create_info, p_elem)))
1510 if ((error= file->
ha_create(part_name, tbl, create_info)))
1519 if (error == HA_ERR_FOUND_DUPP_KEY)
1520 error= HA_ERR_TABLE_EXIST;
1523 DBUG_PRINT(
"info", (
"partition %s created", part_name));
1524 if ((error= file->
ha_open(tbl, part_name, m_mode,
1525 m_open_test_lock | HA_OPEN_NO_PSI_CALL)))
1527 DBUG_PRINT(
"info", (
"partition %s opened", part_name));
1535 goto error_external_lock;
1536 DBUG_PRINT(
"info", (
"partition %s external locked", part_name));
1539 error_external_lock:
1575 void ha_partition::cleanup_new_partition(uint part_count)
1577 DBUG_ENTER(
"ha_partition::cleanup_new_partition");
1583 while ((part_count > 0) && (*file))
1586 (*file)->ha_close();
1629 ulonglong *
const copied,
1630 ulonglong *
const deleted,
1631 const uchar *pack_frm_data
1632 __attribute__((unused)),
1634 __attribute__((unused)))
1638 char part_name_buff[FN_REFLEN];
1639 uint num_parts= m_part_info->partitions.elements;
1640 uint num_subparts= m_part_info->num_subparts;
1642 uint num_remain_partitions, part_count, orig_count;
1646 uint temp_partitions= m_part_info->temp_partitions.elements;
1648 DBUG_ENTER(
"ha_partition::change_partitions");
1657 if (!m_part_info->is_sub_partitioned())
1665 if (temp_partitions)
1667 m_reorged_parts= temp_partitions * num_subparts;
1674 if (part_elem->part_state == PART_CHANGED ||
1675 part_elem->part_state == PART_REORGED_DROPPED)
1677 m_reorged_parts+= num_subparts;
1679 }
while (++i < num_parts);
1681 if (m_reorged_parts &&
1683 (m_reorged_parts + 1))))
1685 mem_alloc_error(
sizeof(
handler*)*(m_reorged_parts+1));
1686 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1694 num_remain_partitions= 0;
1695 if (temp_partitions)
1697 num_remain_partitions= num_parts * num_subparts;
1706 if (part_elem->part_state == PART_NORMAL ||
1707 part_elem->part_state == PART_TO_BE_ADDED ||
1708 part_elem->part_state == PART_CHANGED)
1710 num_remain_partitions+= num_subparts;
1712 }
while (++i < num_parts);
1715 (2*(num_remain_partitions + 1)))))
1717 mem_alloc_error(
sizeof(
handler*)*2*(num_remain_partitions+1));
1718 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1720 m_added_file= &new_file_array[num_remain_partitions + 1];
1726 if (m_reorged_parts)
1735 if (part_elem->part_state == PART_CHANGED ||
1736 part_elem->part_state == PART_REORGED_DROPPED)
1738 memcpy((
void*)&m_reorged_file[part_count],
1739 (
void*)&m_file[i*num_subparts],
1740 sizeof(
handler*)*num_subparts);
1741 part_count+= num_subparts;
1743 else if (first && temp_partitions &&
1744 part_elem->part_state == PART_TO_BE_ADDED)
1756 DBUG_ASSERT(((i*num_subparts) + m_reorged_parts) <= m_file_tot_parts);
1757 memcpy((
void*)m_reorged_file, &m_file[i*num_subparts],
1758 sizeof(
handler*)*m_reorged_parts);
1760 }
while (++i < num_parts);
1776 if (part_elem->part_state == PART_NORMAL)
1778 DBUG_ASSERT(orig_count + num_subparts <= m_file_tot_parts);
1779 memcpy((
void*)&new_file_array[part_count], (
void*)&m_file[orig_count],
1780 sizeof(
handler*)*num_subparts);
1781 part_count+= num_subparts;
1782 orig_count+= num_subparts;
1784 else if (part_elem->part_state == PART_CHANGED ||
1785 part_elem->part_state == PART_TO_BE_ADDED)
1796 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1797 if (p_share_refs->init(num_subparts))
1798 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1799 if (m_new_partitions_share_refs.push_back(p_share_refs))
1800 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1803 handler **new_file= &new_file_array[part_count++];
1805 get_new_handler(
table->s,
1807 part_elem->engine_type)))
1809 mem_alloc_error(
sizeof(
handler));
1810 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1812 if ((*new_file)->set_ha_share_ref(&p_share_refs->
ha_shares[j]))
1814 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1816 }
while (++j < num_subparts);
1817 if (part_elem->part_state == PART_CHANGED)
1818 orig_count+= num_subparts;
1819 else if (temp_partitions && first)
1821 orig_count+= (num_subparts * temp_partitions);
1825 }
while (++i < num_parts);
1839 if (part_elem->part_state == PART_TO_BE_ADDED ||
1840 part_elem->part_state == PART_CHANGED)
1847 uint name_variant= NORMAL_PART_NAME;
1848 if (part_elem->part_state == PART_CHANGED ||
1849 (part_elem->part_state == PART_TO_BE_ADDED && temp_partitions))
1850 name_variant= TEMP_PART_NAME;
1851 if (m_part_info->is_sub_partitioned())
1858 create_subpartition_name(part_name_buff, path,
1859 part_elem->partition_name,
1860 sub_elem->partition_name,
1862 part= i * num_subparts + j;
1863 DBUG_PRINT(
"info", (
"Add subpartition %s", part_name_buff));
1864 if ((error= prepare_new_partition(
table, create_info,
1865 new_file_array[part],
1866 (
const char *)part_name_buff,
1869 cleanup_new_partition(part_count);
1872 m_added_file[part_count++]= new_file_array[part];
1873 }
while (++j < num_subparts);
1877 create_partition_name(part_name_buff, path,
1878 part_elem->partition_name, name_variant,
1880 DBUG_PRINT(
"info", (
"Add partition %s", part_name_buff));
1881 if ((error= prepare_new_partition(
table, create_info,
1883 (
const char *)part_name_buff,
1886 cleanup_new_partition(part_count);
1889 m_added_file[part_count++]= new_file_array[
i];
1892 }
while (++i < num_parts);
1903 if (part_elem->part_state == PART_TO_BE_ADDED)
1904 part_elem->part_state= PART_IS_ADDED;
1905 else if (part_elem->part_state == PART_CHANGED)
1906 part_elem->part_state= PART_IS_CHANGED;
1907 else if (part_elem->part_state == PART_REORGED_DROPPED)
1908 part_elem->part_state= PART_TO_BE_DROPPED;
1909 }
while (++i < num_parts);
1910 for (i= 0; i < temp_partitions; i++)
1913 DBUG_ASSERT(part_elem->part_state == PART_TO_BE_REORGED);
1914 part_elem->part_state= PART_TO_BE_DROPPED;
1916 m_new_file= new_file_array;
1917 if ((error= copy_partitions(copied, deleted)))
1923 cleanup_new_partition(part_count);
1947 int ha_partition::copy_partitions(ulonglong *
const copied,
1948 ulonglong *
const deleted)
1952 longlong func_value;
1953 DBUG_ENTER(
"ha_partition::copy_partitions");
1955 if (m_part_info->linear_hash_ind)
1957 if (m_part_info->part_type == HASH_PARTITION)
1958 set_linear_hash_mask(m_part_info, m_part_info->num_parts);
1960 set_linear_hash_mask(m_part_info, m_part_info->num_subparts);
1963 while (reorg_part < m_reorged_parts)
1965 handler *file= m_reorged_file[reorg_part];
1968 late_extra_cache(reorg_part);
1975 if (result == HA_ERR_RECORD_DELETED)
1977 if (result != HA_ERR_END_OF_FILE)
1986 if (m_part_info->get_partition_id(m_part_info, &new_part,
2001 tmp_disable_binlog(thd);
2002 result= m_new_file[new_part]->ha_write_row(m_rec0);
2003 reenable_binlog(thd);
2008 late_extra_no_cache(reorg_part);
2016 DBUG_RETURN(result);
2036 void ha_partition::update_create_info(
HA_CREATE_INFO *create_info)
2038 DBUG_ENTER(
"ha_partition::update_create_info");
2046 info(HA_STATUS_VARIABLE);
2048 info(HA_STATUS_AUTO);
2050 if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
2051 create_info->auto_increment_value=
stats.auto_increment_value;
2057 my_bool from_alter = (create_info->data_file_name == (
const char*) -1);
2058 create_info->data_file_name= create_info->index_file_name = NULL;
2075 uint num_subparts= m_part_info->num_subparts;
2076 uint num_parts = num_subparts ? m_file_tot_parts / num_subparts
2079 memset(&dummy_info, 0,
sizeof(dummy_info));
2087 for (i= 0; i < num_parts; i++)
2089 part_elem= part_it++;
2092 if (m_is_sub_partitioned)
2095 for (j= 0; j < num_subparts; j++)
2097 sub_elem= subpart_it++;
2100 part= i * num_subparts + j;
2101 if (part >= m_file_tot_parts || !m_file[part])
2113 for (i= 0; i < num_parts; i++)
2115 part_elem= part_it++;
2116 DBUG_ASSERT(part_elem);
2117 if (m_is_sub_partitioned)
2120 for (j= 0; j < num_subparts; j++)
2122 sub_elem= subpart_it++;
2123 DBUG_ASSERT(sub_elem);
2124 part= i * num_subparts + j;
2125 DBUG_ASSERT(part < m_file_tot_parts && m_file[part]);
2126 if (ha_legacy_type(m_file[part]->ht) == DB_TYPE_INNODB)
2128 dummy_info.data_file_name= dummy_info.index_file_name = NULL;
2129 m_file[part]->update_create_info(&dummy_info);
2131 if (dummy_info.data_file_name || sub_elem->data_file_name)
2133 sub_elem->data_file_name = (
char*) dummy_info.data_file_name;
2135 if (dummy_info.index_file_name || sub_elem->index_file_name)
2137 sub_elem->index_file_name = (
char*) dummy_info.index_file_name;
2144 DBUG_ASSERT(m_file[i]);
2145 if (ha_legacy_type(m_file[i]->ht) == DB_TYPE_INNODB)
2147 dummy_info.data_file_name= dummy_info.index_file_name= NULL;
2148 m_file[
i]->update_create_info(&dummy_info);
2149 if (dummy_info.data_file_name || part_elem->data_file_name)
2151 part_elem->data_file_name = (
char*) dummy_info.data_file_name;
2153 if (dummy_info.index_file_name || part_elem->index_file_name)
2155 part_elem->index_file_name = (
char*) dummy_info.index_file_name;
2186 DBUG_ASSERT(*file_array);
2189 (*file_array)->change_table_ptr(table_arg, share);
2190 }
while (*(++file_array));
2193 if (m_added_file && m_added_file[0])
2196 file_array= m_added_file;
2199 (*file_array)->change_table_ptr(table_arg, share);
2200 }
while (*(++file_array));
2218 char *ha_partition::update_table_comment(
const char *comment)
2220 return (
char*) comment;
2242 int ha_partition::del_ren_table(
const char *from,
const char *to)
2245 int error= HA_ERR_INTERNAL_ERROR;
2246 char from_buff[FN_REFLEN], to_buff[FN_REFLEN], from_lc_buff[FN_REFLEN],
2247 to_lc_buff[FN_REFLEN], buff[FN_REFLEN];
2248 char *name_buffer_ptr;
2249 const char *from_path;
2250 const char *to_path= NULL;
2253 DBUG_ENTER(
"ha_partition::del_ren_table");
2255 fn_format(buff,from,
"", ha_par_ext, MY_APPEND_EXT);
2257 if (my_access(buff,F_OK))
2264 error= HA_ERR_NO_SUCH_TABLE;
2268 if (get_from_handler_file(from, ha_thd()->mem_root,
false))
2270 DBUG_ASSERT(m_file_buffer);
2271 DBUG_PRINT(
"enter", (
"from: (%s) to: (%s)", from, to ? to :
"(nil)"));
2272 name_buffer_ptr= m_name_buffer_ptr;
2287 create_partition_name(from_buff, from_path, name_buffer_ptr,
2288 NORMAL_PART_NAME, FALSE);
2292 create_partition_name(to_buff, to_path, name_buffer_ptr,
2293 NORMAL_PART_NAME, FALSE);
2294 error= (*file)->ha_rename_table(from_buff, to_buff);
2300 error= (*file)->ha_delete_table(from_buff);
2302 name_buffer_ptr= strend(name_buffer_ptr) + 1;
2306 }
while (*(++file));
2310 DBUG_EXECUTE_IF(
"crash_before_deleting_par_file", DBUG_SUICIDE(););
2316 DBUG_EXECUTE_IF(
"crash_after_deleting_par_file", DBUG_SUICIDE(););
2328 DBUG_RETURN(save_error);
2330 name_buffer_ptr= m_name_buffer_ptr;
2331 for (abort_file= file, file= m_file; file < abort_file; file++)
2334 create_partition_name(from_buff, from_path, name_buffer_ptr,
2335 NORMAL_PART_NAME, FALSE);
2336 create_partition_name(to_buff, to_path, name_buffer_ptr,
2337 NORMAL_PART_NAME, FALSE);
2339 (void) (*file)->ha_rename_table(to_buff, from_buff);
2340 name_buffer_ptr= strend(name_buffer_ptr) + 1;
2365 int ha_partition::set_up_table_before_create(
TABLE *tbl,
2366 const char *partition_name_with_path,
2371 const char *partition_name;
2373 DBUG_ENTER(
"set_up_table_before_create");
2375 DBUG_ASSERT(part_elem);
2379 tbl->s->max_rows= part_elem->part_max_rows;
2380 tbl->s->min_rows= part_elem->part_min_rows;
2381 partition_name= strrchr(partition_name_with_path, FN_LIBCHAR);
2382 if ((part_elem->index_file_name &&
2384 (
const char**)&part_elem->index_file_name,
2385 partition_name+1))) ||
2386 (part_elem->data_file_name &&
2388 (
const char**)&part_elem->data_file_name,
2389 partition_name+1))))
2393 info->index_file_name= part_elem->index_file_name;
2394 info->data_file_name= part_elem->data_file_name;
2419 static uint name_add(
char *dest,
const char *first_name,
const char *sec_name)
2421 return (uint) (strxmov(dest, first_name,
"#SP#", sec_name, NullS) -dest) + 1;
2439 bool ha_partition::create_handler_file(
const char *name)
2442 uint
i, j, part_name_len, subpart_name_len;
2443 uint tot_partition_words, tot_name_len, num_parts;
2445 uint tot_len_words, tot_len_byte, chksum, tot_name_words;
2446 char *name_buffer_ptr;
2447 uchar *file_buffer, *engine_array;
2449 char file_name[FN_REFLEN];
2450 char part_name[FN_REFLEN];
2451 char subpart_name[FN_REFLEN];
2454 DBUG_ENTER(
"create_handler_file");
2456 num_parts= m_part_info->partitions.elements;
2457 DBUG_PRINT(
"info", (
"table name = %s, num_parts = %u", name,
2460 for (i= 0; i < num_parts; i++)
2462 part_elem= part_it++;
2463 if (part_elem->part_state != PART_NORMAL &&
2464 part_elem->part_state != PART_TO_BE_ADDED &&
2465 part_elem->part_state != PART_CHANGED)
2467 tablename_to_filename(part_elem->partition_name, part_name,
2469 part_name_len= strlen(part_name);
2470 if (!m_is_sub_partitioned)
2472 tot_name_len+= part_name_len + 1;
2478 for (j= 0; j < m_part_info->num_subparts; j++)
2480 subpart_elem= sub_it++;
2481 tablename_to_filename(subpart_elem->partition_name,
2484 subpart_name_len= strlen(subpart_name);
2485 tot_name_len+= part_name_len + subpart_name_len + 5;
2504 tot_partition_words= (tot_parts + PAR_WORD_SIZE - 1) / PAR_WORD_SIZE;
2505 tot_name_words= (tot_name_len + PAR_WORD_SIZE - 1) / PAR_WORD_SIZE;
2507 tot_len_words= 4 + tot_partition_words + tot_name_words;
2508 tot_len_byte= PAR_WORD_SIZE * tot_len_words;
2509 if (!(file_buffer= (uchar *) my_malloc(tot_len_byte, MYF(MY_ZEROFILL))))
2511 engine_array= (file_buffer + PAR_ENGINES_OFFSET);
2512 name_buffer_ptr= (
char*) (engine_array + tot_partition_words * PAR_WORD_SIZE
2515 for (i= 0; i < num_parts; i++)
2517 part_elem= part_it++;
2518 if (part_elem->part_state != PART_NORMAL &&
2519 part_elem->part_state != PART_TO_BE_ADDED &&
2520 part_elem->part_state != PART_CHANGED)
2522 if (!m_is_sub_partitioned)
2524 tablename_to_filename(part_elem->partition_name, part_name, FN_REFLEN);
2525 name_buffer_ptr= strmov(name_buffer_ptr, part_name)+1;
2526 *engine_array= (uchar) ha_legacy_type(part_elem->engine_type);
2527 DBUG_PRINT(
"info", (
"engine: %u", *engine_array));
2533 for (j= 0; j < m_part_info->num_subparts; j++)
2535 subpart_elem= sub_it++;
2536 tablename_to_filename(part_elem->partition_name, part_name,
2538 tablename_to_filename(subpart_elem->partition_name, subpart_name,
2540 name_buffer_ptr+= name_add(name_buffer_ptr,
2543 *engine_array= (uchar) ha_legacy_type(subpart_elem->engine_type);
2544 DBUG_PRINT(
"info", (
"engine: %u", *engine_array));
2550 int4store(file_buffer, tot_len_words);
2551 int4store(file_buffer + PAR_NUM_PARTS_OFFSET, tot_parts);
2552 int4store(file_buffer + PAR_ENGINES_OFFSET +
2553 (tot_partition_words * PAR_WORD_SIZE),
2555 for (i= 0; i < tot_len_words; i++)
2556 chksum^= uint4korr(file_buffer + PAR_WORD_SIZE * i);
2557 int4store(file_buffer + PAR_CHECKSUM_OFFSET, chksum);
2563 fn_format(file_name, name,
"", ha_par_ext, MY_APPEND_EXT);
2565 file_name, CREATE_MODE, O_RDWR | O_TRUNC,
2569 MYF(MY_WME | MY_NABP)) != 0;
2574 my_free(file_buffer);
2575 DBUG_RETURN(result);
2583 void ha_partition::clear_handler_file()
2587 plugin_unlock_list(NULL, m_engine_array, m_tot_parts);
2588 my_free(m_engine_array);
2589 m_engine_array= NULL;
2593 my_free(m_file_buffer);
2594 m_file_buffer= NULL;
2609 bool ha_partition::create_handlers(
MEM_ROOT *mem_root)
2612 uint alloc_len= (m_tot_parts + 1) *
sizeof(
handler*);
2614 DBUG_ENTER(
"create_handlers");
2616 if (!(m_file= (
handler **) alloc_root(mem_root, alloc_len)))
2618 m_file_tot_parts= m_tot_parts;
2619 memset(m_file, 0, alloc_len);
2620 for (i= 0; i < m_tot_parts; i++)
2623 if (!(m_file[i]= get_new_handler(table_share, mem_root, hton)))
2625 DBUG_PRINT(
"info", (
"engine_type: %u", hton->db_type));
2628 hton0= plugin_data(m_engine_array[0],
handlerton*);
2629 if (hton0 == myisam_hton)
2631 DBUG_PRINT(
"info", (
"MyISAM"));
2635 else if (ha_legacy_type(hton0) == DB_TYPE_INNODB)
2637 DBUG_PRINT(
"info", (
"InnoDB"));
2656 bool ha_partition::new_handlers_from_part_info(
MEM_ROOT *mem_root)
2658 uint
i, j, part_count;
2660 uint alloc_len= (m_tot_parts + 1) *
sizeof(
handler*);
2662 DBUG_ENTER(
"ha_partition::new_handlers_from_part_info");
2664 if (!(m_file= (
handler **) alloc_root(mem_root, alloc_len)))
2666 mem_alloc_error(alloc_len);
2669 m_file_tot_parts= m_tot_parts;
2670 memset(m_file, 0, alloc_len);
2671 DBUG_ASSERT(m_part_info->num_parts > 0);
2681 part_elem= part_it++;
2682 if (m_is_sub_partitioned)
2684 for (j= 0; j < m_part_info->num_subparts; j++)
2686 if (!(m_file[part_count++]= get_new_handler(table_share, mem_root,
2687 part_elem->engine_type)))
2689 DBUG_PRINT(
"info", (
"engine_type: %u",
2690 (uint) ha_legacy_type(part_elem->engine_type)));
2695 if (!(m_file[part_count++]= get_new_handler(table_share, mem_root,
2696 part_elem->engine_type)))
2698 DBUG_PRINT(
"info", (
"engine_type: %u",
2699 (uint) ha_legacy_type(part_elem->engine_type)));
2701 }
while (++i < m_part_info->num_parts);
2702 if (part_elem->engine_type == myisam_hton)
2704 DBUG_PRINT(
"info", (
"MyISAM"));
2709 mem_alloc_error(
sizeof(
handler));
2728 bool ha_partition::read_par_file(
const char *name)
2730 char buff[FN_REFLEN], *tot_name_len_offset, *buff_p= buff;
2733 uint
i, len_bytes, len_words, tot_partition_words, tot_name_words, chksum;
2734 DBUG_ENTER(
"ha_partition::read_par_file");
2735 DBUG_PRINT(
"enter", (
"table name: '%s'", name));
2739 fn_format(buff, name,
"", ha_par_ext, MY_APPEND_EXT);
2743 buff, O_RDONLY | O_SHARE, MYF(0))) < 0)
2745 if (
mysql_file_read(file, (uchar *) &buff[0], PAR_WORD_SIZE, MYF(MY_NABP)))
2747 len_words= uint4korr(buff_p);
2748 len_bytes= PAR_WORD_SIZE * len_words;
2749 if (
mysql_file_seek(file, 0, MY_SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
2751 if (!(file_buffer= (
char*) my_malloc(len_bytes, MYF(0))))
2753 if (
mysql_file_read(file, (uchar *) file_buffer, len_bytes, MYF(MY_NABP)))
2757 for (i= 0; i < len_words; i++)
2758 chksum ^= uint4korr((file_buffer) + PAR_WORD_SIZE * i);
2761 m_tot_parts= uint4korr((file_buffer) + PAR_NUM_PARTS_OFFSET);
2762 DBUG_PRINT(
"info", (
"No of parts = %u", m_tot_parts));
2763 tot_partition_words= (m_tot_parts + PAR_WORD_SIZE - 1) / PAR_WORD_SIZE;
2765 tot_name_len_offset= file_buffer + PAR_ENGINES_OFFSET +
2766 PAR_WORD_SIZE * tot_partition_words;
2767 tot_name_words= (uint4korr(tot_name_len_offset) + PAR_WORD_SIZE - 1) /
2773 if (len_words != (tot_partition_words + tot_name_words + 4))
2776 m_file_buffer= file_buffer;
2777 m_name_buffer_ptr= tot_name_len_offset + PAR_WORD_SIZE;
2782 my_free(file_buffer);
2799 bool ha_partition::setup_engine_array(
MEM_ROOT *mem_root)
2804 enum legacy_db_type db_type, first_db_type;
2806 DBUG_ASSERT(!m_file);
2807 DBUG_ENTER(
"ha_partition::setup_engine_array");
2812 buff= (uchar *) (m_file_buffer + PAR_ENGINES_OFFSET);
2813 first_db_type= (
enum legacy_db_type) buff[0];
2814 first_engine= ha_resolve_by_legacy_type(ha_thd(), first_db_type);
2819 my_malloc(m_tot_parts *
sizeof(
plugin_ref), MYF(MY_WME))))
2822 for (i= 0; i < m_tot_parts; i++)
2824 db_type= (
enum legacy_db_type) buff[i];
2825 if (db_type != first_db_type)
2827 DBUG_PRINT(
"error", (
"partition %u engine %d is not same as "
2828 "first partition %d", i, db_type,
2829 (
int) first_db_type));
2831 clear_handler_file();
2834 m_engine_array[
i]= ha_lock_engine(NULL, first_engine);
2835 if (!m_engine_array[i])
2837 clear_handler_file();
2842 my_afree((gptr) engine_array);
2844 if (create_handlers(mem_root))
2846 clear_handler_file();
2853 my_afree((gptr) engine_array);
2873 bool ha_partition::get_from_handler_file(
const char *name,
MEM_ROOT *mem_root,
2876 DBUG_ENTER(
"ha_partition::get_from_handler_file");
2877 DBUG_PRINT(
"enter", (
"table name: '%s'", name));
2882 if (read_par_file(name))
2885 if (!is_clone && setup_engine_array(mem_root))
2905 static uchar *get_part_name(
PART_NAME_DEF *part,
size_t *length,
2906 my_bool not_used __attribute__((unused)))
2908 *length= part->length;
2909 return part->partition_name;
2925 bool ha_partition::insert_partition_name_in_hash(
const char *name, uint part_id,
2930 uint part_name_length;
2931 DBUG_ENTER(
"ha_partition::insert_partition_name_in_hash");
2936 part_name_length= strlen(name);
2943 if (!my_multi_malloc(MY_WME,
2945 &part_name, part_name_length + 1,
2948 memcpy(part_name, name, part_name_length + 1);
2949 part_def->partition_name= part_name;
2950 part_def->length= part_name_length;
2951 part_def->part_id= part_id;
2952 part_def->is_subpart= is_subpart;
2953 if (my_hash_insert(&part_share->partition_name_hash, (uchar *) part_def))
2966 bool ha_partition::populate_partition_name_hash()
2969 uint num_parts= m_part_info->num_parts;
2970 uint num_subparts= m_is_sub_partitioned ? m_part_info->num_subparts : 1;
2973 DBUG_ASSERT(part_share);
2975 DBUG_ENTER(
"ha_partition::populate_partition_name_hash");
2990 tot_names= m_is_sub_partitioned ? m_tot_parts + num_parts : num_parts;
2991 if (my_hash_init(&part_share->partition_name_hash,
2992 system_charset_info, tot_names, 0, 0,
2993 (my_hash_get_key) get_part_name,
2994 my_free, HASH_UNIQUE))
3003 DBUG_ASSERT(part_elem->part_state == PART_NORMAL);
3004 if (part_elem->part_state == PART_NORMAL)
3006 if (insert_partition_name_in_hash(part_elem->partition_name,
3007 i * num_subparts,
false))
3009 if (m_is_sub_partitioned)
3012 subpart_it(part_elem->subpartitions);
3017 sub_elem= subpart_it++;
3018 if (insert_partition_name_in_hash(sub_elem->partition_name,
3019 i * num_subparts + j,
true))
3022 }
while (++j < num_subparts);
3025 }
while (++i < num_parts);
3032 my_hash_free(&part_share->partition_name_hash);
3051 bool ha_partition::set_ha_share_ref(
Handler_share **ha_share_arg)
3055 DBUG_ENTER(
"ha_partition::set_ha_share_ref");
3057 DBUG_ASSERT(!part_share);
3058 DBUG_ASSERT(table_share);
3059 DBUG_ASSERT(!m_is_clone_of);
3060 DBUG_ASSERT(m_tot_parts);
3061 if (handler::set_ha_share_ref(ha_share_arg))
3063 if (!(part_share= get_share()))
3068 for (i= 0; i < m_tot_parts; i++)
3070 if (m_file[i]->set_ha_share_ref(&ha_shares[i]))
3091 DBUG_ENTER(
"ha_partition::get_share");
3092 DBUG_ASSERT(table_share);
3100 if (tmp_share->init(m_tot_parts))
3110 DBUG_RETURN(tmp_share);
3119 void ha_partition::free_partition_bitmaps()
3122 bitmap_free(&m_bulk_insert_started);
3123 bitmap_free(&m_locked_partitions);
3124 bitmap_free(&m_partitions_to_reset);
3125 bitmap_free(&m_key_not_found_partitions);
3133 bool ha_partition::init_partition_bitmaps()
3135 DBUG_ENTER(
"ha_partition::init_partition_bitmaps");
3137 if (bitmap_init(&m_bulk_insert_started, NULL, m_tot_parts + 1, FALSE))
3139 bitmap_clear_all(&m_bulk_insert_started);
3142 if (bitmap_init(&m_locked_partitions, NULL, m_tot_parts, FALSE))
3144 bitmap_free(&m_bulk_insert_started);
3147 bitmap_clear_all(&m_locked_partitions);
3153 if (bitmap_init(&m_partitions_to_reset, NULL, m_tot_parts, FALSE))
3155 bitmap_free(&m_bulk_insert_started);
3156 bitmap_free(&m_locked_partitions);
3159 bitmap_clear_all(&m_partitions_to_reset);
3165 if (bitmap_init(&m_key_not_found_partitions, NULL, m_tot_parts, FALSE))
3167 bitmap_free(&m_bulk_insert_started);
3168 bitmap_free(&m_locked_partitions);
3169 bitmap_free(&m_partitions_to_reset);
3172 bitmap_clear_all(&m_key_not_found_partitions);
3173 m_key_not_found=
false;
3177 DBUG_ASSERT(!m_clone_mem_root);
3178 if (m_part_info->set_partition_bitmaps(NULL))
3180 free_partition_bitmaps();
3211 int ha_partition::open(
const char *name,
int mode, uint test_if_locked)
3213 char *name_buffer_ptr;
3214 int error= HA_ERR_INITIALIZATION;
3216 char name_buff[FN_REFLEN];
3217 ulonglong check_table_flags;
3218 DBUG_ENTER(
"ha_partition::open");
3220 DBUG_ASSERT(
table->s == table_share);
3223 m_open_test_lock= test_if_locked;
3224 m_part_field_array= m_part_info->full_part_field_array;
3225 if (get_from_handler_file(name, &
table->mem_root,
test(m_is_clone_of)))
3227 name_buffer_ptr= m_name_buffer_ptr;
3228 if (populate_partition_name_hash())
3230 DBUG_RETURN(HA_ERR_INITIALIZATION);
3232 m_start_key.length= 0;
3233 m_rec0=
table->record[0];
3234 m_rec_length= table_share->reclength;
3235 if (!m_part_ids_sorted_by_num_of_records)
3237 if (!(m_part_ids_sorted_by_num_of_records=
3238 (uint32*) my_malloc(m_tot_parts *
sizeof(uint32), MYF(MY_WME))))
3242 for (i= 0; i < m_tot_parts; i++)
3243 m_part_ids_sorted_by_num_of_records[i]= i;
3246 if (init_partition_bitmaps())
3249 DBUG_ASSERT(m_part_info);
3254 DBUG_ASSERT(m_clone_mem_root);
3256 alloc_len= (m_tot_parts + 1) *
sizeof(
handler*);
3257 if (!(m_file= (
handler **) alloc_root(m_clone_mem_root, alloc_len)))
3259 error= HA_ERR_INITIALIZATION;
3262 memset(m_file, 0, alloc_len);
3267 file= m_is_clone_of->m_file;
3268 for (i= 0; i < m_tot_parts; i++)
3270 create_partition_name(name_buff, name, name_buffer_ptr, NORMAL_PART_NAME,
3273 if (!(m_file[i]= file[i]->clone(name_buff, m_clone_mem_root)))
3275 error= HA_ERR_INITIALIZATION;
3279 name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
3287 create_partition_name(name_buff, name, name_buffer_ptr, NORMAL_PART_NAME,
3289 if ((error= (*file)->ha_open(
table, name_buff, mode,
3290 test_if_locked | HA_OPEN_NO_PSI_CALL)))
3293 m_num_locks= (*file)->lock_count();
3294 DBUG_ASSERT(m_num_locks == (*file)->lock_count());
3295 name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
3296 }
while (*(++file));
3301 check_table_flags= (((*file)->ha_table_flags() &
3302 ~(PARTITION_DISABLED_TABLE_FLAGS)) |
3303 (PARTITION_ENABLED_TABLE_FLAGS));
3307 set_if_bigger(
ref_length, ((*file)->ref_length));
3312 if (check_table_flags != (((*file)->ha_table_flags() &
3313 ~(PARTITION_DISABLED_TABLE_FLAGS)) |
3314 (PARTITION_ENABLED_TABLE_FLAGS)))
3316 error= HA_ERR_INITIALIZATION;
3318 file = &m_file[m_tot_parts - 1];
3322 key_used_on_scan= m_file[0]->key_used_on_scan;
3323 implicit_emptied= m_file[0]->implicit_emptied;
3335 clear_handler_file();
3343 m_handler_status= handler_opened;
3344 if (m_part_info->part_expr)
3345 m_part_func_monotonicity_info=
3346 m_part_info->part_expr->get_monotonicity_info();
3347 else if (m_part_info->list_of_part_fields)
3348 m_part_func_monotonicity_info= MONOTONIC_STRICT_INCREASING;
3349 info(HA_STATUS_VARIABLE | HA_STATUS_CONST);
3353 DEBUG_SYNC(ha_thd(),
"partition_open_error");
3354 while (file-- != m_file)
3355 (*file)->ha_close();
3357 free_partition_bitmaps();
3369 #ifdef HAVE_M_PSI_PER_PARTITION
3370 void ha_partition::unbind_psi()
3374 DBUG_ENTER(
"ha_partition::unbind_psi");
3375 handler::unbind_psi();
3376 for (i= 0; i < m_tot_parts; i++)
3378 DBUG_ASSERT(m_file[i] != NULL);
3379 m_file[
i]->unbind_psi();
3384 void ha_partition::rebind_psi()
3388 DBUG_ENTER(
"ha_partition::rebind_psi");
3389 handler::rebind_psi();
3390 for (i= 0; i < m_tot_parts; i++)
3392 DBUG_ASSERT(m_file[i] != NULL);
3393 m_file[
i]->rebind_psi();
3420 DBUG_ENTER(
"ha_partition::clone");
3421 new_handler=
new (mem_root)
ha_partition(ht, table_share, m_part_info,
3438 if (!(new_handler->ref= (uchar*) alloc_root(mem_root,
3439 ALIGN_SIZE(m_ref_length)*2)))
3444 HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_NO_PSI_CALL))
3447 DBUG_RETURN((
handler*) new_handler);
3473 int ha_partition::close(
void)
3477 DBUG_ENTER(
"ha_partition::close");
3479 DBUG_ASSERT(
table->s == table_share);
3480 destroy_record_priority_queue();
3481 free_partition_bitmaps();
3482 DBUG_ASSERT(m_part_info);
3489 }
while (*(++file));
3491 if (first && m_added_file && m_added_file[0])
3498 m_handler_status= handler_closed;
3542 int ha_partition::external_lock(THD *thd,
int lock_type)
3545 uint
i, first_used_partition;
3547 DBUG_ENTER(
"ha_partition::external_lock");
3549 DBUG_ASSERT(!auto_increment_lock && !auto_increment_safe_stmt_log_lock);
3551 if (lock_type == F_UNLCK)
3552 used_partitions= &m_locked_partitions;
3554 used_partitions= &(m_part_info->lock_partitions);
3556 first_used_partition= bitmap_get_first_set(used_partitions);
3558 for (i= first_used_partition;
3560 i= bitmap_get_next_set(used_partitions, i))
3562 DBUG_PRINT(
"info", (
"external_lock(thd, %d) part %d", lock_type, i));
3565 if (lock_type != F_UNLCK)
3568 DBUG_PRINT(
"info", (
"external_lock part %u lock %d", i, lock_type));
3569 if (lock_type != F_UNLCK)
3570 bitmap_set_bit(&m_locked_partitions, i);
3572 if (lock_type == F_UNLCK)
3574 bitmap_clear_all(used_partitions);
3579 bitmap_union(&m_partitions_to_reset, used_partitions);
3582 if (m_added_file && m_added_file[0])
3585 DBUG_ASSERT(lock_type == F_UNLCK);
3588 (void) (*file)->ha_external_lock(thd, lock_type);
3589 }
while (*(++file));
3595 for (j= first_used_partition;
3597 j= bitmap_get_next_set(&m_locked_partitions, j))
3601 bitmap_clear_all(&m_locked_partitions);
3654 enum thr_lock_type lock_type)
3657 DBUG_ENTER(
"ha_partition::store_lock");
3658 DBUG_ASSERT(thd == current_thd);
3665 if (thd !=
table->in_use)
3667 for (i= 0; i < m_tot_parts; i++)
3668 to= m_file[i]->
store_lock(thd, to, lock_type);
3672 for (i= bitmap_get_first_set(&(m_part_info->lock_partitions));
3674 i= bitmap_get_next_set(&m_part_info->lock_partitions, i))
3676 DBUG_PRINT(
"info", (
"store lock %d iteration", i));
3700 int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type)
3705 DBUG_ASSERT(bitmap_is_subset(&m_part_info->read_partitions,
3706 &m_part_info->lock_partitions));
3712 DBUG_ASSERT(bitmap_is_subset(&m_part_info->lock_partitions,
3713 &m_locked_partitions));
3714 DBUG_ENTER(
"ha_partition::start_stmt");
3716 for (i= bitmap_get_first_set(&(m_part_info->lock_partitions));
3718 i= bitmap_get_next_set(&m_part_info->lock_partitions, i))
3720 if ((error= m_file[i]->start_stmt(thd, lock_type)))
3723 bitmap_set_bit(&m_partitions_to_reset, i);
3743 DBUG_ENTER(
"ha_partition::lock_count");
3753 DBUG_RETURN(m_tot_parts * m_num_locks);
3771 void ha_partition::unlock_row()
3773 DBUG_ENTER(
"ha_partition::unlock_row");
3774 m_file[m_last_part]->unlock_row();
3803 DBUG_ENTER(
"ha_partition::was_semi_consistent_read");
3804 DBUG_ASSERT(m_last_part < m_tot_parts &&
3805 bitmap_is_set(&(m_part_info->read_partitions), m_last_part));
3831 DBUG_ENTER(
"ha_partition::try_semi_consistent_read");
3833 i= bitmap_get_first_set(&(m_part_info->read_partitions));
3834 DBUG_ASSERT(i != MY_BIT_NONE);
3837 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
3882 int ha_partition::write_row(uchar *
buf)
3886 longlong func_value;
3887 bool have_auto_increment=
table->next_number_field && buf ==
table->record[0];
3888 my_bitmap_map *old_map;
3890 sql_mode_t saved_sql_mode= thd->variables.sql_mode;
3891 bool saved_auto_inc_field_not_null=
table->auto_increment_field_not_null;
3892 DBUG_ENTER(
"ha_partition::write_row");
3893 DBUG_ASSERT(buf == m_rec0);
3899 if (have_auto_increment)
3901 if (!part_share->auto_inc_initialized &&
3902 !table_share->next_number_keypart)
3908 info(HA_STATUS_AUTO);
3910 error= update_auto_increment();
3930 if (
table->next_number_field->val_int() == 0)
3932 table->auto_increment_field_not_null= TRUE;
3933 thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
3937 old_map= dbug_tmp_use_all_columns(
table,
table->read_set);
3938 error= m_part_info->get_partition_id(m_part_info, &part_id, &func_value);
3939 dbug_tmp_restore_column_map(
table->read_set, old_map);
3940 if (unlikely(error))
3942 m_part_info->err_value= func_value;
3945 if (!bitmap_is_set(&(m_part_info->lock_partitions), part_id))
3947 DBUG_PRINT(
"info", (
"Write to non-locked partition %u (func_value: %ld)",
3948 part_id, (
long) func_value));
3949 error= HA_ERR_NOT_IN_LOCK_PARTITIONS;
3952 m_last_part= part_id;
3953 DBUG_PRINT(
"info", (
"Insert in partition %d", part_id));
3954 start_part_bulk_insert(thd, part_id);
3956 tmp_disable_binlog(thd);
3957 error= m_file[part_id]->ha_write_row(buf);
3958 if (have_auto_increment && !
table->s->next_number_keypart)
3959 set_auto_increment_if_higher(
table->next_number_field);
3960 reenable_binlog(thd);
3962 thd->variables.sql_mode= saved_sql_mode;
3963 table->auto_increment_field_not_null= saved_auto_inc_field_not_null;
3992 int ha_partition::update_row(
const uchar *old_data, uchar *new_data)
3995 uint32 new_part_id, old_part_id;
3997 longlong func_value;
3998 DBUG_ENTER(
"ha_partition::update_row");
4002 DBUG_ASSERT(bitmap_is_subset(&m_part_info->full_part_field_set,
4004 if ((error= get_parts_for_update(old_data, new_data,
table->record[0],
4005 m_part_info, &old_part_id, &new_part_id,
4008 m_part_info->err_value= func_value;
4011 DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), old_part_id));
4012 if (!bitmap_is_set(&(m_part_info->lock_partitions), new_part_id))
4014 error= HA_ERR_NOT_IN_LOCK_PARTITIONS;
4035 if (old_part_id != m_last_part)
4037 m_err_rec= old_data;
4038 DBUG_RETURN(HA_ERR_ROW_IN_WRONG_PARTITION);
4041 m_last_part= new_part_id;
4042 start_part_bulk_insert(thd, new_part_id);
4043 if (new_part_id == old_part_id)
4045 DBUG_PRINT(
"info", (
"Update in partition %d", new_part_id));
4046 tmp_disable_binlog(thd);
4047 error= m_file[new_part_id]->ha_update_row(old_data, new_data);
4048 reenable_binlog(thd);
4053 Field *saved_next_number_field=
table->next_number_field;
4064 table->next_number_field= NULL;
4065 DBUG_PRINT(
"info", (
"Update from partition %d to partition %d",
4066 old_part_id, new_part_id));
4067 tmp_disable_binlog(thd);
4068 error= m_file[new_part_id]->ha_write_row(new_data);
4069 reenable_binlog(thd);
4070 table->next_number_field= saved_next_number_field;
4074 tmp_disable_binlog(thd);
4075 error= m_file[old_part_id]->ha_delete_row(old_data);
4076 reenable_binlog(thd);
4079 #ifdef IN_THE_FUTURE
4080 (void) m_file[new_part_id]->delete_last_inserted_row(new_data);
4096 if (
table->found_next_number_field &&
4097 new_data ==
table->record[0] &&
4098 !
table->s->next_number_keypart &&
4099 bitmap_is_set(
table->write_set,
4100 table->found_next_number_field->field_index))
4102 if (!part_share->auto_inc_initialized)
4103 info(HA_STATUS_AUTO);
4104 set_auto_increment_if_higher(
table->found_next_number_field);
4138 int ha_partition::delete_row(
const uchar *buf)
4143 DBUG_ENTER(
"ha_partition::delete_row");
4146 DBUG_ASSERT(bitmap_is_subset(&m_part_info->full_part_field_set,
4148 if ((error= get_part_for_delete(buf, m_rec0, m_part_info, &part_id)))
4153 DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), part_id));
4154 DBUG_ASSERT(bitmap_is_set(&(m_part_info->lock_partitions), part_id));
4155 if (!bitmap_is_set(&(m_part_info->lock_partitions), part_id))
4156 DBUG_RETURN(HA_ERR_NOT_IN_LOCK_PARTITIONS);
4178 if (part_id != m_last_part)
4181 DBUG_RETURN(HA_ERR_ROW_IN_WRONG_PARTITION);
4184 m_last_part= part_id;
4185 tmp_disable_binlog(thd);
4186 error= m_file[part_id]->ha_delete_row(buf);
4187 reenable_binlog(thd);
4218 DBUG_ENTER(
"ha_partition::delete_all_rows");
4220 for (i= bitmap_get_first_set(&m_part_info->read_partitions);
4222 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
4243 DBUG_ENTER(
"ha_partition::truncate");
4249 lock_auto_increment();
4251 part_share->auto_inc_initialized=
false;
4252 unlock_auto_increment();
4257 if ((error= (*file)->ha_truncate()))
4259 }
while (*(++file));
4272 int ha_partition::truncate_partition(
Alter_info *alter_info,
bool *binlog_stmt)
4276 uint num_parts= m_part_info->num_parts;
4277 uint num_subparts= m_part_info->num_subparts;
4279 DBUG_ENTER(
"ha_partition::truncate_partition");
4282 *binlog_stmt=
false;
4284 if (set_part_state(alter_info, m_part_info, PART_ADMIN))
4285 DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
4291 lock_auto_increment();
4293 part_share->auto_inc_initialized= FALSE;
4294 unlock_auto_increment();
4301 if (part_elem->part_state == PART_ADMIN)
4303 if (m_is_sub_partitioned)
4306 subpart_it(part_elem->subpartitions);
4311 sub_elem= subpart_it++;
4312 part= i * num_subparts + j;
4313 DBUG_PRINT(
"info", (
"truncate subpartition %u (%s)",
4314 part, sub_elem->partition_name));
4317 sub_elem->part_state= PART_NORMAL;
4318 }
while (++j < num_subparts);
4322 DBUG_PRINT(
"info", (
"truncate partition %u (%s)", i,
4323 part_elem->partition_name));
4326 part_elem->part_state= PART_NORMAL;
4328 }
while (!error && (++i < num_parts));
4346 void ha_partition::start_bulk_insert(ha_rows rows)
4348 DBUG_ENTER(
"ha_partition::start_bulk_insert");
4350 m_bulk_inserted_rows= 0;
4351 bitmap_clear_all(&m_bulk_insert_started);
4353 bitmap_set_bit(&m_bulk_insert_started, m_tot_parts);
4362 void ha_partition::start_part_bulk_insert(THD *thd, uint part_id)
4364 long old_buffer_size;
4365 if (!bitmap_is_set(&m_bulk_insert_started, part_id) &&
4366 bitmap_is_set(&m_bulk_insert_started, m_tot_parts))
4368 DBUG_ASSERT(bitmap_is_set(&(m_part_info->lock_partitions), part_id));
4369 old_buffer_size= thd->variables.read_buff_size;
4371 thd->variables.read_buff_size= estimate_read_buffer_size(old_buffer_size);
4373 bitmap_set_bit(&m_bulk_insert_started, part_id);
4374 thd->variables.read_buff_size= old_buffer_size;
4376 m_bulk_inserted_rows++;
4395 long ha_partition::estimate_read_buffer_size(
long original_size)
4401 if (estimation_rows_to_insert && (estimation_rows_to_insert < 10))
4402 return (original_size);
4407 if (!m_bulk_inserted_rows &&
4408 m_part_func_monotonicity_info != NON_MONOTONIC &&
4410 return original_size;
4416 if (m_tot_parts < 10)
4417 return original_size;
4418 return (original_size * 10 / m_tot_parts);
4430 ha_rows ha_partition::guess_bulk_insert_rows()
4432 DBUG_ENTER(
"guess_bulk_insert_rows");
4434 if (estimation_rows_to_insert < 10)
4435 DBUG_RETURN(estimation_rows_to_insert);
4438 if (!m_bulk_inserted_rows &&
4439 m_part_func_monotonicity_info != NON_MONOTONIC &&
4441 DBUG_RETURN(estimation_rows_to_insert / 2);
4444 if (m_bulk_inserted_rows < estimation_rows_to_insert)
4445 DBUG_RETURN(((estimation_rows_to_insert - m_bulk_inserted_rows)
4446 / m_tot_parts) + 1);
4460 int ha_partition::end_bulk_insert()
4464 DBUG_ENTER(
"ha_partition::end_bulk_insert");
4466 if (!bitmap_is_set(&m_bulk_insert_started, m_tot_parts))
4472 for (i= bitmap_get_first_set(&m_bulk_insert_started);
4474 i= bitmap_get_next_set(&m_bulk_insert_started, i))
4480 bitmap_clear_all(&m_bulk_insert_started);
4519 DBUG_ENTER(
"ha_partition::rnd_init");
4525 if (get_lock_type() == F_WRLCK)
4534 if (bitmap_is_overlapping(&m_part_info->full_part_field_set,
4536 bitmap_set_all(
table->read_set);
4545 bitmap_union(
table->read_set, &m_part_info->full_part_field_set);
4550 DBUG_PRINT(
"info", (
"m_part_info->read_partitions: 0x%lx",
4551 (
long) m_part_info->read_partitions.bitmap));
4552 part_id= bitmap_get_first_set(&(m_part_info->read_partitions));
4553 DBUG_PRINT(
"info", (
"m_part_spec.start_part %d", part_id));
4555 if (MY_BIT_NONE == part_id)
4565 DBUG_PRINT(
"info", (
"rnd_init on partition %d", part_id));
4573 late_extra_cache(part_id);
4581 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
4588 m_part_spec.start_part= part_id;
4589 m_part_spec.end_part= m_tot_parts - 1;
4590 DBUG_PRINT(
"info", (
"m_scan_value=%d", m_scan_value));
4597 part_id= bitmap_get_next_set(&m_part_info->read_partitions, part_id))
4603 m_part_spec.start_part= NO_CURRENT_PART_ID;
4619 int ha_partition::rnd_end()
4621 DBUG_ENTER(
"ha_partition::rnd_end");
4622 switch (m_scan_value) {
4626 if (NO_CURRENT_PART_ID != m_part_spec.start_part)
4628 late_extra_no_cache(m_part_spec.start_part);
4629 m_file[m_part_spec.start_part]->
ha_rnd_end();
4634 for (i= bitmap_get_first_set(&m_part_info->read_partitions);
4636 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
4643 m_part_spec.start_part= NO_CURRENT_PART_ID;
4671 int result= HA_ERR_END_OF_FILE;
4672 uint part_id= m_part_spec.start_part;
4673 DBUG_ENTER(
"ha_partition::rnd_next");
4675 if (NO_CURRENT_PART_ID == part_id)
4684 DBUG_ASSERT(m_scan_value == 1);
4685 file= m_file[part_id];
4692 m_last_part= part_id;
4693 m_part_spec.start_part= part_id;
4701 if (result == HA_ERR_RECORD_DELETED)
4704 if (result != HA_ERR_END_OF_FILE)
4705 goto end_dont_reset_start_part;
4708 late_extra_no_cache(part_id);
4709 DBUG_PRINT(
"info", (
"rnd_end on partition %d", part_id));
4714 part_id= bitmap_get_next_set(&m_part_info->read_partitions, part_id);
4715 if (part_id >= m_tot_parts)
4717 result= HA_ERR_END_OF_FILE;
4720 m_last_part= part_id;
4721 m_part_spec.start_part= part_id;
4722 file= m_file[part_id];
4723 DBUG_PRINT(
"info", (
"rnd_init on partition %d", part_id));
4726 late_extra_cache(part_id);
4730 m_part_spec.start_part= NO_CURRENT_PART_ID;
4731 end_dont_reset_start_part:
4732 table->status= STATUS_NOT_FOUND;
4733 DBUG_RETURN(result);
4762 void ha_partition::position(
const uchar *
record)
4764 handler *file= m_file[m_last_part];
4766 DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), m_last_part));
4767 DBUG_ENTER(
"ha_partition::position");
4769 file->position(record);
4770 int2store(ref, m_last_part);
4771 memcpy((ref + PARTITION_BYTES_IN_POS), file->ref, file->
ref_length);
4772 pad_length= m_ref_length - PARTITION_BYTES_IN_POS - file->
ref_length;
4774 memset((ref + PARTITION_BYTES_IN_POS + file->
ref_length), 0, pad_length);
4805 DBUG_ENTER(
"ha_partition::rnd_pos");
4807 part_id= uint2korr((
const uchar *) pos);
4808 DBUG_ASSERT(part_id < m_tot_parts);
4809 file= m_file[part_id];
4810 DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), part_id));
4811 m_last_part= part_id;
4812 DBUG_RETURN(file->
ha_rnd_pos(buf, (pos + PARTITION_BYTES_IN_POS)));
4837 DBUG_ENTER(
"ha_partition::rnd_pos_by_record");
4839 if (unlikely(get_part_for_delete(record, m_rec0, m_part_info, &m_last_part)))
4870 bool ha_partition::init_record_priority_queue()
4872 DBUG_ENTER(
"ha_partition::init_record_priority_queue");
4873 DBUG_ASSERT(!m_ordered_rec_buffer);
4877 if (!m_ordered_rec_buffer)
4880 uint used_parts= bitmap_bits_set(&m_part_info->read_partitions);
4882 alloc_len= used_parts * (m_rec_length + PARTITION_BYTES_IN_POS);
4884 alloc_len+= table_share->max_key_length;
4886 if (!(m_ordered_rec_buffer= (uchar*)my_malloc(alloc_len, MYF(MY_WME))))
4896 char *ptr= (
char*) m_ordered_rec_buffer;
4898 for (i= bitmap_get_first_set(&m_part_info->read_partitions);
4900 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
4902 DBUG_PRINT(
"info", (
"init rec-buf for part %u", i));
4904 ptr+= m_rec_length + PARTITION_BYTES_IN_POS;
4906 m_start_key.key= (
const uchar*)ptr;
4908 if (init_queue(&m_queue, used_parts, (uint) PARTITION_BYTES_IN_POS,
4909 0, key_rec_cmp, (
void*)m_curr_key_info))
4911 my_free(m_ordered_rec_buffer);
4912 m_ordered_rec_buffer= NULL;
4924 void ha_partition::destroy_record_priority_queue()
4926 DBUG_ENTER(
"ha_partition::destroy_record_priority_queue");
4927 if (m_ordered_rec_buffer)
4929 delete_queue(&m_queue);
4930 my_free(m_ordered_rec_buffer);
4931 m_ordered_rec_buffer= NULL;
4954 int ha_partition::index_init(uint inx,
bool sorted)
4958 DBUG_ENTER(
"ha_partition::index_init");
4960 DBUG_PRINT(
"info", (
"inx %u sorted %u", inx, sorted));
4962 m_part_spec.start_part= NO_CURRENT_PART_ID;
4963 m_start_key.length= 0;
4965 m_curr_key_info[0]=
table->key_info+inx;
4966 if (m_pkey_is_clustered &&
table->s->primary_key != MAX_KEY)
4972 DBUG_PRINT(
"info", (
"Clustered pk, using pk as secondary cmp"));
4973 m_curr_key_info[1]=
table->key_info+
table->s->primary_key;
4974 m_curr_key_info[2]= NULL;
4977 m_curr_key_info[1]= NULL;
4979 if (init_record_priority_queue())
4980 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
4989 if (get_lock_type() == F_WRLCK)
4990 bitmap_union(
table->read_set, &m_part_info->full_part_field_set);
4991 for (i= bitmap_get_first_set(&m_part_info->read_partitions);
4993 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
4998 DBUG_EXECUTE_IF(
"ha_partition_fail_index_init", {
5000 error= HA_ERR_NO_PARTITION_FOUND;
5009 for (j= bitmap_get_first_set(&m_part_info->read_partitions);
5011 j= bitmap_get_next_set(&m_part_info->read_partitions, j))
5035 int ha_partition::index_end()
5039 DBUG_ENTER(
"ha_partition::index_end");
5041 active_index= MAX_KEY;
5042 m_part_spec.start_part= NO_CURRENT_PART_ID;
5043 for (i= bitmap_get_first_set(&m_part_info->read_partitions);
5045 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
5051 destroy_record_priority_queue();
5082 key_part_map keypart_map,
5083 enum ha_rkey_function find_flag)
5085 DBUG_ENTER(
"ha_partition::index_read_map");
5087 m_index_scan_type= partition_index_read;
5088 m_start_key.key= key;
5089 m_start_key.keypart_map= keypart_map;
5090 m_start_key.flag= find_flag;
5091 DBUG_RETURN(common_index_read(buf, TRUE));
5124 int ha_partition::common_index_read(uchar *buf,
bool have_start_key)
5127 uint UNINIT_VAR(key_len);
5128 bool reverse_order= FALSE;
5129 DBUG_ENTER(
"ha_partition::common_index_read");
5131 DBUG_PRINT(
"info", (
"m_ordered %u m_ordered_scan_ong %u",
5132 m_ordered, m_ordered_scan_ongoing));
5136 m_start_key.length= key_len= calculate_key_len(
table, active_index,
5138 m_start_key.keypart_map);
5139 DBUG_PRINT(
"info", (
"have_start_key map %lu find_flag %u len %u",
5140 m_start_key.keypart_map, m_start_key.flag, key_len));
5141 DBUG_ASSERT(key_len);
5143 if ((error= partition_scan_set_up(buf, have_start_key)))
5148 if (have_start_key &&
5149 (m_start_key.flag == HA_READ_PREFIX_LAST ||
5150 m_start_key.flag == HA_READ_PREFIX_LAST_OR_PREV ||
5151 m_start_key.flag == HA_READ_BEFORE_KEY))
5153 reverse_order= TRUE;
5154 m_ordered_scan_ongoing= TRUE;
5156 DBUG_PRINT(
"info", (
"m_ordered %u m_o_scan_ong %u have_start_key %u",
5157 m_ordered, m_ordered_scan_ongoing, have_start_key));
5158 if (!m_ordered_scan_ongoing)
5167 DBUG_PRINT(
"info", (
"doing unordered scan"));
5168 error= handle_unordered_scan_next_partition(buf);
5176 error= handle_ordered_index_scan(buf, reverse_order);
5205 DBUG_ENTER(
"ha_partition::index_first");
5208 m_index_scan_type= partition_index_first;
5209 DBUG_RETURN(common_first_last(buf));
5236 DBUG_ENTER(
"ha_partition::index_last");
5238 m_index_scan_type= partition_index_last;
5239 DBUG_RETURN(common_first_last(buf));
5251 int ha_partition::common_first_last(uchar *buf)
5255 if ((error= partition_scan_set_up(buf, FALSE)))
5257 if (!m_ordered_scan_ongoing &&
5258 m_index_scan_type != partition_index_last)
5259 return handle_unordered_scan_next_partition(buf);
5260 return handle_ordered_index_scan(buf, FALSE);
5283 key_part_map keypart_map)
5285 DBUG_ENTER(
"ha_partition::index_read_last_map");
5289 m_index_scan_type= partition_index_read_last;
5290 m_start_key.key= key;
5291 m_start_key.keypart_map= keypart_map;
5292 m_start_key.flag= HA_READ_PREFIX_LAST;
5293 DBUG_RETURN(common_index_read(buf, TRUE));
5303 key_part_map keypart_map,
5304 enum ha_rkey_function find_flag)
5306 int error= HA_ERR_KEY_NOT_FOUND;
5307 DBUG_ENTER(
"ha_partition::index_read_idx_map");
5309 if (find_flag == HA_READ_KEY_EXACT)
5312 m_start_key.key= key;
5313 m_start_key.keypart_map= keypart_map;
5314 m_start_key.flag= find_flag;
5315 m_start_key.length= calculate_key_len(
table, index, m_start_key.key,
5316 m_start_key.keypart_map);
5318 get_partition_set(
table, buf, index, &m_start_key, &m_part_spec);
5325 DBUG_ASSERT(m_part_spec.start_part >= m_part_spec.end_part);
5327 DBUG_ASSERT(m_part_spec.start_part > m_part_spec.end_part ||
5328 bitmap_is_set(&(m_part_info->read_partitions),
5329 m_part_spec.start_part));
5331 for (part= m_part_spec.start_part;
5332 part <= m_part_spec.end_part;
5333 part= bitmap_get_next_set(&m_part_info->read_partitions, part))
5336 keypart_map, find_flag);
5337 if (error != HA_ERR_KEY_NOT_FOUND &&
5338 error != HA_ERR_END_OF_FILE)
5341 if (part <= m_part_spec.end_part)
5375 DBUG_ENTER(
"ha_partition::index_next");
5384 DBUG_ASSERT(m_index_scan_type != partition_index_last);
5385 if (!m_ordered_scan_ongoing)
5387 DBUG_RETURN(handle_unordered_next(buf, FALSE));
5389 DBUG_RETURN(handle_ordered_next(buf, FALSE));
5413 DBUG_ENTER(
"ha_partition::index_next_same");
5415 DBUG_ASSERT(keylen == m_start_key.length);
5416 DBUG_ASSERT(m_index_scan_type != partition_index_last);
5417 if (!m_ordered_scan_ongoing)
5418 DBUG_RETURN(handle_unordered_next(buf, TRUE));
5419 DBUG_RETURN(handle_ordered_next(buf, TRUE));
5440 DBUG_ENTER(
"ha_partition::index_prev");
5443 DBUG_ASSERT(m_index_scan_type != partition_index_first);
5444 DBUG_RETURN(handle_ordered_prev(buf));
5471 bool eq_range_arg,
bool sorted)
5474 DBUG_ENTER(
"ha_partition::read_range_first");
5477 eq_range= eq_range_arg;
5480 range_key_part= m_curr_key_info[0]->key_part;
5482 m_start_key= *start_key;
5484 m_start_key.key= NULL;
5486 m_index_scan_type= partition_read_range;
5487 error= common_index_read(m_rec0,
test(start_key));
5505 DBUG_ENTER(
"ha_partition::read_range_next");
5507 if (m_ordered_scan_ongoing)
5509 DBUG_RETURN(handle_ordered_next(
table->record[0], eq_range));
5511 DBUG_RETURN(handle_unordered_next(
table->record[0], eq_range));
5541 int ha_partition::partition_scan_set_up(uchar * buf,
bool idx_read_flag)
5543 DBUG_ENTER(
"ha_partition::partition_scan_set_up");
5546 get_partition_set(
table,buf,active_index,&m_start_key,&m_part_spec);
5549 m_part_spec.start_part= 0;
5550 m_part_spec.end_part= m_tot_parts - 1;
5552 if (m_part_spec.start_part > m_part_spec.end_part)
5558 DBUG_PRINT(
"info", (
"scan with no partition to scan"));
5559 table->status= STATUS_NOT_FOUND;
5560 DBUG_RETURN(HA_ERR_END_OF_FILE);
5562 if (m_part_spec.start_part == m_part_spec.end_part)
5568 DBUG_PRINT(
"info", (
"index scan using the single partition %d",
5569 m_part_spec.start_part));
5570 m_ordered_scan_ongoing= FALSE;
5580 uint start_part= bitmap_get_first_set(&(m_part_info->read_partitions));
5581 if (start_part == MY_BIT_NONE)
5583 DBUG_PRINT(
"info", (
"scan with no partition to scan"));
5584 table->status= STATUS_NOT_FOUND;
5585 DBUG_RETURN(HA_ERR_END_OF_FILE);
5587 if (start_part > m_part_spec.start_part)
5588 m_part_spec.start_part= start_part;
5589 DBUG_ASSERT(m_part_spec.start_part < m_tot_parts);
5590 m_ordered_scan_ongoing= m_ordered;
5592 DBUG_ASSERT(m_part_spec.start_part < m_tot_parts &&
5593 m_part_spec.end_part < m_tot_parts);
5624 int ha_partition::handle_unordered_next(uchar *buf,
bool is_next_same)
5628 DBUG_ENTER(
"ha_partition::handle_unordered_next");
5630 if (m_part_spec.start_part >= m_tot_parts)
5634 DBUG_RETURN(HA_ERR_END_OF_FILE);
5636 file= m_file[m_part_spec.start_part];
5643 if (m_index_scan_type == partition_read_range)
5647 m_last_part= m_part_spec.start_part;
5651 else if (is_next_same)
5654 m_start_key.length)))
5656 m_last_part= m_part_spec.start_part;
5664 m_last_part= m_part_spec.start_part;
5669 if (error == HA_ERR_END_OF_FILE)
5671 m_part_spec.start_part++;
5672 error= handle_unordered_scan_next_partition(buf);
5695 int ha_partition::handle_unordered_scan_next_partition(uchar * buf)
5697 uint i= m_part_spec.start_part;
5698 int saved_error= HA_ERR_END_OF_FILE;
5699 DBUG_ENTER(
"ha_partition::handle_unordered_scan_next_partition");
5702 i= bitmap_get_next_set(&m_part_info->read_partitions, i - 1);
5704 i= bitmap_get_first_set(&m_part_info->read_partitions);
5707 i <= m_part_spec.end_part;
5708 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
5712 m_part_spec.start_part=
i;
5713 switch (m_index_scan_type) {
5714 case partition_read_range:
5715 DBUG_PRINT(
"info", (
"read_range_first on partition %d", i));
5717 end_range, eq_range, FALSE);
5719 case partition_index_read:
5720 DBUG_PRINT(
"info", (
"index_read on partition %d", i));
5722 m_start_key.keypart_map,
5725 case partition_index_first:
5726 DBUG_PRINT(
"info", (
"index_first on partition %d", i));
5729 case partition_index_first_unordered:
5736 DBUG_PRINT(
"info", (
"read_range_first on partition %d", i));
5739 table->record[0]= m_rec0;
5750 if ((error != HA_ERR_END_OF_FILE) && (error != HA_ERR_KEY_NOT_FOUND))
5757 if (saved_error != HA_ERR_KEY_NOT_FOUND)
5759 DBUG_PRINT(
"info", (
"END_OF_FILE/KEY_NOT_FOUND on partition %d", i));
5761 if (saved_error == HA_ERR_END_OF_FILE)
5762 m_part_spec.start_part= NO_CURRENT_PART_ID;
5763 DBUG_RETURN(saved_error);
5794 int ha_partition::handle_ordered_index_scan(uchar *buf,
bool reverse_order)
5799 uchar *part_rec_buf_ptr= m_ordered_rec_buffer;
5800 int saved_error= HA_ERR_END_OF_FILE;
5801 DBUG_ENTER(
"ha_partition::handle_ordered_index_scan");
5803 if (m_key_not_found)
5805 m_key_not_found=
false;
5806 bitmap_clear_all(&m_key_not_found_partitions);
5808 m_top_entry= NO_CURRENT_PART_ID;
5809 queue_remove_all(&m_queue);
5810 DBUG_ASSERT(bitmap_is_set(&m_part_info->read_partitions,
5811 m_part_spec.start_part));
5819 for (i= bitmap_get_first_set(&m_part_info->read_partitions);
5820 i < m_part_spec.start_part;
5821 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
5823 part_rec_buf_ptr+= m_rec_length + PARTITION_BYTES_IN_POS;
5825 DBUG_PRINT(
"info", (
"m_part_spec.start_part %u first_used_part %u",
5826 m_part_spec.start_part, i));
5828 i <= m_part_spec.end_part;
5829 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
5831 DBUG_PRINT(
"info", (
"reading from part %u (scan_type: %u)",
5832 i, m_index_scan_type));
5833 DBUG_ASSERT(i == uint2korr(part_rec_buf_ptr));
5834 uchar *rec_buf_ptr= part_rec_buf_ptr + PARTITION_BYTES_IN_POS;
5838 switch (m_index_scan_type) {
5839 case partition_index_read:
5842 m_start_key.keypart_map,
5845 case partition_index_first:
5847 reverse_order= FALSE;
5849 case partition_index_last:
5851 reverse_order= TRUE;
5853 case partition_index_read_last:
5854 error= file->ha_index_read_last_map(rec_buf_ptr,
5856 m_start_key.keypart_map);
5857 reverse_order= TRUE;
5859 case partition_read_range:
5866 end_range, eq_range, TRUE);
5867 memcpy(rec_buf_ptr,
table->record[0], m_rec_length);
5868 reverse_order= FALSE;
5873 DBUG_RETURN(HA_ERR_END_OF_FILE);
5881 queue_element(&m_queue, j++)= part_rec_buf_ptr;
5883 else if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
5887 else if (error == HA_ERR_KEY_NOT_FOUND)
5889 DBUG_PRINT(
"info", (
"HA_ERR_KEY_NOT_FOUND from partition %u", i));
5890 bitmap_set_bit(&m_key_not_found_partitions, i);
5891 m_key_not_found=
true;
5894 part_rec_buf_ptr+= m_rec_length + PARTITION_BYTES_IN_POS;
5902 queue_set_max_at_top(&m_queue, reverse_order);
5903 queue_set_cmp_arg(&m_queue, (
void*)m_curr_key_info);
5904 m_queue.elements= j;
5905 queue_fix(&m_queue);
5906 return_top_record(buf);
5908 DBUG_PRINT(
"info", (
"Record returned from partition %d", m_top_entry));
5911 DBUG_RETURN(saved_error);
5926 void ha_partition::return_top_record(uchar *buf)
5929 uchar *key_buffer= queue_top(&m_queue);
5930 uchar *rec_buffer= key_buffer + PARTITION_BYTES_IN_POS;
5932 part_id= uint2korr(key_buffer);
5933 memcpy(buf, rec_buffer, m_rec_length);
5934 m_last_part= part_id;
5935 m_top_entry= part_id;
5947 int ha_partition::handle_ordered_index_scan_key_not_found()
5951 uchar *part_buf= m_ordered_rec_buffer;
5952 uchar *curr_rec_buf= NULL;
5953 DBUG_ENTER(
"ha_partition::handle_ordered_index_scan_key_not_found");
5954 DBUG_ASSERT(m_key_not_found);
5959 for (i= bitmap_get_first_set(&m_part_info->read_partitions);
5961 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
5963 if (bitmap_is_set(&m_key_not_found_partitions, i))
5969 curr_rec_buf= part_buf + PARTITION_BYTES_IN_POS;
5972 DBUG_ASSERT(error != HA_ERR_KEY_NOT_FOUND);
5974 queue_insert(&m_queue, part_buf);
5975 else if (error != HA_ERR_END_OF_FILE && error != HA_ERR_KEY_NOT_FOUND)
5978 part_buf+= m_rec_length + PARTITION_BYTES_IN_POS;
5980 DBUG_ASSERT(curr_rec_buf);
5981 bitmap_clear_all(&m_key_not_found_partitions);
5982 m_key_not_found=
false;
5985 uchar *key_buffer= queue_top(&m_queue);
5986 m_top_entry= uint2korr(key_buffer);
6005 int ha_partition::handle_ordered_next(uchar *buf,
bool is_next_same)
6008 uint part_id= m_top_entry;
6009 uchar *rec_buf= queue_top(&m_queue) + PARTITION_BYTES_IN_POS;
6011 DBUG_ENTER(
"ha_partition::handle_ordered_next");
6013 if (m_key_not_found)
6018 m_key_not_found=
false;
6019 bitmap_clear_all(&m_key_not_found_partitions);
6024 uint old_elements= m_queue.elements;
6025 if ((error= handle_ordered_index_scan_key_not_found()))
6033 if (old_elements != m_queue.elements && part_id != m_top_entry)
6035 return_top_record(buf);
6040 if (part_id >= m_tot_parts)
6041 DBUG_RETURN(HA_ERR_END_OF_FILE);
6043 file= m_file[part_id];
6045 if (m_index_scan_type == partition_read_range)
6048 memcpy(rec_buf,
table->record[0], m_rec_length);
6050 else if (!is_next_same)
6054 m_start_key.length);
6057 if (error == HA_ERR_END_OF_FILE)
6060 queue_remove(&m_queue, (uint) 0);
6061 if (m_queue.elements)
6063 DBUG_PRINT(
"info", (
"Record returned from partition %u (2)",
6065 return_top_record(buf);
6072 queue_replaced(&m_queue);
6073 return_top_record(buf);
6074 DBUG_PRINT(
"info", (
"Record returned from partition %u", m_top_entry));
6092 int ha_partition::handle_ordered_prev(uchar *buf)
6095 uint part_id= m_top_entry;
6096 uchar *rec_buf= queue_top(&m_queue) + PARTITION_BYTES_IN_POS;
6097 handler *file= m_file[part_id];
6098 DBUG_ENTER(
"ha_partition::handle_ordered_prev");
6102 if (error == HA_ERR_END_OF_FILE)
6104 queue_remove(&m_queue, (uint) 0);
6105 if (m_queue.elements)
6107 return_top_record(buf);
6108 DBUG_PRINT(
"info", (
"Record returned from partition %d (2)",
6116 queue_replaced(&m_queue);
6117 return_top_record(buf);
6118 DBUG_PRINT(
"info", (
"Record returned from partition %d", m_top_entry));
6136 int ha_partition::compare_number_of_records(
ha_partition *me,
6142 if (file[*a]->
stats.records > file[*b]->stats.records)
6144 if (file[*a]->
stats.records < file[*b]->stats.records)
6215 int ha_partition::info(uint flag)
6217 uint no_lock_flag= flag & HA_STATUS_NO_LOCK;
6218 uint extra_var_flag= flag & HA_STATUS_VARIABLE_EXTRA;
6219 DBUG_ENTER(
"ha_partition::info");
6222 if (bitmap_is_set_all(&(m_part_info->read_partitions)))
6223 DBUG_PRINT(
"info", (
"All partitions are used"));
6225 if (flag & HA_STATUS_AUTO)
6227 bool auto_inc_is_first_in_idx= (table_share->next_number_keypart == 0);
6228 DBUG_PRINT(
"info", (
"HA_STATUS_AUTO"));
6229 if (!
table->found_next_number_field)
6230 stats.auto_increment_value= 0;
6231 else if (part_share->auto_inc_initialized)
6233 lock_auto_increment();
6235 unlock_auto_increment();
6239 lock_auto_increment();
6241 if (part_share->auto_inc_initialized)
6252 ulonglong auto_increment_value= 0;
6255 (
"checking all partitions for auto_increment_value"));
6259 file->info(HA_STATUS_AUTO | no_lock_flag);
6260 set_if_bigger(auto_increment_value,
6261 file->stats.auto_increment_value);
6262 }
while (*(++file_array));
6264 DBUG_ASSERT(auto_increment_value);
6265 stats.auto_increment_value= auto_increment_value;
6266 if (auto_inc_is_first_in_idx)
6269 auto_increment_value);
6270 part_share->auto_inc_initialized=
true;
6271 DBUG_PRINT(
"info", (
"initializing next_auto_inc_val to %lu",
6275 unlock_auto_increment();
6278 if (flag & HA_STATUS_VARIABLE)
6281 DBUG_PRINT(
"info", (
"HA_STATUS_VARIABLE"));
6304 stats.data_file_length= 0;
6305 stats.index_file_length= 0;
6306 stats.check_time= 0;
6307 stats.delete_length= 0;
6308 for (i= bitmap_get_first_set(&m_part_info->read_partitions);
6310 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
6313 file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag);
6314 stats.records+= file->stats.records;
6315 stats.deleted+= file->stats.deleted;
6316 stats.data_file_length+= file->stats.data_file_length;
6317 stats.index_file_length+= file->stats.index_file_length;
6318 stats.delete_length+= file->stats.delete_length;
6319 if (file->stats.check_time >
stats.check_time)
6320 stats.check_time= file->stats.check_time;
6323 !(m_file[0]->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT))
6325 if (
stats.records > 0)
6326 stats.mean_rec_length= (ulong) (
stats.data_file_length /
stats.records);
6328 stats.mean_rec_length= 0;
6330 if (flag & HA_STATUS_CONST)
6332 DBUG_PRINT(
"info", (
"HA_STATUS_CONST"));
6382 ulonglong max_records= 0;
6384 uint32 handler_instance= 0;
6391 if (!(flag & HA_STATUS_VARIABLE) ||
6392 !bitmap_is_set(&(m_part_info->read_partitions),
6393 (file_array - m_file)))
6394 file->info(HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag);
6395 if (file->stats.records > max_records)
6397 max_records= file->stats.records;
6398 handler_instance=
i;
6401 }
while (*(++file_array));
6406 my_qsort2((
void*) m_part_ids_sorted_by_num_of_records,
6409 (qsort2_cmp) compare_number_of_records,
6412 file= m_file[handler_instance];
6413 file->info(HA_STATUS_CONST | no_lock_flag);
6414 stats.block_size= file->stats.block_size;
6415 stats.create_time= file->stats.create_time;
6418 if (flag & HA_STATUS_ERRKEY)
6420 handler *file= m_file[m_last_part];
6421 DBUG_PRINT(
"info", (
"info: HA_STATUS_ERRKEY"));
6428 file->errkey= errkey;
6429 file->info(HA_STATUS_ERRKEY | no_lock_flag);
6430 errkey= file->errkey;
6432 if (flag & HA_STATUS_TIME)
6435 DBUG_PRINT(
"info", (
"info: HA_STATUS_TIME"));
6441 stats.update_time= 0;
6446 file->info(HA_STATUS_TIME | no_lock_flag);
6447 if (file->stats.update_time >
stats.update_time)
6448 stats.update_time= file->stats.update_time;
6449 }
while (*(++file_array));
6455 void ha_partition::get_dynamic_partition_info(
PARTITION_STATS *stat_info,
6458 handler *file= m_file[part_id];
6459 DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), part_id));
6460 file->info(HA_STATUS_TIME | HA_STATUS_VARIABLE |
6461 HA_STATUS_VARIABLE_EXTRA | HA_STATUS_NO_LOCK);
6463 stat_info->records= file->stats.records;
6464 stat_info->mean_rec_length= file->stats.mean_rec_length;
6465 stat_info->data_file_length= file->stats.data_file_length;
6466 stat_info->max_data_file_length= file->stats.max_data_file_length;
6467 stat_info->index_file_length= file->stats.index_file_length;
6468 stat_info->delete_length= file->stats.delete_length;
6469 stat_info->create_time= file->stats.create_time;
6470 stat_info->update_time= file->stats.update_time;
6471 stat_info->check_time= file->stats.check_time;
6472 stat_info->check_sum= 0;
6474 stat_info->check_sum= file->checksum();
6791 int ha_partition::extra(
enum ha_extra_function operation)
6793 DBUG_ENTER(
"ha_partition:extra");
6794 DBUG_PRINT(
"info", (
"operation: %d", (
int) operation));
6796 switch (operation) {
6798 case HA_EXTRA_KEYREAD:
6799 case HA_EXTRA_NO_KEYREAD:
6800 case HA_EXTRA_FLUSH:
6801 DBUG_RETURN(loop_extra(operation));
6802 case HA_EXTRA_PREPARE_FOR_RENAME:
6803 case HA_EXTRA_FORCE_REOPEN:
6804 DBUG_RETURN(loop_extra_alter(operation));
6808 case HA_EXTRA_IGNORE_DUP_KEY:
6809 case HA_EXTRA_NO_IGNORE_DUP_KEY:
6810 case HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
6813 DBUG_RETURN(loop_extra(operation));
6818 case HA_EXTRA_PREPARE_FOR_UPDATE:
6823 m_extra_prepare_for_update= TRUE;
6824 if (m_part_spec.start_part != NO_CURRENT_PART_ID)
6827 m_extra_cache_part_id= m_part_spec.start_part;
6828 DBUG_ASSERT(m_extra_cache_part_id == m_part_spec.start_part);
6829 (void) m_file[m_part_spec.start_part]->extra(HA_EXTRA_PREPARE_FOR_UPDATE);
6832 case HA_EXTRA_NORMAL:
6833 case HA_EXTRA_QUICK:
6834 case HA_EXTRA_PREPARE_FOR_DROP:
6835 case HA_EXTRA_FLUSH_CACHE:
6838 DBUG_RETURN(loop_extra(operation));
6841 case HA_EXTRA_NO_READCHECK:
6849 case HA_EXTRA_CACHE:
6851 prepare_extra_cache(0);
6854 case HA_EXTRA_NO_CACHE:
6857 if (m_extra_cache_part_id != NO_CURRENT_PART_ID)
6858 ret= m_file[m_extra_cache_part_id]->extra(HA_EXTRA_NO_CACHE);
6859 m_extra_cache= FALSE;
6860 m_extra_cache_size= 0;
6861 m_extra_prepare_for_update= FALSE;
6862 m_extra_cache_part_id= NO_CURRENT_PART_ID;
6865 case HA_EXTRA_WRITE_CACHE:
6867 m_extra_cache= FALSE;
6868 m_extra_cache_size= 0;
6869 m_extra_prepare_for_update= FALSE;
6870 m_extra_cache_part_id= NO_CURRENT_PART_ID;
6871 DBUG_RETURN(loop_extra(operation));
6873 case HA_EXTRA_IGNORE_NO_KEY:
6874 case HA_EXTRA_NO_IGNORE_NO_KEY:
6882 case HA_EXTRA_WRITE_CAN_REPLACE:
6883 case HA_EXTRA_WRITE_CANNOT_REPLACE:
6904 case HA_EXTRA_INSERT_WITH_UPDATE:
6905 DBUG_RETURN(loop_extra(operation));
6907 case HA_EXTRA_DELETE_CANNOT_BATCH:
6908 case HA_EXTRA_UPDATE_CANNOT_BATCH:
6914 case HA_EXTRA_ADD_CHILDREN_LIST:
6915 case HA_EXTRA_ATTACH_CHILDREN:
6916 case HA_EXTRA_IS_ATTACHED_CHILDREN:
6917 case HA_EXTRA_DETACH_CHILDREN:
6927 case HA_EXTRA_MARK_AS_LOG_TABLE:
6928 DBUG_RETURN(ER_UNSUPORTED_LOG_ENGINE);
6958 DBUG_ENTER(
"ha_partition::reset");
6960 for (i= bitmap_get_first_set(&m_partitions_to_reset);
6962 i= bitmap_get_next_set(&m_partitions_to_reset, i))
6967 bitmap_clear_all(&m_partitions_to_reset);
6968 DBUG_RETURN(result);
6984 int ha_partition::extra_opt(
enum ha_extra_function operation, ulong cachesize)
6986 DBUG_ENTER(
"ha_partition::extra_opt()");
6988 DBUG_ASSERT(HA_EXTRA_CACHE == operation);
6989 prepare_extra_cache(cachesize);
7005 void ha_partition::prepare_extra_cache(uint cachesize)
7007 DBUG_ENTER(
"ha_partition::prepare_extra_cache()");
7008 DBUG_PRINT(
"info", (
"cachesize %u", cachesize));
7010 m_extra_cache= TRUE;
7011 m_extra_cache_size= cachesize;
7012 if (m_part_spec.start_part != NO_CURRENT_PART_ID)
7014 DBUG_ASSERT(bitmap_is_set(&m_partitions_to_reset,
7015 m_part_spec.start_part));
7016 bitmap_set_bit(&m_partitions_to_reset, m_part_spec.start_part);
7017 late_extra_cache(m_part_spec.start_part);
7033 int ha_partition::loop_extra_alter(
enum ha_extra_function operation)
7037 DBUG_ENTER(
"ha_partition::loop_extra_alter()");
7038 DBUG_ASSERT(operation == HA_EXTRA_PREPARE_FOR_RENAME ||
7039 operation == HA_EXTRA_FORCE_REOPEN);
7041 if (m_new_file != NULL)
7043 for (file= m_new_file; *
file; file++)
7044 if ((tmp= (*file)->extra(operation)))
7047 if (m_reorged_file != NULL)
7049 for (file= m_reorged_file; *
file; file++)
7050 if ((tmp= (*file)->extra(operation)))
7053 if ((tmp= loop_extra(operation)))
7055 DBUG_RETURN(result);
7070 int ha_partition::loop_extra(
enum ha_extra_function operation)
7074 DBUG_ENTER(
"ha_partition::loop_extra()");
7076 for (i= bitmap_get_first_set(&m_part_info->lock_partitions);
7078 i= bitmap_get_next_set(&m_part_info->lock_partitions, i))
7080 if ((tmp= m_file[i]->
extra(operation)))
7084 bitmap_union(&m_partitions_to_reset, &m_part_info->lock_partitions);
7085 DBUG_RETURN(result);
7100 void ha_partition::late_extra_cache(uint partition_id)
7103 DBUG_ENTER(
"ha_partition::late_extra_cache");
7104 DBUG_PRINT(
"info", (
"extra_cache %u prepare %u partid %u size %u",
7105 m_extra_cache, m_extra_prepare_for_update,
7106 partition_id, m_extra_cache_size));
7108 if (!m_extra_cache && !m_extra_prepare_for_update)
7110 file= m_file[partition_id];
7113 if (m_extra_cache_size == 0)
7114 (void) file->extra(HA_EXTRA_CACHE);
7116 (
void) file->extra_opt(HA_EXTRA_CACHE, m_extra_cache_size);
7118 if (m_extra_prepare_for_update)
7120 (void) file->extra(HA_EXTRA_PREPARE_FOR_UPDATE);
7122 m_extra_cache_part_id= partition_id;
7138 void ha_partition::late_extra_no_cache(uint partition_id)
7141 DBUG_ENTER(
"ha_partition::late_extra_no_cache");
7143 if (!m_extra_cache && !m_extra_prepare_for_update)
7145 file= m_file[partition_id];
7146 (void) file->extra(HA_EXTRA_NO_CACHE);
7147 DBUG_ASSERT(partition_id == m_extra_cache_part_id);
7148 m_extra_cache_part_id= NO_CURRENT_PART_ID;
7166 const key_map *ha_partition::keys_to_use_for_scanning()
7168 DBUG_ENTER(
"ha_partition::keys_to_use_for_scanning");
7169 DBUG_RETURN(m_file[0]->keys_to_use_for_scanning());
7177 ha_rows ha_partition::min_rows_for_estimate()
7179 uint
i, max_used_partitions, tot_used_partitions;
7180 DBUG_ENTER(
"ha_partition::min_rows_for_estimate");
7182 tot_used_partitions= bitmap_bits_set(&m_part_info->read_partitions);
7192 if (!tot_used_partitions)
7202 max_used_partitions= 1;
7203 while (i < m_tot_parts)
7205 max_used_partitions++;
7208 if (max_used_partitions > tot_used_partitions)
7209 max_used_partitions= tot_used_partitions;
7212 DBUG_PRINT(
"info", (
"max_used_partitions: %u tot_rows: %lu",
7213 max_used_partitions,
7214 (ulong)
stats.records));
7215 DBUG_PRINT(
"info", (
"tot_used_partitions: %u min_rows_to_check: %lu",
7216 tot_used_partitions,
7217 (ulong)
stats.records * max_used_partitions
7218 / tot_used_partitions));
7219 DBUG_RETURN(
stats.records * max_used_partitions / tot_used_partitions);
7239 uint ha_partition::get_biggest_used_partition(uint *part_index)
7242 while ((*part_index) < m_tot_parts)
7244 part_id= m_part_ids_sorted_by_num_of_records[(*part_index)++];
7245 if (bitmap_is_set(&m_part_info->read_partitions, part_id))
7248 return NO_CURRENT_PART_ID;
7262 double ha_partition::scan_time()
7264 double scan_time= 0;
7266 DBUG_ENTER(
"ha_partition::scan_time");
7268 for (i= bitmap_get_first_set(&m_part_info->read_partitions);
7270 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
7271 scan_time+= m_file[
i]->scan_time();
7272 DBUG_RETURN(scan_time);
7289 ha_rows ha_partition::records_in_range(uint inx,
key_range *min_key,
7292 ha_rows min_rows_to_check, rows, estimated_rows=0, checked_rows= 0;
7293 uint partition_index= 0, part_id;
7294 DBUG_ENTER(
"ha_partition::records_in_range");
7296 min_rows_to_check= min_rows_for_estimate();
7298 while ((part_id= get_biggest_used_partition(&partition_index))
7299 != NO_CURRENT_PART_ID)
7301 rows= m_file[part_id]->records_in_range(inx, min_key, max_key);
7303 DBUG_PRINT(
"info", (
"part %u match %lu rows of %lu", part_id, (ulong) rows,
7304 (ulong) m_file[part_id]->
stats.records));
7306 if (rows == HA_POS_ERROR)
7307 DBUG_RETURN(HA_POS_ERROR);
7308 estimated_rows+= rows;
7309 checked_rows+= m_file[part_id]->stats.records;
7323 if (estimated_rows && checked_rows &&
7324 checked_rows >= min_rows_to_check)
7327 (
"records_in_range(inx %u): %lu (%lu * %lu / %lu)",
7329 (ulong) (estimated_rows *
stats.records / checked_rows),
7330 (ulong) estimated_rows,
7331 (ulong)
stats.records,
7332 (ulong) checked_rows));
7333 DBUG_RETURN(estimated_rows *
stats.records / checked_rows);
7336 DBUG_PRINT(
"info", (
"records_in_range(inx %u): %lu",
7338 (ulong) estimated_rows));
7339 DBUG_RETURN(estimated_rows);
7351 ha_rows rows, tot_rows= 0;
7353 DBUG_ENTER(
"ha_partition::estimate_rows_upper_bound");
7357 if (bitmap_is_set(&(m_part_info->read_partitions), (file - m_file)))
7359 rows= (*file)->estimate_rows_upper_bound();
7360 if (rows == HA_POS_ERROR)
7361 DBUG_RETURN(HA_POS_ERROR);
7364 }
while (*(++file));
7365 DBUG_RETURN(tot_rows);
7390 DBUG_ENTER(
"ha_partition::read_time");
7392 DBUG_RETURN(m_file[0]->
read_time(index, ranges, rows));
7404 ha_rows rows, tot_rows= 0;
7406 DBUG_ENTER(
"ha_partition::records");
7408 for (i= bitmap_get_first_set(&m_part_info->read_partitions);
7410 i= bitmap_get_next_set(&m_part_info->read_partitions, i))
7413 if (rows == HA_POS_ERROR)
7414 DBUG_RETURN(HA_POS_ERROR);
7417 DBUG_RETURN(tot_rows);
7439 DBUG_ENTER(
"ha_partition::can_switch_engines");
7444 if (!(*file)->can_switch_engines())
7446 }
while (*(++file));
7461 DBUG_ENTER(
"ha_partition::table_cache_type");
7478 uint32 ha_partition::calculate_key_hash_value(
Field **field_array)
7483 use_51_hash=
test((*field_array)->table->part_info->key_algorithm ==
7484 partition_info::KEY_ALGORITHM_51);
7488 Field *field= *field_array;
7491 switch (field->real_type()) {
7492 case MYSQL_TYPE_TINY:
7493 case MYSQL_TYPE_SHORT:
7494 case MYSQL_TYPE_LONG:
7495 case MYSQL_TYPE_FLOAT:
7496 case MYSQL_TYPE_DOUBLE:
7497 case MYSQL_TYPE_NEWDECIMAL:
7498 case MYSQL_TYPE_TIMESTAMP:
7499 case MYSQL_TYPE_LONGLONG:
7500 case MYSQL_TYPE_INT24:
7501 case MYSQL_TYPE_TIME:
7502 case MYSQL_TYPE_DATETIME:
7503 case MYSQL_TYPE_YEAR:
7504 case MYSQL_TYPE_NEWDATE:
7506 if (field->is_null())
7508 nr1^= (nr1 << 1) | 1;
7512 uint len= field->pack_length();
7513 my_charset_bin.coll->hash_sort(&my_charset_bin, field->ptr, len,
7518 case MYSQL_TYPE_STRING:
7519 case MYSQL_TYPE_VARCHAR:
7520 case MYSQL_TYPE_BIT:
7527 case MYSQL_TYPE_ENUM:
7528 case MYSQL_TYPE_SET:
7530 if (field->is_null())
7532 nr1^= (nr1 << 1) | 1;
7536 uint len= field->pack_length();
7537 my_charset_latin1.coll->hash_sort(&my_charset_latin1, field->ptr,
7542 case MYSQL_TYPE_DATETIME2:
7543 case MYSQL_TYPE_TIME2:
7544 case MYSQL_TYPE_TIMESTAMP2:
7549 case MYSQL_TYPE_NULL:
7550 case MYSQL_TYPE_DECIMAL:
7551 case MYSQL_TYPE_DATE:
7552 case MYSQL_TYPE_TINY_BLOB:
7553 case MYSQL_TYPE_MEDIUM_BLOB:
7554 case MYSQL_TYPE_LONG_BLOB:
7555 case MYSQL_TYPE_BLOB:
7556 case MYSQL_TYPE_VAR_STRING:
7557 case MYSQL_TYPE_GEOMETRY:
7565 field->hash(&nr1, &nr2);
7566 }
while (*(++field_array));
7567 return (uint32) nr1;
7575 const char *ha_partition::index_type(uint inx)
7577 uint first_used_partition;
7578 DBUG_ENTER(
"ha_partition::index_type");
7580 first_used_partition= bitmap_get_first_set(&(m_part_info->read_partitions));
7582 if (first_used_partition == MY_BIT_NONE)
7585 DBUG_RETURN(handler::index_type(inx));
7588 DBUG_RETURN(m_file[first_used_partition]->index_type(inx));
7596 DBUG_ENTER(
"ha_partition::get_row_type");
7598 i= bitmap_get_first_set(&m_part_info->read_partitions);
7599 DBUG_ASSERT(i < m_tot_parts);
7600 if (i >= m_tot_parts)
7601 DBUG_RETURN(ROW_TYPE_NOT_USED);
7604 DBUG_PRINT(
"info", (
"partition %u, row_type: %d", i, type));
7606 for (i= bitmap_get_next_set(&m_part_info->lock_partitions, i);
7608 i= bitmap_get_next_set(&m_part_info->lock_partitions, i))
7611 DBUG_PRINT(
"info", (
"partition %u, row_type: %d", i, type));
7612 if (part_type != type)
7613 DBUG_RETURN(ROW_TYPE_NOT_USED);
7620 void ha_partition::append_row_to_str(
String &str)
7623 bool is_rec0= !m_err_rec || m_err_rec ==
table->record[0];
7625 rec=
table->record[0];
7629 if (
table->s->primary_key != MAX_KEY)
7635 set_key_field_ptr(key, rec,
table->record[0]);
7636 for (; key_part != key_part_end; key_part++)
7638 Field *field= key_part->field;
7640 str.append(field->field_name);
7642 field_unpack(&str, field, rec, 0,
false);
7645 set_key_field_ptr(key,
table->record[0], rec);
7651 set_field_ptr(m_part_info->full_part_field_array, rec,
7654 for (field_ptr= m_part_info->full_part_field_array;
7658 Field *field= *field_ptr;
7660 str.append(field->field_name);
7662 field_unpack(&str, field, rec, 0,
false);
7665 set_field_ptr(m_part_info->full_part_field_array,
table->record[0],
7674 DBUG_ENTER(
"ha_partition::print_error");
7677 DBUG_PRINT(
"enter", (
"error: %d", error));
7679 if ((error == HA_ERR_NO_PARTITION_FOUND) &&
7680 ! (thd->lex->alter_info.flags & Alter_info::ALTER_TRUNCATE_PARTITION))
7681 m_part_info->print_no_partition_found(
table);
7682 else if (error == HA_ERR_ROW_IN_WRONG_PARTITION)
7685 DBUG_ASSERT(thd_sql_command(thd) == SQLCOM_DELETE ||
7686 thd_sql_command(thd) == SQLCOM_DELETE_MULTI ||
7687 thd_sql_command(thd) == SQLCOM_UPDATE ||
7688 thd_sql_command(thd) == SQLCOM_UPDATE_MULTI);
7689 DBUG_ASSERT(m_err_rec);
7693 char buf[MAX_KEY_LENGTH];
7694 String str(buf,
sizeof(buf),system_charset_info);
7698 str.append_ulonglong(m_last_part);
7700 if (get_part_for_delete(m_err_rec, m_rec0, m_part_info, &part_id))
7703 str.append_ulonglong(part_id);
7705 append_row_to_str(str);
7708 sql_print_error(
"Table '%-192s' corrupted: row in wrong partition: %s\n"
7709 "Please REPAIR the table!",
7710 table->s->table_name.str,
7713 max_length= (MYSQL_ERRMSG_SIZE - (uint) strlen(ER(ER_ROW_IN_WRONG_PARTITION)));
7714 if (str.length() >= max_length)
7716 str.length(max_length-4);
7717 str.append(STRING_WITH_LEN(
"..."));
7719 my_error(ER_ROW_IN_WRONG_PARTITION, MYF(0), str.c_ptr_safe());
7729 if (m_last_part >= m_tot_parts)
7744 DBUG_ENTER(
"ha_partition::get_error_message");
7763 handler::Table_flags ha_partition::table_flags()
const
7765 uint first_used_partition= 0;
7766 DBUG_ENTER(
"ha_partition::table_flags");
7767 if (m_handler_status < handler_initialized ||
7768 m_handler_status >= handler_closed)
7769 DBUG_RETURN(PARTITION_ENABLED_TABLE_FLAGS);
7771 if (get_lock_type() != F_UNLCK)
7777 first_used_partition= bitmap_get_first_set(&m_part_info->lock_partitions);
7778 if (first_used_partition == MY_BIT_NONE)
7779 first_used_partition= 0;
7782 ~(PARTITION_DISABLED_TABLE_FLAGS)) |
7783 (PARTITION_ENABLED_TABLE_FLAGS));
7793 uint flags_to_return;
7794 DBUG_ENTER(
"ha_partition::alter_table_flags");
7796 flags_to_return= ht->alter_table_flags(flags);
7797 flags_to_return|= m_file[0]->alter_table_flags(flags);
7799 DBUG_RETURN(flags_to_return);
7810 bool ret= COMPATIBLE_DATA_YES;
7817 for (file= m_file; *
file; file++)
7818 if ((ret= (*file)->check_if_incompatible_data(create_info,
7820 COMPATIBLE_DATA_YES)
7842 ha_partition_inplace_ctx(THD *thd, uint tot_parts)
7844 handler_ctx_array(NULL),
7845 m_tot_parts(tot_parts)
7848 ~ha_partition_inplace_ctx()
7850 if (handler_ctx_array)
7852 for (uint index= 0; index < m_tot_parts; index++)
7853 delete handler_ctx_array[index];
7859 enum_alter_inplace_result
7864 enum_alter_inplace_result result= HA_ALTER_INPLACE_NO_LOCK;
7865 ha_partition_inplace_ctx *part_inplace_ctx;
7866 bool first_is_set=
false;
7869 DBUG_ENTER(
"ha_partition::check_if_supported_inplace_alter");
7875 if (ha_alter_info->
alter_info->flags == Alter_info::ALTER_PARTITION)
7876 DBUG_RETURN(HA_ALTER_INPLACE_NO_LOCK);
7879 new (thd->mem_root) ha_partition_inplace_ctx(thd, m_tot_parts);
7880 if (!part_inplace_ctx)
7881 DBUG_RETURN(HA_ALTER_ERROR);
7885 if (!part_inplace_ctx->handler_ctx_array)
7886 DBUG_RETURN(HA_ALTER_ERROR);
7889 for (index= 0; index <= m_tot_parts; index++)
7890 part_inplace_ctx->handler_ctx_array[index]= NULL;
7892 for (index= 0; index < m_tot_parts; index++)
7894 enum_alter_inplace_result p_result=
7901 first_is_set= (ha_alter_info->
handler_ctx != NULL);
7903 else if (first_is_set != (ha_alter_info->
handler_ctx != NULL))
7907 DBUG_RETURN(HA_ALTER_ERROR);
7909 if (p_result < result)
7911 if (result == HA_ALTER_ERROR)
7924 DBUG_RETURN(result);
7933 ha_partition_inplace_ctx *part_inplace_ctx;
7935 DBUG_ENTER(
"ha_partition::prepare_inplace_alter_table");
7941 if (ha_alter_info->
alter_info->flags == Alter_info::ALTER_PARTITION)
7945 static_cast<class ha_partition_inplace_ctx*
>(ha_alter_info->
handler_ctx);
7947 for (index= 0; index < m_tot_parts && !error; index++)
7966 ha_partition_inplace_ctx *part_inplace_ctx;
7968 DBUG_ENTER(
"ha_partition::inplace_alter_table");
7974 if (ha_alter_info->
alter_info->flags == Alter_info::ALTER_PARTITION)
7978 static_cast<class ha_partition_inplace_ctx*
>(ha_alter_info->
handler_ctx);
7980 for (index= 0; index < m_tot_parts && !error; index++)
8005 ha_partition_inplace_ctx *part_inplace_ctx;
8008 DBUG_ENTER(
"ha_partition::commit_inplace_alter_table");
8014 if (ha_alter_info->
alter_info->flags == Alter_info::ALTER_PARTITION)
8018 static_cast<class ha_partition_inplace_ctx*
>(ha_alter_info->
handler_ctx);
8023 part_inplace_ctx->handler_ctx_array);
8024 ha_alter_info->
handler_ctx= part_inplace_ctx->handler_ctx_array[0];
8026 ha_alter_info, commit);
8041 for (i= 1; i < m_tot_parts; i++)
8043 ha_alter_info->
handler_ctx= part_inplace_ctx->handler_ctx_array[
i];
8053 for (i= 0; i < m_tot_parts; i++)
8056 ha_alter_info->
handler_ctx= part_inplace_ctx->handler_ctx_array[
i];
8058 ha_alter_info,
false))
8073 DBUG_ENTER(
"ha_partition::notify_table_changed");
8075 for (file= m_file; *
file; file++)
8076 (*file)->ha_notify_table_changed();
8088 static const char *ha_partition_ext[]=
8094 {
return ha_partition_ext; }
8097 uint ha_partition::min_of_the_max_uint(
8098 uint (
handler::*operator_func)(
void)
const)
const
8101 uint min_of_the_max= ((*m_file)->*operator_func)();
8103 for (file= m_file+1; *
file; file++)
8105 uint tmp= ((*file)->*operator_func)();
8106 set_if_smaller(min_of_the_max, tmp);
8108 return min_of_the_max;
8112 uint ha_partition::max_supported_key_parts()
const
8114 return min_of_the_max_uint(&handler::max_supported_key_parts);
8118 uint ha_partition::max_supported_key_length()
const
8120 return min_of_the_max_uint(&handler::max_supported_key_length);
8124 uint ha_partition::max_supported_key_part_length()
const
8126 return min_of_the_max_uint(&handler::max_supported_key_part_length);
8130 uint ha_partition::max_supported_record_length()
const
8132 return min_of_the_max_uint(&handler::max_supported_record_length);
8136 uint ha_partition::max_supported_keys()
const
8138 return min_of_the_max_uint(&handler::max_supported_keys);
8142 uint ha_partition::extra_rec_buf_length()
const
8145 uint max= (*m_file)->extra_rec_buf_length();
8147 for (file= m_file, file++; *
file; file++)
8148 if (max < (*file)->extra_rec_buf_length())
8149 max= (*file)->extra_rec_buf_length();
8154 uint ha_partition::min_record_length(uint options)
const
8157 uint max= (*m_file)->min_record_length(options);
8159 for (file= m_file, file++; *
file; file++)
8160 if (max < (*file)->min_record_length(options))
8161 max= (*file)->min_record_length(options);
8189 int ha_partition::cmp_ref(
const uchar *ref1,
const uchar *ref2)
8192 my_ptrdiff_t diff1, diff2;
8194 DBUG_ENTER(
"ha_partition::cmp_ref");
8196 if ((ref1[0] == ref2[0]) && (ref1[1] == ref2[1]))
8198 part_id= uint2korr(ref1);
8199 file= m_file[part_id];
8200 DBUG_ASSERT(part_id < m_tot_parts);
8201 DBUG_RETURN(file->cmp_ref((ref1 + PARTITION_BYTES_IN_POS),
8202 (ref2 + PARTITION_BYTES_IN_POS)));
8204 diff1= ref2[1] - ref1[1];
8205 diff2= ref2[0] - ref1[0];
8227 int ha_partition::reset_auto_increment(ulonglong value)
8231 DBUG_ENTER(
"ha_partition::reset_auto_increment");
8232 lock_auto_increment();
8233 part_share->auto_inc_initialized=
false;
8237 if ((res= (*file)->ha_reset_auto_increment(value)) != 0)
8239 }
while (*(++file));
8240 unlock_auto_increment();
8255 ulonglong nb_desired_values,
8256 ulonglong *first_value,
8257 ulonglong *nb_reserved_values)
8259 DBUG_ENTER(
"ha_partition::get_auto_increment");
8260 DBUG_PRINT(
"info", (
"offset: %lu inc: %lu desired_values: %lu "
8261 "first_value: %lu", (ulong) offset, (ulong) increment,
8262 (ulong) nb_desired_values, (ulong) *first_value));
8263 DBUG_ASSERT(increment && nb_desired_values);
8265 if (table->s->next_number_keypart)
8271 DBUG_PRINT(
"info", (
"next_number_keypart != 0"));
8272 ulonglong nb_reserved_values_part;
8273 ulonglong first_value_part, max_first_value;
8275 first_value_part= max_first_value= *first_value;
8277 lock_auto_increment();
8281 (*file)->get_auto_increment(offset, increment, 1,
8282 &first_value_part, &nb_reserved_values_part);
8283 if (first_value_part == ULONGLONG_MAX)
8285 *first_value= first_value_part;
8287 sql_print_error(
"Partition failed to reserve auto_increment value");
8288 unlock_auto_increment();
8291 DBUG_PRINT(
"info", (
"first_value_part: %lu", (ulong) first_value_part));
8292 set_if_bigger(max_first_value, first_value_part);
8293 }
while (*(++file));
8294 *first_value= max_first_value;
8295 *nb_reserved_values= 1;
8296 unlock_auto_increment();
8304 DBUG_ASSERT(part_share->auto_inc_initialized);
8310 lock_auto_increment();
8322 if (!auto_increment_safe_stmt_log_lock &&
8323 thd->lex->sql_command != SQLCOM_INSERT &&
8324 mysql_bin_log.is_open() &&
8325 !thd->is_current_stmt_binlog_format_row() &&
8326 (thd->variables.option_bits & OPTION_BIN_LOG))
8328 DBUG_PRINT(
"info", (
"locking auto_increment_safe_stmt_log_lock"));
8329 auto_increment_safe_stmt_log_lock= TRUE;
8336 unlock_auto_increment();
8337 DBUG_PRINT(
"info", (
"*first_value: %lu", (ulong) *first_value));
8338 *nb_reserved_values= nb_desired_values;
8343 void ha_partition::release_auto_increment()
8345 DBUG_ENTER(
"ha_partition::release_auto_increment");
8347 if (table->s->next_number_keypart)
8350 for (i= bitmap_get_first_set(&m_part_info->lock_partitions);
8352 i= bitmap_get_next_set(&m_part_info->lock_partitions, i))
8354 m_file[
i]->ha_release_auto_increment();
8359 ulonglong next_auto_inc_val;
8360 lock_auto_increment();
8378 DBUG_PRINT(
"info", (
"part_share->next_auto_inc_val: %lu",
8382 if (auto_increment_safe_stmt_log_lock)
8384 auto_increment_safe_stmt_log_lock= FALSE;
8385 DBUG_PRINT(
"info", (
"unlocking auto_increment_safe_stmt_log_lock"));
8388 unlock_auto_increment();
8397 void ha_partition::init_table_handle_for_HANDLER()
8407 uint ha_partition::checksum()
const
8411 DBUG_ENTER(
"ha_partition::checksum");
8412 if ((table_flags() & HA_HAS_CHECKSUM))
8417 sum+= (*file)->checksum();
8418 }
while (*(++file));
8438 int ha_partition::disable_indexes(uint mode)
8443 DBUG_ASSERT(bitmap_is_set_all(&(m_part_info->lock_partitions)));
8444 for (file= m_file; *
file; file++)
8446 if ((error= (*file)->ha_disable_indexes(mode)))
8463 int ha_partition::enable_indexes(uint mode)
8468 DBUG_ASSERT(bitmap_is_set_all(&(m_part_info->lock_partitions)));
8469 for (file= m_file; *
file; file++)
8471 if ((error= (*file)->ha_enable_indexes(mode)))
8488 int ha_partition::indexes_are_disabled(
void)
8493 DBUG_ASSERT(bitmap_is_set_all(&(m_part_info->lock_partitions)));
8494 for (file= m_file; *
file; file++)
8496 if ((error= (*file)->indexes_are_disabled()))
8514 int ha_partition::check_misplaced_rows(uint read_part_id,
bool repair)
8517 uint32 correct_part_id;
8518 longlong func_value;
8519 longlong num_misplaced_rows= 0;
8521 DBUG_ENTER(
"ha_partition::check_misplaced_rows");
8523 DBUG_ASSERT(m_file);
8528 bitmap_set_all(table->read_set);
8529 bitmap_set_all(table->write_set);
8534 bitmap_union(table->read_set, &m_part_info->full_part_field_set);
8537 if ((result= m_file[read_part_id]->
ha_rnd_init(1)))
8538 DBUG_RETURN(result);
8542 if ((result= m_file[read_part_id]->
ha_rnd_next(m_rec0)))
8544 if (result == HA_ERR_RECORD_DELETED)
8546 if (result != HA_ERR_END_OF_FILE)
8549 if (num_misplaced_rows > 0)
8551 print_admin_msg(ha_thd(), MI_MAX_MSG_BUF,
"warning",
8552 table_share->db.str, table->alias,
8553 opt_op_name[REPAIR_PARTS],
8554 "Moved %lld misplaced rows",
8555 num_misplaced_rows);
8562 result= m_part_info->get_partition_id(m_part_info, &correct_part_id,
8567 if (correct_part_id != read_part_id)
8569 num_misplaced_rows++;
8573 print_admin_msg(ha_thd(), MI_MAX_MSG_BUF,
"error",
8574 table_share->db.str, table->alias,
8575 opt_op_name[CHECK_PARTS],
8576 "Found a misplaced row");
8578 result= HA_ADMIN_NEEDS_UPGRADE;
8583 DBUG_PRINT(
"info", (
"Moving row from partition %d to %d",
8584 read_part_id, correct_part_id));
8590 if ((result= m_file[correct_part_id]->ha_write_row(m_rec0)))
8595 char buf[MAX_KEY_LENGTH];
8596 String str(buf,
sizeof(buf),system_charset_info);
8598 if (result == HA_ERR_FOUND_DUPP_KEY)
8600 str.append(
"Duplicate key found, "
8601 "please update or delete the record:\n");
8602 result= HA_ADMIN_CORRUPT;
8605 append_row_to_str(str);
8611 if (!m_file[correct_part_id]->has_transactions())
8614 sql_print_error(
"Table '%-192s' failed to move/insert a row"
8615 " from part %d into part %d:\n%s",
8616 table->s->table_name.str,
8621 print_admin_msg(ha_thd(), MI_MAX_MSG_BUF,
"error",
8622 table_share->db.str, table->alias,
8623 opt_op_name[REPAIR_PARTS],
8624 "Failed to move/insert a row"
8625 " from part %d into part %d:\n%s",
8633 if ((result= m_file[read_part_id]->ha_delete_row(m_rec0)))
8635 if (m_file[correct_part_id]->has_transactions())
8641 char buf[MAX_KEY_LENGTH];
8642 String str(buf,
sizeof(buf),system_charset_info);
8645 append_row_to_str(str);
8648 sql_print_error(
"Table '%-192s': Delete from part %d failed with"
8649 " error %d. But it was already inserted into"
8650 " part %d, when moving the misplaced row!"
8651 "\nPlease manually fix the duplicate row:\n%s",
8652 table->s->table_name.str,
8663 int tmp_result= m_file[read_part_id]->
ha_rnd_end();
8664 DBUG_RETURN(result ? result : tmp_result);
8668 #define KEY_PARTITIONING_CHANGED_STR \
8669 "KEY () partitioning changed, please run:\n" \
8670 "ALTER TABLE %s.%s ALGORITHM = INPLACE %s"
8674 int error= HA_ADMIN_NEEDS_CHECK;
8675 DBUG_ENTER(
"ha_partition::check_for_upgrade");
8682 if (!(check_opt->sql_flags & TT_FOR_UPGRADE))
8691 if (table->s->mysql_version < 50503 &&
8692 ((m_part_info->part_type == HASH_PARTITION &&
8693 m_part_info->list_of_part_fields) ||
8694 (m_is_sub_partitioned &&
8695 m_part_info->list_of_subpart_fields)))
8698 if (m_is_sub_partitioned)
8700 field= m_part_info->subpart_field_array;
8704 field= m_part_info->part_field_array;
8706 for (; *field; field++)
8708 switch ((*field)->real_type()) {
8709 case MYSQL_TYPE_TINY:
8710 case MYSQL_TYPE_SHORT:
8711 case MYSQL_TYPE_LONG:
8712 case MYSQL_TYPE_FLOAT:
8713 case MYSQL_TYPE_DOUBLE:
8714 case MYSQL_TYPE_NEWDECIMAL:
8715 case MYSQL_TYPE_TIMESTAMP:
8716 case MYSQL_TYPE_LONGLONG:
8717 case MYSQL_TYPE_INT24:
8718 case MYSQL_TYPE_TIME:
8719 case MYSQL_TYPE_DATETIME:
8720 case MYSQL_TYPE_YEAR:
8721 case MYSQL_TYPE_NEWDATE:
8722 case MYSQL_TYPE_ENUM:
8723 case MYSQL_TYPE_SET:
8729 bool skip_generation=
false;
8730 partition_info::enum_key_algorithm old_algorithm;
8731 old_algorithm= m_part_info->key_algorithm;
8732 error= HA_ADMIN_FAILED;
8733 append_identifier(ha_thd(), &db_name, table_share->db.str,
8734 table_share->db.length);
8735 append_identifier(ha_thd(), &table_name, table_share->table_name.str,
8736 table_share->table_name.length);
8737 if (m_part_info->key_algorithm != partition_info::KEY_ALGORITHM_NONE)
8743 skip_generation=
true;
8745 m_part_info->key_algorithm= partition_info::KEY_ALGORITHM_51;
8746 if (skip_generation ||
8747 !(part_buf= generate_partition_syntax(m_part_info,
8754 print_admin_msg(thd, SQL_ADMIN_MSG_TEXT_SIZE + 1,
"error",
8755 table_share->db.str,
8757 opt_op_name[CHECK_PARTS],
8758 KEY_PARTITIONING_CHANGED_STR,
8759 db_name.c_ptr_safe(),
8760 table_name.c_ptr_safe(),
8764 print_admin_msg(thd, MI_MAX_MSG_BUF,
"error",
8765 table_share->db.str, table->alias,
8766 opt_op_name[CHECK_PARTS],
8767 KEY_PARTITIONING_CHANGED_STR,
8768 db_name.c_ptr_safe(), table_name.c_ptr_safe(),
8769 "<old partition clause>, but add ALGORITHM = 1"
8770 " between 'KEY' and '(' to change the metadata"
8771 " without the need of a full table rebuild.");
8773 m_part_info->key_algorithm= old_algorithm;
8788 { MYSQL_HANDLERTON_INTERFACE_VERSION };
8790 mysql_declare_plugin(partition)
8792 MYSQL_STORAGE_ENGINE_PLUGIN,
8793 &partition_storage_engine,
8795 "Mikael Ronstrom, MySQL AB",
8796 "Partition Storage Engine Helper",
8798 partition_initialize,
8806 mysql_declare_plugin_end;