From f048032c6843548ca6c04d78b2dd77ff5eddbe9e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 14 Feb 2005 02:06:21 +0200 Subject: [PATCH 01/12] removed wrong distinct UNION detection (BUG#6565) mysql-test/r/derived.result: test of union subquery in the FROM clause with complex distinct/all mysql-test/t/derived.test: test of union subquery in the FROM clause with complex distinct/all sql/sql_derived.cc: removed wrong distinct UNION detection --- mysql-test/r/derived.result | 19 +++++++++++++++++++ mysql-test/t/derived.test | 12 ++++++++++++ sql/sql_derived.cc | 10 ++++++++-- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 61d745d0236..b4d9a921178 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -339,3 +339,22 @@ select distinct sum(b) from (select a,b from t1) y group by a; sum(b) 4 drop table t1; +create table t1(a int); +create table t2(a int); +create table t3(a int); +insert into t1 values(1),(1); +insert into t2 values(2),(2); +insert into t3 values(3),(3); +select * from t1 union distinct select * from t2 union all select * from t3; +a +1 +2 +3 +3 +select * from (select * from t1 union distinct select * from t2 union all select * from t3) X; +a +1 +2 +3 +3 +drop table t1, t2, t3; diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index 8b322746ed6..bd27e0654e0 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -224,3 +224,15 @@ select distinct sum(b) from t1 group by a; select distinct sum(b) from (select a,b from t1) y group by a; drop table t1; +# +# test of union subquery in the FROM clause with complex distinct/all (BUG#6565) +# +create table t1(a int); +create table t2(a int); +create table t3(a int); +insert into t1 values(1),(1); +insert into t2 values(2),(2); +insert into t3 values(3),(3); +select * from t1 union distinct select * from t2 union all select * from t3; +select * from (select * from t1 union distinct select * from t2 union all select * from t3) X; +drop table t1, t2, t3; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 9475ec08c96..3e627243b9f 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -132,10 +132,16 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, /* Temp table is created so that it hounours if UNION without ALL is to be processed + + As 'distinct' parameter we always pass FALSE (0), because underlying + query will control distinct condition by itself. Correct test of + distinct underlying query will be is_union && + !unit->union_distinct->next_select() (i.e. it is union and last distinct + SELECT is last SELECT of UNION). */ if (!(table= create_tmp_table(thd, &derived_result->tmp_table_param, - unit->types, (ORDER*) 0, - is_union && unit->union_distinct, 1, + unit->types, (ORDER*) 0, + FALSE, 1, (first_select->options | thd->options | TMP_TABLE_ALL_COLUMNS), HA_POS_ERROR, From 95dec435c2c2b0d2dff54adb5d46b1d766efa3b7 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 15 Feb 2005 11:02:01 +0100 Subject: [PATCH 02/12] Bug#7879: Using TL_READ_NO_INSERT locks instead of TL_READ locks when reading tables in "complex" SQL statements. If inserts happen in a table being read, the statements have no serialization order and the change can therefore not be reproduced on the slave. sql/sql_update.cc: Switching to using T_READ_NO_INSERT when the binlog is used. sql/sql_yacc.yy: Switching to using T_READ_NO_INSERT when the binlog is used. --- sql/sql_update.cc | 5 ++++- sql/sql_yacc.yy | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 4f7e34ec74f..bff360d02dc 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -479,7 +479,10 @@ int mysql_multi_update(THD *thd, else { DBUG_PRINT("info",("setting table `%s` for read-only", tl->alias)); - tl->lock_type= TL_READ; + // If we are using the binary log, we need TL_READ_NO_INSERT to get + // correct order of statements. Otherwise, we use a TL_READ lock to + // improve performance. + tl->lock_type= using_update_log ? TL_READ_NO_INSERT : TL_READ; tl->updating= 0; wants= SELECT_ACL; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 7b72c73a915..3e45e35c618 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -822,7 +822,7 @@ create_select: SELECT_SYM { LEX *lex=Lex; - lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; + lex->lock_option= using_update_log ? TL_READ_NO_INSERT : TL_READ; if (lex->sql_command == SQLCOM_INSERT) lex->sql_command= SQLCOM_INSERT_SELECT; else if (lex->sql_command == SQLCOM_REPLACE) @@ -1532,7 +1532,7 @@ select_part2: { LEX *lex=Lex; lex->lock_option=TL_READ; - mysql_init_select(lex); + mysql_init_select(lex); } select_options select_item_list select_into select_lock_type; From 97e6e780063e464b7ec1ec2b8204fb3ec3831a20 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 19 Feb 2005 19:51:47 +0200 Subject: [PATCH 03/12] fix for a bug with my_print_defaults with --defaults-extra-file= option --- extra/my_print_defaults.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c index 2ec6f8b406f..d5836cb0dc8 100644 --- a/extra/my_print_defaults.c +++ b/extra/my_print_defaults.c @@ -120,25 +120,33 @@ int main(int argc, char **argv) int count, error; char **load_default_groups, *tmp_arguments[2], **argument, **arguments; + char *defaults, *extra_defaults; MY_INIT(argv[0]); + get_defaults_files(argc, argv, &defaults, &extra_defaults); + /* ** Check out the args */ - if (get_options(&argc,&argv)) - exit(1); if (!(load_default_groups=(char**) my_malloc((argc+2)*sizeof(char*), MYF(MY_WME)))) exit(1); + if (get_options(&argc,&argv)) + exit(1); for (count=0; *argv ; argv++,count++) load_default_groups[count]= *argv; load_default_groups[count]=0; - count=1; + count=0; arguments=tmp_arguments; - arguments[0]=my_progname; - arguments[1]=0; + arguments[count++]=my_progname; + if (extra_defaults) + arguments[count++]= extra_defaults; + if (defaults) + arguments[count++]= defaults; + arguments[count]= 0; + if ((error= load_defaults(config_file, (const char **) load_default_groups, &count, &arguments))) { From e8f888a52593988b642046c162edca6e45270f57 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 21 Feb 2005 15:43:25 +0400 Subject: [PATCH 04/12] mysql.cc: bug#7571: Server & Client characterset are shown under different decriptions Switch them into the correct order. client/mysql.cc: bug#7571: Server & Client characterset are shown under different decriptions Switch them into the correct order. --- client/mysql.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 635973e946c..4004757359b 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2914,9 +2914,9 @@ com_status(String *buffer __attribute__((unused)), MYSQL_ROW cur=mysql_fetch_row(result); if (cur) { - tee_fprintf(stdout, "Server characterset:\t%s\n", cur[0] ? cur[0] : ""); + tee_fprintf(stdout, "Server characterset:\t%s\n", cur[0] ? cur[2] : ""); tee_fprintf(stdout, "Db characterset:\t%s\n", cur[3] ? cur[3] : ""); - tee_fprintf(stdout, "Client characterset:\t%s\n", cur[2] ? cur[2] : ""); + tee_fprintf(stdout, "Client characterset:\t%s\n", cur[2] ? cur[0] : ""); tee_fprintf(stdout, "Conn. characterset:\t%s\n", cur[1] ? cur[1] : ""); } mysql_free_result(result); From 65410bd0a15f42a0f0858524ba98ad92d88bcdc6 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 21 Feb 2005 17:17:30 +0400 Subject: [PATCH 05/12] ctype_utf8.result, ctype_utf8.test, ctype-utf8.c: Bugs: #8385: utf8_general_ci treats cyrillic letters I and SHORT I as the same strings/ctype-utf8.c: Bugs: #8385: utf8_general_ci treats cyrillic letters I and SHORT I as the same mysql-test/t/ctype_utf8.test: Bugs: #8385: utf8_general_ci treats cyrillic letters I and SHORT I as the same mysql-test/r/ctype_utf8.result: Bugs: #8385: utf8_general_ci treats cyrillic letters I and SHORT I as the same --- mysql-test/r/ctype_utf8.result | 3 +++ mysql-test/t/ctype_utf8.test | 5 +++++ strings/ctype-utf8.c | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 415ed33ad40..13105e2276c 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -861,3 +861,6 @@ user c one two DROP TABLE t1; +select convert(_koi8r'É' using utf8) < convert(_koi8r'Ê' using utf8); +convert(_koi8r'É' using utf8) < convert(_koi8r'Ê' using utf8) +1 diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 8e3eb71c3e5..35f2b2642be 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -693,3 +693,8 @@ INSERT INTO t1 VALUES ('one'),('two'); SELECT CHARSET('a'); SELECT user, CONCAT('<', user, '>') AS c FROM t1; DROP TABLE t1; + +# +# Bug#8385: utf8_general_ci treats Cyrillic letters I and SHORT I as the same +# +select convert(_koi8r'É' using utf8) < convert(_koi8r'Ê' using utf8); diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 486d428bf1d..69371aa38c2 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -578,7 +578,7 @@ static MY_UNICASE_INFO plane04[]={ {0x0412,0x0432,0x0412}, {0x0413,0x0433,0x0413}, {0x0414,0x0434,0x0414}, {0x0415,0x0435,0x0415}, {0x0416,0x0436,0x0416}, {0x0417,0x0437,0x0417}, - {0x0418,0x0438,0x0418}, {0x0419,0x0439,0x0418}, + {0x0418,0x0438,0x0418}, {0x0419,0x0439,0x0419}, {0x041A,0x043A,0x041A}, {0x041B,0x043B,0x041B}, {0x041C,0x043C,0x041C}, {0x041D,0x043D,0x041D}, {0x041E,0x043E,0x041E}, {0x041F,0x043F,0x041F}, @@ -594,7 +594,7 @@ static MY_UNICASE_INFO plane04[]={ {0x0412,0x0432,0x0412}, {0x0413,0x0433,0x0413}, {0x0414,0x0434,0x0414}, {0x0415,0x0435,0x0415}, {0x0416,0x0436,0x0416}, {0x0417,0x0437,0x0417}, - {0x0418,0x0438,0x0418}, {0x0419,0x0439,0x0418}, + {0x0418,0x0438,0x0418}, {0x0419,0x0439,0x0419}, {0x041A,0x043A,0x041A}, {0x041B,0x043B,0x041B}, {0x041C,0x043C,0x041C}, {0x041D,0x043D,0x041D}, {0x041E,0x043E,0x041E}, {0x041F,0x043F,0x041F}, From ae8c3e130a91687839b570f82f6694f81c21dbaf Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 21 Feb 2005 17:27:36 +0300 Subject: [PATCH 06/12] Fix -ansi -pedantic compilation failure. --- sql/sql_parse.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0dcb59f689d..a22feda7d89 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2780,8 +2780,8 @@ unsent_create_error: TABLE *table= tables->table; /* Skip first table, which is the table we are inserting in */ - tables= (TABLE_LIST *) - lex->select_lex.table_list.first= (byte*) first_local_table->next; + lex->select_lex.table_list.first= (byte*) first_local_table->next; + tables= (TABLE_LIST *) lex->select_lex.table_list.first; first_local_table->next= 0; if (!(res= mysql_prepare_insert(thd, tables, first_local_table, From aef137bc810d8c4cbe13651f9fe14c1a8ea0f2df Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 21 Feb 2005 09:15:43 -0600 Subject: [PATCH 07/12] sql_parse.cc: Fix compiler complaint. sql/sql_parse.cc: Fix compiler complaint. --- sql/sql_parse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0dcb59f689d..41705fb82e7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2781,7 +2781,7 @@ unsent_create_error: TABLE *table= tables->table; /* Skip first table, which is the table we are inserting in */ tables= (TABLE_LIST *) - lex->select_lex.table_list.first= (byte*) first_local_table->next; + (lex->select_lex.table_list.first= (byte*) first_local_table->next); first_local_table->next= 0; if (!(res= mysql_prepare_insert(thd, tables, first_local_table, From 1329f063c052e70fa71c7aaacb08e49357d108f5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Feb 2005 08:35:15 +0400 Subject: [PATCH 08/12] field.cc: optimize test_if_minus() when not UCS2 support is compiled. sql/field.cc: optimize test_if_minus() when not UCS2 support is compiled. --- sql/field.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sql/field.cc b/sql/field.cc index fa0e202d513..34c5d572526 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1776,13 +1776,23 @@ void Field_medium::sql_type(String &res) const ** long int ****************************************************************************/ - +/* + A helper function to check whether the next character + in the string "s" is MINUS SIGN. +*/ +#ifdef HAVE_CHARSET_ucs2 static bool test_if_minus(CHARSET_INFO *cs, const char *s, const char *e) { my_wc_t wc; return cs->cset->mb_wc(cs, &wc, (uchar*) s, (uchar*) e) > 0 && wc == '-'; } +#else +/* + If not UCS2 support is compiled then it is easier +*/ +#define test_if_minus(cs, s, e) (*s == '-') +#endif int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) From 14707d71c388375817b4ffb74df189bbe14a709d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Feb 2005 09:56:07 +0400 Subject: [PATCH 09/12] ctype_latin1.result, ctype_latin1.test, charset.c: Treat unknown characters straight in a query as syntax error, rather skipping it as a space character. mysys/charset.c: Treat unknown characters straight in a query as syntax error, rather skipping it as a space character. mysql-test/t/ctype_latin1.test: Treat unknown characters straight in a query as syntax error, rather skipping it as a space character. mysql-test/r/ctype_latin1.result: Treat unknown characters straight in a query as syntax error, rather skipping it as a space character. --- mysql-test/r/ctype_latin1.result | 5 +++++ mysql-test/t/ctype_latin1.test | 9 +++++++++ mysys/charset.c | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result index cd804939a75..21c40e24fe2 100644 --- a/mysql-test/r/ctype_latin1.result +++ b/mysql-test/r/ctype_latin1.result @@ -325,3 +325,8 @@ latin1_bin 6109 latin1_bin 61 latin1_bin 6120 drop table t1; +CREATE TABLE „a (a int); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '„a (a int)' at line 1 +SELECT '„a' as str; +str +„a diff --git a/mysql-test/t/ctype_latin1.test b/mysql-test/t/ctype_latin1.test index cee0324d12f..6006ee4c527 100644 --- a/mysql-test/t/ctype_latin1.test +++ b/mysql-test/t/ctype_latin1.test @@ -66,3 +66,12 @@ SET collation_connection='latin1_swedish_ci'; -- source include/ctype_filesort.inc SET collation_connection='latin1_bin'; -- source include/ctype_filesort.inc + +# +# Bug#8041 +# An unknown character (e.g. 0x84) should result in ERROR, +# It was treated like a space character earlier. +# Howerver, it should still work fine as a string part. +--error 1064 +CREATE TABLE „a (a int); +SELECT '„a' as str; diff --git a/mysys/charset.c b/mysys/charset.c index bb8f2d178b9..5840c885e40 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -64,7 +64,7 @@ static my_bool init_state_maps(CHARSET_INFO *cs) else if (my_mbcharlen(cs, i)>1) state_map[i]=(uchar) MY_LEX_IDENT; #endif - else if (!my_isgraph(cs,i)) + else if (my_isspace(cs,i)) state_map[i]=(uchar) MY_LEX_SKIP; else state_map[i]=(uchar) MY_LEX_CHAR; From cb8d9c3ad40f00018cff05168e731ff2547d6144 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Feb 2005 12:51:23 +0200 Subject: [PATCH 10/12] Backport my_strntod() from 5.0 Change string->float conversion to delay division as long as possible. This gives us more exact integer->float conversion for numbers of type '123.45E+02' (Bug #7740) client/mysql.cc: Fix wront usage of charset (found during review of pushed code) include/m_string.h: Backported my_strtod() from 5.0 mysql-test/mysql-test-run.sh: Run also mysql_client_test with --debug mysql-test/r/ps_1general.result: Safety fix (if mysql_client_test.test fails) mysql-test/r/type_float.result: More test mysql-test/t/mysql_client_test.test: Comments for what to do if this test fails mysql-test/t/ps_1general.test: Safety fix (if mysql_client_test.test fails) mysql-test/t/type_float.test: More test to better test new strtod() function Test also bug #7740 (wrong comparsion between integer and float-in-integer-range) sql/field.cc: Backport my_strntod() from 5.0 sql/item.cc: Backport my_strntod() from 5.0 sql/item.h: Backport my_strntod() from 5.0 sql/item_func.h: Backport my_strntod() from 5.0 sql/item_strfunc.cc: Backport my_strntod() from 5.0 sql/item_sum.cc: Backport my_strntod() from 5.0 sql/item_sum.h: Backport my_strntod() from 5.0 sql/procedure.h: Backport my_strntod() from 5.0 strings/ctype-simple.c: Backport my_strntod() from 5.0 strings/ctype-ucs2.c: Backport my_strntod() from 5.0 strings/strtod.c: Backport my_strntod() from 5.0 Change conversion to delay division as long as possible. This gives us more exact integer-> float conversion for numbers of type '123.45E+02' --- client/mysql.cc | 4 +- include/m_string.h | 2 +- mysql-test/mysql-test-run.sh | 3 +- mysql-test/r/ps_1general.result | 1 + mysql-test/r/type_float.result | 34 +++++- mysql-test/t/mysql_client_test.test | 7 ++ mysql-test/t/ps_1general.test | 1 + mysql-test/t/type_float.test | 26 ++++- sql/field.cc | 14 ++- sql/item.cc | 11 +- sql/item.h | 6 +- sql/item_func.h | 7 +- sql/item_strfunc.cc | 3 +- sql/item_sum.cc | 3 +- sql/item_sum.h | 6 +- sql/procedure.h | 11 +- strings/ctype-simple.c | 27 +---- strings/ctype-ucs2.c | 9 +- strings/strtod.c | 175 +++++++++++++++++++--------- 19 files changed, 243 insertions(+), 107 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 4004757359b..1bbab75434c 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2914,9 +2914,9 @@ com_status(String *buffer __attribute__((unused)), MYSQL_ROW cur=mysql_fetch_row(result); if (cur) { - tee_fprintf(stdout, "Server characterset:\t%s\n", cur[0] ? cur[2] : ""); + tee_fprintf(stdout, "Server characterset:\t%s\n", cur[2] ? cur[2] : ""); tee_fprintf(stdout, "Db characterset:\t%s\n", cur[3] ? cur[3] : ""); - tee_fprintf(stdout, "Client characterset:\t%s\n", cur[2] ? cur[0] : ""); + tee_fprintf(stdout, "Client characterset:\t%s\n", cur[0] ? cur[0] : ""); tee_fprintf(stdout, "Conn. characterset:\t%s\n", cur[1] ? cur[1] : ""); } mysql_free_result(result); diff --git a/include/m_string.h b/include/m_string.h index 97d34421537..d3465363beb 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -215,7 +215,7 @@ extern char *strstr(const char *, const char *); extern int is_prefix(const char *, const char *); /* Conversion routines */ -double my_strtod(const char *str, char **end); +double my_strtod(const char *str, char **end, int *error); double my_atof(const char *nptr); extern char *llstr(longlong value,char *buff); diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index af432f37868..8c484d2ddb1 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -444,6 +444,7 @@ while test $# -gt 0; do --debug=d:t:A,$MYSQL_TEST_DIR/var/log/mysqldump.trace" EXTRA_MYSQLBINLOG_OPT="$EXTRA_MYSQLBINLOG_OPT \ --debug=d:t:A,$MYSQL_TEST_DIR/var/log/mysqlbinlog.trace" + EXTRA_MYSQL_CLIENT_TEST_OPT="--debug=d:t:A,$MYSQL_TEST_DIR/var/log/mysql_client_test.trace" ;; --fast) FAST_START=1 @@ -681,7 +682,7 @@ then EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --user=root" fi -MYSQL_CLIENT_TEST="$MYSQL_CLIENT_TEST --no-defaults --testcase --user=root --socket=$MASTER_MYSOCK --port=$MYSQL_TCP_PORT --silent" +MYSQL_CLIENT_TEST="$MYSQL_CLIENT_TEST --no-defaults --testcase --user=root --socket=$MASTER_MYSOCK --port=$MYSQL_TCP_PORT --silent $EXTRA_MYSQL_CLIENT_TEST_OPT" MYSQL_DUMP="$MYSQL_DUMP --no-defaults -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLDUMP_OPT" MYSQL_BINLOG="$MYSQL_BINLOG --no-defaults --local-load=$MYSQL_TMP_DIR $EXTRA_MYSQLBINLOG_OPT" MYSQL_FIX_SYSTEM_TABLES="$MYSQL_FIX_SYSTEM_TABLES --no-defaults --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD --basedir=$BASEDIR --bindir=$CLIENT_BINDIR --verbose" diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index 2356989eaf6..ec4aa528a7f 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -1,5 +1,6 @@ drop table if exists t5, t6, t7, t8; drop database if exists mysqltest ; +drop database if exists client_test_db; test_sequence ------ basic tests ------ drop table if exists t1, t9 ; diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 1f5a34917d7..c1cefe4b35d 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -1,4 +1,4 @@ -drop table if exists t1; +drop table if exists t1,t2; SELECT 10,10.0,10.,.1e+2,100.0e-1; 10 10.0 10. .1e+2 100.0e-1 10 10.0 10 10 10 @@ -8,6 +8,15 @@ SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000; SELECT 1e1,1.e1,1.0e1,1e+1,1.e+1,1.0e+1,1e-1,1.e-1,1.0e-1; 1e1 1.e1 1.0e1 1e+1 1.e+1 1.0e+1 1e-1 1.e-1 1.0e-1 10 10 10 10 10 10 0.1 0.1 0.1 +SELECT 0.001e+1,0.001e-1, -0.001e+01,-0.001e-01; +0.001e+1 0.001e-1 -0.001e+01 -0.001e-01 +0.01 0.0001 -0.01 -0.0001 +SELECT 123.23E+02,-123.23E-02,"123.23E+02"+0.0,"-123.23E-02"+0.0; +123.23E+02 -123.23E-02 "123.23E+02"+0.0 "-123.23E-02"+0.0 +12323 -1.2323 12323 -1.2323 +SELECT 2147483647E+02,21474836.47E+06; +2147483647E+02 21474836.47E+06 +214748364700 21474836470000 create table t1 (f1 float(24),f2 float(52)); show full columns from t1; Field Type Collation Null Key Default Extra Privileges Comment @@ -139,6 +148,9 @@ create table t1 (c20 char); insert into t1 values (5000.0); Warnings: Warning 1265 Data truncated for column 'c20' at row 1 +insert into t1 values (0.5e4); +Warnings: +Warning 1265 Data truncated for column 'c20' at row 1 drop table t1; create table t1 (f float(54)); ERROR 42000: Incorrect column specifier for column 'f' @@ -203,3 +215,23 @@ c 0.0002 2e-05 drop table t1; +CREATE TABLE t1 ( +reckey int unsigned NOT NULL, +recdesc varchar(50) NOT NULL, +PRIMARY KEY (reckey) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (108, 'Has 108 as key'); +INSERT INTO t1 VALUES (109, 'Has 109 as key'); +select * from t1 where reckey=108; +reckey recdesc +108 Has 108 as key +select * from t1 where reckey=1.08E2; +reckey recdesc +108 Has 108 as key +select * from t1 where reckey=109; +reckey recdesc +109 Has 109 as key +select * from t1 where reckey=1.09E2; +reckey recdesc +109 Has 109 as key +drop table t1; diff --git a/mysql-test/t/mysql_client_test.test b/mysql-test/t/mysql_client_test.test index 86aecf43cbd..3639fc2e262 100644 --- a/mysql-test/t/mysql_client_test.test +++ b/mysql-test/t/mysql_client_test.test @@ -1,3 +1,10 @@ # We run with different binaries for normal and --embedded-server +# +# If this test fails with "command "$MYSQL_CLIENT_TEST" failed", +# you should either run mysql_client_test separartely against a running +# server or run mysql-test-run --debug mysql_client_test and check +# var/log/mysql_client_test.trace + --disable_result_log +--exec echo $MYSQL_CLIENT_TEST --exec $MYSQL_CLIENT_TEST diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test index 4ab81dfcac5..b3ce6d7fd82 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -11,6 +11,7 @@ --disable_warnings drop table if exists t5, t6, t7, t8; drop database if exists mysqltest ; +drop database if exists client_test_db; --enable_warnings --disable_query_log diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 5b106d242de..6e991dc53d4 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -3,7 +3,7 @@ # Numeric floating point. --disable_warnings -drop table if exists t1; +drop table if exists t1,t2; --enable_warnings --replace_result e-0 e- e+0 e+ @@ -11,6 +11,9 @@ SELECT 10,10.0,10.,.1e+2,100.0e-1; --replace_result e-00 e-0 SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000; SELECT 1e1,1.e1,1.0e1,1e+1,1.e+1,1.0e+1,1e-1,1.e-1,1.0e-1; +SELECT 0.001e+1,0.001e-1, -0.001e+01,-0.001e-01; +SELECT 123.23E+02,-123.23E-02,"123.23E+02"+0.0,"-123.23E-02"+0.0; +SELECT 2147483647E+02,21474836.47E+06; create table t1 (f1 float(24),f2 float(52)); show full columns from t1; @@ -83,6 +86,7 @@ drop table t1; # create table t1 (c20 char); insert into t1 values (5000.0); +insert into t1 values (0.5e4); drop table t1; # Errors @@ -120,3 +124,23 @@ create table t1 (c char(6)); insert into t1 values (2e5),(2e6),(2e-4),(2e-5); select * from t1; drop table t1; + +# +# Test of comparison of integer with float-in-range (Bug #7840) +# This is needed because some ODBC applications (like Foxpro) uses +# floats for everything. +# + +CREATE TABLE t1 ( + reckey int unsigned NOT NULL, + recdesc varchar(50) NOT NULL, + PRIMARY KEY (reckey) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +INSERT INTO t1 VALUES (108, 'Has 108 as key'); +INSERT INTO t1 VALUES (109, 'Has 109 as key'); +select * from t1 where reckey=108; +select * from t1 where reckey=1.08E2; +select * from t1 where reckey=109; +select * from t1 where reckey=1.09E2; +drop table t1; diff --git a/sql/field.cc b/sql/field.cc index fa0e202d513..ca923d723bc 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -968,7 +968,9 @@ int Field_decimal::store(longlong nr) double Field_decimal::val_real(void) { int not_used; - return my_strntod(&my_charset_bin, ptr, field_length, NULL, ¬_used); + char *end_not_used; + return my_strntod(&my_charset_bin, ptr, field_length, &end_not_used, + ¬_used); } longlong Field_decimal::val_int(void) @@ -4360,8 +4362,9 @@ int Field_string::store(longlong nr) double Field_string::val_real(void) { int not_used; + char *end_not_used; CHARSET_INFO *cs=charset(); - return my_strntod(cs,ptr,field_length,(char**)0,¬_used); + return my_strntod(cs, ptr, field_length, &end_not_used, ¬_used); } @@ -4577,7 +4580,9 @@ double Field_varstring::val_real(void) int not_used; uint length=uint2korr(ptr)+HA_KEY_BLOB_LENGTH; CHARSET_INFO *cs=charset(); - return my_strntod(cs, ptr+HA_KEY_BLOB_LENGTH, length, (char**)0, ¬_used); + char *end_not_used; + return my_strntod(cs, ptr+HA_KEY_BLOB_LENGTH, length, &end_not_used, + ¬_used); } @@ -4955,12 +4960,13 @@ double Field_blob::val_real(void) { int not_used; char *blob; + char *end_not_used; memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); if (!blob) return 0.0; uint32 length=get_length(ptr); CHARSET_INFO *cs=charset(); - return my_strntod(cs,blob,length,(char**)0, ¬_used); + return my_strntod(cs,blob,length, &end_not_used, ¬_used); } diff --git a/sql/item.cc b/sql/item.cc index 4b3acbe5a3c..76cbaa99029 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1140,8 +1140,9 @@ double Item_param::val() case LONG_DATA_VALUE: { int dummy_err; + char *end_not_used; return my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(), (char**) 0, &dummy_err); + str_value.length(), &end_not_used, &dummy_err); } case TIME_VALUE: /* @@ -2585,10 +2586,12 @@ double Item_cache_str::val() DBUG_ASSERT(fixed == 1); int err; if (value) + { + char *end_not_used; return my_strntod(value->charset(), (char*) value->ptr(), - value->length(), (char**) 0, &err); - else - return (double)0; + value->length(), &end_not_used, &err); + } + return (double)0; } diff --git a/sql/item.h b/sql/item.h index dd06d4ce61a..97e2b0c0945 100644 --- a/sql/item.h +++ b/sql/item.h @@ -719,8 +719,9 @@ public: { DBUG_ASSERT(fixed == 1); int err; + char *end_not_used; return my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(), (char**) 0, &err); + str_value.length(), &end_not_used, &err); } longlong val_int() { @@ -1044,9 +1045,10 @@ public: double val() { int err; + char *end_not_used; return (null_value ? 0.0 : my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(),NULL,&err)); + str_value.length(), &end_not_used, &err)); } longlong val_int() { diff --git a/sql/item_func.h b/sql/item_func.h index 8a5347d675e..2738c7419ca 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -828,8 +828,11 @@ public: double val() { int err; - String *res; res=val_str(&str_value); - return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),0,&err) : 0.0; + String *res; + char *end_not_used; + res=val_str(&str_value); + return res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(), + &end_not_used, &err) : 0.0; } longlong val_int() { diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index bbbcadbb071..8bd1da4e15f 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -63,10 +63,11 @@ double Item_str_func::val() DBUG_ASSERT(fixed == 1); int err; char buff[64]; + char *end_not_used; String *res, tmp(buff,sizeof(buff), &my_charset_bin); res= val_str(&tmp); return res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(), - NULL, &err) : 0.0; + &end_not_used, &err) : 0.0; } longlong Item_str_func::val_int() diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 029a1fd6c48..6bd2cc00b3e 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -471,13 +471,14 @@ double Item_sum_hybrid::val() { DBUG_ASSERT(fixed == 1); int err; + char *end_not_used; if (null_value) return 0.0; switch (hybrid_type) { case STRING_RESULT: String *res; res=val_str(&str_value); return (res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(), - (char**) 0, &err) : 0.0); + &end_not_used, &err) : 0.0); case INT_RESULT: if (unsigned_flag) return ulonglong2double(sum_int); diff --git a/sql/item_sum.h b/sql/item_sum.h index d1e82387944..dab136e4716 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -600,9 +600,11 @@ public: double val() { int err; - String *res; res=val_str(&str_value); + char *end_not_used; + String *res; + res=val_str(&str_value); return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(), - (char**) 0, &err) : 0.0; + &end_not_used, &err) : 0.0; } longlong val_int() { diff --git a/sql/procedure.h b/sql/procedure.h index 5365b2e1102..abe50bdc0a0 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -59,7 +59,11 @@ public: void set(double nr) { value=nr; } void set(longlong nr) { value=(double) nr; } void set(const char *str,uint length,CHARSET_INFO *cs) - { int err; value=my_strntod(cs,(char*) str,length,(char**)0,&err); } + { + int err; + char *end_not_used; + value= my_strntod(cs, (char*) str, length, &end_not_used, &err); + } double val() { return value; } longlong val_int() { return (longlong) value; } String *val_str(String *s) { s->set(value,decimals,default_charset()); return s; } @@ -99,9 +103,10 @@ public: double val() { int err; - CHARSET_INFO *cs=str_value.charset(); + CHARSET_INFO *cs= str_value.charset(); + char *end_not_used; return my_strntod(cs, (char*) str_value.ptr(), str_value.length(), - (char**) 0, &err); + &end_not_used, &err); } longlong val_int() { diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 1a09b16a264..c2a6aa4e17f 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -773,31 +773,10 @@ double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)), char *str, uint length, char **end, int *err) { - char end_char; - double result; - - errno= 0; /* Safety */ - - /* - The following define is to avoid warnings from valgrind as str[length] - may not be defined (which is not fatal in real life) - */ - -#ifdef HAVE_purify if (length == INT_MAX32) -#else - if (length == INT_MAX32 || str[length] == 0) -#endif - result= my_strtod(str, end); - else - { - end_char= str[length]; - str[length]= 0; - result= my_strtod(str, end); - str[length]= end_char; /* Restore end char */ - } - *err= errno; - return result; + length= 65535; /* Should be big enough */ + *end= str + length; + return my_strtod(str, end, err); } diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index e92704b83d7..9c67d1b7846 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -946,13 +946,10 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), break; /* Can't be part of double */ *b++= (char) wc; } - *b= 0; - errno= 0; - res=my_strtod(buf, endptr); - *err= errno; - if (endptr) - *endptr=(char*) (*endptr-buf+nptr); + *endptr= b; + res= my_strtod(buf, endptr, err); + *endptr= nptr + (uint) (*endptr- buf); return res; } diff --git a/strings/strtod.c b/strings/strtod.c index bc8105b8040..61f2c107abe 100644 --- a/strings/strtod.c +++ b/strings/strtod.c @@ -2,7 +2,7 @@ An alternative implementation of "strtod()" that is both simplier, and thread-safe. - From mit-threads as bundled with MySQL 3.23 + Original code from mit-threads as bundled with MySQL 3.23 SQL:2003 specifies a number as @@ -29,6 +29,8 @@ #include "my_base.h" /* Includes errno.h */ #include "m_ctype.h" +#define MAX_DBL_EXP 308 +#define MAX_RESULT_FOR_MAX_EXP 1.79769313486232 static double scaler10[] = { 1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90 }; @@ -37,89 +39,157 @@ static double scaler1[] = { }; -double my_strtod(const char *str, char **end) +/* + Convert string to double (string doesn't have to be null terminated) + + SYNOPSIS + my_strtod() + str String to convert + end_ptr Pointer to pointer that points to end of string + Will be updated to point to end of double. + error Will contain error number in case of error (else 0) + + RETURN + value of str as double +*/ + +double my_strtod(const char *str, char **end_ptr, int *error) { double result= 0.0; - int negative, ndigits; - const char *old_str; + uint negative= 0, ndigits, dec_digits= 0, neg_exp= 0; + int exp= 0, digits_after_dec_point= 0; + const char *old_str, *end= *end_ptr, *start_of_number; + char next_char; my_bool overflow=0; - while (my_isspace(&my_charset_latin1, *str)) - str++; + *error= 0; + if (str >= end) + goto done; + while (my_isspace(&my_charset_latin1, *str)) + { + if (++str == end) + goto done; + } + + start_of_number= str; if ((negative= (*str == '-')) || *str=='+') - str++; + { + if (++str == end) + goto done; /* Could be changed to error */ + } + + /* Skip pre-zero for easier calculation of overflows */ + while (*str == '0') + { + if (++str == end) + goto done; + start_of_number= 0; /* Found digit */ + } old_str= str; - while (my_isdigit (&my_charset_latin1, *str)) + while ((next_char= *str) >= '0' && next_char <= '9') { - result= result*10.0 + (*str - '0'); - str++; - } - ndigits= str-old_str; - - if (*str == '.') - { - double p10=10; - str++; - old_str= str; - while (my_isdigit (&my_charset_latin1, *str)) + result= result*10.0 + (next_char - '0'); + if (++str == end) { - result+= (*str++ - '0')/p10; - p10*=10; + next_char= 0; /* Found end of string */ + break; } - ndigits+= str-old_str; - if (!ndigits) str--; + start_of_number= 0; /* Found digit */ } - if (ndigits && (*str=='e' || *str=='E')) + ndigits= (uint) (str-old_str); + + if (next_char == '.' && str < end-1) + { + /* + Continue to add numbers after decimal point to the result, as if there + was no decimal point. We will later (in the exponent handling) shift + the number down with the required number of fractions. We do it this + way to be able to get maximum precision for numbers like 123.45E+02, + which are normal for some ODBC applications. + */ + old_str= ++str; + while (my_isdigit(&my_charset_latin1, (next_char= *str))) + { + result= result*10.0 + (next_char - '0'); + digits_after_dec_point++; + if (++str == end) + { + next_char= 0; + break; + } + } + /* If we found just '+.' or '.' then point at first character */ + if (!(dec_digits= (uint) (str-old_str)) && start_of_number) + str= start_of_number; /* Point at '+' or '.' */ + } + if ((next_char == 'e' || next_char == 'E') && + dec_digits + ndigits != 0 && str < end-1) { - int exp= 0; - int neg= 0; const char *old_str= str++; - if ((neg= (*str == '-')) || *str == '+') + if ((neg_exp= (*str == '-')) || *str == '+') str++; - if (!my_isdigit (&my_charset_latin1, *str)) + if (str == end || !my_isdigit(&my_charset_latin1, *str)) str= old_str; else { - double scaler= 1.0; - while (my_isdigit (&my_charset_latin1, *str)) + do { - if (exp < 9999) /* protection against exp overflow */ - exp= exp*10 + *str - '0'; + if (exp < 9999) /* prot. against exp overfl. */ + exp= exp*10 + (*str - '0'); str++; - } - if (exp >= 1000) + } while (str < end && my_isdigit(&my_charset_latin1, *str)); + } + } + if ((exp= (neg_exp ? exp + digits_after_dec_point : + exp - digits_after_dec_point))) + { + double scaler; + if (exp < 0) + { + exp= -exp; + neg_exp= 1; /* neg_exp was 0 before */ + } + if (exp + ndigits >= MAX_DBL_EXP + 1 && result) + { + /* + This is not 100 % as we actually will give an owerflow for + 17E307 but not for 1.7E308 but lets cut some corners to make life + simpler + */ + if (exp + ndigits > MAX_DBL_EXP + 1 || + result >= MAX_RESULT_FOR_MAX_EXP) { - if (neg) - result= 0.0; - else + if (neg_exp) + result= 0.0; + else overflow= 1; goto done; } - while (exp >= 100) - { - scaler*= 1.0e100; - exp-= 100; - } - scaler*= scaler10[exp/10]*scaler1[exp%10]; - if (neg) - result/= scaler; - else - result*= scaler; } + scaler= 1.0; + while (exp >= 100) + { + scaler*= 1.0e100; + exp-= 100; + } + scaler*= scaler10[exp/10]*scaler1[exp%10]; + if (neg_exp) + result/= scaler; + else + result*= scaler; } done: - if (end) - *end = (char *)str; + *end_ptr= (char*) str; /* end of number */ if (overflow || isinf(result)) { result= DBL_MAX; - errno= EOVERFLOW; + *error= EOVERFLOW; } return negative ? -result : result; @@ -127,6 +197,7 @@ done: double my_atof(const char *nptr) { - return (my_strtod(nptr, 0)); + int error; + const char *end= nptr+65535; /* Should be enough */ + return (my_strtod(nptr, (char**) &end, &error)); } - From 2fb807d1d0a817c177e02cee7b508b6122ce832e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Feb 2005 15:55:40 +0400 Subject: [PATCH 11/12] A user variable are now always have IMPLICIT coercibility, independently from the expression it is initialized from. In other words, this change treats a user variable like a table with one column and one record. Discussed with PeterG, Serg and Lars. This change also simplifies replication allowing not to replicate variables' coercibility. mysql-test/r/user_var.result: Test changes accordintly mysql-test/t/user_var.test: Test changes accordintly --- mysql-test/r/user_var.result | 16 +++++++++------- mysql-test/t/user_var.test | 2 -- sql/item_func.cc | 10 +++++----- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 81846391795..d82c17b0fe0 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -123,7 +123,7 @@ drop table t1; set @a=_latin2'test'; select charset(@a),collation(@a),coercibility(@a); charset(@a) collation(@a) coercibility(@a) -latin2 latin2_general_ci 3 +latin2 latin2_general_ci 2 select @a=_latin2'TEST'; @a=_latin2'TEST' 1 @@ -133,12 +133,13 @@ select @a=_latin2'TEST' collate latin2_bin; set @a=_latin2'test' collate latin2_general_ci; select charset(@a),collation(@a),coercibility(@a); charset(@a) collation(@a) coercibility(@a) -latin2 latin2_general_ci 0 +latin2 latin2_general_ci 2 select @a=_latin2'TEST'; @a=_latin2'TEST' 1 select @a=_latin2'TEST' collate latin2_bin; -ERROR HY000: Illegal mix of collations (latin2_general_ci,EXPLICIT) and (latin2_bin,EXPLICIT) for operation '=' +@a=_latin2'TEST' collate latin2_bin +0 select charset(@a:=_latin2'test'); charset(@a:=_latin2'test') latin2 @@ -147,21 +148,22 @@ collation(@a:=_latin2'test') latin2_general_ci select coercibility(@a:=_latin2'test'); coercibility(@a:=_latin2'test') -3 +2 select collation(@a:=_latin2'test' collate latin2_bin); collation(@a:=_latin2'test' collate latin2_bin) latin2_bin select coercibility(@a:=_latin2'test' collate latin2_bin); coercibility(@a:=_latin2'test' collate latin2_bin) -0 +2 select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST'; (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' 0 select charset(@a),collation(@a),coercibility(@a); charset(@a) collation(@a) coercibility(@a) -latin2 latin2_bin 0 +latin2 latin2_bin 2 select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' collate latin2_general_ci; -ERROR HY000: Illegal mix of collations (latin2_bin,EXPLICIT) and (latin2_general_ci,EXPLICIT) for operation '=' +(@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' collate latin2_general_ci +1 create table t1 (a varchar(50)); reset master; SET TIMESTAMP=10000; diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 81788ce8d73..2f526dc9a46 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -84,7 +84,6 @@ select @a=_latin2'TEST' collate latin2_bin; set @a=_latin2'test' collate latin2_general_ci; select charset(@a),collation(@a),coercibility(@a); select @a=_latin2'TEST'; ---error 1267 select @a=_latin2'TEST' collate latin2_bin; # @@ -97,7 +96,6 @@ select collation(@a:=_latin2'test' collate latin2_bin); select coercibility(@a:=_latin2'test' collate latin2_bin); select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST'; select charset(@a),collation(@a),coercibility(@a); ---error 1267 select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' collate latin2_general_ci; # Check that user variables are binlogged correctly (BUG#3875) diff --git a/sql/item_func.cc b/sql/item_func.cc index 34c8732a9f2..895740d2e5e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2361,7 +2361,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, entry->value=0; entry->length=0; entry->update_query_id=0; - entry->collation.set(NULL, DERIVATION_NONE); + entry->collation.set(NULL, DERIVATION_IMPLICIT); /* If we are here, we were called from a SET or a query which sets a variable. Imagine it is this: @@ -2419,8 +2419,8 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables, and the variable has previously been initialized. */ if (!entry->collation.collation || !args[0]->null_value) - entry->collation.set(args[0]->collation); - collation.set(entry->collation); + entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT); + collation.set(entry->collation.collation, DERIVATION_IMPLICIT); cached_result_type= args[0]->result_type(); return 0; } @@ -2432,7 +2432,7 @@ Item_func_set_user_var::fix_length_and_dec() maybe_null=args[0]->maybe_null; max_length=args[0]->max_length; decimals=args[0]->decimals; - collation.set(args[0]->collation); + collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT); } @@ -2659,7 +2659,7 @@ Item_func_set_user_var::update() res= update_hash((void*) save_result.vstr->ptr(), save_result.vstr->length(), STRING_RESULT, save_result.vstr->charset(), - args[0]->collation.derivation); + DERIVATION_IMPLICIT); break; } case ROW_RESULT: From 2ae6eb094bb02a3e41ab611c9e9f27982a2ef9c3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Feb 2005 15:08:12 +0200 Subject: [PATCH 12/12] Fix errors in my last changeset --- libmysql/libmysql.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 9c49c7eb15b..16dda115ee9 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3390,14 +3390,17 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value, } case MYSQL_TYPE_FLOAT: { + char *end_not_used; float data = (float) my_strntod(&my_charset_latin1, value, length, - NULL, &err); + &end_not_used, &err); floatstore(buffer, data); break; } case MYSQL_TYPE_DOUBLE: { - double data= my_strntod(&my_charset_latin1, value, length, NULL, &err); + char *end_not_used; + double data= my_strntod(&my_charset_latin1, value, length, &end_not_used, + &err); doublestore(buffer, data); break; }