From 0390de8672255aed7d35734fa8bc0d87efbe532e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Oct 2005 01:22:24 +0400 Subject: Fix bug #13855 select distinct with group by caused server crash DISTINCT wasn't optimized away and caused creation of tmp table in wrong case. This result in integer overrun and running out of memory. Fix backported from 4.1. Now if optimizer founds that in result be only 1 row it removes distinct. sql/sql_select.cc: Fix bug #13855 select distinct with group by caused server crash mysql-test/r/select.result: Test case for bug#13855 select distinct with group by caused server crash mysql-test/t/select.test: Test case for bug#13855 select distinct with group by caused server crash --- mysql-test/r/select.result | 8 ++++++++ mysql-test/t/select.test | 9 +++++++++ sql/sql_select.cc | 1 + 3 files changed, 18 insertions(+) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 11a50d6cabc..98d474821c9 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2477,3 +2477,11 @@ a b c d 1 2 2 1 1 2 3 1 DROP TABLE IF EXISTS t1, t2; +create table t1 (f1 int primary key, f2 int); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t1 values (1,1); +insert into t2 values (1,1),(1,2); +select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; +count(f2) >0 +1 +drop table t1,t2; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 2607a00bed4..984b467d435 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2013,3 +2013,12 @@ SELECT t2.a, t2.b, IF(t1.b IS NULL,'',c) AS c, COUNT(*) AS d FROM t2,t1 WHERE t2.a = t1.a AND t2.b = t1.b GROUP BY a, b, c; DROP TABLE IF EXISTS t1, t2; +# +# Bug #13855 select distinct with group by caused server crash +# +create table t1 (f1 int primary key, f2 int); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t1 values (1,1); +insert into t2 values (1,1),(1,2); +select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; +drop table t1,t2; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7c2c233d754..46f0139a608 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -626,6 +626,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, { order=0; // The output has only one row simple_order=1; + select_distinct= 0; // No need in distinct for 1 row } calc_group_buffer(&join,group); -- cgit v1.2.1 From 71fdef4d10b5eda9bec9743fc457cb8629e93344 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 21 Oct 2005 06:29:17 +0400 Subject: BUG#9622, stage 2, work together with fix for BUG#12232: added "nulls_ignored" index statistics collection method for MyISAM tables. (notification trigger: this is about BUG#9622). include/my_base.h: BUG#9622: Added MI_STATS_METHOD_IGNORE_NULLS statistics collection method: Added SEARCH_RETURN_B_POS flag for ha_key_cmp() include/my_handler.h: BUG#9622: Added MI_STATS_METHOD_IGNORE_NULLS statistics collection method: added ha_find_null() include/myisam.h: BUG#9622: Added MI_STATS_METHOD_IGNORE_NULLS statistics collection method. myisam/mi_check.c: BUG#9622: Added MI_STATS_METHOD_IGNORE_NULLS statistics collection method, added mi_collect_stats_*(), updated update_key_parts() to deal with all 3 methods. myisam/myisamchk.c: BUG#9622: Added nulls_ignored index statistics collection method for MyISAM myisam/myisamdef.h: BUG#9622: Added MI_STATS_METHOD_IGNORE_NULLS statistics collection method. myisam/sort.c: BUG#9622: Added MI_STATS_METHOD_IGNORE_NULLS statistics collection method. mysql-test/r/myisam.result: Testcase for BUG9622 mysql-test/t/myisam.test: Testcase for BUG9622 mysys/my_handler.c: BUG#9622: ha_key_cmp() now supports new SEARCH_RETURN_B_POS flag, added ha_find_null() sql/ha_myisam.cc: BUG#9622: Added MI_STATS_METHOD_IGNORE_NULLS statistics collection method. sql/mysqld.cc: BUG#9622: Added MI_STATS_METHOD_IGNORE_NULLS statistics collection method. --- include/my_base.h | 2 + include/my_handler.h | 2 + include/myisam.h | 14 +++- myisam/mi_check.c | 176 +++++++++++++++++++++++++++++++++++++++++---- myisam/myisamchk.c | 24 +++++-- myisam/myisamdef.h | 7 ++ myisam/sort.c | 8 ++- mysql-test/r/myisam.result | 32 +++++++++ mysql-test/t/myisam.test | 19 +++++ mysys/my_handler.c | 99 ++++++++++++++++++++++++- sql/ha_myisam.cc | 2 +- sql/mysqld.cc | 21 ++++-- 12 files changed, 375 insertions(+), 31 deletions(-) diff --git a/include/my_base.h b/include/my_base.h index d702ec45140..950af8903ff 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -319,6 +319,8 @@ enum ha_base_keytype { #define SEARCH_NULL_ARE_EQUAL 32768 /* NULL in keys are equal */ #define SEARCH_NULL_ARE_NOT_EQUAL 65536 /* NULL in keys are not equal */ +#define SEARCH_RETURN_B_POS (65536*2) /* see ha_key_cmp for description */ + /* bits in opt_flag */ #define QUICK_USED 1 #define READ_CACHE_USED 2 diff --git a/include/my_handler.h b/include/my_handler.h index 18a6234d3f6..8b3cc1a1ee0 100644 --- a/include/my_handler.h +++ b/include/my_handler.h @@ -63,4 +63,6 @@ extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, register uchar *b, uint key_length, uint nextflag, uint *diff_pos); +extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a); + #endif /* _my_handler_h */ diff --git a/include/myisam.h b/include/myisam.h index e276d4efdff..e564bf29cac 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -322,7 +322,9 @@ typedef enum /* Treat NULLs as inequal when collecting statistics (default for 4.1/5.0) */ MI_STATS_METHOD_NULLS_NOT_EQUAL, /* Treat NULLs as equal when collecting statistics (like 4.0 did) */ - MI_STATS_METHOD_NULLS_EQUAL + MI_STATS_METHOD_NULLS_EQUAL, + /* Ignore NULLs - count tuples without NULLs only */ + MI_STATS_METHOD_IGNORE_NULLS } enum_mi_stats_method; typedef struct st_mi_check_param @@ -349,7 +351,14 @@ typedef struct st_mi_check_param int tmpfile_createflag; myf myf_rw; IO_CACHE read_cache; + + /* + The next two are used to collect statistics, see update_key_parts for + description. + */ ulonglong unique_count[MI_MAX_KEY_SEG+1]; + ulonglong notnull_count[MI_MAX_KEY_SEG+1]; + ha_checksum key_crc[MI_MAX_POSSIBLE_KEY]; ulong rec_per_key_part[MI_MAX_KEY_SEG*MI_MAX_POSSIBLE_KEY]; void *thd; @@ -409,7 +418,8 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, my_bool repair); int update_state_info(MI_CHECK *param, MI_INFO *info,uint update); void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part, - ulonglong *unique, ulonglong records); + ulonglong *unique, ulonglong *notnull, + ulonglong records); int filecopy(MI_CHECK *param, File to,File from,my_off_t start, my_off_t length, const char *type); int movepoint(MI_INFO *info,byte *record,my_off_t oldpos, diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 7397ee4e204..1fd7f1b45f6 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -391,7 +391,10 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) found_keys++; param->record_checksum=init_checksum; + bzero((char*) ¶m->unique_count,sizeof(param->unique_count)); + bzero((char*) ¶m->notnull_count,sizeof(param->notnull_count)); + if ((!(param->testflag & T_SILENT))) printf ("- check data record references index: %d\n",key+1); if (keyinfo->flag & HA_FULLTEXT) @@ -496,7 +499,9 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) if (param->testflag & T_STATISTICS) update_key_parts(keyinfo, rec_per_key_part, param->unique_count, - (ulonglong) info->state->records); + param->stats_method == MI_STATS_METHOD_IGNORE_NULLS? + param->notnull_count: NULL, + (ulonglong)info->state->records); } if (param->testflag & T_INFO) { @@ -552,6 +557,87 @@ err: return 1; } + +/* + "Ignore NULLs" statistics collection method: process first index tuple. + + SYNOPSIS + mi_collect_stats_nonulls_first() + keyseg IN Array of key part descriptions + notnull INOUT Array, notnull[i] = (number of {keypart1...keypart_i} + tuples that don't contain NULLs) + key IN Key values tuple + + DESCRIPTION + Process the first index tuple - find out which prefix tuples don't + contain NULLs, and update the array of notnull counters accordingly. +*/ + +static +void mi_collect_stats_nonulls_first(HA_KEYSEG *keyseg, ulonglong *notnull, + uchar *key) +{ + uint first_null, kp; + first_null= ha_find_null(keyseg, key) - keyseg; + /* + All prefix tuples that don't include keypart_{first_null} are not-null + tuples (and all others aren't), increment counters for them. + */ + for (kp= 0; kp < first_null; kp++) + notnull[kp]++; +} + + +/* + "Ignore NULLs" statistics collection method: process next index tuple. + + SYNOPSIS + mi_collect_stats_nonulls_next() + keyseg IN Array of key part descriptions + notnull INOUT Array, notnull[i] = (number of {keypart1...keypart_i} + tuples that don't contain NULLs) + prev_key IN Previous key values tuple + last_key IN Next key values tuple + + DESCRIPTION + Process the next index tuple: + 1. Find out which prefix tuples of last_key don't contain NULLs, and + update the array of notnull counters accordingly. + 2. Find the first keypart number where the tuples are different(A), or + last_key has NULL value (B), and return it, so caller can count + number of unique tuples for each key prefix. We don't need (B) to be + counted, and that is compensated back in update_key_parts(). + + RETURN + 1 + number of first keypart where values differ or last_key tuple has NULL +*/ + +static +int mi_collect_stats_nonulls_next(HA_KEYSEG *keyseg, ulonglong *notnull, + uchar *prev_key, uchar *last_key) +{ + uint diffs[2]; + uint first_null_seg, kp; + + /* Find first keypart where values are different or either of them is NULL */ + ha_key_cmp(keyseg, prev_key, last_key, USE_WHOLE_KEY, + SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL | SEARCH_RETURN_B_POS, + diffs); + HA_KEYSEG *seg= keyseg + diffs[0] - 1; + /* Find first NULL in last_key */ + first_null_seg= ha_find_null(seg, last_key + diffs[1]) - keyseg; + for (kp= 0; kp < first_null_seg; kp++) + notnull[kp]++; + + /* + Return 1+ number of first key part where values differ. Don't care if + these were NULLs and not .... We compensate for that in + update_key_parts. + */ + return diffs[0]; +} + + /* Check if index is ok */ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, @@ -641,8 +727,20 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY, SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, &diff_pos); + else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS) + { + diff_pos= mi_collect_stats_nonulls_next(keyinfo->seg, + param->notnull_count, + info->lastkey, key); + } param->unique_count[diff_pos-1]++; } + else + { + if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS) + mi_collect_stats_nonulls_first(keyinfo->seg, param->notnull_count, + key); + } } (*key_checksum)+= mi_byte_checksum((byte*) key, key_length- info->s->rec_reflength); @@ -2088,7 +2186,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, if (param->testflag & T_STATISTICS) update_key_parts(sort_param.keyinfo, rec_per_key_part, sort_param.unique, - (ulonglong) info->state->records); + param->stats_method == MI_STATS_METHOD_IGNORE_NULLS? + sort_param.notnull: NULL,(ulonglong) info->state->records); share->state.key_map|=(ulonglong) 1 << sort_param.key; if (sort_param.fix_datafile) @@ -3255,11 +3354,21 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a) ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey, (uchar*) a, USE_WHOLE_KEY, SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, &diff_pos); + else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS) + { + diff_pos= mi_collect_stats_nonulls_next(sort_param->seg, + sort_param->notnull, + sort_info->key_block->lastkey, + (uchar*)a); + } sort_param->unique[diff_pos-1]++; } else { cmp= -1; + if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS) + mi_collect_stats_nonulls_first(sort_param->seg, sort_param->notnull, + (uchar*)a); } if ((sort_param->keyinfo->flag & HA_NOSAME) && cmp == 0) { @@ -3981,21 +4090,30 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, SYNOPSIS update_key_parts() - keyinfo Index information (only key->keysegs used) + keyinfo IN Index information (only key->keysegs used) rec_per_key_part OUT Store statistics here - unique IN Array of #distinct values collected over index - run. + unique IN Array of (#distinct tuples) + notnull_tuples IN Array of (#tuples), or NULL records Number of records in the table NOTES + This function handles all 3 index statistics collection methods. + Unique is an array: unique[0]= (#different values of {keypart1}) - 1 - unique[1]= (#different values of {keypart2,keypart1} tuple) - unique[0] - 1 + unique[1]= (#different values of {keypart1,keypart2} tuple) - unique[0] - 1 ... + + For MI_STATS_METHOD_IGNORE_NULLS notnull_tuples is an array too: + notnull_tuples[0]= (# of {keypart1} tuples such that keypart1 is not NULL) + notnull_tuples[1]= (# of {keypart1,keypart2} tuples such that all + keypart{i} are not NULL) + ... + For all other statistics collection methods notnull_tuples=NULL. + The 'unique' array is collected in one sequential scan through the entire index. This is done in two places: in chk_index() and in sort_key_write(). - Statistics collection may consider NULLs as either equal or unequal (see - SEARCH_NULL_ARE_NOT_EQUAL, MI_STATS_METHOD_*). + notnull_tuples, if present, is collected during the same index scan. Output is an array: rec_per_key_part[k] = @@ -4007,25 +4125,53 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, index tuples} = #tuples-in-the-index / #distinct-tuples-in-the-index. + + The #tuples-in-the-index and #distinct-tuples-in-the-index have different + meaning depending on which statistics collection method is used: + + MI_STATS_METHOD_* how are nulls compared? which tuples are counted? + NULLS_EQUAL NULL == NULL all tuples in table + NULLS_NOT_EQUAL NULL != NULL all tuples in table + IGNORE_NULLS n/a tuples that don't have NULLs */ void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part, - ulonglong *unique, ulonglong records) + ulonglong *unique, ulonglong *notnull, + ulonglong records) { - ulonglong count=0,tmp; + ulonglong count=0,tmp, unique_tuples; + ulonglong tuples= records; uint parts; for (parts=0 ; parts < keyinfo->keysegs ; parts++) { count+=unique[parts]; - if (count == 0) - tmp=records; + unique_tuples= count + 1; + if (notnull) + { + tuples= notnull[parts]; + /* + #(unique_tuples not counting tuples with NULLs) = + #(unique_tuples counting tuples with NULLs as different) - + #(tuples with NULLs) + */ + unique_tuples -= (records - notnull[parts]); + } + + if (unique_tuples == 0) + tmp= 1; + else if (count == 0) + tmp= tuples; /* 1 unique tuple */ else - tmp= (records + (count+1)/2) / (count+1); - /* for some weird keys (e.g. FULLTEXT) tmp can be <1 here. - let's ensure it is not */ + tmp= (tuples + unique_tuples/2) / unique_tuples; + + /* + for some weird keys (e.g. FULLTEXT) tmp can be <1 here. + let's ensure it is not + */ set_if_bigger(tmp,1); if (tmp >= (ulonglong) ~(ulong) 0) tmp=(ulonglong) ~(ulong) 0; + *rec_per_key_part=(ulong) tmp; rec_per_key_part++; } diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 2dd05cf7e67..d68ea410852 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -339,7 +339,8 @@ static struct my_option my_long_options[] = REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"stats_method", OPT_STATS_METHOD, "Specifies how index statistics collection code should threat NULLs. " - "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), and \"nulls_equal\" (emulate 4.0 behavior).", + "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), " + "\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".", (gptr*) &myisam_stats_method_str, (gptr*) &myisam_stats_method_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} @@ -451,6 +452,10 @@ static void usage(void) -a, --analyze Analyze distribution of keys. Will make some joins in\n\ MySQL faster. You can check the calculated distribution\n\ by using '--description --verbose table_name'.\n\ + --stats_method=name Specifies how index statistics collection code should\n\ + threat NULLs. Possible values of name are \"nulls_unequal\"\n\ + (default for 4.1/5.0), \"nulls_equal\" (emulate 4.0), and \n\ + \"nulls_ignored\".\n\ -d, --description Prints some information about table.\n\ -A, --set-auto-increment[=value]\n\ Force auto_increment to start at this or higher value\n\ @@ -472,7 +477,7 @@ static void usage(void) #include const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal", - NullS}; + "nulls_ignored", NullS}; TYPELIB myisam_stats_method_typelib= { array_elements(myisam_stats_method_names) - 1, "", myisam_stats_method_names, NULL}; @@ -699,14 +704,25 @@ get_one_option(int optid, case OPT_STATS_METHOD: { int method; + enum_mi_stats_method method_conv; myisam_stats_method_str= argument; if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0) { fprintf(stderr, "Invalid value of stats_method: %s.\n", argument); exit(1); } - check_param.stats_method= test(method-1)? MI_STATS_METHOD_NULLS_EQUAL : - MI_STATS_METHOD_NULLS_NOT_EQUAL; + switch (method-1) { + case 0: + method_conv= MI_STATS_METHOD_NULLS_EQUAL; + break; + case 1: + method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL; + break; + case 2: + method_conv= MI_STATS_METHOD_IGNORE_NULLS; + break; + } + check_param.stats_method= method_conv; break; } #ifdef DEBUG /* Only useful if debugging */ diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 93a7bf96f59..a766d59d72a 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -297,7 +297,14 @@ typedef struct st_mi_sort_param pthread_t thr; IO_CACHE read_cache, tempfile, tempfile_for_exceptions; DYNAMIC_ARRAY buffpek; + + /* + The next two are used to collect statistics, see update_key_parts for + description. + */ ulonglong unique[MI_MAX_KEY_SEG+1]; + ulonglong notnull[MI_MAX_KEY_SEG+1]; + my_off_t pos,max_pos,filepos,start_recpos; uint key, key_length,real_key_length,sortbuff_size; uint maxbuffers, keys, find_length, sort_keys_length; diff --git a/myisam/sort.c b/myisam/sort.c index e8cd9938e42..96b55d599c8 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -481,8 +481,12 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) { share->state.key_map|=(ulonglong) 1 << sinfo->key; if (param->testflag & T_STATISTICS) - update_key_parts(sinfo->keyinfo, rec_per_key_part, - sinfo->unique, (ulonglong) info->state->records); + update_key_parts(sinfo->keyinfo, rec_per_key_part, sinfo->unique, + param->stats_method == MI_STATS_METHOD_IGNORE_NULLS? + sinfo->notnull: NULL, + (ulonglong) info->state->records); + + if (!sinfo->buffpek.elements) { if (param->testflag & T_VERBOSE) diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 0a6f3ddc28b..17dba82dc00 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -670,3 +670,35 @@ show index from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t1 1 a 1 a A 10 NULL NULL YES BTREE drop table t1; +set myisam_stats_method=nulls_ignored; +show variables like 'myisam_stats_method'; +Variable_name Value +myisam_stats_method nulls_ignored +create table t1 ( +a char(3), b char(4), c char(5), d char(6), +key(a,b,c,d) +); +insert into t1 values ('bcd','def1', NULL, 'zz'); +insert into t1 values ('bcd','def2', NULL, 'zz'); +insert into t1 values ('bce','def1', 'yuu', NULL); +insert into t1 values ('bce','def2', NULL, 'quux'); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +show index from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A 2 NULL NULL YES BTREE +t1 1 a 2 b A 4 NULL NULL YES BTREE +t1 1 a 3 c A 4 NULL NULL YES BTREE +t1 1 a 4 d A 4 NULL NULL YES BTREE +delete from t1; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +show index from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A 0 NULL NULL YES BTREE +t1 1 a 2 b A 0 NULL NULL YES BTREE +t1 1 a 3 c A 0 NULL NULL YES BTREE +t1 1 a 4 d A 0 NULL NULL YES BTREE +set myisam_stats_method=DEFAULT; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index dc40ecc2dd4..fbde658660d 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -637,4 +637,23 @@ show index from t1; drop table t1; +# WL#2609, CSC#XXXX: MyISAM +set myisam_stats_method=nulls_ignored; +show variables like 'myisam_stats_method'; + +create table t1 ( + a char(3), b char(4), c char(5), d char(6), + key(a,b,c,d) +); +insert into t1 values ('bcd','def1', NULL, 'zz'); +insert into t1 values ('bcd','def2', NULL, 'zz'); +insert into t1 values ('bce','def1', 'yuu', NULL); +insert into t1 values ('bce','def2', NULL, 'quux'); +analyze table t1; +show index from t1; +delete from t1; +analyze table t1; +show index from t1; + +set myisam_stats_method=DEFAULT; # End of 4.1 tests diff --git a/mysys/my_handler.c b/mysys/my_handler.c index 5ee181ca78e..14b71dcbc8b 100644 --- a/mysys/my_handler.c +++ b/mysys/my_handler.c @@ -75,7 +75,7 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length, SYNOPSIS ha_key_cmp() - keyseg Key segments of key to compare + keyseg Array of key segments of key to compare a First key to compare, in format from _mi_pack_key() This is normally key specified by user b Second key to compare. This is always from a row @@ -84,10 +84,20 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length, next_flag How keys should be compared If bit SEARCH_FIND is not set the keys includes the row position and this should also be compared - + diff_pos OUT Number of first keypart where values differ, counting + from one. + NOTES Number-keys can't be splited + DESCRIPTION + + If SEARCH_RETURN_B_POS flag is set, diff_pos must point to array of 2 + values, first value has the meaning as described above, second value is: + + diff_pos[1] OUT (b + diff_pos[1]) points to first value in tuple b + that is different from corresponding value in tuple a. + RETURN VALUES <0 If a < b 0 If a == b @@ -107,6 +117,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, float f_1,f_2; double d_1,d_2; uint next_key_length; + uchar *orig_b= b; *diff_pos=0; for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++) @@ -115,6 +126,9 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, uint piks=! (keyseg->flag & HA_NO_SORT); (*diff_pos)++; + if (nextflag & SEARCH_RETURN_B_POS) + diff_pos[1]= (uint)(b - orig_b); + /* Handle NULL part */ if (keyseg->null_bit) { @@ -448,3 +462,84 @@ end: } return 0; } /* ha_key_cmp */ + + +/* + Find the first NULL value in index-suffix values tuple + + SYNOPSIS + ha_find_null() + keyseg Array of keyparts for key suffix + a Key suffix value tuple + + DESCRIPTION + Find the first NULL value in index-suffix values tuple. + TODO Consider optimizing this fuction or its use so we don't search for + NULL values in completely NOT NULL index suffixes. + + RETURN + First key part that has NULL as value in values tuple, or the last key part + (with keyseg->type==HA_TYPE_END) if values tuple doesn't contain NULLs. +*/ + +HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a) +{ + for (; (enum ha_base_keytype) keyseg->type != HA_KEYTYPE_END; keyseg++) + { + uchar *end; + if (keyseg->null_bit) + { + if (!*a++) + return keyseg; + } + end= a+ keyseg->length; + + switch ((enum ha_base_keytype) keyseg->type) { + case HA_KEYTYPE_TEXT: + case HA_KEYTYPE_BINARY: + if (keyseg->flag & HA_SPACE_PACK) + { + int a_length; + get_key_length(a_length, a); + a += a_length; + break; + } + else + a= end; + break; + case HA_KEYTYPE_VARTEXT: + case HA_KEYTYPE_VARBINARY: + { + int a_length; + get_key_length(a_length, a); + a+= a_length; + break; + } + case HA_KEYTYPE_NUM: + if (keyseg->flag & HA_SPACE_PACK) + { + int alength= *a++; + end= a+alength; + } + a= end; + break; + case HA_KEYTYPE_INT8: + case HA_KEYTYPE_SHORT_INT: + case HA_KEYTYPE_USHORT_INT: + case HA_KEYTYPE_LONG_INT: + case HA_KEYTYPE_ULONG_INT: + case HA_KEYTYPE_INT24: + case HA_KEYTYPE_UINT24: +#ifdef HAVE_LONG_LONG + case HA_KEYTYPE_LONGLONG: + case HA_KEYTYPE_ULONGLONG: +#endif + case HA_KEYTYPE_FLOAT: + case HA_KEYTYPE_DOUBLE: + a= end; + break; + } + } + return keyseg; +} + diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 87529cc8713..9b84e48e970 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -40,7 +40,7 @@ TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"", myisam_recover_names, NULL}; const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal", - NullS}; + "nulls_ignored", NullS}; TYPELIB myisam_stats_method_typelib= { array_elements(myisam_stats_method_names) - 1, "", myisam_stats_method_names, NULL}; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a6a91ac32ee..4a0394247e3 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5212,7 +5212,8 @@ The minimum value for this variable is 4096.", GET_ULONG, REQUIRED_ARG, 8192*1024, 4, ~0L, 0, 1, 0}, {"myisam_stats_method", OPT_MYISAM_STATS_METHOD, "Specifies how MyISAM index statistics collection code should threat NULLs. " - "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), and \"nulls_equal\" (emulate 4.0 behavior).", + "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), " + "\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".", (gptr*) &myisam_stats_method_str, (gptr*) &myisam_stats_method_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"net_buffer_length", OPT_NET_BUFFER_LENGTH, @@ -6405,16 +6406,26 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } case OPT_MYISAM_STATS_METHOD: { - myisam_stats_method_str= argument; int method; + ulong method_conv; + myisam_stats_method_str= argument; if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0) { fprintf(stderr, "Invalid value of myisam_stats_method: %s.\n", argument); exit(1); } - global_system_variables.myisam_stats_method= - test(method-1)? MI_STATS_METHOD_NULLS_EQUAL : - MI_STATS_METHOD_NULLS_NOT_EQUAL; + switch (method-1) { + case 0: + method_conv= MI_STATS_METHOD_NULLS_EQUAL; + break; + case 1: + method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL; + break; + case 2: + method_conv= MI_STATS_METHOD_IGNORE_NULLS; + break; + } + global_system_variables.myisam_stats_method= method_conv; break; } case OPT_SQL_MODE: -- cgit v1.2.1 From 02dc7bfb1a52c21621356cc0799f3f896a2e2fea Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 23 Oct 2005 02:46:10 +0400 Subject: BUG#9622: post-review-fixes: better comments --- include/myisam.h | 2 +- myisam/mi_check.c | 54 ++++++++++++++++++++++++++++++++---------------------- mysys/my_handler.c | 26 +++++++++++++++++++------- 3 files changed, 52 insertions(+), 30 deletions(-) diff --git a/include/myisam.h b/include/myisam.h index e564bf29cac..c2d3d99a414 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -323,7 +323,7 @@ typedef enum MI_STATS_METHOD_NULLS_NOT_EQUAL, /* Treat NULLs as equal when collecting statistics (like 4.0 did) */ MI_STATS_METHOD_NULLS_EQUAL, - /* Ignore NULLs - count tuples without NULLs only */ + /* Ignore NULLs - count only tuples without NULLs in the index components */ MI_STATS_METHOD_IGNORE_NULLS } enum_mi_stats_method; diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 1fd7f1b45f6..75f25f1361a 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -603,10 +603,11 @@ void mi_collect_stats_nonulls_first(HA_KEYSEG *keyseg, ulonglong *notnull, Process the next index tuple: 1. Find out which prefix tuples of last_key don't contain NULLs, and update the array of notnull counters accordingly. - 2. Find the first keypart number where the tuples are different(A), or - last_key has NULL value (B), and return it, so caller can count - number of unique tuples for each key prefix. We don't need (B) to be - counted, and that is compensated back in update_key_parts(). + 2. Find the first keypart number where the prev_key and last_key tuples + are different(A), or last_key has NULL value(B), and return it, so the + caller can count number of unique tuples for each key prefix. We don't + need (B) to be counted, and that is compensated back in + update_key_parts(). RETURN 1 + number of first keypart where values differ or last_key tuple has NULL @@ -619,11 +620,19 @@ int mi_collect_stats_nonulls_next(HA_KEYSEG *keyseg, ulonglong *notnull, uint diffs[2]; uint first_null_seg, kp; - /* Find first keypart where values are different or either of them is NULL */ + /* + Find the first keypart where values are different or either of them is + NULL. We get results in diffs array: + diffs[0]= 1 + number of first different keypart + diffs[1]=offset: (last_key + diffs[1]) points to first value in + last_key that is NULL or different from corresponding + value in prev_key. + */ ha_key_cmp(keyseg, prev_key, last_key, USE_WHOLE_KEY, SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL | SEARCH_RETURN_B_POS, diffs); HA_KEYSEG *seg= keyseg + diffs[0] - 1; + /* Find first NULL in last_key */ first_null_seg= ha_find_null(seg, last_key + diffs[1]) - keyseg; for (kp= 0; kp < first_null_seg; kp++) @@ -4087,7 +4096,7 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, /* Update statistics for each part of an index - + SYNOPSIS update_key_parts() keyinfo IN Index information (only key->keysegs used) @@ -4095,25 +4104,26 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, unique IN Array of (#distinct tuples) notnull_tuples IN Array of (#tuples), or NULL records Number of records in the table - - NOTES + + DESCRIPTION + This function is called produce index statistics values from unique and + notnull_tuples arrays after these arrays were produced with sequential + index scan (the scan is done in two places: chk_index() and + sort_key_write()). + This function handles all 3 index statistics collection methods. Unique is an array: - unique[0]= (#different values of {keypart1}) - 1 - unique[1]= (#different values of {keypart1,keypart2} tuple) - unique[0] - 1 - ... - - For MI_STATS_METHOD_IGNORE_NULLS notnull_tuples is an array too: - notnull_tuples[0]= (# of {keypart1} tuples such that keypart1 is not NULL) - notnull_tuples[1]= (# of {keypart1,keypart2} tuples such that all - keypart{i} are not NULL) - ... - For all other statistics collection methods notnull_tuples=NULL. - - The 'unique' array is collected in one sequential scan through the entire - index. This is done in two places: in chk_index() and in sort_key_write(). - notnull_tuples, if present, is collected during the same index scan. + unique[0]= (#different values of {keypart1}) - 1 + unique[1]= (#different values of {keypart1,keypart2} tuple)-unique[0]-1 + ... + + For MI_STATS_METHOD_IGNORE_NULLS method, notnull_tuples is an array too: + notnull_tuples[0]= (#of {keypart1} tuples such that keypart1 is not NULL) + notnull_tuples[1]= (#of {keypart1,keypart2} tuples such that all + keypart{i} are not NULL) + ... + For all other statistics collection methods notnull_tuples==NULL. Output is an array: rec_per_key_part[k] = diff --git a/mysys/my_handler.c b/mysys/my_handler.c index 14b71dcbc8b..135480756da 100644 --- a/mysys/my_handler.c +++ b/mysys/my_handler.c @@ -86,18 +86,30 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length, position and this should also be compared diff_pos OUT Number of first keypart where values differ, counting from one. - - NOTES - Number-keys can't be splited DESCRIPTION - If SEARCH_RETURN_B_POS flag is set, diff_pos must point to array of 2 - values, first value has the meaning as described above, second value is: - + values, first value has the meaning as described in parameter + description above, the second value is: + diff_pos[1] OUT (b + diff_pos[1]) points to first value in tuple b that is different from corresponding value in tuple a. - + + EXAMPLES + Example1: if the function is called for tuples + ('aaa','bbb') and ('eee','fff'), then + diff_pos[0] = 1 (as 'aaa' != 'eee') + diff_pos[1] = 0 (offset from beggining of tuple b to 'eee' keypart). + + Example2: if the index function is called for tuples + ('aaa','bbb') and ('aaa','fff'), + diff_pos[0] = 2 (as 'aaa' != 'eee') + diff_pos[1] = 3 (offset from beggining of tuple b to 'fff' keypart, + here we assume that first key part is CHAR(3) NOT NULL) + + NOTES + Number-keys can't be splited + RETURN VALUES <0 If a < b 0 If a == b -- cgit v1.2.1 From 8d6634c9e0c43b2d4ed2b0cc9f90b66c850855ab Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 25 Oct 2005 02:27:40 +0300 Subject: Added more tests for new UPDATE ... ORDER BY ... LIMIT optimization heap/_check.c: Change arguments to ha_key_cmp heap/hp_create.c: Change arguments to ha_key_cmp include/my_base.h: Remove SEARCH_RETURN_B_POS and instead always send an array to ha_key_cmp() as last argument myisam/mi_check.c: Change arguments to ha_key_cmp myisam/mi_rnext_same.c: Change arguments to ha_key_cmp myisam/mi_search.c: Change arguments to ha_key_cmp myisam/mi_write.c: Change arguments to ha_key_cmp myisammrg/myrg_queue.c: Change arguments to ha_key_cmp mysys/my_handler.c: Remove SEARCH_RETURN_B_POS and instead always send an array to ha_key_cmp() as last argument (This removes an if in a loop at the expensive of an int on the stack) sql/records.cc: Simplify new rr_index() code Create common error handling function for rr_() functions. Remove loop from rr_index() as handler::index_next() can never return HA_ERR_RECORD_DELETED sql/sql_load.cc: Simplify sql/sql_update.cc: Simplify code Fixed bug when one is updating an index column that could be used with ORDER BY sql/structs.h: Removed not needed structure element --- heap/_check.c | 4 +- heap/hp_create.c | 4 +- include/my_base.h | 2 - myisam/mi_check.c | 36 ++++----- myisam/mi_rnext_same.c | 4 +- myisam/mi_search.c | 18 ++--- myisam/mi_write.c | 6 +- myisammrg/myrg_queue.c | 4 +- mysql-test/r/update.result | 31 ++++++-- mysql-test/t/update.test | 13 +++- mysys/my_handler.c | 14 +--- sql/records.cc | 182 +++++++++++++++++++++------------------------ sql/sql_load.cc | 7 +- sql/sql_update.cc | 24 +++--- sql/structs.h | 1 - 15 files changed, 169 insertions(+), 181 deletions(-) diff --git a/heap/_check.c b/heap/_check.c index a745aee48bf..ad432856a69 100644 --- a/heap/_check.c +++ b/heap/_check.c @@ -167,7 +167,7 @@ static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records, ulong found= 0; byte *key, *recpos; uint key_length; - uint not_used; + uint not_used[2]; if ((key= tree_search_edge(&keydef->rb_tree, info->parents, &info->last_pos, offsetof(TREE_ELEMENT, left)))) @@ -177,7 +177,7 @@ static int check_one_rb_key(HP_INFO *info, uint keynr, ulong records, memcpy(&recpos, key + (*keydef->get_key_length)(keydef,key), sizeof(byte*)); key_length= hp_rb_make_key(keydef, info->recbuf, recpos, 0); if (ha_key_cmp(keydef->seg, (uchar*) info->recbuf, (uchar*) key, - key_length, SEARCH_FIND | SEARCH_SAME, ¬_used)) + key_length, SEARCH_FIND | SEARCH_SAME, not_used)) { error= 1; DBUG_PRINT("error",("Record in wrong link: key: %d Record: %lx\n", diff --git a/heap/hp_create.c b/heap/hp_create.c index af32fefea1b..2b811dac89b 100644 --- a/heap/hp_create.c +++ b/heap/hp_create.c @@ -170,9 +170,9 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2) { - uint not_used; + uint not_used[2]; return ha_key_cmp(param->keyseg, key1, key2, param->key_length, - param->search_flag, ¬_used); + param->search_flag, not_used); } static void init_block(HP_BLOCK *block, uint reclength, ulong min_records, diff --git a/include/my_base.h b/include/my_base.h index 950af8903ff..d702ec45140 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -319,8 +319,6 @@ enum ha_base_keytype { #define SEARCH_NULL_ARE_EQUAL 32768 /* NULL in keys are equal */ #define SEARCH_NULL_ARE_NOT_EQUAL 65536 /* NULL in keys are not equal */ -#define SEARCH_RETURN_B_POS (65536*2) /* see ha_key_cmp for description */ - /* bits in opt_flag */ #define QUICK_USED 1 #define READ_CACHE_USED 2 diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 75f25f1361a..ef384c4bcc6 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -619,6 +619,7 @@ int mi_collect_stats_nonulls_next(HA_KEYSEG *keyseg, ulonglong *notnull, { uint diffs[2]; uint first_null_seg, kp; + HA_KEYSEG *seg; /* Find the first keypart where values are different or either of them is @@ -629,9 +630,8 @@ int mi_collect_stats_nonulls_next(HA_KEYSEG *keyseg, ulonglong *notnull, value in prev_key. */ ha_key_cmp(keyseg, prev_key, last_key, USE_WHOLE_KEY, - SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL | SEARCH_RETURN_B_POS, - diffs); - HA_KEYSEG *seg= keyseg + diffs[0] - 1; + SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diffs); + seg= keyseg + diffs[0] - 1; /* Find first NULL in last_key */ first_null_seg= ha_find_null(seg, last_key + diffs[1]) - keyseg; @@ -658,7 +658,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, uchar key[MI_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos; my_off_t next_page,record; char llbuff[22]; - uint diff_pos; + uint diff_pos[2]; DBUG_ENTER("chk_index"); DBUG_DUMP("buff",(byte*) buff,mi_getint(buff)); @@ -716,7 +716,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, } if ((*keys)++ && (flag=ha_key_cmp(keyinfo->seg,info->lastkey,key,key_length, - comp_flag, &diff_pos)) >=0) + comp_flag, diff_pos)) >=0) { DBUG_DUMP("old",(byte*) info->lastkey, info->lastkey_length); DBUG_DUMP("new",(byte*) key, key_length); @@ -735,14 +735,14 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL) ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY, SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, - &diff_pos); + diff_pos); else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS) { - diff_pos= mi_collect_stats_nonulls_next(keyinfo->seg, + diff_pos[0]= mi_collect_stats_nonulls_next(keyinfo->seg, param->notnull_count, info->lastkey, key); } - param->unique_count[diff_pos-1]++; + param->unique_count[diff_pos[0]-1]++; } else { @@ -3340,15 +3340,15 @@ int sort_write_record(MI_SORT_PARAM *sort_param) static int sort_key_cmp(MI_SORT_PARAM *sort_param, const void *a, const void *b) { - uint not_used; + uint not_used[2]; return (ha_key_cmp(sort_param->seg, *((uchar**) a), *((uchar**) b), - USE_WHOLE_KEY, SEARCH_SAME,¬_used)); + USE_WHOLE_KEY, SEARCH_SAME, not_used)); } /* sort_key_cmp */ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a) { - uint diff_pos; + uint diff_pos[2]; char llbuff[22],llbuff2[22]; SORT_INFO *sort_info=sort_param->sort_info; MI_CHECK *param= sort_info->param; @@ -3358,19 +3358,19 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a) { cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey, (uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE, - &diff_pos); + diff_pos); if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL) ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey, (uchar*) a, USE_WHOLE_KEY, - SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, &diff_pos); + SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, diff_pos); else if (param->stats_method == MI_STATS_METHOD_IGNORE_NULLS) { - diff_pos= mi_collect_stats_nonulls_next(sort_param->seg, - sort_param->notnull, - sort_info->key_block->lastkey, - (uchar*)a); + diff_pos[0]= mi_collect_stats_nonulls_next(sort_param->seg, + sort_param->notnull, + sort_info->key_block->lastkey, + (uchar*)a); } - sort_param->unique[diff_pos-1]++; + sort_param->unique[diff_pos[0]-1]++; } else { diff --git a/myisam/mi_rnext_same.c b/myisam/mi_rnext_same.c index 4d770258a72..92692d0517f 100644 --- a/myisam/mi_rnext_same.c +++ b/myisam/mi_rnext_same.c @@ -28,7 +28,7 @@ int mi_rnext_same(MI_INFO *info, byte *buf) { int error; - uint inx,not_used; + uint inx,not_used[2]; MI_KEYDEF *keyinfo; DBUG_ENTER("mi_rnext_same"); @@ -69,7 +69,7 @@ int mi_rnext_same(MI_INFO *info, byte *buf) info->s->state.key_root[inx]))) break; if (ha_key_cmp(keyinfo->seg, info->lastkey, info->lastkey2, - info->last_rkey_length, SEARCH_FIND, ¬_used)) + info->last_rkey_length, SEARCH_FIND, not_used)) { error=1; my_errno=HA_ERR_END_OF_FILE; diff --git a/myisam/mi_search.c b/myisam/mi_search.c index 4ea2480889e..9321f5b87d5 100644 --- a/myisam/mi_search.c +++ b/myisam/mi_search.c @@ -128,13 +128,13 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, if ((nextflag & (SEARCH_SMALLER | SEARCH_LAST)) && flag != 0) { - uint not_used; + uint not_used[2]; if (_mi_get_prev_key(info,keyinfo, buff, info->lastkey, keypos, &info->lastkey_length)) goto err; if (!(nextflag & SEARCH_SMALLER) && ha_key_cmp(keyinfo->seg, info->lastkey, key, key_len, SEARCH_FIND, - ¬_used)) + not_used)) { my_errno=HA_ERR_KEY_NOT_FOUND; /* Didn't find key */ goto err; @@ -178,7 +178,7 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, { reg4 int start,mid,end,save_end; int flag; - uint totlength,nod_flag,not_used; + uint totlength,nod_flag,not_used[2]; DBUG_ENTER("_mi_bin_search"); LINT_INIT(flag); @@ -192,7 +192,7 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, { mid= (start+end)/2; if ((flag=ha_key_cmp(keyinfo->seg,page+(uint) mid*totlength,key,key_len, - comp_flag,¬_used)) + comp_flag, not_used)) >= 0) end=mid; else @@ -200,7 +200,7 @@ int _mi_bin_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, } if (mid != start) flag=ha_key_cmp(keyinfo->seg,page+(uint) start*totlength,key,key_len, - comp_flag,¬_used); + comp_flag, not_used); if (flag < 0) start++; /* point at next, bigger key */ *ret_pos=page+(uint) start*totlength; @@ -241,7 +241,7 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, uchar *buff, my_bool *last_key) { int flag; - uint nod_flag,length,not_used; + uint nod_flag,length,not_used[2]; uchar t_buff[MI_MAX_KEY_BUFF],*end; DBUG_ENTER("_mi_seq_search"); @@ -262,7 +262,7 @@ int _mi_seq_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, DBUG_RETURN(MI_FOUND_WRONG_KEY); } if ((flag=ha_key_cmp(keyinfo->seg,t_buff,key,key_len,comp_flag, - ¬_used)) >= 0) + not_used)) >= 0) break; #ifdef EXTRA_DEBUG DBUG_PRINT("loop",("page: %lx key: '%s' flag: %d", (long) page, t_buff, @@ -503,9 +503,9 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page, cmp_rest: if (key_len_left>0) { - uint not_used; + uint not_used[2]; if ((flag = ha_key_cmp(keyinfo->seg+1,vseg, - k,key_len_left,nextflag,¬_used)) >= 0) + k, key_len_left, nextflag, not_used)) >= 0) break; } else diff --git a/myisam/mi_write.c b/myisam/mi_write.c index cd9e73fba22..52455320515 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -885,10 +885,10 @@ int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key, static int keys_compare(bulk_insert_param *param, uchar *key1, uchar *key2) { - uint not_used; + uint not_used[2]; return ha_key_cmp(param->info->s->keyinfo[param->keynr].seg, - key1, key2, USE_WHOLE_KEY, SEARCH_SAME, - ¬_used); + key1, key2, USE_WHOLE_KEY, SEARCH_SAME, + not_used); } diff --git a/myisammrg/myrg_queue.c b/myisammrg/myrg_queue.c index dfb434d6397..7172b9f0e2a 100644 --- a/myisammrg/myrg_queue.c +++ b/myisammrg/myrg_queue.c @@ -20,9 +20,9 @@ static int queue_key_cmp(void *keyseg, byte *a, byte *b) { MI_INFO *aa=((MYRG_TABLE *)a)->table; MI_INFO *bb=((MYRG_TABLE *)b)->table; - uint not_used; + uint not_used[2]; int ret= ha_key_cmp((HA_KEYSEG *)keyseg, aa->lastkey, bb->lastkey, - USE_WHOLE_KEY, SEARCH_FIND, ¬_used); + USE_WHOLE_KEY, SEARCH_FIND, not_used); return ret < 0 ? -1 : ret > 0 ? 1 : 0; } /* queue_key_cmp */ diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index cf07487febc..3408766d603 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -263,8 +263,8 @@ test delete from t1 where count(*)=1; ERROR HY000: Invalid use of group function drop table t1; -create table t1 ( a int, index (a) ); -insert into t1 values (0),(0),(0),(0),(0),(0),(0),(0); +create table t1 ( a int, b int default 0, index (a) ); +insert into t1 (a) values (0),(0),(0),(0),(0),(0),(0),(0); flush status; select a from t1 order by a limit 1; a @@ -278,15 +278,16 @@ Handler_read_prev 0 Handler_read_rnd 0 Handler_read_rnd_next 0 flush status; -update t1 set a=unix_timestamp() order by a limit 1; +update t1 set a=9999 order by a limit 1; +update t1 set b=9999 order by a limit 1; show status like 'handler_read%'; Variable_name Value Handler_read_first 1 Handler_read_key 0 Handler_read_next 0 Handler_read_prev 0 -Handler_read_rnd 1 -Handler_read_rnd_next 0 +Handler_read_rnd 2 +Handler_read_rnd_next 9 flush status; delete from t1 order by a limit 1; show status like 'handler_read%'; @@ -318,7 +319,21 @@ Handler_read_next 0 Handler_read_prev 0 Handler_read_rnd 1 Handler_read_rnd_next 9 -select count(*) from t1; -count(*) -5 +select * from t1; +a b +0 0 +0 0 +0 0 +0 0 +0 0 +update t1 set a=a+10,b=1 order by a limit 3; +update t1 set a=a+11,b=2 order by a limit 3; +update t1 set a=a+12,b=3 order by a limit 3; +select * from t1 order by a; +a b +11 2 +21 2 +22 3 +22 3 +23 3 drop table t1; diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test index a37655b15fe..e81415628d0 100644 --- a/mysql-test/t/update.test +++ b/mysql-test/t/update.test @@ -228,15 +228,16 @@ delete from t1 where count(*)=1; drop table t1; # BUG#12915: Optimize "DELETE|UPDATE ... ORDER BY ... LIMIT n" to use an index -create table t1 ( a int, index (a) ); -insert into t1 values (0),(0),(0),(0),(0),(0),(0),(0); +create table t1 ( a int, b int default 0, index (a) ); +insert into t1 (a) values (0),(0),(0),(0),(0),(0),(0),(0); flush status; select a from t1 order by a limit 1; show status like 'handler_read%'; flush status; -update t1 set a=unix_timestamp() order by a limit 1; +update t1 set a=9999 order by a limit 1; +update t1 set b=9999 order by a limit 1; show status like 'handler_read%'; flush status; @@ -253,7 +254,11 @@ flush status; delete from t1 order by a limit 1; show status like 'handler_read%'; -select count(*) from t1; +select * from t1; +update t1 set a=a+10,b=1 order by a limit 3; +update t1 set a=a+11,b=2 order by a limit 3; +update t1 set a=a+12,b=3 order by a limit 3; +select * from t1 order by a; drop table t1; # End of 4.1 tests diff --git a/mysys/my_handler.c b/mysys/my_handler.c index 135480756da..3eed0ee6c08 100644 --- a/mysys/my_handler.c +++ b/mysys/my_handler.c @@ -86,15 +86,9 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length, position and this should also be compared diff_pos OUT Number of first keypart where values differ, counting from one. - - DESCRIPTION - If SEARCH_RETURN_B_POS flag is set, diff_pos must point to array of 2 - values, first value has the meaning as described in parameter - description above, the second value is: - - diff_pos[1] OUT (b + diff_pos[1]) points to first value in tuple b + diff_pos[1] OUT (b + diff_pos[1]) points to first value in tuple b that is different from corresponding value in tuple a. - + EXAMPLES Example1: if the function is called for tuples ('aaa','bbb') and ('eee','fff'), then @@ -137,9 +131,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, uchar *end; uint piks=! (keyseg->flag & HA_NO_SORT); (*diff_pos)++; - - if (nextflag & SEARCH_RETURN_B_POS) - diff_pos[1]= (uint)(b - orig_b); + diff_pos[1]= (uint)(b - orig_b); /* Handle NULL part */ if (keyseg->null_bit) diff --git a/sql/records.cc b/sql/records.cc index 9150024d4b8..7e4a808f0c3 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -28,11 +28,10 @@ static int rr_from_pointers(READ_RECORD *info); static int rr_from_cache(READ_RECORD *info); static int init_rr_cache(READ_RECORD *info); static int rr_cmp(uchar *a,uchar *b); - +static int rr_index_first(READ_RECORD *info); static int rr_index(READ_RECORD *info); - /* Initialize READ_RECORD structure to perform full index scan @@ -58,26 +57,19 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, bool print_error, uint idx) { bzero((char*) info,sizeof(*info)); - info->thd=thd; - info->table=table; - info->file= table->file; - info->forms= &info->table; /* Only one table */ - + info->table= table; + info->file= table->file; info->record= table->record[0]; - info->ref_length= table->file->ref_length; + info->print_error= print_error; - info->select=NULL; - info->print_error=print_error; - info->ignore_not_found_rows= 0; table->status=0; /* And it's always found */ - if (!table->file->inited) { table->file->ha_index_init(idx); table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY); } - info->read_record= rr_index; - info->first= TRUE; + /* read_record will be changed to rr_index in rr_index_first */ + info->read_record= rr_index_first; } @@ -204,6 +196,21 @@ void end_read_record(READ_RECORD *info) } } +static int rr_handle_error(READ_RECORD *info, int error) +{ + if (error == HA_ERR_END_OF_FILE) + error= -1; + else + { + if (info->print_error) + info->table->file->print_error(error, MYF(0)); + if (error < 0) // Fix negative BDB errno + error= 1; + } + return error; +} + + /* Read a record from head-database */ static int rr_quick(READ_RECORD *info) @@ -218,15 +225,7 @@ static int rr_quick(READ_RECORD *info) } if (tmp != HA_ERR_RECORD_DELETED) { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else - { - if (info->print_error) - info->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } + tmp= rr_handle_error(info, tmp); break; } } @@ -235,7 +234,31 @@ static int rr_quick(READ_RECORD *info) /* - A READ_RECORD::read_record implementation that reads index sequentially + Reads first row in an index scan + + SYNOPSIS + rr_index_first() + info Scan info + + RETURN + 0 Ok + -1 End of records + 1 Error +*/ + + +static int rr_index_first(READ_RECORD *info) +{ + int tmp= info->file->index_first(info->record); + info->read_record= rr_index; + if (tmp) + tmp= rr_handle_error(info, tmp); + return tmp; +} + + +/* + Reads index sequentially after first row SYNOPSIS rr_index() @@ -251,43 +274,16 @@ static int rr_quick(READ_RECORD *info) 1 Error */ + static int rr_index(READ_RECORD *info) { - int tmp; - while (1) - { - if (info->first) - { - info->first= FALSE; - tmp= info->file->index_first(info->record); - } - else - tmp= info->file->index_next(info->record); - - if (!tmp) - break; - if (info->thd->killed) - { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); - return 1; - } - if (tmp != HA_ERR_RECORD_DELETED) - { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else - { - if (info->print_error) - info->table->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } - break; - } - } + int tmp= info->file->index_next(info->record); + if (tmp) + tmp= rr_handle_error(info, tmp); return tmp; } + static int rr_sequential(READ_RECORD *info) { int tmp; @@ -298,17 +294,13 @@ static int rr_sequential(READ_RECORD *info) my_error(ER_SERVER_SHUTDOWN,MYF(0)); return 1; } + /* + rnd_next can return RECORD_DELETED for MyISAM when one thread is + reading and another deleting without locks. + */ if (tmp != HA_ERR_RECORD_DELETED) { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else - { - if (info->print_error) - info->table->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } + tmp= rr_handle_error(info, tmp); break; } } @@ -319,23 +311,18 @@ static int rr_sequential(READ_RECORD *info) static int rr_from_tempfile(READ_RECORD *info) { int tmp; -tryNext: - if (my_b_read(info->io_cache,info->ref_pos,info->ref_length)) - return -1; /* End of file */ - if ((tmp=info->file->rnd_pos(info->record,info->ref_pos))) + for (;;) { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else if (tmp == HA_ERR_RECORD_DELETED || - (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) - goto tryNext; - else - { - if (info->print_error) - info->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } + if (my_b_read(info->io_cache,info->ref_pos,info->ref_length)) + return -1; /* End of file */ + if (!(tmp=info->file->rnd_pos(info->record,info->ref_pos))) + break; + /* The following is extremely unlikely to happen */ + if (tmp == HA_ERR_RECORD_DELETED || + (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) + continue; + tmp= rr_handle_error(info, tmp); + break; } return tmp; } /* rr_from_tempfile */ @@ -373,26 +360,23 @@ static int rr_from_pointers(READ_RECORD *info) { int tmp; byte *cache_pos; -tryNext: - if (info->cache_pos == info->cache_end) - return -1; /* End of file */ - cache_pos=info->cache_pos; - info->cache_pos+=info->ref_length; - if ((tmp=info->file->rnd_pos(info->record,cache_pos))) + for (;;) { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else if (tmp == HA_ERR_RECORD_DELETED || - (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) - goto tryNext; - else - { - if (info->print_error) - info->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } + if (info->cache_pos == info->cache_end) + return -1; /* End of file */ + cache_pos= info->cache_pos; + info->cache_pos+= info->ref_length; + + if (!(tmp=info->file->rnd_pos(info->record,cache_pos))) + break; + + /* The following is extremely unlikely to happen */ + if (tmp == HA_ERR_RECORD_DELETED || + (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) + continue; + tmp= rr_handle_error(info, tmp); + break; } return tmp; } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 3b7c6608aef..aa4ea3e6c8c 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -818,11 +818,8 @@ int READ_INFO::read_field() *to++ = (byte) unescape((char) chr); continue; } - else - { - PUSH(chr); - chr= escape_char; - } + PUSH(chr); + chr= escape_char; } #ifdef ALLOW_LINESEPARATOR_IN_STRINGS if (chr == line_term_char) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index c30749677d6..b6bce800b0e 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -148,7 +148,7 @@ int mysql_update(THD *thd, } if (!select && limit != HA_POS_ERROR) { - if (MAX_KEY != (used_index= get_index_for_order(table, order, limit))) + if ((used_index= get_index_for_order(table, order, limit)) != MAX_KEY) need_sort= FALSE; } /* If running in safe sql mode, don't allow updates without keys */ @@ -171,14 +171,14 @@ int mysql_update(THD *thd, used_key_is_modified= (!select->quick->unique_key_range() && check_if_key_used(table, used_index, fields)); } - else if (used_index != MAX_KEY) + else { - used_key_is_modified= check_if_key_used(table, used_index, fields); + used_key_is_modified= 0; + if (used_index == MAX_KEY) // no index for sort order + used_index= table->file->key_used_on_scan; + if (used_index != MAX_KEY) + used_key_is_modified= check_if_key_used(table, used_index, fields); } - else if ((used_index=table->file->key_used_on_scan) < MAX_KEY) - used_key_is_modified=check_if_key_used(table, used_index, fields); - else - used_key_is_modified=0; if (used_key_is_modified || order) { @@ -190,11 +190,11 @@ int mysql_update(THD *thd, if (used_index < MAX_KEY && old_used_keys.is_set(used_index)) { table->key_read=1; - table->file->extra(HA_EXTRA_KEYREAD); //todo: psergey: check + table->file->extra(HA_EXTRA_KEYREAD); } /* note: can actually avoid sorting below.. */ - if (order && need_sort) + if (order && (need_sort || used_key_is_modified)) { /* Doing an ORDER BY; Let filesort find and sort the rows we are going @@ -204,6 +204,7 @@ int mysql_update(THD *thd, SORT_FIELD *sortorder; ha_rows examined_rows; + used_index= MAX_KEY; // For call to init_read_record() table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), MYF(MY_FAE | MY_ZEROFILL)); if (!(sortorder=make_unireg_sortorder(order, &length)) || @@ -265,10 +266,7 @@ int mysql_update(THD *thd, error= 1; // Aborted limit= tmp_limit; end_read_record(&info); - - /* if we got here we must not use index in the main update loop below */ - used_index= MAX_KEY; - + /* Change select to use tempfile */ if (select) { diff --git a/sql/structs.h b/sql/structs.h index 4a88a17cdd0..081ada88bf7 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -132,7 +132,6 @@ typedef struct st_read_record { /* Parameter to read_record */ byte *cache,*cache_pos,*cache_end,*read_positions; IO_CACHE *io_cache; bool print_error, ignore_not_found_rows; - bool first; /* used only with rr_index_read */ } READ_RECORD; -- cgit v1.2.1 From b31dd53c853179e5c4d84cd7f7eeb9b09ca3cbbf Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 25 Oct 2005 12:11:31 +0300 Subject: Changed some dbug print options. myisam/mi_check.c: Changed print style for keyoffset. myisam/mi_delete.c: Changed print style for keypos. --- myisam/mi_check.c | 7 ++++--- myisam/mi_delete.c | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 7397ee4e204..f4bc7a59549 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1731,9 +1731,10 @@ static int sort_one_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, _mi_kpointer(info,keypos-nod_flag,param->new_file_pos); /* Save new pos */ if (sort_one_index(param,info,keyinfo,next_page,new_file)) { - DBUG_PRINT("error",("From page: %ld, keyoffset: %d used_length: %d", - (ulong) pagepos, (int) (keypos - buff), - (int) used_length)); + DBUG_PRINT("error", + ("From page: %ld, keyoffset: 0x%lx used_length: %d", + (ulong) pagepos, (ulong) (keypos - buff), + (int) used_length)); DBUG_DUMP("buff",(byte*) buff,used_length); goto err; } diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c index b964cb35dd8..833223221ec 100644 --- a/myisam/mi_delete.c +++ b/myisam/mi_delete.c @@ -390,7 +390,8 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key, MYISAM_SHARE *share=info->s; MI_KEY_PARAM s_temp; DBUG_ENTER("del"); - DBUG_PRINT("enter",("leaf_page: %ld keypos: %lx",leaf_page,keypos)); + DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx", leaf_page, + (ulong) keypos)); DBUG_DUMP("leaf_buff",(byte*) leaf_buff,mi_getint(leaf_buff)); endpos=leaf_buff+mi_getint(leaf_buff); @@ -495,7 +496,8 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo, MI_KEY_PARAM s_temp; MYISAM_SHARE *share=info->s; DBUG_ENTER("underflow"); - DBUG_PRINT("enter",("leaf_page: %ld keypos: %lx",(long) leaf_page,keypos)); + DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx",(long) leaf_page, + (ulong) keypos)); DBUG_DUMP("anc_buff",(byte*) anc_buff,mi_getint(anc_buff)); DBUG_DUMP("leaf_buff",(byte*) leaf_buff,mi_getint(leaf_buff)); -- cgit v1.2.1 From cabb72f27fe1335a5bdb2ce823f0bb6966ee545b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 25 Oct 2005 14:49:04 +0500 Subject: Bug#13347: empty result from query with like and cp1250 charset ctype-win1250ch.c: Like range prefix tables were wrong. ctype_cp1250_ch.result, ctype_cp1250_ch.test: Adding test case. strings/ctype-win1250ch.c: Bug#13347: empty result from query with like and cp1250 charset Like range prefix tables were wrong. mysql-test/t/ctype_cp1250_ch.test: Adding test case. mysql-test/r/ctype_cp1250_ch.result: Adding test case. --- mysql-test/r/ctype_cp1250_ch.result | 23 ++++++++ mysql-test/t/ctype_cp1250_ch.test | 21 +++++++ strings/ctype-win1250ch.c | 110 +++++++++++++++++++++++++----------- 3 files changed, 120 insertions(+), 34 deletions(-) diff --git a/mysql-test/r/ctype_cp1250_ch.result b/mysql-test/r/ctype_cp1250_ch.result index 7b2ca7d7e0e..533bfb8cb53 100644 --- a/mysql-test/r/ctype_cp1250_ch.result +++ b/mysql-test/r/ctype_cp1250_ch.result @@ -19,3 +19,26 @@ SELECT * FROM t1 WHERE popisek LIKE '2005-01-1'; popisek 2005-01-1 drop table t1; +set names cp1250; +CREATE TABLE t1 +( +id INT AUTO_INCREMENT PRIMARY KEY, +str VARCHAR(32) CHARACTER SET cp1250 COLLATE cp1250_czech_cs NOT NULL default '', +UNIQUE KEY (str) +); +INSERT INTO t1 VALUES (NULL, 'a'); +INSERT INTO t1 VALUES (NULL, 'aa'); +INSERT INTO t1 VALUES (NULL, 'aaa'); +INSERT INTO t1 VALUES (NULL, 'aaaa'); +INSERT INTO t1 VALUES (NULL, 'aaaaa'); +INSERT INTO t1 VALUES (NULL, 'aaaaaa'); +INSERT INTO t1 VALUES (NULL, 'aaaaaaa'); +select * from t1 where str like 'aa%'; +id str +2 aa +3 aaa +4 aaaa +5 aaaaa +6 aaaaaa +7 aaaaaaa +drop table t1; diff --git a/mysql-test/t/ctype_cp1250_ch.test b/mysql-test/t/ctype_cp1250_ch.test index ea4b35a44a3..2d1e5f0bf9d 100644 --- a/mysql-test/t/ctype_cp1250_ch.test +++ b/mysql-test/t/ctype_cp1250_ch.test @@ -23,4 +23,25 @@ SELECT * FROM t1 WHERE popisek = '2005-01-1'; SELECT * FROM t1 WHERE popisek LIKE '2005-01-1'; drop table t1; +# +# Bug#13347: empty result from query with like and cp1250 charset +# +set names cp1250; +CREATE TABLE t1 +( + id INT AUTO_INCREMENT PRIMARY KEY, + str VARCHAR(32) CHARACTER SET cp1250 COLLATE cp1250_czech_cs NOT NULL default '', + UNIQUE KEY (str) +); + +INSERT INTO t1 VALUES (NULL, 'a'); +INSERT INTO t1 VALUES (NULL, 'aa'); +INSERT INTO t1 VALUES (NULL, 'aaa'); +INSERT INTO t1 VALUES (NULL, 'aaaa'); +INSERT INTO t1 VALUES (NULL, 'aaaaa'); +INSERT INTO t1 VALUES (NULL, 'aaaaaa'); +INSERT INTO t1 VALUES (NULL, 'aaaaaaa'); +select * from t1 where str like 'aa%'; +drop table t1; + # End of 4.1 tests diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 351af3de23e..e936ef1d423 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -512,42 +512,84 @@ static int my_strnxfrm_win1250ch(CHARSET_INFO * cs __attribute__((unused)), #ifdef REAL_MYSQL -static uchar NEAR like_range_prefix_min_win1250ch[] = +static uchar NEAR like_range_prefix_min_win1250ch[]= { -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, -48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, -80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, -96, 54, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, -80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 165, 124, 125, 126, 0, -0, 0, 130, 0, 132, 133, 134, 135, 0, 137, 138, 139, 83, 84, 142, 90, -0, 145, 146, 147, 148, 149, 150, 151, 0, 153, 138, 155, 83, 84, 142, 90, -32, 161, 162, 76, 164, 165, 166, 167, 168, 65, 83, 171, 172, 173, 174, 90, -176, 177, 178, 76, 180, 181, 0, 183, 184, 65, 83, 187, 76, 189, 76, 90, -82, 65, 65, 65, 65, 76, 67, 67, 200, 69, 69, 69, 69, 73, 73, 68, -68, 78, 78, 79, 79, 79, 79, 215, 216, 85, 85, 85, 85, 89, 84, 223, -82, 65, 65, 65, 65, 76, 67, 67, 200, 69, 69, 69, 69, 73, 73, 68, -68, 78, 78, 79, 79, 79, 79, 247, 216, 85, 85, 85, 85, 89, 84, 255, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, + 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; -static uchar NEAR like_range_prefix_max_win1250ch[] = { -182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, -182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, -160, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, -48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -64, 185, 98, 73, 240, 234, 102, 103, 104, 238, 106, 107, 179, 109, 242, 245, -112, 113, 224, 186, 254, 251, 118, 119, 120, 253, 159, 91, 92, 93, 94, 95, -96, 54, 98, 73, 240, 234, 102, 103, 104, 238, 106, 107, 179, 109, 242, 245, -112, 113, 224, 186, 254, 251, 118, 119, 120, 253, 159, 165, 124, 125, 126, 182, -182, 182, 130, 182, 132, 133, 134, 135, 182, 137, 154, 139, 186, 254, 158, 159, -182, 145, 146, 147, 148, 149, 150, 151, 182, 153, 154, 155, 186, 254, 158, 159, -32, 161, 162, 179, 164, 165, 166, 167, 168, 185, 186, 171, 172, 173, 174, 159, -176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 179, 189, 179, 159, -224, 185, 185, 185, 185, 179, 238, 238, 200, 234, 234, 234, 234, 238, 238, 240, -240, 242, 242, 245, 245, 245, 245, 215, 248, 251, 251, 251, 251, 253, 254, 223, -224, 185, 185, 185, 185, 179, 238, 238, 200, 234, 234, 234, 234, 238, 238, 240, -240, 242, 242, 245, 245, 245, 245, 247, 248, 251, 251, 251, 251, 253, 254, 255, + +/* + The letter "C" is a special case: + "CH" is sorted between "H" and "I". + prefix_max for "C" is "I": prefix_max[0x43] == 0x49 + prefix_max for "c" is "i": prefix_max[0x63] == 0x69 + For all other characters: prefix_max[i] == i +*/ + +static uchar NEAR like_range_prefix_max_win1250ch[]= +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x49, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x69, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, + 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF }; #define min_sort_char '\x20' -- cgit v1.2.1 From a345629ac699f718a5494afe2ea9e64bffdf3723 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 25 Oct 2005 16:56:25 +0300 Subject: Imported fixes from 4.1 and 5.0 to 4.0. --- include/config-netware.h | 4 ++++ netware/mysql_test_run.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/config-netware.h b/include/config-netware.h index 578975a1cea..310c9bb7db8 100644 --- a/include/config-netware.h +++ b/include/config-netware.h @@ -45,6 +45,7 @@ extern "C" { #undef HAVE_SCHED_H #undef HAVE_SYS_MMAN_H #undef HAVE_SYNCH_H +#undef HAVE_RINT #define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1 #define HAVE_PTHREAD_SIGMASK 1 #define HAVE_PTHREAD_YIELD_ZERO_ARG 1 @@ -91,6 +92,9 @@ extern "C" { /* On NetWare, stack grows towards lower address*/ #define STACK_DIRECTION -1 +/* On NetWare, to fix the problem with the deletion of open files */ +#define CANT_DELETE_OPEN_FILES 1 + /* default directory information */ #define DEFAULT_MYSQL_HOME "sys:/mysql" #define PACKAGE "mysql" diff --git a/netware/mysql_test_run.c b/netware/mysql_test_run.c index 28fbe34993d..e8d4c09bc16 100644 --- a/netware/mysql_test_run.c +++ b/netware/mysql_test_run.c @@ -173,7 +173,7 @@ void report_stats() mtr_log("\nFailed %u/%u test(s), %.02f%% successful.\n", total_fail, total_test, percent); mtr_log("\nThe .out and .err files in %s may give you some\n", result_dir); - mtr_log("hint of what when wrong.\n"); + mtr_log("hint of what went wrong.\n"); mtr_log("\nIf you want to report this error, please first read the documentation\n"); mtr_log("at: http://www.mysql.com/doc/M/y/MySQL_test_suite.html\n"); } -- cgit v1.2.1 From 45369edf570069f500b83c27b84004a0e4593074 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 25 Oct 2005 20:04:12 +0400 Subject: Fix bug#13392 Wrong VALUES() behaviour in INSERT SELECT with ON DUPLICATE VALUES() can only refer to table insert going to. But Item_insert_value::fix_fields() were passing to it's arg full table list, This results in finding second column which shouldn't be found, and failing with error about ambiguous field. Item_insert_value::fix_fields() now passes only first table of full table list. sql/item.cc: Fix bug #14016 date_format() 2nd parameter was compared using case insensitive collation. If second parameter of date_format() is constant then it's collation is changed to case sensitive. mysql-test/r/insert_select.result: Test case for bug#14016 2nd parameter was compared using case insensitive collation mysql-test/t/insert_select.test: Test case for bug#14016 2nd parameter was compared using case insensitive collation --- mysql-test/r/insert_select.result | 8 ++++++++ mysql-test/t/insert_select.test | 12 ++++++++++++ sql/item.cc | 7 +++++++ 3 files changed, 27 insertions(+) diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index d4eb4e8b788..028b40ac3b6 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -678,3 +678,11 @@ f1 2001 2002 drop table t1; +create table t1(x int, y int); +create table t2(x int, z int); +insert into t1(x,y) select x,z from t2 on duplicate key update x=values(x); +insert into t1(x,y) select x,z from t2 on duplicate key update x=values(z); +ERROR 42S22: Unknown column 'z' in 'field list' +insert into t1(x,y) select x,z from t2 on duplicate key update x=values(t2.x); +ERROR 42S02: Unknown table 't2' in field list +drop table t1,t2; diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index 6fcdef6ab03..48acdf1cbc5 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -214,4 +214,16 @@ insert into t1(f1) select if(max(f1) is null, '2000',max(f1)+1) from t1; select * from t1; drop table t1; +# +# Bug #13392 values() fails with 'ambiguous' or returns NULL +# with ON DUPLICATE and SELECT +create table t1(x int, y int); +create table t2(x int, z int); +insert into t1(x,y) select x,z from t2 on duplicate key update x=values(x); +--error 1054 +insert into t1(x,y) select x,z from t2 on duplicate key update x=values(z); +--error 1109 +insert into t1(x,y) select x,z from t2 on duplicate key update x=values(t2.x); +drop table t1,t2; + # End of 4.1 tests diff --git a/sql/item.cc b/sql/item.cc index b2a1e44cfcc..642a0ccf1b4 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2796,8 +2796,14 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items) { DBUG_ASSERT(fixed == 0); + st_table_list *orig_next_table= table_list->next; + table_list->next= 0; if (!arg->fixed && arg->fix_fields(thd, table_list, &arg)) + { + table_list->next= orig_next_table; return 1; + } + table_list->next= orig_next_table; if (arg->type() == REF_ITEM) { @@ -2809,6 +2815,7 @@ bool Item_insert_value::fix_fields(THD *thd, arg= ref->ref[0]; } Item_field *field_arg= (Item_field *)arg; + if (field_arg->field->table->insert_values) { Field *def_field= (Field*) sql_alloc(field_arg->field->size_of()); -- cgit v1.2.1 From b96dbef6fd553360f13a52d2b496fe7d86665e7c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 25 Oct 2005 20:37:26 +0400 Subject: Fix bug #14016 date_format() 2nd parameter was compared using case insensitive collation By default constant strings in second parameter of date_time() have case insensitive collation. Because of this expressions date_format(f,'%m') and date_format(f,'%M') wrongly becomes equal, which results in choosing wrong column to sort by. Now if second parameter of date_format() is constant then it's collation is changed to case sensitive. sql/item_timefunc.cc: Fix bug #14016 date_format() 2nd parameter was compared using case insensitive collation. If second parameter of date_format() is constant then it's collation is changed to case sensitive. mysql-test/r/date_formats.result: Test case for bug#14016 2nd parameter was compared using case insensitive collation mysql-test/t/date_formats.test: Test case for bug#14016 2nd parameter was compared using case insensitive collation --- mysql-test/r/date_formats.result | 8 ++++++++ mysql-test/t/date_formats.test | 8 ++++++++ sql/item_timefunc.cc | 10 ++++++++++ 3 files changed, 26 insertions(+) diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 2db014c4a52..34a2dedd976 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -456,3 +456,11 @@ f1 f2 Warnings: Warning 1292 Truncated incorrect date value: '2003-04-05 g' Warning 1292 Truncated incorrect datetime value: '2003-04-05 10:11:12.101010234567' +create table t1 (f1 datetime); +insert into t1 (f1) values ("2005-01-01"); +insert into t1 (f1) values ("2005-02-01"); +select date_format(f1, "%m") as d1, date_format(f1, "%M") as d2 from t1 order by date_format(f1, "%M"); +d1 d2 +02 February +01 January +drop table t1; diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index 62e9d81021e..6d501865d2c 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -260,4 +260,12 @@ select str_to_date("2003-04-05 g", "%Y-%m-%d") as f1, str_to_date("2003-04-05 10:11:12.101010234567", "%Y-%m-%d %H:%i:%S.%f") as f2; --enable_ps_protocol +# +# Bug #14016 +# +create table t1 (f1 datetime); +insert into t1 (f1) values ("2005-01-01"); +insert into t1 (f1) values ("2005-02-01"); +select date_format(f1, "%m") as d1, date_format(f1, "%M") as d2 from t1 order by date_format(f1, "%M"); +drop table t1; # End of 4.1 tests diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 2c53ba82007..7398b1746da 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1528,6 +1528,16 @@ void Item_func_date_format::fix_length_and_dec() if (args[1]->type() == STRING_ITEM) { // Optimize the normal case fixed_length=1; + + /* + Force case sensitive collation on format string. + This needed because format modifiers with different case, + for example %m and %M, have different meaning. Thus eq() + will distinguish them. + */ + args[1]->collation.set( + get_charset_by_csname(args[1]->collation.collation->csname, + MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE); /* The result is a binary string (no reason to use collation->mbmaxlen This is becasue make_date_time() only returns binary strings -- cgit v1.2.1 From b5dc243e3d7b8864cc8165856a9b47cca754e8d2 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 25 Oct 2005 10:10:53 -0700 Subject: Fix incorrect casts in my_getopt code that capped the maximum of longlong options to the wrong value. (Bug #12925) mysql-test/t/mysql_client_test.test: Add parameter for testing getopt bug mysys/my_getopt.c: Remove incorrect and unnecessary casts tests/mysql_client_test.c: Add test case for Bug #12925 (my_getopt bug) --- mysql-test/t/mysql_client_test.test | 4 ++-- mysys/my_getopt.c | 6 +++--- tests/mysql_client_test.c | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/mysql-test/t/mysql_client_test.test b/mysql-test/t/mysql_client_test.test index ccf5e0bf66a..66b57dd5fb7 100644 --- a/mysql-test/t/mysql_client_test.test +++ b/mysql-test/t/mysql_client_test.test @@ -6,7 +6,7 @@ # var/log/mysql_client_test.trace --disable_result_log ---exec echo $MYSQL_CLIENT_TEST ---exec $MYSQL_CLIENT_TEST +--exec echo $MYSQL_CLIENT_TEST --getopt-ll-test=25600M +--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M # End of 4.1 tests diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 53e46932167..dfc3fb3d39c 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -689,10 +689,10 @@ static longlong getopt_ll(char *arg, const struct my_option *optp, int *err) ulonglong block_size= (optp->block_size ? (ulonglong) optp->block_size : 1L); num= eval_num_suffix(arg, err, (char*) optp->name); - if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value && + if (num > 0 && (ulonglong) num > (ulonglong) optp->max_value && optp->max_value) /* if max value is not set -> no upper limit */ - num= (longlong) (ulong) optp->max_value; - num= ((num - (longlong) optp->sub_size) / block_size); + num= (ulonglong) optp->max_value; + num= ((num - optp->sub_size) / block_size); num= (longlong) (num * block_size); return max(num, optp->min_value); } diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index eadbd37f8f6..d0a0409e6ce 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -51,6 +51,8 @@ static unsigned int iter_count= 0; static const char *opt_basedir= "./"; +static longlong opt_getopt_ll_test= 0; + static int embedded_server_arg_count= 0; static char *embedded_server_args[MAX_SERVER_ARGS]; @@ -11830,6 +11832,19 @@ static void test_bug11718() rc= mysql_query(mysql, "drop table t1, t2"); myquery(rc); } + + +/* + Bug #12925: Bad handling of maximum values in getopt +*/ +static void test_bug12925() +{ + myheader("test_bug12925"); + if (opt_getopt_ll_test) + DIE_UNLESS(opt_getopt_ll_test == LL(25600*1024*1024)); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -11872,6 +11887,9 @@ static struct my_option client_test_long_options[] = {"user", 'u', "User for login if not current user", (char **) &opt_user, (char **) &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif + {"getopt-ll-test", 'g', "Option for testing bug in getopt library", + (char **) &opt_getopt_ll_test, (char **) &opt_getopt_ll_test, 0, + GET_LL, REQUIRED_ARG, 0, 0, LONGLONG_MAX, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -12048,6 +12066,7 @@ static struct my_tests_st my_tests[]= { { "test_bug11183", test_bug11183 }, { "test_bug12001", test_bug12001 }, { "test_bug11718", test_bug11718 }, + { "test_bug12925", test_bug12925 }, { 0, 0 } }; -- cgit v1.2.1 From dd1dc7def96ea77b0f9c14561ebe1d0edbc97c2e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Oct 2005 01:24:03 +0200 Subject: mysql-test-run.pl: Added MTR_BUILD_THREAD to control the port range mysql-test/mysql-test-run.pl: Added MTR_BUILD_THREAD to control the port range --- mysql-test/mysql-test-run.pl | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 4b055e0bb84..8764f3dc9a4 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -462,6 +462,13 @@ sub command_line_setup () { my $opt_slave_myport= 9308; $opt_ndbcluster_port= 9350; + if ( $ENV{'MTR_BUILD_THREAD'} ) + { + $opt_master_myport= $ENV{'MTR_BUILD_THREAD'} * 40 + 8120; + $opt_slave_myport= $opt_master_myport + 16; + $opt_ndbcluster_port= $opt_master_myport + 24; + } + # Read the command line # Note: Keep list, and the order, in sync with usage at end of this file @@ -833,7 +840,9 @@ sub executable_setup () { { $path_client_bindir= mtr_path_exists("$glob_basedir/client_release", "$glob_basedir/bin"); - $exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-nt"); + $exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-nt", + "$path_client_bindir/mysqld", + "$path_client_bindir/mysqld-debug",); $path_language= mtr_path_exists("$glob_basedir/share/english/"); $path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets"); } @@ -886,8 +895,18 @@ sub executable_setup () { "$glob_basedir/share/english/"); $path_charsetsdir= mtr_path_exists("$glob_basedir/share/mysql/charsets", "$glob_basedir/share/charsets"); - $exe_mysqld= mtr_exe_exists ("$glob_basedir/libexec/mysqld", - "$glob_basedir/bin/mysqld"); + + if ( $glob_win32 ) + { + $exe_mysqld= mtr_exe_exists ("$glob_basedir/bin/mysqld-nt", + "$glob_basedir/bin/mysqld", + "$glob_basedir/bin/mysqld-debug",); + } + else + { + $exe_mysqld= mtr_exe_exists ("$glob_basedir/libexec/mysqld", + "$glob_basedir/bin/mysqld"); + } if ( $glob_use_embedded_server ) { @@ -971,6 +990,13 @@ sub environment_setup () { chomp($ENV{$key}); } } + + # We are nice and report a bit about our settings + print "Using MTR_BUILD_THREAD = ",$ENV{MTR_BUILD_THREAD} || 0,"\n"; + print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n"; + print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n"; + print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n"; + print "Using NDBCLUSTER_PORT = $opt_ndbcluster_port\n"; } -- cgit v1.2.1 From fe90e5677c702b65b4f246d8a7a1af0d41284e91 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Oct 2005 16:12:41 +0300 Subject: Imported fix from 5.0. --- netware/mysql_test_run.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netware/mysql_test_run.c b/netware/mysql_test_run.c index 849828210f2..fd328777ec9 100644 --- a/netware/mysql_test_run.c +++ b/netware/mysql_test_run.c @@ -941,7 +941,7 @@ void run_test(char *test) // increment total ++total_test; } - else if (err == 2) + else if (err == 62) // To reflect the changes made in client/mysqltest.c { // skip rstr = TEST_SKIP; -- cgit v1.2.1 From d1d49ce14c8704082f38a4e8a4a1ec3def92416e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Oct 2005 20:06:08 +0400 Subject: Removed innobase/my_cnf, innobase/include/makefilewin.i, and innobase/*/makefilewin (which are unused now). BitKeeper/deleted/.del-makefilewin.i~5c8479dcb8a455b2: Delete: innobase/include/makefilewin.i BitKeeper/deleted/.del-makefilewin~78000390c783b1c5: Delete: innobase/btr/makefilewin BitKeeper/deleted/.del-makefilewin~2fc379bd4065c995: Delete: innobase/buf/makefilewin BitKeeper/deleted/.del-makefilewin~d37b6b303348c871: Delete: innobase/data/makefilewin BitKeeper/deleted/.del-makefilewin~5104767c73775697: Delete: innobase/dict/makefilewin BitKeeper/deleted/.del-makefilewin~d90f35fdc3f2ee5f: Delete: innobase/dyn/makefilewin BitKeeper/deleted/.del-makefilewin~c7b621c745e5de95: Delete: innobase/eval/makefilewin BitKeeper/deleted/.del-makefilewin~4d139e182457e553: Delete: innobase/fil/makefilewin BitKeeper/deleted/.del-makefilewin~d1a9d1f7d33fcb73: Delete: innobase/fsp/makefilewin BitKeeper/deleted/.del-makefilewin~ef3a208fa0e9b0db: Delete: innobase/fut/makefilewin BitKeeper/deleted/.del-makefilewin~f1e3b890aa1c9ea3: Delete: innobase/ha/makefilewin BitKeeper/deleted/.del-makefilewin~1c53f31b88dd36e: Delete: innobase/ibuf/makefilewin BitKeeper/deleted/.del-makefilewin~7a9d7d5a42bbfaf5: Delete: innobase/lock/makefilewin BitKeeper/deleted/.del-makefilewin~b643e38d8da389ac: Delete: innobase/log/makefilewin BitKeeper/deleted/.del-makefilewin~a40ea12eebdd6ef0: Delete: innobase/mach/makefilewin BitKeeper/deleted/.del-makefilewin~1dbc058d76ebf1db: Delete: innobase/mem/makefilewin BitKeeper/deleted/.del-makefilewin~6ba64863bce3d0b8: Delete: innobase/mtr/makefilewin BitKeeper/deleted/.del-makefilewin~15e9e5c9e8fa870b: Delete: innobase/os/makefilewin BitKeeper/deleted/.del-makefilewin~aeea7c82f21f7cf5: Delete: innobase/page/makefilewin BitKeeper/deleted/.del-makefilewin~dea10ec1c94f7be: Delete: innobase/pars/makefilewin BitKeeper/deleted/.del-makefilewin~608ed49dcd88e0f7: Delete: innobase/que/makefilewin BitKeeper/deleted/.del-makefilewin~2e0407fe123f8365: Delete: innobase/read/makefilewin BitKeeper/deleted/.del-makefilewin~fdda94ad32fa9e34: Delete: innobase/rem/makefilewin BitKeeper/deleted/.del-makefilewin~dc4b8ad5ea53bd: Delete: innobase/row/makefilewin BitKeeper/deleted/.del-makefilewin~63acd666293282a: Delete: innobase/srv/makefilewin BitKeeper/deleted/.del-makefilewin~13888739357b3025: Delete: innobase/sync/makefilewin BitKeeper/deleted/.del-makefilewin~c8273a47b90f52bb: Delete: innobase/thr/makefilewin BitKeeper/deleted/.del-makefilewin~f4b7b99a887b7de: Delete: innobase/trx/makefilewin BitKeeper/deleted/.del-makefilewin~72a64128bacce71b: Delete: innobase/usr/makefilewin BitKeeper/deleted/.del-makefilewin~389ee2dcf79afb79: Delete: innobase/ut/makefilewin BitKeeper/deleted/.del-makefilewin~14f24a4a173e2fcd: Delete: innobase/makefilewin BitKeeper/deleted/.del-my_cnf~977f69858affc57b: Delete: innobase/my_cnf innobase/include/Makefile.am: Removed ref to Makefilewin.i (it is unused now). --- innobase/btr/makefilewin | 16 ---- innobase/buf/makefilewin | 20 ----- innobase/data/makefilewin | 11 --- innobase/dict/makefilewin | 21 ------ innobase/dyn/makefilewin | 9 --- innobase/eval/makefilewin | 10 --- innobase/fil/makefilewin | 10 --- innobase/fsp/makefilewin | 9 --- innobase/fut/makefilewin | 12 --- innobase/ha/makefilewin | 10 --- innobase/ibuf/makefilewin | 7 -- innobase/include/Makefile.am | 2 +- innobase/include/makefilewin.i | 34 --------- innobase/lock/makefilewin | 7 -- innobase/log/makefilewin | 10 --- innobase/mach/makefilewin | 9 --- innobase/makefilewin | 164 ----------------------------------------- innobase/mem/makefilewin | 10 --- innobase/mtr/makefilewin | 14 ---- innobase/my_cnf | 63 ---------------- innobase/os/makefilewin | 17 ----- innobase/page/makefilewin | 12 --- innobase/pars/makefilewin | 26 ------- innobase/que/makefilewin | 7 -- innobase/read/makefilewin | 7 -- innobase/rem/makefilewin | 12 --- innobase/row/makefilewin | 34 --------- innobase/srv/makefilewin | 15 ---- innobase/sync/makefilewin | 14 ---- innobase/thr/makefilewin | 9 --- innobase/trx/makefilewin | 26 ------- innobase/usr/makefilewin | 7 -- innobase/ut/makefilewin | 21 ------ 33 files changed, 1 insertion(+), 654 deletions(-) delete mode 100644 innobase/btr/makefilewin delete mode 100644 innobase/buf/makefilewin delete mode 100644 innobase/data/makefilewin delete mode 100644 innobase/dict/makefilewin delete mode 100644 innobase/dyn/makefilewin delete mode 100644 innobase/eval/makefilewin delete mode 100644 innobase/fil/makefilewin delete mode 100644 innobase/fsp/makefilewin delete mode 100644 innobase/fut/makefilewin delete mode 100644 innobase/ha/makefilewin delete mode 100644 innobase/ibuf/makefilewin delete mode 100644 innobase/include/makefilewin.i delete mode 100644 innobase/lock/makefilewin delete mode 100644 innobase/log/makefilewin delete mode 100644 innobase/mach/makefilewin delete mode 100644 innobase/makefilewin delete mode 100644 innobase/mem/makefilewin delete mode 100644 innobase/mtr/makefilewin delete mode 100644 innobase/my_cnf delete mode 100644 innobase/os/makefilewin delete mode 100644 innobase/page/makefilewin delete mode 100644 innobase/pars/makefilewin delete mode 100644 innobase/que/makefilewin delete mode 100644 innobase/read/makefilewin delete mode 100644 innobase/rem/makefilewin delete mode 100644 innobase/row/makefilewin delete mode 100644 innobase/srv/makefilewin delete mode 100644 innobase/sync/makefilewin delete mode 100644 innobase/thr/makefilewin delete mode 100644 innobase/trx/makefilewin delete mode 100644 innobase/usr/makefilewin delete mode 100644 innobase/ut/makefilewin diff --git a/innobase/btr/makefilewin b/innobase/btr/makefilewin deleted file mode 100644 index a5806b74a51..00000000000 --- a/innobase/btr/makefilewin +++ /dev/null @@ -1,16 +0,0 @@ -include ..\include\makefile.i - -btr.lib: btr0cur.obj btr0btr.obj btr0pcur.obj btr0sea.obj - lib -out:..\libs\btr.lib btr0cur.obj btr0btr.obj btr0pcur.obj btr0sea.obj - -btr0cur.obj: btr0cur.c - $(CCOM) $(CFL) -c btr0cur.c - -btr0btr.obj: btr0btr.c - $(CCOM) $(CFL) -c btr0btr.c - -btr0sea.obj: btr0sea.c - $(CCOM) $(CFL) -c btr0sea.c - -btr0pcur.obj: btr0pcur.c - $(CCOM) $(CFL) -c btr0pcur.c diff --git a/innobase/buf/makefilewin b/innobase/buf/makefilewin deleted file mode 100644 index ce62cb95958..00000000000 --- a/innobase/buf/makefilewin +++ /dev/null @@ -1,20 +0,0 @@ -include ..\include\makefile.i - -buf.lib: buf0buf.obj buf0lru.obj buf0flu.obj buf0rea.obj - lib -out:..\libs\buf.lib buf0buf.obj buf0lru.obj buf0flu.obj buf0rea.obj - -buf0buf.obj: buf0buf.c - $(CCOM) $(CFL) -c buf0buf.c - -buf0lru.obj: buf0lru.c - $(CCOM) $(CFL) -c buf0lru.c - -buf0flu.obj: buf0flu.c - $(CCOM) $(CFL) -c buf0flu.c - -buf0rea.obj: buf0rea.c - $(CCOM) $(CFL) -c buf0rea.c - - - - diff --git a/innobase/data/makefilewin b/innobase/data/makefilewin deleted file mode 100644 index 785b75fbb2b..00000000000 --- a/innobase/data/makefilewin +++ /dev/null @@ -1,11 +0,0 @@ -include ..\include\makefile.i - -data.lib: data0type.obj data0data.obj - lib -out:..\libs\data.lib data0type.obj data0data.obj - -data0type.obj: data0type.c - $(CCOM) $(CFL) -c data0type.c - -data0data.obj: data0data.c - $(CCOM) $(CFL) -c data0data.c - diff --git a/innobase/dict/makefilewin b/innobase/dict/makefilewin deleted file mode 100644 index e828d06943c..00000000000 --- a/innobase/dict/makefilewin +++ /dev/null @@ -1,21 +0,0 @@ -include ..\include\makefile.i - -dict.lib: dict0dict.obj dict0boot.obj dict0load.obj dict0mem.obj dict0crea.obj - lib -out:..\libs\dict.lib dict0dict.obj dict0boot.obj dict0load.obj dict0mem.obj dict0crea.obj - -dict0dict.obj: dict0dict.c - $(CCOM) $(CFL) -c dict0dict.c - -dict0boot.obj: dict0boot.c - $(CCOM) $(CFL) -c dict0boot.c - -dict0mem.obj: dict0mem.c - $(CCOM) $(CFL) -c dict0mem.c - -dict0crea.obj: dict0crea.c - $(CCOM) $(CFL) -c dict0crea.c - -dict0load.obj: dict0load.c - $(CCOM) $(CFL) -c dict0load.c - - diff --git a/innobase/dyn/makefilewin b/innobase/dyn/makefilewin deleted file mode 100644 index 71a58a756c1..00000000000 --- a/innobase/dyn/makefilewin +++ /dev/null @@ -1,9 +0,0 @@ -include ..\include\makefile.i - -dyn.lib: dyn0dyn.obj makefile - lib -out:..\libs\dyn.lib dyn0dyn.obj - -dyn0dyn.obj: dyn0dyn.c - $(CCOM) $(CFL) -c dyn0dyn.c - - diff --git a/innobase/eval/makefilewin b/innobase/eval/makefilewin deleted file mode 100644 index f587f2a05a6..00000000000 --- a/innobase/eval/makefilewin +++ /dev/null @@ -1,10 +0,0 @@ -include ..\include\makefile.i - -eval.lib: eval0eval.obj eval0proc.obj - lib -out:..\libs\eval.lib eval0eval.obj eval0proc.obj - -eval0eval.obj: eval0eval.c - $(CCOM) $(CFL) -c eval0eval.c - -eval0proc.obj: eval0proc.c - $(CCOM) $(CFL) -c eval0proc.c diff --git a/innobase/fil/makefilewin b/innobase/fil/makefilewin deleted file mode 100644 index 1b2d6ab2dbb..00000000000 --- a/innobase/fil/makefilewin +++ /dev/null @@ -1,10 +0,0 @@ -include ..\include\makefile.i - -fil.lib: fil0fil.obj - lib -out:..\libs\fil.lib fil0fil.obj - -fil0fil.obj: fil0fil.c - $(CCOM) $(CFL) -c fil0fil.c - - - diff --git a/innobase/fsp/makefilewin b/innobase/fsp/makefilewin deleted file mode 100644 index 503cf27f490..00000000000 --- a/innobase/fsp/makefilewin +++ /dev/null @@ -1,9 +0,0 @@ -include ..\include\makefile.i - -fsp.lib: fsp0fsp.obj - lib -out:..\libs\fsp.lib fsp0fsp.obj - -fsp0fsp.obj: fsp0fsp.c - $(CCOM) $(CFL) -c fsp0fsp.c - - diff --git a/innobase/fut/makefilewin b/innobase/fut/makefilewin deleted file mode 100644 index 40f3161015c..00000000000 --- a/innobase/fut/makefilewin +++ /dev/null @@ -1,12 +0,0 @@ -include ..\include\makefile.i - -fut.lib: fut0lst.obj fut0fut.obj - lib -out:..\libs\fut.lib fut0lst.obj fut0fut.obj - -fut0lst.obj: fut0lst.c - $(CCOM) $(CFL) -c fut0lst.c - -fut0fut.obj: fut0fut.c - $(CCOM) $(CFL) -c fut0fut.c - - diff --git a/innobase/ha/makefilewin b/innobase/ha/makefilewin deleted file mode 100644 index c7cd130ceea..00000000000 --- a/innobase/ha/makefilewin +++ /dev/null @@ -1,10 +0,0 @@ -include ..\include\makefile.i - -ha.lib: ha0ha.obj hash0hash.obj - lib -out:..\libs\ha.lib ha0ha.obj hash0hash.obj - -ha0ha.obj: ha0ha.c - $(CCOM) $(CFL) -c ha0ha.c - -hash0hash.obj: hash0hash.c - $(CCOM) $(CFL) -c hash0hash.c diff --git a/innobase/ibuf/makefilewin b/innobase/ibuf/makefilewin deleted file mode 100644 index 86bf9794520..00000000000 --- a/innobase/ibuf/makefilewin +++ /dev/null @@ -1,7 +0,0 @@ -include ..\include\makefile.i - -ibuf.lib: ibuf0ibuf.obj - lib -out:..\libs\ibuf.lib ibuf0ibuf.obj - -ibuf0ibuf.obj: ibuf0ibuf.c - $(CCOM) $(CFL) -c ibuf0ibuf.c diff --git a/innobase/include/Makefile.am b/innobase/include/Makefile.am index 102d25566da..3483556abe1 100644 --- a/innobase/include/Makefile.am +++ b/innobase/include/Makefile.am @@ -28,7 +28,7 @@ noinst_HEADERS = btr0btr.h btr0btr.ic btr0cur.h btr0cur.ic \ ha0ha.h ha0ha.ic hash0hash.h hash0hash.ic \ ibuf0ibuf.h ibuf0ibuf.ic ibuf0types.h lock0lock.h \ lock0lock.ic lock0types.h log0log.h log0log.ic log0recv.h \ - log0recv.ic mach0data.h mach0data.ic makefilewin.i \ + log0recv.ic mach0data.h mach0data.ic \ mem0dbg.h mem0dbg.ic mem0mem.h mem0mem.ic mem0pool.h \ mem0pool.ic mtr0log.h mtr0log.ic mtr0mtr.h mtr0mtr.ic \ mtr0types.h os0file.h os0proc.h os0proc.ic \ diff --git a/innobase/include/makefilewin.i b/innobase/include/makefilewin.i deleted file mode 100644 index f756cf2ea3a..00000000000 --- a/innobase/include/makefilewin.i +++ /dev/null @@ -1,34 +0,0 @@ -# File included in all makefiles of the database -# (c) Innobase Oy 1995 - 2000 - -CCOM=cl - -# Flags for the debug version -#CFL= -MTd -Za -Zi -W4 -WX -F8192 -D "WIN32" -#CFLN = -MTd -Zi -W4 -F8192 -D "WIN32" -#CFLW = -MTd -Zi -W3 -WX -F8192 -D "WIN32" -#LFL = - -# Flags for the fast version -#CFL= -MT -Zi -Og -O2 -W3 -WX -D "WIN32" -#CFLN = -MT -Zi -Og -O2 -W3 -D "WIN32" -#CFLW = -MT -Zi -Og -O2 -W3 -WX -D "WIN32" -#LFL = - -# Flags for the fast debug version -CFL= -MTd -Zi -W3 -WX -F8192 -D "WIN32" -CFLN = -MTd -Zi -W3 -F8192 -D "WIN32" -CFLW = -MTd -Zi -W3 -WX -F8192 -D "WIN32" -LFL = /link/NODEFAULTLIB:LIBCMT - -# Flags for the profiler version -#CFL= -MT -Zi -Og -O2 -W3 -WX -D "WIN32" -#CFLN = -MT -Zi -Og -O2 -WX -D "WIN32" -#CFLW = -MT -Zi -Og -O2 -W3 -WX -D "WIN32" -#LFL= -link -PROFILE - -# Flags for the fast version without debug info (= the production version) -#CFL= -MT -Og -O2 -G6 -W3 -WX -D "WIN32" -#CFLN = -MT -Og -O2 -G6 -W3 -D "WIN32" -#CFLW = -MT -Og -O2 -G6 -W3 -WX -D "WIN32" -#LFL = diff --git a/innobase/lock/makefilewin b/innobase/lock/makefilewin deleted file mode 100644 index 149b0a2fed6..00000000000 --- a/innobase/lock/makefilewin +++ /dev/null @@ -1,7 +0,0 @@ -include ..\include\makefile.i - -lock.lib: lock0lock.obj - lib -out:..\libs\lock.lib lock0lock.obj - -lock0lock.obj: lock0lock.c - $(CCOM) $(CFL) -c lock0lock.c diff --git a/innobase/log/makefilewin b/innobase/log/makefilewin deleted file mode 100644 index a690af3bb35..00000000000 --- a/innobase/log/makefilewin +++ /dev/null @@ -1,10 +0,0 @@ -include ..\include\makefile.i - -log.lib: log0log.obj log0recv.obj - lib -out:..\libs\log.lib log0log.obj log0recv.obj - -log0log.obj: log0log.c - $(CCOM) $(CFL) -c log0log.c - -log0recv.obj: log0recv.c - $(CCOM) $(CFL) -c log0recv.c diff --git a/innobase/mach/makefilewin b/innobase/mach/makefilewin deleted file mode 100644 index 5306b0fe14c..00000000000 --- a/innobase/mach/makefilewin +++ /dev/null @@ -1,9 +0,0 @@ -include ..\include\makefile.i - -mach.lib: mach0data.obj - lib -out:..\libs\mach.lib mach0data.obj - -mach0data.obj: mach0data.c - $(CCOM) $(CFLN) -c mach0data.c - - diff --git a/innobase/makefilewin b/innobase/makefilewin deleted file mode 100644 index 1bd8d96e5e7..00000000000 --- a/innobase/makefilewin +++ /dev/null @@ -1,164 +0,0 @@ -doall: del_libs pb_all os.lib ut.lib mach.lib sync.lib mem.lib dyn.lib ha.lib com.lib thr.lib srv.lib fil.lib buf.lib log.lib mtr.lib log.lib fut.lib fsp.lib dict.lib data.lib rem.lib page.lib btr.lib ibuf.lib usr.lib que.lib trx.lib lock.lib read.lib row.lib pars.lib eval.lib ib_odbc.lib - -del_libs: - cd libs - del *.lib - cd .. - -pb_all: - pb_all - -os.lib: - cd os - remake - cd .. - -ut.lib: - cd ut - remake - cd .. - -mach.lib: - cd mach - remake - cd .. - -sync.lib: - cd sync - remake - cd .. - -mem.lib: - cd mem - remake - cd .. - -dyn.lib: - cd dyn - remake - cd .. - -ha.lib: - cd ha - remake - cd .. - -com.lib: - cd com - remake - cd .. - -thr.lib: - cd thr - remake - cd .. - -srv.lib: - cd srv - remake - cd .. - -fil.lib: - cd fil - remake - cd .. - -buf.lib: - cd buf - remake - cd .. - -log.lib: - cd log - remake - cd .. - -mtr.lib: - cd mtr - remake - cd .. - -fut.lib: - cd fut - remake - cd .. - -fsp.lib: - cd fsp - remake - cd .. - -dict.lib: - cd dict - remake - cd .. - -data.lib: - cd data - remake - cd .. - -rem.lib: - cd rem - remake - cd .. - -page.lib: - cd page - remake - cd .. - -btr.lib: - cd btr - remake - cd .. - -ibuf.lib: - cd ibuf - remake - cd .. - -usr.lib: - cd usr - remake - cd .. - -que.lib: - cd que - remake - cd .. - -trx.lib: - cd trx - remake - cd .. - -lock.lib: - cd lock - remake - cd .. - -read.lib: - cd read - remake - cd .. - -row.lib: - cd row - remake - cd .. - -pars.lib: - cd pars - remake - cd .. - -eval.lib: - cd eval - remake - cd .. - -ib_odbc.lib: - cd odbc - remake - cd .. diff --git a/innobase/mem/makefilewin b/innobase/mem/makefilewin deleted file mode 100644 index 8a30f8a6e71..00000000000 --- a/innobase/mem/makefilewin +++ /dev/null @@ -1,10 +0,0 @@ -include ..\include\makefile.i - -mem.lib: mem0mem.obj mem0pool.obj makefile - lib -out:..\libs\mem.lib mem0mem.obj mem0pool.obj - -mem0mem.obj: mem0mem.c mem0dbg.c - $(CCOM) $(CFL) -c mem0mem.c - -mem0pool.obj: mem0pool.c - $(CCOM) $(CFL) -c mem0pool.c diff --git a/innobase/mtr/makefilewin b/innobase/mtr/makefilewin deleted file mode 100644 index 9da0863bd28..00000000000 --- a/innobase/mtr/makefilewin +++ /dev/null @@ -1,14 +0,0 @@ -include ..\include\makefile.i - -mtr.lib: mtr0mtr.obj mtr0log.obj - lib -out:..\libs\mtr.lib mtr0mtr.obj mtr0log.obj - -mtr0mtr.obj: mtr0mtr.c - $(CCOM) $(CFL) -c mtr0mtr.c - -mtr0log.obj: mtr0log.c - $(CCOM) $(CFL) -c mtr0log.c - - - - diff --git a/innobase/my_cnf b/innobase/my_cnf deleted file mode 100644 index 94365237841..00000000000 --- a/innobase/my_cnf +++ /dev/null @@ -1,63 +0,0 @@ -# Example mysql config file. -# Copy this file to c:\my.cnf to set global options -# -# One can use all long options that the program supports. -# Run the program with --help to get a list of available options - -# This will be passed to all mysql clients -[client] -#password=my_password -port=3306 -#socket=MySQL - -# Here is entries for some specific programs -# The following values assume you have at least 32M ram - -# The MySQL server -[mysqld] -port=3306 -#socket=MySQL -skip-locking -default-character-set=latin1 -set-variable = key_buffer=2M -set-variable = max_allowed_packet=1M -set-variable = thread_stack=128K -set-variable = flush_time=1800 - -innobase_data_home_dir = e:\ibdata\ -innobase_data_file_path = ibdata1:25M;ibdata2:37M;ibdata3:100M;ibdata4:300M -set-variable = innobase_mirrored_log_groups=1 -innobase_log_group_home_dir = e:\iblogs\ -set-variable = innobase_log_files_in_group=3 -set-variable = innobase_log_file_size=5M -set-variable = innobase_log_buffer_size=8M -innobase_flush_log_at_trx_commit=1 -innobase_log_arch_dir = e:\iblogs\ -innobase_log_archive=0 -set-variable = innobase_buffer_pool_size=16M -set-variable = innobase_additional_mem_pool_size=2M -set-variable = innobase_file_io_threads=4 -set-variable = innobase_lock_wait_timeout=50 - - -# Uncomment the following row if you move the MySQL distribution to another -# location -#basedir = d:/mysql/ - -[mysqldump] -quick -set-variable = max_allowed_packet=16M - -[mysql] -no-auto-rehash - -[isamchk] -set-variable= key=16M - -[client_fltk] -help_file= c:\mysql\sql_client\MySQL.help -client_file= c:\mysql\MySQL.options -history_length=20 -database = test -queries_root= c:\mysql\queries -last_database_file= c:\mysql\lastdb diff --git a/innobase/os/makefilewin b/innobase/os/makefilewin deleted file mode 100644 index 8bc8d08611b..00000000000 --- a/innobase/os/makefilewin +++ /dev/null @@ -1,17 +0,0 @@ -include ..\include\makefile.i - -os.lib: os0sync.obj os0thread.obj os0proc.obj os0file.obj - lib -out:..\libs\os.lib os0sync.obj os0thread.obj os0proc.obj os0file.obj - -os0sync.obj: os0sync.c - $(CCOM) $(CFLW) -c os0sync.c - -os0thread.obj: os0thread.c - $(CCOM) $(CFLW) -c os0thread.c - -os0proc.obj: os0proc.c - $(CCOM) $(CFLW) -c os0proc.c - -os0file.obj: os0file.c - $(CCOM) $(CFLW) -c os0file.c - diff --git a/innobase/page/makefilewin b/innobase/page/makefilewin deleted file mode 100644 index 4a132cf828c..00000000000 --- a/innobase/page/makefilewin +++ /dev/null @@ -1,12 +0,0 @@ -include ..\include\makefile.i - -page.lib: page0page.obj page0cur.obj - lib -out:..\libs\page.lib page0page.obj page0cur.obj - -page0page.obj: page0page.c - $(CCOM) $(CFL) -c page0page.c - -page0cur.obj: page0cur.c - $(CCOM) $(CFL) -c page0cur.c - - diff --git a/innobase/pars/makefilewin b/innobase/pars/makefilewin deleted file mode 100644 index f183d89cbe2..00000000000 --- a/innobase/pars/makefilewin +++ /dev/null @@ -1,26 +0,0 @@ -include ..\include\makefile.i - -pars.lib: pars0grm.obj lexyy.obj pars0pars.obj pars0opt.obj pars0sym.obj rename_and_copy - lib -out:..\libs\pars.lib pars0grm.obj lexyy.obj pars0pars.obj pars0opt.obj pars0sym.obj - -pars0grm.obj: pars0grm.y - bs pars0grm.y - $(CCOM) $(CFLW) -c pars0grm.c - -rename_and_copy: - ren pars0grm.h pars0grm.h - copy pars0grm.h ..\include - -lexyy.obj: pars0lex.l - fl pars0lex.l - $(CCOM) $(CFLN) -c lexyy.c - -pars0pars.obj: pars0pars.c - $(CCOM) $(CFL) -c pars0pars.c - -pars0opt.obj: pars0opt.c - $(CCOM) $(CFL) -c pars0opt.c - -pars0sym.obj: pars0sym.c - $(CCOM) $(CFL) -c pars0sym.c - diff --git a/innobase/que/makefilewin b/innobase/que/makefilewin deleted file mode 100644 index 9661c716551..00000000000 --- a/innobase/que/makefilewin +++ /dev/null @@ -1,7 +0,0 @@ -include ..\include\makefile.i - -que.lib: que0que.obj - lib -out:..\libs\que.lib que0que.obj - -que0que.obj: que0que.c - $(CCOM) $(CFL) -c que0que.c diff --git a/innobase/read/makefilewin b/innobase/read/makefilewin deleted file mode 100644 index 39593993a67..00000000000 --- a/innobase/read/makefilewin +++ /dev/null @@ -1,7 +0,0 @@ -include ..\include\makefile.i - -read.lib: read0read.obj - lib -out:..\libs\read.lib read0read.obj - -read0read.obj: read0read.c - $(CCOM) $(CFL) -c read0read.c diff --git a/innobase/rem/makefilewin b/innobase/rem/makefilewin deleted file mode 100644 index 51ca4a92012..00000000000 --- a/innobase/rem/makefilewin +++ /dev/null @@ -1,12 +0,0 @@ -include ..\include\makefile.i - -rem.lib: rem0rec.obj rem0cmp.obj - lib -out:..\libs\rem.lib rem0rec.obj rem0cmp.obj - -rem0rec.obj: rem0rec.c - $(CCOM) $(CFL) -c rem0rec.c - -rem0cmp.obj: rem0cmp.c - $(CCOM) $(CFL) -c rem0cmp.c - - diff --git a/innobase/row/makefilewin b/innobase/row/makefilewin deleted file mode 100644 index c17240c6119..00000000000 --- a/innobase/row/makefilewin +++ /dev/null @@ -1,34 +0,0 @@ -include ..\include\makefile.i - -row.lib: row0mysql.obj row0upd.obj row0sel.obj row0umod.obj row0uins.obj row0ins.obj row0upd.obj row0undo.obj row0purge.obj row0vers.obj row0row.obj - lib -out:..\libs\row.lib row0mysql.obj row0sel.obj row0umod.obj row0uins.obj row0ins.obj row0upd.obj row0undo.obj row0purge.obj row0vers.obj row0row.obj - -row0mysql.obj: row0mysql.c - $(CCOM) $(CFL) -c row0mysql.c - -row0ins.obj: row0ins.c - $(CCOM) $(CFL) -c row0ins.c - -row0sel.obj: row0sel.c - $(CCOM) $(CFL) -c row0sel.c - -row0upd.obj: row0upd.c - $(CCOM) $(CFL) -c row0upd.c - -row0undo.obj: row0undo.c - $(CCOM) $(CFL) -c row0undo.c - -row0purge.obj: row0purge.c - $(CCOM) $(CFL) -c row0purge.c - -row0row.obj: row0row.c - $(CCOM) $(CFL) -c row0row.c - -row0vers.obj: row0vers.c - $(CCOM) $(CFL) -c row0vers.c - -row0umod.obj: row0umod.c - $(CCOM) $(CFL) -c row0umod.c - -row0uins.obj: row0uins.c - $(CCOM) $(CFL) -c row0uins.c diff --git a/innobase/srv/makefilewin b/innobase/srv/makefilewin deleted file mode 100644 index 129c65ec220..00000000000 --- a/innobase/srv/makefilewin +++ /dev/null @@ -1,15 +0,0 @@ -include ..\include\makefile.i - -srv.lib: srv0srv.obj srv0que.obj srv0start.obj - lib -out:..\libs\srv.lib srv0srv.obj srv0que.obj srv0start.obj - -srv0srv.obj: srv0srv.c - $(CCOM) $(CFL) -c srv0srv.c - -srv0que.obj: srv0que.c - $(CCOM) $(CFL) -c srv0que.c - -srv0start.obj: srv0start.c - $(CCOM) $(CFL) -c srv0start.c - - diff --git a/innobase/sync/makefilewin b/innobase/sync/makefilewin deleted file mode 100644 index 73cff40405a..00000000000 --- a/innobase/sync/makefilewin +++ /dev/null @@ -1,14 +0,0 @@ -include ..\include\makefile.i - -sync.lib: sync0sync.obj sync0rw.obj sync0arr.obj - lib -out:..\libs\sync.lib sync0sync.obj sync0rw.obj sync0arr.obj - -sync0sync.obj: sync0sync.c - $(CCOM) $(CFLN) -c sync0sync.c - -sync0rw.obj: sync0rw.c - $(CCOM) $(CFL) -c sync0rw.c - -sync0arr.obj: sync0arr.c - $(CCOM) $(CFL) -c sync0arr.c - diff --git a/innobase/thr/makefilewin b/innobase/thr/makefilewin deleted file mode 100644 index 3f29ea1d3e3..00000000000 --- a/innobase/thr/makefilewin +++ /dev/null @@ -1,9 +0,0 @@ -include ..\include\makefile.i - -thr.lib: thr0loc.obj - lib -out:..\libs\thr.lib thr0loc.obj - -thr0loc.obj: thr0loc.c - $(CCOM) $(CFL) -c thr0loc.c - - diff --git a/innobase/trx/makefilewin b/innobase/trx/makefilewin deleted file mode 100644 index 35588779d66..00000000000 --- a/innobase/trx/makefilewin +++ /dev/null @@ -1,26 +0,0 @@ -include ..\include\makefile.i - -trx.lib: trx0sys.obj trx0trx.obj trx0rseg.obj trx0undo.obj trx0rec.obj trx0roll.obj trx0purge.obj - lib -out:..\libs\trx.lib trx0sys.obj trx0trx.obj trx0rseg.obj trx0undo.obj trx0rec.obj trx0roll.obj trx0purge.obj - -trx0trx.obj: trx0trx.c - $(CCOM) $(CFL) -c -I.. trx0trx.c - -trx0sys.obj: trx0sys.c - $(CCOM) $(CFL) -c -I.. trx0sys.c - -trx0rseg.obj: trx0rseg.c - $(CCOM) $(CFL) -c -I.. trx0rseg.c - -trx0undo.obj: trx0undo.c - $(CCOM) $(CFL) -c -I.. trx0undo.c - -trx0rec.obj: trx0rec.c - $(CCOM) $(CFL) -c -I.. trx0rec.c - -trx0roll.obj: trx0roll.c - $(CCOM) $(CFL) -c -I.. trx0roll.c - -trx0purge.obj: trx0purge.c - $(CCOM) $(CFL) -c -I.. trx0purge.c - diff --git a/innobase/usr/makefilewin b/innobase/usr/makefilewin deleted file mode 100644 index 66a77275e9b..00000000000 --- a/innobase/usr/makefilewin +++ /dev/null @@ -1,7 +0,0 @@ -include ..\include\makefile.i - -usr.lib: usr0sess.obj - lib -out:..\libs\usr.lib usr0sess.obj - -usr0sess.obj: usr0sess.c - $(CCOM) $(CFL) -c usr0sess.c diff --git a/innobase/ut/makefilewin b/innobase/ut/makefilewin deleted file mode 100644 index 2fda190773b..00000000000 --- a/innobase/ut/makefilewin +++ /dev/null @@ -1,21 +0,0 @@ -include ..\include\makefile.i - -ut.lib: ut0ut.obj ut0mem.obj ut0byte.obj ut0dbg.obj ut0rnd.obj - lib -out:..\libs\ut.lib ut0ut.obj ut0mem.obj ut0byte.obj ut0dbg.obj ut0rnd.obj - -ut0ut.obj: ut0ut.c - $(CCOM) $(CFL) -c ut0ut.c - -ut0mem.obj: ut0mem.c - $(CCOM) $(CFL) -c ut0mem.c - -ut0byte.obj: ut0byte.c - $(CCOM) $(CFL) -c ut0byte.c - -ut0dbg.obj: ut0dbg.c - $(CCOM) $(CFL) -c ut0dbg.c - -ut0rnd.obj: ut0rnd.c - $(CCOM) $(CFL) -c ut0rnd.c - - -- cgit v1.2.1 From fed8b2082a958e840add62b774588639fc306420 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Oct 2005 16:48:49 +0500 Subject: conf_to_src.c: Updating to conform the current CHARSET_INFO structure. strings/conf_to_src.c: Updating to conform the current structure. --- strings/conf_to_src.c | 66 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/strings/conf_to_src.c b/strings/conf_to_src.c index d5ffa15ee0c..f07855af9e2 100644 --- a/strings/conf_to_src.c +++ b/strings/conf_to_src.c @@ -179,40 +179,49 @@ void dispcset(FILE *f,CHARSET_INFO *cs) if (cs->name) { - fprintf(f," \"%s\",\n",cs->csname); - fprintf(f," \"%s\",\n",cs->name); - fprintf(f," \"\",\n"); - fprintf(f," ctype_%s,\n",cs->name); - fprintf(f," to_lower_%s,\n",cs->name); - fprintf(f," to_upper_%s,\n",cs->name); + fprintf(f," \"%s\", /* cset name */\n",cs->csname); + fprintf(f," \"%s\", /* coll name */\n",cs->name); + fprintf(f," \"\", /* comment */\n"); + fprintf(f," NULL, /* tailoring */\n"); + fprintf(f," ctype_%s, /* ctype */\n",cs->name); + fprintf(f," to_lower_%s, /* lower */\n",cs->name); + fprintf(f," to_upper_%s, /* upper */\n",cs->name); if (cs->sort_order) - fprintf(f," sort_order_%s,\n",cs->name); + fprintf(f," sort_order_%s, /* sort_order */\n",cs->name); else - fprintf(f," NULL,\n"); - fprintf(f," to_uni_%s,\n",cs->name); - fprintf(f," from_uni_%s,\n",cs->name); + fprintf(f," NULL, /* sort_order */\n"); + fprintf(f," NULL, /* contractions */\n"); + fprintf(f," NULL, /* sort_order_big*/\n"); + fprintf(f," to_uni_%s, /* to_uni */\n",cs->name); } else { - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); - fprintf(f," NULL,\n"); + fprintf(f," NULL, /* cset name */\n"); + fprintf(f," NULL, /* coll name */\n"); + fprintf(f," NULL, /* comment */\n"); + fprintf(f," NULL, /* tailoging */\n"); + fprintf(f," NULL, /* ctype */\n"); + fprintf(f," NULL, /* lower */\n"); + fprintf(f," NULL, /* upper */\n"); + fprintf(f," NULL, /* sort order */\n"); + fprintf(f," NULL, /* contractions */\n"); + fprintf(f," NULL, /* sort_order_big*/\n"); + fprintf(f," NULL, /* to_uni */\n"); } - - fprintf(f," \"\",\n"); - fprintf(f," \"\",\n"); - fprintf(f," 0,\n"); - fprintf(f," 0,\n"); - fprintf(f," 0,\n"); + + fprintf(f," NULL, /* from_uni */\n"); + fprintf(f," NULL, /* state map */\n"); + fprintf(f," NULL, /* ident map */\n"); + fprintf(f," 1, /* strxfrm_multiply*/\n"); + fprintf(f," 1, /* mbminlen */\n"); + fprintf(f," 1, /* mbmaxlen */\n"); + fprintf(f," 0, /* min_sort_char */\n"); + fprintf(f," 255, /* max_sort_char */\n"); + fprintf(f," 0, /* escape_with_backslash_is_dangerous */\n"); + fprintf(f," &my_charset_8bit_handler,\n"); if (cs->state & MY_CS_BINSORT) - fprintf(f," &my_collation_bin_handler,\n"); + fprintf(f," &my_collation_8bit_bin_handler,\n"); else fprintf(f," &my_collation_8bit_simple_ci_handler,\n"); fprintf(f,"}\n"); @@ -251,6 +260,11 @@ main(int argc, char **argv __attribute__((unused))) } } + + fprintf(f,"#include \n"); + fprintf(f,"#include \n\n"); + + for (cs=all_charsets; cs < all_charsets+256; cs++) { if (simple_cs_is_full(cs)) -- cgit v1.2.1 From 4cccc642e9169cafd865f4a7acf7bbd8f1a77eca Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Oct 2005 17:40:21 +0500 Subject: conf_to_src.c: Dump MY_CS_CSSORT when it's necessary. strings/conf_to_src.c: Dump MY_CS_CSSORT when it's necessary. --- strings/conf_to_src.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/strings/conf_to_src.c b/strings/conf_to_src.c index f07855af9e2..93088bc7512 100644 --- a/strings/conf_to_src.c +++ b/strings/conf_to_src.c @@ -169,13 +169,22 @@ static int my_read_charset_file(const char *filename) return FALSE; } +static int +is_case_sensitive(CHARSET_INFO *cs) +{ + return (cs->sort_order && + cs->sort_order['A'] < cs->sort_order['a'] && + cs->sort_order['a'] < cs->sort_order['B']) ? 1 : 0; +} + void dispcset(FILE *f,CHARSET_INFO *cs) { fprintf(f,"{\n"); fprintf(f," %d,%d,%d,\n",cs->number,0,0); - fprintf(f," MY_CS_COMPILED%s%s,\n", + fprintf(f," MY_CS_COMPILED%s%s%s,\n", cs->state & MY_CS_BINSORT ? "|MY_CS_BINSORT" : "", - cs->state & MY_CS_PRIMARY ? "|MY_CS_PRIMARY" : ""); + cs->state & MY_CS_PRIMARY ? "|MY_CS_PRIMARY" : "", + is_case_sensitive(cs) ? "|MY_CS_CSSORT" : ""); if (cs->name) { -- cgit v1.2.1 From fb94ffdaf58e783850cb1761b71caa9750b35a54 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Oct 2005 18:36:11 +0400 Subject: select.result: After merge fix mysql-test/r/select.result: After merge fix --- mysql-test/r/select.result | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 27a0c8276e0..64c329ee104 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2400,14 +2400,6 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 1 SIMPLE t2 ref a a 23 test.t1.a 2 DROP TABLE t1, t2; -create table t1 (f1 int primary key, f2 int); -create table t2 (f3 int, f4 int, primary key(f3,f4)); -insert into t1 values (1,1); -insert into t2 values (1,1),(1,2); -select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; -count(f2) >0 -1 -drop table t1,t2; CREATE TABLE t1 ( city char(30) ); INSERT INTO t1 VALUES ('London'); INSERT INTO t1 VALUES ('Paris'); @@ -2706,3 +2698,11 @@ a b c d 1 2 2 1 1 2 3 1 DROP TABLE IF EXISTS t1, t2; +create table t1 (f1 int primary key, f2 int); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t1 values (1,1); +insert into t2 values (1,1),(1,2); +select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; +count(f2) >0 +1 +drop table t1,t2; -- cgit v1.2.1