diff options
44 files changed, 710 insertions, 197 deletions
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index 88d59555f5b..b4c4aab621d 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12851,3 +12851,14 @@ OPTIMIZE TABLE t1; Table Op Msg_type Msg_text test.t1 optimize status OK DROP TABLE t1; +# +# BUG#917689 Using wrong archive table causes crash +# +create table t1 (a int, b char(50)) engine=archive; +select * from t1; +ERROR HY000: Table 't1' is marked as crashed and should be repaired +show warnings; +Level Code Message +Warning 127 Got error 127 when reading table `test`.`t1` +Error 1194 Table 't1' is marked as crashed and should be repaired +drop table t1; diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index c60ef213e8f..5a3d547d6b3 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -1970,6 +1970,42 @@ ON ( COLUMNS.TABLE_SCHEMA = UNIQUES.TABLE_SCHEMA); COUNT(*) > 0 1 DROP TABLE t1; -set SESSION optimizer_switch= @save_optimizer_switch; +SET SESSION optimizer_switch= @save_optimizer_switch; +# +# LP BUG#953649: crash when estimating the cost of a look-up +# into a derived table to be materialized +# +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (132); +CREATE TABLE t2 (b int, c varchar(256)); +INSERT INTO t2 VALUES (132,'test1'), (120,'text2'), (132,'text3'); +CREATE VIEW v AS +SELECT b, GROUP_CONCAT(c) AS gc FROM t2 GROUP BY b; +SET @save_optimizer_switch=@@optimizer_switch; +SET SESSION optimizer_switch='derived_merge=off'; +SET SESSION optimizer_switch='derived_with_keys=off'; +EXPLAIN +SELECT * FROM t1, v WHERE a = b; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using where +2 DERIVED t2 ALL NULL NULL NULL NULL 3 Using filesort +SELECT * FROM t1, v WHERE a = b; +a b gc +132 132 test1,text3 +SET SESSION optimizer_switch='derived_merge=on'; +SET SESSION optimizer_switch='derived_with_keys=on'; +EXPLAIN +SELECT * FROM t1, v WHERE a = b; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +1 PRIMARY <derived2> ref key0 key0 5 const 0 +2 DERIVED t2 ALL NULL NULL NULL NULL 3 Using filesort +SELECT * FROM t1, v WHERE a = b; +a b gc +132 132 test1,text3 +SET SESSION optimizer_switch= @save_optimizer_switch; +DROP VIEW v; +DROP TABLE t1,t2; set optimizer_switch=@exit_optimizer_switch; set join_cache_level=@exit_join_cache_level; diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 6ac8a8bbd5f..c38201f6d9f 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1887,6 +1887,53 @@ NULL NULL DROP TABLE t1,t2,t3; # +# Bug #884175: MIN/MAX for short varchar = long const +# +CREATE TABLE t1 (f1 varchar(1), f2 varchar(1), KEY (f2)); +INSERT INTO t1 VALUES ('b', 'b'), ('a','a'); +EXPLAIN +SELECT MAX(f1) FROM t1 WHERE f1 = 'abc'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT MAX(f1) FROM t1 WHERE f1 = 'abc'; +MAX(f1) +NULL +EXPLAIN +SELECT MAX(f2) FROM t1 WHERE f2 = 'abc'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref f2 f2 4 const 1 Using where; Using index +SELECT MAX(f2) FROM t1 WHERE f2 = 'abc'; +MAX(f2) +NULL +EXPLAIN +SELECT MIN(f1) FROM t1 WHERE f1 >= 'abc'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT MIN(f1) FROM t1 WHERE f1 >= 'abc'; +MIN(f1) +b +EXPLAIN +SELECT MIN(f2) FROM t1 WHERE f2 >= 'abc'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index f2 f2 4 NULL 2 Using where; Using index +SELECT MIN(f2) FROM t1 WHERE f2 >= 'abc'; +MIN(f2) +b +EXPLAIN +SELECT MIN(f1) FROM t1 WHERE f1 BETWEEN 'abc' AND 'b' ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT MIN(f1) FROM t1 WHERE f1 BETWEEN 'abc' AND 'b' ; +MIN(f1) +b +EXPLAIN +SELECT MIN(f2) FROM t1 WHERE f2 BETWEEN 'abc' AND 'b' ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index f2 f2 4 NULL 2 Using where; Using index +SELECT MIN(f2) FROM t1 WHERE f2 BETWEEN 'abc' AND 'b' ; +MIN(f2) +b +DROP TABLE t1; End of 5.2 tests # # BUG#46680 - Assertion failed in file item_subselect.cc, diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index b57bc21524e..cffed9529d6 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -1948,6 +1948,52 @@ DROP TABLE t1; SET SQL_BIG_TABLES=0; # End of 5.1 tests # +# LP bug#694450 Wrong result with non-standard GROUP BY + ORDER BY +# +SET SESSION SQL_MODE='ONLY_FULL_GROUP_BY'; +CREATE TABLE t1 ( +f1 int(11), f2 int(11), f3 datetime, f4 varchar(1), PRIMARY KEY (f1)) ; +INSERT IGNORE INTO t1 VALUES ('1','9','2004-10-11 18:13','x'),('2','5','2004-03-07 14:02','g'),('3','1','2004-04-09 09:38','o'),('4','0','1900-01-01 00:00','g'),('5','1','2009-02-19 02:05','v'); +SELECT alias2.f3 AS field1 , alias2.f1 AS field2 FROM t1 AS alias1 JOIN t1 AS alias2 ON alias2.f1 = alias1.f2 AND alias2.f1 != alias1.f4 GROUP BY field1 , field2 ORDER BY alias1.f2 , field2; +field1 field2 +2004-10-11 18:13:00 1 +2009-02-19 02:05:00 5 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'g' +Warning 1292 Truncated incorrect DOUBLE value: 'o' +Warning 1292 Truncated incorrect DOUBLE value: 'g' +Warning 1292 Truncated incorrect DOUBLE value: 'v' +SELECT alias2.f3 AS field1 , alias2.f1 AS field2 FROM t1 AS alias1 JOIN t1 AS alias2 ON alias2.f1 = alias1.f2 AND alias2.f1 != alias1.f4 GROUP BY field1 , field2 ; +field1 field2 +2004-10-11 18:13:00 1 +2009-02-19 02:05:00 5 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'x' +Warning 1292 Truncated incorrect DOUBLE value: 'g' +Warning 1292 Truncated incorrect DOUBLE value: 'o' +Warning 1292 Truncated incorrect DOUBLE value: 'g' +Warning 1292 Truncated incorrect DOUBLE value: 'v' +SET SESSION SQL_MODE=default; +drop table t1; +# End of 5.2 tests +# +# lp:872702: Crash in add_ref_to_table_cond() when grouping by a PK +# +CREATE TABLE t1 (a int, PRIMARY KEY (a)) ; +INSERT INTO t1 VALUES (14),(15),(16),(17),(18),(19),(20); +CREATE TABLE t2 (a int) ; +SELECT a +FROM t1 +WHERE a = ( +SELECT t2.a +FROM t2 +) OR t1.a = 73 +GROUP BY 1; +a +DROP TABLE t1, t2; +# End of 5.3 tests +# # Bug#49771: Incorrect MIN (date) when minimum value is 0000-00-00 # CREATE TABLE t1 (f1 int, f2 DATE); @@ -1976,18 +2022,3 @@ f1 MIN(f2) MAX(f2) 4 00:25:00 00:25:00 DROP TABLE t1; #End of test#49771 -# -# lp:872702: Crash in add_ref_to_table_cond() when grouping by a PK -# -CREATE TABLE t1 (a int, PRIMARY KEY (a)) ; -INSERT INTO t1 VALUES (14),(15),(16),(17),(18),(19),(20); -CREATE TABLE t2 (a int) ; -SELECT a -FROM t1 -WHERE a = ( -SELECT t2.a -FROM t2 -) OR t1.a = 73 -GROUP BY 1; -a -DROP TABLE t1, t2; diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index b5e511e1f39..86442df1e8b 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -1964,6 +1964,28 @@ a c SET optimizer_switch=@save_optimizer_switch; SET join_cache_level=@save_join_cache_level; DROP TABLE t1,t2; +# +# BUG#952297: Server crashes on 2nd execution of PS in Field::is_null with semijoin+materialization +# +CREATE TABLE t1 ( a VARCHAR(1) ); +INSERT INTO t1 VALUES ('y'),('z'); +CREATE TABLE t2 ( b VARCHAR(1), c VARCHAR(1) ); +INSERT INTO t2 VALUES ('v','v'),('v','v'); +CREATE VIEW v2 AS SELECT * FROM t2; +PREPARE ps FROM ' +SELECT a FROM t1, v2 +WHERE ( c, b ) IN ( SELECT b, b FROM t2 ) +GROUP BY a '; +EXECUTE ps; +a +y +z +EXECUTE ps; +a +y +z +DROP VIEW v2; +DROP TABLE t1, t2; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index f06fe52393d..5729e86ce70 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -2004,6 +2004,28 @@ a c SET optimizer_switch=@save_optimizer_switch; SET join_cache_level=@save_join_cache_level; DROP TABLE t1,t2; +# +# BUG#952297: Server crashes on 2nd execution of PS in Field::is_null with semijoin+materialization +# +CREATE TABLE t1 ( a VARCHAR(1) ); +INSERT INTO t1 VALUES ('y'),('z'); +CREATE TABLE t2 ( b VARCHAR(1), c VARCHAR(1) ); +INSERT INTO t2 VALUES ('v','v'),('v','v'); +CREATE VIEW v2 AS SELECT * FROM t2; +PREPARE ps FROM ' +SELECT a FROM t1, v2 +WHERE ( c, b ) IN ( SELECT b, b FROM t2 ) +GROUP BY a '; +EXECUTE ps; +a +y +z +EXECUTE ps; +a +y +z +DROP VIEW v2; +DROP TABLE t1, t2; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/std_data/t917689.ARZ b/mysql-test/std_data/t917689.ARZ Binary files differnew file mode 100644 index 00000000000..4770ca0c257 --- /dev/null +++ b/mysql-test/std_data/t917689.ARZ diff --git a/mysql-test/suite/innodb/r/innodb_corrupt_bit.result b/mysql-test/suite/innodb/r/innodb_corrupt_bit.result index 7e8792bb5b4..13b1e24a9ed 100644 --- a/mysql-test/suite/innodb/r/innodb_corrupt_bit.result +++ b/mysql-test/suite/innodb/r/innodb_corrupt_bit.result @@ -46,6 +46,7 @@ ERROR HY000: Index corrupt_bit_test_Ä is corrupted show warnings; Level Code Message Warning 179 InnoDB: Index "idxÄ“" for table "test"."corrupt_bit_test_Ä" is marked as corrupted +Warning 179 Got error 179 when reading table `test`.`corrupt_bit_test_Ä` Error 1712 Index corrupt_bit_test_Ä is corrupted insert into corrupt_bit_test_Ä values (10001, "a", 20001, 20001); select * from corrupt_bit_test_Ä use index(primary) where a = 10001; diff --git a/mysql-test/suite/maria/r/maria-ucs2.result b/mysql-test/suite/maria/r/maria-ucs2.result new file mode 100644 index 00000000000..e7258f21d4f --- /dev/null +++ b/mysql-test/suite/maria/r/maria-ucs2.result @@ -0,0 +1,39 @@ +select * from INFORMATION_SCHEMA.ENGINES where ENGINE="ARIA"; +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +Aria YES Crash-safe tables with MyISAM heritage NO NO NO +set global storage_engine=aria; +set session storage_engine=aria; +drop table if exists t1; +SET SQL_WARNINGS=1; +CREATE TABLE t1 ( a VARCHAR(800),KEY(a) ) +ENGINE=Aria DEFAULT CHARACTER SET latin1; +INSERT INTO t1 VALUES +(REPEAT('abc ',200)), (REPEAT('def ',200)), +(REPEAT('ghi ',200)), (REPEAT('jkl ',200)); +INSERT INTO t1 SELECT * FROM t1; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +ALTER TABLE t1 MODIFY a VARCHAR(800) CHARSET `ucs2`; +Warnings: +Warning 1071 Specified key was too long; max key length is 1000 bytes +Warning 1071 Specified key was too long; max key length is 1000 bytes +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SHOW CREATE table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(800) CHARACTER SET ucs2 DEFAULT NULL, + KEY `a` (`a`(500)) +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(800),KEY(a)) ENGINE=Aria CHARACTER SET ucs2; +Warnings: +Warning 1071 Specified key was too long; max key length is 1000 bytes +INSERT INTO t1 VALUES (REPEAT('abc ',200)); +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +# End of 5.2 tests diff --git a/mysql-test/suite/maria/r/maria3.result b/mysql-test/suite/maria/r/maria3.result index 63f5af57396..37613875f38 100644 --- a/mysql-test/suite/maria/r/maria3.result +++ b/mysql-test/suite/maria/r/maria3.result @@ -392,6 +392,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +set global aria_page_checksum=0; drop table t1; set global aria_log_file_size=4294967296; Warnings: @@ -508,7 +509,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `n` int(11) NOT NULL, `c` char(1) DEFAULT NULL -) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 drop table t1; create table t1 (n int not null, c char(1)) engine=aria transactional=1; alter table t1 engine=myisam; @@ -520,7 +521,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `n` int(11) NOT NULL, `c` char(1) DEFAULT NULL -) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 TRANSACTIONAL=1 drop table t1; create table t1 (n int not null, c char(1)) engine=myisam transactional=1; Warnings: @@ -531,7 +532,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `n` int(11) NOT NULL, `c` char(1) DEFAULT NULL -) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1 +) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 TRANSACTIONAL=1 drop table t1; create table t1 (a int, key(a)) transactional=0; insert into t1 values (0),(1),(2),(3),(4); @@ -644,29 +645,7 @@ a b c d e f g h i j 1 A B C D 1 M H 2 Abcdefghi E F G 2 N H drop table t1,t2; -CREATE TABLE t1 ( a VARCHAR(800),KEY(a) ) -ENGINE=Aria DEFAULT CHARACTER SET latin1; -INSERT INTO t1 VALUES -(REPEAT('abc ',200)), (REPEAT('def ',200)), -(REPEAT('ghi ',200)), (REPEAT('jkl ',200)); -INSERT INTO t1 SELECT * FROM t1; -CHECK TABLE t1; -Table Op Msg_type Msg_text -test.t1 check status OK -ALTER TABLE t1 MODIFY a VARCHAR(800) CHARSET `ucs2`; -Warnings: -Warning 1071 Specified key was too long; max key length is 1000 bytes -Warning 1071 Specified key was too long; max key length is 1000 bytes -CHECK TABLE t1; -Table Op Msg_type Msg_text -test.t1 check status OK -SHOW CREATE table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `a` varchar(800) CHARACTER SET ucs2 DEFAULT NULL, - KEY `a` (`a`(500)) -) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 -DROP TABLE t1; +# End of 5.1 tests create table t1 (a int) engine=aria; lock table t1 write; drop table t1; diff --git a/mysql-test/suite/maria/t/maria-ucs2.test b/mysql-test/suite/maria/t/maria-ucs2.test new file mode 100644 index 00000000000..fed67d780e9 --- /dev/null +++ b/mysql-test/suite/maria/t/maria-ucs2.test @@ -0,0 +1,51 @@ +-- source include/have_maria.inc +-- source include/have_ucs2.inc + +select * from INFORMATION_SCHEMA.ENGINES where ENGINE="ARIA"; + +let $default_engine=`select @@global.storage_engine`; +set global storage_engine=aria; +set session storage_engine=aria; + +# Initialise +--disable_warnings +drop table if exists t1; +--enable_warnings +SET SQL_WARNINGS=1; + +# +# bug#905716: Assertion `page->size <= share->max_index_block_size' +# + +CREATE TABLE t1 ( a VARCHAR(800),KEY(a) ) + ENGINE=Aria DEFAULT CHARACTER SET latin1; +INSERT INTO t1 VALUES + (REPEAT('abc ',200)), (REPEAT('def ',200)), + (REPEAT('ghi ',200)), (REPEAT('jkl ',200)); +INSERT INTO t1 SELECT * FROM t1; +# check table is not needed to reproduce the problem, +# but shows that by this time the table appears to be okay. +CHECK TABLE t1; +ALTER TABLE t1 MODIFY a VARCHAR(800) CHARSET `ucs2`; +CHECK TABLE t1; +SHOW CREATE table t1; +DROP TABLE t1; + +# +# BUG#905782 Assertion `pageno < ((1ULL) << 40)' failed at ma_pagecache.c +# Issue was too long key +# + +CREATE TABLE t1 (a VARCHAR(800),KEY(a)) ENGINE=Aria CHARACTER SET ucs2; +INSERT INTO t1 VALUES (REPEAT('abc ',200)); +CHECK TABLE t1; +DROP TABLE t1; + +--echo # End of 5.2 tests + + +--disable_result_log +--disable_query_log +eval set global storage_engine=$default_engine; +--enable_result_log +--enable_query_log diff --git a/mysql-test/suite/maria/t/maria3.test b/mysql-test/suite/maria/t/maria3.test index 62073b10102..f1d95a15ba5 100644 --- a/mysql-test/suite/maria/t/maria3.test +++ b/mysql-test/suite/maria/t/maria3.test @@ -304,6 +304,7 @@ drop table t1; set global aria_page_checksum=1; create table t1 (a int); show create table t1; +set global aria_page_checksum=0; drop table t1; # @@ -553,27 +554,7 @@ INSERT INTO t2 VALUES (1,'M','','H'), SELECT * FROM t1, t2 WHERE a = g ORDER BY b; drop table t1,t2; -# End of 5.1 tests - -# -# bug#905716: Assertion `page->size <= share->max_index_block_size' -# - -CREATE TABLE t1 ( a VARCHAR(800),KEY(a) ) - ENGINE=Aria DEFAULT CHARACTER SET latin1; -INSERT INTO t1 VALUES - (REPEAT('abc ',200)), (REPEAT('def ',200)), - (REPEAT('ghi ',200)), (REPEAT('jkl ',200)); -INSERT INTO t1 SELECT * FROM t1; -# check table is not needed to reproduce the problem, -# but shows that by this time the table appears to be okay. -CHECK TABLE t1; -ALTER TABLE t1 MODIFY a VARCHAR(800) CHARSET `ucs2`; -CHECK TABLE t1; -SHOW CREATE table t1; -DROP TABLE t1; - -# End of 5.2 tests +--echo # End of 5.1 tests create table t1 (a int) engine=aria; lock table t1 write; diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result index 693ea0d9174..c27b36089c6 100644 --- a/mysql-test/suite/vcol/r/vcol_misc.result +++ b/mysql-test/suite/vcol/r/vcol_misc.result @@ -133,6 +133,19 @@ t1 CREATE TABLE `t1` ( `v` char(32) CHARACTER SET ucs2 AS (a) VIRTUAL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; +CREATE TABLE t1 (a int, b int); +CREATE TABLE t2 (a int, b int as (a+1) VIRTUAL); +SELECT table_schema, table_name, column_name, column_type, extra +FROM information_schema.columns WHERE table_name = 't1'; +table_schema table_name column_name column_type extra +test t1 a int(11) +test t1 b int(11) +SELECT table_schema, table_name, column_name, column_type, extra +FROM information_schema.columns WHERE table_name = 't2'; +table_schema table_name column_name column_type extra +test t2 a int(11) +test t2 b int(11) VIRTUAL +DROP TABLE t1,t2; create table t1 (a int, b int); insert into t1 values (3, 30), (4, 20), (1, 20); create table t2 (c int, d int, v int as (d+1), index idx(c)); diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test index f87cb5fbec8..6f576f61513 100644 --- a/mysql-test/suite/vcol/t/vcol_misc.test +++ b/mysql-test/suite/vcol/t/vcol_misc.test @@ -142,6 +142,20 @@ SHOW CREATE TABLE t1; DROP TABLE t1; # +# Bug#930814: no info in information schema for tables with virtual columns +# + +CREATE TABLE t1 (a int, b int); +CREATE TABLE t2 (a int, b int as (a+1) VIRTUAL); + +SELECT table_schema, table_name, column_name, column_type, extra + FROM information_schema.columns WHERE table_name = 't1'; +SELECT table_schema, table_name, column_name, column_type, extra + FROM information_schema.columns WHERE table_name = 't2'; + +DROP TABLE t1,t2; + +# # SELECT that uses a virtual column and executed with BKA # diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index d979ba509d5..5dd85bf1aba 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1769,3 +1769,14 @@ CHECKSUM TABLE t1 EXTENDED; FLUSH TABLE t1; OPTIMIZE TABLE t1; DROP TABLE t1; + +--echo # +--echo # BUG#917689 Using wrong archive table causes crash +--echo # +create table t1 (a int, b char(50)) engine=archive; +--remove_file $MYSQLD_DATADIR/test/t1.ARZ +copy_file std_data/t917689.ARZ $MYSQLD_DATADIR/test/t1.ARZ; +--error 1194 +select * from t1; +show warnings; +drop table t1; diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test index 9660dd1e5f5..d1ed2ff5ba6 100644 --- a/mysql-test/t/derived_view.test +++ b/mysql-test/t/derived_view.test @@ -1345,7 +1345,40 @@ SELECT COUNT(*) > 0 DROP TABLE t1; -set SESSION optimizer_switch= @save_optimizer_switch; +SET SESSION optimizer_switch= @save_optimizer_switch; + +--echo # +--echo # LP BUG#953649: crash when estimating the cost of a look-up +--echo # into a derived table to be materialized +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (132); + +CREATE TABLE t2 (b int, c varchar(256)); +INSERT INTO t2 VALUES (132,'test1'), (120,'text2'), (132,'text3'); + +CREATE VIEW v AS + SELECT b, GROUP_CONCAT(c) AS gc FROM t2 GROUP BY b; + +SET @save_optimizer_switch=@@optimizer_switch; + +SET SESSION optimizer_switch='derived_merge=off'; +SET SESSION optimizer_switch='derived_with_keys=off'; +EXPLAIN +SELECT * FROM t1, v WHERE a = b; +SELECT * FROM t1, v WHERE a = b; + +SET SESSION optimizer_switch='derived_merge=on'; +SET SESSION optimizer_switch='derived_with_keys=on'; +EXPLAIN +SELECT * FROM t1, v WHERE a = b; +SELECT * FROM t1, v WHERE a = b; + +SET SESSION optimizer_switch= @save_optimizer_switch; + +DROP VIEW v; +DROP TABLE t1,t2; # The following command must be the last one the file set optimizer_switch=@exit_optimizer_switch; diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 7a098c44e5b..89c6c0fe534 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -1198,6 +1198,39 @@ SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3; DROP TABLE t1,t2,t3; --echo # +--echo # Bug #884175: MIN/MAX for short varchar = long const +--echo # + +CREATE TABLE t1 (f1 varchar(1), f2 varchar(1), KEY (f2)); +INSERT INTO t1 VALUES ('b', 'b'), ('a','a'); + +EXPLAIN +SELECT MAX(f1) FROM t1 WHERE f1 = 'abc'; +SELECT MAX(f1) FROM t1 WHERE f1 = 'abc'; + +EXPLAIN +SELECT MAX(f2) FROM t1 WHERE f2 = 'abc'; +SELECT MAX(f2) FROM t1 WHERE f2 = 'abc'; + +EXPLAIN +SELECT MIN(f1) FROM t1 WHERE f1 >= 'abc'; +SELECT MIN(f1) FROM t1 WHERE f1 >= 'abc'; + +EXPLAIN +SELECT MIN(f2) FROM t1 WHERE f2 >= 'abc'; +SELECT MIN(f2) FROM t1 WHERE f2 >= 'abc'; + +EXPLAIN +SELECT MIN(f1) FROM t1 WHERE f1 BETWEEN 'abc' AND 'b' ; +SELECT MIN(f1) FROM t1 WHERE f1 BETWEEN 'abc' AND 'b' ; + +EXPLAIN +SELECT MIN(f2) FROM t1 WHERE f2 BETWEEN 'abc' AND 'b' ; +SELECT MIN(f2) FROM t1 WHERE f2 BETWEEN 'abc' AND 'b' ; + +DROP TABLE t1; + + --echo End of 5.2 tests --echo # diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index 9e9df515bd2..db8bfce2320 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -1324,27 +1324,23 @@ SET SQL_BIG_TABLES=0; --echo # End of 5.1 tests --echo # ---echo # Bug#49771: Incorrect MIN (date) when minimum value is 0000-00-00 +--echo # LP bug#694450 Wrong result with non-standard GROUP BY + ORDER BY --echo # -CREATE TABLE t1 (f1 int, f2 DATE); - -INSERT INTO t1 VALUES (1,'2004-04-19'), (1,'0000-00-00'), (1,'2004-04-18'), -(2,'2004-05-19'), (2,'0001-01-01'), (3,'2004-04-10'); - -SELECT MIN(f2),MAX(f2) FROM t1; -SELECT f1,MIN(f2),MAX(f2) FROM t1 GROUP BY 1; +SET SESSION SQL_MODE='ONLY_FULL_GROUP_BY'; +CREATE TABLE t1 ( +f1 int(11), f2 int(11), f3 datetime, f4 varchar(1), PRIMARY KEY (f1)) ; +INSERT IGNORE INTO t1 VALUES ('1','9','2004-10-11 18:13','x'),('2','5','2004-03-07 14:02','g'),('3','1','2004-04-09 09:38','o'),('4','0','1900-01-01 00:00','g'),('5','1','2009-02-19 02:05','v'); -DROP TABLE t1; +# This must return an error, but instead returns 1 row +SELECT alias2.f3 AS field1 , alias2.f1 AS field2 FROM t1 AS alias1 JOIN t1 AS alias2 ON alias2.f1 = alias1.f2 AND alias2.f1 != alias1.f4 GROUP BY field1 , field2 ORDER BY alias1.f2 , field2; -CREATE TABLE t1 ( f1 int, f2 time); -INSERT INTO t1 VALUES (1,'01:27:35'), (1,'06:11:01'), (2,'19:53:05'), -(2,'21:44:25'), (3,'10:55:12'), (3,'05:45:11'), (4,'00:25:00'); +# This returns several rows +SELECT alias2.f3 AS field1 , alias2.f1 AS field2 FROM t1 AS alias1 JOIN t1 AS alias2 ON alias2.f1 = alias1.f2 AND alias2.f1 != alias1.f4 GROUP BY field1 , field2 ; +SET SESSION SQL_MODE=default; +drop table t1; -SELECT MIN(f2),MAX(f2) FROM t1; -SELECT f1,MIN(f2),MAX(f2) FROM t1 GROUP BY 1; +--echo # End of 5.2 tests -DROP TABLE t1; ---echo #End of test#49771 --echo # --echo # lp:872702: Crash in add_ref_to_table_cond() when grouping by a PK --echo # @@ -1362,3 +1358,27 @@ WHERE a = ( GROUP BY 1; DROP TABLE t1, t2; +--echo # End of 5.3 tests + +--echo # +--echo # Bug#49771: Incorrect MIN (date) when minimum value is 0000-00-00 +--echo # +CREATE TABLE t1 (f1 int, f2 DATE); + +INSERT INTO t1 VALUES (1,'2004-04-19'), (1,'0000-00-00'), (1,'2004-04-18'), +(2,'2004-05-19'), (2,'0001-01-01'), (3,'2004-04-10'); + +SELECT MIN(f2),MAX(f2) FROM t1; +SELECT f1,MIN(f2),MAX(f2) FROM t1 GROUP BY 1; + +DROP TABLE t1; + +CREATE TABLE t1 ( f1 int, f2 time); +INSERT INTO t1 VALUES (1,'01:27:35'), (1,'06:11:01'), (2,'19:53:05'), +(2,'21:44:25'), (3,'10:55:12'), (3,'05:45:11'), (4,'00:25:00'); + +SELECT MIN(f2),MAX(f2) FROM t1; +SELECT f1,MIN(f2),MAX(f2) FROM t1 GROUP BY 1; + +DROP TABLE t1; +--echo #End of test#49771 diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 09deb057ea0..cafa7f0a551 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -194,12 +194,15 @@ begin insert into test.t1 values (x, z); end| +let $start_value= `SELECT @@max_join_size`| call mixset("mixset", 19)| show variables like 'max_join_size'| select id,data,@z from t1| delete from t1| drop procedure mixset| - +--disable_query_log +eval SET @@max_join_size= $start_value| +--enable_query_log # Multiple CALL statements, one with OUT parameter. --disable_warnings diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index ba260b7d8c3..a077e9b5af5 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -1642,6 +1642,28 @@ SET join_cache_level=@save_join_cache_level; DROP TABLE t1,t2; +--echo # +--echo # BUG#952297: Server crashes on 2nd execution of PS in Field::is_null with semijoin+materialization +--echo # +CREATE TABLE t1 ( a VARCHAR(1) ); +INSERT INTO t1 VALUES ('y'),('z'); + +CREATE TABLE t2 ( b VARCHAR(1), c VARCHAR(1) ); +INSERT INTO t2 VALUES ('v','v'),('v','v'); + +CREATE VIEW v2 AS SELECT * FROM t2; + +PREPARE ps FROM ' +SELECT a FROM t1, v2 +WHERE ( c, b ) IN ( SELECT b, b FROM t2 ) +GROUP BY a '; + +EXECUTE ps; +EXECUTE ps; + +DROP VIEW v2; +DROP TABLE t1, t2; + --echo # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index db51195db25..c4c863404b4 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -661,10 +661,9 @@ void my_print_stacktrace(uchar* unused1, ulong unused2) my_safe_printf_stderr("%s!", base_image_name); } if(have_symbol) - my_safe_printf_stderr("%s()", package.sym.Name); - + fprintf(stderr, "%s()", package.sym.Name); else if(have_module) - my_safe_printf_stderr("%s", "???"); + fprintf(stderr,"%s", "???"); if(have_source) { @@ -672,7 +671,7 @@ void my_print_stacktrace(uchar* unused1, ulong unused2) my_safe_printf_stderr("[%s:%u]", base_file_name, line.LineNumber); } - my_safe_printf_stderr("%s", "\n"); + fprintf(stderr,"%s", "\n"); } } @@ -746,10 +745,7 @@ void my_safe_print_str(const char *val, int len) #ifdef __WIN__ size_t my_write_stderr(const void *buf, size_t count) { - DWORD bytes_written; - SetFilePointer(GetStdHandle(STD_ERROR_HANDLE), 0, NULL, FILE_END); - WriteFile(GetStdHandle(STD_ERROR_HANDLE), buf, count, &bytes_written, NULL); - return bytes_written; + return fwrite(buf, 1, count, stderr); } #else size_t my_write_stderr(const void *buf, size_t count) diff --git a/sql/field.cc b/sql/field.cc index f0f0ca2c8f4..f5b43c69f63 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1496,11 +1496,13 @@ Field::pack(uchar *to, const uchar *from, uint max_length) data @return New pointer into memory based on from + length of the data + @return 0 if wrong data */ const uchar * -Field::unpack(uchar* to, const uchar *from, uint param_data) +Field::unpack(uchar* to, const uchar *from, const uchar *from_end, + uint param_data) { - uint length=pack_length(); + uint length=pack_length(), len; int from_type= 0; /* If from length is > 255, it has encoded data in the upper bits. Need @@ -1516,14 +1518,19 @@ Field::unpack(uchar* to, const uchar *from, uint param_data) (length == param_data) || (from_type != real_type())) { + if (from + length > from_end) + return 0; // Error in data + memcpy(to, from, length); return from+length; } - uint len= (param_data && (param_data < length)) ? - param_data : length; + len= (param_data && (param_data < length)) ? param_data : length; + + if (from + len > from_end) + return 0; // Error in data - memcpy(to, from, param_data > length ? length : len); + memcpy(to, from, len); return from+len; } @@ -2907,10 +2914,11 @@ uint Field_new_decimal::is_equal(Create_field *new_field) @return New pointer into memory based on from + length of the data */ const uchar * -Field_new_decimal::unpack(uchar* to, const uchar *from, uint param_data) +Field_new_decimal::unpack(uchar* to, const uchar *from, const uchar *from_end, + uint param_data) { if (param_data == 0) - return Field::unpack(to, from, param_data); + return Field::unpack(to, from, from_end, param_data); uint from_precision= (param_data & 0xff00) >> 8U; uint from_decimal= param_data & 0x00ff; @@ -2940,7 +2948,11 @@ Field_new_decimal::unpack(uchar* to, const uchar *from, uint param_data) decimal2bin(&dec_val, to, precision, decimals()); } else + { + if (from + len > from_end) + return 0; // Wrong data memcpy(to, from, len); // Sizes are the same, just copy the data. + } return from+len; } @@ -6369,7 +6381,8 @@ uchar *Field_string::pack(uchar *to, const uchar *from, uint max_length) @return New pointer into memory based on from + length of the data */ const uchar * -Field_string::unpack(uchar *to, const uchar *from, uint param_data) +Field_string::unpack(uchar *to, const uchar *from, const uchar *from_end, + uint param_data) { uint from_length, length; @@ -6391,11 +6404,19 @@ Field_string::unpack(uchar *to, const uchar *from, uint param_data) */ if (from_length > 255) { + if (from + 2 > from_end) + return 0; length= uint2korr(from); from+= 2; } else + { + if (from + 1 > from_end) + return 0; length= (uint) *from++; + } + if (from + length > from_end || length > field_length) + return 0; memcpy(to, from, length); // Pad the string with the pad character of the fields charset @@ -6818,11 +6839,16 @@ uchar *Field_varstring::pack(uchar *to, const uchar *from, uint max_length) @return New pointer into memory based on from + length of the data */ const uchar * -Field_varstring::unpack(uchar *to, const uchar *from, uint param_data) +Field_varstring::unpack(uchar *to, const uchar *from, const uchar *from_end, + uint param_data) { uint length; uint l_bytes= (param_data && (param_data < field_length)) ? (param_data <= 255) ? 1 : 2 : length_bytes; + + if (from + l_bytes > from_end) + return 0; // Error in data + if (l_bytes == 1) { to[0]= *from++; @@ -6837,7 +6863,11 @@ Field_varstring::unpack(uchar *to, const uchar *from, uint param_data) to[1]= *from++; } if (length) + { + if (from + length > from_end || length > field_length) + return 0; // Error in data memcpy(to+ length_bytes, from, length); + } return from+length; } @@ -7414,16 +7444,21 @@ uchar *Field_blob::pack(uchar *to, const uchar *from, uint max_length) @return New pointer into memory based on from + length of the data */ -const uchar *Field_blob::unpack(uchar *to, const uchar *from, uint param_data) +const uchar *Field_blob::unpack(uchar *to, const uchar *from, + const uchar *from_end, uint param_data) { DBUG_ENTER("Field_blob::unpack"); DBUG_PRINT("enter", ("to: 0x%lx; from: 0x%lx; param_data: %u", (ulong) to, (ulong) from, param_data)); uint const master_packlength= param_data > 0 ? param_data & 0xFF : packlength; + if (from + master_packlength > from_end) + DBUG_RETURN(0); // Error in data uint32 const length= get_length(from, master_packlength); DBUG_DUMP("packed", from, length + master_packlength); bitmap_set_bit(table->write_set, field_index); + if (from + master_packlength + length > from_end) + DBUG_RETURN(0); store(reinterpret_cast<const char*>(from) + master_packlength, length, field_charset); DBUG_DUMP("record", to, table->s->reclength); @@ -7971,12 +8006,13 @@ uchar *Field_enum::pack(uchar *to, const uchar *from, uint max_length) DBUG_RETURN(pack_int(to, from, packlength)); } -const uchar *Field_enum::unpack(uchar *to, const uchar *from, uint param_data) +const uchar *Field_enum::unpack(uchar *to, const uchar *from, + const uchar *from_end, uint param_data) { DBUG_ENTER("Field_enum::unpack"); DBUG_PRINT("debug", ("packlength: %d", packlength)); DBUG_DUMP("from", from, packlength); - DBUG_RETURN(unpack_int(to, from, packlength)); + DBUG_RETURN(unpack_int(to, from, from_end, packlength)); } @@ -8472,7 +8508,8 @@ Field_bit::pack(uchar *to, const uchar *from, uint max_length) @return New pointer into memory based on from + length of the data */ const uchar * -Field_bit::unpack(uchar *to, const uchar *from, uint param_data) +Field_bit::unpack(uchar *to, const uchar *from, const uchar *from_end, + uint param_data) { DBUG_ENTER("Field_bit::unpack"); DBUG_PRINT("enter", ("to: %p, from: %p, param_data: 0x%x", @@ -8490,6 +8527,9 @@ Field_bit::unpack(uchar *to, const uchar *from, uint param_data) if (param_data == 0 || ((from_bit_len == bit_len) && (from_len == bytes_in_rec))) { + if (from + bytes_in_rec + test(bit_len) > from_end) + return 0; // Error in data + if (bit_len > 0) { /* @@ -8514,10 +8554,16 @@ Field_bit::unpack(uchar *to, const uchar *from, uint param_data) Lastly the odd bits need to be masked out if the bytes_in_rec > 0. Otherwise stray bits can cause spurious values. */ + + uint len= from_len + ((from_bit_len > 0) ? 1 : 0); uint new_len= (field_length + 7) / 8; + + if (from + len > from_end || new_len < len) + return 0; // Error in data + char *value= (char *)my_alloca(new_len); bzero(value, new_len); - uint len= from_len + ((from_bit_len > 0) ? 1 : 0); + memcpy(value + (new_len - len), from, len); /* Mask out the unused bits in the partial byte. diff --git a/sql/field.h b/sql/field.h index fee141d30b0..0b32aab0337 100644 --- a/sql/field.h +++ b/sql/field.h @@ -504,16 +504,8 @@ public: DBUG_RETURN(result); } - virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data); - /** - @overload Field::unpack(uchar*, const uchar*, uint, bool) - */ - const uchar *unpack(uchar* to, const uchar *from) - { - DBUG_ENTER("Field::unpack"); - const uchar *result= unpack(to, from, 0); - DBUG_RETURN(result); - } + virtual const uchar *unpack(uchar* to, const uchar *from, + const uchar *from_end, uint param_data=0); virtual uint packed_col_length(const uchar *to, uint length) { return length;} @@ -644,28 +636,31 @@ protected: return to + size; } - const uchar *unpack_int(uchar* to, const uchar *from, size_t size) + const uchar *unpack_int(uchar* to, const uchar *from, + const uchar *from_end, size_t size) { + if (from + size > from_end) + return 0; memcpy(to, from, size); return from + size; } uchar *pack_int16(uchar *to, const uchar *from) { return pack_int(to, from, 2); } - const uchar *unpack_int16(uchar* to, const uchar *from) - { return unpack_int(to, from, 2); } + const uchar *unpack_int16(uchar* to, const uchar *from, const uchar *from_end) + { return unpack_int(to, from, from_end, 2); } uchar *pack_int24(uchar *to, const uchar *from) { return pack_int(to, from, 3); } - const uchar *unpack_int24(uchar* to, const uchar *from) - { return unpack_int(to, from, 3); } + const uchar *unpack_int24(uchar* to, const uchar *from, const uchar *from_end) + { return unpack_int(to, from, from_end, 3); } uchar *pack_int32(uchar *to, const uchar *from) { return pack_int(to, from, 4); } - const uchar *unpack_int32(uchar* to, const uchar *from) - { return unpack_int(to, from, 4); } + const uchar *unpack_int32(uchar* to, const uchar *from, const uchar *from_end) + { return unpack_int(to, from, from_end, 4); } uchar *pack_int64(uchar* to, const uchar *from) { return pack_int(to, from, 8); } - const uchar *unpack_int64(uchar* to, const uchar *from) - { return unpack_int(to, from, 8); } + const uchar *unpack_int64(uchar* to, const uchar *from, const uchar *from_end) + { return unpack_int(to, from, from_end, 8); } bool field_flags_are_binary() { @@ -824,10 +819,6 @@ public: void overflow(bool negative); bool zero_pack() const { return 0; } void sql_type(String &str) const; - virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data) - { - return Field::unpack(to, from, param_data); - } virtual uchar *pack(uchar* to, const uchar *from, uint max_length) { return Field::pack(to, from, max_length); @@ -883,7 +874,7 @@ public: bool compatible_field_size(uint field_metadata, Relay_log_info *rli, uint16 mflags, int *order_var); uint is_equal(Create_field *new_field); - virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data); + virtual const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, uint param_data); static Field *create_from_item (Item *); }; @@ -921,8 +912,11 @@ public: return to + 1; } - virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data) + virtual const uchar *unpack(uchar* to, const uchar *from, + const uchar *from_end, uint param_data) { + if (from == from_end) + return 0; *to= *from; return from + 1; } @@ -964,8 +958,9 @@ public: virtual uchar *pack(uchar* to, const uchar *from, uint max_length) { return pack_int16(to, from); } - virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data) - { return unpack_int16(to, from); } + virtual const uchar *unpack(uchar* to, const uchar *from, + const uchar *from_end, uint param_data) + { return unpack_int16(to, from, from_end); } }; class Field_medium :public Field_num { @@ -999,11 +994,6 @@ public: { return Field::pack(to, from, max_length); } - - virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data) - { - return Field::unpack(to, from, param_data); - } }; @@ -1044,9 +1034,10 @@ public: return pack_int32(to, from); } virtual const uchar *unpack(uchar* to, const uchar *from, + const uchar *from_end, uint param_data __attribute__((unused))) { - return unpack_int32(to, from); + return unpack_int32(to, from, from_end); } }; @@ -1092,10 +1083,10 @@ public: { return pack_int64(to, from); } - virtual const uchar *unpack(uchar* to, const uchar *from, - uint param_data __attribute__((unused))) + const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, + uint param_data __attribute__((unused))) { - return unpack_int64(to, from); + return unpack_int64(to, from, from_end); } }; @@ -1264,10 +1255,10 @@ public: { return pack_int32(to, from); } - const uchar *unpack(uchar* to, const uchar *from, + const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, uint param_data __attribute__((unused))) { - return unpack_int32(to, from); + return unpack_int32(to, from, from_end); } }; @@ -1303,8 +1294,9 @@ public: uint32 pack_length() const; uchar *pack(uchar *to, const uchar *from, uint max_length) { return Field::pack(to, from, max_length); } - const uchar *unpack(uchar* to, const uchar *from, uint param_data) - { return Field::unpack(to, from, param_data); } + const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, + uint param_data) + { return Field::unpack(to, from, from_end, param_data); } uint size_of() const { return sizeof(*this); } bool eq_def(Field *field) { return Field_str::eq_def(field) && dec == field->decimals(); } @@ -1389,10 +1381,10 @@ public: { return pack_int32(to, from); } - const uchar *unpack(uchar* to, const uchar *from, + const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, uint param_data __attribute__((unused))) { - return unpack_int32(to, from); + return unpack_int32(to, from, from_end); } }; @@ -1513,10 +1505,10 @@ public: { return pack_int64(to, from); } - const uchar *unpack(uchar* to, const uchar *from, + const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, uint param_data __attribute__((unused))) { - return unpack_int64(to, from); + return unpack_int64(to, from, from_end); } }; @@ -1551,8 +1543,9 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); uchar *pack(uchar *to, const uchar *from, uint max_length) { return Field::pack(to, from, max_length); } - const uchar *unpack(uchar* to, const uchar *from, uint param_data) - { return Field::unpack(to, from, param_data); } + const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, + uint param_data) + { return Field::unpack(to, from, from_end, param_data); } uint size_of() const { return sizeof(*this); } }; @@ -1644,7 +1637,8 @@ public: void sql_type(String &str) const; virtual uchar *pack(uchar *to, const uchar *from, uint max_length); - virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data); + virtual const uchar *unpack(uchar* to, const uchar *from, + const uchar *from_end,uint param_data); uint pack_length_from_metadata(uint field_metadata) { DBUG_PRINT("debug", ("field_metadata: 0x%04x", field_metadata)); @@ -1730,8 +1724,9 @@ public: uint get_key_image(uchar *buff,uint length, imagetype type); void set_key_image(const uchar *buff,uint length); void sql_type(String &str) const; - uchar *pack(uchar *to, const uchar *from, uint max_length); - const uchar *unpack(uchar* to, const uchar *from, uint param_data); + virtual uchar *pack(uchar *to, const uchar *from, uint max_length); + virtual const uchar *unpack(uchar* to, const uchar *from, + const uchar *from_end, uint param_data); int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L); int key_cmp(const uchar *,const uchar*); int key_cmp(const uchar *str, uint length); @@ -1898,8 +1893,9 @@ public: memcpy(ptr+packlength, &tmp, sizeof(char*)); return 0; } - uchar *pack(uchar *to, const uchar *from, uint max_length); - const uchar *unpack(uchar *to, const uchar *from, uint param_data); + virtual uchar *pack(uchar *to, const uchar *from, uint max_length); + virtual const uchar *unpack(uchar *to, const uchar *from, + const uchar *from_end, uint param_data); uint packed_col_length(const uchar *col_ptr, uint length); uint max_packed_col_length(uint max_length); void free() { value.free(); } @@ -2001,7 +1997,8 @@ public: CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; } virtual uchar *pack(uchar *to, const uchar *from, uint max_length); - virtual const uchar *unpack(uchar *to, const uchar *from, uint param_data); + virtual const uchar *unpack(uchar *to, const uchar *from, + const uchar *from_end, uint param_data); private: int do_save_field_metadata(uchar *first_byte); @@ -2113,7 +2110,8 @@ public: uint16 mflags, int *order_var); void sql_type(String &str) const; virtual uchar *pack(uchar *to, const uchar *from, uint max_length); - virtual const uchar *unpack(uchar *to, const uchar *from, uint param_data); + virtual const uchar *unpack(uchar *to, const uchar *from, + const uchar *from_end, uint param_data); virtual void set_default(); Field *new_key_field(MEM_ROOT *root, TABLE *new_table, diff --git a/sql/filesort.cc b/sql/filesort.cc index b531c4d8026..2ef9a48e6a2 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -63,7 +63,7 @@ static uint sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length, static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength); static void unpack_addon_fields(struct st_sort_addon_field *addon_field, - uchar *buff); + uchar *buff, uchar *buff_end); /** Sort a table. Creates a set of pointers that can be used to read the rows @@ -1753,7 +1753,8 @@ get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength) */ static void -unpack_addon_fields(struct st_sort_addon_field *addon_field, uchar *buff) +unpack_addon_fields(struct st_sort_addon_field *addon_field, uchar *buff, + uchar *buff_end) { Field *field; SORT_ADDON_FIELD *addonf= addon_field; @@ -1766,7 +1767,7 @@ unpack_addon_fields(struct st_sort_addon_field *addon_field, uchar *buff) continue; } field->set_notnull(); - field->unpack(field->ptr, buff + addonf->offset); + field->unpack(field->ptr, buff + addonf->offset, buff_end, 0); } } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index f2d7d69e173..d5f85e7ff5d 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2389,7 +2389,8 @@ Item_in_subselect::select_in_like_transformer(JOIN *join) object, but we can't know it here, but here we need address correct reference on left expresion. - //psergey: he means degenerate cases like "... IN (SELECT 1)" + note: we won't need Item_in_optimizer when handling degenerate cases + like "... IN (SELECT 1)" */ if (!optimizer) { diff --git a/sql/log_event.h b/sql/log_event.h index 7866a7d7efa..de9cd65514c 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -3847,7 +3847,8 @@ protected: DBUG_ASSERT(m_table); ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT); - int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols, + int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, + m_rows_end, &m_cols, &m_curr_row_end, &m_master_reclength); if (m_curr_row_end > m_rows_end) my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0)); diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 09a58e29c18..104a77c65a7 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -975,7 +975,8 @@ Write_rows_log_event_old::do_prepare_row(THD *thd_arg, int error; error= unpack_row_old(const_cast<Relay_log_info*>(rli), table, m_width, table->record[0], - row_start, &m_cols, row_end, &m_master_reclength, + row_start, m_rows_end, + &m_cols, row_end, &m_master_reclength, table->write_set, PRE_GA_WRITE_ROWS_EVENT); bitmap_copy(table->read_set, table->write_set); return error; @@ -1062,7 +1063,8 @@ Delete_rows_log_event_old::do_prepare_row(THD *thd_arg, error= unpack_row_old(const_cast<Relay_log_info*>(rli), table, m_width, table->record[0], - row_start, &m_cols, row_end, &m_master_reclength, + row_start, m_rows_end, + &m_cols, row_end, &m_master_reclength, table->read_set, PRE_GA_DELETE_ROWS_EVENT); /* If we will access rows using the random access method, m_key will @@ -1161,13 +1163,15 @@ int Update_rows_log_event_old::do_prepare_row(THD *thd_arg, /* record[0] is the before image for the update */ error= unpack_row_old(const_cast<Relay_log_info*>(rli), table, m_width, table->record[0], - row_start, &m_cols, row_end, &m_master_reclength, + row_start, m_rows_end, + &m_cols, row_end, &m_master_reclength, table->read_set, PRE_GA_UPDATE_ROWS_EVENT); row_start = *row_end; /* m_after_image is the after image for the update */ error= unpack_row_old(const_cast<Relay_log_info*>(rli), table, m_width, m_after_image, - row_start, &m_cols, row_end, &m_master_reclength, + row_start, m_rows_end, + &m_cols, row_end, &m_master_reclength, table->write_set, PRE_GA_UPDATE_ROWS_EVENT); DBUG_DUMP("record[0]", table->record[0], table->s->reclength); diff --git a/sql/log_event_old.h b/sql/log_event_old.h index da5cf403fdb..8fe2e9e0a75 100644 --- a/sql/log_event_old.h +++ b/sql/log_event_old.h @@ -203,7 +203,8 @@ protected: { DBUG_ASSERT(m_table); ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT); - int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols, + int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, + m_rows_end, &m_cols, &m_curr_row_end, &m_master_reclength); ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT); return result; diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index bdc8b768849..430c201d3e6 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -486,8 +486,8 @@ int opt_sum_query(THD *thd, 'const op field' @retval - 0 func_item is a simple predicate: a field is compared with - constants + 0 func_item is a simple predicate: a field is compared with a constant + whose length does not exceed the max length of the field values @retval 1 Otherwise */ @@ -507,6 +507,8 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order) if (!(item= it++)) return 0; args[0]= item->real_item(); + if (args[0]->max_length < args[1]->max_length) + return 0; if (it++) return 0; } @@ -540,6 +542,8 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order) } else return 0; + if (args[0]->max_length < args[1]->max_length) + return 0; break; case 3: /* field BETWEEN const AND const */ @@ -553,6 +557,8 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order) if (!item->const_item()) return 0; args[i]= item; + if (args[0]->max_length < args[i]->max_length) + return 0; } } else diff --git a/sql/records.cc b/sql/records.cc index 5050064926b..77fdc427b86 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -507,7 +507,8 @@ static int rr_unpack_from_tempfile(READ_RECORD *info) if (my_b_read(info->io_cache, info->rec_buf, info->ref_length)) return -1; TABLE *table= info->table; - (*table->sort.unpack)(table->sort.addon_field, info->rec_buf); + (*table->sort.unpack)(table->sort.addon_field, info->rec_buf, + info->rec_buf + info->ref_length); return 0; } @@ -558,7 +559,8 @@ static int rr_unpack_from_buffer(READ_RECORD *info) if (info->cache_pos == info->cache_end) return -1; /* End of buffer */ TABLE *table= info->table; - (*table->sort.unpack)(table->sort.addon_field, info->cache_pos); + (*table->sort.unpack)(table->sort.addon_field, info->cache_pos, + info->cache_end); info->cache_pos+= info->ref_length; return 0; diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index d51e5a5ba4c..a49f10db440 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -181,12 +181,15 @@ pack_row(TABLE *table, MY_BITMAP const* cols, @retval HA_ERR_GENERIC A generic, internal, error caused the unpacking to fail. + @retval ER_SLAVE_CORRUPT_EVENT + Found error when trying to unpack fields. */ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) int unpack_row(Relay_log_info const *rli, TABLE *table, uint const colcnt, - uchar const *const row_data, MY_BITMAP const *cols, + uchar const *const row_data, uchar const *const row_buffer_end, + MY_BITMAP const *cols, uchar const **const row_end, ulong *const master_reclength) { DBUG_ENTER("unpack_row"); @@ -257,9 +260,6 @@ unpack_row(Relay_log_info const *rli, DBUG_ASSERT(null_mask & 0xFF); // One of the 8 LSB should be set - /* Field...::unpack() cannot return 0 */ - DBUG_ASSERT(pack_ptr != NULL); - if (null_bits & null_mask) { if (f->maybe_null()) @@ -305,12 +305,20 @@ unpack_row(Relay_log_info const *rli, #ifndef DBUG_OFF uchar const *const old_pack_ptr= pack_ptr; #endif - pack_ptr= f->unpack(f->ptr, pack_ptr, metadata); + pack_ptr= f->unpack(f->ptr, pack_ptr, row_buffer_end, metadata); DBUG_PRINT("debug", ("field: %s; metadata: 0x%x;" " pack_ptr: 0x%lx; pack_ptr': 0x%lx; bytes: %d", f->field_name, metadata, (ulong) old_pack_ptr, (ulong) pack_ptr, (int) (pack_ptr - old_pack_ptr))); + if (!pack_ptr) + { + rli->report(ERROR_LEVEL, ER_SLAVE_CORRUPT_EVENT, + "Could not read field `%s` of table `%s`.`%s`", + f->field_name, table->s->db.str, + table->s->table_name.str); + DBUG_RETURN(ER_SLAVE_CORRUPT_EVENT); + } } /* diff --git a/sql/rpl_record.h b/sql/rpl_record.h index efe2a1da72c..4b34dcd0a96 100644 --- a/sql/rpl_record.h +++ b/sql/rpl_record.h @@ -33,7 +33,8 @@ size_t pack_row(TABLE* table, MY_BITMAP const* cols, #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) int unpack_row(Relay_log_info const *rli, TABLE *table, uint const colcnt, - uchar const *const row_data, MY_BITMAP const *cols, + uchar const *const row_data, uchar const *row_buffer_end, + MY_BITMAP const *cols, uchar const **const row_end, ulong *const master_reclength); // Fill table's record[0] with default values. diff --git a/sql/rpl_record_old.cc b/sql/rpl_record_old.cc index b91006d46d1..fa0c49b413c 100644 --- a/sql/rpl_record_old.cc +++ b/sql/rpl_record_old.cc @@ -83,12 +83,15 @@ pack_row_old(TABLE *table, MY_BITMAP const* cols, ER_NO_DEFAULT_FOR_FIELD Returned if one of the fields existing on the slave but not on the master does not have a default value (and isn't nullable) + ER_SLAVE_CORRUPT_EVENT + Wrong data for field found. */ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) int unpack_row_old(Relay_log_info *rli, TABLE *table, uint const colcnt, uchar *record, - uchar const *row, MY_BITMAP const *cols, + uchar const *row, const uchar *row_buffer_end, + MY_BITMAP const *cols, uchar const **row_end, ulong *master_reclength, MY_BITMAP* const rw_set, Log_event_type const event_type) { @@ -134,10 +137,16 @@ unpack_row_old(Relay_log_info *rli, if (bitmap_is_set(cols, field_ptr - begin_ptr)) { f->move_field_offset(offset); - ptr= f->unpack(f->ptr, ptr); + ptr= f->unpack(f->ptr, ptr, row_buffer_end, 0); f->move_field_offset(-offset); - /* Field...::unpack() cannot return 0 */ - DBUG_ASSERT(ptr != NULL); + if (!ptr) + { + rli->report(ERROR_LEVEL, ER_SLAVE_CORRUPT_EVENT, + "Could not read field `%s` of table `%s`.`%s`", + f->field_name, table->s->db.str, + table->s->table_name.str); + return(ER_SLAVE_CORRUPT_EVENT); + } } else bitmap_clear_bit(rw_set, field_ptr - begin_ptr); diff --git a/sql/rpl_record_old.h b/sql/rpl_record_old.h index 201f62b1946..ea981fb23c3 100644 --- a/sql/rpl_record_old.h +++ b/sql/rpl_record_old.h @@ -25,7 +25,8 @@ size_t pack_row_old(TABLE *table, MY_BITMAP const* cols, #ifdef HAVE_REPLICATION int unpack_row_old(Relay_log_info *rli, TABLE *table, uint const colcnt, uchar *record, - uchar const *row, MY_BITMAP const *cols, + uchar const *row, uchar const *row_buffer_end, + MY_BITMAP const *cols, uchar const **row_end, ulong *master_reclength, MY_BITMAP* const rw_set, Log_event_type const event_type); diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 61b67c9d229..0b5fce7758f 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -77,7 +77,7 @@ extern "C" sig_handler handle_fatal_signal(int sig) curr_time= my_time(0); localtime_r(&curr_time, &tm); - my_safe_printf_stderr("%02d%02d%02d %2d:%02d:%02d ", + fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d ", tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); if (opt_expect_abort diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 9fd6e0efafe..9298d3ccb72 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8662,6 +8662,17 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves, goto err_no_arena; select_lex->cond_count++; } + /* + If it's a semi-join nest, fix its "left expression", as it is used by + the SJ-Materialization + */ + if (embedded->sj_subq_pred) + { + Item **left_expr= &embedded->sj_subq_pred->left_expr; + if (!(*left_expr)->fixed && (*left_expr)->fix_fields(thd, left_expr)) + goto err_no_arena; + } + embedding= embedded->embedding; } while (embedding && diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 9f06c99c472..526d2445d3d 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -807,6 +807,7 @@ bool mysql_derived_create(THD *thd, LEX *lex, TABLE_LIST *derived) select_union *result= (select_union*)unit->result; if (table->s->db_type() == TMP_ENGINE_HTON) { + result->tmp_table_param.keyinfo= table->s->key_info; if (create_internal_tmp_table(table, result->tmp_table_param.keyinfo, result->tmp_table_param.start_recinfo, &result->tmp_table_param.recinfo, diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2e63a16d4e6..35c45a9033c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3558,12 +3558,16 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, Perform range analysis if there are keys it could use (1). Don't do range analysis if we're on the inner side of an outer join (2). Do range analysis if we're on the inner side of a semi-join (3). + Don't do range analysis for materialized subqueries (4). + Don't do range analysis for materialized derived tables (5) */ - if (!s->const_keys.is_clear_all() && // (1) - (!s->table->pos_in_table_list->embedding || // (2) - (s->table->pos_in_table_list->embedding && // (3) - s->table->pos_in_table_list->embedding->sj_on_expr)) && // (3) - !s->table->is_filled_at_execution()) + if (!s->const_keys.is_clear_all() && // (1) + (!s->table->pos_in_table_list->embedding || // (2) + (s->table->pos_in_table_list->embedding && // (3) + s->table->pos_in_table_list->embedding->sj_on_expr)) && // (3) + !s->table->is_filled_at_execution() && // (4) + !(s->table->pos_in_table_list->derived && // (5) + s->table->pos_in_table_list->is_materialized_derived())) // (5) { ha_rows records; SQL_SELECT *select; @@ -16093,8 +16097,13 @@ int report_error(TABLE *table, int error) print them to the .err log */ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + { + push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, error, + "Got error %d when reading table `%s`.`%s`", + error, table->s->db.str, table->s->table_name.str); sql_print_error("Got error %d when reading table '%s'", error, table->s->path.str); + } table->file->print_error(error,MYF(0)); return 1; } diff --git a/sql/table.cc b/sql/table.cc index 016f79607d0..f8430b9575a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2559,8 +2559,8 @@ partititon_err: /* Check virtual columns against table's storage engine. */ if (share->vfields && - !(outparam->file && - (outparam->file->ha_table_flags() & HA_CAN_VIRTUAL_COLUMNS))) + (outparam->file && + !(outparam->file->ha_table_flags() & HA_CAN_VIRTUAL_COLUMNS))) { my_error(ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS, MYF(0), plugin_name(share->db_plugin)->str); diff --git a/sql/table.h b/sql/table.h index 124f1c54de2..d2337022724 100644 --- a/sql/table.h +++ b/sql/table.h @@ -308,7 +308,7 @@ typedef struct st_filesort_info uchar *addon_buf; /* Pointer to a buffer if sorted with fields */ size_t addon_length; /* Length of the buffer */ struct st_sort_addon_field *addon_field; /* Pointer to the fields info */ - void (*unpack)(struct st_sort_addon_field *, uchar *); /* To unpack back */ + void (*unpack)(struct st_sort_addon_field *, uchar *, uchar *); /* To unpack back */ uchar *record_pointers; /* If sorted in memory */ ha_rows found_records; /* How many records in sort */ } FILESORT_INFO; diff --git a/sql/winservice.c b/sql/winservice.c index 1f41cf61ea4..1cf9f8d7823 100644 --- a/sql/winservice.c +++ b/sql/winservice.c @@ -75,6 +75,41 @@ void normalize_path(char *path, size_t size) } /* + Exclusion rules. + + Some hardware manufacturers deliver systems with own preinstalled MySQL copy + and services. We do not want to mess up with these installations. We will + just ignore such services, pretending it is not MySQL. + + ´@return + TRUE, if this service should be excluded from UI lists etc (OEM install) + FALSE otherwise. +*/ +BOOL exclude_service(mysqld_service_properties *props) +{ + static const char* exclude_patterns[] = + { + "common files\\dell\\mysql\\bin\\", /* Dell's private installation */ + NULL + }; + int i; + char buf[MAX_PATH]; + + /* Convert mysqld path to lower case, rules for paths are case-insensitive. */ + memcpy(buf, props->mysqld_exe, sizeof(props->mysqld_exe)); + _strlwr(buf); + + for(i= 0; exclude_patterns[i]; i++) + { + if (strstr(buf, exclude_patterns[i])) + return TRUE; + } + + return FALSE; +} + + +/* Retrieve some properties from windows mysqld service binary path. We're interested in ini file location and datadir, and also in version of the data. We tolerate missing mysqld.exe. @@ -256,7 +291,9 @@ int get_mysql_service_properties(const wchar_t *bin_path, } } } - retval = 0; + + if (!exclude_service(props)) + retval = 0; end: LocalFree((HLOCAL)args); return retval; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 2c178fb7055..25812a7ad48 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1182,20 +1182,26 @@ int ha_archive::unpack_row(azio_stream *file_to_read, uchar *record) if (read != row_len || error) { - DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); + DBUG_RETURN(error ? HA_ERR_CRASHED_ON_USAGE : HA_ERR_WRONG_IN_RECORD); } /* Copy null bits */ - const uchar *ptr= record_buffer->buffer; + const uchar *ptr= record_buffer->buffer, *end= ptr+ row_len; memcpy(record, ptr, table->s->null_bytes); ptr+= table->s->null_bytes; + if (ptr > end) + DBUG_RETURN(HA_ERR_WRONG_IN_RECORD); for (Field **field=table->field ; *field ; field++) { if (!((*field)->is_null_in_record(record))) { - ptr= (*field)->unpack(record + (*field)->offset(table->record[0]), ptr); + if (!(ptr= (*field)->unpack(record + (*field)->offset(table->record[0]), + ptr, end))) + DBUG_RETURN(HA_ERR_WRONG_IN_RECORD); } } + if (ptr != end) + DBUG_RETURN(HA_ERR_WRONG_IN_RECORD); DBUG_RETURN(0); } diff --git a/win/packaging/heidisql.wxi.in b/win/packaging/heidisql.wxi.in index 2af52862e06..1e6e3d552a8 100644 --- a/win/packaging/heidisql.wxi.in +++ b/win/packaging/heidisql.wxi.in @@ -3,7 +3,7 @@ <RegistrySearch Id="HeidiSQL"
Root="HKLM"
Key="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\HeidiSQL_is1"
- Name="Install"
+ Name="UninstallString"
Type="raw"
Win64="no"
/>
@@ -30,11 +30,15 @@ <Component Id="component.HeidiSQL_MenuShortcut" Guid="*" Win64="no">
<RegistryValue Root="HKCU" Key="Software\@CPACK_WIX_PACKAGE_NAME@\Uninstall" Name="shortcuts.heidisql" Value="1" Type="string" KeyPath="yes" />
<Shortcut Id="startmenuHeidiSQL" Directory="ShortcutFolder" Name="HeidiSQL" Target="[D.HeidiSQL]\heidisql.exe"/>
- <RemoveRegistryKey Id="HeidiSQL_RegistryCleanup" Root="HKCU" Key="SOFTWARE\HeidiSQL" Action="removeOnUninstall" />
</Component>
<Component Id="component.HeidiSQL_libmysql.dll" Guid="*" Win64="no">
<File Id="heidisql.libmysql.dll" Name="libmysql.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libmysql.dll" />
</Component>
+ <Component Id="component.HeidiSQL_CleanupSettings" Guid="*" Win64="no">
+ <Condition>HEIDISQLINSTALLED</Condition>
+ <RegistryValue Root="HKCU" Key="Software\@CPACK_WIX_PACKAGE_NAME@\UninstallCleanupHeidiSQLSettings" Name="cleanup.heidisql" Value="1" Type="string" KeyPath="yes" />
+ <RemoveRegistryKey Id="HeidiSQL_RegistryCleanup" Root="HKCU" Key="SOFTWARE\HeidiSQL" Action="removeOnUninstall" />
+ </Component>
</Directory>
</DirectoryRef>
@@ -42,5 +46,6 @@ <ComponentRef Id="component.HeidiSQL"/>
<ComponentRef Id="component.HeidiSQL_MenuShortcut"/>
<ComponentRef Id="component.HeidiSQL_libmysql.dll"/>
+ <ComponentRef Id="component.HeidiSQL_CleanupSettings"/>
</ComponentGroup>
</Include>
diff --git a/win/packaging/heidisql_feature.wxi.in b/win/packaging/heidisql_feature.wxi.in index 9fceb4689d0..3f60fcd8f27 100644 --- a/win/packaging/heidisql_feature.wxi.in +++ b/win/packaging/heidisql_feature.wxi.in @@ -4,7 +4,7 @@ Description= 'Powerful, easy and free MySQL/MariaDB GUI client by Ansgar Becker'
AllowAdvertise='no'
Level='1'>
- <Condition Level="0">HEIDISQLINSTALLED</Condition>
+ <Condition Level="0">HEIDISQLINSTALLED AND NOT REMOVE ~= ALL</Condition>
<ComponentGroupRef Id='HeidiSQL'/>
</Feature>
</Include>
|