diff options
-rw-r--r-- | BitKeeper/etc/logging_ok | 1 | ||||
-rw-r--r-- | client/mysql.cc | 4 | ||||
-rw-r--r-- | extra/my_print_defaults.c | 18 | ||||
-rw-r--r-- | mysql-test/mysql-test-run.sh | 3 | ||||
-rw-r--r-- | mysql-test/r/ctype_latin1.result | 5 | ||||
-rw-r--r-- | mysql-test/r/ctype_utf8.result | 3 | ||||
-rw-r--r-- | mysql-test/r/derived.result | 19 | ||||
-rw-r--r-- | mysql-test/r/ps_1general.result | 1 | ||||
-rw-r--r-- | mysql-test/r/type_float.result | 26 | ||||
-rw-r--r-- | mysql-test/r/user_var.result | 16 | ||||
-rw-r--r-- | mysql-test/t/ctype_latin1.test | 9 | ||||
-rw-r--r-- | mysql-test/t/ctype_utf8.test | 5 | ||||
-rw-r--r-- | mysql-test/t/derived.test | 12 | ||||
-rw-r--r-- | mysql-test/t/mysql_client_test.test | 7 | ||||
-rw-r--r-- | mysql-test/t/ps_1general.test | 2 | ||||
-rw-r--r-- | mysql-test/t/type_float.test | 22 | ||||
-rw-r--r-- | mysql-test/t/user_var.test | 2 | ||||
-rw-r--r-- | mysys/charset.c | 2 | ||||
-rw-r--r-- | sql/field.cc | 11 | ||||
-rw-r--r-- | sql/item_func.cc | 10 | ||||
-rw-r--r-- | sql/item_sum.h | 4 | ||||
-rw-r--r-- | sql/procedure.h | 2 | ||||
-rw-r--r-- | sql/sql_derived.cc | 8 | ||||
-rw-r--r-- | sql/sql_update.cc | 7 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 | ||||
-rw-r--r-- | strings/ctype-utf8.c | 4 | ||||
-rw-r--r-- | strings/strtod.c | 27 |
27 files changed, 190 insertions, 42 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index e6292a20347..f5cb190ec8d 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -27,6 +27,7 @@ bar@deer.(none) bar@gw.udmsearch.izhnet.ru bar@mysql.com bar@noter.intranet.mysql.r18.ru +bell@51.0.168.192.in-addr.arpa bell@laptop.sanja.is.com.ua bell@sanja.is.com.ua bk@admin.bk diff --git a/client/mysql.cc b/client/mysql.cc index e387bb26063..edd6e59fb4e 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2926,9 +2926,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[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[2] : ""); + 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/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))) { diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 8a71d8fc566..cee8ca4bfd0 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -450,6 +450,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 @@ -690,7 +691,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 --character-sets-dir=$CHARSETSDIR $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/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/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index faab013559a..893c7cc7039 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -861,3 +861,6 @@ user c one <one> two <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/r/derived.result b/mysql-test/r/derived.result index 071cb673501..fd6a834c694 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -344,3 +344,22 @@ INSERT INTO t1 VALUES ('root','localhost'), ('root','%'); SELECT * FROM (SELECT (SELECT a.a FROM t1 AS a WHERE a.a = b.a) FROM t1 AS b) AS c; ERROR 21000: Subquery returns more than 1 row 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/r/ps_1general.result b/mysql-test/r/ps_1general.result index 153121f0662..cd3c8e162f7 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; drop database if exists testtets; drop table if exists t1Aa,t2Aa,v1Aa,v2Aa; drop view if exists t1Aa,t2Aa,v1Aa,v2Aa; diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 8140167870e..eec9701d054 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -11,6 +11,12 @@ 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; 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 @@ -209,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/r/user_var.result b/mysql-test/r/user_var.result index 511ef5e3188..8ae1d145227 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -127,7 +127,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 @@ -137,12 +137,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 @@ -151,21 +152,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/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/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/mysql-test/t/derived.test b/mysql-test/t/derived.test index df860d92b38..1e3ffd5160b 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -236,3 +236,15 @@ INSERT INTO t1 VALUES ('root','localhost'), ('root','%'); --error 1242 SELECT * FROM (SELECT (SELECT a.a FROM t1 AS a WHERE a.a = b.a) FROM t1 AS b) AS c; 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/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 81934547f82..22a4a8bf2c9 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -11,7 +11,9 @@ --disable_warnings drop table if exists t5, t6, t7, t8; drop database if exists mysqltest ; + # Cleanup from other tests +drop database if exists client_test_db; drop database if exists testtets; drop table if exists t1Aa,t2Aa,v1Aa,v2Aa; drop view if exists t1Aa,t2Aa,v1Aa,v2Aa; diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 4f40d97743a..6e991dc53d4 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -12,6 +12,8 @@ SELECT 10,10.0,10.,.1e+2,100.0e-1; 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; @@ -122,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/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 5dc24bde21f..07076f1f6f4 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -85,7 +85,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; # @@ -98,7 +97,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/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; diff --git a/sql/field.cc b/sql/field.cc index a32b402cbdb..194f4522851 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2432,12 +2432,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) diff --git a/sql/item_func.cc b/sql/item_func.cc index 40abd130d02..3742a13e0bc 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3169,7 +3169,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: @@ -3227,8 +3227,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 FALSE; } @@ -3240,7 +3240,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); } @@ -3516,7 +3516,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 DECIMAL_RESULT: diff --git a/sql/item_sum.h b/sql/item_sum.h index e284416f0f5..c3eae176b1f 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -691,7 +691,9 @@ public: { int err_not_used; char *end_not_used; - 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(), &end_not_used, &err_not_used) : 0.0; } diff --git a/sql/procedure.h b/sql/procedure.h index 4e5bf8a2f4b..5d0dccbcd5e 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -110,7 +110,7 @@ public: { int err_not_used; char *end_not_used; - CHARSET_INFO *cs=str_value.charset(); + CHARSET_INFO *cs= str_value.charset(); return my_strntod(cs, (char*) str_value.ptr(), str_value.length(), &end_not_used, &err_not_used); } diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index c01728e68d5..eb7b3e8a319 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -124,10 +124,16 @@ int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list) /* 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, + FALSE, 1, (first_select->options | thd->options | TMP_TABLE_ALL_COLUMNS), HA_POS_ERROR, diff --git a/sql/sql_update.cc b/sql/sql_update.cc index b7a088ff37c..80ad13195c8 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -707,7 +707,12 @@ bool mysql_multi_update_prepare(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; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c75068f0047..ba1b999b240 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2451,7 +2451,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) diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 4c90726e877..187e5cb9e4a 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}, diff --git a/strings/strtod.c b/strings/strtod.c index 92d93612dd0..61f2c107abe 100644 --- a/strings/strtod.c +++ b/strings/strtod.c @@ -56,8 +56,8 @@ static double scaler1[] = { double my_strtod(const char *str, char **end_ptr, int *error) { double result= 0.0; - uint negative= 0, ndigits, dec_digits= 0, pre_zero, neg_exp= 0; - int exp= 0; + 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; @@ -100,18 +100,20 @@ double my_strtod(const char *str, char **end_ptr, int *error) } ndigits= (uint) (str-old_str); - pre_zero= 0; if (next_char == '.' && str < end-1) { - double p10= 10; + /* + 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+= (next_char - '0')/p10; - if (!result) - pre_zero++; - else - p10*= 10; + result= result*10.0 + (next_char - '0'); + digits_after_dec_point++; if (++str == end) { next_char= 0; @@ -136,13 +138,14 @@ double my_strtod(const char *str, char **end_ptr, int *error) { do { - if (exp < 9999) /* protec against exp overfl. */ - exp= exp*10 + *str - '0'; + if (exp < 9999) /* prot. against exp overfl. */ + exp= exp*10 + (*str - '0'); str++; } while (str < end && my_isdigit(&my_charset_latin1, *str)); } } - if ((exp= neg_exp ? exp + pre_zero : exp - pre_zero)) + if ((exp= (neg_exp ? exp + digits_after_dec_point : + exp - digits_after_dec_point))) { double scaler; if (exp < 0) |