diff options
author | unknown <monty@hundin.mysql.fi> | 2001-11-22 13:50:50 +0200 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2001-11-22 13:50:50 +0200 |
commit | d576cd65d00d23b634e0ef4254660e67c055c045 (patch) | |
tree | 8c1d3e9b787e1017fce3c9e905b829557889f97a | |
parent | 5975e2364942dfcf8bca2fcc8e3107b16dd2fa46 (diff) | |
download | mariadb-git-d576cd65d00d23b634e0ef4254660e67c055c045.tar.gz |
Fix bug when repairing compressed MyISAM files
LOCATE() is now case sensitive
BUILD/compile-alpha-cxx:
Don't build manager because it fails with linker error on Linux Alpha
Docs/manual.texi:
Changelog
myisam/mi_check.c:
Fix bug when repairing compressed MyISAM files
myisam/mi_open.c:
Fix bug when repairing compressed MyISAM files
myisam/mi_packrec.c:
Fix bug when repairing compressed MyISAM files
myisam/myisamchk.c:
Fix bug when repairing compressed MyISAM files
myisam/myisamdef.h:
Fix bug when repairing compressed MyISAM files
mysql-test/r/func_group.result:
Fix result for new RND function
mysql-test/r/func_math.result:
Fix result for new RND function
mysql-test/r/func_str.result:
test of new locate()
mysql-test/t/func_str.test:
test of new locate()
sql/item_func.cc:
LOCATE() is now case sensitive
sql/sql_string.cc:
LOCATE() is now case sensitive
sql/sql_string.h:
LOCATE() is now case sensitive
-rwxr-xr-x | BUILD/compile-alpha-cxx | 2 | ||||
-rw-r--r-- | Docs/manual.texi | 18 | ||||
-rw-r--r-- | myisam/mi_check.c | 75 | ||||
-rw-r--r-- | myisam/mi_open.c | 5 | ||||
-rw-r--r-- | myisam/mi_packrec.c | 9 | ||||
-rw-r--r-- | myisam/myisamchk.c | 4 | ||||
-rw-r--r-- | myisam/myisamdef.h | 1 | ||||
-rw-r--r-- | mysql-test/r/func_group.result | 8 | ||||
-rw-r--r-- | mysql-test/r/func_math.result | 2 | ||||
-rw-r--r-- | mysql-test/r/func_str.result | 10 | ||||
-rw-r--r-- | mysql-test/t/func_str.test | 4 | ||||
-rw-r--r-- | sql/item_func.cc | 10 | ||||
-rw-r--r-- | sql/sql_string.cc | 31 | ||||
-rw-r--r-- | sql/sql_string.h | 1 |
14 files changed, 125 insertions, 55 deletions
diff --git a/BUILD/compile-alpha-cxx b/BUILD/compile-alpha-cxx index 250b092fe2a..3e6eee9a0d6 100755 --- a/BUILD/compile-alpha-cxx +++ b/BUILD/compile-alpha-cxx @@ -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 diff --git a/Docs/manual.texi b/Docs/manual.texi index e302b9d4a98..06c313a2020 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -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. diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 2bae475e5e1..27af7666d62 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -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; + } +} diff --git a/myisam/mi_open.c b/myisam/mi_open.c index 64707479d11..ff42e6fbff7 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -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) { diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c index 31be2113c20..00e2c05ef5e 100644 --- a/myisam/mi_packrec.c +++ b/myisam/mi_packrec.c @@ -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]))) + diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 853c1de5ed7..0fb6beabf97 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -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); } @@ -260,7 +260,7 @@ static void usage(void) puts("Repair options (When using -r or -o) \n\ -B, --backup Make a backup of the .MYD file as 'filename-time.BAK'\n\ - --correct-checksum Correct checksum information for table. \n\ + --correct-checksum Correct checksum information for table.\n\ -D, --data-file-length=# Max length of data file (when recreating data\n\ file when it's full)\n\ -e, --extend-check Try to recover every possible row from the data file\n\ diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index ea77d700234..0f48216ccbf 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -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); diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index bdb33be5d4c..2d24b8ffd4e 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -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) diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index 771c640805b..fce98a58682 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -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 diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index efbcd91964b..28a4870cfc6 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -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) diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index b7200b2d144..49f5c6143f3 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -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); diff --git a/sql/item_func.cc b/sql/item_func.cc index 6657d860592..91ec8826f73 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -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; } diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 046346c1e03..beefa09b54b 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -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 diff --git a/sql/sql_string.h b/sql/sql_string.h index 31dea9991cc..00a078640b3 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -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) |