Commit 1776fbac authored by unknown's avatar unknown

Fixed bug in ALTER TABLE

Removed _mi_rkey() function
New fork_big.pl multi-thread test


BitKeeper/deleted/.del-fork3_test.pl~c4a7bffb4f8e813c:
  Delete: tests/fork3_test.pl
BitKeeper/deleted/.del-fork_test.pl~3d3535329ed8cd5e:
  Delete: tests/fork_test.pl
Docs/manual.texi:
  Changelog.
  Updated support information
client/mysqladmin.c:
  Removed not used --timeout option
configure.in:
  Update version
myisam/mi_extra.c:
  Fixed bug in ALTER TABLE
myisam/mi_rkey.c:
  Removed _mi_rkey() function
myisam/myisamdef.h:
  Removed _mi_rkey() function
myisammrg/myrg_rkey.c:
  Removed _mi_rkey() function
myisammrg/myrg_rnext.c:
  Removed _mi_rkey() function
mysql-test/t/alter_table.test:
  Added test case for ALTER TABLE bug
sql/derror.cc:
  Moved shutdown message to clean_up
sql/mysql_priv.h:
  Moved shutdown message to clean_up
sql/sql_class.cc:
  Fixed bug in MySQL compiled with transactions but using --skip-"table-handler"
sql/sql_show.cc:
  Use time_after_lock for time of query when debugging
sql/sql_test.cc:
  Check memory overruns when using 'mysqladmin debug'
strings/ctype-tis620.c:
  F
