summaryrefslogtreecommitdiff
path: root/storage/myisam
diff options
context:
space:
mode:
Diffstat (limited to 'storage/myisam')
-rw-r--r--storage/myisam/ft_boolean_search.c6
-rw-r--r--storage/myisam/ft_nlq_search.c4
-rw-r--r--storage/myisam/ft_parser.c5
-rw-r--r--storage/myisam/ft_stopwords.c3
-rw-r--r--storage/myisam/ha_myisam.cc167
-rw-r--r--storage/myisam/ha_myisam.h11
-rw-r--r--storage/myisam/mi_cache.c2
-rw-r--r--storage/myisam/mi_check.c57
-rw-r--r--storage/myisam/mi_checksum.c2
-rw-r--r--storage/myisam/mi_close.c9
-rw-r--r--storage/myisam/mi_create.c43
-rw-r--r--storage/myisam/mi_delete.c4
-rw-r--r--storage/myisam/mi_delete_table.c53
-rw-r--r--storage/myisam/mi_dynrec.c37
-rw-r--r--storage/myisam/mi_extra.c6
-rw-r--r--storage/myisam/mi_locking.c2
-rw-r--r--storage/myisam/mi_open.c51
-rw-r--r--storage/myisam/mi_packrec.c4
-rw-r--r--storage/myisam/mi_search.c4
-rw-r--r--storage/myisam/mi_static.c15
-rw-r--r--storage/myisam/mi_test1.c9
-rw-r--r--storage/myisam/mi_test2.c2
-rw-r--r--storage/myisam/mi_write.c10
-rw-r--r--storage/myisam/myisam_ftdump.c2
-rw-r--r--storage/myisam/myisamchk.c52
-rw-r--r--storage/myisam/myisamdef.h17
-rw-r--r--storage/myisam/myisamlog.c7
-rw-r--r--storage/myisam/myisampack.c14
-rw-r--r--storage/myisam/mysql-test/storage_engine/alter_table_online.rdiff71
-rw-r--r--storage/myisam/mysql-test/storage_engine/alter_tablespace.rdiff8
-rw-r--r--storage/myisam/mysql-test/storage_engine/foreign_keys.rdiff2
-rw-r--r--storage/myisam/mysql-test/storage_engine/misc.rdiff25
-rw-r--r--storage/myisam/rt_mbr.c24
-rw-r--r--storage/myisam/sort.c294
34 files changed, 652 insertions, 370 deletions
diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c
index 8b61e1dc4f2..6befe3b2d7a 100644
--- a/storage/myisam/ft_boolean_search.c
+++ b/storage/myisam/ft_boolean_search.c
@@ -533,7 +533,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
{
if (ftbe->flags & FTB_FLAG_NO || /* 2 */
ftbe->up->ythresh - ftbe->up->yweaks >
- (uint) test(ftbe->flags & FTB_FLAG_YES)) /* 1 */
+ (uint) MY_TEST(ftbe->flags & FTB_FLAG_YES)) /* 1 */
{
FTB_EXPR *top_ftbe=ftbe->up;
ftbw->docid[0]=HA_OFFSET_ERROR;
@@ -550,7 +550,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
/* 4 */
if (!is_tree_inited(& ftb->no_dupes))
init_tree(& ftb->no_dupes,0,0,sizeof(my_off_t),
- _ftb_no_dupes_cmp,0,0,0);
+ _ftb_no_dupes_cmp,0,0,MYF(0));
else
reset_tree(& ftb->no_dupes);
}
@@ -583,7 +583,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, uchar *query,
bzero(& ftb->no_dupes, sizeof(TREE));
ftb->last_word= 0;
- init_alloc_root(&ftb->mem_root, 1024, 1024);
+ init_alloc_root(&ftb->mem_root, 1024, 1024, MYF(0));
ftb->queue.max_elements= 0;
if (!(ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR))))
goto err;
diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c
index bafa7064e28..9524b6f1833 100644
--- a/storage/myisam/ft_nlq_search.c
+++ b/storage/myisam/ft_nlq_search.c
@@ -248,8 +248,8 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, uchar *query,
bzero(&wtree,sizeof(wtree));
- init_tree(&aio.dtree,0,0,sizeof(FT_SUPERDOC),(qsort_cmp2)&FT_SUPERDOC_cmp,0,
- NULL, NULL);
+ init_tree(&aio.dtree,0,0,sizeof(FT_SUPERDOC),(qsort_cmp2)&FT_SUPERDOC_cmp,
+ NULL, NULL, MYF(0));
ft_parse_init(&wtree, aio.charset);
ftparser_param->flags= 0;
diff --git a/storage/myisam/ft_parser.c b/storage/myisam/ft_parser.c
index c534a9a060b..0e89d7d1b3a 100644
--- a/storage/myisam/ft_parser.c
+++ b/storage/myisam/ft_parser.c
@@ -249,7 +249,8 @@ void ft_parse_init(TREE *wtree, CHARSET_INFO *cs)
{
DBUG_ENTER("ft_parse_init");
if (!is_tree_inited(wtree))
- init_tree(wtree,0,0,sizeof(FT_WORD),(qsort_cmp2)&FT_WORD_cmp,0,0,(void*)cs);
+ init_tree(wtree, 0, 0, sizeof(FT_WORD), (qsort_cmp2)&FT_WORD_cmp, 0,
+ (void*)cs, MYF(0));
DBUG_VOID_RETURN;
}
@@ -341,7 +342,7 @@ MYSQL_FTPARSER_PARAM* ftparser_alloc_param(MI_INFO *info)
info->ftparser_param= (MYSQL_FTPARSER_PARAM *)
my_malloc(MAX_PARAM_NR * sizeof(MYSQL_FTPARSER_PARAM) *
info->s->ftkeys, MYF(MY_WME | MY_ZEROFILL));
- init_alloc_root(&info->ft_memroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
+ init_alloc_root(&info->ft_memroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, MYF(0));
}
return info->ftparser_param;
}
diff --git a/storage/myisam/ft_stopwords.c b/storage/myisam/ft_stopwords.c
index a04985cd0b8..7b2d520a65a 100644
--- a/storage/myisam/ft_stopwords.c
+++ b/storage/myisam/ft_stopwords.c
@@ -61,9 +61,8 @@ int ft_init_stopwords()
if (!(stopwords3=(TREE *)my_malloc(sizeof(TREE),MYF(0))))
DBUG_RETURN(-1);
init_tree(stopwords3,0,0,sizeof(FT_STOPWORD),(qsort_cmp2)&FT_STOPWORD_cmp,
- 0,
(ft_stopword_file ? (tree_element_free)&FT_STOPWORD_free : 0),
- NULL);
+ NULL, MYF(0));
/*
Stopword engine currently does not support tricky
character sets UCS2, UTF16, UTF32.
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 04879f4b26c..bc4c5139810 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -79,7 +79,7 @@ static MYSQL_THDVAR_ULONG(repair_threads, PLUGIN_VAR_RQCMDARG,
static MYSQL_THDVAR_ULONGLONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG,
"The buffer that is allocated when sorting the index when doing "
"a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE", NULL, NULL,
- 8192 * 1024, MIN_SORT_BUFFER + MALLOC_OVERHEAD, SIZE_T_MAX, 1);
+ SORT_BUFFER_INIT, MIN_SORT_BUFFER, SIZE_T_MAX, 1);
static MYSQL_SYSVAR_BOOL(use_mmap, opt_myisam_use_mmap, PLUGIN_VAR_NOCMDARG,
"Use memory mapping for reading and writing MyISAM tables", NULL, NULL, FALSE);
@@ -141,6 +141,9 @@ static void mi_check_print_msg(HA_CHECK *param, const char* msg_type,
char msgbuf[MYSQL_ERRMSG_SIZE];
char name[NAME_LEN*2+2];
+ if (param->testflag & T_SUPPRESS_ERR_HANDLING)
+ return;
+
msg_length= my_vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
@@ -246,8 +249,8 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out,
pos->algorithm;
keydef[i].block_length= pos->block_size;
keydef[i].seg= keyseg;
- keydef[i].keysegs= pos->key_parts;
- for (j= 0; j < pos->key_parts; j++)
+ keydef[i].keysegs= pos->user_defined_key_parts;
+ for (j= 0; j < pos->user_defined_key_parts; j++)
{
Field *field= pos->key_part[j].field;
type= field->key_type();
@@ -299,7 +302,7 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out,
keydef[i].seg[j].flag|= HA_BLOB_PART;
/* save number of bytes used to pack length */
keydef[i].seg[j].bit_start= (uint) (field->pack_length() -
- share->blob_ptr_size);
+ portable_sizeof_char_ptr);
}
else if (field->type() == MYSQL_TYPE_BIT)
{
@@ -309,7 +312,7 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out,
(uchar*) table_arg->record[0]);
}
}
- keyseg+= pos->key_parts;
+ keyseg+= pos->user_defined_key_parts;
}
if (table_arg->found_next_number_field)
keydef[share->next_number_index].flag|= HA_AUTO_KEY;
@@ -353,12 +356,23 @@ int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out,
if (found->flags & BLOB_FLAG)
recinfo_pos->type= FIELD_BLOB;
- else if (found->type() == MYSQL_TYPE_TIMESTAMP)
+ else if (found->real_type() == MYSQL_TYPE_TIMESTAMP)
+ {
+ /* pre-MySQL-5.6.4 TIMESTAMP, or MariaDB-5.3+ TIMESTAMP */
recinfo_pos->type= FIELD_NORMAL;
+ }
else if (found->type() == MYSQL_TYPE_VARCHAR)
recinfo_pos->type= FIELD_VARCHAR;
else if (!(options & HA_OPTION_PACK_RECORD))
recinfo_pos->type= FIELD_NORMAL;
+ else if (found->real_type() == MYSQL_TYPE_TIMESTAMP2)
+ {
+ /*
+ MySQL-5.6.4+ erroneously marks Field_timestampf as FIELD_SKIP_PRESPACE,
+ but only if HA_OPTION_PACK_RECORD is set.
+ */
+ recinfo_pos->type= FIELD_SKIP_PRESPACE;
+ }
else if (found->zero_pack())
recinfo_pos->type= FIELD_SKIP_ZERO;
else
@@ -466,8 +480,8 @@ int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
{
DBUG_PRINT("error", ("Key %d has different definition", i));
DBUG_PRINT("error", ("t1_fulltext= %d, t2_fulltext=%d",
- test(t1_keyinfo[i].flag & HA_FULLTEXT),
- test(t2_keyinfo[i].flag & HA_FULLTEXT)));
+ MY_TEST(t1_keyinfo[i].flag & HA_FULLTEXT),
+ MY_TEST(t2_keyinfo[i].flag & HA_FULLTEXT)));
DBUG_RETURN(1);
}
if (t1_keyinfo[i].flag & HA_SPATIAL && t2_keyinfo[i].flag & HA_SPATIAL)
@@ -477,8 +491,8 @@ int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
{
DBUG_PRINT("error", ("Key %d has different definition", i));
DBUG_PRINT("error", ("t1_spatial= %d, t2_spatial=%d",
- test(t1_keyinfo[i].flag & HA_SPATIAL),
- test(t2_keyinfo[i].flag & HA_SPATIAL)));
+ MY_TEST(t1_keyinfo[i].flag & HA_SPATIAL),
+ MY_TEST(t2_keyinfo[i].flag & HA_SPATIAL)));
DBUG_RETURN(1);
}
if ((!mysql_40_compat &&
@@ -573,6 +587,8 @@ void mi_check_print_error(HA_CHECK *param, const char *fmt,...)
{
param->error_printed|=1;
param->out_flag|= O_DATA_LOST;
+ if (param->testflag & T_SUPPRESS_ERR_HANDLING)
+ return;
va_list args;
va_start(args, fmt);
mi_check_print_msg(param, "error", fmt, args);
@@ -631,8 +647,10 @@ void _mi_report_crashed(MI_INFO *file, const char *message,
for (element= file->s->in_use; element; element= list_rest(element))
{
THD *thd= (THD*) element->data;
- sql_print_error("%s", thd ? thd_security_context(thd, buf, sizeof(buf), 0)
- : "Unknown thread accessing table");
+ sql_print_error("%s",
+ thd ?
+ thd_get_error_context_description(thd, buf, sizeof(buf), 0)
+ : "Unknown thread accessing table");
}
mysql_mutex_unlock(&file->s->intern_lock);
}
@@ -650,7 +668,7 @@ ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
:handler(hton, table_arg), file(0),
int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
- HA_CAN_VIRTUAL_COLUMNS |
+ HA_CAN_VIRTUAL_COLUMNS | HA_CAN_EXPORT |
HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS |
HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS |
@@ -674,12 +692,6 @@ static const char *ha_myisam_exts[] = {
NullS
};
-const char **ha_myisam::bas_ext() const
-{
- return ha_myisam_exts;
-}
-
-
const char *ha_myisam::index_type(uint key_number)
{
return ((table->key_info[key_number].flags & HA_FULLTEXT) ?
@@ -835,10 +847,6 @@ int ha_myisam::close(void)
int ha_myisam::write_row(uchar *buf)
{
- /* If we have a timestamp column, update it to the current time */
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
-
/*
If we have an auto_increment column and we are writing a changed row
or a new row, then update the auto_increment value in the record.
@@ -905,7 +913,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
my_default_record_cache_size, READ_CACHE,
share->pack.header_length, 1, MYF(MY_WME))))
{
- error= chk_data_link(&param, file, test(param.testflag & T_EXTEND));
+ error= chk_data_link(&param, file, MY_TEST(param.testflag & T_EXTEND));
end_io_cache(&(param.read_cache));
}
param.testflag= old_testflag;
@@ -1077,6 +1085,7 @@ int ha_myisam::repair(THD *thd, HA_CHECK &param, bool do_optimize)
param.thd= thd;
param.tmpdir= &mysql_tmpdir_list;
param.out_flag= 0;
+ share->state.dupp_key= MI_MAX_KEY;
strmov(fixed_name,file->filename);
// Release latches since this can take a long time
@@ -1100,7 +1109,7 @@ int ha_myisam::repair(THD *thd, HA_CHECK &param, bool do_optimize)
share->state.key_map);
ulonglong testflag= param.testflag;
#ifdef HAVE_MMAP
- bool remap= test(share->file_map);
+ bool remap= MY_TEST(share->file_map);
/*
mi_repair*() functions family use file I/O even if memory
mapping is available.
@@ -1122,22 +1131,26 @@ int ha_myisam::repair(THD *thd, HA_CHECK &param, bool do_optimize)
/* TODO: respect myisam_repair_threads variable */
thd_proc_info(thd, "Parallel repair");
error = mi_repair_parallel(&param, file, fixed_name,
- test(param.testflag & T_QUICK));
+ MY_TEST(param.testflag & T_QUICK));
}
else
{
thd_proc_info(thd, "Repair by sorting");
+ DEBUG_SYNC(thd, "myisam_before_repair_by_sort");
error = mi_repair_by_sort(&param, file, fixed_name,
- test(param.testflag & T_QUICK));
- DEBUG_SYNC(thd, "myisam_after_repair_by_sort");
+ MY_TEST(param.testflag & T_QUICK));
}
+ if (error && file->create_unique_index_by_sort &&
+ share->state.dupp_key != MAX_KEY)
+ print_keydup_error(table, &table->key_info[share->state.dupp_key],
+ MYF(0));
}
else
{
thd_proc_info(thd, "Repair with keycache");
param.testflag &= ~T_REP_BY_SORT;
error= mi_repair(&param, file, fixed_name,
- test(param.testflag & T_QUICK));
+ MY_TEST(param.testflag & T_QUICK));
}
param.testflag= testflag | (param.testflag & T_RETRY_WITHOUT_QUICK);
#ifdef HAVE_MMAP
@@ -1438,6 +1451,8 @@ int ha_myisam::enable_indexes(uint mode)
param.op_name= "recreating_index";
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
T_CREATE_MISSING_KEYS);
+ if (file->create_unique_index_by_sort)
+ param.testflag|= T_CREATE_UNIQUE_BY_SORT;
param.myf_rw&= ~MY_WAIT_IF_FULL;
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
param.stats_method= (enum_handler_stats_method)THDVAR(thd, stats_method);
@@ -1505,20 +1520,21 @@ int ha_myisam::indexes_are_disabled(void)
activate special bulk-insert optimizations
SYNOPSIS
- start_bulk_insert(rows)
+ start_bulk_insert(rows, flags)
rows Rows to be inserted
0 if we don't know
+ flags Flags to control index creation
NOTICE
Do not forget to call end_bulk_insert() later!
*/
-void ha_myisam::start_bulk_insert(ha_rows rows)
+void ha_myisam::start_bulk_insert(ha_rows rows, uint flags)
{
DBUG_ENTER("ha_myisam::start_bulk_insert");
THD *thd= current_thd;
- ulong size= min(thd->variables.read_buff_size,
- (ulong) (table->s->avg_row_length*rows));
+ ulong size= MY_MIN(thd->variables.read_buff_size,
+ (ulong) (table->s->avg_row_length*rows));
DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
(ulong) rows, size));
@@ -1529,34 +1545,34 @@ void ha_myisam::start_bulk_insert(ha_rows rows)
can_enable_indexes= mi_is_all_keys_active(file->s->state.key_map,
file->s->base.keys);
- if (!(specialflag & SPECIAL_SAFE_MODE))
+ /*
+ Only disable old index if the table was empty and we are inserting
+ a lot of rows.
+ Note that in end_bulk_insert() we may truncate the table if
+ enable_indexes() failed, thus it's essential that indexes are
+ disabled ONLY for an empty table.
+ */
+ if (file->state->records == 0 && can_enable_indexes &&
+ (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
{
- /*
- Only disable old index if the table was empty and we are inserting
- a lot of rows.
- Note that in end_bulk_insert() we may truncate the table if
- enable_indexes() failed, thus it's essential that indexes are
- disabled ONLY for an empty table.
- */
- if (file->state->records == 0 && can_enable_indexes &&
- (!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES))
+ if (file->open_flag & HA_OPEN_INTERNAL_TABLE)
{
- if (file->open_flag & HA_OPEN_INTERNAL_TABLE)
- {
- file->update|= HA_STATE_CHANGED;
- mi_clear_all_keys_active(file->s->state.key_map);
- }
- else
- mi_disable_non_unique_index(file,rows);
+ file->update|= HA_STATE_CHANGED;
+ mi_clear_all_keys_active(file->s->state.key_map);
}
else
+ {
+ my_bool all_keys= MY_TEST(flags & HA_CREATE_UNIQUE_INDEX_BY_SORT);
+ mi_disable_indexes_for_rebuild(file, rows, all_keys);
+ }
+ }
+ else
if (!file->bulk_insert &&
(!rows || rows >= MI_MIN_ROWS_TO_USE_BULK_INSERT))
{
mi_init_bulk_insert(file, (size_t) thd->variables.bulk_insert_buff_size,
rows);
}
- }
DBUG_VOID_RETURN;
}
@@ -1657,8 +1673,6 @@ bool ha_myisam::is_crashed() const
int ha_myisam::update_row(const uchar *old_data, uchar *new_data)
{
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
- table->timestamp_field->set_time();
return mi_update(file,old_data,new_data);
}
@@ -1836,15 +1850,14 @@ int ha_myisam::info(uint flag)
number of records in the buffer results in a different number of buffer
refills and in a different order of records in the result set.
*/
- stats.mrr_length_per_rec= misam_info.reflength + 8; // 8=max(sizeof(void *))
+ stats.mrr_length_per_rec= misam_info.reflength + 8; // 8=MY_MAX(sizeof(void *))
ref_length= misam_info.reflength;
share->db_options_in_use= misam_info.options;
stats.block_size= myisam_block_size; /* record block size */
- /* Update share */
- if (share->tmp_table == NO_TMP_TABLE)
- mysql_mutex_lock(&share->LOCK_ha_data);
+ if (table_share->tmp_table == NO_TMP_TABLE)
+ mysql_mutex_lock(&table_share->LOCK_share);
share->keys_in_use.set_prefix(share->keys);
share->keys_in_use.intersect_extended(misam_info.key_map);
share->keys_for_keyread.intersect(share->keys_in_use);
@@ -1853,8 +1866,8 @@ int ha_myisam::info(uint flag)
memcpy((char*) table->key_info[0].rec_per_key,
(char*) misam_info.rec_per_key,
sizeof(table->key_info[0].rec_per_key[0])*share->key_parts);
- if (share->tmp_table == NO_TMP_TABLE)
- mysql_mutex_unlock(&share->LOCK_ha_data);
+ if (table_share->tmp_table == NO_TMP_TABLE)
+ mysql_mutex_unlock(&table_share->LOCK_share);
/*
Set data_file_name and index_file_name to point at the symlink value
@@ -1886,8 +1899,6 @@ int ha_myisam::info(uint flag)
int ha_myisam::extra(enum ha_extra_function operation)
{
- if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_KEYREAD)
- return 0;
if (operation == HA_EXTRA_MMAP && !opt_myisam_use_mmap)
return 0;
return mi_extra(file, operation, 0);
@@ -1905,8 +1916,6 @@ int ha_myisam::reset(void)
int ha_myisam::extra_opt(enum ha_extra_function operation, ulong cache_size)
{
- if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_WRITE_CACHE)
- return 0;
return mi_extra(file, operation, (void*) &cache_size);
}
@@ -1997,12 +2006,29 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
(ulonglong) 0);
create_info.data_file_length= ((ulonglong) share->max_rows *
share->avg_row_length);
- create_info.data_file_name= ha_create_info->data_file_name;
- create_info.index_file_name= ha_create_info->index_file_name;
create_info.language= share->table_charset->number;
- if (ha_create_info->options & HA_LEX_CREATE_TMP_TABLE)
- create_flags|= HA_CREATE_TMP_TABLE;
+#ifdef HAVE_READLINK
+ if (my_use_symdir)
+ {
+ create_info.data_file_name= ha_create_info->data_file_name;
+ create_info.index_file_name= ha_create_info->index_file_name;
+ }
+ else
+#endif /* HAVE_READLINK */
+ {
+ if (ha_create_info->data_file_name)
+ push_warning_printf(table_arg->in_use, Sql_condition::WARN_LEVEL_WARN,
+ WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
+ "DATA DIRECTORY");
+ if (ha_create_info->index_file_name)
+ push_warning_printf(table_arg->in_use, Sql_condition::WARN_LEVEL_WARN,
+ WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
+ "INDEX DIRECTORY");
+ }
+
+ if (ha_create_info->tmp_table())
+ create_flags|= HA_CREATE_TMP_TABLE | HA_CREATE_DELAY_KEY_WRITE;
if (ha_create_info->options & HA_CREATE_KEEP_FILES)
create_flags|= HA_CREATE_KEEP_FILES;
if (options & HA_OPTION_PACK_RECORD)
@@ -2200,6 +2226,7 @@ static int myisam_init(void *p)
myisam_hton->create= myisam_create_handler;
myisam_hton->panic= myisam_panic;
myisam_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
+ myisam_hton->tablefile_extensions= ha_myisam_exts;
mi_killed= mi_killed_in_mariadb;
return 0;
@@ -2237,7 +2264,7 @@ int ha_myisam::multi_range_read_next(range_id_t *range_info)
ha_rows ha_myisam::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
void *seq_init_param,
uint n_ranges, uint *bufsz,
- uint *flags, COST_VECT *cost)
+ uint *flags, Cost_estimate *cost)
{
/*
This call is here because there is no location where this->table would
@@ -2251,7 +2278,7 @@ ha_rows ha_myisam::multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
ha_rows ha_myisam::multi_range_read_info(uint keyno, uint n_ranges, uint keys,
uint key_parts, uint *bufsz,
- uint *flags, COST_VECT *cost)
+ uint *flags, Cost_estimate *cost)
{
ds_mrr.init(this, table);
return ds_mrr.dsmrr_info(keyno, n_ranges, keys, key_parts, bufsz, flags, cost);
@@ -2281,7 +2308,7 @@ Item *ha_myisam::idx_cond_push(uint keyno_arg, Item* idx_cond_arg)
*/
const KEY *key= &table_share->key_info[keyno_arg];
- for (uint k= 0; k < key->key_parts; ++k)
+ for (uint k= 0; k < key->user_defined_key_parts; ++k)
{
const KEY_PART_INFO *key_part= &key->key_part[k];
if (key_part->key_part_flag & HA_BLOB_PART)
diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h
index 79324f64370..63fb0ea5a2a 100644
--- a/storage/myisam/ha_myisam.h
+++ b/storage/myisam/ha_myisam.h
@@ -26,9 +26,6 @@
#include "handler.h" /* handler */
#include "table.h" /* TABLE_SHARE */
-struct TABLE_SHARE;
-typedef struct st_ha_create_information HA_CREATE_INFO;
-
#define HA_RECOVER_DEFAULT 1 /* Automatic recover active */
#define HA_RECOVER_BACKUP 2 /* Make a backupfile on recover */
#define HA_RECOVER_FORCE 4 /* Recover even if we loose rows */
@@ -56,9 +53,7 @@ class ha_myisam: public handler
ha_myisam(handlerton *hton, TABLE_SHARE *table_arg);
~ha_myisam() {}
handler *clone(const char *name, MEM_ROOT *mem_root);
- const char *table_type() const { return "MyISAM"; }
const char *index_type(uint key_number);
- const char **bas_ext() const;
ulonglong table_flags() const { return int_table_flags; }
int index_init(uint idx, bool sorted);
int index_end();
@@ -116,7 +111,7 @@ class ha_myisam: public handler
int disable_indexes(uint mode);
int enable_indexes(uint mode);
int indexes_are_disabled(void);
- void start_bulk_insert(ha_rows rows);
+ void start_bulk_insert(ha_rows rows, uint flags);
int end_bulk_insert();
ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
void update_create_info(HA_CREATE_INFO *create_info);
@@ -165,10 +160,10 @@ public:
ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
void *seq_init_param,
uint n_ranges, uint *bufsz,
- uint *flags, COST_VECT *cost);
+ uint *flags, Cost_estimate *cost);
ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
uint key_parts, uint *bufsz,
- uint *flags, COST_VECT *cost);
+ uint *flags, Cost_estimate *cost);
int multi_range_read_explain_info(uint mrr_mode, char *str, size_t size);
/* Index condition pushdown implementation */
diff --git a/storage/myisam/mi_cache.c b/storage/myisam/mi_cache.c
index 6e9feaefb2d..3477e67eae5 100644
--- a/storage/myisam/mi_cache.c
+++ b/storage/myisam/mi_cache.c
@@ -62,7 +62,7 @@ int _mi_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length,
(my_off_t) (info->read_end - info->request_pos))
{
in_buff_pos=info->request_pos+(uint) offset;
- in_buff_length= min(length, (size_t) (info->read_end-in_buff_pos));
+ in_buff_length= MY_MIN(length, (size_t) (info->read_end-in_buff_pos));
memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
if (!(length-=in_buff_length))
DBUG_RETURN(0);
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index 73558ce77b3..3a2bdb2e899 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -90,7 +90,7 @@ void myisamchk_init(HA_CHECK *param)
param->opt_follow_links=1;
param->keys_in_use= ~(ulonglong) 0;
param->search_after_block=HA_OFFSET_ERROR;
- param->use_buffers=USE_BUFFER_INIT;
+ param->use_buffers= KEY_BUFFER_INIT;
param->read_buffer_length=READ_BUFFER_INIT;
param->write_buffer_length=READ_BUFFER_INIT;
param->sort_buffer_length=SORT_BUFFER_INIT;
@@ -1146,7 +1146,7 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend)
if (param->testflag & (T_EXTEND | T_MEDIUM | T_VERBOSE))
{
if (_mi_rec_check(info,record, info->rec_buff,block_info.rec_len,
- test(info->s->calc_checksum)))
+ MY_TEST(info->s->calc_checksum)))
{
mi_check_print_error(param,"Found wrong packed record at %s",
llstr(start_recpos,llbuff));
@@ -1945,7 +1945,13 @@ int mi_sort_index(HA_CHECK *param, register MI_INFO *info, char * name)
key++,keyinfo++)
{
if (! mi_is_key_active(info->s->state.key_map, key))
+ {
+ /* Since the key is not active, this should not be read, but we
+ initialize it anyway to silence a Valgrind warn when passing that
+ chunk of memory to pwrite(). */
+ index_pos[key]= HA_OFFSET_ERROR;
continue;
+ }
if (share->state.key_root[key] != HA_OFFSET_ERROR)
{
@@ -2144,7 +2150,7 @@ int filecopy(HA_CHECK *param, File to,File from,my_off_t start,
ulong buff_length;
DBUG_ENTER("filecopy");
- buff_length=(ulong) min(param->write_buffer_length,length);
+ buff_length=(ulong) MY_MIN(param->write_buffer_length,length);
if (!(buff=my_malloc(buff_length,MYF(0))))
{
buff=tmp_buff; buff_length=IO_SIZE;
@@ -2298,10 +2304,11 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
mysql_file_seek(param->read_cache.file, 0L, MY_SEEK_END, MYF(0));
sort_param.wordlist=NULL;
- init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
+ init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0,
+ MYF(param->malloc_flags));
if (share->data_file_type == DYNAMIC_RECORD)
- length=max(share->base.min_pack_length+1,share->base.min_block_length);
+ length=MY_MAX(share->base.min_pack_length+1,share->base.min_block_length);
else if (share->data_file_type == COMPRESSED_RECORD)
length=share->base.min_block_length;
else
@@ -2356,7 +2363,7 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
if (keyseg[i].flag & HA_SPACE_PACK)
sort_param.key_length+=get_pack_length(keyseg[i].length);
if (keyseg[i].flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART))
- sort_param.key_length+=2 + test(keyseg[i].length >= 127);
+ sort_param.key_length+= 2 + MY_TEST(keyseg[i].length >= 127);
if (keyseg[i].flag & HA_NULL_PART)
sort_param.key_length++;
}
@@ -2390,7 +2397,7 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
(see _create_index_by_sort)
*/
sort_info.max_records= 10 *
- max(param->sort_buffer_length, MIN_SORT_BUFFER) /
+ MY_MAX(param->sort_buffer_length, MIN_SORT_BUFFER) /
sort_param.key_length;
}
@@ -2407,7 +2414,10 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
(my_bool) (!(param->testflag & T_VERBOSE)),
param->sort_buffer_length))
{
- param->retry_repair= 1;
+ if ((param->testflag & T_CREATE_UNIQUE_BY_SORT) && sort_param.sort_info->dupp)
+ share->state.dupp_key= sort_param.key;
+ else
+ param->retry_repair= 1;
if (! param->error_printed)
mi_check_print_error(param, "Couldn't fix table with create_index_by_sort(). Error: %d",
my_errno);
@@ -2755,7 +2765,7 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info,
mysql_file_seek(param->read_cache.file, 0L, MY_SEEK_END, MYF(0));
if (share->data_file_type == DYNAMIC_RECORD)
- rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
+ rec_length=MY_MAX(share->base.min_pack_length+1,share->base.min_block_length);
else if (share->data_file_type == COMPRESSED_RECORD)
rec_length=share->base.min_block_length;
else
@@ -2855,7 +2865,7 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info,
if (keyseg->flag & HA_SPACE_PACK)
sort_param[i].key_length+=get_pack_length(keyseg->length);
if (keyseg->flag & (HA_BLOB_PART | HA_VAR_LENGTH_PART))
- sort_param[i].key_length+=2 + test(keyseg->length >= 127);
+ sort_param[i].key_length+= 2 + MY_TEST(keyseg->length >= 127);
if (keyseg->flag & HA_NULL_PART)
sort_param[i].key_length++;
}
@@ -2866,13 +2876,14 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info,
uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT*
sort_param[i].keyinfo->seg->charset->mbmaxlen;
sort_param[i].key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN;
- init_alloc_root(&sort_param[i].wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
+ init_alloc_root(&sort_param[i].wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0,
+ MYF(param->malloc_flags));
}
}
sort_info.total_keys=i;
sort_param[0].master= 1;
sort_param[0].fix_datafile= (my_bool)(! rep_quick);
- sort_param[0].calc_checksum= test(param->testflag & T_CALC_CHECKSUM);
+ sort_param[0].calc_checksum= MY_TEST(param->testflag & T_CALC_CHECKSUM);
if (!ftparser_alloc_param(info))
goto err;
@@ -3561,7 +3572,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
sort_param->find_length,
(param->testflag & T_QUICK) &&
sort_param->calc_checksum &&
- test(info->s->calc_checksum)))
+ MY_TEST(info->s->calc_checksum)))
{
mi_check_print_info(param,"Found wrong packed record at %s",
llstr(sort_param->start_recpos,llbuff));
@@ -3722,7 +3733,7 @@ int sort_write_record(MI_SORT_PARAM *sort_param)
do
{
- block_length=reclength+ 3 + test(reclength >= (65520-3));
+ block_length= reclength + 3 + MY_TEST(reclength >= (65520 - 3));
if (block_length < share->base.min_block_length)
block_length=share->base.min_block_length;
info->update|=HA_STATE_WRITE_AT_END;
@@ -3830,6 +3841,9 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
sort_info->info->lastpos=get_record_for_key(sort_info->info,
sort_param->keyinfo,
(uchar*) a);
+ if ((param->testflag & (T_CREATE_UNIQUE_BY_SORT | T_SUPPRESS_ERR_HANDLING))
+ == T_CREATE_UNIQUE_BY_SORT)
+ param->testflag|= T_SUPPRESS_ERR_HANDLING;
mi_check_print_warning(param,
"Duplicate key for record at %10s against record at %10s",
llstr(sort_info->info->lastpos,llbuff),
@@ -3977,7 +3991,7 @@ word_init_ft_buf:
ft_buf->buf=ft_buf->lastkey+a_len;
/*
32 is just a safety margin here
- (at least max(val_len, sizeof(nod_flag)) should be there).
+ (at least MY_MAX(val_len, sizeof(nod_flag)) should be there).
May be better performance could be achieved if we'd put
(sort_info->keyinfo->block_length-32)/XXX
instead.
@@ -4646,7 +4660,7 @@ static ha_checksum mi_byte_checksum(const uchar *buf, uint length)
const uchar *end=buf+length;
for (crc=0; buf != end; buf++)
crc=((crc << 1) + *((uchar*) buf)) +
- test(crc & (((ha_checksum) 1) << (8*sizeof(ha_checksum)-1)));
+ MY_TEST(crc & (((ha_checksum) 1) << (8 * sizeof(ha_checksum) - 1)));
return crc;
}
@@ -4665,7 +4679,7 @@ static my_bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows)
}
/*
- Deactivate all not unique index that can be recreated fast
+ Deactivate all indexes that can be recreated fast.
These include packed keys on which sorting will use more temporary
space than the max allowed file length or for which the unpacked keys
will take much more space than packed keys.
@@ -4673,7 +4687,8 @@ static my_bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows)
rows we will put into the file.
*/
-void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows)
+void mi_disable_indexes_for_rebuild(MI_INFO *info, ha_rows rows,
+ my_bool all_keys)
{
MYISAM_SHARE *share=info->s;
MI_KEYDEF *key=share->keyinfo;
@@ -4683,11 +4698,13 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows)
(!rows || rows >= MI_MIN_ROWS_TO_DISABLE_INDEXES));
for (i=0 ; i < share->base.keys ; i++,key++)
{
- if (!(key->flag & (HA_NOSAME | HA_SPATIAL | HA_AUTO_KEY)) &&
- ! mi_too_big_key_for_sort(key,rows) && info->s->base.auto_key != i+1)
+ if (!(key->flag & (HA_SPATIAL | HA_AUTO_KEY)) &&
+ ! mi_too_big_key_for_sort(key,rows) && info->s->base.auto_key != i+1 &&
+ (all_keys || !(key->flag & HA_NOSAME)))
{
mi_clear_key_active(share->state.key_map, i);
info->update|= HA_STATE_CHANGED;
+ info->create_unique_index_by_sort= all_keys;
}
}
}
diff --git a/storage/myisam/mi_checksum.c b/storage/myisam/mi_checksum.c
index ec8b51fce7b..baee85566c2 100644
--- a/storage/myisam/mi_checksum.c
+++ b/storage/myisam/mi_checksum.c
@@ -23,7 +23,7 @@ ha_checksum mi_checksum(MI_INFO *info, const uchar *buf)
const uchar *record= buf;
MI_COLUMNDEF *column= info->s->rec;
MI_COLUMNDEF *column_end= column+ info->s->base.fields;
- my_bool skip_null_bits= test(info->s->options & HA_OPTION_NULL_FIELDS);
+ my_bool skip_null_bits= MY_TEST(info->s->options & HA_OPTION_NULL_FIELDS);
for ( ; column != column_end ; buf+= column++->length)
{
diff --git a/storage/myisam/mi_close.c b/storage/myisam/mi_close.c
index e58c2e0f189..f0a82bcef04 100644
--- a/storage/myisam/mi_close.c
+++ b/storage/myisam/mi_close.c
@@ -31,7 +31,8 @@ int mi_close(register MI_INFO *info)
(long) info, (uint) share->reopen,
(uint) share->tot_locks));
- mysql_mutex_lock(&THR_LOCK_myisam);
+ if (info->open_list.data)
+ mysql_mutex_lock(&THR_LOCK_myisam);
if (info->lock_type == F_EXTRA_LCK)
info->lock_type=F_UNLCK; /* HA_EXTRA_NO_USER_CHANGE */
@@ -54,7 +55,8 @@ int mi_close(register MI_INFO *info)
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
}
flag= !--share->reopen;
- myisam_open_list=list_delete(myisam_open_list,&info->open_list);
+ if (info->open_list.data)
+ myisam_open_list= list_delete(myisam_open_list, &info->open_list);
mysql_mutex_unlock(&share->intern_lock);
my_free(mi_get_rec_buff_ptr(info, info->rec_buff));
@@ -111,7 +113,8 @@ int mi_close(register MI_INFO *info)
}
my_free(info->s);
}
- mysql_mutex_unlock(&THR_LOCK_myisam);
+ if (info->open_list.data)
+ mysql_mutex_unlock(&THR_LOCK_myisam);
if (info->ftparser_param)
{
my_free(info->ftparser_param);
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index d4cc31368dd..88b9da6f8a9 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -1,5 +1,6 @@
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates
+ Copyright (c) 2009, 2013, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -43,6 +44,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
base_pos,long_varchar_count,varchar_length,
max_key_block_length,unique_key_parts,fulltext_keys,offset;
uint aligned_key_start, block_length, res;
+ uint internal_table= flags & HA_CREATE_INTERNAL_TABLE;
ulong reclength, real_reclength,min_pack_length;
char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
ulong pack_reclength;
@@ -136,7 +138,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
pack_reclength++;
min_pack_length++;
/* We must test for 257 as length includes pack-length */
- if (test(rec->length >= 257))
+ if (MY_TEST(rec->length >= 257))
{
long_varchar_count++;
pack_reclength+= 2; /* May be packed on 3 bytes */
@@ -203,7 +205,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
pack_bytes= (packed+7)/8;
if (pack_reclength != INT_MAX32)
pack_reclength+= reclength+packed +
- test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_OPTION_PACK_RECORD));
+ MY_TEST(test_all_bits(options, HA_OPTION_CHECKSUM |
+ HA_OPTION_PACK_RECORD));
min_pack_length+= pack_bytes;
if (!ci->data_file_length && ci->max_rows)
@@ -446,8 +449,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
block_length= (keydef->block_length ?
my_round_up_to_next_power(keydef->block_length) :
myisam_block_size);
- block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
- block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
+ block_length= MY_MAX(block_length, MI_MIN_KEY_BLOCK_LENGTH);
+ block_length= MY_MIN(block_length, MI_MAX_KEY_BLOCK_LENGTH);
keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
pointer,MI_MAX_KEYPTR_SIZE,
@@ -473,7 +476,6 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
key_del[i]=HA_OFFSET_ERROR;
unique_key_parts=0;
- offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH;
for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++)
{
uniquedef->key=keys+i;
@@ -537,7 +539,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
got from MYI file header (see also myisampack.c:save_state)
*/
share.base.key_reflength=
- mi_get_pointer_length(max(ci->key_file_length,tmp),3);
+ mi_get_pointer_length(MY_MAX(ci->key_file_length,tmp),3);
share.base.keys= share.state.header.keys= keys;
share.state.header.uniques= uniques;
share.state.header.fulltext_keys= fulltext_keys;
@@ -556,7 +558,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.base.records=ci->max_rows;
share.base.reloc= ci->reloc_rows;
share.base.reclength=real_reclength;
- share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);
+ share.base.pack_reclength= reclength + MY_TEST(options & HA_OPTION_CHECKSUM);
share.base.max_pack_length=pack_reclength;
share.base.min_pack_length=min_pack_length;
share.base.pack_bits= pack_bytes;
@@ -570,12 +572,13 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.base.min_block_length=
(share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
! share.base.blobs) ?
- max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
+ MY_MAX(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
MI_EXTEND_BLOCK_LENGTH;
if (! (flags & HA_DONT_TOUCH_DATA))
share.state.create_time= time((time_t*) 0);
- mysql_mutex_lock(&THR_LOCK_myisam);
+ if (!internal_table)
+ mysql_mutex_lock(&THR_LOCK_myisam);
/*
NOTE: For test_if_reopen() we need a real path name. Hence we need
@@ -632,7 +635,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
NOTE: The filename is compared against unique_file_name of every
open table. Hence we need a real path here.
*/
- if (test_if_reopen(filename))
+ if (!internal_table && test_if_reopen(filename))
{
my_printf_error(HA_ERR_TABLE_EXIST, "MyISAM table '%s' is in use "
"(most likely by a MERGE table). Try FLUSH TABLES.",
@@ -739,7 +742,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
#endif
}
/* Create extra keys for unique definitions */
- offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH;
+ offset= real_reclength - uniques * MI_UNIQUE_HASH_LENGTH;
bzero((char*) &tmp_keydef,sizeof(tmp_keydef));
bzero((char*) &tmp_keyseg,sizeof(tmp_keyseg));
for (i=0; i < uniques ; i++)
@@ -821,7 +824,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
goto err;
}
errpos=0;
- mysql_mutex_unlock(&THR_LOCK_myisam);
+ if (!internal_table)
+ mysql_mutex_unlock(&THR_LOCK_myisam);
res= 0;
if (mysql_file_close(file, MYF(0)))
res= my_errno;
@@ -829,7 +833,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
DBUG_RETURN(res);
err:
- mysql_mutex_unlock(&THR_LOCK_myisam);
+ if (!internal_table)
+ mysql_mutex_unlock(&THR_LOCK_myisam);
err_no_lock:
save_errno=my_errno;
@@ -863,19 +868,19 @@ uint mi_get_pointer_length(ulonglong file_length, uint def)
if (file_length) /* If not default */
{
#ifdef NOT_YET_READY_FOR_8_BYTE_POINTERS
- if (file_length >= ULL(1) << 56)
+ if (file_length >= 1ULL << 56)
def=8;
else
#endif
- if (file_length >= ULL(1) << 48)
+ if (file_length >= 1ULL << 48)
def=7;
- else if (file_length >= ULL(1) << 40)
+ else if (file_length >= 1ULL << 40)
def=6;
- else if (file_length >= ULL(1) << 32)
+ else if (file_length >= 1ULL << 32)
def=5;
- else if (file_length >= ULL(1) << 24)
+ else if (file_length >= 1ULL << 24)
def=4;
- else if (file_length >= ULL(1) << 16)
+ else if (file_length >= 1ULL << 16)
def=3;
else
def=2;
diff --git a/storage/myisam/mi_delete.c b/storage/myisam/mi_delete.c
index 907d8e291f6..3fffa55341b 100644
--- a/storage/myisam/mi_delete.c
+++ b/storage/myisam/mi_delete.c
@@ -353,8 +353,8 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
DBUG_RETURN(-1);
}
/* Page will be update later if we return 1 */
- DBUG_RETURN(test(length <= (info->quick_mode ? MI_MIN_KEYBLOCK_LENGTH :
- (uint) keyinfo->underflow_block_length)));
+ DBUG_RETURN(MY_TEST(length <= (info->quick_mode ? MI_MIN_KEYBLOCK_LENGTH :
+ (uint) keyinfo->underflow_block_length)));
}
save_flag=1;
ret_value=del(info,keyinfo,key,anc_buff,leaf_page,leaf_buff,keypos,
diff --git a/storage/myisam/mi_delete_table.c b/storage/myisam/mi_delete_table.c
index 885990ee1be..7f351bb35a6 100644
--- a/storage/myisam/mi_delete_table.c
+++ b/storage/myisam/mi_delete_table.c
@@ -20,44 +20,47 @@
#include "fulltext.h"
-int mi_delete_table(const char *name)
+static int delete_one_file(const char *name, const char *ext,
+ PSI_file_key pskey, myf flags)
{
char from[FN_REFLEN];
- DBUG_ENTER("mi_delete_table");
-
-#ifdef EXTRA_DEBUG
- check_table_is_closed(name,"delete");
-#endif
-
- fn_format(from,name,"",MI_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
+ DBUG_ENTER("delete_one_file");
+ fn_format(from,name, "", ext, MY_UNPACK_FILENAME | MY_APPEND_EXT);
if (my_is_symlink(from) && (*myisam_test_invalid_symlink)(from))
{
/*
Symlink is pointing to file in data directory.
Remove symlink, keep file.
*/
- if (mysql_file_delete(mi_key_file_kfile, from, MYF(MY_WME)))
+ if (mysql_file_delete(pskey, from, flags))
DBUG_RETURN(my_errno);
}
else
{
- if (mysql_file_delete_with_symlink(mi_key_file_kfile, from, MYF(MY_WME)))
- DBUG_RETURN(my_errno);
- }
- fn_format(from,name,"",MI_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
- if (my_is_symlink(from) && (*myisam_test_invalid_symlink)(from))
- {
- /*
- Symlink is pointing to file in data directory.
- Remove symlink, keep file.
- */
- if (mysql_file_delete(mi_key_file_dfile, from, MYF(MY_WME)))
- DBUG_RETURN(my_errno);
- }
- else
- {
- if (mysql_file_delete_with_symlink(mi_key_file_dfile, from, MYF(MY_WME)))
+ if (mysql_file_delete_with_symlink(pskey, from, flags))
DBUG_RETURN(my_errno);
}
DBUG_RETURN(0);
}
+
+int mi_delete_table(const char *name)
+{
+ int res;
+ DBUG_ENTER("mi_delete_table");
+
+#ifdef EXTRA_DEBUG
+ check_table_is_closed(name,"delete");
+#endif
+
+ if ((res= delete_one_file(name, MI_NAME_IEXT, mi_key_file_kfile, MYF(MY_WME))))
+ DBUG_RETURN(res);
+ if ((res= delete_one_file(name, MI_NAME_DEXT, mi_key_file_dfile, MYF(MY_WME))))
+ DBUG_RETURN(res);
+
+ // optionally present:
+ delete_one_file(name, ".OLD", mi_key_file_dfile, MYF(0));
+ delete_one_file(name, ".TMD", mi_key_file_dfile, MYF(0));
+
+ DBUG_RETURN(0);
+}
+
diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c
index 009a2affe0c..5241d72014c 100644
--- a/storage/myisam/mi_dynrec.c
+++ b/storage/myisam/mi_dynrec.c
@@ -118,7 +118,8 @@ int mi_munmap_file(MI_INFO *info)
{
int ret;
DBUG_ENTER("mi_unmap_file");
- if ((ret= my_munmap(info->s->file_map, (size_t) info->s->mmaped_length)))
+ if ((ret= my_munmap((void*) info->s->file_map,
+ (size_t) info->s->mmaped_length)))
DBUG_RETURN(ret);
info->s->file_read= mi_nommap_pread;
info->s->file_write= mi_nommap_pwrite;
@@ -415,7 +416,7 @@ static int _mi_find_writepos(MI_INFO *info,
{
/* No deleted blocks; Allocate a new block */
*filepos=info->state->data_file_length;
- if ((tmp=reclength+3 + test(reclength >= (65520-3))) <
+ if ((tmp= reclength + 3 + MY_TEST(reclength >= (65520 - 3))) <
info->s->base.min_block_length)
tmp= info->s->base.min_block_length;
else
@@ -863,9 +864,9 @@ static int update_dynamic_record(MI_INFO *info, my_off_t filepos, uchar *record,
if (length < reclength)
{
uint tmp=MY_ALIGN(reclength - length + 3 +
- test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
+ MY_TEST(reclength >= 65520L), MI_DYN_ALIGN_SIZE);
/* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */
- tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
+ tmp= MY_MIN(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
/* Check if we can extend this block */
if (block_info.filepos + block_info.block_len ==
info->state->data_file_length &&
@@ -1024,7 +1025,7 @@ uint _mi_rec_pack(MI_INFO *info, register uchar *to,
pos++;
}
new_length=(uint) (end-pos);
- if (new_length +1 + test(rec->length > 255 && new_length > 127)
+ if (new_length + 1 + MY_TEST(rec->length > 255 && new_length > 127)
< length)
{
if (rec->length > 255 && new_length > 127)
@@ -1144,7 +1145,7 @@ my_bool _mi_rec_check(MI_INFO *info,const uchar *record, uchar *rec_buff,
pos++;
}
new_length=(uint) (end-pos);
- if (new_length +1 + test(rec->length > 255 && new_length > 127)
+ if (new_length + 1 + MY_TEST(rec->length > 255 && new_length > 127)
< length)
{
if (!(flag & bit))
@@ -1196,7 +1197,7 @@ my_bool _mi_rec_check(MI_INFO *info,const uchar *record, uchar *rec_buff,
else
to+= length;
}
- if (packed_length != (uint) (to - rec_buff) + test(info->s->calc_checksum) ||
+ if (packed_length != (uint) (to - rec_buff) + MY_TEST(info->s->calc_checksum) ||
(bit != 1 && (flag & ~(bit - 1))))
goto err;
if (with_checksum && ((uchar) info->checksum != (uchar) *to))
@@ -1780,15 +1781,21 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, uchar *buf,
if (b_type & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR |
BLOCK_FATAL_ERROR))
{
- if ((b_type & (BLOCK_DELETED | BLOCK_SYNC_ERROR))
- && skip_deleted_blocks)
- {
- filepos=block_info.filepos+block_info.block_len;
- block_info.second_read=0;
- continue; /* Search after next_record */
- }
- if (b_type & (BLOCK_DELETED | BLOCK_SYNC_ERROR))
+ if ((b_type & (BLOCK_DELETED | BLOCK_SYNC_ERROR)))
{
+ if (skip_deleted_blocks)
+ {
+ filepos=block_info.filepos+block_info.block_len;
+ block_info.second_read=0;
+ continue; /* Search after next_record */
+ }
+ /*
+ If we're not on the first block of a record and
+ the block is marked as deleted or out of sync,
+ something's gone wrong: the record is damaged.
+ */
+ if (block_of_record != 0)
+ goto panic;
my_errno=HA_ERR_RECORD_DELETED;
info->lastpos=block_info.filepos;
info->nextpos=block_info.filepos+block_info.block_len;
diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c
index dab1f66ed6d..a47c1987e38 100644
--- a/storage/myisam/mi_extra.c
+++ b/storage/myisam/mi_extra.c
@@ -56,7 +56,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
{
reinit_io_cache(&info->rec_cache,READ_CACHE,0,
(pbool) (info->lock_type != F_UNLCK),
- (pbool) test(info->update & HA_STATE_ROW_CHANGED)
+ (pbool) MY_TEST(info->update & HA_STATE_ROW_CHANGED)
);
}
info->update= ((info->update & HA_STATE_CHANGED) | HA_STATE_NEXT_FOUND |
@@ -100,7 +100,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
cache_size= (extra_arg ? *(ulong*) extra_arg :
my_default_record_cache_size);
if (!(init_io_cache(&info->rec_cache,info->dfile,
- (uint) min(info->state->data_file_length+1,
+ (uint) MY_MIN(info->state->data_file_length+1,
cache_size),
READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
MYF(share->write_flag & MY_WAIT_IF_FULL))))
@@ -117,7 +117,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
{
reinit_io_cache(&info->rec_cache,READ_CACHE,info->nextpos,
(pbool) (info->lock_type != F_UNLCK),
- (pbool) test(info->update & HA_STATE_ROW_CHANGED));
+ (pbool) MY_TEST(info->update & HA_STATE_ROW_CHANGED));
info->update&= ~HA_STATE_ROW_CHANGED;
if (share->concurrent_insert)
info->rec_cache.end_of_file=info->state->data_file_length;
diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c
index 663a226d850..531b800c63e 100644
--- a/storage/myisam/mi_locking.c
+++ b/storage/myisam/mi_locking.c
@@ -646,7 +646,7 @@ int _mi_decrement_open_count(MI_INFO *info)
if (!lock_error && !my_disable_locking)
lock_error=mi_lock_database(info,old_lock);
}
- return test(lock_error || write_error);
+ return MY_TEST(lock_error || write_error);
}
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index 22225303bae..c6af5195f82 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -14,7 +14,18 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-/* open a isam-database */
+/*
+ open a isam-database
+
+ Internal temporary tables
+ -------------------------
+ Since only single instance of internal temporary table is required by
+ optimizer, such tables are not registered on myisam_open_list. In effect
+ it means (a) THR_LOCK_myisam is not held while such table is being created,
+ opened or closed; (b) no iteration through myisam_open_list while opening a
+ table. This optimization gives nice scalability benefit in concurrent
+ environment. MEMORY internal temporary tables are optimized similarly.
+*/
#include "fulltext.h"
#include "sp_defs.h"
@@ -74,10 +85,11 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
int lock_error,kfile,open_mode,save_errno,have_rtree=0, realpath_err;
uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
key_parts,unique_key_parts,base_key_parts,fulltext_keys,uniques;
+ uint internal_table= open_flags & HA_OPEN_INTERNAL_TABLE;
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
data_name[FN_REFLEN];
uchar *UNINIT_VAR(disk_cache), *disk_pos, *end_pos;
- MI_INFO info,*UNINIT_VAR(m_info),*old_info;
+ MI_INFO info,*UNINIT_VAR(m_info),*old_info= NULL;
MYISAM_SHARE share_buff,*share;
ulong *rec_per_key_part= 0;
my_off_t *key_root, *key_del;
@@ -99,8 +111,13 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
DBUG_RETURN (NULL);
}
- mysql_mutex_lock(&THR_LOCK_myisam);
- if (!(old_info=test_if_reopen(name_buff)))
+ if (!internal_table)
+ {
+ mysql_mutex_lock(&THR_LOCK_myisam);
+ old_info= test_if_reopen(name_buff);
+ }
+
+ if (!old_info)
{
share= &share_buff;
bzero((uchar*) &share_buff,sizeof(share_buff));
@@ -311,7 +328,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
strmov(share->index_file_name, index_name);
strmov(share->data_file_name, data_name);
- share->blocksize=min(IO_SIZE,myisam_block_size);
+ share->blocksize=MY_MIN(IO_SIZE,myisam_block_size);
{
HA_KEYSEG *pos=share->keyparts;
uint32 ftkey_nr= 1;
@@ -497,7 +514,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share->base.margin_key_file_length=(share->base.max_key_file_length -
(keys ? MI_INDEX_BLOCK_MARGIN *
share->blocksize * keys : 0));
- share->blocksize=min(IO_SIZE,myisam_block_size);
+ share->blocksize=MY_MIN(IO_SIZE,myisam_block_size);
share->data_file_type=STATIC_RECORD;
if (share->options & HA_OPTION_COMPRESS_RECORD)
{
@@ -506,9 +523,9 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
info.s=share;
if (_mi_read_pack_info(&info,
(pbool)
- test(!(share->options &
- (HA_OPTION_PACK_RECORD |
- HA_OPTION_TEMP_COMPRESS_RECORD)))))
+ MY_TEST(!(share->options &
+ (HA_OPTION_PACK_RECORD |
+ HA_OPTION_TEMP_COMPRESS_RECORD)))))
goto err;
}
else if (share->options & HA_OPTION_PACK_RECORD)
@@ -644,10 +661,13 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
*m_info=info;
thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
- m_info->open_list.data=(void*) m_info;
- myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
- mysql_mutex_unlock(&THR_LOCK_myisam);
+ if (!internal_table)
+ {
+ m_info->open_list.data= (void*) m_info;
+ myisam_open_list= list_add(myisam_open_list, &m_info->open_list);
+ mysql_mutex_unlock(&THR_LOCK_myisam);
+ }
bzero(info.buff, share->base.max_key_block_length * 2);
my_free(rec_per_key_part);
@@ -692,7 +712,8 @@ err:
default:
break;
}
- mysql_mutex_unlock(&THR_LOCK_myisam);
+ if (!internal_table)
+ mysql_mutex_unlock(&THR_LOCK_myisam);
my_errno=save_errno;
DBUG_RETURN (NULL);
} /* mi_open */
@@ -712,10 +733,10 @@ uchar *mi_alloc_rec_buff(MI_INFO *info, ulong length, uchar **buf)
if (length == (ulong) -1)
{
if (info->s->options & HA_OPTION_COMPRESS_RECORD)
- length= max(info->s->base.pack_reclength, info->s->max_pack_length);
+ length= MY_MAX(info->s->base.pack_reclength, info->s->max_pack_length);
else
length= info->s->base.pack_reclength;
- length= max(length, info->s->base.max_key_length);
+ length= MY_MAX(length, info->s->base.max_key_length);
/* Avoid unnecessary realloc */
if (newptr && length == old_length)
return newptr;
diff --git a/storage/myisam/mi_packrec.c b/storage/myisam/mi_packrec.c
index f0a4d764e7a..d1ad911d334 100644
--- a/storage/myisam/mi_packrec.c
+++ b/storage/myisam/mi_packrec.c
@@ -685,7 +685,7 @@ static uint find_longest_bitstream(uint16 *table, uint16 *end)
return OFFSET_TABLE_SIZE;
}
length2= find_longest_bitstream(next, end) + 1;
- length=max(length,length2);
+ length=MY_MAX(length,length2);
}
return length;
}
@@ -1399,7 +1399,7 @@ uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
info->filepos=filepos+head_length;
if (file > 0)
{
- info->offset=min(info->rec_len, ref_length - head_length);
+ info->offset=MY_MIN(info->rec_len, ref_length - head_length);
memcpy(*rec_buff_p, header + head_length, info->offset);
}
return 0;
diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c
index 01fa10de7a3..3ce112f7906 100644
--- a/storage/myisam/mi_search.c
+++ b/storage/myisam/mi_search.c
@@ -83,7 +83,7 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
}
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
- test(!(nextflag & SEARCH_SAVE_BUFF)))))
+ MY_TEST(!(nextflag & SEARCH_SAVE_BUFF)))))
goto err;
DBUG_DUMP("page", buff, mi_getint(buff));
@@ -129,7 +129,7 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
{
uchar *old_buff=buff;
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
- test(!(nextflag & SEARCH_SAVE_BUFF)))))
+ MY_TEST(!(nextflag & SEARCH_SAVE_BUFF)))))
goto err;
keypos=buff+(keypos-old_buff);
maxpos=buff+(maxpos-old_buff);
diff --git a/storage/myisam/mi_static.c b/storage/myisam/mi_static.c
index 30e463746d5..d77f4f6b8e2 100644
--- a/storage/myisam/mi_static.c
+++ b/storage/myisam/mi_static.c
@@ -18,7 +18,7 @@
a shared library
*/
-#ifndef _global_h
+#ifndef MY_GLOBAL_INCLUDED
#include "myisamdef.h"
#endif
@@ -119,23 +119,20 @@ void init_myisam_psi_keys()
const char* category= "myisam";
int count;
- if (PSI_server == NULL)
- return;
-
count= array_elements(all_myisam_mutexes);
- PSI_server->register_mutex(category, all_myisam_mutexes, count);
+ mysql_mutex_register(category, all_myisam_mutexes, count);
count= array_elements(all_myisam_rwlocks);
- PSI_server->register_rwlock(category, all_myisam_rwlocks, count);
+ mysql_rwlock_register(category, all_myisam_rwlocks, count);
count= array_elements(all_myisam_conds);
- PSI_server->register_cond(category, all_myisam_conds, count);
+ mysql_cond_register(category, all_myisam_conds, count);
count= array_elements(all_myisam_files);
- PSI_server->register_file(category, all_myisam_files, count);
+ mysql_file_register(category, all_myisam_files, count);
count= array_elements(all_myisam_threads);
- PSI_server->register_thread(category, all_myisam_threads, count);
+ mysql_thread_register(category, all_myisam_threads, count);
}
#endif /* HAVE_PSI_INTERFACE */
diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c
index 3b2597eb01e..87cea2e5566 100644
--- a/storage/myisam/mi_test1.c
+++ b/storage/myisam/mi_test1.c
@@ -268,14 +268,14 @@ static int run_test(const char *filename)
if (verbose || (flags[j] >= 1 ||
(error && my_errno != HA_ERR_KEY_NOT_FOUND)))
printf("key: '%.*s' mi_rkey: %3d errno: %3d\n",
- (int) key_length,key+test(null_fields),error,my_errno);
+ (int) key_length, key + MY_TEST(null_fields), error, my_errno);
}
else
{
error=mi_delete(file,read_record);
if (verbose || error)
printf("key: '%.*s' mi_delete: %3d errno: %3d\n",
- (int) key_length, key+test(null_fields), error, my_errno);
+ (int) key_length, key + MY_TEST(null_fields), error, my_errno);
if (! error)
{
deleted++;
@@ -296,7 +296,8 @@ static int run_test(const char *filename)
(error && (flags[i] != 0 || my_errno != HA_ERR_KEY_NOT_FOUND)))
{
printf("key: '%.*s' mi_rkey: %3d errno: %3d record: %s\n",
- (int) key_length,key+test(null_fields),error,my_errno,record+1);
+ (int) key_length, key + MY_TEST(null_fields), error, my_errno,
+ record + 1);
}
}
@@ -439,7 +440,7 @@ static void create_record(uchar *record,uint rownr)
uint tmp;
uchar *ptr;;
sprintf((char*) blob_record,"... row: %d", rownr);
- strappend((char*) blob_record,max(MAX_REC_LENGTH-rownr,10),' ');
+ strappend((char*) blob_record,MY_MAX(MAX_REC_LENGTH-rownr,10),' ');
tmp=strlen((char*) blob_record);
int4store(pos,tmp);
ptr=blob_record;
diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c
index 3ec12ef5cca..e53c68874b2 100644
--- a/storage/myisam/mi_test2.c
+++ b/storage/myisam/mi_test2.c
@@ -597,7 +597,7 @@ int main(int argc, char *argv[])
goto err;
bmove(read_record2,read_record,reclength);
- for (i=min(2,keys) ; i-- > 0 ;)
+ for (i=MY_MIN(2,keys) ; i-- > 0 ;)
{
if (mi_rsame(file,read_record2,(int) i)) goto err;
if (memcmp(read_record,read_record2,reclength) != 0)
diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c
index e8eb2463a23..2b922bbaa9e 100644
--- a/storage/myisam/mi_write.c
+++ b/storage/myisam/mi_write.c
@@ -54,6 +54,10 @@ int mi_write(MI_INFO *info, uchar *record)
DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_usage",
mi_print_error(info->s, HA_ERR_CRASHED);
DBUG_RETURN(my_errno= HA_ERR_CRASHED););
+
+ /* it's always a bug to try to write a record with the deleted flag set */
+ DBUG_ASSERT(info->s->data_file_type != STATIC_RECORD || *record);
+
if (share->options & HA_OPTION_READ_ONLY_DATA)
{
DBUG_RETURN(my_errno=EACCES);
@@ -544,7 +548,7 @@ int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo,
/* yup. converting */
info->ft1_to_ft2=(DYNAMIC_ARRAY *)
my_malloc(sizeof(DYNAMIC_ARRAY), MYF(MY_WME));
- my_init_dynamic_array(info->ft1_to_ft2, ft2len, 300, 50);
+ my_init_dynamic_array(info->ft1_to_ft2, ft2len, 300, 50, MYF(0));
/*
now, adding all keys from the page to dynarray
@@ -1013,8 +1017,8 @@ int mi_init_bulk_insert(MI_INFO *info, size_t cache_size, ha_rows rows)
init_tree(&info->bulk_insert[i],
cache_size * key[i].maxlength,
cache_size * key[i].maxlength, 0,
- (qsort_cmp2)keys_compare, 0,
- (tree_element_free) keys_free, (void *)params++);
+ (qsort_cmp2)keys_compare,
+ (tree_element_free) keys_free, (void *)params++, MYF(0));
}
else
info->bulk_insert[i].root=0;
diff --git a/storage/myisam/myisam_ftdump.c b/storage/myisam/myisam_ftdump.c
index ce0d7be3f0b..e1ea9f2de37 100644
--- a/storage/myisam/myisam_ftdump.c
+++ b/storage/myisam/myisam_ftdump.c
@@ -84,7 +84,7 @@ int main(int argc,char *argv[])
usage();
}
- init_key_cache(dflt_key_cache,MI_KEY_BLOCK_LENGTH,USE_BUFFER_INIT, 0, 0, 0);
+ init_key_cache(dflt_key_cache, MI_KEY_BLOCK_LENGTH, KEY_BUFFER_INIT, 0, 0, 0);
if (!(info=mi_open(argv[0], O_RDONLY,
HA_OPEN_ABORT_IF_LOCKED|HA_OPEN_FROM_SQL_LAYER)))
diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c
index 917893f58a9..0cd01398cbc 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -16,6 +16,7 @@
/* Describe, check and repair of MyISAM tables */
#include "fulltext.h"
+#include "my_default.h"
#include <m_ctype.h>
#include <stdarg.h>
#include <my_getopt.h>
@@ -134,7 +135,7 @@ int main(int argc, char **argv)
enum options_mc {
OPT_CHARSETS_DIR=256, OPT_SET_COLLATION,OPT_START_CHECK_POS,
- OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE,
+ OPT_CORRECT_CHECKSUM, OPT_CREATE_MISSING_KEYS, OPT_KEY_BUFFER_SIZE,
OPT_KEY_CACHE_BLOCK_SIZE, OPT_MYISAM_BLOCK_SIZE,
OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
@@ -165,6 +166,11 @@ static struct my_option my_long_options[] =
{"correct-checksum", OPT_CORRECT_CHECKSUM,
"Correct checksum information for table.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"create-missing-keys", OPT_CREATE_MISSING_KEYS,
+ "Create missing keys. This assumes that the data file is correct and that "
+ "the the number of rows stored in the index file is correct. Enables "
+ "--quick",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
{"debug", '#',
"Output debug log. Often this is 'd:t:o,filename'.",
@@ -270,7 +276,7 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{ "key_buffer_size", OPT_KEY_BUFFER_SIZE, "",
&check_param.use_buffers, &check_param.use_buffers, 0,
- GET_ULL, REQUIRED_ARG, USE_BUFFER_INIT, MALLOC_OVERHEAD,
+ GET_ULL, REQUIRED_ARG, KEY_BUFFER_INIT, MALLOC_OVERHEAD,
SIZE_T_MAX, MALLOC_OVERHEAD, IO_SIZE, 0},
{ "key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE, "",
&opt_key_cache_block_size,
@@ -395,10 +401,18 @@ static void usage(void)
-e, --extend-check Try to recover every possible row from the data file\n\
Normally this will also find a lot of garbage rows;\n\
Don't use this option if you are not totally desperate.\n\
- -f, --force Overwrite old temporary files.\n\
+ -f, --force Overwrite old temporary files. Add another --force to\n\
+ avoid 'myisam_sort_buffer_size is too small' errors.\n\
+ In this case we will attempt to do the repair with the\n\
+ given myisam_sort_buffer_size and dynamically allocate\n\
+ as many management buffers as needed.\n\
-k, --keys-used=# Tell MyISAM to update only some specific keys. # is a\n\
bit mask of which keys to use. This can be used to\n\
get faster inserts.\n\
+ --create-missing-keys\n\
+ Create missing keys. This assumes that the data\n\
+ file is correct and that the the number of rows stored\n\
+ in the index file is correct. Enables --quick\n\
--max-record-length=#\n\
Skip rows bigger than this if myisamchk can't allocate\n\
memory to hold it.\n\
@@ -541,10 +555,13 @@ get_one_option(int optid,
if (argument == disabled_my_option)
{
check_param.tmpfile_createflag= O_RDWR | O_TRUNC | O_EXCL;
- check_param.testflag&= ~(T_FORCE_CREATE | T_UPDATE_STATE);
+ check_param.testflag&= ~(T_FORCE_CREATE | T_UPDATE_STATE |
+ T_FORCE_SORT_MEMORY);
}
else
{
+ if (check_param.testflag & T_FORCE_CREATE)
+ check_param.testflag= T_FORCE_SORT_MEMORY;
check_param.tmpfile_createflag= O_RDWR | O_TRUNC;
check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE;
}
@@ -597,8 +614,26 @@ get_one_option(int optid,
if (argument == disabled_my_option)
check_param.testflag&= ~(T_QUICK | T_FORCE_UNIQUENESS);
else
+ {
+ /*
+ If T_QUICK was specified before, but not OPT_CREATE_MISSING_KEYS,
+ then add T_FORCE_UNIQUENESS.
+ */
check_param.testflag|=
- (check_param.testflag & T_QUICK) ? T_FORCE_UNIQUENESS : T_QUICK;
+ ((check_param.testflag & (T_QUICK | T_CREATE_MISSING_KEYS)) ==
+ T_QUICK ? T_FORCE_UNIQUENESS : T_QUICK);
+ }
+ break;
+ case OPT_CREATE_MISSING_KEYS:
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~(T_QUICK | T_CREATE_MISSING_KEYS);
+ else
+ {
+ check_param.testflag|= T_QUICK | T_CREATE_MISSING_KEYS;
+ /* Use repair by sort by default */
+ if (!(check_param.testflag & T_REP_ANY))
+ check_param.testflag|= T_REP_BY_SORT;
+ }
break;
case 'u':
if (argument == disabled_my_option)
@@ -779,7 +814,7 @@ static void get_options(register int *argc,register char ***argv)
static int myisamchk(HA_CHECK *param, char * filename)
{
int error,lock_type,recreate;
- int rep_quick= test(param->testflag & (T_QUICK | T_FORCE_UNIQUENESS));
+ int rep_quick= MY_TEST(param->testflag & (T_QUICK | T_FORCE_UNIQUENESS));
MI_INFO *info;
File datafile;
char llbuff[22],llbuff2[22];
@@ -1093,7 +1128,8 @@ static int myisamchk(HA_CHECK *param, char * filename)
if ((info->s->options & (HA_OPTION_PACK_RECORD |
HA_OPTION_COMPRESS_RECORD)) ||
(param->testflag & (T_EXTEND | T_MEDIUM)))
- error|=chk_data_link(param, info, test(param->testflag & T_EXTEND));
+ error|= chk_data_link(param, info,
+ MY_TEST(param->testflag & T_EXTEND));
error|=flush_blocks(param, share->key_cache, share->kfile,
&share->dirty_part_map);
(void) end_io_cache(&param->read_cache);
@@ -1117,7 +1153,7 @@ static int myisamchk(HA_CHECK *param, char * filename)
if ((param->testflag & T_AUTO_INC) ||
((param->testflag & T_REP_ANY) && info->s->base.auto_key))
update_auto_increment_key(param, info,
- (my_bool) !test(param->testflag & T_AUTO_INC));
+ (my_bool) !MY_TEST(param->testflag & T_AUTO_INC));
if (!(param->testflag & T_DESCRIPT))
{
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index 221d6e36aea..8ca052af4ac 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -82,6 +82,9 @@ typedef struct st_mi_state_info
uint open_count;
uint8 changed; /* Changed since myisamchk */
+ uint8 dupp_key; /* Lastly processed index with */
+ /* violated uniqueness constraint */
+
/* the following isn't saved on disk */
uint state_diff_length; /* Should be 0 */
uint state_length; /* Length of state header in file */
@@ -296,6 +299,7 @@ struct st_myisam_info
my_bool page_changed;
/* If info->buff has to be reread for rnext */
my_bool buff_used;
+ my_bool create_unique_index_by_sort;
index_cond_func_t index_cond_func; /* Index condition function */
void *index_cond_func_arg; /* parameter for the func */
THR_LOCK_DATA lock;
@@ -624,10 +628,11 @@ typedef struct st_mi_block_info /* Parameter to _mi_get_block_info */
#define UPDATE_AUTO_INC 8
#define UPDATE_OPEN_COUNT 16
-#define USE_BUFFER_INIT (((1024L*512L-MALLOC_OVERHEAD)/IO_SIZE)*IO_SIZE)
-#define READ_BUFFER_INIT (1024L*256L-MALLOC_OVERHEAD)
-#define SORT_BUFFER_INIT (2048L*1024L-MALLOC_OVERHEAD)
-#define MIN_SORT_BUFFER (4096-MALLOC_OVERHEAD)
+/* We use MY_ALIGN_DOWN here mainly to ensure that we get stable values for mysqld --help ) */
+#define KEY_BUFFER_INIT MY_ALIGN_DOWN(1024L*1024L-MALLOC_OVERHEAD, IO_SIZE)
+#define READ_BUFFER_INIT MY_ALIGN_DOWN(1024L*256L-MALLOC_OVERHEAD, 1024)
+#define SORT_BUFFER_INIT MY_ALIGN_DOWN(1024L*1024L*128L-MALLOC_OVERHEAD, 1024)
+#define MIN_SORT_BUFFER 4096
enum myisam_log_commands
{
@@ -704,8 +709,8 @@ void mi_restore_status(void *param);
void mi_copy_status(void *to, void *from);
my_bool mi_check_status(void *param);
void mi_fix_status(MI_INFO *org_table, MI_INFO *new_table);
-void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
-
+void mi_disable_indexes_for_rebuild(MI_INFO *info, ha_rows rows,
+ my_bool all_keys);
extern MI_INFO *test_if_reopen(char *filename);
my_bool check_table_is_closed(const char *name, const char *where);
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *orn_name,
diff --git a/storage/myisam/myisamlog.c b/storage/myisam/myisamlog.c
index 3314f1b94ac..86e1978edaa 100644
--- a/storage/myisam/myisamlog.c
+++ b/storage/myisam/myisamlog.c
@@ -91,7 +91,7 @@ int main(int argc, char **argv)
log_filename=myisam_log_filename;
get_options(&argc,&argv);
/* Number of MyISAM files we can have open at one time */
- max_files= (my_set_max_open_files(min(max_files,8))-6)/2;
+ max_files= (my_set_max_open_files(MY_MIN(max_files,8))-6)/2;
if (update)
printf("Trying to %s MyISAM files according to log '%s'\n",
(recover ? "recover" : "update"),log_filename);
@@ -329,8 +329,9 @@ static int examine_log(char * file_name, char **table_names)
init_io_cache(&cache,file,0,READ_CACHE,start_offset,0,MYF(0));
bzero((uchar*) com_count,sizeof(com_count));
- init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
- (tree_element_free) file_info_free, NULL);
+ init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,
+ (tree_element_free) file_info_free, NULL,
+ MYF(MY_TREE_WITH_DELETE));
(void) init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE,
0, 0, 0);
diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c
index 92ee1dde84c..8854a85c3d3 100644
--- a/storage/myisam/myisampack.c
+++ b/storage/myisam/myisampack.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates
+ Copyright (c) 2009, 2013, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,6 +21,7 @@
#endif
#include "myisamdef.h"
+#include "my_default.h"
#include <queues.h>
#include <my_tree.h>
#include "mysys_err.h"
@@ -783,7 +785,7 @@ static int create_dest_frm(char *source_table, char *dest_table)
*/
(void) my_copy(source_name, dest_name, MYF(MY_DONT_OVERWRITE_FILE));
- return 0;
+ DBUG_RETURN(0);
}
@@ -816,8 +818,8 @@ static HUFF_COUNTS *init_huff_count(MI_INFO *info,my_off_t records)
'tree_pos'. It's keys are implemented by pointers into 'tree_buff'.
This is accomplished by '-1' as the element size.
*/
- init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree,0, NULL,
- NULL);
+ init_tree(&count[i].int_tree,0,0,-1,(qsort_cmp2) compare_tree, NULL,
+ NULL, MYF(0));
if (records && type != FIELD_BLOB && type != FIELD_VARCHAR)
count[i].tree_pos=count[i].tree_buff =
my_malloc(count[i].field_length > 1 ? tree_buff_length : 2,
@@ -1269,7 +1271,7 @@ static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
{
if (huff_counts->field_length > 2 &&
huff_counts->empty_fields + (records - huff_counts->empty_fields)*
- (1+max_bit(max(huff_counts->max_pre_space,
+ (1+max_bit(MY_MAX(huff_counts->max_pre_space,
huff_counts->max_end_space))) <
records * max_bit(huff_counts->field_length))
{
@@ -1931,7 +1933,7 @@ static int make_huff_decode_table(HUFF_TREE *huff_tree, uint trees)
return 1;
huff_tree->code_len=(uchar*) (huff_tree->code+elements);
make_traverse_code_tree(huff_tree, huff_tree->root,
- 8 * sizeof(ulonglong), LL(0));
+ 8 * sizeof(ulonglong), 0);
}
}
return 0;
@@ -3023,7 +3025,7 @@ static int save_state_mrg(File file,PACK_MRG_INFO *mrg,my_off_t new_length,
if (mrg->src_file_has_indexes_disabled)
{
isam_file->s->state.state.key_file_length=
- max(isam_file->s->state.state.key_file_length, new_length);
+ MY_MAX(isam_file->s->state.state.key_file_length, new_length);
}
state.dellink= HA_OFFSET_ERROR;
state.version=(ulong) time((time_t*) 0);
diff --git a/storage/myisam/mysql-test/storage_engine/alter_table_online.rdiff b/storage/myisam/mysql-test/storage_engine/alter_table_online.rdiff
new file mode 100644
index 00000000000..3a7fef61d3b
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/alter_table_online.rdiff
@@ -0,0 +1,71 @@
+--- suite/storage_engine/alter_table_online.result 2013-11-08 20:01:16.000000000 +0400
++++ suite/storage_engine/alter_table_online.reject 2013-11-08 20:02:03.000000000 +0400
+@@ -2,8 +2,35 @@
+ CREATE TABLE t1 (a <INT_COLUMN>, b <INT_COLUMN>, c <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ INSERT INTO t1 (a,b,c) VALUES (1,100,'a'),(2,200,'b'),(3,300,'c');
+ ALTER ONLINE TABLE t1 MODIFY b <INT_COLUMN> DEFAULT 5;
++ERROR 0A000: LOCK=NONE/SHARED is not supported for this operation. Try LOCK=EXCLUSIVE.
++# ERROR: Statement ended with errno 1845, errname ER_ALTER_OPERATION_NOT_SUPPORTED (expected to succeed)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command finished with ER_ALTER_OPERATION_NOT_SUPPORTED.
++# Functionality or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ ALTER ONLINE TABLE t1 CHANGE b new_name <INT_COLUMN>;
++ERROR 0A000: LOCK=NONE/SHARED is not supported for this operation. Try LOCK=EXCLUSIVE.
++# ERROR: Statement ended with errno 1845, errname ER_ALTER_OPERATION_NOT_SUPPORTED (expected to succeed)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command finished with ER_ALTER_OPERATION_NOT_SUPPORTED.
++# Functionality or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ ALTER ONLINE TABLE t1 COMMENT 'new comment';
++ERROR 0A000: LOCK=NONE/SHARED is not supported for this operation. Try LOCK=EXCLUSIVE.
++# ERROR: Statement ended with errno 1845, errname ER_ALTER_OPERATION_NOT_SUPPORTED (expected to succeed)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command finished with ER_ALTER_OPERATION_NOT_SUPPORTED.
++# Functionality or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ ALTER ONLINE TABLE t1 RENAME TO t2;
+ ERROR 0A000: LOCK=NONE/SHARED is not supported for this operation. Try LOCK=EXCLUSIVE.
+ DROP TABLE IF EXISTS t2;
+@@ -23,12 +50,30 @@
+ CREATE TABLE t1 (a <INT_COLUMN>, b <INT_COLUMN>, c <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ INSERT INTO t1 (a,b,c) VALUES (1,100,'a'),(2,200,'b'),(3,300,'c');
+ ALTER ONLINE TABLE t1 DROP COLUMN b, ADD b <INT_COLUMN>;
++ERROR 0A000: LOCK=NONE is not supported for this operation. Try LOCK=SHARED.
++# ERROR: Statement ended with errno 1845, errname ER_ALTER_OPERATION_NOT_SUPPORTED (expected to succeed)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command finished with ER_ALTER_OPERATION_NOT_SUPPORTED.
++# Functionality or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ ALTER ONLINE TABLE t1 MODIFY b BIGINT <CUSTOM_COL_OPTIONS>;
+-ERROR 0A000: LOCK=NONE is not supported. Reason: Cannot change column type INPLACE. Try LOCK=SHARED.
++ERROR 0A000: LOCK=NONE is not supported for this operation. Try LOCK=SHARED.
++# ERROR: Statement ended with errno 1845, errname ER_ALTER_OPERATION_NOT_SUPPORTED (expected results: ER_ALTER_OPERATION_NOT_SUPPORTED_REASON)
+ ALTER ONLINE TABLE t1 ENGINE=MEMORY;
+ ERROR 0A000: LOCK=NONE is not supported. Reason: COPY algorithm requires a lock. Try LOCK=SHARED.
+ DROP TABLE t1;
+ CREATE TABLE t1 (a <INT_COLUMN>, b <INT_COLUMN>, c <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ ALTER ONLINE TABLE t1 ADD INDEX (b);
+-ALTER ONLINE TABLE t1 DROP INDEX b;
++ERROR 0A000: LOCK=NONE is not supported for this operation. Try LOCK=SHARED.
++# ERROR: Statement ended with errno 1845, errname ER_ALTER_OPERATION_NOT_SUPPORTED (expected to succeed)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command finished with ER_ALTER_OPERATION_NOT_SUPPORTED.
++# Adding an index or ALTER ONLINE or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ DROP TABLE t1;
diff --git a/storage/myisam/mysql-test/storage_engine/alter_tablespace.rdiff b/storage/myisam/mysql-test/storage_engine/alter_tablespace.rdiff
index 07c03fc8d3e..4215af58011 100644
--- a/storage/myisam/mysql-test/storage_engine/alter_tablespace.rdiff
+++ b/storage/myisam/mysql-test/storage_engine/alter_tablespace.rdiff
@@ -1,6 +1,6 @@
--- suite/storage_engine/alter_tablespace.result 2012-07-12 19:53:40.775419511 +0400
+++ suite/storage_engine/alter_tablespace.reject 2012-07-15 16:21:14.910435703 +0400
-@@ -1,19 +1,14 @@
+@@ -1,21 +1,14 @@
DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 (a <INT_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
ALTER TABLE t1 DISCARD TABLESPACE;
@@ -13,13 +13,15 @@
-2
-ALTER TABLE t1 DISCARD TABLESPACE;
-SELECT a FROM t1;
--ERROR HY000: Got error -1 from storage engine
+-ERROR HY000: Tablespace has been discarded for table 't1'
-ALTER TABLE t1 IMPORT TABLESPACE;
+-Warnings:
+-Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t1.cfg', will attempt to import without schema verification
-SELECT a FROM t1;
-a
-1
-2
-+ERROR HY000: Table storage engine for 't1' doesn't have this option
++ERROR HY000: Storage engine <STORAGE_ENGINE> of the table `test`.`t1` doesn't have this option
+# ERROR: Statement ended with errno 1031, errname ER_ILLEGAL_HA (expected to succeed)
+# ------------ UNEXPECTED RESULT ------------
+# [ ALTER TABLE t1 DISCARD TABLESPACE ]
diff --git a/storage/myisam/mysql-test/storage_engine/foreign_keys.rdiff b/storage/myisam/mysql-test/storage_engine/foreign_keys.rdiff
index 31da75e5ea5..205e7314fda 100644
--- a/storage/myisam/mysql-test/storage_engine/foreign_keys.rdiff
+++ b/storage/myisam/mysql-test/storage_engine/foreign_keys.rdiff
@@ -142,4 +142,4 @@
+# -------------------------------------------
DROP TABLE t2;
DROP TABLE t1;
-+ERROR 42S02: Unknown table 't1'
++ERROR 42S02: Unknown table 'test.t1'
diff --git a/storage/myisam/mysql-test/storage_engine/misc.rdiff b/storage/myisam/mysql-test/storage_engine/misc.rdiff
new file mode 100644
index 00000000000..39d43d07be2
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/misc.rdiff
@@ -0,0 +1,25 @@
+--- suite/storage_engine/misc.result 2013-11-08 21:49:40.000000000 +0400
++++ suite/storage_engine/misc.reject 2013-11-08 21:51:58.000000000 +0400
+@@ -28,6 +28,9 @@
+ SELECT TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
+ FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ORDER BY TABLE_NAME;
+ TABLE_NAME COLUMN_NAME REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME
++Warning 1286 Unknown storage engine 'InnoDB'
++Warning 1286 Unknown storage engine 'InnoDB'
++Warnings:
+ column_stats column_name NULL NULL
+ column_stats db_name NULL NULL
+ column_stats table_name NULL NULL
+@@ -58,12 +61,6 @@
+ index_stats index_name NULL NULL
+ index_stats prefix_arity NULL NULL
+ index_stats table_name NULL NULL
+-innodb_index_stats database_name NULL NULL
+-innodb_index_stats index_name NULL NULL
+-innodb_index_stats stat_name NULL NULL
+-innodb_index_stats table_name NULL NULL
+-innodb_table_stats database_name NULL NULL
+-innodb_table_stats table_name NULL NULL
+ plugin name NULL NULL
+ proc db NULL NULL
+ proc name NULL NULL
diff --git a/storage/myisam/rt_mbr.c b/storage/myisam/rt_mbr.c
index c59b872ae3e..05576f0b5e9 100644
--- a/storage/myisam/rt_mbr.c
+++ b/storage/myisam/rt_mbr.c
@@ -326,8 +326,8 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res)
bmin = korr_func(b); \
amax = korr_func(a+len); \
bmax = korr_func(b+len); \
- amin = min(amin, bmin); \
- amax = max(amax, bmax); \
+ amin = MY_MIN(amin, bmin); \
+ amax = MY_MAX(amax, bmax); \
store_func(c, amin); \
store_func(c+len, amax); \
}
@@ -339,8 +339,8 @@ int rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res)
get_func(bmin, b); \
get_func(amax, a+len); \
get_func(bmax, b+len); \
- amin = min(amin, bmin); \
- amax = max(amax, bmax); \
+ amin = MY_MIN(amin, bmin); \
+ amax = MY_MAX(amax, bmax); \
store_func(c, amin); \
store_func(c+len, amax); \
}
@@ -418,8 +418,8 @@ int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c,
bmin = korr_func(b); \
amax = korr_func(a+len); \
bmax = korr_func(b+len); \
- amin = max(amin, bmin); \
- amax = min(amax, bmax); \
+ amin = MY_MAX(amin, bmin); \
+ amax = MY_MIN(amax, bmax); \
if (amin >= amax) \
return 0; \
res *= amax - amin; \
@@ -432,8 +432,8 @@ int rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c,
get_func(bmin, b); \
get_func(amax, a+len); \
get_func(bmax, b+len); \
- amin = max(amin, bmin); \
- amax = min(amax, bmax); \
+ amin = MY_MAX(amin, bmin); \
+ amax = MY_MIN(amax, bmax); \
if (amin >= amax) \
return 0; \
res *= amax - amin; \
@@ -509,7 +509,7 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b,
amax = korr_func(a+len); \
bmax = korr_func(b+len); \
a_area *= (((double)amax) - ((double)amin)); \
- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
+ loc_ab_area *= ((double)MY_MAX(amax, bmax) - (double)MY_MIN(amin, bmin)); \
}
#define RT_AREA_INC_GET(type, get_func, len)\
@@ -520,7 +520,7 @@ double rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b,
get_func(amax, a+len); \
get_func(bmax, b+len); \
a_area *= (((double)amax) - ((double)amin)); \
- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
+ loc_ab_area *= ((double)MY_MAX(amax, bmax) - (double)MY_MIN(amin, bmin)); \
}
/*
@@ -605,7 +605,7 @@ safe_end:
amax = korr_func(a+len); \
bmax = korr_func(b+len); \
a_perim+= (((double)amax) - ((double)amin)); \
- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
+ *ab_perim+= ((double)MY_MAX(amax, bmax) - (double)MY_MIN(amin, bmin)); \
}
#define RT_PERIM_INC_GET(type, get_func, len)\
@@ -616,7 +616,7 @@ safe_end:
get_func(amax, a+len); \
get_func(bmax, b+len); \
a_perim+= (((double)amax) - ((double)amin)); \
- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
+ *ab_perim+= ((double)MY_MAX(amax, bmax) - (double)MY_MIN(amin, bmin)); \
}
/*
diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c
index 2c4639b3143..8e45ca1a3ea 100644
--- a/storage/myisam/sort.c
+++ b/storage/myisam/sort.c
@@ -34,8 +34,10 @@
#define MERGEBUFF 15
#define MERGEBUFF2 31
#define MYF_RW MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL)
-#define DISK_BUFFER_SIZE (IO_SIZE*16)
+#define DISK_BUFFER_SIZE (IO_SIZE*128)
+/* How many keys we can keep in memory */
+typedef ulonglong ha_keys;
/*
Pointers of functions for store and read keys from temp file
@@ -45,42 +47,42 @@ extern void print_error(const char *fmt,...);
/* Functions defined in this file */
-static ha_rows find_all_keys(MI_SORT_PARAM *info,uint keys,
+static ha_rows find_all_keys(MI_SORT_PARAM *info, ha_keys keys,
uchar **sort_keys,
- DYNAMIC_ARRAY *buffpek,int *maxbuffer,
+ DYNAMIC_ARRAY *buffpek,uint *maxbuffer,
IO_CACHE *tempfile,
IO_CACHE *tempfile_for_exceptions);
static int write_keys(MI_SORT_PARAM *info,uchar **sort_keys,
- uint count, BUFFPEK *buffpek,IO_CACHE *tempfile);
+ ha_keys count, BUFFPEK *buffpek,IO_CACHE *tempfile);
static int write_key(MI_SORT_PARAM *info, uchar *key,
IO_CACHE *tempfile);
static int write_index(MI_SORT_PARAM *info,uchar * *sort_keys,
- uint count);
-static int merge_many_buff(MI_SORT_PARAM *info,uint keys,
+ ha_keys count);
+static int merge_many_buff(MI_SORT_PARAM *info, ha_keys keys,
uchar * *sort_keys,
- BUFFPEK *buffpek,int *maxbuffer,
+ BUFFPEK *buffpek, uint *maxbuffer,
IO_CACHE *t_file);
-static uint read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
- uint sort_length);
-static int merge_buffers(MI_SORT_PARAM *info,uint keys,
+static my_off_t read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
+ uint sort_length);
+static int merge_buffers(MI_SORT_PARAM *info, ha_keys keys,
IO_CACHE *from_file, IO_CACHE *to_file,
uchar * *sort_keys, BUFFPEK *lastbuff,
BUFFPEK *Fb, BUFFPEK *Tb);
-static int merge_index(MI_SORT_PARAM *,uint,uchar **,BUFFPEK *, int,
+static int merge_index(MI_SORT_PARAM *,ha_keys,uchar **,BUFFPEK *, uint,
IO_CACHE *);
static int flush_ft_buf(MI_SORT_PARAM *info);
static int write_keys_varlen(MI_SORT_PARAM *info,uchar **sort_keys,
- uint count, BUFFPEK *buffpek,
+ ha_keys count, BUFFPEK *buffpek,
IO_CACHE *tempfile);
-static uint read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek,
+static my_off_t read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek,
uint sort_length);
static int write_merge_key(MI_SORT_PARAM *info, IO_CACHE *to_file,
- uchar *key, uint sort_length, uint count);
+ uchar *key, uint sort_length, ha_keys count);
static int write_merge_key_varlen(MI_SORT_PARAM *info,
IO_CACHE *to_file,
uchar* key, uint sort_length,
- uint count);
+ ha_keys count);
static inline int
my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs);
@@ -101,15 +103,15 @@ my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs);
int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
ulonglong sortbuff_size)
{
- int error,maxbuffer,skr;
- uint sort_length, keys;
+ int error;
+ uint sort_length, maxbuffer;
ulonglong memavl, old_memavl;
DYNAMIC_ARRAY buffpek;
- ha_rows records;
+ ha_rows records, keys;
uchar **sort_keys;
IO_CACHE tempfile, tempfile_for_exceptions;
DBUG_ENTER("_create_index_by_sort");
- DBUG_PRINT("enter",("sort_length: %d", info->key_length));
+ DBUG_PRINT("enter",("sort_length: %u", info->key_length));
if (info->keyinfo->flag & HA_VAR_LENGTH_KEY)
{
@@ -130,42 +132,60 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
sort_keys= (uchar **) NULL; error= 1;
maxbuffer=1;
- memavl= max(sortbuff_size, MIN_SORT_BUFFER);
+ memavl= MY_MAX(sortbuff_size, MIN_SORT_BUFFER);
records= info->sort_info->max_records;
sort_length= info->key_length;
LINT_INIT(keys);
- if ((memavl - sizeof(BUFFPEK)) / (sort_length + sizeof(char *)) > UINT_MAX32)
- memavl= sizeof(BUFFPEK) + UINT_MAX32 * (sort_length + sizeof(char *));
-
while (memavl >= MIN_SORT_BUFFER)
{
- if ((records < UINT_MAX32) &&
- ((my_off_t) (records + 1) *
- (sort_length + sizeof(char*)) <= (my_off_t) memavl))
- keys= (uint)records+1;
+ /* Check if we can fit all keys into memory */
+ if (((ulonglong) (records + 1) *
+ (sort_length + sizeof(char*)) <= memavl))
+ keys= records+1;
+ else if ((info->sort_info->param->testflag &
+ (T_FORCE_SORT_MEMORY | T_CREATE_MISSING_KEYS)) ==
+ T_FORCE_SORT_MEMORY)
+ {
+ /*
+ Use all of the given sort buffer for key data.
+ Allocate 1000 buffers at a start for new data. More buffers
+ will be allocated when needed.
+ */
+ keys= memavl / (sort_length+sizeof(char*));
+ maxbuffer= (uint) MY_MIN((ulonglong) 1000, (records / keys)+1);
+ }
else
+ {
+ /*
+ All keys can't fit in memory.
+ Calculate how many keys + buffers we can keep in memory
+ */
+ uint maxbuffer_org;
do
{
- skr=maxbuffer;
- if (memavl < sizeof(BUFFPEK)*(uint) maxbuffer ||
- (keys=(memavl-sizeof(BUFFPEK)*(uint) maxbuffer)/
+ maxbuffer_org= maxbuffer;
+ if (memavl < sizeof(BUFFPEK) * maxbuffer ||
+ (keys= (memavl-sizeof(BUFFPEK)*maxbuffer)/
(sort_length+sizeof(char*))) <= 1 ||
- keys < (uint) maxbuffer)
+ keys < maxbuffer)
{
mi_check_print_error(info->sort_info->param,
- "myisam_sort_buffer_size is too small");
+ "myisam_sort_buffer_size is too small. Current myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
+ sortbuff_size, (ulonglong) records,
+ sort_length);
my_errno= ENOMEM;
goto err;
}
}
- while ((maxbuffer= (int) (records/(keys-1)+1)) != skr);
+ while ((maxbuffer= (uint) (records/(keys-1)+1)) != maxbuffer_org);
+ }
if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+
HA_FT_MAXBYTELEN, MYF(0))))
{
if (my_init_dynamic_array(&buffpek, sizeof(BUFFPEK), maxbuffer,
- maxbuffer/2))
+ MY_MIN(maxbuffer/2, 1000), MYF(0)))
{
my_free(sort_keys);
sort_keys= 0;
@@ -179,24 +199,30 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
}
if (memavl < MIN_SORT_BUFFER)
{
- mi_check_print_error(info->sort_info->param,"MyISAM sort buffer too small"); /* purecov: tested */
- my_errno= ENOMEM; /* purecov: tested */
- goto err; /* purecov: tested */
+ /* purecov: begin inspected */
+ mi_check_print_error(info->sort_info->param,
+ "myisam_sort_buffer_size is too small. Current myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
+ sortbuff_size, (ulonglong) records, sort_length);
+ my_errno= ENOMEM;
+ goto err;
+ /* purecov: end inspected */
}
(*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */
if (!no_messages)
- printf(" - Searching for keys, allocating buffer for %d keys\n",keys);
+ my_fprintf(stdout,
+ " - Searching for keys, allocating buffer for %llu keys\n",
+ (ulonglong) keys);
- if ((records=find_all_keys(info,keys,sort_keys,&buffpek,&maxbuffer,
- &tempfile,&tempfile_for_exceptions))
+ if ((records= find_all_keys(info,keys,sort_keys,&buffpek,&maxbuffer,
+ &tempfile,&tempfile_for_exceptions))
== HA_POS_ERROR)
goto err; /* purecov: tested */
if (maxbuffer == 0)
{
if (!no_messages)
- printf(" - Dumping %lu keys\n", (ulong) records);
- if (write_index(info,sort_keys, (uint) records))
+ my_fprintf(stdout, " - Dumping %llu keys\n", (ulonglong) records);
+ if (write_index(info, sort_keys, (ha_keys) records))
goto err; /* purecov: inspected */
}
else
@@ -205,7 +231,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
if (maxbuffer >= MERGEBUFF2)
{
if (!no_messages)
- printf(" - Merging %lu keys\n", (ulong) records); /* purecov: tested */
+ my_fprintf(stdout, " - Merging %llu keys\n",
+ (ulonglong) records); /* purecov: tested */
if (merge_many_buff(info,keys,sort_keys,
dynamic_element(&buffpek,0,BUFFPEK *),&maxbuffer,&tempfile))
goto err; /* purecov: inspected */
@@ -259,13 +286,13 @@ err:
/* Search after all keys and place them in a temp. file */
-static ha_rows find_all_keys(MI_SORT_PARAM *info, uint keys,
+static ha_rows find_all_keys(MI_SORT_PARAM *info, ha_rows keys,
uchar **sort_keys, DYNAMIC_ARRAY *buffpek,
- int *maxbuffer, IO_CACHE *tempfile,
+ uint *maxbuffer, IO_CACHE *tempfile,
IO_CACHE *tempfile_for_exceptions)
{
int error;
- uint idx;
+ ha_rows idx;
DBUG_ENTER("find_all_keys");
idx=error=0;
@@ -314,9 +341,10 @@ pthread_handler_t thr_find_all_keys(void *arg)
{
MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg;
int error;
- ulonglong memavl, old_memavl;
- uint keys, sort_length;
- uint idx, maxbuffer;
+ ulonglong memavl, old_memavl, sortbuff_size;
+ ha_keys keys, idx;
+ uint sort_length;
+ uint maxbuffer;
uchar **sort_keys=0;
LINT_INIT(keys);
@@ -351,37 +379,47 @@ pthread_handler_t thr_find_all_keys(void *arg)
bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
sort_keys= (uchar **) NULL;
- memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
- idx= (uint)sort_param->sort_info->max_records;
+ sortbuff_size= sort_param->sortbuff_size;
+ memavl= MY_MAX(sortbuff_size, MIN_SORT_BUFFER);
+ idx= (ha_keys) sort_param->sort_info->max_records;
sort_length= sort_param->key_length;
maxbuffer= 1;
- if ((memavl - sizeof(BUFFPEK)) / (sort_length +
- sizeof(char *)) > UINT_MAX32)
- memavl= sizeof(BUFFPEK) + UINT_MAX32 * (sort_length + sizeof(char *));
-
while (memavl >= MIN_SORT_BUFFER)
{
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
(my_off_t) memavl)
keys= idx+1;
+ else if ((sort_param->sort_info->param->testflag &
+ (T_FORCE_SORT_MEMORY | T_CREATE_MISSING_KEYS)) ==
+ T_FORCE_SORT_MEMORY)
+ {
+ /*
+ Use all of the given sort buffer for key data.
+ Allocate 1000 buffers at a start for new data. More buffers
+ will be allocated when needed.
+ */
+ keys= memavl / (sort_length+sizeof(char*));
+ maxbuffer= (uint) MY_MIN((ulonglong) 1000, (idx / keys)+1);
+ }
else
{
- uint skr;
+ uint maxbuffer_org;
do
{
- skr= maxbuffer;
+ maxbuffer_org= maxbuffer;
if (memavl < sizeof(BUFFPEK)*maxbuffer ||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
(sort_length+sizeof(char*))) <= 1 ||
keys < (uint) maxbuffer)
{
mi_check_print_error(sort_param->sort_info->param,
- "myisam_sort_buffer_size is too small");
+ "myisam_sort_buffer_size is too small. Current myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
+ sortbuff_size, (ulonglong) idx, sort_length);
goto err;
}
}
- while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
+ while ((maxbuffer= (uint) (idx/(keys-1)+1)) != maxbuffer_org);
}
if ((sort_keys= (uchar**)
my_malloc(keys*(sort_length+sizeof(char*))+
@@ -389,7 +427,7 @@ pthread_handler_t thr_find_all_keys(void *arg)
HA_FT_MAXBYTELEN : 0), MYF(0))))
{
if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK),
- maxbuffer, maxbuffer/2))
+ maxbuffer, MY_MIN(maxbuffer/2, 1000), MYF(0)))
{
my_free(sort_keys);
sort_keys= (uchar **) NULL; /* for err: label */
@@ -404,14 +442,19 @@ pthread_handler_t thr_find_all_keys(void *arg)
}
if (memavl < MIN_SORT_BUFFER)
{
+ /* purecov: begin inspected */
mi_check_print_error(sort_param->sort_info->param,
- "MyISAM sort buffer too small");
- goto err; /* purecov: tested */
+ "myisam_sort_buffer_size is too small. Current myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
+ sortbuff_size, (ulonglong) idx, sort_length);
+ my_errno= ENOMEM;
+ goto err;
+ /* purecov: end inspected */
}
if (sort_param->sort_info->param->testflag & T_VERBOSE)
- printf("Key %d - Allocating buffer for %d keys\n",
- sort_param->key + 1, keys);
+ my_fprintf(stdout,
+ "Key %d - Allocating buffer for %llu keys\n",
+ sort_param->key + 1, (ulonglong) keys);
sort_param->sort_keys= sort_keys;
idx= error= 0;
@@ -436,7 +479,8 @@ pthread_handler_t thr_find_all_keys(void *arg)
&sort_param->tempfile))
goto err;
sort_keys[0]= (uchar*) (sort_keys+keys);
- memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length);
+ memcpy(sort_keys[0], sort_keys[idx - 1],
+ (size_t) sort_param->key_length);
idx= 1;
}
sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
@@ -454,7 +498,6 @@ pthread_handler_t thr_find_all_keys(void *arg)
else
sort_param->keys= idx;
- sort_param->sort_keys_length= keys;
goto ok;
err:
@@ -499,7 +542,8 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
{
MI_SORT_INFO *sort_info=sort_param->sort_info;
HA_CHECK *param=sort_info->param;
- ulong UNINIT_VAR(length), keys;
+ ulonglong UNINIT_VAR(length);
+ ha_rows keys;
ulong *rec_per_key_part=param->rec_per_key_part;
int got_error=sort_info->got_error;
uint i;
@@ -527,7 +571,9 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
{
if (param->testflag & T_VERBOSE)
{
- printf("Key %d - Dumping %u keys\n",sinfo->key+1, sinfo->keys);
+ my_fprintf(stdout,
+ "Key %d - Dumping %llu keys\n", sinfo->key+1,
+ (ulonglong) sinfo->keys);
fflush(stdout);
}
if (write_index(sinfo, sinfo->sort_keys, sinfo->keys) ||
@@ -584,10 +630,12 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
if (maxbuffer >= MERGEBUFF2)
{
if (param->testflag & T_VERBOSE)
- printf("Key %d - Merging %u keys\n",sinfo->key+1, sinfo->keys);
+ my_fprintf(stdout,
+ "Key %d - Merging %llu keys\n",
+ sinfo->key+1, (ulonglong) sinfo->keys);
if (merge_many_buff(sinfo, keys, (uchar **)mergebuf,
dynamic_element(&sinfo->buffpek, 0, BUFFPEK *),
- (int*) &maxbuffer, &sinfo->tempfile))
+ &maxbuffer, &sinfo->tempfile))
{
got_error=1;
continue;
@@ -651,12 +699,15 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
/* Write all keys in memory to file for later merge */
static int write_keys(MI_SORT_PARAM *info, register uchar **sort_keys,
- uint count, BUFFPEK *buffpek, IO_CACHE *tempfile)
+ ha_keys count, BUFFPEK *buffpek, IO_CACHE *tempfile)
{
uchar **end;
uint sort_length=info->key_length;
DBUG_ENTER("write_keys");
+ if (!buffpek)
+ DBUG_RETURN(1); /* Out of memory */
+
my_qsort2((uchar*) sort_keys,count,sizeof(uchar*),(qsort2_cmp) info->key_cmp,
info);
if (!my_b_inited(tempfile) &&
@@ -669,7 +720,7 @@ static int write_keys(MI_SORT_PARAM *info, register uchar **sort_keys,
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
{
- if (my_b_write(tempfile,(uchar*) *sort_keys,(uint) sort_length))
+ if (my_b_write(tempfile,(uchar*) *sort_keys, sort_length))
DBUG_RETURN(1); /* purecov: inspected */
}
DBUG_RETURN(0);
@@ -693,13 +744,16 @@ my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs)
static int write_keys_varlen(MI_SORT_PARAM *info,
register uchar **sort_keys,
- uint count, BUFFPEK *buffpek,
+ ha_keys count, BUFFPEK *buffpek,
IO_CACHE *tempfile)
{
uchar **end;
int err;
DBUG_ENTER("write_keys_varlen");
+ if (!buffpek)
+ DBUG_RETURN(1); /* Out of memory */
+
my_qsort2((uchar*) sort_keys,count,sizeof(uchar*),(qsort2_cmp) info->key_cmp,
info);
if (!my_b_inited(tempfile) &&
@@ -738,7 +792,7 @@ static int write_key(MI_SORT_PARAM *info, uchar *key, IO_CACHE *tempfile)
/* Write index */
static int write_index(MI_SORT_PARAM *info, register uchar **sort_keys,
- register uint count)
+ register ha_keys count)
{
DBUG_ENTER("write_index");
@@ -755,11 +809,11 @@ static int write_index(MI_SORT_PARAM *info, register uchar **sort_keys,
/* Merge buffers to make < MERGEBUFF2 buffers */
-static int merge_many_buff(MI_SORT_PARAM *info, uint keys,
+static int merge_many_buff(MI_SORT_PARAM *info, ha_keys keys,
uchar **sort_keys, BUFFPEK *buffpek,
- int *maxbuffer, IO_CACHE *t_file)
+ uint *maxbuffer, IO_CACHE *t_file)
{
- register int i;
+ register uint i;
IO_CACHE t_file2, *from_file, *to_file, *temp;
BUFFPEK *lastbuff;
DBUG_ENTER("merge_many_buff");
@@ -777,7 +831,7 @@ static int merge_many_buff(MI_SORT_PARAM *info, uint keys,
reinit_io_cache(from_file,READ_CACHE,0L,0,0);
reinit_io_cache(to_file,WRITE_CACHE,0L,0,0);
lastbuff=buffpek;
- for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
+ for (i=0 ; i + MERGEBUFF*3/2 <= *maxbuffer ; i+=MERGEBUFF)
{
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
buffpek+i,buffpek+i+MERGEBUFF-1))
@@ -789,7 +843,7 @@ static int merge_many_buff(MI_SORT_PARAM *info, uint keys,
if (flush_io_cache(to_file))
break; /* purecov: inspected */
temp=from_file; from_file=to_file; to_file=temp;
- *maxbuffer= (int) (lastbuff-buffpek)-1;
+ *maxbuffer= (uint) (lastbuff-buffpek)-1;
}
cleanup:
close_cached_file(to_file); /* This holds old result */
@@ -818,35 +872,36 @@ cleanup:
-1 Error
*/
-static uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
- uint sort_length)
+static my_off_t read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
+ uint sort_length)
{
- register uint count;
- uint length;
+ register ha_keys count;
+ my_off_t length;
- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
+ if ((count= (ha_keys) MY_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
{
if (mysql_file_pread(fromfile->file, (uchar*) buffpek->base,
- (length= sort_length*count),
+ (length= sort_length * count),
buffpek->file_pos, MYF_RW))
- return((uint) -1); /* purecov: inspected */
+ return(HA_OFFSET_ERROR); /* purecov: inspected */
buffpek->key=buffpek->base;
- buffpek->file_pos+= length; /* New filepos */
+ buffpek->file_pos+= length; /* New filepos */
buffpek->count-= count;
buffpek->mem_count= count;
}
- return (count*sort_length);
+ return (((my_off_t) count) * sort_length);
} /* read_to_buffer */
-static uint read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
- uint sort_length)
+
+static my_off_t read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
+ uint sort_length)
{
- register uint count;
+ register ha_keys count;
uint16 length_of_key = 0;
uint idx;
uchar *buffp;
- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
+ if ((count= (ha_keys) MY_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
{
buffp = buffpek->base;
@@ -854,11 +909,11 @@ static uint read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
{
if (mysql_file_pread(fromfile->file, (uchar*)&length_of_key,
sizeof(length_of_key), buffpek->file_pos, MYF_RW))
- return((uint) -1);
+ return(HA_OFFSET_ERROR);
buffpek->file_pos+=sizeof(length_of_key);
if (mysql_file_pread(fromfile->file, (uchar*) buffp,
length_of_key, buffpek->file_pos, MYF_RW))
- return((uint) -1);
+ return(HA_OFFSET_ERROR);
buffpek->file_pos+=length_of_key;
buffp = buffp + sort_length;
}
@@ -866,15 +921,15 @@ static uint read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
buffpek->count-= count;
buffpek->mem_count= count;
}
- return (count*sort_length);
+ return (((my_off_t) count) * sort_length);
} /* read_to_buffer_varlen */
static int write_merge_key_varlen(MI_SORT_PARAM *info,
IO_CACHE *to_file, uchar* key,
- uint sort_length, uint count)
+ uint sort_length, ha_keys count)
{
- uint idx;
+ ha_keys idx;
uchar *bufs = key;
for (idx=1;idx<=count;idx++)
@@ -890,32 +945,37 @@ static int write_merge_key_varlen(MI_SORT_PARAM *info,
static int write_merge_key(MI_SORT_PARAM *info __attribute__((unused)),
IO_CACHE *to_file, uchar *key,
- uint sort_length, uint count)
+ uint sort_length, ha_keys count)
{
- return my_b_write(to_file, key, (size_t) sort_length*count);
+ return my_b_write(to_file, key, ((size_t) sort_length) * count);
}
/*
Merge buffers to one buffer
If to_file == 0 then use info->key_write
+
+ Return:
+ 0 ok
+ 1 error
*/
static int
-merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
+merge_buffers(MI_SORT_PARAM *info, ha_keys keys, IO_CACHE *from_file,
IO_CACHE *to_file, uchar **sort_keys, BUFFPEK *lastbuff,
BUFFPEK *Fb, BUFFPEK *Tb)
{
- int error;
- uint sort_length,maxcount;
+ int error= 1;
+ uint sort_length;
+ ha_keys maxcount;
ha_rows count;
- my_off_t UNINIT_VAR(to_start_filepos);
+ my_off_t UNINIT_VAR(to_start_filepos), read_length;
uchar *strpos;
BUFFPEK *buffpek,**refpek;
QUEUE queue;
DBUG_ENTER("merge_buffers");
count=error=0;
- maxcount=keys/((uint) (Tb-Fb) +1);
+ maxcount= keys/((uint) (Tb-Fb) +1);
DBUG_ASSERT(maxcount > 0);
LINT_INIT(to_start_filepos);
if (to_file)
@@ -932,10 +992,10 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
{
count+= buffpek->count;
buffpek->base= (uchar*) strpos;
- buffpek->max_keys=maxcount;
- strpos+= (uint) (error=(int) info->read_to_buffer(from_file,buffpek,
- sort_length));
- if (error == -1)
+ buffpek->max_keys= maxcount;
+ strpos+= (read_length= info->read_to_buffer(from_file,buffpek,
+ sort_length));
+ if (read_length == HA_OFFSET_ERROR)
goto err; /* purecov: inspected */
queue_insert(&queue,(uchar*) buffpek);
}
@@ -966,10 +1026,9 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
/* It's enough to check for killedptr before a slow operation */
if (killed_ptr(info->sort_info->param))
{
- error=1;
goto err;
}
- if (!(error=(int) info->read_to_buffer(from_file,buffpek,sort_length)))
+ if (!(read_length= info->read_to_buffer(from_file,buffpek,sort_length)))
{
uchar *base= buffpek->base;
uint max_keys=buffpek->max_keys;
@@ -996,9 +1055,9 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
}
break; /* One buffer have been removed */
}
+ else if (read_length == HA_OFFSET_ERROR)
+ goto err; /* purecov: inspected */
}
- else if (error == -1)
- goto err; /* purecov: inspected */
queue_replace_top(&queue); /* Top element has been replaced */
}
}
@@ -1030,8 +1089,9 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
}
}
}
- while ((error=(int) info->read_to_buffer(from_file,buffpek,sort_length)) != -1 &&
- error != 0);
+ while ((read_length= info->read_to_buffer(from_file,buffpek,sort_length)) != HA_OFFSET_ERROR && read_length != 0);
+ if (read_length == 0)
+ error= 0;
lastbuff->count=count;
if (to_file)
@@ -1045,8 +1105,8 @@ err:
/* Do a merge to output-file (save only positions) */
static int
-merge_index(MI_SORT_PARAM *info, uint keys, uchar **sort_keys,
- BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile)
+merge_index(MI_SORT_PARAM *info, ha_keys keys, uchar **sort_keys,
+ BUFFPEK *buffpek, uint maxbuffer, IO_CACHE *tempfile)
{
DBUG_ENTER("merge_index");
if (merge_buffers(info,keys,tempfile,(IO_CACHE*) 0,sort_keys,buffpek,buffpek,
@@ -1055,6 +1115,7 @@ merge_index(MI_SORT_PARAM *info, uint keys, uchar **sort_keys,
DBUG_RETURN(0);
} /* merge_index */
+
static int
flush_ft_buf(MI_SORT_PARAM *info)
{
@@ -1067,4 +1128,3 @@ flush_ft_buf(MI_SORT_PARAM *info)
}
return err;
}
-