From 6ed7e24d52acb0e861245b70fdcd6169c4237eee Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 Dec 2004 18:35:11 +0200 Subject: InnoDB: Fixed bugs in the padding and trimming of trailing spaces that affected the UCS2 character set. (Bug #7350) innobase/data/data0type.c: Added dtype_get_charset_coll_noninline() innobase/include/data0type.h: Added dtype_get_charset_coll_noninline() innobase/include/row0mysql.h: Added charset field to mysql_row_templ_struct. innobase/include/row0mysql.ic: row_mysql_store_col_in_innobase_format(): When removing trailing spaces, treat the UCS2 character set properly. innobase/rem/rem0cmp.c: cmp_whole_field(): Do not remove trailing 0x20 bytes, as innobase_mysql_cmp() implicitly pads the strings with trailing spaces as necessary. innobase/row/row0sel.c: row_sel_field_store_in_mysql_format(): Do not pad with 0x20 bytes. row_sel_store_mysql_rec(): Pad VARCHARs with trailing spaces (0x20, or 0x0020 in UCS2). sql/ha_innodb.cc: build_template(): Initialize templ->charset --- innobase/data/data0type.c | 11 +++++++ innobase/include/data0type.h | 7 +++++ innobase/include/row0mysql.h | 2 ++ innobase/include/row0mysql.ic | 31 ++++++++++++++++---- innobase/rem/rem0cmp.c | 16 ---------- innobase/row/row0sel.c | 68 +++++++++++++++++++++++++++++++++++++++---- sql/ha_innodb.cc | 2 ++ 7 files changed, 110 insertions(+), 27 deletions(-) diff --git a/innobase/data/data0type.c b/innobase/data/data0type.c index 714cf92bc65..dab14df4240 100644 --- a/innobase/data/data0type.c +++ b/innobase/data/data0type.c @@ -165,6 +165,17 @@ dtype_is_non_binary_string_type( return(FALSE); } +/************************************************************************* +Gets the MySQL charset-collation code for MySQL string types. */ + +ulint +dtype_get_charset_coll_noninline( +/*=============================*/ + ulint prtype) /* in: precise data type */ +{ + return(dtype_get_charset_coll(prtype)); +} + /************************************************************************* Forms a precise type from the < 4.1.2 format precise type plus the charset-collation code. */ diff --git a/innobase/include/data0type.h b/innobase/include/data0type.h index c263d2bf613..02c874836fd 100644 --- a/innobase/include/data0type.h +++ b/innobase/include/data0type.h @@ -234,6 +234,13 @@ dtype_get_prtype( dtype_t* type); /************************************************************************* Gets the MySQL charset-collation code for MySQL string types. */ + +ulint +dtype_get_charset_coll_noninline( +/*=============================*/ + ulint prtype);/* in: precise data type */ +/************************************************************************* +Gets the MySQL charset-collation code for MySQL string types. */ UNIV_INLINE ulint dtype_get_charset_coll( diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index f47ce74ce37..062dae4e60c 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -454,6 +454,8 @@ struct mysql_row_templ_struct { zero if column cannot be NULL */ ulint type; /* column type in Innobase mtype numbers DATA_CHAR... */ + ulint charset; /* MySQL charset-collation code + of the column, or zero */ ulint is_unsigned; /* if a column type is an integer type and this field is != 0, then it is an unsigned integer type */ diff --git a/innobase/include/row0mysql.ic b/innobase/include/row0mysql.ic index 4ecd66e06ec..fc922b52d0a 100644 --- a/innobase/include/row0mysql.ic +++ b/innobase/include/row0mysql.ic @@ -91,12 +91,33 @@ row_mysql_store_col_in_innobase_format( } } else if (type == DATA_VARCHAR || type == DATA_VARMYSQL || type == DATA_BINARY) { + /* Remove trailing spaces. */ + + /* Handle UCS2 strings differently. As no new + collations will be introduced in 4.1, we hardcode the + charset-collation codes here. In 5.0, the logic will + be based on mbminlen. */ + ulint cset = dtype_get_charset_coll( + dtype_get_prtype(dfield_get_type(dfield))); ptr = row_mysql_read_var_ref(&col_len, mysql_data); - - /* Remove trailing spaces */ - while (col_len > 0 && ptr[col_len - 1] == ' ') { - col_len--; - } + if (cset == 35/*ucs2_general_ci*/ + || cset == 90/*ucs2_bin*/ + || (cset >= 128/*ucs2_unicode_ci*/ + && cset <= 144/*ucs2_persian_ci*/)) { + /* space=0x0020 */ + /* Trim "half-chars", just in case. */ + col_len &= ~1; + + while (col_len >= 2 && ptr[col_len - 2] == 0x00 + && ptr[col_len - 1] == 0x20) { + col_len -= 2; + } + } else { + /* space=0x20 */ + while (col_len > 0 && ptr[col_len - 1] == 0x20) { + col_len--; + } + } } else if (type == DATA_BLOB) { ptr = row_mysql_read_blob_ref(&col_len, mysql_data, col_len); } diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c index 041fb7914e2..cf549284acc 100644 --- a/innobase/rem/rem0cmp.c +++ b/innobase/rem/rem0cmp.c @@ -261,22 +261,6 @@ cmp_whole_field( "InnoDB: comparison!\n"); } - /* MySQL does not pad the ends of strings with spaces in a - comparison. That would cause a foreign key check to fail for - non-latin1 character sets if we have different length columns. - To prevent that we remove trailing spaces here before doing - the comparison. NOTE that if we in the future map more MySQL - types to DATA_MYSQL or DATA_VARMYSQL, we have to change this - code. */ - - while (a_length > 0 && a[a_length - 1] == ' ') { - a_length--; - } - - while (b_length > 0 && b[b_length - 1] == ' ') { - b_length--; - } - return(innobase_mysql_cmp( (int)(type->prtype & DATA_MYSQL_TYPE_MASK), (uint)dtype_get_charset_coll(type->prtype), diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index ce76f48e7a7..61ba0b53172 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2204,9 +2204,6 @@ row_sel_field_store_in_mysql_format( dest = row_mysql_store_var_len(dest, len); ut_memcpy(dest, data, len); - /* Pad with trailing spaces */ - memset(dest + len, ' ', col_len - len); - /* ut_ad(col_len >= len + 2); No real var implemented in MySQL yet! */ @@ -2334,7 +2331,45 @@ row_sel_store_mysql_rec( mysql_rec + templ->mysql_col_offset, templ->mysql_col_len, data, len, templ->type, templ->is_unsigned); - + + if (templ->type == DATA_VARCHAR + || templ->type == DATA_VARMYSQL + || templ->type == DATA_BINARY) { + /* Pad with trailing spaces */ + data = mysql_rec + templ->mysql_col_offset; + + /* Handle UCS2 strings differently. As no new + collations will be introduced in 4.1, we + hardcode the charset-collation codes here. + 5.0 will use a different approach. */ + if (templ->charset == 35 + || templ->charset == 90 + || (templ->charset >= 128 + && templ->charset <= 144)) { + /* space=0x0020 */ + ulint col_len = templ->mysql_col_len; + + ut_a(!(col_len & 1)); + if (len & 1) { + /* A 0x20 has been stripped + from the column. + Pad it back. */ + goto pad_0x20; + } + /* Pad the rest of the string + with 0x0020 */ + while (len < col_len) { + data[len++] = 0x00; + pad_0x20: + data[len++] = 0x20; + } + } else { + /* space=0x20 */ + memset(data + len, 0x20, + templ->mysql_col_len - len); + } + } + /* Cleanup */ if (extern_field_heap) { mem_heap_free(extern_field_heap); @@ -2368,8 +2403,29 @@ row_sel_store_mysql_rec( pad_char = '\0'; } - memset(mysql_rec + templ->mysql_col_offset, pad_char, - templ->mysql_col_len); + /* Handle UCS2 strings differently. As no new + collations will be introduced in 4.1, + we hardcode the charset-collation codes here. + 5.0 will use a different approach. */ + if (templ->charset == 35 + || templ->charset == 90 + || (templ->charset >= 128 + && templ->charset <= 144)) { + /* There are two bytes per char, so the length + has to be an even number. */ + ut_a(!(templ->mysql_col_len & 1)); + data = mysql_rec + templ->mysql_col_offset; + len = templ->mysql_col_len; + /* Pad with 0x0020. */ + while (len >= 2) { + *data++ = 0x00; + *data++ = 0x20; + len -= 2; + } + } else { + memset(mysql_rec + templ->mysql_col_offset, + pad_char, templ->mysql_col_len); + } } } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index cc69762cbdb..8110df1063f 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2248,6 +2248,8 @@ build_template( templ->mysql_col_len = (ulint) field->pack_length(); templ->type = get_innobase_type_from_mysql_type(field); + templ->charset = dtype_get_charset_coll_noninline( + index->table->cols[i].type.prtype); templ->is_unsigned = (ulint) (field->flags & UNSIGNED_FLAG); if (templ->type == DATA_BLOB) { -- cgit v1.2.1 From 48259b6988ef29ae32fc4a0a545570efa4825ab8 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 8 Jan 2005 06:15:41 +0100 Subject: Show the index type even for indexes using the default index type in tables that support multiple index types. (Bug #7235) sql/sql_show.cc: Always output 'TYPE ' for indexes on tables with multiple index types mysql-test/r/ctype_utf8.result: Fix results for test --- mysql-test/r/ctype_utf8.result | 4 ++-- sql/sql_show.cc | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 599d49208e7..6140fd04c9c 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -412,7 +412,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) character set utf8 default NULL, - UNIQUE KEY `a` (`c`(1)) + UNIQUE KEY `a` TYPE HASH (`c`(1)) ) ENGINE=HEAP DEFAULT CHARSET=latin1 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); insert into t1 values ('aa'); @@ -570,7 +570,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `c` char(10) character set utf8 collate utf8_bin default NULL, - UNIQUE KEY `a` (`c`(1)) + UNIQUE KEY `a` TYPE HASH (`c`(1)) ) ENGINE=HEAP DEFAULT CHARSET=latin1 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); insert into t1 values ('aa'); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index ba13dd1ff04..a3f497d71ae 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1406,14 +1406,18 @@ store_create_info(THD *thd, TABLE *table, String *packet) if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) && !limited_mysql_mode && !foreign_db_mode) { - if (table->db_type == DB_TYPE_HEAP && - key_info->algorithm == HA_KEY_ALG_BTREE) + if (key_info->algorithm == HA_KEY_ALG_BTREE) packet->append(" TYPE BTREE", 11); + if (key_info->algorithm == HA_KEY_ALG_HASH) + packet->append(" TYPE HASH", 10); + // +BAR: send USING only in non-default case: non-spatial rtree if ((key_info->algorithm == HA_KEY_ALG_RTREE) && !(key_info->flags & HA_SPATIAL)) packet->append(" TYPE RTREE", 11); + + // No need to send TYPE FULLTEXT, it is sent as FULLTEXT KEY } packet->append(" (", 2); -- cgit v1.2.1 From 9d4b5896fbf45f3c7718a2fcd5712c64c06cc7d1 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Jan 2005 14:26:40 +0300 Subject: Fix for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB mode". Changed grammar rule for "type" token. Now we have one branch with optional length specification for TIMESTAMP type instead of two separate branches. mysql-test/r/type_timestamp.result: Added test case for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB mode". mysql-test/t/type_timestamp.test: Added test case for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB mode". sql/sql_yacc.yy: Changed rule for "type" token. Now we have one branch with optional length specification for TIMESTAMP type instead of two separate branches. This also gives us consistent behavior for TIMETSAMP in MAXDB mode. --- mysql-test/r/type_timestamp.result | 10 ++++++++++ mysql-test/t/type_timestamp.test | 12 ++++++++++++ sql/sql_yacc.yy | 9 +-------- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index 42fdc7e50c6..6c46d308e7e 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -422,3 +422,13 @@ max(t) 2004-01-01 01:00:00 2004-02-01 00:00:00 drop table t1; +set sql_mode='maxdb'; +create table t1 (a timestamp, b timestamp(19)); +show create table t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" datetime default NULL, + "b" datetime default NULL +) +set sql_mode=''; +drop table t1; diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index a8a0cf8703c..783e310f02d 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -286,3 +286,15 @@ insert into t1 values ('a', '2004-01-01 00:00:00'), ('a', '2004-01-01 01:00:00') ('b', '2004-02-01 00:00:00'); select max(t) from t1 group by a; drop table t1; + +# +# Test for bug #7418 "TIMESTAMP not always converted to DATETIME in MAXDB +# mode". TIMESTAMP columns should be converted DATETIME columns in MAXDB +# mode regardless of whether a display width is given. +# +set sql_mode='maxdb'; +create table t1 (a timestamp, b timestamp(19)); +show create table t1; +# restore default mode +set sql_mode=''; +drop table t1; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a09694ee1e6..66f7882c4e7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1415,7 +1415,7 @@ type: | YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; } | DATE_SYM { $$=FIELD_TYPE_DATE; } | TIME_SYM { $$=FIELD_TYPE_TIME; } - | TIMESTAMP + | TIMESTAMP opt_len { if (YYTHD->variables.sql_mode & MODE_MAXDB) $$=FIELD_TYPE_DATETIME; @@ -1428,13 +1428,6 @@ type: $$=FIELD_TYPE_TIMESTAMP; } } - | TIMESTAMP '(' NUM ')' - { - LEX *lex= Lex; - lex->length= $3.str; - lex->type|= NOT_NULL_FLAG; - $$= FIELD_TYPE_TIMESTAMP; - } | DATETIME { $$=FIELD_TYPE_DATETIME; } | TINYBLOB { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_TINY_BLOB; } -- cgit v1.2.1 From ce2821c78e937da3462ee5c752bd1992834c7c43 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Jan 2005 18:55:53 +0200 Subject: Review of new pushed code Indentation cleanup client/mysqladmin.cc: Indentation cleanup --- client/mysqladmin.cc | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 24cd461b1fa..d390a152fc7 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -832,7 +832,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) if (argv[1][0]) { char *pw= argv[1]; - bool old= find_type(argv[0], &command_typelib, 2) == ADMIN_OLD_PASSWORD; + bool old= (find_type(argv[0], &command_typelib, 2) == + ADMIN_OLD_PASSWORD); #ifdef __WIN__ uint pw_len= strlen(pw); if (pw_len > 1 && pw[0] == '\'' && pw[pw_len-1] == '\'') @@ -843,21 +844,29 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) If we don't already know to use an old-style password, see what the server is using */ - if (!old) { - if (mysql_query(mysql, "SHOW VARIABLES LIKE 'old_passwords'")) { + if (!old) + { + if (mysql_query(mysql, "SHOW VARIABLES LIKE 'old_passwords'")) + { my_printf_error(0, "Could not determine old_passwords setting from server; error: '%s'", MYF(ME_BELL),mysql_error(mysql)); return -1; - } else { + } + else + { MYSQL_RES *res= mysql_store_result(mysql); - if (!res) { - my_printf_error(0, "Could not get old_passwords setting from server; error: '%s'", + if (!res) + { + my_printf_error(0, + "Could not get old_passwords setting from " + "server; error: '%s'", MYF(ME_BELL),mysql_error(mysql)); return -1; } - if (!mysql_num_rows(res)) { + if (!mysql_num_rows(res)) old= 1; - } else { + else + { MYSQL_ROW row= mysql_fetch_row(res); old= !strncmp(row[1], "ON", 2); } -- cgit v1.2.1 From 5a770b9c37efdd8dcd86fe74912ca031463b39b0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Jan 2005 12:18:36 +0300 Subject: Fix for bug #7586 "TIMEDIFF for sec+microsec not working properly". mysql-test/r/func_sapdb.result: Added test for bug #7586 "TIMEDIFF for sec+microsec not working properly". Corrected previously wrong results of couple other statements. mysql-test/t/func_sapdb.test: Added test for bug #7586 "TIMEDIFF for sec+microsec not working properly". sql/item_timefunc.cc: Item_func_timediff::val_str(): Use simplier and less error-prone implementation. Now we are counting difference between time values in microseconds and convert it to time value (instead of using seconds and taking difference in "second_part"s into account). --- mysql-test/r/func_sapdb.result | 7 +++++-- mysql-test/t/func_sapdb.test | 1 + sql/item_timefunc.cc | 30 ++++++++++-------------------- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index cf2bd687115..c74d6fc5a4e 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -97,13 +97,16 @@ timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") 46:58:57.999999 select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002"); timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") --23:59:59.999999 +-24:00:00.000001 select timediff("1997-12-31 23:59:59.000001","23:59:59.000001"); timediff("1997-12-31 23:59:59.000001","23:59:59.000001") NULL select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001"); timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001") -00:00:00.000001 +select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50"); +timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50") +-00:00:00.000001 select maketime(10,11,12); maketime(10,11,12) 10:11:12 @@ -175,7 +178,7 @@ f8 date YES NULL f9 time YES NULL select * from t1; f1 f2 f3 f4 f5 f6 f7 f8 f9 -1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -23:59:59 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59 +1997-01-01 1998-01-02 01:01:00 49:01:01 46:58:57 -24:00:00 10:11:12 2001-12-01 01:01:01 1997-12-31 23:59:59 create table test(t1 datetime, t2 time, t3 time, t4 datetime); insert into test values ('2001-01-01 01:01:01', '01:01:01', null, '2001-02-01 01:01:01'), diff --git a/mysql-test/t/func_sapdb.test b/mysql-test/t/func_sapdb.test index 2ae3c438243..de433485fca 100644 --- a/mysql-test/t/func_sapdb.test +++ b/mysql-test/t/func_sapdb.test @@ -54,6 +54,7 @@ select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002"); select timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002"); select timediff("1997-12-31 23:59:59.000001","23:59:59.000001"); select timediff("2000:01:01 00:00:00", "2000:01:01 00:00:00.000001"); +select timediff("2005-01-11 15:48:49.999999", "2005-01-11 15:48:50"); --enable_ps_protocol select maketime(10,11,12); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 0d652a431cb..f9c9d1f013d 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2432,8 +2432,7 @@ void Item_func_add_time::print(String *str) String *Item_func_timediff::val_str(String *str) { DBUG_ASSERT(fixed == 1); - longlong seconds; - long microseconds; + longlong microseconds; long days; int l_sign= 1; TIME l_time1 ,l_time2, l_time3; @@ -2457,32 +2456,23 @@ String *Item_func_timediff::val_str(String *str) (uint) l_time2.month, (uint) l_time2.day)); - microseconds= l_time1.second_part - l_sign*l_time2.second_part; - seconds= ((longlong) days*86400L + l_time1.hour*3600L + - l_time1.minute*60L + l_time1.second + microseconds/1000000L - - (longlong)l_sign*(l_time2.hour*3600L+l_time2.minute*60L+ - l_time2.second)); + microseconds= ((longlong)days*86400L + + l_time1.hour*3600L + l_time1.minute*60L + l_time1.second - + (longlong)l_sign*(l_time2.hour*3600L + l_time2.minute*60L + + l_time2.second))*1000000 + + l_time1.second_part - l_sign*l_time2.second_part; l_time3.neg= 0; - if (seconds < 0) - { - seconds= -seconds; - l_time3.neg= 1; - } - else if (seconds == 0 && microseconds < 0) + if (microseconds < 0) { microseconds= -microseconds; l_time3.neg= 1; } - if (microseconds < 0) - { - microseconds+= 1000000L; - seconds--; - } - if ((l_time2.neg == l_time1.neg) && l_time1.neg) + if ((l_time2.neg == l_time1.neg) && l_time1.neg && microseconds) l_time3.neg= l_time3.neg ? 0 : 1; - calc_time_from_sec(&l_time3, (long) seconds, microseconds); + calc_time_from_sec(&l_time3, (long)(microseconds/1000000), + (long)(microseconds%1000000)); if (!make_datetime(l_time1.second_part || l_time2.second_part ? TIME_MICROSECOND : TIME_ONLY, -- cgit v1.2.1 From 11ce0a7690a730bbe16dba929050a50841bf0ed4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Jan 2005 15:24:49 +0200 Subject: InnoDB: Use system-supplied tmpfile() on Netware, as there is no open interface for setting the "delete-on-close" flag. innobase/os/os0file.c: Use system-supplied tmpfile() on Netware sql/ha_innodb.cc: Remove innobase_mysql_tmpfile() on Netware. --- innobase/os/os0file.c | 24 +++++++++++++++--------- sql/ha_innodb.cc | 2 ++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index b8339134fb1..cadf1c0385f 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -375,7 +375,7 @@ os_io_init_simple(void) } } -#ifndef UNIV_HOTBACKUP +#if !defined(UNIV_HOTBACKUP) && !defined(__NETWARE__) /************************************************************************* Creates a temporary file. This function is defined in ha_innodb.cc. */ @@ -383,7 +383,7 @@ int innobase_mysql_tmpfile(void); /*========================*/ /* out: temporary file descriptor, or < 0 on error */ -#endif /* !UNIV_HOTBACKUP */ +#endif /* !UNIV_HOTBACKUP && !__NETWARE__ */ /*************************************************************************** Creates a temporary file. */ @@ -393,9 +393,12 @@ os_file_create_tmpfile(void) /*========================*/ /* out: temporary file handle, or NULL on error */ { +#ifdef __NETWARE__ + FILE* file = tmpfile(); +#else /* __NETWARE__ */ FILE* file = NULL; int fd = -1; -#ifdef UNIV_HOTBACKUP +# ifdef UNIV_HOTBACKUP int tries; for (tries = 10; tries--; ) { char* name = tempnam(fil_path_to_mysql_datadir, "ib"); @@ -404,15 +407,15 @@ os_file_create_tmpfile(void) } fd = open(name, -# ifdef __WIN__ +# ifdef __WIN__ O_SEQUENTIAL | O_SHORT_LIVED | O_TEMPORARY | -# endif /* __WIN__ */ +# endif /* __WIN__ */ O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE); if (fd >= 0) { -# ifndef __WIN__ +# ifndef __WIN__ unlink(name); -# endif /* !__WIN__ */ +# endif /* !__WIN__ */ free(name); break; } @@ -423,22 +426,25 @@ os_file_create_tmpfile(void) name); free(name); } -#else /* UNIV_HOTBACKUP */ +# else /* UNIV_HOTBACKUP */ fd = innobase_mysql_tmpfile(); -#endif /* UNIV_HOTBACKUP */ +# endif /* UNIV_HOTBACKUP */ if (fd >= 0) { file = fdopen(fd, "w+b"); } +#endif /* __NETWARE__ */ if (!file) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Error: unable to create temporary file;" " errno: %d\n", errno); +#ifndef __NETWARE__ if (fd >= 0) { close(fd); } +#endif /* !__NETWARE__ */ } return(file); diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 69d9d885b8e..54d93783481 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -413,6 +413,7 @@ innobase_mysql_print_thd( putc('\n', f); } +#ifndef __NETWARE__ /************************************************************************* Creates a temporary file. */ extern "C" @@ -456,6 +457,7 @@ innobase_mysql_tmpfile(void) } return(fd2); } +#endif /* !__NETWARE__ */ /************************************************************************* Gets the InnoDB transaction handle for a MySQL handler object, creates -- cgit v1.2.1 From 89b1d5f0ead4c3a7edbb4c76c157ce9e4cc83a1c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Jan 2005 23:30:54 +0100 Subject: Symlink vulnerability fixed. reported by Javier Fernandez-Sanguino Pena and Debian Security Audit Team (http://www.debian.org/security/audit) --- scripts/mysqlaccess.sh | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/scripts/mysqlaccess.sh b/scripts/mysqlaccess.sh index 75ef63ecdd0..b71f6847baf 100644 --- a/scripts/mysqlaccess.sh +++ b/scripts/mysqlaccess.sh @@ -2,7 +2,7 @@ # **************************** package MySQLaccess; #use strict; -use POSIX qw(tmpnam); +use File::Temp qw(tempfile tmpnam); use Fcntl; BEGIN { @@ -32,7 +32,6 @@ BEGIN { $ACCESS_U_BCK = 'user_backup'; $ACCESS_D_BCK = 'db_backup'; $DIFF = '/usr/bin/diff'; - $TMP_PATH = '/tmp'; #path to writable tmp-directory $MYSQLDUMP = '@bindir@/mysqldump'; #path to mysqldump executable @@ -432,7 +431,7 @@ use IPC::Open3; # no caching on STDOUT $|=1; - $MYSQL_CNF = POSIX::tmpnam(); + $MYSQL_CNF = tmpnam(); %MYSQL_CNF = (client => { }, mysql => { }, mysqldump => { }, @@ -577,8 +576,6 @@ if (!defined($Param{'host'})) { $Param{'host'}='localhost'; } push(@MySQLaccess::Grant::Error,'not_found_mysql') if !(-x $MYSQL); push(@MySQLaccess::Grant::Error,'not_found_diff') if !(-x $DIFF); push(@MySQLaccess::Grant::Error,'not_found_mysqldump') if !(-x $MYSQLDUMP); -push(@MySQLaccess::Grant::Error,'not_found_tmp') if !(-d $TMP_PATH); -push(@MySQLaccess::Grant::Error,'write_err_tmp') if !(-w $TMP_PATH); if (@MySQLaccess::Grant::Error) { MySQLaccess::Report::Print_Error_Messages() ; exit 0; @@ -1777,17 +1774,15 @@ sub Diff_Privileges { @before = sort(@before); @after = sort(@after); - $before = "$MySQLaccess::TMP_PATH/$MySQLaccess::script.before.$$"; - $after = "$MySQLaccess::TMP_PATH/$MySQLaccess::script.after.$$"; - #$after = "/tmp/t0"; - open(BEFORE,"> $before") || - push(@MySQLaccess::Report::Errors,"Can't open temporary file $before for writing"); - open(AFTER,"> $after") || - push(@MySQLaccess::Report::Errors,"Can't open temporary file $after for writing"); - print BEFORE join("\n",@before); - print AFTER join("\n",@after); - close(BEFORE); - close(AFTER); + ($hb, $before) = tempfile("$MySQLaccess::script.XXXXXX") or + push(@MySQLaccess::Report::Errors,"Can't create temporary file: $!"); + ($ha, $after) = tempfile("$MySQLaccess::script.XXXXXX") or + push(@MySQLaccess::Report::Errors,"Can't create temporary file: $!"); + + print $hb join("\n",@before); + print $ha join("\n",@after); + close $hb; + close $ha; # ---------------------------------- # compute difference @@ -1800,8 +1795,8 @@ sub Diff_Privileges { # ---------------------------------- # cleanup temp. files - unlink(BEFORE); - unlink(AFTER); + unlink($before); + unlink($after); return \@diffs; } @@ -2316,14 +2311,6 @@ BEGIN { => "The diff program <$MySQLaccess::DIFF> could not be found.\n" ."+ Check your path, or\n" ."+ edit the source of this script to point \$DIFF to the diff program.\n" - ,'not_found_tmp' - => "The temporary directory <$MySQLaccess::TMP_PATH> could not be found.\n" - ."+ create this directory (writeable!), or\n" - ."+ edit the source of this script to point \$TMP_PATH to the right directory.\n" - ,'write_err_tmp' - => "The temporary directory <$MySQLaccess::TMP_PATH> is not writable.\n" - ."+ make this directory writeable!, or\n" - ."+ edit the source of this script to point \$TMP_PATH to another directory.\n" ,'Unrecognized_option' => "Sorry,\n" ."You are using an old version of the mysql-program,\n" -- cgit v1.2.1 From 27db215fa687daf8c6e5e7e22d978c706e98c7e7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 00:41:45 +0100 Subject: Fix conversion of floating point values to character fields when the absolute value of the float is less than 1, and also fix calculation of length for negative values. (Bug #7774) sql/field.cc: Fix handling of negative values and fabs(values> < 1 in Field_str::store mysql-test/r/type_float.result: Add results mysql-test/r/type_float.result.es: Add results mysql-test/t/type_float.test: Add test for conversion of floats to character field --- mysql-test/r/type_float.result | 15 +++++++++++++++ mysql-test/r/type_float.result.es | 15 +++++++++++++++ mysql-test/t/type_float.test | 10 ++++++++++ sql/field.cc | 13 ++++++++++--- 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 9dd92c13c98..530eb32f77d 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -179,3 +179,18 @@ f 9.999 9.999 drop table if exists t1; +create table t1 (c char(20)); +insert into t1 values (5e-28); +select * from t1; +c +5e-28 +drop table t1; +create table t1 (c char(6)); +insert into t1 values (2e5),(2e6),(2e-4),(2e-5); +select * from t1; +c +200000 +2e+06 +0.0002 +2e-05 +drop table t1; diff --git a/mysql-test/r/type_float.result.es b/mysql-test/r/type_float.result.es index 64d9be7e30f..b93539b6bea 100644 --- a/mysql-test/r/type_float.result.es +++ b/mysql-test/r/type_float.result.es @@ -179,3 +179,18 @@ f 9.999 9.999 drop table if exists t1; +create table t1 (c char(20)); +insert into t1 values (5e-28); +select * from t1; +c +5e-28 +drop table t1; +create table t1 (c char(6)); +insert into t1 values (2e5),(2e6),(2e-4),(2e-5); +select * from t1; +c +200000 +2e+06 +0.0002 +2e-05 +drop table t1; diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 3fe3afa3fac..69cdeaa32a9 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -103,3 +103,13 @@ create table t1 (f double(4,3)); insert into t1 values (-11.0),(-11),("-11"),(11.0),(11),("11"); select * from t1; drop table if exists t1; + +# Check conversion of floats to character field (Bug #7774) +create table t1 (c char(20)); +insert into t1 values (5e-28); +select * from t1; +drop table t1; +create table t1 (c char(6)); +insert into t1 values (2e5),(2e6),(2e-4),(2e-5); +select * from t1; +drop table t1; diff --git a/sql/field.cc b/sql/field.cc index e2c11cc7372..2f2115e55dd 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4301,13 +4301,20 @@ int Field_str::store(double nr) char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; uint length; bool use_scientific_notation= TRUE; - use_scientific_notation= TRUE; - if (field_length < 32 && fabs(nr) < log_10[field_length]-1) + /* + Check fabs(nr) against longest value that can be stored in field, + which depends on whether the value is < 1 or not, and negative or not + */ + double anr= fabs(nr); + int neg= (nr < 0.0) ? 1 : 0; + if (field_length < 32 && + (anr < 1.0 ? anr > 1/(log_10[max(0,field_length-neg-2)]) /* -2 for "0." */ + : anr < log_10[field_length-neg]-1)) use_scientific_notation= FALSE; length= (uint) my_sprintf(buff, (buff, "%-.*g", (use_scientific_notation ? - max(0, (int)field_length-5) : + max(0, (int)field_length-neg-5) : field_length), nr)); /* -- cgit v1.2.1 From b414fd585e7bd96603afd3d8ff6cfa8736e11ced Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 00:52:19 +0100 Subject: Small fix for Field_str::store() to avoid trying to read past beginning of log_10 array. sql/field.cc: Avoid pointless calculation for really short fields, and what could be an attempt to access outside the bounds of the log_10 array. --- sql/field.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/field.cc b/sql/field.cc index 2f2115e55dd..fec65438e4d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4307,7 +4307,7 @@ int Field_str::store(double nr) */ double anr= fabs(nr); int neg= (nr < 0.0) ? 1 : 0; - if (field_length < 32 && + if (field_length > 4 && field_length < 32 && (anr < 1.0 ? anr > 1/(log_10[max(0,field_length-neg-2)]) /* -2 for "0." */ : anr < log_10[field_length-neg]-1)) use_scientific_notation= FALSE; -- cgit v1.2.1 From bc9e3bb40659d1847c1c7ba95f0ef0ed4c4604d2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Jan 2005 17:20:43 -0800 Subject: Fix small memory leak that occured when BerkeleyDB failed to initialize. sql/ha_berkeley.cc: Skip allocation of hash and lock on error --- sql/ha_berkeley.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 2c7cce4bcd0..e33cd3fca1b 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -165,11 +165,13 @@ bool berkeley_init(void) { db_env->close(db_env,0); /* purecov: inspected */ db_env=0; /* purecov: inspected */ + goto err; } (void) hash_init(&bdb_open_tables,system_charset_info,32,0,0, (hash_get_key) bdb_get_key,0,0); pthread_mutex_init(&bdb_mutex,MY_MUTEX_INIT_FAST); +err: DBUG_RETURN(db_env == 0); } -- cgit v1.2.1 From 787557f2e79a8920c41c29ce0af6c7f22a0e6a2a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Jan 2005 19:56:49 -0600 Subject: libmysqld.def, libmysql.def: Add missing 'get_defaults_files' to fix linking error. libmysql/libmysql.def: Add missing 'get_defaults_files' to fix linking error. libmysqld/libmysqld.def: Add missing 'get_defaults_files' to fix linking error. --- libmysql/libmysql.def | 1 + libmysqld/libmysqld.def | 1 + 2 files changed, 2 insertions(+) diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def index c9ff70f208d..6967b09b143 100644 --- a/libmysql/libmysql.def +++ b/libmysql/libmysql.def @@ -146,3 +146,4 @@ EXPORTS mysql_rpl_query_type mysql_slave_query mysql_embedded + get_defaults_files diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def index 14c6725bcb5..5515f50a1de 100644 --- a/libmysqld/libmysqld.def +++ b/libmysqld/libmysqld.def @@ -157,3 +157,4 @@ EXPORTS mysql_stmt_attr_get mysql_stmt_attr_set mysql_stmt_field_count + get_defaults_files -- cgit v1.2.1 From 4dd5858b4e42b63e79e37108fcafd04ce7c86d1d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Jan 2005 21:04:31 -0600 Subject: libmysqld.def, libmysql.def: Use the invisible tabs (!) libmysql/libmysql.def: Use the invisible tabs (!) libmysqld/libmysqld.def: Use the invisible tabs (!) --- libmysql/libmysql.def | 2 +- libmysqld/libmysqld.def | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def index 6967b09b143..c5579e9ec2b 100644 --- a/libmysql/libmysql.def +++ b/libmysql/libmysql.def @@ -146,4 +146,4 @@ EXPORTS mysql_rpl_query_type mysql_slave_query mysql_embedded - get_defaults_files + get_defaults_files diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def index 5515f50a1de..ea3133594f5 100644 --- a/libmysqld/libmysqld.def +++ b/libmysqld/libmysqld.def @@ -157,4 +157,4 @@ EXPORTS mysql_stmt_attr_get mysql_stmt_attr_set mysql_stmt_field_count - get_defaults_files + get_defaults_files -- cgit v1.2.1 From 81bd44261a7864ae1d1f9071b536b232e8279742 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 10:28:26 +0100 Subject: bug#7864 - fix ndb limit 4.5G data memory due to truncation error ndb/src/kernel/blocks/dbtup/DbtupGen.cpp: remove 8k->32k conversion ndb/src/kernel/vm/Configuration.cpp: compute size in 32k pages directly --- ndb/src/kernel/blocks/dbtup/DbtupGen.cpp | 9 +++------ ndb/src/kernel/vm/Configuration.cpp | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index 8e1cba24359..0f0e6d61f41 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -632,14 +632,11 @@ void Dbtup::execREAD_CONFIG_REQ(Signal* signal) ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_FRAG, &cnoOfFragrec)); ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_OP_RECS, &cnoOfOprec)); - - // MemorySpaceTuples is specified in 8k pages, divide by 4 for 32k pages - Uint32 tmp; - ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE, &tmp)); - Uint64 pages = (tmp * 2048 + (ZWORDS_ON_PAGE - 1))/ (Uint64)ZWORDS_ON_PAGE; - cnoOfPage = (Uint32)pages; + + ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE, &cnoOfPage)); Uint32 noOfTriggers= 0; + Uint32 tmp= 0; ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_PAGE_RANGE, &tmp)); initPageRangeSize(tmp); ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TUP_TABLE, &cnoOfTablerec)); diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp index 29255fc9837..4ad7050ce63 100644 --- a/ndb/src/kernel/vm/Configuration.cpp +++ b/ndb/src/kernel/vm/Configuration.cpp @@ -521,7 +521,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ ERROR_SET(fatal, ERR_INVALID_CONFIG, msg, buf); } - noOfDataPages = (dataMem / 8192); + noOfDataPages = (dataMem / 32768); noOfIndexPages = (indexMem / 8192); for(unsigned j = 0; j Date: Thu, 13 Jan 2005 13:07:35 +0100 Subject: - added the 4.0 shared mysqlclient libraries to the 4.1 "shared-compat" RPM --- support-files/MySQL-shared-compat.spec.sh | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/support-files/MySQL-shared-compat.spec.sh b/support-files/MySQL-shared-compat.spec.sh index 068daadab58..e3c88c9415f 100644 --- a/support-files/MySQL-shared-compat.spec.sh +++ b/support-files/MySQL-shared-compat.spec.sh @@ -26,7 +26,8 @@ # # Change this to match the version of the shared libs you want to include # -%define version4 @MYSQL_NO_DASH_VERSION@ +%define version41 @MYSQL_NO_DASH_VERSION@ +%define version40 4.0.23 %define version3 3.23.58 Name: MySQL-shared-compat @@ -36,26 +37,31 @@ License: GPL Group: Applications/Databases URL: http://www.mysql.com/ Autoreqprov: on -Version: %{version4} +Version: %{version41} Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build Obsoletes: MySQL-shared, mysql-shared Provides: MySQL-shared -Summary: MySQL shared libraries for MySQL %{version4} and %{version3} -Source0: MySQL-shared-%{version4}-0.%{_arch}.rpm -Source1: MySQL-shared-%{version3}-1.%{_arch}.rpm +Summary: MySQL shared client libraries for MySQL %{version41}, %{version40} and %{version3} +# We simply use the "MySQL-shared" subpackages as input sources instead of +# rebuilding all from source +Source0: MySQL-shared-%{version41}-0.%{_arch}.rpm +Source1: MySQL-shared-%{version40}-0.%{_arch}.rpm +Source2: MySQL-shared-%{version3}-1.%{_arch}.rpm # No need to include the RPMs once more - they can be downloaded seperately # if you want to rebuild this package NoSource: 0 NoSource: 1 +NoSource: 2 BuildRoot: %{_tmppath}/%{name}-%{version}-build %description -This package includes the shared libraries for both MySQL %{version3} and -MySQL %{version4}. Install this package instead of "MySQL-shared", if you -have applications installed that are dynamically linked against MySQL -3.23.xx but you want to upgrade to MySQL 4.0.xx without breaking the library -dependencies. +This package includes the shared libraries for both MySQL %{version3}, +MySQL %{version40} as well as MySQL %{version41}. +Install this package instead of "MySQL-shared", if you have applications +installed that are dynamically linked against older versions of the MySQL +client library but you want to upgrade to MySQL 4.1.xx without breaking the +library dependencies. %install [ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT; @@ -63,6 +69,8 @@ mkdir -p $RPM_BUILD_ROOT cd $RPM_BUILD_ROOT rpm2cpio %{SOURCE0} | cpio -iv --make-directories rpm2cpio %{SOURCE1} | cpio -iv --make-directories +rpm2cpio %{SOURCE2} | cpio -iv --make-directories +/sbin/ldconfig -n $RPM_BUILD_ROOT%{_libdir} %clean [ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT; -- cgit v1.2.1 From 4b9879707edb787f9fea99bc55e5ab09599206c8 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 15:04:57 +0200 Subject: Fixed a problem with a test. Time could be 0 or 1 seconds, depending on whether running with or without valgrind. --- mysql-test/r/ps_1general.result | 2 +- mysql-test/t/ps_1general.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index 25b9e2dcda4..ee3eca850f4 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -291,7 +291,7 @@ execute stmt4; prepare stmt4 from ' show full processlist '; execute stmt4; Id User Host db Command Time State Info -number root localhost test Query 0 NULL show full processlist +number root localhost test Query time NULL show full processlist prepare stmt4 from ' show grants for user '; prepare stmt4 from ' show create table t2 '; ERROR HY000: This command is not supported in the prepared statement protocol yet diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test index 08c1ad85fb1..d9cc9de6ff1 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -317,7 +317,7 @@ prepare stmt4 from ' show engine bdb logs '; execute stmt4; --enable_result_log prepare stmt4 from ' show full processlist '; ---replace_column 1 number +--replace_column 1 number 6 time execute stmt4; prepare stmt4 from ' show grants for user '; --error 1295 -- cgit v1.2.1 From e41abb40f5fdadcf2f8a15c75de229ae91132dd7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 14:57:51 +0100 Subject: - bumped up the version number in configure.in from 4.1.9 to 4.1.10 - tagged ChangeSet 1.2207 as "mysql-4.1.9" configure.in: - bumped up the version number from 4.1.9 to 4.1.10 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index f2184ed7be5..45ca009123e 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 4.1.9) +AM_INIT_AUTOMAKE(mysql, 4.1.10) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 -- cgit v1.2.1 From 8dea326cf9f060588cda6a824e8a90a222ac0285 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 18:12:04 +0400 Subject: bug#7284: strnxfrm returns different results for equal strings --- mysql-test/include/ctype_filesort.inc | 15 ++++++++++++ mysql-test/r/ctype_big5.result | 21 ++++++++++++++++ mysql-test/r/ctype_latin1.result | 20 ++++++++++++++++ mysql-test/r/ctype_latin1_de.result | 9 +++++++ mysql-test/r/ctype_sjis.result | 20 ++++++++++++++++ mysql-test/r/ctype_tis620.result | 20 ++++++++++++++++ mysql-test/r/ctype_uca.result | 10 ++++++++ mysql-test/r/ctype_ucs.result | 21 ++++++++++++++++ mysql-test/r/ctype_ujis.result | 20 ++++++++++++++++ mysql-test/r/ctype_utf8.result | 20 ++++++++++++++++ mysql-test/t/ctype_big5.test | 6 +++++ mysql-test/t/ctype_latin1.test | 6 +++++ mysql-test/t/ctype_latin1_de.test | 2 ++ mysql-test/t/ctype_sjis.test | 6 +++++ mysql-test/t/ctype_tis620.test | 6 +++++ mysql-test/t/ctype_uca.test | 3 +++ mysql-test/t/ctype_ucs.test | 6 +++++ mysql-test/t/ctype_ujis.test | 6 +++++ mysql-test/t/ctype_utf8.test | 6 +++++ sql/field.cc | 12 +++------- sql/filesort.cc | 5 +--- strings/ctype-big5.c | 5 +++- strings/ctype-bin.c | 26 +++++++++++++++----- strings/ctype-czech.c | 8 ++++--- strings/ctype-gbk.c | 5 +++- strings/ctype-latin1.c | 5 ++-- strings/ctype-mb.c | 11 +++++---- strings/ctype-simple.c | 45 +++++++++++++++++++++++++++++++++-- strings/ctype-sjis.c | 4 +++- strings/ctype-tis620.c | 6 ++++- strings/ctype-uca.c | 16 +++++++++---- strings/ctype-ucs2.c | 9 ++++--- strings/ctype-utf8.c | 5 ++-- strings/ctype-win1250ch.c | 4 +++- 34 files changed, 344 insertions(+), 45 deletions(-) create mode 100644 mysql-test/include/ctype_filesort.inc diff --git a/mysql-test/include/ctype_filesort.inc b/mysql-test/include/ctype_filesort.inc new file mode 100644 index 00000000000..2068463d4e2 --- /dev/null +++ b/mysql-test/include/ctype_filesort.inc @@ -0,0 +1,15 @@ +# +# Set desired charset_connection and collation_collation +# before including this file. +# + +# The next query creates a LONGTEXT column +# using the current character_set_connection +# and collation_connection. + +create table t1 select repeat('a',4000) a; +delete from t1; + +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +drop table t1; diff --git a/mysql-test/r/ctype_big5.result b/mysql-test/r/ctype_big5.result index 9b9fcbccbe0..8f4ee3d0558 100644 --- a/mysql-test/r/ctype_big5.result +++ b/mysql-test/r/ctype_big5.result @@ -56,3 +56,24 @@ DROP DATABASE d1; USE test; SET character_set_server= @safe_character_set_server; SET collation_server= @safe_collation_server; +SET NAMES big5; +SET collation_connection='big5_chinese_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +big5_chinese_ci 6109 +big5_chinese_ci 61 +big5_chinese_ci 6120 +drop table t1; +SET collation_connection='big5_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +big5_bin 6109 +big5_bin 61 +big5_bin 6120 +drop table t1; diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result index 355f53b63a5..cd804939a75 100644 --- a/mysql-test/r/ctype_latin1.result +++ b/mysql-test/r/ctype_latin1.result @@ -305,3 +305,23 @@ select 'a' regexp 'A' collate latin1_general_cs; select 'a' regexp 'A' collate latin1_bin; 'a' regexp 'A' collate latin1_bin 0 +SET collation_connection='latin1_swedish_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +latin1_swedish_ci 6109 +latin1_swedish_ci 61 +latin1_swedish_ci 6120 +drop table t1; +SET collation_connection='latin1_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +latin1_bin 6109 +latin1_bin 61 +latin1_bin 6120 +drop table t1; diff --git a/mysql-test/r/ctype_latin1_de.result b/mysql-test/r/ctype_latin1_de.result index 50af5464f54..6df9d963498 100644 --- a/mysql-test/r/ctype_latin1_de.result +++ b/mysql-test/r/ctype_latin1_de.result @@ -317,3 +317,12 @@ FIELD('ue',s1) FIELD(' 1 1 1 1 1 1 1 1 DROP TABLE t1; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +latin1_german2_ci 6109 +latin1_german2_ci 61 +latin1_german2_ci 6120 +drop table t1; diff --git a/mysql-test/r/ctype_sjis.result b/mysql-test/r/ctype_sjis.result index 944fa0602a9..1f414f89e20 100644 --- a/mysql-test/r/ctype_sjis.result +++ b/mysql-test/r/ctype_sjis.result @@ -71,3 +71,23 @@ B1 B2 B3 drop table t1; +SET collation_connection='sjis_japanese_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +sjis_japanese_ci 6109 +sjis_japanese_ci 61 +sjis_japanese_ci 6120 +drop table t1; +SET collation_connection='sjis_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +sjis_bin 6109 +sjis_bin 61 +sjis_bin 6120 +drop table t1; diff --git a/mysql-test/r/ctype_tis620.result b/mysql-test/r/ctype_tis620.result index fa99c2d1318..6d8bfe74c4b 100644 --- a/mysql-test/r/ctype_tis620.result +++ b/mysql-test/r/ctype_tis620.result @@ -2937,3 +2937,23 @@ Screensaver 2 2002-01-22 491 0 519 0 0 3 http://www.siamzone.com/download/download/000003-jasonx2(800x600).jpg Jaso n X Wallpapers 1 2002-05-31 579 0 1091 0 0 DROP TABLE t1; +SET collation_connection='tis620_thai_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +tis620_thai_ci 6109 +tis620_thai_ci 61 +tis620_thai_ci 6120 +drop table t1; +SET collation_connection='tis620_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +tis620_bin 6109 +tis620_bin 61 +tis620_bin 6120 +drop table t1; diff --git a/mysql-test/r/ctype_uca.result b/mysql-test/r/ctype_uca.result index 0573092e39b..dd5a7ebf6a4 100644 --- a/mysql-test/r/ctype_uca.result +++ b/mysql-test/r/ctype_uca.result @@ -2386,3 +2386,13 @@ a 1 b 0 c 0 drop table t1; +SET collation_connection='utf8_unicode_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +utf8_unicode_ci 6109 +utf8_unicode_ci 61 +utf8_unicode_ci 6120 +drop table t1; diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index b1b83eb8b6c..47211e67905 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -592,3 +592,24 @@ a NULL b NULL c NULL drop table t1; +SET collation_connection='ucs2_general_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +ucs2_general_ci 00610009 +ucs2_general_ci 0061 +ucs2_general_ci 00610020 +drop table t1; +SET NAMES latin1; +SET collation_connection='ucs2_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +ucs2_bin 00610009 +ucs2_bin 0061 +ucs2_bin 00610020 +drop table t1; diff --git a/mysql-test/r/ctype_ujis.result b/mysql-test/r/ctype_ujis.result index aa4c347d54f..fd6c501499b 100644 --- a/mysql-test/r/ctype_ujis.result +++ b/mysql-test/r/ctype_ujis.result @@ -2207,3 +2207,23 @@ F4FC F4FD F4FE DROP TABLE t1; +SET collation_connection='ujis_japanese_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +ujis_japanese_ci 6109 +ujis_japanese_ci 61 +ujis_japanese_ci 6120 +drop table t1; +SET collation_connection='ujis_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +ujis_bin 6109 +ujis_bin 61 +ujis_bin 6120 +drop table t1; diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index ebaa329891c..6e375b53d35 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -829,3 +829,23 @@ select * from t1 where soundex(a) = soundex('test'); id a 1 Test drop table t1; +SET collation_connection='utf8_general_ci'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +utf8_general_ci 6109 +utf8_general_ci 61 +utf8_general_ci 6120 +drop table t1; +SET collation_connection='utf8_bin'; +create table t1 select repeat('a',4000) a; +delete from t1; +insert into t1 values ('a'), ('a '), ('a\t'); +select collation(a),hex(a) from t1 order by a; +collation(a) hex(a) +utf8_bin 6109 +utf8_bin 61 +utf8_bin 6120 +drop table t1; diff --git a/mysql-test/t/ctype_big5.test b/mysql-test/t/ctype_big5.test index b1d71a6af15..8b75123ca32 100644 --- a/mysql-test/t/ctype_big5.test +++ b/mysql-test/t/ctype_big5.test @@ -10,3 +10,9 @@ drop table if exists t1; SET @test_character_set= 'big5'; SET @test_collation= 'big5_chinese_ci'; -- source include/ctype_common.inc + +SET NAMES big5; +SET collation_connection='big5_chinese_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='big5_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_latin1.test b/mysql-test/t/ctype_latin1.test index 677acd9faa9..cee0324d12f 100644 --- a/mysql-test/t/ctype_latin1.test +++ b/mysql-test/t/ctype_latin1.test @@ -60,3 +60,9 @@ DROP TABLE t1; select 'a' regexp 'A' collate latin1_general_ci; select 'a' regexp 'A' collate latin1_general_cs; select 'a' regexp 'A' collate latin1_bin; + + +SET collation_connection='latin1_swedish_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='latin1_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_latin1_de.test b/mysql-test/t/ctype_latin1_de.test index 1c9576c1c56..ce4fdc4e3c9 100644 --- a/mysql-test/t/ctype_latin1_de.test +++ b/mysql-test/t/ctype_latin1_de.test @@ -114,3 +114,5 @@ SELECT s1,COUNT(*) FROM t1 GROUP BY s1; SELECT COUNT(DISTINCT s1) FROM t1; SELECT FIELD('ue',s1), FIELD('Ü',s1), s1='ue', s1='Ü' FROM t1; DROP TABLE t1; + +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_sjis.test b/mysql-test/t/ctype_sjis.test index a3a44789975..58ca3c6a997 100644 --- a/mysql-test/t/ctype_sjis.test +++ b/mysql-test/t/ctype_sjis.test @@ -62,3 +62,9 @@ CREATE TABLE t1 ( insert into t1 values(0xb1),(0xb2),(0xb3); select hex(c) from t1; drop table t1; + + +SET collation_connection='sjis_japanese_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='sjis_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_tis620.test b/mysql-test/t/ctype_tis620.test index 21ec314dca7..87047db9b54 100644 --- a/mysql-test/t/ctype_tis620.test +++ b/mysql-test/t/ctype_tis620.test @@ -151,3 +151,9 @@ INSERT INTO t1 VALUES n X Wallpapers',1,'','2002-05-31','',579,0,'',1091,0,0,''); select * from t1 order by id; DROP TABLE t1; + + +SET collation_connection='tis620_thai_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='tis620_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_uca.test b/mysql-test/t/ctype_uca.test index 8bca2a4b3c2..dfca82fa70a 100644 --- a/mysql-test/t/ctype_uca.test +++ b/mysql-test/t/ctype_uca.test @@ -452,3 +452,6 @@ create table t1 (a varchar(1)) character set utf8 collate utf8_estonian_ci; insert into t1 values ('A'),('B'),('C'),('a'),('b'),('c'); select a, a regexp '[a]' from t1 order by binary a; drop table t1; + +SET collation_connection='utf8_unicode_ci'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index b9f77505446..1a0ba82d6ff 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -384,3 +384,9 @@ alter table t1 add b char(1); show warnings; select * from t1 order by a; drop table t1; + +SET collation_connection='ucs2_general_ci'; +-- source include/ctype_filesort.inc +SET NAMES latin1; +SET collation_connection='ucs2_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_ujis.test b/mysql-test/t/ctype_ujis.test index 3f0e9882179..407287be30a 100644 --- a/mysql-test/t/ctype_ujis.test +++ b/mysql-test/t/ctype_ujis.test @@ -1141,3 +1141,9 @@ INSERT INTO t1 VALUES(0xF4FD); INSERT INTO t1 VALUES(0xF4FE); SELECT HEX(c) FROM t1 ORDER BY BINARY c; DROP TABLE t1; + + +SET collation_connection='ujis_japanese_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='ujis_bin'; +-- source include/ctype_filesort.inc diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 214c2712665..a57db4455ab 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -675,3 +675,9 @@ select * from t1 where soundex(a) = soundex('Test'); select * from t1 where soundex(a) = soundex('TEST'); select * from t1 where soundex(a) = soundex('test'); drop table t1; + + +SET collation_connection='utf8_general_ci'; +-- source include/ctype_filesort.inc +SET collation_connection='utf8_bin'; +-- source include/ctype_filesort.inc diff --git a/sql/field.cc b/sql/field.cc index e2c11cc7372..86073072a64 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4393,8 +4393,7 @@ void Field_string::sort_string(char *to,uint length) uint tmp=my_strnxfrm(field_charset, (unsigned char *) to, length, (unsigned char *) ptr, field_length); - if (tmp < length) - field_charset->cset->fill(field_charset, to + tmp, length - tmp, ' '); + DBUG_ASSERT(tmp == length); } @@ -4596,9 +4595,7 @@ void Field_varstring::sort_string(char *to,uint length) (uchar*) to, length, (uchar*) ptr+HA_KEY_BLOB_LENGTH, tot_length); - if (tot_length < length) - field_charset->cset->fill(field_charset, to+tot_length,length-tot_length, - binary() ? (char) 0 : ' '); + DBUG_ASSERT(tot_length == length); } @@ -5116,10 +5113,7 @@ void Field_blob::sort_string(char *to,uint length) blob_length=my_strnxfrm(field_charset, (uchar*) to, length, (uchar*) blob, blob_length); - if (blob_length < length) - field_charset->cset->fill(field_charset, to+blob_length, - length-blob_length, - binary() ? (char) 0 : ' '); + DBUG_ASSERT(blob_length == length); } } diff --git a/sql/filesort.cc b/sql/filesort.cc index bd0de022fd4..cb377070aaa 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -622,10 +622,7 @@ static void make_sortkey(register SORTPARAM *param, } uint tmp_length=my_strnxfrm(cs,to,sort_field->length, (unsigned char *) from, length); - if (tmp_length < sort_field->length) - cs->cset->fill(cs, (char*) to+tmp_length, - sort_field->length-tmp_length, - fill_char); + DBUG_ASSERT(tmp_length == sort_field->length); } else { diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 8345c53202c..997b8ce93d6 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -298,6 +298,7 @@ static int my_strnxfrm_big5(CHARSET_INFO *cs __attribute__((unused)), const uchar * src, uint srclen) { uint16 e; + uint dstlen= len; len = srclen; while (len--) @@ -312,7 +313,9 @@ static int my_strnxfrm_big5(CHARSET_INFO *cs __attribute__((unused)), } else *dest++ = sort_order_big5[(uchar) *src++]; } - return srclen; + if (dstlen > srclen) + bfill(dest, dstlen - srclen, ' '); + return dstlen; } #if 0 diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 7d17f62c8d0..95c52512243 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -341,13 +341,27 @@ static int my_wildcmp_bin(CHARSET_INFO *cs, static int my_strnxfrm_bin(CHARSET_INFO *cs __attribute__((unused)), - uchar * dest, uint len, - const uchar *src, - uint srclen __attribute__((unused))) + uchar * dest, uint dstlen, + const uchar *src, uint srclen) { if (dest != src) - memcpy(dest,src,len= min(len,srclen)); - return len; + memcpy(dest, src, min(dstlen,srclen)); + if (dstlen > srclen) + bfill(dest + srclen, dstlen - srclen, 0); + return dstlen; +} + + +static +int my_strnxfrm_8bit_bin(CHARSET_INFO *cs __attribute__((unused)), + uchar * dest, uint dstlen, + const uchar *src, uint srclen) +{ + if (dest != src) + memcpy(dest, src, min(dstlen,srclen)); + if (dstlen > srclen) + bfill(dest + srclen, dstlen - srclen, ' '); + return dstlen; } @@ -417,7 +431,7 @@ MY_COLLATION_HANDLER my_collation_8bit_bin_handler = NULL, /* init */ my_strnncoll_8bit_bin, my_strnncollsp_8bit_bin, - my_strnxfrm_bin, + my_strnxfrm_8bit_bin, my_like_range_simple, my_wildcmp_bin, my_strcasecmp_bin, diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index 2177a18504e..5725e81b15e 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -296,16 +296,18 @@ static int my_strnxfrm_czech(CHARSET_INFO *cs __attribute__((unused)), int value; const uchar * p, * store; int pass = 0; - int totlen = 0; + uint totlen = 0; p = src; store = src; do { NEXT_CMP_VALUE(src, p, store, pass, value, (int)srclen); - ADD_TO_RESULT(dest, (int)len, totlen, value); + ADD_TO_RESULT(dest, len, totlen, value); } while (value); - return totlen; + if (len > totlen) + bfill(dest + totlen, len - totlen, ' '); + return len; } #undef IS_END diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 0be56e8d946..731ad58a2fb 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -2659,6 +2659,7 @@ static int my_strnxfrm_gbk(CHARSET_INFO *cs __attribute__((unused)), const uchar * src, uint srclen) { uint16 e; + uint dstlen= len; len = srclen; while (len--) @@ -2673,7 +2674,9 @@ static int my_strnxfrm_gbk(CHARSET_INFO *cs __attribute__((unused)), } else *dest++ = sort_order_gbk[(uchar) *src++]; } - return srclen; + if (dstlen > srclen) + bfill(dest, dstlen - srclen, ' '); + return dstlen; } diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index 5f1850b7772..32d9a227c2f 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -637,7 +637,6 @@ static int my_strnxfrm_latin1_de(CHARSET_INFO *cs __attribute__((unused)), uchar * dest, uint len, const uchar * src, uint srclen) { - const uchar *dest_orig = dest; const uchar *de = dest + len; const uchar *se = src + srclen; for ( ; src < se && dest < de ; src++) @@ -647,7 +646,9 @@ static int my_strnxfrm_latin1_de(CHARSET_INFO *cs __attribute__((unused)), if ((chr=combo2map[*src]) && dest < de) *dest++=chr; } - return (int) (dest - dest_orig); + if (dest < de) + bfill(dest, de - dest, ' '); + return (int) len; } diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 3cdf7f460cd..bf69fe683ae 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -412,13 +412,14 @@ static int my_strnncollsp_mb_bin(CHARSET_INFO * cs __attribute__((unused)), static int my_strnxfrm_mb_bin(CHARSET_INFO *cs __attribute__((unused)), - uchar * dest, uint len, - const uchar *src, - uint srclen __attribute__((unused))) + uchar * dest, uint dstlen, + const uchar *src, uint srclen) { if (dest != src) - memcpy(dest,src,len= min(len,srclen)); - return len; + memcpy(dest, src, min(dstlen, srclen)); + if (dstlen > srclen) + bfill(dest + srclen, dstlen - srclen, ' '); + return dstlen; } diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index a019665a235..5bfa9e52595 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -21,27 +21,68 @@ #include "stdarg.h" +/* + Converts a string into its sort key. + + SYNOPSIS + my_strnxfrm_xxx() + + IMPLEMENTATION + + The my_strxfrm_xxx() function transforms a string pointed to by + 'src' with length 'srclen' according to the charset+collation + pair 'cs' and copies the result key into 'dest'. + + Comparing two strings using memcmp() after my_strnxfrm_xxx() + is equal to comparing two original strings with my_strnncollsp_xxx(). + + Not more than 'dstlen' bytes are written into 'dst'. + To garantee that the whole string is transformed, 'dstlen' must be + at least srclen*cs->strnxfrm_multiply bytes long. Otherwise, + consequent memcmp() may return a non-accurate result. + + If the source string is too short to fill whole 'dstlen' bytes, + then the 'dest' string is padded up to 'dstlen', ensuring that: + + "a" == "a " + "a\0" < "a" + "a\0" < "a " + + my_strnxfrm_simple() is implemented for 8bit charsets and + simple collations with one-to-one string->key transformation. + + See also implementations for various charsets/collations in + other ctype-xxx.c files. + + RETURN + + Target len 'dstlen'. + +*/ + int my_strnxfrm_simple(CHARSET_INFO * cs, uchar *dest, uint len, const uchar *src, uint srclen) { uchar *map= cs->sort_order; + uint dstlen= len; set_if_smaller(len, srclen); if (dest != src) { const uchar *end; for ( end=src+len; src < end ; ) *dest++= map[*src++]; - return len; } else { const uchar *end; for ( end=dest+len; dest < end ; dest++) *dest= (char) map[(uchar) *dest]; - return len; } + if (dstlen > len) + bfill(dest, dstlen - len, ' '); + return dstlen; } int my_strnncoll_simple(CHARSET_INFO * cs, const uchar *s, uint slen, diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index a8b5394f8c5..c0b33a13cdd 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -291,7 +291,9 @@ static int my_strnxfrm_sjis(CHARSET_INFO *cs __attribute__((unused)), else *dest++ = sort_order_sjis[(uchar)*src++]; } - return srclen; + if (len > srclen) + bfill(dest, len - srclen, ' '); + return len; } diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 5d37aa965d9..3a43c556ac8 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -631,9 +631,13 @@ int my_strnxfrm_tis620(CHARSET_INFO *cs __attribute__((unused)), uchar * dest, uint len, const uchar * src, uint srclen) { + uint dstlen= len; len= (uint) (strmake((char*) dest, (char*) src, min(len, srclen)) - (char*) dest); - return (int) thai2sortable(dest, len); + len= thai2sortable(dest, len); + if (dstlen > len) + bfill(dest + len, dstlen - len, ' '); + return dstlen; } diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index 89c876ad10c..4992ef2dcd1 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -7214,8 +7214,7 @@ static int my_strnxfrm_uca(CHARSET_INFO *cs, uchar *dst, uint dstlen, const uchar *src, uint srclen) { - uchar *de = dst + dstlen; - const uchar *dst_orig = dst; + uchar *de = dst + (dstlen & (uint) ~1); // add even length for easier code int s_res; my_uca_scanner scanner; scanner_handler->init(&scanner, cs, src, srclen); @@ -7226,8 +7225,17 @@ static int my_strnxfrm_uca(CHARSET_INFO *cs, dst[1]= s_res & 0xFF; dst+= 2; } - for ( ; dst < de; *dst++='\0'); - return dst - dst_orig; + s_res= cs->sort_order_big[0][0x20 * cs->sort_order[0]]; + while (dst < de) + { + dst[0]= s_res >> 8; + dst[1]= s_res & 0xFF; + dst+= 2; + } + if (dstlen & 1) // if odd number then fill the last char + *dst= '\0'; + + return dstlen; } diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 403d31aa15b..936e2b6fdce 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -347,7 +347,6 @@ static int my_strnxfrm_ucs2(CHARSET_INFO *cs, int plane; uchar *de = dst + dstlen; const uchar *se = src + srclen; - const uchar *dst_orig = dst; while( src < se && dst < de ) { @@ -367,7 +366,9 @@ static int my_strnxfrm_ucs2(CHARSET_INFO *cs, } dst+=res; } - return dst - dst_orig; + if (dst < de) + cs->cset->fill(cs, dst, de - dst, ' '); + return dstlen; } @@ -1377,7 +1378,9 @@ int my_strnxfrm_ucs2_bin(CHARSET_INFO *cs __attribute__((unused)), { if (dst != src) memcpy(dst,src,srclen= min(dstlen,srclen)); - return srclen; + if (dstlen > srclen) + cs->cset->fill(cs, dst + srclen, dstlen - srclen, ' '); + return dstlen; } diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index ce9346eb475..502d0ec285e 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -2228,7 +2228,6 @@ static int my_strnxfrm_utf8(CHARSET_INFO *cs, int plane; uchar *de = dst + dstlen; const uchar *se = src + srclen; - const uchar *dst_orig = dst; while( src < se && dst < de ) { @@ -2248,7 +2247,9 @@ static int my_strnxfrm_utf8(CHARSET_INFO *cs, } dst+=res; } - return dst - dst_orig; + if (dst < de) + bfill(dst, de - dst, ' '); + return dstlen; } static int my_ismbchar_utf8(CHARSET_INFO *cs,const char *b, const char *e) diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 4ada3d47bf5..98389a9a5a4 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -503,7 +503,9 @@ static int my_strnxfrm_win1250ch(CHARSET_INFO * cs __attribute__((unused)), dest[totlen] = value; totlen++; } while (value) ; - return totlen; + if (len > totlen) + bfill(dest + totlen, len - totlen, ' '); + return len; } #undef IS_END -- cgit v1.2.1 From dfceab2f3d3eb8f7c1c98013da8a6127e4006192 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 16:15:14 +0200 Subject: InnoDB: Detect the availability of the Mac OS X fsync() work-around at run-time, so that an executable compiled on Mac OS X 10.2 can be run on Mac OS X 10.2 (without the work-around) and Mac OS X 10.3 and later with the work-aroud enabled. innobase/include/srv0start.h: Mac OS X: Add srv_have_fullfsync innobase/os/os0file.c: os_file_flush(): Use F_FULLFSYNC on Mac OS X 10.3, but not on 10.2 innobase/srv/srv0start.c: innobase_start_or_create_for_mysql(): When compiled on OS X 10.2, detect if the binary is running on OS X 10.3 or later, and set srv_have_fullfsync accordingly. --- innobase/include/srv0start.h | 4 ++++ innobase/os/os0file.c | 24 ++++++++++++++++++------ innobase/srv/srv0start.c | 27 +++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/innobase/include/srv0start.h b/innobase/include/srv0start.h index 75af1a212b4..8df0f97c4ff 100644 --- a/innobase/include/srv0start.h +++ b/innobase/include/srv0start.h @@ -75,6 +75,10 @@ extern dulint srv_start_lsn; void set_panic_flag_for_netware(void); #endif +#ifdef HAVE_DARWIN_THREADS +extern ibool srv_have_fullfsync; +#endif + extern ulint srv_sizeof_trx_t_in_ha_innodb_cc; extern ibool srv_is_being_started; diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 60760d1f8b8..6fb27346a37 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -1763,19 +1763,31 @@ os_file_flush( #else int ret; -#if defined(HAVE_DARWIN_THREADS) && defined(F_FULLFSYNC) +#if defined(HAVE_DARWIN_THREADS) +# ifndef F_FULLFSYNC + /* The following definition is from the Mac OS X 10.3 */ +# define F_FULLFSYNC 51 /* fsync + ask the drive to flush to the media */ +# elif F_FULLFSYNC != 51 +# error "F_FULLFSYNC != 51: ABI incompatibility with Mac OS X 10.3" +# endif /* Apple has disabled fsync() for internal disk drives in OS X. That caused corruption for a user when he tested a power outage. Let us in OS X use a nonstandard flush method recommended by an Apple engineer. */ - ret = fcntl(file, F_FULLFSYNC, NULL); - - if (ret) { - /* If we are not on a file system that supports this, then - fall back to a plain fsync. */ + if (!srv_have_fullfsync) { + /* If we are not on an operating system that supports this, + then fall back to a plain fsync. */ ret = fsync(file); + } else { + ret = fcntl(file, F_FULLFSYNC, NULL); + + if (ret) { + /* If we are not on a file system that supports this, + then fall back to a plain fsync. */ + ret = fsync(file); + } } #elif HAVE_FDATASYNC ret = fdatasync(file); diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 7a61a885ef9..fe05f07df21 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -61,6 +61,11 @@ dulint srv_start_lsn; /* Log sequence number at shutdown */ dulint srv_shutdown_lsn; +#ifdef HAVE_DARWIN_THREADS +# include +ibool srv_have_fullfsync = FALSE; +#endif + ibool srv_start_raw_disk_in_use = FALSE; static ibool srv_start_has_been_called = FALSE; @@ -935,6 +940,28 @@ innobase_start_or_create_for_mysql(void) ulint i; ibool srv_file_per_table_original_value = srv_file_per_table; mtr_t mtr; +#ifdef HAVE_DARWIN_THREADS +# ifdef F_FULLFSYNC + /* This executable has been compiled on Mac OS X 10.3 or later. + Assume that F_FULLFSYNC is available at run-time. */ + srv_have_fullfsync = TRUE; +# else /* F_FULLFSYNC */ + /* This executable has been compiled on Mac OS X 10.2 + or earlier. Determine if the executable is running + on Mac OS X 10.3 or later. */ + struct utsname utsname; + if (uname(&utsname)) { + fputs("InnoDB: cannot determine Mac OS X version!\n", stderr); + } else { + srv_have_fullfsync = strcmp(utsname.release, "7.") >= 0; + } + if (!srv_have_fullfsync) { + fputs( +"InnoDB: On Mac OS X, fsync() may be broken on internal drives,\n" +"InnoDB: making transactions unsafe!\n", stderr); + } +# endif /* F_FULLFSYNC */ +#endif /* HAVE_DARWIN_THREADS */ if (sizeof(ulint) != sizeof(void*)) { fprintf(stderr, -- cgit v1.2.1 From 3a1d782e0479deecc082ce565cd8e1a2b10f459c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 19:20:49 +0200 Subject: ha_innodb.cc: Fix a theoretical hang over the adaptive hash latch in InnoDB if one runs INSERT ... SELECT ... (binlog not enabled), or a multi-table UPDATE or DELETE, and only the read tables are InnoDB type, the rest are MyISAM; this also fixes bug #7879 for InnoDB type tables sql/ha_innodb.cc: Fix a theoretical hang over the adaptive hash latch in InnoDB if one runs INSERT ... SELECT ... (binlog not enabled), or a multi-table UPDATE or DELETE, and only the read tables are InnoDB type, the rest are MyISAM; this also fixes bug #7879 for InnoDB type tables --- sql/ha_innodb.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 54d93783481..2e441b4f085 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4927,7 +4927,9 @@ ha_innobase::store_lock( if ((lock_type == TL_READ && thd->in_lock_tables) || (lock_type == TL_READ_HIGH_PRIORITY && thd->in_lock_tables) || lock_type == TL_READ_WITH_SHARED_LOCKS || - lock_type == TL_READ_NO_INSERT) { + lock_type == TL_READ_NO_INSERT || + thd->lex.sql_command != SQLCOM_SELECT) { + /* The OR cases above are in this order: 1) MySQL is doing LOCK TABLES ... READ LOCAL, or 2) (we do not know when TL_READ_HIGH_PRIORITY is used), or @@ -4935,7 +4937,10 @@ ha_innobase::store_lock( 4) we are doing a complex SQL statement like INSERT INTO ... SELECT ... and the logical logging (MySQL binlog) requires the use of a locking read, or - MySQL is doing LOCK TABLES ... READ. */ + MySQL is doing LOCK TABLES ... READ. + 5) we let InnoDB do locking reads for all SQL statements that + are not simple SELECTs; note that select_lock_type in this + case may get strengthened in ::external_lock() to LOCK_X. */ prebuilt->select_lock_type = LOCK_S; prebuilt->stored_select_lock_type = LOCK_S; -- cgit v1.2.1 From 0ad954050828b6212559baaa01a11d869b0df30a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 18:22:35 +0100 Subject: Add test cases to verify that SHOW CREATE TABLE always outputs the key algorithm for keys where they were explicitly specified. mysql-test/r/show_check.result: Add results mysql-test/t/show_check.test: Add tests for preservation of key algorithm in SHOW CREATE TABLE output --- mysql-test/r/show_check.result | 70 ++++++++++++++++++++++++++++++++++++++++++ mysql-test/t/show_check.test | 32 +++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 0afe45eb5e5..37531f05f43 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -405,3 +405,73 @@ where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3'; delete from mysql.db where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3'; flush privileges; +CREATE TABLE t1 (i int, KEY (i)) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` (`i`) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING HASH (i)) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` TYPE HASH (`i`) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` TYPE BTREE (`i`) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` TYPE BTREE (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +ALTER TABLE t1 ENGINE=MEMORY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` (`i`) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` TYPE BTREE (`i`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +ALTER TABLE t1 ENGINE=MEMORY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL, + KEY `i` TYPE BTREE (`i`) +) ENGINE=HEAP DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 7788215dd27..cd8d4dba6ab 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -321,3 +321,35 @@ flush privileges; #--replace_column 7 # 8 # 9 # #show table status from `ä` LIKE 'ä'; #drop database `ä`; + +# Test that USING is always shown in SHOW CREATE TABLE when it was +# specified during table creation, but not otherwise. (Bug #7235) +CREATE TABLE t1 (i int, KEY (i)) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING HASH (i)) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MEMORY; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +DROP TABLE t1; +# Test that when an index is created with the default key algorithm and +# altered to another storage engine, it gets the default key algorithm +# for that storage engine, but when it is specified, the specified type is +# preserved. +CREATE TABLE t1 (i int, KEY (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +ALTER TABLE t1 ENGINE=MEMORY; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (i int, KEY USING BTREE (i)) ENGINE=MyISAM; +SHOW CREATE TABLE t1; +ALTER TABLE t1 ENGINE=MEMORY; +SHOW CREATE TABLE t1; +DROP TABLE t1; -- cgit v1.2.1 From e878173eec8654d735aac8eae41fbfda18f58166 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 20:08:28 +0200 Subject: ha_innodb.cc: Merge from 4.0: Fix a theoretical hang over the adaptive hash latch in InnoDB if one runs INSERT ... SELECT ... (binlog not enabled), or a multi-table UPDATE or DELETE, and only the read tables are InnoDB type, the rest are MyISAM; this also fixes bug #7879 for InnoDB type tables sql/ha_innodb.cc: Merge from 4.0: Fix a theoretical hang over the adaptive hash latch in InnoDB if one runs INSERT ... SELECT ... (binlog not enabled), or a multi-table UPDATE or DELETE, and only the read tables are InnoDB type, the rest are MyISAM; this also fixes bug #7879 for InnoDB type tables --- sql/ha_innodb.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 14b143ca04b..4c13902c31e 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -5265,7 +5265,9 @@ ha_innobase::store_lock( if ((lock_type == TL_READ && thd->in_lock_tables) || (lock_type == TL_READ_HIGH_PRIORITY && thd->in_lock_tables) || lock_type == TL_READ_WITH_SHARED_LOCKS || - lock_type == TL_READ_NO_INSERT) { + lock_type == TL_READ_NO_INSERT || + thd->lex->sql_command != SQLCOM_SELECT) { + /* The OR cases above are in this order: 1) MySQL is doing LOCK TABLES ... READ LOCAL, or 2) (we do not know when TL_READ_HIGH_PRIORITY is used), or @@ -5273,7 +5275,10 @@ ha_innobase::store_lock( 4) we are doing a complex SQL statement like INSERT INTO ... SELECT ... and the logical logging (MySQL binlog) requires the use of a locking read, or - MySQL is doing LOCK TABLES ... READ. */ + MySQL is doing LOCK TABLES ... READ. + 5) we let InnoDB do locking reads for all SQL statements that + are not simple SELECTs; note that select_lock_type in this + case may get strengthened in ::external_lock() to LOCK_X. */ prebuilt->select_lock_type = LOCK_S; prebuilt->stored_select_lock_type = LOCK_S; -- cgit v1.2.1 From 0898b40c9e42e87d0aa37b6384ad063ef882eeb0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 13 Jan 2005 11:58:10 -0800 Subject: Fix mysql_install_db to look for libexecdir relative to basedir when it has been specified. (Bug #7347) scripts/mysql_install_db.sh: When basedir is specified, look for libexecdir relative to that --- scripts/mysql_install_db.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index f9f3160d220..8d47d67792a 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -98,9 +98,9 @@ else if test -x "$basedir/libexec/mysqld" then execdir="$basedir/libexec" -elif test -x "@libexecdir@/mysqld" +elif test -x "$basedir/sbin/mysqld" then - execdir="@libexecdir@" + execdir="$basedir/sbin" else execdir="$basedir/bin" fi -- cgit v1.2.1 From 4c43672a6ec530f80079ba033bb44bd9a4b92f69 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 00:09:15 +0200 Subject: Fix bug in INSERT DELAYED with prepared statements The bug was that if you have two TL_WRITE_DELAYED at the same time, mi_lock_databases() could be done in the wrong order and we could write the wrong header to the MyISAM index file. sql/mysql_priv.h: Fix bug in insert delayed with prepared statements sql/sql_base.cc: Fix bug in insert delayed with prepared statements sql/sql_prepare.cc: Fix bug in insert delayed with prepared statements The bug was that if you have two TL_WRITE_DELAYED at the same time, mi_lock_databases() could be done in the wrong order and we could write the wrong header to the MyISAM index file. --- sql/mysql_priv.h | 1 + sql/sql_base.cc | 28 ++++++++++++++++++++++++++++ sql/sql_prepare.cc | 6 +++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 204b319138e..4b785aafc5f 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -725,6 +725,7 @@ void wait_for_refresh(THD *thd); int open_tables(THD *thd, TABLE_LIST *tables, uint *counter); int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables); int open_and_lock_tables(THD *thd,TABLE_LIST *tables); +int open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables); void relink_tables_for_derived(THD *thd); int lock_tables(THD *thd, TABLE_LIST *tables, uint counter); TABLE *open_temporary_table(THD *thd, const char *path, const char *db, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 2f2d9b290ac..263c68a82b7 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1702,6 +1702,34 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables) } +/* + Open all tables in list and process derived tables + + SYNOPSIS + open_normal_and_derived_tables + thd - thread handler + tables - list of tables for open&locking + + RETURN + FALSE - ok + TRUE - error + + NOTE + This is to be used on prepare stage when you don't read any + data from the tables. +*/ + +int open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables) +{ + uint counter; + DBUG_ENTER("open_normal_and_derived_tables"); + if (open_tables(thd, tables, &counter)) + DBUG_RETURN(-1); /* purecov: inspected */ + relink_tables_for_derived(thd); + DBUG_RETURN(mysql_handle_derived(thd->lex)); +} + + /* Let us propagate pointers to open tables from global table list to table lists in particular selects if needed. diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index ecf01824755..1dc46aef4da 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -897,8 +897,12 @@ static int mysql_test_insert(Prepared_statement *stmt, /* open temporary memory pool for temporary data allocated by derived tables & preparation procedure + Note that this is done without locks (should not be needed as we will not + access any data here) + If we would use locks, then we have to ensure we are not using + TL_WRITE_DELAYED as having two such locks can cause table corruption. */ - if (open_and_lock_tables(thd, table_list)) + if (open_normal_and_derived_tables(thd, table_list)) { DBUG_RETURN(-1); } -- cgit v1.2.1 From 4e2523401218b6f68940a17d28ab5bf5ddfa0d42 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 01:59:03 +0300 Subject: fix C++ comments in C file (fixed in 5.0 already) strings/ctype-uca.c: fix C++ comments in C file --- strings/ctype-uca.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index 4992ef2dcd1..452ca263433 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -7214,7 +7214,7 @@ static int my_strnxfrm_uca(CHARSET_INFO *cs, uchar *dst, uint dstlen, const uchar *src, uint srclen) { - uchar *de = dst + (dstlen & (uint) ~1); // add even length for easier code + uchar *de = dst + (dstlen & (uint) ~1); /* add even length for easier code */ int s_res; my_uca_scanner scanner; scanner_handler->init(&scanner, cs, src, srclen); @@ -7232,7 +7232,7 @@ static int my_strnxfrm_uca(CHARSET_INFO *cs, dst[1]= s_res & 0xFF; dst+= 2; } - if (dstlen & 1) // if odd number then fill the last char + if (dstlen & 1) /* if odd number then fill the last char */ *dst= '\0'; return dstlen; -- cgit v1.2.1 From 217fe27b0561e880a98d0ed8e16d52da7f1b536d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 16:23:32 +0300 Subject: Backport from 5.0 --- strings/ctype-mb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index bf69fe683ae..731fc460cef 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -274,7 +274,7 @@ uint my_well_formed_len_mb(CHARSET_INFO *cs, my_wc_t wc; int mblen; - if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <0) + if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <= 0) break; b+= mblen; pos--; -- cgit v1.2.1 From 6987f2b4a3e985b497de428bff7c965a25e5e387 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 15:35:32 +0100 Subject: - make sure to enable "--without-ndb-debug" when both --debug and --with-cluster are provided. Yes, this sounds like a contradiction - enabling debugging in NBD enables code parts that may still reveal portability issues when compiled with non-gcc compilers. (request by TomasU) --- Build-tools/Do-compile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index 1e7041e8f7a..b431f9fc1c5 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -264,7 +264,8 @@ if ($opt_stage <= 1) $opt_config_options.= " --with-berkeley-db" if ($opt_bdb); $opt_config_options.= " --with-zlib-dir=bundled" if ($opt_bundled_zlib); $opt_config_options.= " --with-client-ldflags=-all-static" if ($opt_static_client); - $opt_config_options.= " --with-debug" if ($opt_with_debug); + $opt_config_options.= " --with-debug" if ($opt_with_debug); + $opt_config_options.= " --without-ndb-debug" if ($opt_with_debug && $opt_with_cluster); $opt_config_options.= " --with-libwrap" if ($opt_libwrap); $opt_config_options.= " --with-low-memory" if ($opt_with_low_memory); $opt_config_options.= " --with-mysqld-ldflags=-all-static" if ($opt_static_server); -- cgit v1.2.1 From 973800f387515669ccda63539155f25bda9715ec Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 16:14:50 +0100 Subject: bumped up ndb version compatible with 4.1.9 configure.in: bumped up ndb version --- configure.in | 2 +- ndb/src/common/util/version.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 45ca009123e..9f89c635e7f 100644 --- a/configure.in +++ b/configure.in @@ -16,7 +16,7 @@ SHARED_LIB_VERSION=14:0:0 # ndb version NDB_VERSION_MAJOR=4 NDB_VERSION_MINOR=1 -NDB_VERSION_BUILD=9 +NDB_VERSION_BUILD=10 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? diff --git a/ndb/src/common/util/version.c b/ndb/src/common/util/version.c index 9bc3488b078..8cc6de0fc24 100644 --- a/ndb/src/common/util/version.c +++ b/ndb/src/common/util/version.c @@ -90,6 +90,7 @@ void ndbSetOwnVersion() {} #ifndef TEST_VERSION struct NdbUpGradeCompatible ndbCompatibleTable_full[] = { + { MAKE_VERSION(4,1,10), MAKE_VERSION(4,1,9), UG_Exact }, { MAKE_VERSION(4,1,9), MAKE_VERSION(4,1,8), UG_Exact }, { MAKE_VERSION(3,5,2), MAKE_VERSION(3,5,1), UG_Exact }, { 0, 0, UG_Null } -- cgit v1.2.1 From 95a9acabeaf5f8d318e3d1710e1efc5eeada0f7a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 18:20:03 +0100 Subject: - replaced obsoleted "BuildPrereq" with "BuildRequires" in the RPM spec file support-files/mysql.spec.sh: - replaced obsoleted "BuildPrereq" with "BuildRequires" instead --- support-files/mysql.spec.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 5afddee609b..99280385965 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -27,7 +27,7 @@ Packager: Lenz Grimmer Vendor: MySQL AB Requires: fileutils sh-utils Provides: msqlormysql MySQL-server mysql -BuildPrereq: ncurses-devel +BuildRequires: ncurses-devel Obsoletes: mysql # Think about what you use here since the first step is to @@ -607,6 +607,10 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Fri Jan 14 2005 Lenz Grimmer + +- replaced obsoleted "BuildPrereq" with "BuildRequires" instead + * Thu Dec 31 2004 Lenz Grimmer - enabled the "Archive" storage engine for the max binary -- cgit v1.2.1 From 9d8c623cfb418609998217f54f95bf3684f14ea2 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Jan 2005 19:49:45 +0100 Subject: limit HEAP table size with max_heap_table_size, better estimation for mem_per_row heap/hp_create.c: limit HEAP table size with max_heap_table_size heap/hp_write.c: limit HEAP table size with max_heap_table_size include/heap.h: limit HEAP table size with max_heap_table_size sql/ha_heap.cc: limit HEAP table size with max_heap_table_size better estimation for mem_per_row --- heap/hp_create.c | 7 ++++--- heap/hp_write.c | 3 ++- include/heap.h | 7 ++++--- sql/ha_heap.cc | 24 ++++++++++++++++++------ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/heap/hp_create.c b/heap/hp_create.c index fdfe78a1e09..af32fefea1b 100644 --- a/heap/hp_create.c +++ b/heap/hp_create.c @@ -123,15 +123,15 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, keyseg->flag= 0; keyseg->null_bit= 0; keyseg++; - - init_tree(&keyinfo->rb_tree, 0, 0, sizeof(byte*), + + init_tree(&keyinfo->rb_tree, 0, 0, sizeof(byte*), (qsort_cmp2)keys_compare, 1, NULL, NULL); keyinfo->delete_key= hp_rb_delete_key; keyinfo->write_key= hp_rb_write_key; } else { - init_block(&keyinfo->block, sizeof(HASH_INFO), min_records, + init_block(&keyinfo->block, sizeof(HASH_INFO), min_records, max_records); keyinfo->delete_key= hp_delete_key; keyinfo->write_key= hp_write_key; @@ -140,6 +140,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, } share->min_records= min_records; share->max_records= max_records; + share->max_table_size= create_info->max_table_size; share->data_length= share->index_length= 0; share->reclength= reclength; share->blength= 1; diff --git a/heap/hp_write.c b/heap/hp_write.c index 43cee67b39c..808fe6608b1 100644 --- a/heap/hp_write.c +++ b/heap/hp_write.c @@ -143,7 +143,8 @@ static byte *next_free_record_pos(HP_SHARE *info) } if (!(block_pos=(info->records % info->block.records_in_block))) { - if (info->records > info->max_records && info->max_records) + if ((info->records > info->max_records && info->max_records) || + (info->data_length + info->index_length >= info->max_table_size)) { my_errno=HA_ERR_RECORD_FILE_FULL; DBUG_RETURN(NULL); diff --git a/include/heap.h b/include/heap.h index 5e83a6e2cb5..ac2b38d1f2d 100644 --- a/include/heap.h +++ b/include/heap.h @@ -125,8 +125,8 @@ typedef struct st_hp_keydef /* Key definition with open */ TREE rb_tree; int (*write_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo, const byte *record, byte *recpos); - int (*delete_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo, - const byte *record, byte *recpos, int flag); + int (*delete_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo, + const byte *record, byte *recpos, int flag); uint (*get_key_length)(struct st_hp_keydef *keydef, const byte *key); } HP_KEYDEF; @@ -135,7 +135,7 @@ typedef struct st_heap_share HP_BLOCK block; HP_KEYDEF *keydef; ulong min_records,max_records; /* Params to open */ - ulong data_length,index_length; + ulong data_length,index_length,max_table_size; uint records; /* records */ uint blength; /* records rounded up to 2^n */ uint deleted; /* Deleted records in database */ @@ -185,6 +185,7 @@ typedef struct st_heap_create_info { uint auto_key; uint auto_key_type; + ulong max_table_size; ulonglong auto_increment; } HP_CREATE_INFO; diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index dbcf7bc9197..96c19ce0705 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -460,12 +460,24 @@ int ha_heap::create(const char *name, TABLE *table_arg, KEY_PART_INFO *key_part= pos->key_part; KEY_PART_INFO *key_part_end= key_part + pos->key_parts; - mem_per_row+= (pos->key_length + (sizeof(char*) * 2)); - keydef[key].keysegs= (uint) pos->key_parts; keydef[key].flag= (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL)); keydef[key].seg= seg; - keydef[key].algorithm= ((pos->algorithm == HA_KEY_ALG_UNDEF) ? + + switch (pos->algorithm) { + case HA_KEY_ALG_UNDEF: + case HA_KEY_ALG_HASH: + keydef[key].algorithm= HA_KEY_ALG_HASH; + mem_per_row+= sizeof(char*) * 2; // = sizeof(HASH_INFO) + break; + case HA_KEY_ALG_BTREE: + keydef[key].algorithm= HA_KEY_ALG_BTREE; + mem_per_row+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*); + break; + default: + DBUG_ASSERT(0); // cannot happen + } + keydef[key].algorithm= ((pos->algorithm == HA_KEY_ALG_UNDEF) ? HA_KEY_ALG_HASH : pos->algorithm); for (; key_part != key_part_end; key_part++, seg++) @@ -501,17 +513,17 @@ int ha_heap::create(const char *name, TABLE *table_arg, } } mem_per_row+= MY_ALIGN(table_arg->reclength + 1, sizeof(char*)); - max_rows = (ha_rows) (current_thd->variables.max_heap_table_size / - mem_per_row); HP_CREATE_INFO hp_create_info; hp_create_info.auto_key= auto_key; hp_create_info.auto_key_type= auto_key_type; hp_create_info.auto_increment= (create_info->auto_increment_value ? create_info->auto_increment_value - 1 : 0); + hp_create_info.max_table_size=current_thd->variables.max_heap_table_size; + max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row); error= heap_create(fn_format(buff,name,"","",4+2), table_arg->keys,keydef, table_arg->reclength, (ulong) ((table_arg->max_rows < max_rows && - table_arg->max_rows) ? + table_arg->max_rows) ? table_arg->max_rows : max_rows), (ulong) table_arg->min_rows, &hp_create_info); my_free((gptr) keydef, MYF(0)); -- cgit v1.2.1 From 7a9e9fb0b45f9b085eddffc10dbce8ab371ff83b Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 15 Jan 2005 03:47:06 +0200 Subject: Fixed possible access to unintialized memory in filesort when using many buffers include/my_sys.h: Added function to call if IO_CACHE is moved mysys/mf_iocache.c: Added function to call if IO_CACHE is moved sql/filesort.cc: Tell that io_cache is moved --- include/my_sys.h | 1 + mysys/mf_iocache.c | 49 +++++++++++++++++++++++++++++++++++-------------- sql/filesort.cc | 2 ++ 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index 9e43889d0e0..0fdb8d640e7 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -671,6 +671,7 @@ extern int init_io_cache(IO_CACHE *info,File file,uint cachesize, extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type, my_off_t seek_offset,pbool use_async_io, pbool clear_cache); +extern void setup_io_cache(IO_CACHE* info); extern int _my_b_read(IO_CACHE *info,byte *Buffer,uint Count); #ifdef THREAD extern int _my_b_read_r(IO_CACHE *info,byte *Buffer,uint Count); diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 8fb93dc4780..a7937da0cc2 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -71,9 +71,40 @@ static void my_aiowait(my_aio_result *result); #define IO_ROUND_UP(X) (((X)+IO_SIZE-1) & ~(IO_SIZE-1)) #define IO_ROUND_DN(X) ( (X) & ~(IO_SIZE-1)) + +/* + Setup internal pointers inside IO_CACHE + + SYNOPSIS + setup_io_cache() + info IO_CACHE handler + + NOTES + This is called on automaticly on init or reinit of IO_CACHE + It must be called externally if one moves or copies an IO_CACHE + object. +*/ + +void setup_io_cache(IO_CACHE* info) +{ + /* Ensure that my_b_tell() and my_b_bytes_in_cache works */ + if (info->type == WRITE_CACHE) + { + info->current_pos= &info->write_pos; + info->current_end= &info->write_end; + } + else + { + info->current_pos= &info->read_pos; + info->current_end= &info->read_end; + } +} + + static void -init_functions(IO_CACHE* info, enum cache_type type) +init_functions(IO_CACHE* info) { + enum cache_type type= info->type; switch (type) { case READ_NET: /* @@ -97,17 +128,7 @@ init_functions(IO_CACHE* info, enum cache_type type) info->write_function = _my_b_write; } - /* Ensure that my_b_tell() and my_b_bytes_in_cache works */ - if (type == WRITE_CACHE) - { - info->current_pos= &info->write_pos; - info->current_end= &info->write_end; - } - else - { - info->current_pos= &info->read_pos; - info->current_end= &info->read_end; - } + setup_io_cache(info); } /* @@ -211,7 +232,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, /* End_of_file may be changed by user later */ info->end_of_file= end_of_file; info->error=0; - init_functions(info,type); + init_functions(info); #ifdef HAVE_AIOWAIT if (use_async_io && ! my_disable_async_io) { @@ -333,7 +354,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type, } info->type=type; info->error=0; - init_functions(info,type); + init_functions(info); #ifdef HAVE_AIOWAIT if (use_async_io && ! my_disable_async_io && diff --git a/sql/filesort.cc b/sql/filesort.cc index ae6895b26b9..fe42f391007 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -680,6 +680,8 @@ int merge_many_buff(SORTPARAM *param, uchar *sort_buffer, if (flush_io_cache(to_file)) break; /* purecov: inspected */ temp=from_file; from_file=to_file; to_file=temp; + setup_io_cache(from_file); + setup_io_cache(to_file); *maxbuffer= (uint) (lastbuff-buffpek)-1; } close_cached_file(to_file); // This holds old result -- cgit v1.2.1 From 401e5f05456e627c007f42fb7309f8bd5ff6dfb6 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 15 Jan 2005 01:05:00 -0800 Subject: func_gconcat.result, func_gconcat.test: Added a test case for bug #7769. item_sum.h: Fixed bug #7769: a crash for queries with group_concat and having when the query table was empty. The bug was due an unsafe dereferencing. sql/item_sum.h: Fixed bug #7769: a crash for queries with group_concat and having when the query table was empty. The bug was due an unsafe dereferencing. mysql-test/t/func_gconcat.test: Added a test case for bug #7769. mysql-test/r/func_gconcat.result: Added a test case for bug #7769. --- mysql-test/r/func_gconcat.result | 5 +++++ mysql-test/t/func_gconcat.test | 7 +++++++ sql/item_sum.h | 5 +++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index aa202823c77..390b33fdddc 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -457,3 +457,8 @@ group_concat(distinct b order by b) Warnings: Warning 1260 2 line(s) were cut by GROUP_CONCAT() drop table t1; +CREATE TABLE t1 (id int); +SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL; +gc +NULL +DROP TABLE t1; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index e0737a42221..6a91a7ac9c7 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -277,3 +277,10 @@ select group_concat(b order by b) from t1 group by a; select group_concat(distinct b order by b) from t1 group by a; drop table t1; + +# +# bug #7769: group_concat returning null is checked in having +# +CREATE TABLE t1 (id int); +SELECT GROUP_CONCAT(id) AS gc FROM t1 HAVING gc IS NULL; +DROP TABLE t1; diff --git a/sql/item_sum.h b/sql/item_sum.h index cec611b8854..d1e82387944 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -739,9 +739,10 @@ class Item_func_group_concat : public Item_sum String *res; char *end_ptr; int error; - res= val_str(&str_value); + if (!(res= val_str(&str_value))) + return (longlong) 0; end_ptr= (char*) res->ptr()+ res->length(); - return res ? my_strtoll10(res->ptr(), &end_ptr, &error) : (longlong) 0; + return my_strtoll10(res->ptr(), &end_ptr, &error); } String* val_str(String* str); Item *copy_or_same(THD* thd); -- cgit v1.2.1