parent 05f08c18
This diff is collapsed.
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include <my_pthread.h> /* because of signal() */ #include <my_pthread.h> /* because of signal() */
#endif #endif
#define ADMIN_VERSION "8.18" #define ADMIN_VERSION "8.19"
#define MAX_MYSQL_VAR 64 #define MAX_MYSQL_VAR 64
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */ #define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3 #define MAX_TRUNC_LENGTH 3
...@@ -817,8 +817,6 @@ static void usage(void) ...@@ -817,8 +817,6 @@ static void usage(void)
-s, --silent Silently exit if one can't connect to server\n\ -s, --silent Silently exit if one can't connect to server\n\
-S, --socket=... Socket file to use for connection\n"); -S, --socket=... Socket file to use for connection\n");
#include "sslopt-usage.h" #include "sslopt-usage.h"
printf("\
-t, --timeout=... Timeout for connection to the mysqld server\n");
#ifndef DONT_ALLOW_USER_CHANGE #ifndef DONT_ALLOW_USER_CHANGE
printf("\ printf("\
-u, --user=# User for login if not current user\n"); -u, --user=# User for login if not current user\n");
......
...@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. ...@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc) AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line! # The Docs Makefile.am parses this line!
AM_INIT_AUTOMAKE(mysql, 3.23.36) AM_INIT_AUTOMAKE(mysql, 3.23.37)
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10 PROTOCOL_VERSION=10
...@@ -660,6 +660,7 @@ int main() ...@@ -660,6 +660,7 @@ int main()
# #
MAX_C_OPTIMIZE="-O6" MAX_C_OPTIMIZE="-O6"
case $SYSTEM_TYPE in case $SYSTEM_TYPE in
*solaris2.7*) *solaris2.7*)
# Solaris 2.7 has a broken /usr/include/widec.h # Solaris 2.7 has a broken /usr/include/widec.h
......
...@@ -319,6 +319,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function) ...@@ -319,6 +319,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function)
{ {
my_free(info->rec_alloc,MYF(MY_ALLOW_ZERO_PTR)); my_free(info->rec_alloc,MYF(MY_ALLOW_ZERO_PTR));
info->rec_alloc=info->rec_buff=0; info->rec_alloc=info->rec_buff=0;
mi_fix_rec_buff_for_blob(info,info->s->base.pack_reclength);
} }
break; break;
case HA_EXTRA_NORMAL: /* Theese isn't in use */ case HA_EXTRA_NORMAL: /* Theese isn't in use */
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
/* Read a record using key */ /* Read a record using key */
/* Ordinary search_flag is 0 ; Give error if no record with key */ /* Ordinary search_flag is 0 ; Give error if no record with key */
int _mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len, int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
enum ha_rkey_function search_flag, bool raw_key) enum ha_rkey_function search_flag)
{ {
uchar *key_buff; uchar *key_buff;
MYISAM_SHARE *share=info->s; MYISAM_SHARE *share=info->s;
...@@ -37,7 +37,7 @@ int _mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len, ...@@ -37,7 +37,7 @@ int _mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
if (raw_key) if (!info->use_packed_key)
{ {
if (key_len == 0) if (key_len == 0)
key_len=USE_WHOLE_KEY; key_len=USE_WHOLE_KEY;
...@@ -101,11 +101,3 @@ int _mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len, ...@@ -101,11 +101,3 @@ int _mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
err: err:
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
} /* _mi_rkey */ } /* _mi_rkey */
/* shouldn't forget to do it inline sometime */
int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
enum ha_rkey_function search_flag)
{
return _mi_rkey(info,buf,inx,key,key_len,search_flag,TRUE);
}
...@@ -258,6 +258,7 @@ struct st_myisam_info { ...@@ -258,6 +258,7 @@ struct st_myisam_info {
my_bool quick_mode; my_bool quick_mode;
my_bool page_changed; /* If info->buff can't be used for rnext */ my_bool page_changed; /* If info->buff can't be used for rnext */
my_bool buff_used; /* If info->buff has to be reread for rnext */ my_bool buff_used; /* If info->buff has to be reread for rnext */
my_bool use_packed_key; /* For MYISAMMRG */
myf lock_wait; /* is 0 or MY_DONT_WAIT */ myf lock_wait; /* is 0 or MY_DONT_WAIT */
int (*read_record)(struct st_myisam_info*, my_off_t, byte*); int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
LIST open_list; LIST open_list;
...@@ -630,8 +631,6 @@ void mi_update_status(void* param); ...@@ -630,8 +631,6 @@ void mi_update_status(void* param);
void mi_copy_status(void* to,void *from); void mi_copy_status(void* to,void *from);
my_bool mi_check_status(void* param); my_bool mi_check_status(void* param);
void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows); void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
int _mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
enum ha_rkey_function search_flag, bool raw_key);
my_bool check_table_is_closed(const char *name, const char *where); my_bool check_table_is_closed(const char *name, const char *where);
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share); int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share);
......
...@@ -63,7 +63,9 @@ int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key, ...@@ -63,7 +63,9 @@ int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key,
} }
else else
{ {
err=_mi_rkey(mi,buf,inx,key_buff,pack_key_length,search_flag,FALSE); mi->use_packed_key=1;
err=mi_rkey(mi,buf,inx,key_buff,pack_key_length,search_flag);
mi->use_packed_key=0;
} }
info->last_used_table=table+1; info->last_used_table=table+1;
......
...@@ -68,8 +68,10 @@ int _myrg_finish_scan(MYRG_INFO *info, int inx, enum ha_rkey_function type) ...@@ -68,8 +68,10 @@ int _myrg_finish_scan(MYRG_INFO *info, int inx, enum ha_rkey_function type)
for (; table < info->end_table ; table++) for (; table < info->end_table ; table++)
{ {
mi=table->table; mi=table->table;
if ((err=_mi_rkey(mi,NULL,inx,key_buff,pack_key_length, mi->use_packed_key=1;
type,FALSE))) err=mi_rkey(mi,NULL,inx,key_buff,pack_key_length,type);
mi->use_packed_key=0;
if (err)
{ {
if (err == HA_ERR_KEY_NOT_FOUND) /* If end of file */ if (err == HA_ERR_KEY_NOT_FOUND) /* If end of file */
continue; continue;
......
...@@ -57,13 +57,17 @@ CREATE TABLE t1 ( ...@@ -57,13 +57,17 @@ CREATE TABLE t1 (
PRIMARY KEY (id) PRIMARY KEY (id)
) TYPE=MyISAM; ) TYPE=MyISAM;
ALTER TABLE ALTER TABLE t1 ORDER BY t1.id, t1.status, t1.type_id, t1.user_id, t1.body;
t1 DROP TABLE t1;
ORDER BY
t1.id,
t1.status,
t1.type_id,
t1.user_id,
t1.body;
drop table t1; #
# The following combination found a hang-bug in MyISAM
#
CREATE TABLE t1 (AnamneseId int(10) unsigned NOT NULL auto_increment,B BLOB,PRIMARY KEY (AnamneseId)) type=myisam;
insert into t1 values (null,"hello");
LOCK TABLES t1 WRITE;
ALTER TABLE t1 ADD Column new_col int not null;
UNLOCK TABLES;
OPTIMIZE TABLE t1;
DROP TABLE t1;
...@@ -72,7 +72,7 @@ static void read_texts(const char *file_name,const char ***point, ...@@ -72,7 +72,7 @@ static void read_texts(const char *file_name,const char ***point,
Check that the above file is the right version for this program!\n\n", Check that the above file is the right version for this program!\n\n",
my_progname,name,ant,error_messages); my_progname,name,ant,error_messages);
VOID(my_close(file,MYF(MY_WME))); VOID(my_close(file,MYF(MY_WME)));
clean_up(); /* Clean_up frees everything */ clean_up(0); /* Clean_up frees everything */
exit(1); /* We can't continue */ exit(1); /* We can't continue */
} }
...@@ -115,7 +115,7 @@ Check that the above file is the right version for this program!\n\n", ...@@ -115,7 +115,7 @@ Check that the above file is the right version for this program!\n\n",
if (file != FERR) if (file != FERR)
VOID(my_close(file,MYF(MY_WME))); VOID(my_close(file,MYF(MY_WME)));
fprintf(stderr,buff,my_progname,name); fprintf(stderr,buff,my_progname,name);
clean_up(); /* Clean_up frees everything */ clean_up(0); /* Clean_up frees everything */
exit(1); /* We can't continue */ exit(1); /* We can't continue */
} /* read_texts */ } /* read_texts */
......
...@@ -611,7 +611,7 @@ uint calc_week(TIME *ltime, bool with_year, bool sunday_first_day_of_week, ...@@ -611,7 +611,7 @@ uint calc_week(TIME *ltime, bool with_year, bool sunday_first_day_of_week,
void find_date(char *pos,uint *vek,uint flag); void find_date(char *pos,uint *vek,uint flag);
TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end); TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end);
TYPELIB *typelib(List<String> &strings); TYPELIB *typelib(List<String> &strings);
void clean_up(void); void clean_up(bool print_message=1);
ulong get_form_pos(File file, uchar *head, TYPELIB *save_names); ulong get_form_pos(File file, uchar *head, TYPELIB *save_names);
ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames, ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames,
const char *newname); const char *newname);
......
...@@ -136,9 +136,9 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), ...@@ -136,9 +136,9 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
(hash_get_key) get_var_key, (hash_get_key) get_var_key,
(void (*)(void*)) free_var,0); (void (*)(void*)) free_var,0);
#ifdef USING_TRANSACTIONS #ifdef USING_TRANSACTIONS
bzero((char*) &transaction,sizeof(transaction));
if (opt_using_transactions) if (opt_using_transactions)
{ {
bzero((char*) &transaction,sizeof(transaction));
if (open_cached_file(&transaction.trans_log, if (open_cached_file(&transaction.trans_log,
mysql_tmpdir, LOG_PREFIX, binlog_cache_size, mysql_tmpdir, LOG_PREFIX, binlog_cache_size,
MYF(MY_WME))) MYF(MY_WME)))
......
...@@ -1006,7 +1006,11 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) ...@@ -1006,7 +1006,11 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
if (pthread_kill(tmp->real_id,0)) if (pthread_kill(tmp->real_id,0))
tmp->proc_info="*** DEAD ***"; // This shouldn't happen tmp->proc_info="*** DEAD ***"; // This shouldn't happen
#endif #endif
#ifdef EXTRA_DEBUG
thd_info->start_time= tmp->time_after_lock;
#else
thd_info->start_time= tmp->start_time; thd_info->start_time= tmp->start_time;
#endif
thd_info->query=0; thd_info->query=0;
if (tmp->query) if (tmp->query)
{ {
......
...@@ -240,6 +240,7 @@ Open streams: %10lu\n", ...@@ -240,6 +240,7 @@ Open streams: %10lu\n",
fflush(stdout); fflush(stdout);
if (thd) if (thd)
thd->proc_info="malloc"; thd->proc_info="malloc";
my_checkmalloc();
TERMINATE(stdout); // Write malloc information TERMINATE(stdout); // Write malloc information
if (thd) if (thd)
thd->proc_info=0; thd->proc_info=0;
......
/* /*
Copyright (C) 2001 by Korakot Chaovavanich <korakot@iname.com> and
Apisilp Trunganont <apisilp@pantip.inet.co.th>
Copyright (C) 1998, 1999 by Pruet Boonma <pruet@eng.cmu.ac.th> Copyright (C) 1998, 1999 by Pruet Boonma <pruet@eng.cmu.ac.th>
Copyright (C) 1998 by Theppitak Karoonboonyanan <thep@links.nectec.or.th> Copyright (C) 1998 by Theppitak Karoonboonyanan <thep@links.nectec.or.th>
Copyright (C) 1989, 1991 by Samphan Raruenrom <samphan@thai.com> Copyright (C) 1989, 1991 by Samphan Raruenrom <samphan@thai.com>
...@@ -6,9 +8,10 @@ ...@@ -6,9 +8,10 @@
Permission to use, copy, modify, distribute and sell this software Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose is hereby granted without fee, and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies. provided that the above copyright notice appear in all copies.
Smaphan Raruenrom , Theppitak Karoonboonyanan and Pruet Boonma makes Samphan Raruenrom , Theppitak Karoonboonyanan , Pruet Boonma ,
no representations about the suitability of this software for any Korakot Chaovavanich and Apisilp Trunganont makes no representations
purpose. It is provided "as is" without express or implied warranty. about the suitability of this software for any purpose. It is provided
"as is" without express or implied warranty.
*/ */
...@@ -297,7 +300,8 @@ int t_ctype[][TOT_LEVELS] = { ...@@ -297,7 +300,8 @@ int t_ctype[][TOT_LEVELS] = {
/*0xFC*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, /*0xFC*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
/*0xFD*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, /*0xFD*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
/*0xFE*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, /*0xFE*/ { IGNORE, IGNORE, IGNORE, IGNORE, X },
/*0xFF*/ { IGNORE, IGNORE, IGNORE, IGNORE, X }, /* Utilize 0xFF for max_sort_chr in my_like_range_tis620 */
/*0xFF*/ { 255 /*IGNORE*/, IGNORE, IGNORE, IGNORE, X },
}; };
uchar NEAR ctype_tis620[257] = uchar NEAR ctype_tis620[257] =
...@@ -436,10 +440,14 @@ uchar NEAR sort_order_tis620[]= ...@@ -436,10 +440,14 @@ uchar NEAR sort_order_tis620[]=
static uchar* thai2sortable(const uchar * tstr,uint len) static uchar* thai2sortable(const uchar * tstr,uint len)
{ {
/* We use only 3 levels (neglect capitalization). */
const uchar* p = tstr; const uchar* p = tstr;
uchar *outBuf; uchar *outBuf;
uchar *pRight1, *pRight2, *pRight3, *pRight4; // uchar *pRight1, *pRight2, *pRight3, *pRight4;
uchar *pLeft1, *pLeft2, *pLeft3, *pLeft4; // uchar *pLeft1, *pLeft2, *pLeft3, *pLeft4;
uchar *pRight1, *pRight2, *pRight3;
uchar *pLeft1, *pLeft2, *pLeft3;
uint bufSize; uint bufSize;
len = (uint) strnlen((char*) tstr,len); len = (uint) strnlen((char*) tstr,len);
...@@ -460,23 +468,23 @@ static uchar* thai2sortable(const uchar * tstr,uint len) ...@@ -460,23 +468,23 @@ static uchar* thai2sortable(const uchar * tstr,uint len)
return((uchar*) tstr); return((uchar*) tstr);
} }
pLeft3 = pRight3; pLeft3 = pRight3;
if(!(pRight4 = (uchar *)malloc(sizeof(uchar) * (len + 1)))) { /* if(!(pRight4 = (uchar *)malloc(sizeof(uchar) * (len + 1)))) {
free(pRight1); free(pRight1);
free(pRight2); free(pRight2);
free(pRight3); free(pRight3);
return((uchar*) tstr); return((uchar*) tstr);
} }
pLeft4 = pRight4; pLeft4 = pRight4;*/
while(len--) { while(len--) {
if(isldvowel(*p) && isconsnt(p[1])) { if(isldvowel(*p) && isconsnt(p[1])) {
*pRight1++ = t_ctype[p[1]][0]; *pRight1++ = t_ctype[p[1]][0];
*pRight2++ = t_ctype[p[1]][1]; *pRight2++ = t_ctype[p[1]][1];
*pRight3++ = t_ctype[p[1]][2]; *pRight3++ = t_ctype[p[1]][2];
*pRight4++ = t_ctype[p[1]][3]; // *pRight4++ = t_ctype[p[1]][3];
*pRight1++ = t_ctype[*p][0]; *pRight1++ = t_ctype[*p][0];
*pRight2++ = t_ctype[*p][1]; *pRight2++ = t_ctype[*p][1];
*pRight3++ = t_ctype[*p][2]; *pRight3++ = t_ctype[*p][2];
*pRight4++ = t_ctype[*p][3]; // *pRight4++ = t_ctype[*p][3];
len--; len--;
p += 2; p += 2;
} else { } else {
...@@ -486,23 +494,24 @@ static uchar* thai2sortable(const uchar * tstr,uint len) ...@@ -486,23 +494,24 @@ static uchar* thai2sortable(const uchar * tstr,uint len)
if(*pRight2 != IGNORE) pRight2++; if(*pRight2 != IGNORE) pRight2++;
*pRight3 = t_ctype[*p][2]; *pRight3 = t_ctype[*p][2];
if(*pRight3 != IGNORE) pRight3++; if(*pRight3 != IGNORE) pRight3++;
*pRight4 = t_ctype[*p][3]; /* *pRight4 = t_ctype[*p][3];
if(*pRight4 != IGNORE) pRight4++; if(*pRight4 != IGNORE) pRight4++;*/
p++; p++;
} }
} }
*pRight1++ = L2_BLANK; *pRight1++ = L2_BLANK;
*pRight2++ = L3_BLANK; *pRight2++ = L3_BLANK;
*pRight3++ = L4_BLANK; // *pRight3++ = L4_BLANK;
*pRight4++ = '\0'; *pRight3++ = '\0';
// *pRight4++ = '\0';
memcpy(pRight1, pLeft2, pRight2 - pLeft2); memcpy(pRight1, pLeft2, pRight2 - pLeft2);
pRight1 += pRight2 - pLeft2; pRight1 += pRight2 - pLeft2;
memcpy(pRight1, pLeft3, pRight3 - pLeft3); memcpy(pRight1, pLeft3, pRight3 - pLeft3);
pRight1 += pRight3 - pLeft3; // pRight1 += pRight3 - pLeft3;
memcpy(pRight1, pLeft4, pRight4 - pLeft4); // memcpy(pRight1, pLeft4, pRight4 - pLeft4);
free(pLeft2); free(pLeft2);
free(pLeft3); free(pLeft3);
free(pLeft4); // free(pLeft4);
return(outBuf); return(outBuf);
} }
...@@ -574,55 +583,58 @@ int my_strxfrm_tis620(uchar * dest, uchar * src, int len) ...@@ -574,55 +583,58 @@ int my_strxfrm_tis620(uchar * dest, uchar * src, int len)
Arg: String, its length, escape character, resource length, minimal string and maximum string Arg: String, its length, escape character, resource length, minimal string and maximum string
Ret: Alway 0 Ret: Alway 0
*/ */
/* We just copy this function from opt_range.cc. No need to convert to
thai2sortable string. min_str and max_str will be use for comparison and
converted there. */
#define max_sort_chr ((char) 255)
#define wild_one '_'
#define wild_many '%'
my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape, my_bool my_like_range_tis620(const char *ptr, uint ptr_length, pchar escape,
uint res_length, char *min_str, char *max_str, uint res_length, char *min_str, char *max_str,
uint *min_length,uint *max_length) uint *min_length, uint *max_length)
{ {
char *end; const char *end=ptr+ptr_length;
char *min_org= min_str; char *min_org=min_str;
char *min_end = min_str + res_length; char *min_end=min_str+res_length;
char *tbuff; char *tmp;
uchar *tc;
uint tbuff_length;
tbuff = (char*) (tc=thai2sortable((uchar*) ptr, ptr_length)); for (; ptr != end && min_str != min_end ; ptr++)
tbuff_length = (uint) buffsize(ptr);
end = tbuff + tbuff_length;
for(;tbuff != end && min_str != min_end; tbuff++)
{ {
if(*tbuff == escape && tbuff + 1 != end) if (*ptr == escape && ptr+1 != end)
{ {
tbuff++; ptr++; // Skipp escape
*min_str++ = *max_str++ = *tbuff; *min_str++= *max_str++ = *ptr;
continue; continue;
} }
if(*tbuff == '_') if (*ptr == wild_one) // '_' in SQL
{ {
*min_str++ = '\0'; *min_str++='\0'; // This should be min char
*max_str++ = '\255'; *max_str++=max_sort_chr;
continue; continue;
} }
if(*tbuff == '%') if (*ptr == wild_many) // '%' in SQL
{ {
*min_length= (uint) (min_str - min_org); *min_length= (uint) (min_str - min_org);
*max_length= res_length; *max_length=res_length;
do do {
{ *min_str++ = ' '; // Because if key compression
*min_str++ = ' '; *max_str++ = max_sort_chr;
*max_str++ = '\255'; } while (min_str != min_end);
} while(min_str != min_end); return 0;
free(tc);
return(0);
} }
*min_str++ = *max_str++ = *tbuff; *min_str++= *max_str++ = *ptr;
} }
*min_length= *max_length = (uint) (min_str - min_org); *min_length= *max_length = (uint) (min_str - min_org);
while(min_str != min_end)
{ /* Temporary fix for handling wild_one at end of string (key compression) */
*min_str++ = *max_str++ = ' '; // for (tmp= min_str ; tmp > min_org && tmp[-1] == '\0';)
} // *--tmp=' ';
free(tc);
return(0); while (min_str != min_end)
*min_str++ = *max_str++ = ' '; // Because if key compression
return 0;
} }
/* Thai normalization for input sub system /* Thai normalization for input sub system
......
#!/usr/bin/perl -w
#
# This is a test with uses 4 processes to insert, delete , check and select
#
$opt_loop_count=200000; # Change this to make test harder/easier
##################### Standard benchmark inits ##############################
use DBI;
use Getopt::Long;
use Benchmark;
package main;
$opt_skip_create=$opt_skip_in=$opt_verbose=$opt_fast_insert=
$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=0;
$opt_host=""; $opt_db="test";
GetOptions("host=s","db=s","loop-count=i","skip-create","skip-in","skip-delete",
"verbose","fast-insert","lock-tables","debug","fast","force") || die "Aborted";
$opt_verbose=$opt_debug=$opt_lock_tables=$opt_fast_insert=$opt_fast=$opt_skip_in=$opt_force=undef; # Ignore warnings from these
print "Testing 4 multiple connections to a server with 1 insert, 1 delete\n";
print "1 select and one repair/check connection.\n";
$firsttable = "bench_f1";
####
#### Start timeing and start test
####
$start_time=new Benchmark;
if (!$opt_skip_create)
{
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
$dbh->do("drop table if exists $firsttable");
print "Creating table $firsttable in database $opt_db\n";
$dbh->do("create table $firsttable (id int(6) not null, info varchar(32), marker char(1), primary key(id))") || die $DBI::errstr;
$dbh->disconnect; $dbh=0; # Close handler
}
$|= 1; # Autoflush
####
#### Start the tests
####
test_insert() if (($pid=fork()) == 0); $work{$pid}="insert";
test_delete() if (($pid=fork()) == 0); $work{$pid}="delete";
test_select() if (($pid=fork()) == 0); $work{$pid}="select1";
repair_and_check() if (($pid=fork()) == 0); $work{$pid}="repair/check";
$errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
print "thread '" . $work{$pid} . "' finnished with exit code $ret\n";
$errors++ if ($ret != 0);
}
if (!$opt_skip_delete && !$errors)
{
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
$dbh->do("drop table $firsttable");
$dbh->disconnect; $dbh=0; # Close handler
}
print ($errors ? "Test failed\n" :"Test ok\n");
$end_time=new Benchmark;
print "Total time: " .
timestr(timediff($end_time, $start_time),"noc") . "\n";
exit(0);
#
# Insert records in the table
#
sub test_insert
{
my ($dbh,$i,$sth);
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($i=0 ; $i < $opt_loop_count; $i++)
{
$sth=$dbh->do("insert into $firsttable values ($i,'This is entry $i','')") || die "Got error on insert: $Mysql::db_errstr\n";
$sth=0;
}
$dbh->disconnect; $dbh=0;
print "Test_insert: Inserted $i rows\n";
exit(0);
}
sub test_delete
{
my ($dbh,$i,$sth,@row);
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
sleep(5);
if ($opt_lock_tables)
{
$sth=$dbh->do("lock tables $firsttable WRITE") || die "Got error on lock tables $firsttable: $Mysql::db_errstr\n";
}
$sth=$dbh->prepare("select count(*) from $firsttable") || die "Got error on select from $firsttable: $dbh->errstr\n";
$sth->execute || die $dbh->errstr;
if ((@row = $sth->fetchrow_array()))
{
last if (!$row[0]); # Insert thread is probably ready
}
$sth=$dbh->do("delete from $firsttable") || die "Got error on delete from $firsttable: $dbh->errstr;\n";
}
$sth=0;
$dbh->disconnect; $dbh=0;
print "Test_delete: Deleted all rows $i times\n";
exit(0);
}
#
# select records
#
sub test_select
{
my ($dbh,$i,$sth,@row);
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$sth=$dbh->prepare("select count(*) from $firsttable") || die "Got error on select from $firsttable: $dbh->errstr;\n";
$sth->execute || die $dbh->errstr;
@row = $sth->fetchrow_array();
$sth=0;
}
$dbh->disconnect; $dbh=0;
print "Test_select: ok\n";
exit(0);
}
sub repair_and_check
{
my ($dbh,$row,$found1,$last_found1,$i,$type, $table);
$found1=0; $last_found1= -1;
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($i=0; $found1 != $last_found1 ; $i++)
{
$type=($i & 2) ? "repair" : "check";
$table=$firsttable;
$last_found1=$found1;
$sth=$dbh->prepare("$type table $table") || die "Got error on prepare: $dbh->errstr\n";
$sth->execute || die $dbh->errstr;
while (($row=$sth->fetchrow_arrayref))
{
if ($row->[3] ne "OK")
{
print "Got error " . $row->[3] . " when doing $type on $table\n";
exit(1);
}
}
$sth=$dbh->prepare("select count(*) from $table") || die "Got error on prepare: $dbh->errstr\n";
$sth->execute || die $dbh->errstr;
@row = $sth->fetchrow_array();
$found1= $row[0];
$sth->finish;
sleep(3);
}
$dbh->disconnect; $dbh=0;
print "check/repair: Did $i repair/checks\n";
exit(0);
}
This diff is collapsed.
#!/usr/bin/perl -w
# This is a test with uses 5 processes to insert, update and select from
# two tables.
# One inserts records in the tables, one updates some record in it and
# the last 3 does different selects on the tables.
#
$opt_loop_count=10000; # Change this to make test harder/easier
##################### Standard benchmark inits ##############################
use Mysql;
use Getopt::Long;
use Benchmark;
package main;
$opt_skip_create=$opt_skip_in=$opt_verbose=$opt_fast_insert=
$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=0;
$opt_host=""; $opt_db="test";
GetOptions("host=s","db=s","loop-count=i","skip-create","skip-in",
"skip-delete","verbose","fast-insert","lock-tables","debug","fast",
"force") || die "Aborted";
$opt_verbose=$opt_debug=$opt_lock_tables=$opt_fast_insert=$opt_fast=$opt_skip_in=$Mysql::db_errstr=$opt_force=undef; # Ignore warnings from these
print "Testing 5 multiple connections to a server with 1 insert, 1 update\n";
print "and 3 select connections.\n";
$firsttable = "bench_f1";
$secondtable = "bench_f2";
####
#### Start timeing and start test
####
$start_time=new Benchmark;
if (!$opt_skip_create)
{
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$Mysql::QUIET = 1;
$dbh->Query("drop table $firsttable");
$dbh->Query("drop table $secondtable");
$Mysql::QUIET = 0;
print "Creating tables $firsttable and $secondtable in database $opt_db\n";
$dbh->Query("create table $firsttable (id int(6) not null, info varchar(32), marker char(1), primary key(id))") or die $Mysql::db_errstr;
$dbh->Query("create table $secondtable (id int(6) not null, row int(3) not null,value double, primary key(id,row))") or die $Mysql::db_errstr;
$dbh=0; # Close handler
}
$|= 1; # Autoflush
####
#### Start the tests
####
test_1() if (($pid=fork()) == 0); $work{$pid}="insert";
test_2() if (($pid=fork()) == 0); $work{$pid}="update";
test_3() if (($pid=fork()) == 0); $work{$pid}="select1";
test_4() if (($pid=fork()) == 0); $work{$pid}="select2";
test_5() if (($pid=fork()) == 0); $work{$pid}="select3";
$errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
$errors++ if ($ret != 0);
}
if (!$opt_skip_delete && !$errors)
{
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$dbh->Query("drop table $firsttable");
$dbh->Query("drop table $secondtable");
}
print ($errors ? "Test failed\n" :"Test ok\n");
$end_time=new Benchmark;
print "Total time: " .
timestr(timediff($end_time, $start_time),"noc") . "\n";
exit(0);
#
# Insert records in the two tables
#
sub test_1
{
my ($dbh,$tmpvar,$rows,$found,$i);
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$tmpvar=1;
$rows=$found=0;
for ($i=0 ; $i < $opt_loop_count; $i++)
{
$tmpvar^= ((($tmpvar + 63) + $i)*3 % 100000);
$sth=$dbh->Query("insert into $firsttable values ($i,'This is entry $i','')") || die "Got error on insert: $Mysql::db_errstr\n";
$row_count=($i % 7)+1;
$rows+=1+$row_count;
for ($j=0 ; $j < $row_count; $j++)
{
$sth=$dbh->Query("insert into $secondtable values ($i,$j,0)") || die "Got error on insert: $Mysql::db_errstr\n";
}
if (($tmpvar % 10) == 0)
{
$sth=$dbh->Query("select max(info) from $firsttable") || die "Got error on select max(info): $Mysql::db_errstr\n";
$sth=$dbh->Query("select max(value) from $secondtable") || die "Got error on select max(info): $Mysql::db_errstr\n";
$found+=2;
}
}
$dbh=0;
print "Test_1: Inserted $rows rows, found $found rows\n";
exit(0);
}
#
# Update records in both tables
#
sub test_2
{
my ($dbh,$id,$tmpvar,$rows,$found,$i,$max_id,$tmp);
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$tmpvar=111111;
$rows=$found=$max_id=$id=0;
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$tmp=(($tmpvar + 63) + $i)*3;
$tmp=$tmp-int($tmp/100000)*100000;
$tmpvar^= $tmp;
$tmp=$tmpvar - int($tmpvar/10)*10;
if ($max_id < 2 || $tmp == 0)
{
$max_id=0;
$sth=$dbh->Query("select max(id) from $firsttable where marker=''") || die "Got error select max: $Mysql::db_errstr\n";
if ((@row = $sth->FetchRow()) && defined($row[0]))
{
$found++;
$max_id=$id=$row[0];
}
}
else
{
$id= $tmpvar % ($max_id-1)+1;
}
if ($id)
{
$sth=$dbh->Query("update $firsttable set marker='x' where id=$id") || die "Got error update $firsttable: $Mysql::db_errstr\n";
$rows+=$sth->affected_rows;
if ($sth->affected_rows)
{
$sth=$dbh->Query("update $secondtable set value=$i where id=$id") || die "Got error update $firsttable: $Mysql::db_errstr\n";
$rows+=$sth->affected_rows;
}
}
}
$dbh=0;
print "Test_2: Found $found rows, Updated $rows rows\n";
exit(0);
}
#
# select records
#
sub test_3
{
my ($dbh,$id,$tmpvar,$rows,$i);
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$tmpvar=222222;
$rows=0;
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$tmpvar^= ((($tmpvar + 63) + $i)*3 % 100000);
$id=$tmpvar % $opt_loop_count;
$sth=$dbh->Query("select id from $firsttable where id=$id") || die "Got error on select from $firsttable: $Mysql::db_errstr\n";
$rows+=$sth->numrows;
}
$dbh=0;
print "Test_3: Found $rows rows\n";
exit(0);
}
#
# Note that this uses row=1 and in some cases won't find any matching
# records
#
sub test_4
{
my ($dbh,$id,$tmpvar,$rows,$i);
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$tmpvar=333333;
$rows=0;
for ($i=0 ; $i < $opt_loop_count; $i++)
{
$tmpvar^= ((($tmpvar + 63) + $i)*3 % 100000);
$id=$tmpvar % $opt_loop_count;
$sth=$dbh->Query("select id from $secondtable where id=$id") || die "Got error on select form $secondtable: $Mysql::db_errstr\n";
$rows+=$sth->numrows;
}
$dbh=0;
print "Test_4: Found $rows rows\n";
exit(0);
}
sub test_5
{
my ($dbh,$id,$tmpvar,$rows,$i,$max_id);
$dbh = Mysql->Connect($opt_host, $opt_db) || die $Mysql::db_errstr;
$tmpvar=444444;
$rows=$max_id=0;
for ($i=0 ; $i < $opt_loop_count ; $i++)
{
$tmpvar^= ((($tmpvar + 63) + $i)*3 % 100000);
if ($max_id == 0 || ($tmpvar % 10 == 0))
{
$sth=$dbh->Query("select max(id) from $firsttable") || die "Got error select max: $Mysql::db_errstr\n";
if ((@row = $sth->FetchRow()) && defined($row[0]))
{
$max_id=$id=$row[0];
}
else
{
$id=0;
}
}
else
{
$id= $tmpvar % $max_id;
}
$sth=$dbh->Query("select value from $firsttable,$secondtable where $firsttable.id=$id and $secondtable.id=$firsttable.id") || die "Got error on select form $secondtable: $Mysql::db_errstr\n";
$rows+=$sth->numrows;
}
$dbh=0;
print "Test_5: Found $rows rows\n";
exit(0);
}
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