Commit 8144eb5a authored by unknown's avatar unknown

Merge bk-internal.mysql.com:/home/bk/mysql-5.1

into  chilla.local:/home/mydev/mysql-5.1-merge


include/my_sys.h:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/sql_select.cc:
  Auto merged
parents ddee02ec 53630245
...@@ -341,12 +341,18 @@ typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*); ...@@ -341,12 +341,18 @@ typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*);
#ifdef THREAD #ifdef THREAD
typedef struct st_io_cache_share typedef struct st_io_cache_share
{ {
/* to sync on reads into buffer */ pthread_mutex_t mutex; /* To sync on reads into buffer. */
pthread_mutex_t mutex; pthread_cond_t cond; /* To wait for signals. */
pthread_cond_t cond; pthread_cond_t cond_writer; /* For a synchronized writer. */
int count, total; /* Offset in file corresponding to the first byte of buffer. */
/* actual IO_CACHE that filled the buffer */ my_off_t pos_in_file;
struct st_io_cache *active; /* If a synchronized write cache is the source of the data. */
struct st_io_cache *source_cache;
byte *buffer; /* The read buffer. */
byte *read_end; /* Behind last valid byte of buffer. */
int running_threads; /* threads not in lock. */
int total_threads; /* threads sharing the cache. */
int error; /* Last error. */
#ifdef NOT_YET_IMPLEMENTED #ifdef NOT_YET_IMPLEMENTED
/* whether the structure should be free'd */ /* whether the structure should be free'd */
my_bool alloced; my_bool alloced;
...@@ -720,8 +726,8 @@ extern void setup_io_cache(IO_CACHE* info); ...@@ -720,8 +726,8 @@ extern void setup_io_cache(IO_CACHE* info);
extern int _my_b_read(IO_CACHE *info,byte *Buffer,uint Count); extern int _my_b_read(IO_CACHE *info,byte *Buffer,uint Count);
#ifdef THREAD #ifdef THREAD
extern int _my_b_read_r(IO_CACHE *info,byte *Buffer,uint Count); extern int _my_b_read_r(IO_CACHE *info,byte *Buffer,uint Count);
extern void init_io_cache_share(IO_CACHE *info, extern void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare,
IO_CACHE_SHARE *s, uint num_threads); IO_CACHE *write_cache, uint num_threads);
extern void remove_io_thread(IO_CACHE *info); extern void remove_io_thread(IO_CACHE *info);
#endif #endif
extern int _my_b_seq_read(IO_CACHE *info,byte *Buffer,uint Count); extern int _my_b_seq_read(IO_CACHE *info,byte *Buffer,uint Count);
......
...@@ -419,7 +419,7 @@ typedef struct st_mi_check_param ...@@ -419,7 +419,7 @@ typedef struct st_mi_check_param
uint testflag, key_cache_block_size; uint testflag, key_cache_block_size;
uint8 language; uint8 language;
my_bool using_global_keycache, opt_lock_memory, opt_follow_links; my_bool using_global_keycache, opt_lock_memory, opt_follow_links;
my_bool retry_repair, force_sort, calc_checksum; my_bool retry_repair, force_sort;
char temp_filename[FN_REFLEN],*isam_file_name; char temp_filename[FN_REFLEN],*isam_file_name;
MY_TMPDIR *tmpdir; MY_TMPDIR *tmpdir;
int tmpfile_createflag; int tmpfile_createflag;
......
...@@ -796,6 +796,132 @@ a b ...@@ -796,6 +796,132 @@ a b
xxxxxxxxx bbbbbb xxxxxxxxx bbbbbb
xxxxxxxxx bbbbbb xxxxxxxxx bbbbbb
DROP TABLE t1; DROP TABLE t1;
SET @@myisam_repair_threads=2;
SHOW VARIABLES LIKE 'myisam_repair%';
Variable_name Value
myisam_repair_threads 2
CREATE TABLE t1 (
`_id` int(11) NOT NULL default '0',
`url` text,
`email` text,
`description` text,
`loverlap` int(11) default NULL,
`roverlap` int(11) default NULL,
`lneighbor_id` int(11) default NULL,
`rneighbor_id` int(11) default NULL,
`length_` int(11) default NULL,
`sequence` mediumtext,
`name` text,
`_obj_class` text NOT NULL,
PRIMARY KEY (`_id`),
UNIQUE KEY `sequence_name_index` (`name`(50)),
KEY (`length_`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO t1 VALUES
(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
(2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
(3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample3',''),
(4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample4',''),
(5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample5',''),
(6,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample6',''),
(7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample7',''),
(8,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample8',''),
(9,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample9','');
SELECT _id FROM t1;
_id
1
2
3
4
5
6
7
8
9
DELETE FROM t1 WHERE _id < 8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MyISAM 10 Dynamic 2 # # # # 140 # # # # # #
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MyISAM 10 Dynamic 2 # # # # 0 # # # # # #
SELECT _id FROM t1;
_id
8
9
DROP TABLE t1;
CREATE TABLE t1 (
`_id` int(11) NOT NULL default '0',
`url` text,
`email` text,
`description` text,
`loverlap` int(11) default NULL,
`roverlap` int(11) default NULL,
`lneighbor_id` int(11) default NULL,
`rneighbor_id` int(11) default NULL,
`length_` int(11) default NULL,
`sequence` mediumtext,
`name` text,
`_obj_class` text NOT NULL,
PRIMARY KEY (`_id`),
UNIQUE KEY `sequence_name_index` (`name`(50)),
KEY (`length_`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO t1 VALUES
(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
(2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
(3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample3',''),
(4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample4',''),
(5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample5',''),
(6,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample6',''),
(7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample7',''),
(8,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample8',''),
(9,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample9','');
SELECT _id FROM t1;
_id
1
2
3
4
5
6
7
8
9
DELETE FROM t1 WHERE _id < 8;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MyISAM 10 Dynamic 2 # # # # 140 # # # # # #
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
REPAIR TABLE t1 QUICK;
Table Op Msg_type Msg_text
test.t1 repair status OK
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MyISAM 10 Dynamic 2 # # # # 140 # # # # # #
SELECT _id FROM t1;
_id
8
9
DROP TABLE t1;
SET @@myisam_repair_threads=1;
SHOW VARIABLES LIKE 'myisam_repair%';
Variable_name Value
myisam_repair_threads 1
set storage_engine=MyISAM; set storage_engine=MyISAM;
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3;
--- Testing varchar --- --- Testing varchar ---
......
...@@ -755,6 +755,97 @@ SELECT * FROM t1; ...@@ -755,6 +755,97 @@ SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
# #
# Bug#8283 - OPTIMIZE TABLE causes data loss
#
SET @@myisam_repair_threads=2;
SHOW VARIABLES LIKE 'myisam_repair%';
#
# Test OPTIMIZE. This creates a new data file.
CREATE TABLE t1 (
`_id` int(11) NOT NULL default '0',
`url` text,
`email` text,
`description` text,
`loverlap` int(11) default NULL,
`roverlap` int(11) default NULL,
`lneighbor_id` int(11) default NULL,
`rneighbor_id` int(11) default NULL,
`length_` int(11) default NULL,
`sequence` mediumtext,
`name` text,
`_obj_class` text NOT NULL,
PRIMARY KEY (`_id`),
UNIQUE KEY `sequence_name_index` (`name`(50)),
KEY (`length_`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
#
INSERT INTO t1 VALUES
(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
(2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
(3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample3',''),
(4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample4',''),
(5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample5',''),
(6,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample6',''),
(7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample7',''),
(8,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample8',''),
(9,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample9','');
#
SELECT _id FROM t1;
DELETE FROM t1 WHERE _id < 8;
--replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
SHOW TABLE STATUS LIKE 't1';
CHECK TABLE t1 EXTENDED;
OPTIMIZE TABLE t1;
CHECK TABLE t1 EXTENDED;
--replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
SHOW TABLE STATUS LIKE 't1';
SELECT _id FROM t1;
DROP TABLE t1;
#
# Test REPAIR QUICK. This retains the old data file.
CREATE TABLE t1 (
`_id` int(11) NOT NULL default '0',
`url` text,
`email` text,
`description` text,
`loverlap` int(11) default NULL,
`roverlap` int(11) default NULL,
`lneighbor_id` int(11) default NULL,
`rneighbor_id` int(11) default NULL,
`length_` int(11) default NULL,
`sequence` mediumtext,
`name` text,
`_obj_class` text NOT NULL,
PRIMARY KEY (`_id`),
UNIQUE KEY `sequence_name_index` (`name`(50)),
KEY (`length_`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
#
INSERT INTO t1 VALUES
(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
(2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
(3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample3',''),
(4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample4',''),
(5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample5',''),
(6,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample6',''),
(7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample7',''),
(8,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample8',''),
(9,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample9','');
#
SELECT _id FROM t1;
DELETE FROM t1 WHERE _id < 8;
--replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
SHOW TABLE STATUS LIKE 't1';
CHECK TABLE t1 EXTENDED;
REPAIR TABLE t1 QUICK;
CHECK TABLE t1 EXTENDED;
--replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
SHOW TABLE STATUS LIKE 't1';
SELECT _id FROM t1;
DROP TABLE t1;
#
SET @@myisam_repair_threads=1;
SHOW VARIABLES LIKE 'myisam_repair%';
# Test varchar # Test varchar
# #
......
This diff is collapsed.
...@@ -150,7 +150,7 @@ MY_LOCALE *my_locale_by_name(const char *name); ...@@ -150,7 +150,7 @@ MY_LOCALE *my_locale_by_name(const char *name);
Feel free to raise this by the smallest amount you can to get the Feel free to raise this by the smallest amount you can to get the
"execution_constants" test to pass. "execution_constants" test to pass.
*/ */
#define STACK_MIN_SIZE 9336 // Abort if less stack during eval. #define STACK_MIN_SIZE 10788 // Abort if less stack during eval.
#define STACK_MIN_SIZE_FOR_OPEN 1024*80 #define STACK_MIN_SIZE_FOR_OPEN 1024*80
#define STACK_BUFF_ALLOC 256 // For stack overrun checks #define STACK_BUFF_ALLOC 256 // For stack overrun checks
......
...@@ -1378,12 +1378,13 @@ JOIN::exec() ...@@ -1378,12 +1378,13 @@ JOIN::exec()
thd->examined_row_count= 0; thd->examined_row_count= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* /*
don't reset the found rows count if there're no tables Don't reset the found rows count if there're no tables as
as FOUND_ROWS() may be called. FOUND_ROWS() may be called. Never reset the examined row count here.
*/ It must be accumulated from all join iterations of all join parts.
*/
if (tables) if (tables)
thd->limit_found_rows= thd->examined_row_count= 0; thd->limit_found_rows= 0;
if (zero_result_cause) if (zero_result_cause)
{ {
...@@ -1431,6 +1432,12 @@ JOIN::exec() ...@@ -1431,6 +1432,12 @@ JOIN::exec()
List<Item> *curr_all_fields= &all_fields; List<Item> *curr_all_fields= &all_fields;
List<Item> *curr_fields_list= &fields_list; List<Item> *curr_fields_list= &fields_list;
TABLE *curr_tmp_table= 0; TABLE *curr_tmp_table= 0;
/*
Initialize examined rows here because the values from all join parts
must be accumulated in examined_row_count. Hence every join
iteration must count from zero.
*/
curr_join->examined_rows= 0;
if ((curr_join->select_lex->options & OPTION_SCHEMA_TABLE) && if ((curr_join->select_lex->options & OPTION_SCHEMA_TABLE) &&
get_schema_tables_result(curr_join)) get_schema_tables_result(curr_join))
...@@ -1853,9 +1860,12 @@ JOIN::exec() ...@@ -1853,9 +1860,12 @@ JOIN::exec()
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
error= do_select(curr_join, curr_fields_list, NULL, procedure); error= do_select(curr_join, curr_fields_list, NULL, procedure);
thd->limit_found_rows= curr_join->send_records; thd->limit_found_rows= curr_join->send_records;
thd->examined_row_count= curr_join->examined_rows;
} }
/* Accumulate the counts from all join iterations of all join parts. */
thd->examined_row_count+= curr_join->examined_rows;
DBUG_PRINT("counts", ("thd->examined_row_count: %lu",
(ulong) thd->examined_row_count));
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -10352,6 +10362,8 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, ...@@ -10352,6 +10362,8 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
*/ */
join->examined_rows++; join->examined_rows++;
join->thd->row_count++; join->thd->row_count++;
DBUG_PRINT("counts", ("join->examined_rows++: %lu",
(ulong) join->examined_rows));
if (found) if (found)
{ {
......
This diff is collapsed.
...@@ -219,7 +219,10 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -219,7 +219,10 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
((open_flags & HA_OPEN_ABORT_IF_CRASHED) && ((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
(my_disable_locking && share->state.open_count)))) (my_disable_locking && share->state.open_count))))
{ {
DBUG_PRINT("error",("Table is marked as crashed")); DBUG_PRINT("error",("Table is marked as crashed. open_flags: %u "
"changed: %u open_count: %u !locking: %d",
open_flags, share->state.changed,
share->state.open_count, my_disable_locking));
my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ? my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE); HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
goto err; goto err;
......
...@@ -103,7 +103,8 @@ static uint fill_and_get_bits(MI_BIT_BUFF *bit_buff,uint count); ...@@ -103,7 +103,8 @@ static uint fill_and_get_bits(MI_BIT_BUFF *bit_buff,uint count);
static void fill_buffer(MI_BIT_BUFF *bit_buff); static void fill_buffer(MI_BIT_BUFF *bit_buff);
static uint max_bit(uint value); static uint max_bit(uint value);
#ifdef HAVE_MMAP #ifdef HAVE_MMAP
static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info, static uchar *_mi_mempack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
MI_BLOCK_INFO *info, byte **rec_buff_p,
uchar *header); uchar *header);
#endif #endif
...@@ -449,13 +450,15 @@ int _mi_read_pack_record(MI_INFO *info, my_off_t filepos, byte *buf) ...@@ -449,13 +450,15 @@ int _mi_read_pack_record(MI_INFO *info, my_off_t filepos, byte *buf)
DBUG_RETURN(-1); /* _search() didn't find record */ DBUG_RETURN(-1); /* _search() didn't find record */
file=info->dfile; file=info->dfile;
if (_mi_pack_get_block_info(info, &block_info, file, filepos)) if (_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
&info->rec_buff, file, filepos))
goto err; goto err;
if (my_read(file,(byte*) info->rec_buff + block_info.offset , if (my_read(file,(byte*) info->rec_buff + block_info.offset ,
block_info.rec_len - block_info.offset, MYF(MY_NABP))) block_info.rec_len - block_info.offset, MYF(MY_NABP)))
goto panic; goto panic;
info->update|= HA_STATE_AKTIV; info->update|= HA_STATE_AKTIV;
DBUG_RETURN(_mi_pack_rec_unpack(info,buf,info->rec_buff,block_info.rec_len)); DBUG_RETURN(_mi_pack_rec_unpack(info, &info->bit_buff, buf,
info->rec_buff, block_info.rec_len));
panic: panic:
my_errno=HA_ERR_WRONG_IN_RECORD; my_errno=HA_ERR_WRONG_IN_RECORD;
err: err:
...@@ -464,8 +467,8 @@ int _mi_read_pack_record(MI_INFO *info, my_off_t filepos, byte *buf) ...@@ -464,8 +467,8 @@ int _mi_read_pack_record(MI_INFO *info, my_off_t filepos, byte *buf)
int _mi_pack_rec_unpack(register MI_INFO *info, register byte *to, byte *from, int _mi_pack_rec_unpack(register MI_INFO *info, MI_BIT_BUFF *bit_buff,
ulong reclength) register byte *to, byte *from, ulong reclength)
{ {
byte *end_field; byte *end_field;
reg3 MI_COLUMNDEF *end; reg3 MI_COLUMNDEF *end;
...@@ -473,18 +476,18 @@ int _mi_pack_rec_unpack(register MI_INFO *info, register byte *to, byte *from, ...@@ -473,18 +476,18 @@ int _mi_pack_rec_unpack(register MI_INFO *info, register byte *to, byte *from,
MYISAM_SHARE *share=info->s; MYISAM_SHARE *share=info->s;
DBUG_ENTER("_mi_pack_rec_unpack"); DBUG_ENTER("_mi_pack_rec_unpack");
init_bit_buffer(&info->bit_buff, (uchar*) from,reclength); init_bit_buffer(bit_buff, (uchar*) from, reclength);
for (current_field=share->rec, end=current_field+share->base.fields ; for (current_field=share->rec, end=current_field+share->base.fields ;
current_field < end ; current_field < end ;
current_field++,to=end_field) current_field++,to=end_field)
{ {
end_field=to+current_field->length; end_field=to+current_field->length;
(*current_field->unpack)(current_field,&info->bit_buff,(uchar*) to, (*current_field->unpack)(current_field, bit_buff, (uchar*) to,
(uchar*) end_field); (uchar*) end_field);
} }
if (! info->bit_buff.error && if (!bit_buff->error &&
info->bit_buff.pos - info->bit_buff.bits/8 == info->bit_buff.end) bit_buff->pos - bit_buff->bits / 8 == bit_buff->end)
DBUG_RETURN(0); DBUG_RETURN(0);
info->update&= ~HA_STATE_AKTIV; info->update&= ~HA_STATE_AKTIV;
DBUG_RETURN(my_errno=HA_ERR_WRONG_IN_RECORD); DBUG_RETURN(my_errno=HA_ERR_WRONG_IN_RECORD);
...@@ -1015,13 +1018,16 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf, ...@@ -1015,13 +1018,16 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf,
if (info->opt_flag & READ_CACHE_USED) if (info->opt_flag & READ_CACHE_USED)
{ {
if (_mi_read_cache(&info->rec_cache,(byte*) block_info.header,filepos, if (_mi_read_cache(&info->rec_cache, (byte*) block_info.header,
share->pack.ref_length, skip_deleted_blocks)) filepos, share->pack.ref_length,
skip_deleted_blocks ? READING_NEXT : 0))
goto err; goto err;
b_type=_mi_pack_get_block_info(info,&block_info,-1, filepos); b_type=_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
&info->rec_buff, -1, filepos);
} }
else else
b_type=_mi_pack_get_block_info(info,&block_info,info->dfile,filepos); b_type=_mi_pack_get_block_info(info, &info->bit_buff, &block_info,
&info->rec_buff, info->dfile, filepos);
if (b_type) if (b_type)
goto err; /* Error code is already set */ goto err; /* Error code is already set */
#ifndef DBUG_OFF #ifndef DBUG_OFF
...@@ -1034,9 +1040,9 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf, ...@@ -1034,9 +1040,9 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf,
if (info->opt_flag & READ_CACHE_USED) if (info->opt_flag & READ_CACHE_USED)
{ {
if (_mi_read_cache(&info->rec_cache,(byte*) info->rec_buff, if (_mi_read_cache(&info->rec_cache, (byte*) info->rec_buff,
block_info.filepos, block_info.rec_len, block_info.filepos, block_info.rec_len,
skip_deleted_blocks)) skip_deleted_blocks ? READING_NEXT : 0))
goto err; goto err;
} }
else else
...@@ -1051,8 +1057,8 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf, ...@@ -1051,8 +1057,8 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf,
info->nextpos=block_info.filepos+block_info.rec_len; info->nextpos=block_info.filepos+block_info.rec_len;
info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED; info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
DBUG_RETURN (_mi_pack_rec_unpack(info,buf,info->rec_buff, DBUG_RETURN (_mi_pack_rec_unpack(info, &info->bit_buff, buf,
block_info.rec_len)); info->rec_buff, block_info.rec_len));
err: err:
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
} }
...@@ -1060,8 +1066,9 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf, ...@@ -1060,8 +1066,9 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf,
/* Read and process header from a huff-record-file */ /* Read and process header from a huff-record-file */
uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BLOCK_INFO *info, File file, uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
my_off_t filepos) MI_BLOCK_INFO *info, byte **rec_buff_p,
File file, my_off_t filepos)
{ {
uchar *header=info->header; uchar *header=info->header;
uint head_length,ref_length; uint head_length,ref_length;
...@@ -1086,17 +1093,17 @@ uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BLOCK_INFO *info, File file, ...@@ -1086,17 +1093,17 @@ uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BLOCK_INFO *info, File file,
head_length+= read_pack_length((uint) myisam->s->pack.version, head_length+= read_pack_length((uint) myisam->s->pack.version,
header + head_length, &info->blob_len); header + head_length, &info->blob_len);
if (!(mi_alloc_rec_buff(myisam,info->rec_len + info->blob_len, if (!(mi_alloc_rec_buff(myisam,info->rec_len + info->blob_len,
&myisam->rec_buff))) rec_buff_p)))
return BLOCK_FATAL_ERROR; /* not enough memory */ return BLOCK_FATAL_ERROR; /* not enough memory */
myisam->bit_buff.blob_pos=(uchar*) myisam->rec_buff+info->rec_len; bit_buff->blob_pos= (uchar*) *rec_buff_p + info->rec_len;
myisam->bit_buff.blob_end= myisam->bit_buff.blob_pos+info->blob_len; bit_buff->blob_end= bit_buff->blob_pos + info->blob_len;
myisam->blob_length=info->blob_len; myisam->blob_length=info->blob_len;
} }
info->filepos=filepos+head_length; info->filepos=filepos+head_length;
if (file > 0) if (file > 0)
{ {
info->offset=min(info->rec_len, ref_length - head_length); info->offset=min(info->rec_len, ref_length - head_length);
memcpy(myisam->rec_buff, header+head_length, info->offset); memcpy(*rec_buff_p, header + head_length, info->offset);
} }
return 0; return 0;
} }
...@@ -1214,7 +1221,8 @@ void _mi_unmap_file(MI_INFO *info) ...@@ -1214,7 +1221,8 @@ void _mi_unmap_file(MI_INFO *info)
} }
static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info, static uchar *_mi_mempack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
MI_BLOCK_INFO *info, byte **rec_buff_p,
uchar *header) uchar *header)
{ {
header+= read_pack_length((uint) myisam->s->pack.version, header, header+= read_pack_length((uint) myisam->s->pack.version, header,
...@@ -1225,10 +1233,10 @@ static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info, ...@@ -1225,10 +1233,10 @@ static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info,
&info->blob_len); &info->blob_len);
/* mi_alloc_rec_buff sets my_errno on error */ /* mi_alloc_rec_buff sets my_errno on error */
if (!(mi_alloc_rec_buff(myisam, info->blob_len, if (!(mi_alloc_rec_buff(myisam, info->blob_len,
&myisam->rec_buff))) rec_buff_p)))
return 0; /* not enough memory */ return 0; /* not enough memory */
myisam->bit_buff.blob_pos=(uchar*) myisam->rec_buff; bit_buff->blob_pos= (uchar*) *rec_buff_p;
myisam->bit_buff.blob_end= (uchar*) myisam->rec_buff + info->blob_len; bit_buff->blob_end= (uchar*) *rec_buff_p + info->blob_len;
} }
return header; return header;
} }
...@@ -1244,11 +1252,13 @@ static int _mi_read_mempack_record(MI_INFO *info, my_off_t filepos, byte *buf) ...@@ -1244,11 +1252,13 @@ static int _mi_read_mempack_record(MI_INFO *info, my_off_t filepos, byte *buf)
if (filepos == HA_OFFSET_ERROR) if (filepos == HA_OFFSET_ERROR)
DBUG_RETURN(-1); /* _search() didn't find record */ DBUG_RETURN(-1); /* _search() didn't find record */
if (!(pos= (byte*) _mi_mempack_get_block_info(info,&block_info, if (!(pos= (byte*) _mi_mempack_get_block_info(info, &info->bit_buff,
&block_info, &info->rec_buff,
(uchar*) share->file_map+ (uchar*) share->file_map+
filepos))) filepos)))
DBUG_RETURN(-1); DBUG_RETURN(-1);
DBUG_RETURN(_mi_pack_rec_unpack(info, buf, pos, block_info.rec_len)); DBUG_RETURN(_mi_pack_rec_unpack(info, &info->bit_buff, buf,
pos, block_info.rec_len));
} }
...@@ -1268,7 +1278,8 @@ static int _mi_read_rnd_mempack_record(MI_INFO *info, byte *buf, ...@@ -1268,7 +1278,8 @@ static int _mi_read_rnd_mempack_record(MI_INFO *info, byte *buf,
my_errno=HA_ERR_END_OF_FILE; my_errno=HA_ERR_END_OF_FILE;
goto err; goto err;
} }
if (!(pos= (byte*) _mi_mempack_get_block_info(info,&block_info, if (!(pos= (byte*) _mi_mempack_get_block_info(info, &info->bit_buff,
&block_info, &info->rec_buff,
(uchar*) (uchar*)
(start=share->file_map+ (start=share->file_map+
filepos)))) filepos))))
...@@ -1285,7 +1296,8 @@ static int _mi_read_rnd_mempack_record(MI_INFO *info, byte *buf, ...@@ -1285,7 +1296,8 @@ static int _mi_read_rnd_mempack_record(MI_INFO *info, byte *buf,
info->nextpos=filepos+(uint) (pos-start)+block_info.rec_len; info->nextpos=filepos+(uint) (pos-start)+block_info.rec_len;
info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED; info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
DBUG_RETURN (_mi_pack_rec_unpack(info,buf,pos, block_info.rec_len)); DBUG_RETURN (_mi_pack_rec_unpack(info, &info->bit_buff, buf,
pos, block_info.rec_len));
err: err:
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
} }
......
...@@ -76,6 +76,7 @@ typedef struct st_mi_state_info ...@@ -76,6 +76,7 @@ typedef struct st_mi_state_info
ulong sec_index_changed; /* Updated when new sec_index */ ulong sec_index_changed; /* Updated when new sec_index */
ulong sec_index_used; /* which extra index are in use */ ulong sec_index_used; /* which extra index are in use */
ulonglong key_map; /* Which keys are in use */ ulonglong key_map; /* Which keys are in use */
ha_checksum checksum; /* Table checksum */
ulong version; /* timestamp of create */ ulong version; /* timestamp of create */
time_t create_time; /* Time when created database */ time_t create_time; /* Time when created database */
time_t recover_time; /* Time for last recover */ time_t recover_time; /* Time for last recover */
...@@ -177,6 +178,7 @@ typedef struct st_mi_isam_share { /* Shared between opens */ ...@@ -177,6 +178,7 @@ typedef struct st_mi_isam_share { /* Shared between opens */
int (*delete_record)(struct st_myisam_info*); int (*delete_record)(struct st_myisam_info*);
int (*read_rnd)(struct st_myisam_info*, byte*, my_off_t, my_bool); int (*read_rnd)(struct st_myisam_info*, byte*, my_off_t, my_bool);
int (*compare_record)(struct st_myisam_info*, const byte *); int (*compare_record)(struct st_myisam_info*, const byte *);
/* Function to use for a row checksum. */
ha_checksum (*calc_checksum)(struct st_myisam_info*, const byte *); ha_checksum (*calc_checksum)(struct st_myisam_info*, const byte *);
int (*compare_unique)(struct st_myisam_info*, MI_UNIQUEDEF *, int (*compare_unique)(struct st_myisam_info*, MI_UNIQUEDEF *,
const byte *record, my_off_t pos); const byte *record, my_off_t pos);
...@@ -262,7 +264,7 @@ struct st_myisam_info { ...@@ -262,7 +264,7 @@ struct st_myisam_info {
my_off_t last_keypage; /* Last key page read */ my_off_t last_keypage; /* Last key page read */
my_off_t last_search_keypage; /* Last keypage when searching */ my_off_t last_search_keypage; /* Last keypage when searching */
my_off_t dupp_key_pos; my_off_t dupp_key_pos;
ha_checksum checksum; ha_checksum checksum; /* Temp storage for row checksum */
/* QQ: the folloing two xxx_length fields should be removed, /* QQ: the folloing two xxx_length fields should be removed,
as they are not compatible with parallel repair */ as they are not compatible with parallel repair */
ulong packed_length,blob_length; /* Length of found, packed record */ ulong packed_length,blob_length; /* Length of found, packed record */
...@@ -314,8 +316,9 @@ typedef struct st_mi_sort_param ...@@ -314,8 +316,9 @@ typedef struct st_mi_sort_param
pthread_t thr; pthread_t thr;
IO_CACHE read_cache, tempfile, tempfile_for_exceptions; IO_CACHE read_cache, tempfile, tempfile_for_exceptions;
DYNAMIC_ARRAY buffpek; DYNAMIC_ARRAY buffpek;
MI_BIT_BUFF bit_buff; /* For parallel repair of packrec. */
/*
/*
The next two are used to collect statistics, see update_key_parts for The next two are used to collect statistics, see update_key_parts for
description. description.
*/ */
...@@ -326,6 +329,7 @@ typedef struct st_mi_sort_param ...@@ -326,6 +329,7 @@ typedef struct st_mi_sort_param
uint key, key_length,real_key_length,sortbuff_size; uint key, key_length,real_key_length,sortbuff_size;
uint maxbuffers, keys, find_length, sort_keys_length; uint maxbuffers, keys, find_length, sort_keys_length;
my_bool fix_datafile, master; my_bool fix_datafile, master;
my_bool calc_checksum; /* calculate table checksum */
MI_KEYDEF *keyinfo; MI_KEYDEF *keyinfo;
HA_KEYSEG *seg; HA_KEYSEG *seg;
SORT_INFO *sort_info; SORT_INFO *sort_info;
...@@ -379,8 +383,15 @@ typedef struct st_mi_sort_param ...@@ -379,8 +383,15 @@ typedef struct st_mi_sort_param
#define mi_putint(x,y,nod) { uint16 boh=(nod ? (uint16) 32768 : 0) + (uint16) (y);\ #define mi_putint(x,y,nod) { uint16 boh=(nod ? (uint16) 32768 : 0) + (uint16) (y);\
mi_int2store(x,boh); } mi_int2store(x,boh); }
#define mi_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0) #define mi_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0)
#define mi_mark_crashed(x) (x)->s->state.changed|=STATE_CRASHED #define mi_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \
#define mi_mark_crashed_on_repair(x) { (x)->s->state.changed|=STATE_CRASHED|STATE_CRASHED_ON_REPAIR ; (x)->update|= HA_STATE_CHANGED; } DBUG_PRINT("error", ("Marked table crashed")); \
}while(0)
#define mi_mark_crashed_on_repair(x) do{(x)->s->state.changed|= \
STATE_CRASHED|STATE_CRASHED_ON_REPAIR; \
(x)->update|= HA_STATE_CHANGED; \
DBUG_PRINT("error", \
("Marked table crashed")); \
}while(0)
#define mi_is_crashed(x) ((x)->s->state.changed & STATE_CRASHED) #define mi_is_crashed(x) ((x)->s->state.changed & STATE_CRASHED)
#define mi_is_crashed_on_repair(x) ((x)->s->state.changed & STATE_CRASHED_ON_REPAIR) #define mi_is_crashed_on_repair(x) ((x)->s->state.changed & STATE_CRASHED_ON_REPAIR)
#define mi_print_error(SHARE, ERRNO) \ #define mi_print_error(SHARE, ERRNO) \
...@@ -620,8 +631,8 @@ extern void _mi_print_key(FILE *stream,HA_KEYSEG *keyseg,const uchar *key, ...@@ -620,8 +631,8 @@ extern void _mi_print_key(FILE *stream,HA_KEYSEG *keyseg,const uchar *key,
extern my_bool _mi_read_pack_info(MI_INFO *info,pbool fix_keys); extern my_bool _mi_read_pack_info(MI_INFO *info,pbool fix_keys);
extern int _mi_read_pack_record(MI_INFO *info,my_off_t filepos,byte *buf); extern int _mi_read_pack_record(MI_INFO *info,my_off_t filepos,byte *buf);
extern int _mi_read_rnd_pack_record(MI_INFO*, byte *,my_off_t, my_bool); extern int _mi_read_rnd_pack_record(MI_INFO*, byte *,my_off_t, my_bool);
extern int _mi_pack_rec_unpack(MI_INFO *info,byte *to,byte *from, extern int _mi_pack_rec_unpack(MI_INFO *info, MI_BIT_BUFF *bit_buff,
ulong reclength); byte *to, byte *from, ulong reclength);
extern ulonglong mi_safe_mul(ulonglong a,ulonglong b); extern ulonglong mi_safe_mul(ulonglong a,ulonglong b);
extern int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf, extern int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf,
const byte *oldrec, const byte *newrec, my_off_t pos); const byte *oldrec, const byte *newrec, my_off_t pos);
...@@ -686,7 +697,9 @@ extern "C" { ...@@ -686,7 +697,9 @@ extern "C" {
extern uint _mi_get_block_info(MI_BLOCK_INFO *,File, my_off_t); extern uint _mi_get_block_info(MI_BLOCK_INFO *,File, my_off_t);
extern uint _mi_rec_pack(MI_INFO *info,byte *to,const byte *from); extern uint _mi_rec_pack(MI_INFO *info,byte *to,const byte *from);
extern uint _mi_pack_get_block_info(MI_INFO *, MI_BLOCK_INFO *, File, my_off_t); extern uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
MI_BLOCK_INFO *info, byte **rec_buff_p,
File file, my_off_t filepos);
extern void _my_store_blob_length(byte *pos,uint pack_length,uint length); extern void _my_store_blob_length(byte *pos,uint pack_length,uint length);
extern void _myisam_log(enum myisam_log_commands command,MI_INFO *info, extern void _myisam_log(enum myisam_log_commands command,MI_INFO *info,
const byte *buffert,uint length); const byte *buffert,uint length);
......
...@@ -1965,7 +1965,7 @@ static char *bindigits(ulonglong value, uint bits) ...@@ -1965,7 +1965,7 @@ static char *bindigits(ulonglong value, uint bits)
DBUG_ASSERT(idx < sizeof(digits)); DBUG_ASSERT(idx < sizeof(digits));
while (idx) while (idx)
*(ptr++)= '0' + ((value >> (--idx)) & 1); *(ptr++)= '0' + ((char) (value >> (--idx)) & (char) 1);
*ptr= '\0'; *ptr= '\0';
return digits; return digits;
} }
...@@ -1995,7 +1995,7 @@ static char *hexdigits(ulonglong value) ...@@ -1995,7 +1995,7 @@ static char *hexdigits(ulonglong value)
DBUG_ASSERT(idx < sizeof(digits)); DBUG_ASSERT(idx < sizeof(digits));
while (idx) while (idx)
{ {
if ((*(ptr++)= '0' + ((value >> (4 * (--idx))) & 0xf)) > '9') if ((*(ptr++)= '0' + ((char) (value >> (4 * (--idx))) & (char) 0xf)) > '9')
*(ptr - 1)+= 'a' - '9' - 1; *(ptr - 1)+= 'a' - '9' - 1;
} }
*ptr= '\0'; *ptr= '\0';
...@@ -2284,7 +2284,7 @@ static my_off_t write_huff_tree(HUFF_TREE *huff_tree, uint trees) ...@@ -2284,7 +2284,7 @@ static my_off_t write_huff_tree(HUFF_TREE *huff_tree, uint trees)
errors++; errors++;
break; break;
} }
idx+= code & 1; idx+= (uint) code & 1;
if (idx >= length) if (idx >= length)
{ {
VOID(fflush(stdout)); VOID(fflush(stdout));
......
...@@ -309,7 +309,7 @@ static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys, ...@@ -309,7 +309,7 @@ static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys,
pthread_handler_t thr_find_all_keys(void *arg) pthread_handler_t thr_find_all_keys(void *arg)
{ {
MI_SORT_PARAM *info= (MI_SORT_PARAM*) arg; MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg;
int error; int error;
uint memavl,old_memavl,keys,sort_length; uint memavl,old_memavl,keys,sort_length;
uint idx, maxbuffer; uint idx, maxbuffer;
...@@ -321,32 +321,34 @@ pthread_handler_t thr_find_all_keys(void *arg) ...@@ -321,32 +321,34 @@ pthread_handler_t thr_find_all_keys(void *arg)
if (my_thread_init()) if (my_thread_init())
goto err; goto err;
if (info->sort_info->got_error) DBUG_ENTER("thr_find_all_keys");
DBUG_PRINT("enter", ("master: %d", sort_param->master));
if (sort_param->sort_info->got_error)
goto err; goto err;
if (info->keyinfo->flag && HA_VAR_LENGTH_KEY) if (sort_param->keyinfo->flag && HA_VAR_LENGTH_KEY)
{ {
info->write_keys=write_keys_varlen; sort_param->write_keys= write_keys_varlen;
info->read_to_buffer=read_to_buffer_varlen; sort_param->read_to_buffer= read_to_buffer_varlen;
info->write_key=write_merge_key_varlen; sort_param->write_key= write_merge_key_varlen;
} }
else else
{ {
info->write_keys=write_keys; sort_param->write_keys= write_keys;
info->read_to_buffer=read_to_buffer; sort_param->read_to_buffer= read_to_buffer;
info->write_key=write_merge_key; sort_param->write_key= write_merge_key;
} }
my_b_clear(&info->tempfile); my_b_clear(&sort_param->tempfile);
my_b_clear(&info->tempfile_for_exceptions); my_b_clear(&sort_param->tempfile_for_exceptions);
bzero((char*) &info->buffpek,sizeof(info->buffpek)); bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek));
bzero((char*) &info->unique, sizeof(info->unique)); bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
sort_keys= (uchar **) NULL; sort_keys= (uchar **) NULL;
memavl=max(info->sortbuff_size, MIN_SORT_MEMORY); memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY);
idx= info->sort_info->max_records; idx= sort_param->sort_info->max_records;
sort_length= info->key_length; sort_length= sort_param->key_length;
maxbuffer= 1; maxbuffer= 1;
while (memavl >= MIN_SORT_MEMORY) while (memavl >= MIN_SORT_MEMORY)
{ {
...@@ -363,18 +365,19 @@ pthread_handler_t thr_find_all_keys(void *arg) ...@@ -363,18 +365,19 @@ pthread_handler_t thr_find_all_keys(void *arg)
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
(sort_length+sizeof(char*))) <= 1) (sort_length+sizeof(char*))) <= 1)
{ {
mi_check_print_error(info->sort_info->param, mi_check_print_error(sort_param->sort_info->param,
"sort_buffer_size is to small"); "sort_buffer_size is to small");
goto err; goto err;
} }
} }
while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr); while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
} }
if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+ if ((sort_keys= (uchar**)
((info->keyinfo->flag & HA_FULLTEXT) ? my_malloc(keys*(sort_length+sizeof(char*))+
HA_FT_MAXBYTELEN : 0), MYF(0)))) ((sort_param->keyinfo->flag & HA_FULLTEXT) ?
HA_FT_MAXBYTELEN : 0), MYF(0))))
{ {
if (my_init_dynamic_array(&info->buffpek, sizeof(BUFFPEK), if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK),
maxbuffer, maxbuffer/2)) maxbuffer, maxbuffer/2))
{ {
my_free((gptr) sort_keys,MYF(0)); my_free((gptr) sort_keys,MYF(0));
...@@ -389,70 +392,88 @@ pthread_handler_t thr_find_all_keys(void *arg) ...@@ -389,70 +392,88 @@ pthread_handler_t thr_find_all_keys(void *arg)
} }
if (memavl < MIN_SORT_MEMORY) if (memavl < MIN_SORT_MEMORY)
{ {
mi_check_print_error(info->sort_info->param,"Sort buffer to small"); /* purecov: tested */ mi_check_print_error(sort_param->sort_info->param, "Sort buffer too small");
goto err; /* purecov: tested */ goto err; /* purecov: tested */
} }
if (info->sort_info->param->testflag & T_VERBOSE) if (sort_param->sort_info->param->testflag & T_VERBOSE)
printf("Key %d - Allocating buffer for %d keys\n",info->key+1,keys); printf("Key %d - Allocating buffer for %d keys\n",
info->sort_keys=sort_keys; sort_param->key + 1, keys);
sort_param->sort_keys= sort_keys;
idx=error=0; idx=error=0;
sort_keys[0]=(uchar*) (sort_keys+keys); sort_keys[0]=(uchar*) (sort_keys+keys);
while (!(error=info->sort_info->got_error) && DBUG_PRINT("info", ("reading keys"));
!(error=(*info->key_read)(info,sort_keys[idx]))) while (!(error= sort_param->sort_info->got_error) &&
!(error= (*sort_param->key_read)(sort_param, sort_keys[idx])))
{ {
if (info->real_key_length > info->key_length) if (sort_param->real_key_length > sort_param->key_length)
{ {
if (write_key(info,sort_keys[idx], &info->tempfile_for_exceptions)) if (write_key(sort_param, sort_keys[idx],
&sort_param->tempfile_for_exceptions))
goto err; goto err;
continue; continue;
} }
if (++idx == keys) if (++idx == keys)
{ {
if (info->write_keys(info,sort_keys,idx-1, if (sort_param->write_keys(sort_param, sort_keys, idx - 1,
(BUFFPEK *)alloc_dynamic(&info->buffpek), (BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
&info->tempfile)) &sort_param->tempfile))
goto err; goto err;
sort_keys[0]=(uchar*) (sort_keys+keys); sort_keys[0]=(uchar*) (sort_keys+keys);
memcpy(sort_keys[0],sort_keys[idx-1],(size_t) info->key_length); memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length);
idx=1; idx=1;
} }
sort_keys[idx]=sort_keys[idx-1]+info->key_length; sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
} }
if (error > 0) if (error > 0)
goto err; goto err;
if (info->buffpek.elements) if (sort_param->buffpek.elements)
{ {
if (info->write_keys(info,sort_keys, idx, if (sort_param->write_keys(sort_param, sort_keys, idx,
(BUFFPEK *) alloc_dynamic(&info->buffpek), &info->tempfile)) (BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
&sort_param->tempfile))
goto err; goto err;
info->keys=(info->buffpek.elements-1)*(keys-1)+idx; sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx;
} }
else else
info->keys=idx; sort_param->keys= idx;
info->sort_keys_length=keys; sort_param->sort_keys_length= keys;
goto ok; goto ok;
err: err:
info->sort_info->got_error=1; /* no need to protect this with a mutex */ DBUG_PRINT("error", ("got some error"));
sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */
if (sort_keys) if (sort_keys)
my_free((gptr) sort_keys,MYF(0)); my_free((gptr) sort_keys,MYF(0));
info->sort_keys=0; sort_param->sort_keys= 0;
delete_dynamic(& info->buffpek); delete_dynamic(& sort_param->buffpek);
close_cached_file(&info->tempfile); close_cached_file(&sort_param->tempfile);
close_cached_file(&info->tempfile_for_exceptions); close_cached_file(&sort_param->tempfile_for_exceptions);
ok: ok:
free_root(&info->wordroot, MYF(0)); free_root(&sort_param->wordroot, MYF(0));
remove_io_thread(&info->read_cache); /*
pthread_mutex_lock(&info->sort_info->mutex); Detach from the share if the writer is involved. Avoid others to
info->sort_info->threads_running--; be blocked. This includes a flush of the write buffer. This will
pthread_cond_signal(&info->sort_info->cond); also indicate EOF to the readers.
pthread_mutex_unlock(&info->sort_info->mutex); */
if (sort_param->sort_info->info->rec_cache.share)
remove_io_thread(&sort_param->sort_info->info->rec_cache);
/* Readers detach from the share if any. Avoid others to be blocked. */
if (sort_param->read_cache.share)
remove_io_thread(&sort_param->read_cache);
pthread_mutex_lock(&sort_param->sort_info->mutex);
if (!--sort_param->sort_info->threads_running)
pthread_cond_signal(&sort_param->sort_info->cond);
pthread_mutex_unlock(&sort_param->sort_info->mutex);
DBUG_PRINT("exit", ("======== ending thread ========"));
my_thread_end(); my_thread_end();
return NULL; return NULL;
} }
...@@ -470,6 +491,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) ...@@ -470,6 +491,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
MYISAM_SHARE *share=info->s; MYISAM_SHARE *share=info->s;
MI_SORT_PARAM *sinfo; MI_SORT_PARAM *sinfo;
byte *mergebuf=0; byte *mergebuf=0;
DBUG_ENTER("thr_write_keys");
LINT_INIT(length); LINT_INIT(length);
for (i= 0, sinfo= sort_param ; for (i= 0, sinfo= sort_param ;
...@@ -606,7 +628,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) ...@@ -606,7 +628,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
} }
} }
my_free((gptr) mergebuf,MYF(MY_ALLOW_ZERO_PTR)); my_free((gptr) mergebuf,MYF(MY_ALLOW_ZERO_PTR));
return got_error; DBUG_RETURN(got_error);
} }
#endif /* THREAD */ #endif /* THREAD */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment