Commit dc2ca8ca authored by jonas@perch.ndb.mysql.com's avatar jonas@perch.ndb.mysql.com

Merge perch.ndb.mysql.com:/home/jonas/src/mysql-4.1

into  perch.ndb.mysql.com:/home/jonas/src/mysql-4.1-ndb
parents f4af143f 0612a212
...@@ -325,12 +325,18 @@ typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*); ...@@ -325,12 +325,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;
...@@ -672,8 +678,8 @@ extern void setup_io_cache(IO_CACHE* info); ...@@ -672,8 +678,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);
......
...@@ -345,7 +345,7 @@ typedef struct st_mi_check_param ...@@ -345,7 +345,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;
......
This diff is collapsed.
...@@ -201,7 +201,10 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -201,7 +201,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;
......
...@@ -101,7 +101,8 @@ static uint fill_and_get_bits(MI_BIT_BUFF *bit_buff,uint count); ...@@ -101,7 +101,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
...@@ -436,13 +437,15 @@ int _mi_read_pack_record(MI_INFO *info, my_off_t filepos, byte *buf) ...@@ -436,13 +437,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:
...@@ -451,8 +454,8 @@ err: ...@@ -451,8 +454,8 @@ err:
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;
...@@ -460,18 +463,18 @@ int _mi_pack_rec_unpack(register MI_INFO *info, register byte *to, byte *from, ...@@ -460,18 +463,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);
...@@ -985,13 +988,16 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf, ...@@ -985,13 +988,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
...@@ -1004,9 +1010,9 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf, ...@@ -1004,9 +1010,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
...@@ -1021,8 +1027,8 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf, ...@@ -1021,8 +1027,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);
} }
...@@ -1030,8 +1036,9 @@ int _mi_read_rnd_pack_record(MI_INFO *info, byte *buf, ...@@ -1030,8 +1036,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;
...@@ -1056,17 +1063,17 @@ uint _mi_pack_get_block_info(MI_INFO *myisam, MI_BLOCK_INFO *info, File file, ...@@ -1056,17 +1063,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;
} }
...@@ -1206,7 +1213,8 @@ void _mi_unmap_file(MI_INFO *info) ...@@ -1206,7 +1213,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,
...@@ -1217,10 +1225,10 @@ static uchar *_mi_mempack_get_block_info(MI_INFO *myisam,MI_BLOCK_INFO *info, ...@@ -1217,10 +1225,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;
} }
...@@ -1236,11 +1244,13 @@ static int _mi_read_mempack_record(MI_INFO *info, my_off_t filepos, byte *buf) ...@@ -1236,11 +1244,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));
} }
...@@ -1260,7 +1270,8 @@ static int _mi_read_rnd_mempack_record(MI_INFO *info, byte *buf, ...@@ -1260,7 +1270,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))))
...@@ -1277,7 +1288,8 @@ static int _mi_read_rnd_mempack_record(MI_INFO *info, byte *buf, ...@@ -1277,7 +1288,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);
} }
......
...@@ -71,6 +71,21 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, key_range *min_key, ...@@ -71,6 +71,21 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, key_range *min_key,
uchar * key_buff; uchar * key_buff;
uint start_key_len; uint start_key_len;
/*
The problem is that the optimizer doesn't support
RTree keys properly at the moment.
Hope this will be fixed some day.
But now NULL in the min_key means that we
didn't make the task for the RTree key
and expect BTree functionality from it.
As it's not able to handle such request
we return the error.
*/
if (!min_key)
{
res= HA_POS_ERROR;
break;
}
key_buff= info->lastkey+info->s->base.max_key_length; key_buff= info->lastkey+info->s->base.max_key_length;
start_key_len= _mi_pack_key(info,inx, key_buff, start_key_len= _mi_pack_key(info,inx, key_buff,
(uchar*) min_key->key, min_key->length, (uchar*) min_key->key, min_key->length,
......
...@@ -75,7 +75,7 @@ typedef struct st_mi_state_info ...@@ -75,7 +75,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; 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 */
...@@ -176,6 +176,7 @@ typedef struct st_mi_isam_share { /* Shared between opens */ ...@@ -176,6 +176,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);
...@@ -249,7 +250,7 @@ struct st_myisam_info { ...@@ -249,7 +250,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 */
...@@ -297,8 +298,9 @@ typedef struct st_mi_sort_param ...@@ -297,8 +298,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.
*/ */
...@@ -309,6 +311,7 @@ typedef struct st_mi_sort_param ...@@ -309,6 +311,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;
...@@ -361,8 +364,15 @@ typedef struct st_mi_sort_param ...@@ -361,8 +364,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)
...@@ -600,8 +610,8 @@ extern void _mi_print_key(FILE *stream,HA_KEYSEG *keyseg,const uchar *key, ...@@ -600,8 +610,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);
...@@ -666,7 +676,9 @@ extern "C" { ...@@ -666,7 +676,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);
......
...@@ -148,7 +148,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, ...@@ -148,7 +148,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
skr=maxbuffer; skr=maxbuffer;
if (memavl < sizeof(BUFFPEK)*(uint) maxbuffer || if (memavl < sizeof(BUFFPEK)*(uint) maxbuffer ||
(keys=(memavl-sizeof(BUFFPEK)*(uint) maxbuffer)/ (keys=(memavl-sizeof(BUFFPEK)*(uint) maxbuffer)/
(sort_length+sizeof(char*))) <= 1) (sort_length+sizeof(char*))) <= 1 ||
keys < (uint) maxbuffer)
{ {
mi_check_print_error(info->sort_info->param, mi_check_print_error(info->sort_info->param,
"sort_buffer_size is to small"); "sort_buffer_size is to small");
...@@ -309,7 +310,7 @@ static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys, ...@@ -309,7 +310,7 @@ static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys,
pthread_handler_decl(thr_find_all_keys,arg) pthread_handler_decl(thr_find_all_keys,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 +322,34 @@ pthread_handler_decl(thr_find_all_keys,arg) ...@@ -321,32 +322,34 @@ pthread_handler_decl(thr_find_all_keys,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)
{ {
...@@ -361,20 +364,22 @@ pthread_handler_decl(thr_find_all_keys,arg) ...@@ -361,20 +364,22 @@ pthread_handler_decl(thr_find_all_keys,arg)
skr=maxbuffer; skr=maxbuffer;
if (memavl < sizeof(BUFFPEK)*maxbuffer || if (memavl < sizeof(BUFFPEK)*maxbuffer ||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
(sort_length+sizeof(char*))) <= 1) (sort_length+sizeof(char*))) <= 1 ||
keys < (uint) maxbuffer)
{ {
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));
else else
...@@ -386,69 +391,87 @@ pthread_handler_decl(thr_find_all_keys,arg) ...@@ -386,69 +391,87 @@ pthread_handler_decl(thr_find_all_keys,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:
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;
} }
...@@ -466,6 +489,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) ...@@ -466,6 +489,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 ;
...@@ -475,6 +499,8 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) ...@@ -475,6 +499,8 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
if (!sinfo->sort_keys) if (!sinfo->sort_keys)
{ {
got_error=1; got_error=1;
my_free(mi_get_rec_buff_ptr(info, sinfo->rec_buff),
MYF(MY_ALLOW_ZERO_PTR));
continue; continue;
} }
if (!got_error) if (!got_error)
...@@ -602,7 +628,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) ...@@ -602,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 */
......
...@@ -74,11 +74,6 @@ grp group_concat(c order by 1) ...@@ -74,11 +74,6 @@ grp group_concat(c order by 1)
1 a 1 a
2 b,c 2 b,c
3 C,D,d,d,D,E 3 C,D,d,d,D,E
select grp,group_concat(c order by "c") from t1 group by grp;
grp group_concat(c order by "c")
1 a
2 b,c
3 C,D,d,d,D,E
select grp,group_concat(distinct c order by c) from t1 group by grp; select grp,group_concat(distinct c order by c) from t1 group by grp;
grp group_concat(distinct c order by c) grp group_concat(distinct c order by c)
1 a 1 a
......
...@@ -857,3 +857,14 @@ CHECK TABLE t1 EXTENDED; ...@@ -857,3 +857,14 @@ CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) );
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,1)));
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,0)));
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,1)));
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,0)));
SELECT 1 FROM t1 WHERE foo != PointFromWKB(POINT(0,0));
1
1
1
1
DROP TABLE t1;
...@@ -773,3 +773,48 @@ select sql_buffer_result max(f1)+1 from t1; ...@@ -773,3 +773,48 @@ select sql_buffer_result max(f1)+1 from t1;
max(f1)+1 max(f1)+1
3 3
drop table t1; drop table t1;
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1),(2);
SELECT a FROM t1 GROUP BY 'a';
a
1
SELECT a FROM t1 GROUP BY "a";
a
1
SELECT a FROM t1 GROUP BY `a`;
a
1
2
set sql_mode=ANSI_QUOTES;
SELECT a FROM t1 GROUP BY "a";
a
1
2
SELECT a FROM t1 GROUP BY 'a';
a
1
SELECT a FROM t1 GROUP BY `a`;
a
1
2
set sql_mode='';
SELECT a FROM t1 HAVING 'a' > 1;
a
SELECT a FROM t1 HAVING "a" > 1;
a
SELECT a FROM t1 HAVING `a` > 1;
a
2
SELECT a FROM t1 ORDER BY 'a' DESC;
a
1
2
SELECT a FROM t1 ORDER BY "a" DESC;
a
1
2
SELECT a FROM t1 ORDER BY `a` DESC;
a
2
1
DROP TABLE t1;
...@@ -797,6 +797,132 @@ a b ...@@ -797,6 +797,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 9 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 9 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 9 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 9 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
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TEMPORARY TABLE `t1` ( t1 CREATE TEMPORARY TABLE `t1` (
......
...@@ -541,3 +541,18 @@ a max(b) ...@@ -541,3 +541,18 @@ a max(b)
NULL 2 NULL 2
a 1 a 1
drop table t1; drop table t1;
create table t1 (a varchar(22) not null , b int);
insert into t1 values ("2006-07-01 21:30", 1), ("2006-07-01 23:30", 10);
select left(a,10), a, sum(b) from t1 group by 1,2 with rollup;
left(a,10) a sum(b)
2006-07-01 2006-07-01 21:30 1
2006-07-01 2006-07-01 23:30 10
2006-07-01 NULL 11
NULL NULL 11
select left(a,10) x, a, sum(b) from t1 group by x,a with rollup;
x a sum(b)
2006-07-01 2006-07-01 21:30 1
2006-07-01 2006-07-01 23:30 10
2006-07-01 NULL 11
NULL NULL 11
drop table t1;
...@@ -48,3 +48,38 @@ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_par ...@@ -48,3 +48,38 @@ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_par
t1 1 a 1 a A 5 NULL NULL YES BTREE t1 1 a 1 a A 5 NULL NULL YES BTREE
SET myisam_repair_threads=@@global.myisam_repair_threads; SET myisam_repair_threads=@@global.myisam_repair_threads;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1(a INT);
USE mysql;
REPAIR TABLE test.t1 USE_FRM;
Table Op Msg_type Msg_text
test.t1 repair status OK
USE test;
DROP TABLE t1;
CREATE TABLE t1(a CHAR(255), KEY(a));
SET myisam_sort_buffer_size=4096;
INSERT INTO t1 VALUES
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0');
SET myisam_repair_threads=2;
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair error sort_buffer_size is to small
test.t1 repair warning Number of rows changed from 0 to 157
test.t1 repair status OK
SET myisam_repair_threads=@@global.myisam_repair_threads;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
DROP TABLE t1;
...@@ -32,7 +32,6 @@ select grp,group_concat(d order by a desc) from t1 group by grp; ...@@ -32,7 +32,6 @@ select grp,group_concat(d order by a desc) from t1 group by grp;
select grp,group_concat(a order by a,d+c-ascii(c)-a) from t1 group by grp; select grp,group_concat(a order by a,d+c-ascii(c)-a) from t1 group by grp;
select grp,group_concat(a order by d+c-ascii(c),a) from t1 group by grp; select grp,group_concat(a order by d+c-ascii(c),a) from t1 group by grp;
select grp,group_concat(c order by 1) from t1 group by grp; select grp,group_concat(c order by 1) from t1 group by grp;
select grp,group_concat(c order by "c") from t1 group by grp;
select grp,group_concat(distinct c order by c) from t1 group by grp; select grp,group_concat(distinct c order by c) from t1 group by grp;
select grp,group_concat(distinct c order by c desc) from t1 group by grp; select grp,group_concat(distinct c order by c desc) from t1 group by grp;
explain extended select grp,group_concat(distinct c order by c desc) from t1 group by grp; explain extended select grp,group_concat(distinct c order by c desc) from t1 group by grp;
......
...@@ -232,4 +232,14 @@ INSERT INTO t1 (c1) VALUES ( ...@@ -232,4 +232,14 @@ INSERT INTO t1 (c1) VALUES (
CHECK TABLE t1 EXTENDED; CHECK TABLE t1 EXTENDED;
DROP TABLE t1; DROP TABLE t1;
#
# Bug #21888: Query on GEOMETRY field using PointFromWKB() results in lost connection
#
CREATE TABLE t1 (foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) );
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,1)));
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,0)));
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,1)));
INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,0)));
SELECT 1 FROM t1 WHERE foo != PointFromWKB(POINT(0,0));
DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests
...@@ -610,4 +610,27 @@ select sql_buffer_result max(f1) is null from t1; ...@@ -610,4 +610,27 @@ select sql_buffer_result max(f1) is null from t1;
select sql_buffer_result max(f1)+1 from t1; select sql_buffer_result max(f1)+1 from t1;
drop table t1; drop table t1;
#
# BUG#14019-4.1-opt
#
CREATE TABLE t1(a INT); INSERT INTO t1 VALUES (1),(2);
SELECT a FROM t1 GROUP BY 'a';
SELECT a FROM t1 GROUP BY "a";
SELECT a FROM t1 GROUP BY `a`;
set sql_mode=ANSI_QUOTES;
SELECT a FROM t1 GROUP BY "a";
SELECT a FROM t1 GROUP BY 'a';
SELECT a FROM t1 GROUP BY `a`;
set sql_mode='';
SELECT a FROM t1 HAVING 'a' > 1;
SELECT a FROM t1 HAVING "a" > 1;
SELECT a FROM t1 HAVING `a` > 1;
SELECT a FROM t1 ORDER BY 'a' DESC;
SELECT a FROM t1 ORDER BY "a" DESC;
SELECT a FROM t1 ORDER BY `a` DESC;
DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests
...@@ -763,6 +763,97 @@ SELECT * FROM t1; ...@@ -763,6 +763,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%';
# Bug#8706 - temporary table with data directory option fails # Bug#8706 - temporary table with data directory option fails
# #
connect (session1,localhost,root,,); connect (session1,localhost,root,,);
......
...@@ -272,4 +272,13 @@ select a, max(b) from t1 group by a with rollup; ...@@ -272,4 +272,13 @@ select a, max(b) from t1 group by a with rollup;
select distinct a, max(b) from t1 group by a with rollup; select distinct a, max(b) from t1 group by a with rollup;
drop table t1; drop table t1;
#
# Bug #20825: rollup puts non-equal values together
#
create table t1 (a varchar(22) not null , b int);
insert into t1 values ("2006-07-01 21:30", 1), ("2006-07-01 23:30", 10);
select left(a,10), a, sum(b) from t1 group by 1,2 with rollup;
select left(a,10) x, a, sum(b) from t1 group by x,a with rollup;
drop table t1;
# End of 4.1 tests # End of 4.1 tests
...@@ -45,4 +45,42 @@ SHOW INDEX FROM t1; ...@@ -45,4 +45,42 @@ SHOW INDEX FROM t1;
SET myisam_repair_threads=@@global.myisam_repair_threads; SET myisam_repair_threads=@@global.myisam_repair_threads;
DROP TABLE t1; DROP TABLE t1;
#
# BUG#22562 - REPAIR TABLE .. USE_FRM causes server crash on Windows and
# server hangs on Linux
#
CREATE TABLE t1(a INT);
USE mysql;
REPAIR TABLE test.t1 USE_FRM;
USE test;
DROP TABLE t1;
#
# BUG#23175 - MYISAM crash/repair failed during repair
#
CREATE TABLE t1(a CHAR(255), KEY(a));
SET myisam_sort_buffer_size=4096;
INSERT INTO t1 VALUES
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),('0'),
('0'),('0'),('0'),('0'),('0'),('0'),('0');
SET myisam_repair_threads=2;
REPAIR TABLE t1;
SET myisam_repair_threads=@@global.myisam_repair_threads;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests
This diff is collapsed.
...@@ -821,7 +821,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list) ...@@ -821,7 +821,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
if (!(table = table_list->table)) if (!(table = table_list->table))
DBUG_RETURN(0); DBUG_RETURN(0);
char* db = thd->db ? thd->db : table_list->db; char *db= table_list->db;
char* table_name = table_list->real_name; char* table_name = table_list->real_name;
char key[MAX_DBKEY_LENGTH]; char key[MAX_DBKEY_LENGTH];
uint key_length; uint key_length;
...@@ -2284,12 +2284,19 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, ...@@ -2284,12 +2284,19 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
const char *field_name=0; const char *field_name=0;
const char *table_name=0; const char *table_name=0;
bool found_unaliased_non_uniq= 0; bool found_unaliased_non_uniq= 0;
/*
true if the item that we search for is a valid name reference
(and not an item that happens to have a name).
*/
bool is_ref_by_name= 0;
uint unaliased_counter; uint unaliased_counter;
LINT_INIT(unaliased_counter); LINT_INIT(unaliased_counter);
*unaliased= FALSE; *unaliased= FALSE;
if (find->type() == Item::FIELD_ITEM || find->type() == Item::REF_ITEM) is_ref_by_name= (find->type() == Item::FIELD_ITEM ||
find->type() == Item::REF_ITEM);
if (is_ref_by_name)
{ {
field_name= ((Item_ident*) find)->field_name; field_name= ((Item_ident*) find)->field_name;
table_name= ((Item_ident*) find)->table_name; table_name= ((Item_ident*) find)->table_name;
...@@ -2401,7 +2408,7 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, ...@@ -2401,7 +2408,7 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
} }
} }
else if (!table_name && (item->eq(find,0) || else if (!table_name && (item->eq(find,0) ||
find->name && item->name && is_ref_by_name && find->name && item->name &&
!my_strcasecmp(system_charset_info, !my_strcasecmp(system_charset_info,
item->name,find->name))) item->name,find->name)))
{ {
......
...@@ -1184,12 +1184,13 @@ JOIN::exec() ...@@ -1184,12 +1184,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)
{ {
...@@ -1237,6 +1238,12 @@ JOIN::exec() ...@@ -1237,6 +1238,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;
/* Create a tmp table if distinct or if the sort is too complicated */ /* Create a tmp table if distinct or if the sort is too complicated */
if (need_tmp) if (need_tmp)
...@@ -1585,7 +1592,10 @@ JOIN::exec() ...@@ -1585,7 +1592,10 @@ JOIN::exec()
error= thd->net.report_error ? -1 : error= thd->net.report_error ? -1 :
do_select(curr_join, curr_fields_list, NULL, procedure); 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;
} }
...@@ -6191,6 +6201,8 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) ...@@ -6191,6 +6201,8 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
return -2; /* purecov: inspected */ return -2; /* purecov: inspected */
} }
join->examined_rows++; join->examined_rows++;
DBUG_PRINT("counts", ("join->examined_rows++: %lu",
(ulong) join->examined_rows));
join->thd->row_count++; join->thd->row_count++;
if (!on_expr || on_expr->val_int()) if (!on_expr || on_expr->val_int())
{ {
...@@ -9718,12 +9730,17 @@ bool JOIN::rollup_init() ...@@ -9718,12 +9730,17 @@ bool JOIN::rollup_init()
while ((item= it++)) while ((item= it++))
{ {
ORDER *group_tmp; ORDER *group_tmp;
bool found_in_group= 0;
for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next) for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
{ {
if (*group_tmp->item == item) if (*group_tmp->item == item)
{
item->maybe_null= 1; item->maybe_null= 1;
found_in_group= 1;
}
} }
if (item->type() == Item::FUNC_ITEM) if (item->type() == Item::FUNC_ITEM && !found_in_group)
{ {
bool changed= FALSE; bool changed= FALSE;
if (change_group_ref(thd, (Item_func *) item, group_list, &changed)) if (change_group_ref(thd, (Item_func *) item, group_list, &changed))
......
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