Fix bug when repairing compressed MyISAM files
LOCATE() is now case sensitive
This commit is contained in:
parent
c6b3afe2d7
commit
9209210d30
@ -4,7 +4,7 @@ make -k clean
|
||||
/bin/rm -f */.deps/*.P config.cache innobase/config.cache bdb/build_unix/config.cache mysql-*.tar.gz
|
||||
aclocal; autoheader; aclocal; automake; autoconf
|
||||
|
||||
CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared
|
||||
CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared --without-extra-tools
|
||||
|
||||
make -j2
|
||||
find . -name ".deps" | xargs rm -r
|
||||
|
@ -6953,6 +6953,9 @@ version 4.0;
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
@code{LOCATE()} and @code{INSTR()} are case sensitive if neither
|
||||
argument is a binary string. binary strings.
|
||||
@item
|
||||
@code{INSERT INTO ... SELECT} had in 3.23 always @code{IGNORE} enabled.
|
||||
In 4.0.1 MySQL will stop (and possible rollback) in case of an error if you
|
||||
don't specify @code{IGNORE}.
|
||||
@ -28621,7 +28624,9 @@ mysql> select LOCATE('xbar', 'foobar');
|
||||
-> 0
|
||||
@end example
|
||||
|
||||
This function is multi-byte safe.
|
||||
This function is multi-byte safe. In MySQL 3.23 this function is case
|
||||
insensitive, while in 4.0 it's only case insensitive if either argument is
|
||||
a binary string.
|
||||
|
||||
@findex LOCATE()
|
||||
@item LOCATE(substr,str,pos)
|
||||
@ -28634,7 +28639,9 @@ mysql> select LOCATE('bar', 'foobarbar',5);
|
||||
-> 7
|
||||
@end example
|
||||
|
||||
This function is multi-byte safe.
|
||||
This function is multi-byte safe. In MySQL 3.23 this function is case
|
||||
insensitive, while in 4.0 it's only case insensitive if either argument is
|
||||
a binary string.
|
||||
|
||||
@findex INSTR()
|
||||
@item INSTR(str,substr)
|
||||
@ -28649,7 +28656,9 @@ mysql> select INSTR('xbar', 'foobar');
|
||||
-> 0
|
||||
@end example
|
||||
|
||||
This function is multi-byte safe.
|
||||
This function is multi-byte safe. In MySQL 3.23 this function is case
|
||||
insensitive, while in 4.0 it's only case insensitive if either argument is
|
||||
a binary string.
|
||||
|
||||
@findex LPAD()
|
||||
@item LPAD(str,len,padstr)
|
||||
@ -45786,6 +45795,9 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
@code{LOCATE()} and @code{INSTR()} are case sensitive if neither
|
||||
argument is a binary string. binary strings.
|
||||
@item
|
||||
Fixed core dump bug in @code{UPDATE ... ORDER BY }.
|
||||
@item
|
||||
Changed @code{INSERT INTO .. SELECT} to by default stop on errors.
|
||||
|
@ -41,7 +41,8 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
||||
ha_checksum *key_checksum, uint level);
|
||||
static uint isam_key_length(MI_INFO *info,MI_KEYDEF *keyinfo);
|
||||
static ha_checksum calc_checksum(ha_rows count);
|
||||
static int writekeys(MI_INFO *info,byte *buff,my_off_t filepos);
|
||||
static int writekeys(MI_CHECK *param, MI_INFO *info,byte *buff,
|
||||
my_off_t filepos);
|
||||
static int sort_one_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
|
||||
my_off_t pagepos, File new_file);
|
||||
static int sort_key_read(SORT_INFO *sort_info,void *key);
|
||||
@ -62,7 +63,8 @@ static void update_key_parts(MI_KEYDEF *keyinfo,
|
||||
ulonglong *unique,
|
||||
ulonglong records);
|
||||
static ha_checksum mi_byte_checksum(const byte *buf, uint length);
|
||||
|
||||
static void set_data_file_type(MI_CHECK *param, SORT_INFO *info,
|
||||
MYISAM_SHARE *share);
|
||||
|
||||
#ifdef __WIN__
|
||||
static double ulonglong2double(ulonglong value)
|
||||
@ -1190,15 +1192,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
|
||||
sort_info->dupp=0;
|
||||
sort_info->fix_datafile= (my_bool) (! rep_quick);
|
||||
sort_info->max_records= ~(ha_rows) 0;
|
||||
if ((sort_info->new_data_file_type=share->data_file_type) ==
|
||||
COMPRESSED_RECORD && param->testflag & T_UNPACK)
|
||||
{
|
||||
if (share->options & HA_OPTION_PACK_RECORD)
|
||||
sort_info->new_data_file_type = DYNAMIC_RECORD;
|
||||
else
|
||||
sort_info->new_data_file_type = STATIC_RECORD;
|
||||
}
|
||||
|
||||
set_data_file_type(param, sort_info, share);
|
||||
del=info->state->del;
|
||||
info->state->records=info->state->del=share->state.split=0;
|
||||
info->state->empty=0;
|
||||
@ -1226,9 +1221,10 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
|
||||
lock_memory(param); /* Everything is alloced */
|
||||
while (!(error=sort_get_next_record(sort_info)))
|
||||
{
|
||||
if (writekeys(info,(byte*) sort_info->record,sort_info->filepos))
|
||||
if (writekeys(param, info,(byte*) sort_info->record,sort_info->filepos))
|
||||
{
|
||||
if (my_errno != HA_ERR_FOUND_DUPP_KEY) goto err;
|
||||
if (my_errno != HA_ERR_FOUND_DUPP_KEY)
|
||||
goto err;
|
||||
DBUG_DUMP("record",(byte*) sort_info->record,share->base.pack_reclength);
|
||||
mi_check_print_info(param,"Duplicate key %2d for record at %10s against new record at %10s",
|
||||
info->errkey+1,
|
||||
@ -1367,7 +1363,8 @@ err:
|
||||
|
||||
/* Uppate keyfile when doing repair */
|
||||
|
||||
static int writekeys(register MI_INFO *info,byte *buff,my_off_t filepos)
|
||||
static int writekeys(MI_CHECK *param, register MI_INFO *info, byte *buff,
|
||||
my_off_t filepos)
|
||||
{
|
||||
register uint i;
|
||||
uchar *key;
|
||||
@ -1380,12 +1377,14 @@ static int writekeys(register MI_INFO *info,byte *buff,my_off_t filepos)
|
||||
{
|
||||
if (info->s->keyinfo[i].flag & HA_FULLTEXT )
|
||||
{
|
||||
if (_mi_ft_add(info,i,(char*) key,buff,filepos)) goto err;
|
||||
if (_mi_ft_add(info,i,(char*) key,buff,filepos))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint key_length=_mi_make_key(info,i,key,buff,filepos);
|
||||
if (_mi_ck_write(info,i,key,key_length)) goto err;
|
||||
if (_mi_ck_write(info,i,key,key_length))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1401,16 +1400,21 @@ static int writekeys(register MI_INFO *info,byte *buff,my_off_t filepos)
|
||||
{
|
||||
if (info->s->keyinfo[i].flag & HA_FULLTEXT)
|
||||
{
|
||||
if (_mi_ft_del(info,i,(char*) key,buff,filepos)) break;
|
||||
if (_mi_ft_del(info,i,(char*) key,buff,filepos))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint key_length=_mi_make_key(info,i,key,buff,filepos);
|
||||
if (_mi_ck_delete(info,i,key,key_length)) break;
|
||||
if (_mi_ck_delete(info,i,key,key_length))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Remove checksum that was added to glob_crc in sort_get_next_record */
|
||||
if (param->calc_checksum)
|
||||
param->glob_crc-= info->checksum;
|
||||
DBUG_PRINT("error",("errno: %d",my_errno));
|
||||
DBUG_RETURN(-1);
|
||||
} /* writekeys */
|
||||
@ -1847,15 +1851,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
||||
sort_info->info=info;
|
||||
sort_info->param = param;
|
||||
|
||||
if ((sort_info->new_data_file_type=share->data_file_type) ==
|
||||
COMPRESSED_RECORD && param->testflag & T_UNPACK)
|
||||
{
|
||||
if (share->options & HA_OPTION_PACK_RECORD)
|
||||
sort_info->new_data_file_type = DYNAMIC_RECORD;
|
||||
else
|
||||
sort_info->new_data_file_type = STATIC_RECORD;
|
||||
}
|
||||
|
||||
set_data_file_type(param, sort_info, share);
|
||||
sort_info->filepos=new_header_length;
|
||||
sort_info->dupp=0;
|
||||
sort_info->buff=0;
|
||||
@ -2193,7 +2189,8 @@ static int sort_get_next_record(SORT_INFO *sort_info)
|
||||
if (*sort_info->record)
|
||||
{
|
||||
if (param->calc_checksum)
|
||||
param->glob_crc+= mi_static_checksum(info,sort_info->record);
|
||||
param->glob_crc+= (info->checksum=
|
||||
mi_static_checksum(info,sort_info->record));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (!sort_info->fix_datafile)
|
||||
@ -2646,7 +2643,7 @@ static int sort_key_write(SORT_INFO *sort_info, const void *a)
|
||||
sort_info->key_block->
|
||||
lastkey),
|
||||
llbuff2));
|
||||
param->error_printed=param->retry_without_quick=1;
|
||||
param->retry_without_quick=1;
|
||||
if (sort_info->param->testflag & T_VERBOSE)
|
||||
_mi_print_key(stdout,sort_info->keyseg,(uchar*) a, USE_WHOLE_KEY);
|
||||
return (sort_delete_record(param));
|
||||
@ -3291,3 +3288,25 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_data_file_type(MI_CHECK *param, SORT_INFO *sort_info, MYISAM_SHARE *share)
|
||||
{
|
||||
if ((sort_info->new_data_file_type=share->data_file_type) ==
|
||||
COMPRESSED_RECORD && param->testflag & T_UNPACK)
|
||||
{
|
||||
MYISAM_SHARE tmp;
|
||||
|
||||
if (share->options & HA_OPTION_PACK_RECORD)
|
||||
sort_info->new_data_file_type = DYNAMIC_RECORD;
|
||||
else
|
||||
sort_info->new_data_file_type = STATIC_RECORD;
|
||||
|
||||
/* Set delete_function for sort_delete_record() */
|
||||
memcpy((char*) &tmp, share, sizeof(*share));
|
||||
tmp.options= ~HA_OPTION_COMPRESS_RECORD;
|
||||
mi_setup_functions(&tmp);
|
||||
share->delete_record=tmp.delete_record;
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "static.c"
|
||||
#endif
|
||||
|
||||
static void setup_functions(MYISAM_SHARE *info);
|
||||
static void setup_key_functions(MI_KEYDEF *keyinfo);
|
||||
#define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
|
||||
pos+=size;}
|
||||
@ -405,7 +404,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
||||
else if (share->options & HA_OPTION_PACK_RECORD)
|
||||
share->data_file_type = DYNAMIC_RECORD;
|
||||
my_afree((gptr) disk_cache);
|
||||
setup_functions(share);
|
||||
mi_setup_functions(share);
|
||||
#ifdef THREAD
|
||||
thr_lock_init(&share->lock);
|
||||
VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
|
||||
@ -580,7 +579,7 @@ ulonglong mi_safe_mul(ulonglong a, ulonglong b)
|
||||
|
||||
/* Set up functions in structs */
|
||||
|
||||
static void setup_functions(register MYISAM_SHARE *share)
|
||||
void mi_setup_functions(register MYISAM_SHARE *share)
|
||||
{
|
||||
if (share->options & HA_OPTION_COMPRESS_RECORD)
|
||||
{
|
||||
|
@ -785,7 +785,10 @@ static void decode_bytes(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,uchar *to,
|
||||
if (bits <= 32)
|
||||
{
|
||||
if (bit_buff->pos > bit_buff->end+4)
|
||||
{
|
||||
bit_buff->error=1;
|
||||
return; /* Can't be right */
|
||||
}
|
||||
bit_buff->current_byte= (bit_buff->current_byte << 32) +
|
||||
((((uint) bit_buff->pos[3])) +
|
||||
(((uint) bit_buff->pos[2]) << 8) +
|
||||
@ -829,7 +832,8 @@ static void decode_bytes(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,uchar *to,
|
||||
|
||||
#else
|
||||
|
||||
static void decode_bytes(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, uchar *end)
|
||||
static void decode_bytes(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
|
||||
uchar *end)
|
||||
{
|
||||
reg1 uint bits,low_byte;
|
||||
reg3 uint16 *pos;
|
||||
@ -846,7 +850,10 @@ static void decode_bytes(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, uc
|
||||
if (bits < table_bits)
|
||||
{
|
||||
if (bit_buff->pos > bit_buff->end+1)
|
||||
{
|
||||
bit_buff->error=1;
|
||||
return; /* Can't be right */
|
||||
}
|
||||
#if BITS_SAVED == 32
|
||||
bit_buff->current_byte= (bit_buff->current_byte << 24) +
|
||||
(((uint) ((uchar) bit_buff->pos[2]))) +
|
||||
|
@ -217,7 +217,7 @@ static struct option long_options[] =
|
||||
|
||||
static void print_version(void)
|
||||
{
|
||||
printf("%s Ver 1.52 for %s at %s\n",my_progname,SYSTEM_TYPE,
|
||||
printf("%s Ver 2.0 for %s at %s\n",my_progname,SYSTEM_TYPE,
|
||||
MACHINE_TYPE);
|
||||
}
|
||||
|
||||
|
@ -646,6 +646,7 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
|
||||
my_bool check_table_is_closed(const char *name, const char *where);
|
||||
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup);
|
||||
int mi_open_keyfile(MYISAM_SHARE *share);
|
||||
void mi_setup_functions(register MYISAM_SHARE *share);
|
||||
|
||||
int _mi_init_bulk_insert(MI_INFO *info);
|
||||
|
||||
|
@ -20,19 +20,19 @@ sum(a)
|
||||
NULL
|
||||
select a from t1 order by rand(10);
|
||||
a
|
||||
2
|
||||
6
|
||||
1
|
||||
3
|
||||
6
|
||||
5
|
||||
2
|
||||
4
|
||||
select distinct a from t1 order by rand(10);
|
||||
a
|
||||
2
|
||||
6
|
||||
1
|
||||
3
|
||||
6
|
||||
5
|
||||
2
|
||||
4
|
||||
select count(distinct a),count(distinct grp) from t1;
|
||||
count(distinct a) count(distinct grp)
|
||||
|
@ -24,7 +24,7 @@ pow(10,log10(10)) power(2,4)
|
||||
10.000000 16.000000
|
||||
select rand(999999),rand();
|
||||
rand(999999) rand()
|
||||
0.18435012473199 0.76373626176616
|
||||
0.014231365187309 0.8078568166195
|
||||
select pi(),sin(pi()/2),cos(pi()/2),abs(tan(pi())),cot(1),asin(1),acos(0),atan(1);
|
||||
PI() sin(pi()/2) cos(pi()/2) abs(tan(pi())) cot(1) asin(1) acos(0) atan(1)
|
||||
3.141593 1.000000 0.000000 0.000000 0.64209262 1.570796 1.570796 0.785398
|
||||
|
@ -14,11 +14,11 @@ monty was here again 5 h
|
||||
select locate('he','hello'),locate('he','hello',2),locate('lo','hello',2) ;
|
||||
locate('he','hello') locate('he','hello',2) locate('lo','hello',2)
|
||||
1 0 4
|
||||
select instr('hello','he');
|
||||
instr('hello','he')
|
||||
1
|
||||
select position('ll' in 'hello'),position('a' in 'hello');
|
||||
position('ll' in 'hello') position('a' in 'hello')
|
||||
select instr('hello','HE'), instr('hello',binary 'HE'), instr(binary 'hello','HE');
|
||||
instr('hello','HE') instr('hello',binary 'HE') instr(binary 'hello','HE')
|
||||
1 0 0
|
||||
select position(binary 'll' in 'hello'),position('a' in binary 'hello');
|
||||
position(binary 'll' in 'hello') position('a' in binary 'hello')
|
||||
3 0
|
||||
select left('hello',2),right('hello',2),substring('hello',2,2),mid('hello',1,5) ;
|
||||
left('hello',2) right('hello',2) substring('hello',2,2) mid('hello',1,5)
|
||||
|
@ -11,8 +11,8 @@ select 'hello' 'monty';
|
||||
select length('\n\t\r\b\0\_\%\\');
|
||||
select concat('monty',' was here ','again'),length('hello'),char(ascii('h'));
|
||||
select locate('he','hello'),locate('he','hello',2),locate('lo','hello',2) ;
|
||||
select instr('hello','he');
|
||||
select position('ll' in 'hello'),position('a' in 'hello');
|
||||
select instr('hello','HE'), instr('hello',binary 'HE'), instr(binary 'hello','HE');
|
||||
select position(binary 'll' in 'hello'),position('a' in binary 'hello');
|
||||
select left('hello',2),right('hello',2),substring('hello',2,2),mid('hello',1,5) ;
|
||||
select concat('',left(right(concat('what ',concat('is ','happening')),9),4),'',substring('monty',5,1)) ;
|
||||
select substring_index('www.tcx.se','.',-2),substring_index('www.tcx.se','.',1);
|
||||
|
@ -621,8 +621,9 @@ double Item_func_rand::val()
|
||||
{
|
||||
if (arg_count)
|
||||
{ // Only use argument once in query
|
||||
ulong tmp=((ulong) args[0]->val_int());
|
||||
randominit(¤t_thd->rand,tmp*0x10001L+55555555L,tmp*0x10000001L);
|
||||
uint32 tmp= (uint32) (args[0]->val_int());
|
||||
randominit(¤t_thd->rand,(uint32) (tmp*0x10001L+55555555L),
|
||||
(uint32) (tmp*0x10000001L));
|
||||
#ifdef DELETE_ITEMS
|
||||
delete args[0];
|
||||
#endif
|
||||
@ -797,9 +798,7 @@ longlong Item_func_locate::val_int()
|
||||
{
|
||||
String *a=args[0]->val_str(&value1);
|
||||
String *b=args[1]->val_str(&value2);
|
||||
#ifdef USE_MB
|
||||
bool binary_str = args[0]->binary || args[1]->binary;
|
||||
#endif
|
||||
if (!a || !b)
|
||||
{
|
||||
null_value=1;
|
||||
@ -853,7 +852,8 @@ longlong Item_func_locate::val_int()
|
||||
return 0;
|
||||
}
|
||||
#endif /* USE_MB */
|
||||
return (longlong) (a->strstr(*b,start)+1) ;
|
||||
return (longlong) (binary ? a->strstr(*b,start) :
|
||||
(a->strstr_case(*b,start)))+1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -362,6 +362,37 @@ skipp:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
Search after a string without regarding to case
|
||||
This needs to be replaced when we have character sets per string
|
||||
*/
|
||||
|
||||
int String::strstr_case(const String &s,uint32 offset)
|
||||
{
|
||||
if (s.length()+offset <= str_length)
|
||||
{
|
||||
if (!s.length())
|
||||
return ((int) offset); // Empty string is always found
|
||||
|
||||
register const char *str = Ptr+offset;
|
||||
register const char *search=s.ptr();
|
||||
const char *end=Ptr+str_length-s.length()+1;
|
||||
const char *search_end=s.ptr()+s.length();
|
||||
skipp:
|
||||
while (str != end)
|
||||
{
|
||||
if (my_sort_order[*str++] == my_sort_order[*search])
|
||||
{
|
||||
register char *i,*j;
|
||||
i=(char*) str; j=(char*) search+1;
|
||||
while (j != search_end)
|
||||
if (my_sort_order[*i++] != my_sort_order[*j++]) goto skipp;
|
||||
return (int) (str-Ptr) -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Search string from end. Offset is offset to the end of string
|
||||
|
@ -161,6 +161,7 @@ public:
|
||||
bool append(const char *s,uint32 arg_length=0);
|
||||
bool append(IO_CACHE* file, uint32 arg_length);
|
||||
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
|
||||
int strstr_case(const String &s,uint32 offset=0);
|
||||
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
|
||||
bool replace(uint32 offset,uint32 arg_length,const String &to);
|
||||
inline bool append(char chr)
|
||||
|
Loading…
x
Reference in New Issue
Block a user