diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index e426d2c549e..cb60fb20863 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3663,33 +3663,38 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field, case MYSQL_TYPE_FLOAT: { /* - We need to store data in the buffer before the truncation check to + We need to mark the local variable volatile to workaround Intel FPU executive precision feature. (See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 for details) - AFAIU it does not guarantee to work. */ - float data; + volatile float data; if (is_unsigned) + { data= (float) ulonglong2double(value); + *param->error= ((ulonglong) value) != ((ulonglong) data); + } else - data= (float) value; + { + data= (float)value; + *param->error= value != ((longlong) data); + } floatstore(buffer, data); - *param->error= is_unsigned ? - ((ulonglong) value) != ((ulonglong) (*(float*) buffer)) : - ((longlong) value) != ((longlong) (*(float*) buffer)); break; } case MYSQL_TYPE_DOUBLE: { - double data; + volatile double data; if (is_unsigned) + { data= ulonglong2double(value); + *param->error= ((ulonglong) value) != ((ulonglong) data); + } else + { data= (double)value; + *param->error= value != ((longlong) data); + } doublestore(buffer, data); - *param->error= is_unsigned ? - ((ulonglong) value) != ((ulonglong) (*(double*) buffer)) : - ((longlong) value) != ((longlong) (*(double*) buffer)); break; } case MYSQL_TYPE_TIME: diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index f18d1c9b583..064304b27aa 100644 --- a/mysql-test/r/bigint.result +++ b/mysql-test/r/bigint.result @@ -362,3 +362,29 @@ cast(-19999999999999999999 as signed) -9223372036854775808 Warnings: Error 1292 Truncated incorrect DECIMAL value: '' +select -9223372036854775808; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def -9223372036854775808 8 20 20 N 32897 0 63 +-9223372036854775808 +-9223372036854775808 +select -(9223372036854775808); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def -(9223372036854775808) 8 20 20 N 32897 0 63 +-(9223372036854775808) +-9223372036854775808 +select -((9223372036854775808)); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def -((9223372036854775808)) 8 20 20 N 32897 0 63 +-((9223372036854775808)) +-9223372036854775808 +select -(-(9223372036854775808)); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def -(-(9223372036854775808)) 246 21 19 N 129 0 63 +-(-(9223372036854775808)) +9223372036854775808 +select --9223372036854775808, ---9223372036854775808, ----9223372036854775808; +--9223372036854775808 ---9223372036854775808 ----9223372036854775808 +9223372036854775808 -9223372036854775808 9223372036854775808 +select -(-9223372036854775808), -(-(-9223372036854775808)); +-(-9223372036854775808) -(-(-9223372036854775808)) +9223372036854775808 -9223372036854775808 diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index d8afbe13c76..ce9633006af 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -2061,4 +2061,96 @@ C 2707236321 DROP TABLE t1, t2; DROP VIEW v1; +SELECT LOCATE('foo', NULL) FROM DUAL; +LOCATE('foo', NULL) +NULL +SELECT LOCATE(NULL, 'o') FROM DUAL; +LOCATE(NULL, 'o') +NULL +SELECT LOCATE(NULL, NULL) FROM DUAL; +LOCATE(NULL, NULL) +NULL +SELECT LOCATE('foo', NULL) IS NULL FROM DUAL; +LOCATE('foo', NULL) IS NULL +1 +SELECT LOCATE(NULL, 'o') IS NULL FROM DUAL; +LOCATE(NULL, 'o') IS NULL +1 +SELECT LOCATE(NULL, NULL) IS NULL FROM DUAL; +LOCATE(NULL, NULL) IS NULL +1 +SELECT ISNULL(LOCATE('foo', NULL)) FROM DUAL; +ISNULL(LOCATE('foo', NULL)) +1 +SELECT ISNULL(LOCATE(NULL, 'o')) FROM DUAL; +ISNULL(LOCATE(NULL, 'o')) +1 +SELECT ISNULL(LOCATE(NULL, NULL)) FROM DUAL; +ISNULL(LOCATE(NULL, NULL)) +1 +SELECT LOCATE('foo', NULL) <=> NULL FROM DUAL; +LOCATE('foo', NULL) <=> NULL +1 +SELECT LOCATE(NULL, 'o') <=> NULL FROM DUAL; +LOCATE(NULL, 'o') <=> NULL +1 +SELECT LOCATE(NULL, NULL) <=> NULL FROM DUAL; +LOCATE(NULL, NULL) <=> NULL +1 +CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a varchar(10), p varchar(10)); +INSERT INTO t1 VALUES (1, 'foo', 'o'); +INSERT INTO t1 VALUES (2, 'foo', NULL); +INSERT INTO t1 VALUES (3, NULL, 'o'); +INSERT INTO t1 VALUES (4, NULL, NULL); +SELECT id, LOCATE(a,p) FROM t1; +id LOCATE(a,p) +1 0 +2 NULL +3 NULL +4 NULL +SELECT id, LOCATE(a,p) IS NULL FROM t1; +id LOCATE(a,p) IS NULL +1 0 +2 1 +3 1 +4 1 +SELECT id, ISNULL(LOCATE(a,p)) FROM t1; +id ISNULL(LOCATE(a,p)) +1 0 +2 1 +3 1 +4 1 +SELECT id, LOCATE(a,p) <=> NULL FROM t1; +id LOCATE(a,p) <=> NULL +1 0 +2 1 +3 1 +4 1 +SELECT id FROM t1 WHERE LOCATE(a,p) IS NULL; +id +2 +3 +4 +SELECT id FROM t1 WHERE LOCATE(a,p) <=> NULL; +id +2 +3 +4 +DROP TABLE t1; +SELECT SUBSTR('foo',1,0) FROM DUAL; +SUBSTR('foo',1,0) + +SELECT SUBSTR('foo',1,CAST(0 AS SIGNED)) FROM DUAL; +SUBSTR('foo',1,CAST(0 AS SIGNED)) + +SELECT SUBSTR('foo',1,CAST(0 AS UNSIGNED)) FROM DUAL; +SUBSTR('foo',1,CAST(0 AS UNSIGNED)) + +CREATE TABLE t1 (a varchar(10), len int unsigned); +INSERT INTO t1 VALUES ('bar', 2), ('foo', 0); +SELECT SUBSTR(a,1,len) FROM t1; +SUBSTR(a,1,len) +ba + +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 7583aa14db8..2e5193f8563 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2286,3 +2286,24 @@ Variable_name Value Handler_read_key 8 Handler_read_next 1 DROP TABLE t1,t2,t3; +CREATE TABLE t1 (a int, INDEX idx(a)); +INSERT INTO t1 VALUES +(4), (2), (1), (2), (4), (2), (1), (4), +(4), (2), (1), (2), (2), (4), (1), (4); +EXPLAIN SELECT DISTINCT(a) FROM t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL idx 5 NULL 9 Using index for group-by +SELECT DISTINCT(a) FROM t1; +a +1 +2 +4 +EXPLAIN SELECT SQL_BIG_RESULT DISTINCT(a) FROM t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL idx 5 NULL 9 Using index for group-by +SELECT SQL_BIG_RESULT DISTINCT(a) FROM t1; +a +1 +2 +4 +DROP TABLE t1; diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index 08a865e0b94..8cb94072818 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -688,7 +688,16 @@ ERROR 42S22: Unknown column 't2.x' in 'field list' drop table t1,t2; CREATE TABLE t1 (a int PRIMARY KEY); INSERT INTO t1 values (1), (2); +flush status; INSERT INTO t1 SELECT a + 2 FROM t1 LIMIT 1; +show status like 'Handler_read%'; +Variable_name Value +Handler_read_first 1 +Handler_read_key 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_next 1 DROP TABLE t1; CREATE TABLE t1 (x int, y int); CREATE TABLE t2 (z int, y int); @@ -773,3 +782,25 @@ d 20 20 DROP TABLE t1,t2; +CREATE TABLE t1 ( +id INT AUTO_INCREMENT PRIMARY KEY, +prev_id INT, +join_id INT DEFAULT 0); +INSERT INTO t1 (prev_id) VALUES (NULL), (1), (2); +SELECT * FROM t1; +id prev_id join_id +1 NULL 0 +2 1 0 +3 2 0 +CREATE TABLE t2 (join_id INT); +INSERT INTO t2 (join_id) VALUES (0); +INSERT INTO t1 (prev_id) SELECT id +FROM t2 LEFT JOIN t1 ON t1.join_id = t2.join_id +ORDER BY id DESC LIMIT 1; +SELECT * FROM t1; +id prev_id join_id +1 NULL 0 +2 1 0 +3 2 0 +4 3 0 +DROP TABLE t1,t2; diff --git a/mysql-test/r/metadata.result b/mysql-test/r/metadata.result index d33fb038b79..4a776b6a253 100644 --- a/mysql-test/r/metadata.result +++ b/mysql-test/r/metadata.result @@ -140,4 +140,45 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is def a v_small v_small 3 9 9 N 32769 0 63 v_small 214748364 +CREATE TABLE t1 (c1 CHAR(1)); +CREATE TABLE t2 (c2 CHAR(1)); +CREATE VIEW v1 AS SELECT t1.c1 FROM t1; +CREATE VIEW v2 AS SELECT t2.c2 FROM t2; +INSERT INTO t1 VALUES ('1'), ('2'), ('3'); +INSERT INTO t2 VALUES ('1'), ('2'), ('3'), ('2'); +SELECT v1.c1 FROM v1 JOIN t2 ON c1=c2 ORDER BY 1; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def test t1 v1 c1 c1 254 1 1 Y 0 0 8 +c1 +1 +2 +2 +3 +SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def test t1 v1 c1 c1 254 1 1 Y 0 0 8 +def test t2 v2 c2 c2 254 1 1 Y 0 0 8 +c1 c2 +1 1 +2 2 +3 3 +2 2 +SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2 GROUP BY v1.c1; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def test t1 v1 c1 c1 254 1 1 Y 32768 0 8 +def test t2 v2 c2 c2 254 1 1 Y 0 0 8 +c1 c2 +1 1 +2 2 +3 3 +SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2 GROUP BY v1.c1 ORDER BY v2.c2; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def test t1 v1 c1 c1 254 1 1 Y 32768 0 8 +def test t2 v2 c2 c2 254 1 1 Y 0 0 8 +c1 c2 +1 1 +2 2 +3 3 +DROP VIEW v1,v2; +DROP TABLE t1,t2; End of 5.0 tests diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index a50d131cca8..1ba198dfd75 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -312,4 +312,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +CREATE TABLE t1 (c1 CHAR(10)); +flush logs; +INSERT INTO t1 VALUES ('0123456789'); +flush logs; +DROP TABLE t1; +# Query thread_id=REMOVED exec_time=REMOVED error_code=REMOVED End of 5.0 tests diff --git a/mysql-test/r/rpl_change_master.result b/mysql-test/r/rpl_change_master.result index 7f2ba568fb3..98c42069470 100644 --- a/mysql-test/r/rpl_change_master.result +++ b/mysql-test/r/rpl_change_master.result @@ -12,12 +12,74 @@ insert into t1 values(1); insert into t1 values(2); stop slave; show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 357 # # master-bin.000001 No No 0 0 183 # None 0 No # +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 357 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running No +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 183 +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # change master to master_user='root'; show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 183 # # master-bin.000001 No No 0 0 183 # None 0 No # +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 183 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running No +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 183 +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # start slave; select * from t1; n diff --git a/mysql-test/r/rpl_skip_error.result b/mysql-test/r/rpl_skip_error.result index adc61f8c2c8..22ba357ef49 100644 --- a/mysql-test/r/rpl_skip_error.result +++ b/mysql-test/r/rpl_skip_error.result @@ -14,3 +14,22 @@ n 2 3 drop table t1; +create table t1(a int primary key); +insert into t1 values (1),(2); +delete from t1 where @@server_id=1; +set sql_mode=strict_trans_tables; +select @@server_id; +@@server_id +1 +insert into t1 values (1),(2),(3); +select @@server_id; +@@server_id +2 +select * from t1; +a +1 +2 +show slave status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 843 # # master-bin.000001 Yes Yes 0 0 843 # None 0 No # +drop table t1; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 043057f64f7..9adb3f96142 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3476,4 +3476,28 @@ a1 c 2 0 DROP VIEW v1,v2; DROP TABLE t1,t2,t3,t4; +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (1,2), (2,2), (1,3), (1,2); +CREATE VIEW v1 AS SELECT a, b+1 as b FROM t1; +SELECT b, SUM(a) FROM v1 WHERE b=3 GROUP BY b; +b SUM(a) +3 4 +EXPLAIN SELECT b, SUM(a) FROM v1 WHERE b=3 GROUP BY b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +SELECT a, SUM(b) FROM v1 WHERE b=3 GROUP BY a; +a SUM(b) +1 6 +2 3 +EXPLAIN SELECT a, SUM(b) FROM v1 WHERE b=3 GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where; Using temporary; Using filesort +SELECT a, SUM(b) FROM v1 WHERE a=1 GROUP BY a; +a SUM(b) +1 10 +EXPLAIN SELECT a, SUM(b) FROM v1 WHERE a=1 GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +DROP VIEW v1; +DROP TABLE t1; End of 5.0 tests. diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test index 9a5fb11229d..4aef7395184 100644 --- a/mysql-test/t/bigint.test +++ b/mysql-test/t/bigint.test @@ -294,3 +294,19 @@ drop table t1; select cast(19999999999999999999 as signed); select cast(-19999999999999999999 as signed); + +# +# Bug #28625: -9223372036854775808 doesn't fit in BIGINT. +# + +# PS protocol gives different metadata for `Max length' column +--disable_ps_protocol +--enable_metadata +select -9223372036854775808; +select -(9223372036854775808); +select -((9223372036854775808)); +select -(-(9223372036854775808)); +--disable_metadata +--endble_ps_protocol +select --9223372036854775808, ---9223372036854775808, ----9223372036854775808; +select -(-9223372036854775808), -(-(-9223372036854775808)); diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index bca977e6df3..1a32580aa0f 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1076,4 +1076,52 @@ SELECT * FROM (SELECT * FROM v1) x; DROP TABLE t1, t2; DROP VIEW v1; +# +# Bug #27932: LOCATE with argument evaluated to NULL +# + +SELECT LOCATE('foo', NULL) FROM DUAL; +SELECT LOCATE(NULL, 'o') FROM DUAL; +SELECT LOCATE(NULL, NULL) FROM DUAL; +SELECT LOCATE('foo', NULL) IS NULL FROM DUAL; +SELECT LOCATE(NULL, 'o') IS NULL FROM DUAL; +SELECT LOCATE(NULL, NULL) IS NULL FROM DUAL; +SELECT ISNULL(LOCATE('foo', NULL)) FROM DUAL; +SELECT ISNULL(LOCATE(NULL, 'o')) FROM DUAL; +SELECT ISNULL(LOCATE(NULL, NULL)) FROM DUAL; +SELECT LOCATE('foo', NULL) <=> NULL FROM DUAL; +SELECT LOCATE(NULL, 'o') <=> NULL FROM DUAL; +SELECT LOCATE(NULL, NULL) <=> NULL FROM DUAL; + +CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a varchar(10), p varchar(10)); + +INSERT INTO t1 VALUES (1, 'foo', 'o'); +INSERT INTO t1 VALUES (2, 'foo', NULL); +INSERT INTO t1 VALUES (3, NULL, 'o'); +INSERT INTO t1 VALUES (4, NULL, NULL); + +SELECT id, LOCATE(a,p) FROM t1; +SELECT id, LOCATE(a,p) IS NULL FROM t1; +SELECT id, ISNULL(LOCATE(a,p)) FROM t1; +SELECT id, LOCATE(a,p) <=> NULL FROM t1; +SELECT id FROM t1 WHERE LOCATE(a,p) IS NULL; +SELECT id FROM t1 WHERE LOCATE(a,p) <=> NULL; + +DROP TABLE t1; + +# +# Bug #27130: SUBSTR with UNSIGNED 0 as the last argument +# + +SELECT SUBSTR('foo',1,0) FROM DUAL; +SELECT SUBSTR('foo',1,CAST(0 AS SIGNED)) FROM DUAL; +SELECT SUBSTR('foo',1,CAST(0 AS UNSIGNED)) FROM DUAL; + +CREATE TABLE t1 (a varchar(10), len int unsigned); +INSERT INTO t1 VALUES ('bar', 2), ('foo', 0); + +SELECT SUBSTR(a,1,len) FROM t1; + +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index b3049498f90..e1010c9fcfe 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -870,3 +870,25 @@ DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x SHOW STATUS LIKE 'handler_read__e%'; DROP TABLE t1,t2,t3; + +# +# Bug#25602: queries with DISTINCT and SQL_BIG_RESULT hint +# for which loose scan optimization is applied +# + +CREATE TABLE t1 (a int, INDEX idx(a)); +INSERT INTO t1 VALUES + (4), (2), (1), (2), (4), (2), (1), (4), + (4), (2), (1), (2), (2), (4), (1), (4); + +EXPLAIN SELECT DISTINCT(a) FROM t1; +SELECT DISTINCT(a) FROM t1; +EXPLAIN SELECT SQL_BIG_RESULT DISTINCT(a) FROM t1; +SELECT SQL_BIG_RESULT DISTINCT(a) FROM t1; + +DROP TABLE t1; + + + + + diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index bbc51be6dc9..bf6dae96847 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -233,7 +233,9 @@ drop table t1,t2; CREATE TABLE t1 (a int PRIMARY KEY); INSERT INTO t1 values (1), (2); +flush status; INSERT INTO t1 SELECT a + 2 FROM t1 LIMIT 1; +show status like 'Handler_read%'; DROP TABLE t1; @@ -332,3 +334,26 @@ INSERT INTO t2 (d) SELECT * FROM t2; DROP TABLE t1,t2; + +# +# Bug #29095: incorrect pushing of LIMIT into the temporary +# table ignoring ORDER BY clause +# + +CREATE TABLE t1 ( + id INT AUTO_INCREMENT PRIMARY KEY, + prev_id INT, + join_id INT DEFAULT 0); + +INSERT INTO t1 (prev_id) VALUES (NULL), (1), (2); +SELECT * FROM t1; + +CREATE TABLE t2 (join_id INT); +INSERT INTO t2 (join_id) VALUES (0); + +INSERT INTO t1 (prev_id) SELECT id + FROM t2 LEFT JOIN t1 ON t1.join_id = t2.join_id + ORDER BY id DESC LIMIT 1; +SELECT * FROM t1; + +DROP TABLE t1,t2; diff --git a/mysql-test/t/metadata.test b/mysql-test/t/metadata.test index df4acec2021..65c062399b7 100644 --- a/mysql-test/t/metadata.test +++ b/mysql-test/t/metadata.test @@ -90,5 +90,26 @@ select a.* from (select 2147483648 as v_large) a; select a.* from (select 214748364 as v_small) a; --disable_metadata +# +# Bug #28898: table alias and database name of VIEW columns is empty in the +# metadata of # SELECT statement where join is executed via temporary table. +# + +CREATE TABLE t1 (c1 CHAR(1)); +CREATE TABLE t2 (c2 CHAR(1)); +CREATE VIEW v1 AS SELECT t1.c1 FROM t1; +CREATE VIEW v2 AS SELECT t2.c2 FROM t2; +INSERT INTO t1 VALUES ('1'), ('2'), ('3'); +INSERT INTO t2 VALUES ('1'), ('2'), ('3'), ('2'); + +--enable_metadata +SELECT v1.c1 FROM v1 JOIN t2 ON c1=c2 ORDER BY 1; +SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2; +SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2 GROUP BY v1.c1; +SELECT v1.c1, v2.c2 FROM v1 JOIN v2 ON c1=c2 GROUP BY v1.c1 ORDER BY v2.c2; +--disable_metadata + +DROP VIEW v1,v2; +DROP TABLE t1,t2; --echo End of 5.0 tests diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index ba161ddbb89..bd90dcfb930 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -203,4 +203,17 @@ flush logs; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000009 +# +# Bug#28293 missed '#' sign in the hex dump when the dump length +# is divisible by 16. +# + +CREATE TABLE t1 (c1 CHAR(10)); +# we need this for getting fixed timestamps inside of this test +flush logs; +INSERT INTO t1 VALUES ('0123456789'); +flush logs; +DROP TABLE t1; +--exec $MYSQL_BINLOG --hexdump --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000011 | grep 'Query' | sed 's/[0-9]\{1,\}/REMOVED/g' + --echo End of 5.0 tests diff --git a/mysql-test/t/rpl_change_master.test b/mysql-test/t/rpl_change_master.test index 6c055a81ceb..9dd1505af90 100644 --- a/mysql-test/t/rpl_change_master.test +++ b/mysql-test/t/rpl_change_master.test @@ -20,11 +20,11 @@ connection slave; stop slave; --replace_result $MASTER_MYPORT MASTER_MYPORT --replace_column 1 # 8 # 9 # 23 # 33 # -show slave status; +query_vertical show slave status; change master to master_user='root'; --replace_result $MASTER_MYPORT MASTER_MYPORT --replace_column 1 # 8 # 9 # 23 # 33 # -show slave status; +query_vertical show slave status; start slave; sync_with_master; select * from t1; diff --git a/mysql-test/t/rpl_skip_error.test b/mysql-test/t/rpl_skip_error.test index f6fc73f58f2..baa7a88b8bb 100644 --- a/mysql-test/t/rpl_skip_error.test +++ b/mysql-test/t/rpl_skip_error.test @@ -17,3 +17,24 @@ connection master; drop table t1; sync_with_master; # End of 4.1 tests + +# +# #28839 Errors in strict mode silently stop SQL thread if --slave-skip-errors exists +# +create table t1(a int primary key); +insert into t1 values (1),(2); +delete from t1 where @@server_id=1; +set sql_mode=strict_trans_tables; +select @@server_id; +insert into t1 values (1),(2),(3); +sync_slave_with_master; +connection slave; +select @@server_id; +select * from t1; +--replace_column 1 # 8 # 9 # 23 # 33 # +--replace_result $MASTER_MYPORT MASTER_PORT +show slave status; +connection master; +drop table t1; +sync_with_master; +# End of 5.0 tests diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 3c370da4139..f670ac8a49d 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3324,4 +3324,28 @@ SELECT * FROM t1; DROP VIEW v1,v2; DROP TABLE t1,t2,t3,t4; +# +# Bug #29104: assertion abort for a query with a view column reference +# in the GROUP BY list and a condition requiring the value +# of another view column to be equal to a constant +# + +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (1,2), (2,2), (1,3), (1,2); + +CREATE VIEW v1 AS SELECT a, b+1 as b FROM t1; + + +SELECT b, SUM(a) FROM v1 WHERE b=3 GROUP BY b; +EXPLAIN SELECT b, SUM(a) FROM v1 WHERE b=3 GROUP BY b; + +SELECT a, SUM(b) FROM v1 WHERE b=3 GROUP BY a; +EXPLAIN SELECT a, SUM(b) FROM v1 WHERE b=3 GROUP BY a; + +SELECT a, SUM(b) FROM v1 WHERE a=1 GROUP BY a; +EXPLAIN SELECT a, SUM(b) FROM v1 WHERE a=1 GROUP BY a; + +DROP VIEW v1; +DROP TABLE t1; + --echo End of 5.0 tests. diff --git a/sql/item.cc b/sql/item.cc index 32c43eaa865..a334028fd64 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1938,10 +1938,11 @@ bool Item_field::val_bool_result() bool Item_field::eq(const Item *item, bool binary_cmp) const { - if (item->type() != FIELD_ITEM) + Item *real_item= ((Item *) item)->real_item(); + if (real_item->type() != FIELD_ITEM) return 0; - Item_field *item_field= (Item_field*) item; + Item_field *item_field= (Item_field*) real_item; if (item_field->field && field) return item_field->field == field; /* @@ -5501,6 +5502,21 @@ void Item_ref::make_field(Send_field *field) } +Item *Item_ref::get_tmp_table_item(THD *thd) +{ + if (!result_field) + return (*ref)->get_tmp_table_item(thd); + + Item_field *item= new Item_field(result_field); + if (item) + { + item->table_name= table_name; + item->db_name= db_name; + } + return item; +} + + void Item_ref_null_helper::print(String *str) { str->append(STRING_WITH_LEN("(")); @@ -5627,8 +5643,7 @@ bool Item_outer_ref::fix_fields(THD *thd, Item **reference) DESCRIPTION A view column reference is considered equal to another column reference if the second one is a view column and if both column - references resolve to the same item. It is assumed that both - items are of the same type. + references resolve to the same item. RETURN TRUE Referenced item is equal to given item @@ -5644,8 +5659,6 @@ bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const if (item_ref->ref_type() == VIEW_REF) { Item *item_ref_ref= *(item_ref->ref); - DBUG_ASSERT((*ref)->real_item()->type() == - item_ref_ref->real_item()->type()); return ((*ref)->real_item() == item_ref_ref->real_item()); } } diff --git a/sql/item.h b/sql/item.h index 9268afaba0c..3478095351a 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1904,11 +1904,7 @@ public: enum_field_types field_type() const { return (*ref)->field_type(); } Field *get_tmp_table_field() { return result_field ? result_field : (*ref)->get_tmp_table_field(); } - Item *get_tmp_table_item(THD *thd) - { - return (result_field ? new Item_field(result_field) : - (*ref)->get_tmp_table_item(thd)); - } + Item *get_tmp_table_item(THD *thd); table_map used_tables() const { return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables(); diff --git a/sql/item_func.cc b/sql/item_func.cc index ab4a9c50332..b256ce4624a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1523,16 +1523,20 @@ void Item_func_neg::fix_length_and_dec() Use val() to get value as arg_type doesn't mean that item is Item_int or Item_real due to existence of Item_param. */ - if (hybrid_type == INT_RESULT && - args[0]->type() == INT_ITEM && - ((ulonglong) args[0]->val_int() >= (ulonglong) LONGLONG_MIN)) + if (hybrid_type == INT_RESULT && args[0]->const_item()) { - /* - Ensure that result is converted to DECIMAL, as longlong can't hold - the negated number - */ - hybrid_type= DECIMAL_RESULT; - DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT")); + longlong val= args[0]->val_int(); + if ((ulonglong) val >= (ulonglong) LONGLONG_MIN && + ((ulonglong) val != (ulonglong) LONGLONG_MIN || + args[0]->type() != INT_ITEM)) + { + /* + Ensure that result is converted to DECIMAL, as longlong can't hold + the negated number + */ + hybrid_type= DECIMAL_RESULT; + DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT")); + } } unsigned_flag= 0; DBUG_VOID_RETURN; @@ -2507,7 +2511,6 @@ longlong Item_func_coercibility::val_int() void Item_func_locate::fix_length_and_dec() { - maybe_null= 0; max_length= MY_INT32_NUM_DECIMAL_DIGITS; agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 33e9b8de823..0c24f14c8fe 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1145,8 +1145,9 @@ String *Item_func_substr::val_str(String *str) (arg_count == 3 && args[2]->null_value)))) return 0; /* purecov: inspected */ - /* Negative length, will return empty string. */ - if ((arg_count == 3) && (length <= 0) && !args[2]->unsigned_flag) + /* Negative or zero length, will return empty string. */ + if ((arg_count == 3) && (length <= 0) && + (length == 0 || !args[2]->unsigned_flag)) return &my_empty_string; /* Assumes that the maximum length of a String is < INT_MAX32. */ diff --git a/sql/log_event.cc b/sql/log_event.cc index 4d9fde9f9df..c37df31ae00 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1001,11 +1001,15 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info) } *c= '\0'; - /* Non-full last line */ if (hex_string[0]) + { + /* Non-full last line */ fprintf(file, "# %8.8lx %-48.48s |%s|\n# ", (unsigned long) (hexdump_from + (i & 0xfffffff0)), hex_string, char_string); + } + else + fprintf(file, "# "); } } @@ -1964,6 +1968,7 @@ Default database: '%s'. Query: '%s'", { DBUG_PRINT("info",("error ignored")); clear_all_errors(thd, rli); + thd->killed= THD::NOT_KILLED; } /* Other cases: mostly we expected no error and get one. diff --git a/sql/net_serv.cc b/sql/net_serv.cc index c56e9c0b073..017a2eb9ecd 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -120,13 +120,13 @@ static my_bool net_write_buff(NET *net,const char *packet,ulong len); my_bool my_net_init(NET *net, Vio* vio) { DBUG_ENTER("my_net_init"); + net->vio = vio; my_net_local_init(net); /* Set some limits */ if (!(net->buff=(uchar*) my_malloc((uint32) net->max_packet+ NET_HEADER_SIZE + COMP_HEADER_SIZE, MYF(MY_WME)))) DBUG_RETURN(1); net->buff_end=net->buff+net->max_packet; - net->vio = vio; net->no_send_ok= net->no_send_eof= net->no_send_error= 0; net->error=0; net->return_errno=0; net->return_status=0; net->pkt_nr=net->compress_pkt_nr=0; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 36c0988021f..118de99bc6e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1347,8 +1347,7 @@ JOIN::optimize() there are aggregate functions, because in all these cases we need all result rows. */ - ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order || - test(select_options & OPTION_BUFFER_RESULT)) && + ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order) && !tmp_group && !thd->lex->current_select->with_sum_func) ? select_limit : HA_POS_ERROR; @@ -12552,10 +12551,14 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, /* When there is SQL_BIG_RESULT do not sort using index for GROUP BY, - and thus force sorting on disk. + and thus force sorting on disk unless a group min-max optimization + is going to be used as it is applied now only for one table queries + with covering indexes. */ if ((order != join->group_list || - !(join->select_options & SELECT_BIG_RESULT)) && + !(join->select_options & SELECT_BIG_RESULT) || + select && select->quick && + select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) && test_if_skip_sort_order(tab,order,select_limit,0)) DBUG_RETURN(0); for (ORDER *ord= join->order; ord; ord= ord->next) @@ -14245,6 +14248,13 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, if (!item_field) DBUG_RETURN(TRUE); // Fatal error item_field->name= item->name; + if (item->type() == Item::REF_ITEM) + { + Item_field *ifield= (Item_field *) item_field; + Item_ref *iref= (Item_ref *) item; + ifield->table_name= iref->table_name; + ifield->db_name= iref->db_name; + } #ifndef DBUG_OFF if (_db_on_ && !item_field->name) {