diff options
32 files changed, 1092 insertions, 221 deletions
diff --git a/include/scope.h b/include/scope.h index b9e2e96ae5c..e0e9fc62969 100644 --- a/include/scope.h +++ b/include/scope.h @@ -64,3 +64,11 @@ make_scope_exit(Callable &&f) return detail::scope_exit<typename std::decay<Callable>::type>( std::forward<Callable>(f)); } + +#define CONCAT_IMPL(x, y) x##y + +#define CONCAT(x, y) CONCAT_IMPL(x, y) + +#define ANONYMOUS_VARIABLE CONCAT(_anonymous_variable, __LINE__) + +#define SCOPE_EXIT auto ANONYMOUS_VARIABLE= make_scope_exit diff --git a/mysql-test/main/alias.result b/mysql-test/main/alias.result index 266991afbec..78a1eead1db 100644 --- a/mysql-test/main/alias.result +++ b/mysql-test/main/alias.result @@ -219,6 +219,157 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp connection default; disconnect c1; # +# MDEV-25399 Assertion `name.length == strlen(name.str)' failed in Item_func_sp::make_send_field +# +SET sql_mode=''; +CREATE FUNCTION f(i INT) RETURNS INT RETURN 1; +PREPARE s FROM "SELECT f('\0')"; +EXECUTE s; +f('\x00') +1 +DROP FUNCTION f; +SET sql_mode=DEFAULT; +# +# MDEV-22380: Assertion `name.length == strlen(name.str)' failed +# in Item::print_item_w_name on SELECT w/ optimizer_trace enabled +# +SELECT '' LIMIT 0; + +CREATE TABLE t1 AS SELECT ''; +ERROR 42000: Incorrect column name '' +CREATE PROCEDURE test_inject(arg TEXT CHARACTER SET latin1) +BEGIN +SET @stmt=CONCAT('SELECT ''', arg, ''', CONCAT(''', arg, ''') LIMIT 0'); +PREPARE stmt FROM @stmt; +EXECUTE stmt; +SET @stmt=CONCAT('CREATE TABLE t1 AS ', @stmt); +PREPARE stmt FROM @stmt; +EXECUTE stmt; +SHOW CREATE TABLE t1; +DROP TABLE t1; +END; +$$ +SELECT x'FF32', CONCAT(x'FF32') LIMIT 0; +x'FF32' CONCAT(x'FF32') +CREATE TABLE t1 AS SELECT x'FF32', CONCAT(x'FF32'); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x'FF32'` varbinary(2) NOT NULL, + `CONCAT(x'FF32')` varbinary(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CALL test_inject(x'FF32'); +ÿ2 CONCAT('ÿ2') +Table Create Table +t1 CREATE TABLE `t1` ( + `ÿ2` varchar(2) NOT NULL, + `CONCAT('ÿ2')` varchar(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT x'32FF', CONCAT(x'32FF') LIMIT 0; +x'32FF' CONCAT(x'32FF') +CREATE TABLE t1 AS SELECT x'32FF', CONCAT(x'32FF'); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x'32FF'` varbinary(2) NOT NULL, + `CONCAT(x'32FF')` varbinary(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CALL test_inject(x'32FF'); +2ÿ CONCAT('2ÿ') +Table Create Table +t1 CREATE TABLE `t1` ( + `2ÿ` varchar(2) NOT NULL, + `CONCAT('2ÿ')` varchar(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT x'0032', CONCAT(x'0032') LIMIT 0; +x'0032' CONCAT(x'0032') +CREATE TABLE t1 AS SELECT x'0032', CONCAT(x'0032'); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x'0032'` varbinary(2) NOT NULL, + `CONCAT(x'0032')` varbinary(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CALL test_inject(x'0032'); +2 CONCAT('\x002') +Table Create Table +t1 CREATE TABLE `t1` ( + `2` varchar(2) NOT NULL, + `CONCAT('\x002')` varchar(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT x'3200', CONCAT(x'3200') LIMIT 0; +x'3200' CONCAT(x'3200') +CREATE TABLE t1 AS SELECT x'3200', CONCAT(x'3200'); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x'3200'` varbinary(2) NOT NULL, + `CONCAT(x'3200')` varbinary(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CALL test_inject(x'3200'); +2\x00 CONCAT('2\x00') +Table Create Table +t1 CREATE TABLE `t1` ( + `2\x00` varchar(2) NOT NULL, + `CONCAT('2\x00')` varchar(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT '0\a', CONCAT('0\a') LIMIT 0; +0a CONCAT('0\a') +CREATE TABLE t1 AS SELECT '0\a', CONCAT('0\a'); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `0a` varchar(2) NOT NULL, + `CONCAT('0\a')` varchar(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CALL test_inject('0\a'); +0a CONCAT('0a') +Table Create Table +t1 CREATE TABLE `t1` ( + `0a` varchar(2) NOT NULL, + `CONCAT('0a')` varchar(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT 'a\0', CONCAT('a\0') LIMIT 0; +a\x00 CONCAT('a\0') +CREATE TABLE t1 AS SELECT 'a\0', CONCAT('a\0'); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a\x00` varchar(2) NOT NULL, + `CONCAT('a\0')` varchar(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CALL test_inject('a\0'); +a\x00 CONCAT('a\x00') +Table Create Table +t1 CREATE TABLE `t1` ( + `a\x00` varchar(2) NOT NULL, + `CONCAT('a\x00')` varchar(2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SELECT 'a\0b', CONCAT('a\0b') LIMIT 0; +a\x00b CONCAT('a\0b') +CREATE TABLE t1 AS SELECT 'a\0b', CONCAT('a\0b'); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a\x00b` varchar(3) NOT NULL, + `CONCAT('a\0b')` varchar(3) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CALL test_inject('a\0b'); +a\x00b CONCAT('a\x00b') +Table Create Table +t1 CREATE TABLE `t1` ( + `a\x00b` varchar(3) NOT NULL, + `CONCAT('a\x00b')` varchar(3) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP PROCEDURE test_inject; +# # MDEV-23519 # create or replace table t1 (a int); diff --git a/mysql-test/main/alias.test b/mysql-test/main/alias.test index 881cc34d6c6..a0c9377d6dd 100644 --- a/mysql-test/main/alias.test +++ b/mysql-test/main/alias.test @@ -226,6 +226,89 @@ connection c1; DELETE ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZROM t1 WHERE 1=1; connection default; disconnect c1; + +--echo # +--echo # MDEV-25399 Assertion `name.length == strlen(name.str)' failed in Item_func_sp::make_send_field +--echo # + +SET sql_mode=''; +CREATE FUNCTION f(i INT) RETURNS INT RETURN 1; +PREPARE s FROM "SELECT f('\0')"; +--disable_warnings +EXECUTE s; +--enable_warnings +DROP FUNCTION f; +SET sql_mode=DEFAULT; + +--echo # +--echo # MDEV-22380: Assertion `name.length == strlen(name.str)' failed +--echo # in Item::print_item_w_name on SELECT w/ optimizer_trace enabled +--echo # + +SELECT '' LIMIT 0; +--error ER_WRONG_COLUMN_NAME +CREATE TABLE t1 AS SELECT ''; + +DELIMITER $$; +CREATE PROCEDURE test_inject(arg TEXT CHARACTER SET latin1) +BEGIN + SET @stmt=CONCAT('SELECT ''', arg, ''', CONCAT(''', arg, ''') LIMIT 0'); + PREPARE stmt FROM @stmt; + EXECUTE stmt; + + SET @stmt=CONCAT('CREATE TABLE t1 AS ', @stmt); + PREPARE stmt FROM @stmt; + EXECUTE stmt; + SHOW CREATE TABLE t1; + DROP TABLE t1; +END; +$$ +DELIMITER ;$$ + +SELECT x'FF32', CONCAT(x'FF32') LIMIT 0; +CREATE TABLE t1 AS SELECT x'FF32', CONCAT(x'FF32'); +SHOW CREATE TABLE t1; +DROP TABLE t1; +CALL test_inject(x'FF32'); + +SELECT x'32FF', CONCAT(x'32FF') LIMIT 0; +CREATE TABLE t1 AS SELECT x'32FF', CONCAT(x'32FF'); +SHOW CREATE TABLE t1; +DROP TABLE t1; +CALL test_inject(x'32FF'); + +SELECT x'0032', CONCAT(x'0032') LIMIT 0; +CREATE TABLE t1 AS SELECT x'0032', CONCAT(x'0032'); +SHOW CREATE TABLE t1; +DROP TABLE t1; +CALL test_inject(x'0032'); + +SELECT x'3200', CONCAT(x'3200') LIMIT 0; +CREATE TABLE t1 AS SELECT x'3200', CONCAT(x'3200'); +SHOW CREATE TABLE t1; +DROP TABLE t1; +CALL test_inject(x'3200'); + +SELECT '0\a', CONCAT('0\a') LIMIT 0; +CREATE TABLE t1 AS SELECT '0\a', CONCAT('0\a'); +SHOW CREATE TABLE t1; +DROP TABLE t1; +CALL test_inject('0\a'); + +SELECT 'a\0', CONCAT('a\0') LIMIT 0; +CREATE TABLE t1 AS SELECT 'a\0', CONCAT('a\0'); +SHOW CREATE TABLE t1; +DROP TABLE t1; +CALL test_inject('a\0'); + +SELECT 'a\0b', CONCAT('a\0b') LIMIT 0; +CREATE TABLE t1 AS SELECT 'a\0b', CONCAT('a\0b'); +SHOW CREATE TABLE t1; +DROP TABLE t1; +CALL test_inject('a\0b'); + +DROP PROCEDURE test_inject; + --echo # --echo # MDEV-23519 --echo # diff --git a/mysql-test/main/cast.result b/mysql-test/main/cast.result index 6f6de3c8e79..b17d89788cf 100644 --- a/mysql-test/main/cast.result +++ b/mysql-test/main/cast.result @@ -402,7 +402,7 @@ select cast(_latin1'test' as char character set latin2); cast(_latin1'test' as char character set latin2) test select cast(_koi8r'ÔÅÓÔ' as char character set cp1251); -cast(_koi8r'ÔÅÓÔ' as char character set cp1251) +cast(_koi8r'\xD4\xC5\xD3\xD4' as char character set cp1251) òåñò create table t1 select cast(_koi8r'ÔÅÓÔ' as char character set cp1251) as t; show create table t1; diff --git a/mysql-test/main/ctype_big5.result b/mysql-test/main/ctype_big5.result index 41ce8f0b82e..6a218dcbf7b 100644 --- a/mysql-test/main/ctype_big5.result +++ b/mysql-test/main/ctype_big5.result @@ -4710,7 +4710,7 @@ SELECT @@character_set_client, @@character_set_connection, @@character_set_resul @@character_set_client @@character_set_connection @@character_set_results binary big5 binary SELECT HEX('à\['), HEX('\à\['); -HEX('à\[') HEX('\à\[') +HEX('\xE0\[') HEX('\\xE0\[') E05B E05B CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0; SHOW CREATE TABLE t1; diff --git a/mysql-test/main/ctype_cp932_binlog_stm.result b/mysql-test/main/ctype_cp932_binlog_stm.result index 089820d628a..c583564f7c2 100644 --- a/mysql-test/main/ctype_cp932_binlog_stm.result +++ b/mysql-test/main/ctype_cp932_binlog_stm.result @@ -20418,7 +20418,7 @@ SELECT @@character_set_client, @@character_set_connection, @@character_set_resul @@character_set_client @@character_set_connection @@character_set_results binary cp932 binary SELECT HEX('à\['), HEX('\à\['); -HEX('à\[') HEX('\à\[') +HEX('\xE0\[') HEX('\\xE0\[') E05B E05B CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0; SHOW CREATE TABLE t1; diff --git a/mysql-test/main/ctype_gbk.result b/mysql-test/main/ctype_gbk.result index 7b54794a884..80bf4dbfeaa 100644 --- a/mysql-test/main/ctype_gbk.result +++ b/mysql-test/main/ctype_gbk.result @@ -5058,7 +5058,7 @@ SELECT @@character_set_client, @@character_set_connection, @@character_set_resul @@character_set_client @@character_set_connection @@character_set_results binary gbk binary SELECT HEX('à\['), HEX('\à\['); -HEX('à\[') HEX('\à\[') +HEX('\xE0\[') HEX('\\xE0\[') E05B E05B CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0; SHOW CREATE TABLE t1; diff --git a/mysql-test/main/ctype_latin1.result b/mysql-test/main/ctype_latin1.result index 68870bbeea8..7853f8557f0 100644 --- a/mysql-test/main/ctype_latin1.result +++ b/mysql-test/main/ctype_latin1.result @@ -7965,37 +7965,37 @@ SELECT 'Â'; ? ? SELECT HEX('Â'); -HEX('Â') +HEX('\xC2') 3F SELECT HEX(CAST('Â' AS CHAR CHARACTER SET utf8)); -HEX(CAST('Â' AS CHAR CHARACTER SET utf8)) +HEX(CAST('\xC2' AS CHAR CHARACTER SET utf8)) 3F SELECT HEX(CAST('Â' AS CHAR CHARACTER SET latin1)); -HEX(CAST('Â' AS CHAR CHARACTER SET latin1)) +HEX(CAST('\xC2' AS CHAR CHARACTER SET latin1)) 3F SELECT HEX(CONVERT('Â' USING utf8)); -HEX(CONVERT('Â' USING utf8)) +HEX(CONVERT('\xC2' USING utf8)) 3F SELECT HEX(CONVERT('Â' USING latin1)); -HEX(CONVERT('Â' USING latin1)) +HEX(CONVERT('\xC2' USING latin1)) 3F SELECT 'Âx'; ?x ?x SELECT HEX('Âx'); -HEX('Âx') +HEX('\xC2x') 3F78 SELECT HEX(CAST('Âx' AS CHAR CHARACTER SET utf8)); -HEX(CAST('Âx' AS CHAR CHARACTER SET utf8)) +HEX(CAST('\xC2x' AS CHAR CHARACTER SET utf8)) 3F78 SELECT HEX(CAST('Âx' AS CHAR CHARACTER SET latin1)); -HEX(CAST('Âx' AS CHAR CHARACTER SET latin1)) +HEX(CAST('\xC2x' AS CHAR CHARACTER SET latin1)) 3F78 SELECT HEX(CONVERT('Âx' USING utf8)); -HEX(CONVERT('Âx' USING utf8)) +HEX(CONVERT('\xC2x' USING utf8)) 3F78 SELECT HEX(CONVERT('Âx' USING latin1)); -HEX(CONVERT('Âx' USING latin1)) +HEX(CONVERT('\xC2x' USING latin1)) 3F78 SET NAMES utf8; CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1); diff --git a/mysql-test/main/ctype_sjis.result b/mysql-test/main/ctype_sjis.result index 638f9bc21c7..432aefd56f8 100644 --- a/mysql-test/main/ctype_sjis.result +++ b/mysql-test/main/ctype_sjis.result @@ -18682,7 +18682,7 @@ SELECT @@character_set_client, @@character_set_connection, @@character_set_resul @@character_set_client @@character_set_connection @@character_set_results binary sjis binary SELECT HEX('à\['), HEX('\à\['); -HEX('à\[') HEX('\à\[') +HEX('\xE0\[') HEX('\\xE0\[') E05B E05B CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0; SHOW CREATE TABLE t1; diff --git a/mysql-test/main/ctype_utf8.result b/mysql-test/main/ctype_utf8.result index 967cfdf8fbc..dc8961f19a7 100644 --- a/mysql-test/main/ctype_utf8.result +++ b/mysql-test/main/ctype_utf8.result @@ -67,13 +67,13 @@ select _utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD0B1,_utf8 '%'); _utf8 0xD0B0D0B1D0B2 like concat(_utf8'%',_utf8 0xD0B1,_utf8 '%') 1 select convert(_latin1'Günter André' using utf8) like CONVERT(_latin1'GÜNTER%' USING utf8); -convert(_latin1'Günter André' using utf8) like CONVERT(_latin1'GÜNTER%' USING utf8) +convert(_latin1'G\xFCnter Andr\xE9' using utf8) like CONVERT(_latin1'G\xDCNTER%' USING utf8) 1 select CONVERT(_koi8r'×ÁÓÑ' USING utf8) LIKE CONVERT(_koi8r'÷áóñ' USING utf8); -CONVERT(_koi8r'×ÁÓÑ' USING utf8) LIKE CONVERT(_koi8r'÷áóñ' USING utf8) +CONVERT(_koi8r'\xD7\xC1\xD3\xD1' USING utf8) LIKE CONVERT(_koi8r'\xF7\xE1\xF3\xF1' USING utf8) 1 select CONVERT(_koi8r'÷áóñ' USING utf8) LIKE CONVERT(_koi8r'×ÁÓÑ' USING utf8); -CONVERT(_koi8r'÷áóñ' USING utf8) LIKE CONVERT(_koi8r'×ÁÓÑ' USING utf8) +CONVERT(_koi8r'\xF7\xE1\xF3\xF1' USING utf8) LIKE CONVERT(_koi8r'\xD7\xC1\xD3\xD1' USING utf8) 1 SELECT 'a' = 'a '; 'a' = 'a ' @@ -1295,7 +1295,7 @@ concat(concat(_latin1'->',f1),_latin1'<-') -><- drop table t1; select convert(_koi8r'É' using utf8) < convert(_koi8r'Ê' using utf8); -convert(_koi8r'É' using utf8) < convert(_koi8r'Ê' using utf8) +convert(_koi8r'\xC9' using utf8) < convert(_koi8r'\xCA' using utf8) 1 set names latin1; create table t1 (a varchar(10)) character set utf8; diff --git a/mysql-test/main/ctype_utf8mb4.result b/mysql-test/main/ctype_utf8mb4.result index 20ebfd255b2..5d039195f33 100644 --- a/mysql-test/main/ctype_utf8mb4.result +++ b/mysql-test/main/ctype_utf8mb4.result @@ -67,13 +67,13 @@ select _utf8mb4 0xD0B0D0B1D0B2 like concat(_utf8mb4'%',_utf8mb4 0xD0B1,_utf8mb4 _utf8mb4 0xD0B0D0B1D0B2 like concat(_utf8mb4'%',_utf8mb4 0xD0B1,_utf8mb4 '%') 1 select convert(_latin1'Günter André' using utf8mb4) like CONVERT(_latin1'GÜNTER%' USING utf8mb4); -convert(_latin1'G?nter Andr?' using utf8mb4) like CONVERT(_latin1'G?NTER%' USING utf8mb4) +convert(_latin1'G\xFCnter Andr\xE9' using utf8mb4) like CONVERT(_latin1'G\xDCNTER%' USING utf8mb4) 1 select CONVERT(_koi8r'×ÁÓÑ' USING utf8mb4) LIKE CONVERT(_koi8r'÷áóñ' USING utf8mb4); -CONVERT(_koi8r'????' USING utf8mb4) LIKE CONVERT(_koi8r'????' USING utf8mb4) +CONVERT(_koi8r'\xD7\xC1\xD3\xD1' USING utf8mb4) LIKE CONVERT(_koi8r'\xF7\xE1\xF3\xF1' USING utf8mb4) 1 select CONVERT(_koi8r'÷áóñ' USING utf8mb4) LIKE CONVERT(_koi8r'×ÁÓÑ' USING utf8mb4); -CONVERT(_koi8r'????' USING utf8mb4) LIKE CONVERT(_koi8r'????' USING utf8mb4) +CONVERT(_koi8r'\xF7\xE1\xF3\xF1' USING utf8mb4) LIKE CONVERT(_koi8r'\xD7\xC1\xD3\xD1' USING utf8mb4) 1 SELECT 'a' = 'a '; 'a' = 'a ' @@ -1316,7 +1316,7 @@ concat(concat(_latin1'->',f1),_latin1'<-') -><- drop table t1; select convert(_koi8r'É' using utf8mb4) < convert(_koi8r'Ê' using utf8mb4); -convert(_koi8r'?' using utf8mb4) < convert(_koi8r'?' using utf8mb4) +convert(_koi8r'\xC9' using utf8mb4) < convert(_koi8r'\xCA' using utf8mb4) 1 set names latin1; create table t1 (a varchar(10)) character set utf8mb4; diff --git a/mysql-test/main/ctype_utf8mb4_heap.result b/mysql-test/main/ctype_utf8mb4_heap.result index 9eb7d48370f..d18d1939aa9 100644 --- a/mysql-test/main/ctype_utf8mb4_heap.result +++ b/mysql-test/main/ctype_utf8mb4_heap.result @@ -67,13 +67,13 @@ select _utf8mb4 0xD0B0D0B1D0B2 like concat(_utf8mb4'%',_utf8mb4 0xD0B1,_utf8mb4 _utf8mb4 0xD0B0D0B1D0B2 like concat(_utf8mb4'%',_utf8mb4 0xD0B1,_utf8mb4 '%') 1 select convert(_latin1'Günter André' using utf8mb4) like CONVERT(_latin1'GÜNTER%' USING utf8mb4); -convert(_latin1'G?nter Andr?' using utf8mb4) like CONVERT(_latin1'G?NTER%' USING utf8mb4) +convert(_latin1'G\xFCnter Andr\xE9' using utf8mb4) like CONVERT(_latin1'G\xDCNTER%' USING utf8mb4) 1 select CONVERT(_koi8r'×ÁÓÑ' USING utf8mb4) LIKE CONVERT(_koi8r'÷áóñ' USING utf8mb4); -CONVERT(_koi8r'????' USING utf8mb4) LIKE CONVERT(_koi8r'????' USING utf8mb4) +CONVERT(_koi8r'\xD7\xC1\xD3\xD1' USING utf8mb4) LIKE CONVERT(_koi8r'\xF7\xE1\xF3\xF1' USING utf8mb4) 1 select CONVERT(_koi8r'÷áóñ' USING utf8mb4) LIKE CONVERT(_koi8r'×ÁÓÑ' USING utf8mb4); -CONVERT(_koi8r'????' USING utf8mb4) LIKE CONVERT(_koi8r'????' USING utf8mb4) +CONVERT(_koi8r'\xF7\xE1\xF3\xF1' USING utf8mb4) LIKE CONVERT(_koi8r'\xD7\xC1\xD3\xD1' USING utf8mb4) 1 SELECT 'a' = 'a '; 'a' = 'a ' @@ -1215,7 +1215,7 @@ concat(concat(_latin1'->',f1),_latin1'<-') -><- drop table t1; select convert(_koi8r'É' using utf8mb4) < convert(_koi8r'Ê' using utf8mb4); -convert(_koi8r'?' using utf8mb4) < convert(_koi8r'?' using utf8mb4) +convert(_koi8r'\xC9' using utf8mb4) < convert(_koi8r'\xCA' using utf8mb4) 1 set names latin1; create table t1 (a varchar(10)) character set utf8mb4 engine heap; diff --git a/mysql-test/main/ctype_utf8mb4_innodb.result b/mysql-test/main/ctype_utf8mb4_innodb.result index fc2a368f3f0..c04f62f3cb0 100644 --- a/mysql-test/main/ctype_utf8mb4_innodb.result +++ b/mysql-test/main/ctype_utf8mb4_innodb.result @@ -67,13 +67,13 @@ select _utf8mb4 0xD0B0D0B1D0B2 like concat(_utf8mb4'%',_utf8mb4 0xD0B1,_utf8mb4 _utf8mb4 0xD0B0D0B1D0B2 like concat(_utf8mb4'%',_utf8mb4 0xD0B1,_utf8mb4 '%') 1 select convert(_latin1'Günter André' using utf8mb4) like CONVERT(_latin1'GÜNTER%' USING utf8mb4); -convert(_latin1'G?nter Andr?' using utf8mb4) like CONVERT(_latin1'G?NTER%' USING utf8mb4) +convert(_latin1'G\xFCnter Andr\xE9' using utf8mb4) like CONVERT(_latin1'G\xDCNTER%' USING utf8mb4) 1 select CONVERT(_koi8r'×ÁÓÑ' USING utf8mb4) LIKE CONVERT(_koi8r'÷áóñ' USING utf8mb4); -CONVERT(_koi8r'????' USING utf8mb4) LIKE CONVERT(_koi8r'????' USING utf8mb4) +CONVERT(_koi8r'\xD7\xC1\xD3\xD1' USING utf8mb4) LIKE CONVERT(_koi8r'\xF7\xE1\xF3\xF1' USING utf8mb4) 1 select CONVERT(_koi8r'÷áóñ' USING utf8mb4) LIKE CONVERT(_koi8r'×ÁÓÑ' USING utf8mb4); -CONVERT(_koi8r'????' USING utf8mb4) LIKE CONVERT(_koi8r'????' USING utf8mb4) +CONVERT(_koi8r'\xF7\xE1\xF3\xF1' USING utf8mb4) LIKE CONVERT(_koi8r'\xD7\xC1\xD3\xD1' USING utf8mb4) 1 SELECT 'a' = 'a '; 'a' = 'a ' @@ -1278,7 +1278,7 @@ concat(concat(_latin1'->',f1),_latin1'<-') -><- drop table t1; select convert(_koi8r'É' using utf8mb4) < convert(_koi8r'Ê' using utf8mb4); -convert(_koi8r'?' using utf8mb4) < convert(_koi8r'?' using utf8mb4) +convert(_koi8r'\xC9' using utf8mb4) < convert(_koi8r'\xCA' using utf8mb4) 1 set names latin1; create table t1 (a varchar(10)) character set utf8mb4 engine InnoDB; diff --git a/mysql-test/main/ctype_utf8mb4_myisam.result b/mysql-test/main/ctype_utf8mb4_myisam.result index ee2bd4431fc..a8b740305c6 100644 --- a/mysql-test/main/ctype_utf8mb4_myisam.result +++ b/mysql-test/main/ctype_utf8mb4_myisam.result @@ -67,13 +67,13 @@ select _utf8mb4 0xD0B0D0B1D0B2 like concat(_utf8mb4'%',_utf8mb4 0xD0B1,_utf8mb4 _utf8mb4 0xD0B0D0B1D0B2 like concat(_utf8mb4'%',_utf8mb4 0xD0B1,_utf8mb4 '%') 1 select convert(_latin1'Günter André' using utf8mb4) like CONVERT(_latin1'GÜNTER%' USING utf8mb4); -convert(_latin1'G?nter Andr?' using utf8mb4) like CONVERT(_latin1'G?NTER%' USING utf8mb4) +convert(_latin1'G\xFCnter Andr\xE9' using utf8mb4) like CONVERT(_latin1'G\xDCNTER%' USING utf8mb4) 1 select CONVERT(_koi8r'×ÁÓÑ' USING utf8mb4) LIKE CONVERT(_koi8r'÷áóñ' USING utf8mb4); -CONVERT(_koi8r'????' USING utf8mb4) LIKE CONVERT(_koi8r'????' USING utf8mb4) +CONVERT(_koi8r'\xD7\xC1\xD3\xD1' USING utf8mb4) LIKE CONVERT(_koi8r'\xF7\xE1\xF3\xF1' USING utf8mb4) 1 select CONVERT(_koi8r'÷áóñ' USING utf8mb4) LIKE CONVERT(_koi8r'×ÁÓÑ' USING utf8mb4); -CONVERT(_koi8r'????' USING utf8mb4) LIKE CONVERT(_koi8r'????' USING utf8mb4) +CONVERT(_koi8r'\xF7\xE1\xF3\xF1' USING utf8mb4) LIKE CONVERT(_koi8r'\xD7\xC1\xD3\xD1' USING utf8mb4) 1 SELECT 'a' = 'a '; 'a' = 'a ' @@ -1281,7 +1281,7 @@ concat(concat(_latin1'->',f1),_latin1'<-') -><- drop table t1; select convert(_koi8r'É' using utf8mb4) < convert(_koi8r'Ê' using utf8mb4); -convert(_koi8r'?' using utf8mb4) < convert(_koi8r'?' using utf8mb4) +convert(_koi8r'\xC9' using utf8mb4) < convert(_koi8r'\xCA' using utf8mb4) 1 set names latin1; create table t1 (a varchar(10)) character set utf8mb4 engine MyISAM; diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index 8f912e0500d..0815ff06557 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -8563,6 +8563,41 @@ select count(*) from information_schema.optimizer_trace; select * from information_schema.optimizer_trace; set max_session_mem_used=default; # +# MDEV-22380 Assertion `name.length == strlen(name.str)' failed in Item::print_item_w_name on SELECT w/ optimizer_trace enabled +# +SET optimizer_trace="enabled=on"; +SELECT 'a\0' LIMIT 0; +a\x00 +SELECT query, trace FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +query trace +SELECT 'a\0' LIMIT 0 { + "steps": [ + { + "join_preparation": { + "select_id": 1, + "steps": [ + { + "expanded_query": "select 'a\0' AS `a\x00` limit 0" + } + ] + } + }, + { + "join_optimization": { + "select_id": 1, + "steps": [] + } + }, + { + "join_execution": { + "select_id": 1, + "steps": [] + } + } + ] +} +SET optimizer_trace=DEFAULT; +# # End of 10.4 tests # set optimizer_trace='enabled=on'; diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test index ecb6658e338..a191761d17d 100644 --- a/mysql-test/main/opt_trace.test +++ b/mysql-test/main/opt_trace.test @@ -635,6 +635,15 @@ select * from information_schema.optimizer_trace; set max_session_mem_used=default; --echo # +--echo # MDEV-22380 Assertion `name.length == strlen(name.str)' failed in Item::print_item_w_name on SELECT w/ optimizer_trace enabled +--echo # + +SET optimizer_trace="enabled=on"; +SELECT 'a\0' LIMIT 0; +SELECT query, trace FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +SET optimizer_trace=DEFAULT; + +--echo # --echo # End of 10.4 tests --echo # diff --git a/mysql-test/main/plugin.result b/mysql-test/main/plugin.result index 50986b95ccc..a0c7eef818b 100644 --- a/mysql-test/main/plugin.result +++ b/mysql-test/main/plugin.result @@ -320,7 +320,7 @@ select plugin_name from information_schema.plugins where plugin_library like 'ha plugin_name set names utf8; select convert('adminðŒ†' using utf8); -convert('adminðŒ†' using utf8) +convert('admin\xF0\x9D\x8C\x86' using utf8) admin???? Warnings: Warning 1300 Invalid utf8 character string: '\xF0\x9D\x8C\x86' diff --git a/mysql-test/suite/encryption/r/instant_alter_import.result b/mysql-test/suite/encryption/r/instant_alter_import.result new file mode 100644 index 00000000000..cb6e7ea7307 --- /dev/null +++ b/mysql-test/suite/encryption/r/instant_alter_import.result @@ -0,0 +1,24 @@ +SET GLOBAL innodb_encrypt_tables = ON; +SET GLOBAL innodb_encryption_threads = 4; +CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, i2 INT, i1 INT) +ENGINE=INNODB ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +INSERT INTO t1 (i2) SELECT 4 FROM seq_1_to_1024; +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; +FLUSH TABLE t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; +DROP TABLE t2, t1; +CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, i2 INT, i1 INT) +ENGINE=INNODB ENCRYPTED=YES ENCRYPTION_KEY_ID=4 PAGE_COMPRESSED=1; +INSERT INTO t1 (i2) SELECT 4 FROM seq_1_to_1024; +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; +FLUSH TABLE t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; +DROP TABLE t2, t1; +SET GLOBAL innodb_encrypt_tables = OFF; +SET GLOBAL innodb_encryption_threads = 0; diff --git a/mysql-test/suite/encryption/t/instant_alter_import.test b/mysql-test/suite/encryption/t/instant_alter_import.test new file mode 100644 index 00000000000..3a00c54665c --- /dev/null +++ b/mysql-test/suite/encryption/t/instant_alter_import.test @@ -0,0 +1,52 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc +--source include/have_file_key_management_plugin.inc + +SET GLOBAL innodb_encrypt_tables = ON; +SET GLOBAL innodb_encryption_threads = 4; + + +--let $MYSQLD_DATADIR= `SELECT @@datadir` + +CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, i2 INT, i1 INT) + ENGINE=INNODB ENCRYPTED=YES ENCRYPTION_KEY_ID=4; + +INSERT INTO t1 (i2) SELECT 4 FROM seq_1_to_1024; +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; + +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; + +FLUSH TABLE t1 FOR EXPORT; + +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t2.ibd +--copy_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_DATADIR/test/t2.cfg + +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; + +DROP TABLE t2, t1; + + +CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, i2 INT, i1 INT) + ENGINE=INNODB ENCRYPTED=YES ENCRYPTION_KEY_ID=4 PAGE_COMPRESSED=1; + +INSERT INTO t1 (i2) SELECT 4 FROM seq_1_to_1024; +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; + +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; + +FLUSH TABLE t1 FOR EXPORT; + +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t2.ibd +--copy_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_DATADIR/test/t2.cfg + +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; + +DROP TABLE t2, t1; + + +SET GLOBAL innodb_encrypt_tables = OFF; +SET GLOBAL innodb_encryption_threads = 0; diff --git a/mysql-test/suite/innodb/r/default_row_format_compatibility.result b/mysql-test/suite/innodb/r/default_row_format_compatibility.result index 5070fa33a2e..f7aa984b279 100644 --- a/mysql-test/suite/innodb/r/default_row_format_compatibility.result +++ b/mysql-test/suite/innodb/r/default_row_format_compatibility.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("Index for table 'tab' is corrupt; try to repair it"); SET @row_format = @@GLOBAL.innodb_default_row_format; # ########################################################### # Check with Import/Export tablespace with Default_row_format @@ -38,7 +39,7 @@ tab InnoDB # Compact # # # # # # NULL # NULL NULL latin1_swedish_ci NULL 0 N ALTER TABLE tab DISCARD TABLESPACE; call mtr.add_suppression("InnoDB: Tried to read .* bytes at offset 0"); ALTER TABLE tab IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`tab` : I/O error +ERROR HY000: Index for table 'tab' is corrupt; try to repair it ALTER TABLE tab IMPORT TABLESPACE; SELECT * FROM tab; a diff --git a/mysql-test/suite/innodb/r/full_crc32_import.result b/mysql-test/suite/innodb/r/full_crc32_import.result index 6fec6107f2c..677bff22d53 100644 --- a/mysql-test/suite/innodb/r/full_crc32_import.result +++ b/mysql-test/suite/innodb/r/full_crc32_import.result @@ -46,7 +46,7 @@ t1 CREATE TABLE `t1` ( `b` blob DEFAULT NULL, `c` blob DEFAULT NULL, PRIMARY KEY (`a`) -) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC UPDATE t1 set b = repeat("de", 100) where b = repeat("cd", 200); explain SELECT a FROM t1 where b = repeat("de", 100); id select_type table type possible_keys key key_len ref rows Extra @@ -127,7 +127,7 @@ t1 CREATE TABLE `t1` ( `c2` point NOT NULL, `c3` linestring NOT NULL, PRIMARY KEY (`c1`) -) ENGINE=InnoDB AUTO_INCREMENT=14325 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +) ENGINE=InnoDB AUTO_INCREMENT=16372 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC UPDATE t1 SET C2 = ST_GeomFromText('POINT(0 0)'); SELECT COUNT(*) FROM t1; COUNT(*) diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result index 1030fbd0502..0b5d9ab55b6 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result @@ -935,7 +935,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Index for table 't1' is corrupt; try to repair it SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd diff --git a/mysql-test/suite/innodb/r/instant_alter_import.result b/mysql-test/suite/innodb/r/instant_alter_import.result index 008a26ea6af..c31e9c8e656 100644 --- a/mysql-test/suite/innodb/r/instant_alter_import.result +++ b/mysql-test/suite/innodb/r/instant_alter_import.result @@ -61,13 +61,10 @@ alter table t1 discard tablespace; flush tables t2 for export; unlock tables; alter table t1 import tablespace; -ERROR HY000: Schema mismatch (Index field count 4 doesn't match tablespace metadata file value 5) select * from t1; -ERROR HY000: Tablespace has been discarded for table `t1` -alter table t1 import tablespace; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Unsupported -select * from t1; -ERROR HY000: Tablespace has been discarded for table `t1` +z +42 +41 drop table t2; drop table t1; CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, i1 INT) ENGINE=INNODB; @@ -78,3 +75,46 @@ FLUSH TABLE t1 FOR EXPORT; UNLOCK TABLES; ALTER TABLE t2 IMPORT TABLESPACE; DROP TABLE t2, t1; +CREATE TABLE t1 (id INT PRIMARY KEY, i2 INT, i1 INT) ENGINE=INNODB; +INSERT INTO t1 VALUES (1, 1, 1); +ALTER TABLE t1 MODIFY COLUMN i2 INT AFTER i1, ALGORITHM=INSTANT; +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; +FLUSH TABLE t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; +SELECT * FROM t2; +id i1 i2 +1 1 1 +DROP TABLE t2, t1; +CREATE TABLE t1 (id INT PRIMARY KEY, i2 INT, i1 INT) ENGINE=INNODB; +INSERT INTO t1 VALUES (1, 1, 1); +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; +FLUSH TABLE t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; +SELECT * FROM t2; +id i1 +1 1 +DROP TABLE t2, t1; +CREATE TABLE t1 (id INT PRIMARY KEY, i2 INT, i1 INT) +ENGINE=INNODB PAGE_COMPRESSED=1; +INSERT INTO t1 VALUES (1, 1, 1); +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; +FLUSH TABLE t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; +DROP TABLE t2, t1; +CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, i2 INT, i1 INT) ENGINE=INNODB; +INSERT INTO t1 (i2) SELECT 4 FROM seq_1_to_1024; +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; +FLUSH TABLE t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; +DROP TABLE t2, t1; diff --git a/mysql-test/suite/innodb/t/default_row_format_compatibility.test b/mysql-test/suite/innodb/t/default_row_format_compatibility.test index 3dea78b2ff0..0868974c9df 100644 --- a/mysql-test/suite/innodb/t/default_row_format_compatibility.test +++ b/mysql-test/suite/innodb/t/default_row_format_compatibility.test @@ -1,5 +1,8 @@ --source include/have_innodb.inc +call mtr.add_suppression("Index for table 'tab' is corrupt; try to repair it"); + + SET @row_format = @@GLOBAL.innodb_default_row_format; # set the variables @@ -79,7 +82,7 @@ ALTER TABLE tab DISCARD TABLESPACE; call mtr.add_suppression("InnoDB: Tried to read .* bytes at offset 0"); ---error ER_INTERNAL_ERROR +--error ER_NOT_KEYFILE ALTER TABLE tab IMPORT TABLESPACE; --remove_file $MYSQLD_DATADIR/test/tab.ibd --move_file $MYSQLD_DATADIR/tab.ibd $MYSQLD_DATADIR/test/tab.ibd diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test index a22afc041b0..7bc71d87a03 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test @@ -1351,7 +1351,7 @@ SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure"; --replace_regex /'.*t1.cfg'/'t1.cfg'/ ---error ER_INTERNAL_ERROR +--error ER_NOT_KEYFILE ALTER TABLE t1 IMPORT TABLESPACE; SET SESSION debug_dbug=@saved_debug_dbug; diff --git a/mysql-test/suite/innodb/t/instant_alter_import.test b/mysql-test/suite/innodb/t/instant_alter_import.test index d01f4325f1e..4bec3f8b7f5 100644 --- a/mysql-test/suite/innodb/t/instant_alter_import.test +++ b/mysql-test/suite/innodb/t/instant_alter_import.test @@ -1,4 +1,7 @@ --source include/have_innodb.inc +--source include/have_sequence.inc +--source include/innodb_checksum_algorithm.inc + set default_storage_engine=innodb; --echo # @@ -70,14 +73,7 @@ flush tables t2 for export; --copy_file $MYSQLD_DATADIR/test/t2.ibd $MYSQLD_DATADIR/test/t1.ibd unlock tables; ---error ER_TABLE_SCHEMA_MISMATCH -alter table t1 import tablespace; ---error ER_TABLESPACE_DISCARDED -select * from t1; ---remove_file $MYSQLD_DATADIR/test/t1.cfg ---error ER_INTERNAL_ERROR alter table t1 import tablespace; ---error ER_TABLESPACE_DISCARDED select * from t1; drop table t2; @@ -101,3 +97,86 @@ UNLOCK TABLES; ALTER TABLE t2 IMPORT TABLESPACE; DROP TABLE t2, t1; + + +CREATE TABLE t1 (id INT PRIMARY KEY, i2 INT, i1 INT) ENGINE=INNODB; + +INSERT INTO t1 VALUES (1, 1, 1); +ALTER TABLE t1 MODIFY COLUMN i2 INT AFTER i1, ALGORITHM=INSTANT; + +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; + + +FLUSH TABLE t1 FOR EXPORT; + +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t2.ibd +--copy_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_DATADIR/test/t2.cfg + +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; + +SELECT * FROM t2; + +DROP TABLE t2, t1; + + +CREATE TABLE t1 (id INT PRIMARY KEY, i2 INT, i1 INT) ENGINE=INNODB; + +INSERT INTO t1 VALUES (1, 1, 1); +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; + +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; + + +FLUSH TABLE t1 FOR EXPORT; + +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t2.ibd +--copy_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_DATADIR/test/t2.cfg + +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; + +SELECT * FROM t2; + +DROP TABLE t2, t1; + + +CREATE TABLE t1 (id INT PRIMARY KEY, i2 INT, i1 INT) + ENGINE=INNODB PAGE_COMPRESSED=1; + +INSERT INTO t1 VALUES (1, 1, 1); +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; + +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; + +FLUSH TABLE t1 FOR EXPORT; + +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t2.ibd +--copy_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_DATADIR/test/t2.cfg + +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; + +DROP TABLE t2, t1; + + +CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, i2 INT, i1 INT) ENGINE=INNODB; + +INSERT INTO t1 (i2) SELECT 4 FROM seq_1_to_1024; +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; + +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; + +FLUSH TABLE t1 FOR EXPORT; + +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t2.ibd +--copy_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_DATADIR/test/t2.cfg + +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; + +DROP TABLE t2, t1; diff --git a/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result index fccee685caf..3feb51bac98 100644 --- a/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result +++ b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result @@ -402,7 +402,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Index for table 't1' is corrupt; try to repair it SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd diff --git a/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test b/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test index 282469f0a0c..a7916477e0a 100644 --- a/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test +++ b/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test @@ -611,7 +611,7 @@ EOF SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure"; ---error ER_INTERNAL_ERROR +--error ER_NOT_KEYFILE ALTER TABLE t1 IMPORT TABLESPACE; SET SESSION debug_dbug=@saved_debug_dbug; diff --git a/sql/item.cc b/sql/item.cc index 2f9f6a25a7e..c661722ead4 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1119,6 +1119,80 @@ bool Item::check_type_scalar(const char *opname) const } +extern "C" { + +/* + All values greater than MY_NAME_BINARY_VALUE are + interpreted as binary bytes. + The exact constant value does not matter, + but it must be greater than 0x10FFFF, + which is the maximum possible character in Unicode. +*/ +#define MY_NAME_BINARY_VALUE 0x200000 + +/* + Print all binary bytes as well as zero character U+0000 in hex notation. + Print other characters normally. +*/ +static int +my_wc_mb_item_name(CHARSET_INFO *cs, my_wc_t wc, uchar *str, uchar *end) +{ + if (wc == 0 || wc >= MY_NAME_BINARY_VALUE) + { + if (str + 4 >= end) + return MY_CS_TOOSMALL3; + str[0]= '\\'; + str[1]= 'x'; + str[2]= _dig_vec_upper[(uchar) (wc >> 4)]; + str[3]= _dig_vec_upper[(uchar) wc & 0x0F]; + return 4; + } + return my_charset_utf8mb3_handler.wc_mb(cs, wc, str, end); +} + + +/* + Scan characters and mark all illegal sequences as binary byte values, + to have my_wc_mb_utf8_escape_name() print them using HEX notation. +*/ +static int +my_mb_wc_item_name(CHARSET_INFO *cs, my_wc_t *pwc, + const uchar *str, const uchar *end) +{ + int rc= cs->cset->mb_wc(cs, pwc, str, end); + if (rc == MY_CS_ILSEQ) + { + *pwc= MY_NAME_BINARY_VALUE + *str; + return 1; + } + return rc; +} + +} + + +static LEX_CSTRING +make_name(THD *thd, + const char *str, size_t length, CHARSET_INFO *cs, + size_t max_octet_length) +{ + uint errors; + size_t dst_nbytes= length * system_charset_info->mbmaxlen; + set_if_smaller(dst_nbytes, max_octet_length); + char *dst= (char*) thd->alloc(dst_nbytes + 1); + if (!dst) + return null_clex_str; + uint32 cnv_length= my_convert_using_func(dst, dst_nbytes, system_charset_info, + my_wc_mb_item_name, + str, length, + cs == &my_charset_bin ? + system_charset_info : cs, + my_mb_wc_item_name, &errors); + dst[cnv_length]= '\0'; + return Lex_cstring(dst, cnv_length); +} + + void Item::set_name(THD *thd, const char *str, size_t length, CHARSET_INFO *cs) { if (!length) @@ -1169,32 +1243,14 @@ void Item::set_name(THD *thd, const char *str, size_t length, CHARSET_INFO *cs) ER_REMOVED_SPACES, ER_THD(thd, ER_REMOVED_SPACES), buff); } - if (!my_charset_same(cs, system_charset_info)) - { - size_t res_length; - name.str= sql_strmake_with_convert(thd, str, length, cs, - MAX_ALIAS_NAME, system_charset_info, - &res_length); - name.length= res_length; - } - else - name.str= thd->strmake(str, (name.length= MY_MIN(length,MAX_ALIAS_NAME))); + name= make_name(thd, str, length, cs, MAX_ALIAS_NAME - 1); } void Item::set_name_no_truncate(THD *thd, const char *str, uint length, CHARSET_INFO *cs) { - if (!my_charset_same(cs, system_charset_info)) - { - size_t res_length; - name.str= sql_strmake_with_convert(thd, str, length, cs, - UINT_MAX, system_charset_info, - &res_length); - name.length= res_length; - } - else - name.str= thd->strmake(str, (name.length= length)); + name= make_name(thd, str, length, cs, UINT_MAX - 1); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 7d3eb64e5a0..e61c19cd0d5 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -13163,25 +13163,6 @@ ha_innobase::discard_or_import_tablespace( err, m_prebuilt->table->flags, NULL)); } - /* Evict and reload the table definition in order to invoke - btr_cur_instant_init(). */ - table_id_t id = m_prebuilt->table->id; - ut_ad(id); - mutex_enter(&dict_sys.mutex); - dict_table_close(m_prebuilt->table, TRUE, FALSE); - dict_sys.remove(m_prebuilt->table); - m_prebuilt->table = dict_table_open_on_id(id, TRUE, - DICT_TABLE_OP_NORMAL); - mutex_exit(&dict_sys.mutex); - if (!m_prebuilt->table) { - err = DB_TABLE_NOT_FOUND; - } else { - if (const Field* ai = table->found_next_number_field) { - initialize_auto_increment(m_prebuilt->table, ai); - } - dict_stats_init(m_prebuilt->table); - } - if (dict_stats_is_persistent_enabled(m_prebuilt->table)) { dberr_t ret; diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 10fec4d0871..ea4a0b93516 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -633,6 +633,18 @@ public: static bool full_crc32(ulint flags) { return flags & FSP_FLAGS_FCRC32_MASK_MARKER; } + /** Determine if full_crc32 is used along with compression */ + static bool is_full_crc32_compressed(ulint flags) + { + if (full_crc32(flags)) + { + ulint algo= FSP_FLAGS_FCRC32_GET_COMPRESSED_ALGO(flags); + DBUG_ASSERT(algo <= PAGE_ALGORITHM_LAST); + return algo > 0; + } + + return false; + } /** @return whether innodb_checksum_algorithm=full_crc32 is active */ bool full_crc32() const { return full_crc32(flags); } /** Determine the logical page size. @@ -694,21 +706,15 @@ public: unsigned zip_size() const { return zip_size(flags); } /** @return the physical page size */ unsigned physical_size() const { return physical_size(flags); } - /** Check whether the compression enabled in tablespace. - @param[in] flags tablespace flags */ - static bool is_compressed(ulint flags) { - - if (full_crc32(flags)) { - ulint algo = FSP_FLAGS_FCRC32_GET_COMPRESSED_ALGO( - flags); - DBUG_ASSERT(algo <= PAGE_ALGORITHM_LAST); - return algo > 0; - } - - return FSP_FLAGS_HAS_PAGE_COMPRESSION(flags); - } - /** @return whether the compression enabled for the tablespace. */ - bool is_compressed() const { return is_compressed(flags); } + /** Check whether the compression enabled in tablespace. + @param[in] flags tablespace flags */ + static bool is_compressed(ulint flags) + { + return is_full_crc32_compressed(flags) || + FSP_FLAGS_HAS_PAGE_COMPRESSION(flags); + } + /** @return whether the compression enabled for the tablespace. */ + bool is_compressed() const { return is_compressed(flags); } /** Get the compression algorithm for full crc32 format. @param[in] flags tablespace flags diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 7fe5cc1802c..aa1613fe436 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -40,6 +40,7 @@ Created 2012-02-08 by Sunny Bains. #include "row0quiesce.h" #include "fil0pagecompress.h" #include "trx0undo.h" +#include "row0row.h" #ifdef HAVE_LZO #include "lzo/lzo1x.h" #endif @@ -47,6 +48,8 @@ Created 2012-02-08 by Sunny Bains. #include "snappy-c.h" #endif +#include "scope.h" + #include <vector> #ifdef HAVE_MY_AES_H @@ -190,6 +193,9 @@ struct row_import { dberr_t match_schema( THD* thd) UNIV_NOTHROW; + dberr_t match_flags(THD *thd) const ; + + dict_table_t* m_table; /*!< Table instance */ ulint m_version; /*!< Version of config file */ @@ -327,7 +333,7 @@ public: mtr_t m_mtr; }; -/** Class that purges delete marked reocords from indexes, both secondary +/** Class that purges delete marked records from indexes, both secondary and cluster. It does a pessimistic delete. This should only be done if we couldn't purge the delete marked reocrds during Phase I. */ class IndexPurge { @@ -605,8 +611,6 @@ AbstractCallback::init( if (!fil_space_t::is_valid_flags(m_space_flags, true)) { ulint cflags = fsp_flags_convert_from_101(m_space_flags); if (cflags == ULINT_UNDEFINED) { - ib::error() << "Invalid FSP_SPACE_FLAGS=" - << ib::hex(m_space_flags); return(DB_CORRUPTION); } m_space_flags = cflags; @@ -1123,7 +1127,8 @@ row_import::match_index_columns( for (ulint i = 0; i < index->n_fields; ++i, ++field, ++cfg_field) { - if (strcmp(field->name(), cfg_field->name()) != 0) { + if (field->name() && cfg_field->name() + && strcmp(field->name(), cfg_field->name()) != 0) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, "Index field name %s doesn't match" @@ -1292,6 +1297,61 @@ row_import::match_table_columns( return(err); } +dberr_t row_import::match_flags(THD *thd) const +{ + ulint mismatch= (m_table->flags ^ m_flags) & ~DICT_TF_MASK_DATA_DIR; + if (!mismatch) + return DB_SUCCESS; + + const char *msg; + if (mismatch & DICT_TF_MASK_ZIP_SSIZE) + { + if ((m_table->flags & DICT_TF_MASK_ZIP_SSIZE) && + (m_flags & DICT_TF_MASK_ZIP_SSIZE)) + { + switch (m_flags & DICT_TF_MASK_ZIP_SSIZE) { + case 0U << DICT_TF_POS_ZIP_SSIZE: + goto uncompressed; + case 1U << DICT_TF_POS_ZIP_SSIZE: + msg= "ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1"; + break; + case 2U << DICT_TF_POS_ZIP_SSIZE: + msg= "ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2"; + break; + case 3U << DICT_TF_POS_ZIP_SSIZE: + msg= "ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4"; + break; + case 4U << DICT_TF_POS_ZIP_SSIZE: + msg= "ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8"; + break; + case 5U << DICT_TF_POS_ZIP_SSIZE: + msg= "ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16"; + break; + default: + msg= "strange KEY_BLOCK_SIZE"; + } + } + else if (m_flags & DICT_TF_MASK_ZIP_SSIZE) + msg= "ROW_FORMAT=COMPRESSED"; + else + goto uncompressed; + } + else + { + uncompressed: + msg= (m_flags & DICT_TF_MASK_ATOMIC_BLOBS) ? "ROW_FORMAT=DYNAMIC" + : (m_flags & DICT_TF_MASK_COMPACT) ? "ROW_FORMAT=COMPACT" + : "ROW_FORMAT=REDUNDANT"; + } + + ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, + "Table flags don't match, server table has 0x%x and the meta-data " + "file has 0x%zx; .cfg file uses %s", + m_table->flags, m_flags, msg); + + return DB_ERROR; +} + /** Check if the table (and index) schema that was read from the .cfg file matches the in memory table definition. @param thd MySQL session variable @@ -1302,60 +1362,7 @@ row_import::match_schema( { /* Do some simple checks. */ - if (ulint mismatch = (m_table->flags ^ m_flags) - & ~DICT_TF_MASK_DATA_DIR) { - const char* msg; - if (mismatch & DICT_TF_MASK_ZIP_SSIZE) { - if ((m_table->flags & DICT_TF_MASK_ZIP_SSIZE) - && (m_flags & DICT_TF_MASK_ZIP_SSIZE)) { - switch (m_flags & DICT_TF_MASK_ZIP_SSIZE) { - case 0U << DICT_TF_POS_ZIP_SSIZE: - goto uncompressed; - case 1U << DICT_TF_POS_ZIP_SSIZE: - msg = "ROW_FORMAT=COMPRESSED" - " KEY_BLOCK_SIZE=1"; - break; - case 2U << DICT_TF_POS_ZIP_SSIZE: - msg = "ROW_FORMAT=COMPRESSED" - " KEY_BLOCK_SIZE=2"; - break; - case 3U << DICT_TF_POS_ZIP_SSIZE: - msg = "ROW_FORMAT=COMPRESSED" - " KEY_BLOCK_SIZE=4"; - break; - case 4U << DICT_TF_POS_ZIP_SSIZE: - msg = "ROW_FORMAT=COMPRESSED" - " KEY_BLOCK_SIZE=8"; - break; - case 5U << DICT_TF_POS_ZIP_SSIZE: - msg = "ROW_FORMAT=COMPRESSED" - " KEY_BLOCK_SIZE=16"; - break; - default: - msg = "strange KEY_BLOCK_SIZE"; - } - } else if (m_flags & DICT_TF_MASK_ZIP_SSIZE) { - msg = "ROW_FORMAT=COMPRESSED"; - } else { - goto uncompressed; - } - } else { -uncompressed: - msg = (m_flags & DICT_TF_MASK_ATOMIC_BLOBS) - ? "ROW_FORMAT=DYNAMIC" - : (m_flags & DICT_TF_MASK_COMPACT) - ? "ROW_FORMAT=COMPACT" - : "ROW_FORMAT=REDUNDANT"; - } - - ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, - "Table flags don't match, server table has 0x%x" - " and the meta-data file has 0x" ULINTPFx ";" - " .cfg file uses %s", - m_table->flags, m_flags, msg); - - return(DB_ERROR); - } else if (m_table->n_cols != m_n_cols) { + if (m_table->n_cols != m_n_cols) { ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, "Number of columns don't match, table has %u " "columns but the tablespace meta-data file has " @@ -1977,42 +1984,7 @@ PageConverter::update_index_page( } if (m_index->m_srv_index->is_clust()) { - if (page_id.page_no() == m_index->m_srv_index->page) { - dict_index_t* index = const_cast<dict_index_t*>( - m_index->m_srv_index); - /* Preserve the PAGE_ROOT_AUTO_INC. */ - if (index->table->supports_instant()) { - if (btr_cur_instant_root_init(index, page)) { - return(DB_CORRUPTION); - } - - if (index->n_core_fields > index->n_fields) { - /* Some columns have been dropped. - Refuse to IMPORT TABLESPACE for now. - - NOTE: This is not an accurate check. - Columns could have been both - added and dropped instantly. - For an accurate check, we must read - the metadata BLOB page pointed to - by the leftmost leaf page. - - But we would have to read - those pages in a special way, - bypassing the buffer pool! */ - return DB_UNSUPPORTED; - } - - /* Provisionally set all instantly - added columns to be DEFAULT NULL. */ - for (unsigned i = index->n_core_fields; - i < index->n_fields; i++) { - dict_col_t* col = index->fields[i].col; - col->def_val.len = UNIV_SQL_NULL; - col->def_val.data = NULL; - } - } - } else { + if (page_id.page_no() != m_index->m_srv_index->page) { goto clear_page_max_trx_id; } } else if (page_is_leaf(page)) { @@ -3120,6 +3092,377 @@ row_import_read_meta_data( return(DB_ERROR); } +#define BTR_BLOB_HDR_PART_LEN 0 /*!< BLOB part len on this page */ +#define BTR_BLOB_HDR_NEXT_PAGE_NO 4 /*!< next BLOB part page no, + FIL_NULL if none */ +#define BTR_BLOB_HDR_SIZE 8 /*!< Size of a BLOB part header, in bytes */ + +/* decrypt and decompress page if needed */ +static dberr_t decrypt_decompress(fil_space_crypt_t *space_crypt, + size_t space_flags, span<byte> page, + size_t space_id, byte *page_compress_buf) +{ + auto *data= page.data(); + + if (space_crypt && space_crypt->should_encrypt()) + { + if (!buf_page_verify_crypt_checksum(data, space_flags)) + return DB_CORRUPTION; + + dberr_t err; + if (!fil_space_decrypt(space_id, space_crypt, data, page.size(), + space_flags, data, &err) || err != DB_SUCCESS) + return err; + } + + bool page_compressed= false; + + if (fil_space_t::full_crc32(space_flags) && + fil_space_t::is_compressed(space_flags)) + page_compressed= buf_page_is_compressed(data, space_flags); + else + { + switch (fil_page_get_type(data)) { + case FIL_PAGE_PAGE_COMPRESSED: + case FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED: + page_compressed= true; + } + } + + if (page_compressed) + { + auto compress_length= + fil_page_decompress(page_compress_buf, data, space_flags); + ut_ad(compress_length != srv_page_size); + + if (compress_length == 0) + return DB_CORRUPTION; + } + + return DB_SUCCESS; +} + +static size_t get_buf_size() +{ + return srv_page_size +#ifdef HAVE_LZO + + LZO1X_1_15_MEM_COMPRESS +#elif defined HAVE_SNAPPY + + snappy_max_compressed_length(srv_page_size) +#endif + ; +} + +/* find, parse instant metadata, performing variaous checks, +and apply it to dict_table_t +@return DB_SUCCESS or some error */ +static dberr_t handle_instant_metadata(dict_table_t *table, + const row_import &cfg) +{ + dict_get_and_save_data_dir_path(table, false); + + char *filepath; + if (DICT_TF_HAS_DATA_DIR(table->flags)) + { + ut_a(table->data_dir_path); + + filepath= + fil_make_filepath(table->data_dir_path, table->name.m_name, IBD, true); + } + else + filepath= fil_make_filepath(nullptr, table->name.m_name, IBD, false); + + if (!filepath) + return DB_OUT_OF_MEMORY; + + SCOPE_EXIT([filepath]() { ut_free(filepath); }); + + bool success; + auto file= os_file_create_simple_no_error_handling( + innodb_data_file_key, filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, false, + &success); + if (!success) + return DB_IO_ERROR; + + if (os_file_get_size(file) < srv_page_size * 4) + return DB_CORRUPTION; + + SCOPE_EXIT([&file]() { os_file_close(file); }); + + std::unique_ptr<byte[], decltype(&aligned_free)> first_page( + static_cast<byte *>(aligned_malloc(srv_page_size, srv_page_size)), + &aligned_free); + + if (dberr_t err= os_file_read_no_error_handling(IORequestReadPartial, + file, first_page.get(), 0, + srv_page_size, nullptr)) + return err; + + auto space_flags= fsp_header_get_flags(first_page.get()); + + if (!fil_space_t::is_valid_flags(space_flags, true)) + { + auto cflags= fsp_flags_convert_from_101(space_flags); + if (cflags == ULINT_UNDEFINED) + { + ib::error() << "Invalid FSP_SPACE_FLAGS=" << ib::hex(space_flags); + return DB_CORRUPTION; + } + space_flags= static_cast<decltype(space_flags)>(cflags); + } + + if (!cfg.m_missing) + { + if (dberr_t err= cfg.match_flags(current_thd)) + return err; + } + + const auto zip_size= fil_space_t::zip_size(space_flags); + const uint64_t physical_size= zip_size ? zip_size : srv_page_size; + ut_ad(physical_size <= UNIV_PAGE_SIZE_MAX); + const auto space_id= page_get_space_id(first_page.get()); + + auto *space_crypt= fil_space_read_crypt_data(zip_size, first_page.get()); + SCOPE_EXIT([&space_crypt]() { + if (space_crypt) + fil_space_destroy_crypt_data(&space_crypt); + }); + + std::unique_ptr<byte[], decltype(&aligned_free)> page( + static_cast<byte *>( + aligned_malloc(UNIV_PAGE_SIZE_MAX, UNIV_PAGE_SIZE_MAX)), + &aligned_free); + + if (dberr_t err= os_file_read_no_error_handling( + IORequestReadPartial, file, page.get(), 3 * physical_size, + physical_size, nullptr)) + return err; + + std::unique_ptr<byte[]> page_compress_buf(new byte[get_buf_size()]); + + if (dberr_t err= decrypt_decompress(space_crypt, space_flags, + {page.get(), static_cast<size_t> + (physical_size)}, + space_id, page_compress_buf.get())) + return err; + + if (table->supports_instant()) + { + dict_index_t *index= dict_table_get_first_index(table); + + auto tmp1= table->space_id; + table->space_id= page_get_space_id(page.get()); + SCOPE_EXIT([tmp1, table]() { table->space_id= tmp1; }); + + auto tmp2= index->page; + index->page= page_get_page_no(page.get()); + SCOPE_EXIT([tmp2, index]() { index->page= tmp2; }); + + if (!page_is_comp(page.get()) != !dict_table_is_comp(table)) + { + ib_errf(current_thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH, + "ROW_FORMAT mismatch"); + return DB_CORRUPTION; + } + + if (btr_cur_instant_root_init(index, page.get())) + return DB_ERROR; + + ut_ad(index->n_core_null_bytes != dict_index_t::NO_CORE_NULL_BYTES); + + if (fil_page_get_type(page.get()) == FIL_PAGE_INDEX) + { + ut_ad(!index->is_instant()); + return DB_SUCCESS; + } + + mem_heap_t *heap= NULL; + SCOPE_EXIT([&heap]() { mem_heap_free(heap); }); + + while (btr_page_get_level(page.get()) != 0) + { + const rec_t *rec= page_rec_get_next(page_get_infimum_rec(page.get())); + + /* Relax the assertion in rec_init_offsets(). */ + ut_ad(!index->in_instant_init); + ut_d(index->in_instant_init= true); + rec_offs *offsets= + rec_get_offsets(rec, index, nullptr, 0, ULINT_UNDEFINED, &heap); + ut_d(index->in_instant_init= false); + + uint64_t child_page_no= btr_node_ptr_get_child_page_no(rec, offsets); + + if (dberr_t err= + os_file_read_no_error_handling(IORequestReadPartial, file, + page.get(), + child_page_no * physical_size, + physical_size, nullptr)) + return err; + + if (dberr_t err= decrypt_decompress(space_crypt, space_flags, + {page.get(), static_cast<size_t> + (physical_size)}, space_id, + page_compress_buf.get())) + return err; + } + + const auto *rec= page_rec_get_next(page_get_infimum_rec(page.get())); + const auto comp= dict_table_is_comp(index->table); + const auto info_bits= rec_get_info_bits(rec, comp); + + if (page_rec_is_supremum(rec) || !(info_bits & REC_INFO_MIN_REC_FLAG)) + { + ib::error() << "Table " << index->table->name + << " is missing instant ALTER metadata"; + index->table->corrupted= true; + return DB_CORRUPTION; + } + + if ((info_bits & ~REC_INFO_DELETED_FLAG) != REC_INFO_MIN_REC_FLAG || + (comp && rec_get_status(rec) != REC_STATUS_INSTANT)) + { + incompatible: + ib::error() << "Table " << index->table->name + << " contains unrecognizable instant ALTER metadata"; + index->table->corrupted= true; + return DB_CORRUPTION; + } + + if (info_bits & REC_INFO_DELETED_FLAG) + { + ulint trx_id_offset= index->trx_id_offset; + ut_ad(index->n_uniq); + + if (trx_id_offset) + { + } + else if (index->table->not_redundant()) + { + + for (uint i= index->n_uniq; i--;) + trx_id_offset+= index->fields[i].fixed_len; + } + else if (rec_get_1byte_offs_flag(rec)) + { + trx_id_offset= rec_1_get_field_end_info(rec, index->n_uniq - 1); + ut_ad(!(trx_id_offset & REC_1BYTE_SQL_NULL_MASK)); + trx_id_offset&= ~REC_1BYTE_SQL_NULL_MASK; + } + else + { + trx_id_offset= rec_2_get_field_end_info(rec, index->n_uniq - 1); + ut_ad(!(trx_id_offset & REC_2BYTE_SQL_NULL_MASK)); + trx_id_offset&= ~REC_2BYTE_SQL_NULL_MASK; + } + + const byte *ptr= + rec + trx_id_offset + (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN); + + if (mach_read_from_4(ptr + BTR_EXTERN_LEN)) + goto incompatible; + + uint len= mach_read_from_4(ptr + BTR_EXTERN_LEN + 4); + if (!len || mach_read_from_4(ptr + BTR_EXTERN_OFFSET) != FIL_PAGE_DATA) + goto incompatible; + + std::unique_ptr<byte[], decltype(&aligned_free)> + second_page(static_cast<byte*>(aligned_malloc(physical_size, + physical_size)), + &aligned_free); + + if (dberr_t err= + os_file_read_no_error_handling(IORequestReadPartial, file, + second_page.get(), physical_size * + mach_read_from_4(ptr + + BTR_EXTERN_PAGE_NO), + srv_page_size, nullptr)) + return err; + + if (dberr_t err= decrypt_decompress(space_crypt, space_flags, + {second_page.get(), + static_cast<size_t>(physical_size)}, + space_id, page_compress_buf.get())) + return err; + + if (fil_page_get_type(second_page.get()) != FIL_PAGE_TYPE_BLOB || + mach_read_from_4( + &second_page[FIL_PAGE_DATA + BTR_BLOB_HDR_NEXT_PAGE_NO]) != + FIL_NULL || + mach_read_from_4( + &second_page[FIL_PAGE_DATA + BTR_BLOB_HDR_PART_LEN]) != len) + goto incompatible; + + /* The unused part of the BLOB page should be zero-filled. */ + for (const byte * + b= second_page.get() + (FIL_PAGE_DATA + BTR_BLOB_HDR_SIZE) + + len, + *const end= second_page.get() + srv_page_size - BTR_EXTERN_LEN; + b < end;) + { + if (*b++) + goto incompatible; + } + + if (index->table->deserialise_columns( + &second_page[FIL_PAGE_DATA + BTR_BLOB_HDR_SIZE], len)) + goto incompatible; + } + + rec_offs *offsets= rec_get_offsets( + rec, index, nullptr, index->n_core_fields, ULINT_UNDEFINED, &heap); + if (rec_offs_any_default(offsets)) + { + inconsistent: + goto incompatible; + } + + /* In fact, because we only ever append fields to the metadata + record, it is also OK to perform READ UNCOMMITTED and + then ignore any extra fields, provided that + trx_sys.is_registered(DB_TRX_ID). */ + if (rec_offs_n_fields(offsets) > + ulint(index->n_fields) + !!index->table->instant && + !trx_sys.is_registered(current_trx(), + row_get_rec_trx_id(rec, index, offsets))) + goto inconsistent; + + for (unsigned i= index->n_core_fields; i < index->n_fields; i++) + { + dict_col_t *col= index->fields[i].col; + const unsigned o= i + !!index->table->instant; + ulint len; + const byte *data= rec_get_nth_field(rec, offsets, o, &len); + ut_ad(!col->is_added()); + ut_ad(!col->def_val.data); + col->def_val.len= len; + switch (len) { + case UNIV_SQL_NULL: + continue; + case 0: + col->def_val.data= field_ref_zero; + continue; + } + ut_ad(len != UNIV_SQL_DEFAULT); + if (!rec_offs_nth_extern(offsets, o)) + col->def_val.data= mem_heap_dup(index->table->heap, data, len); + else if (len < BTR_EXTERN_FIELD_REF_SIZE || + !memcmp(data + len - BTR_EXTERN_FIELD_REF_SIZE, field_ref_zero, + BTR_EXTERN_FIELD_REF_SIZE)) + { + col->def_val.len= UNIV_SQL_DEFAULT; + goto inconsistent; + } + else + { + col->def_val.data= btr_copy_externally_stored_field( + &col->def_val.len, data, srv_page_size, len, index->table->heap); + } + } + } + + return DB_SUCCESS; +} + /** Read the contents of the <tablename>.cfg file. @return DB_SUCCESS or error code. */ @@ -3428,14 +3771,7 @@ dberr_t FetchIndexRootPages::run(const fil_iterator_t& iter, { const unsigned zip_size= fil_space_t::zip_size(m_space_flags); const unsigned size= zip_size ? zip_size : unsigned(srv_page_size); - const ulint buf_size= -#ifdef HAVE_LZO - LZO1X_1_15_MEM_COMPRESS+ -#elif defined HAVE_SNAPPY - snappy_max_compressed_length(srv_page_size) + -#endif - srv_page_size; - byte* page_compress_buf = static_cast<byte*>(malloc(buf_size)); + byte* page_compress_buf= static_cast<byte*>(malloc(get_buf_size())); const bool full_crc32 = fil_space_t::full_crc32(m_space_flags); bool skip_checksum_check = false; ut_ad(!srv_read_only_mode); @@ -3527,14 +3863,7 @@ static dberr_t fil_iterate( const ulint size = callback.physical_size(); ulint n_bytes = iter.n_io_buffers * size; - const ulint buf_size = srv_page_size -#ifdef HAVE_LZO - + LZO1X_1_15_MEM_COMPRESS -#elif defined HAVE_SNAPPY - + snappy_max_compressed_length(srv_page_size) -#endif - ; - byte* page_compress_buf = static_cast<byte*>(malloc(buf_size)); + byte* page_compress_buf= static_cast<byte*>(malloc(get_buf_size())); ut_ad(!srv_read_only_mode); if (!page_compress_buf) { @@ -4094,6 +4423,11 @@ row_import_for_mysql( if (err == DB_SUCCESS) { + if (dberr_t err = handle_instant_metadata(table, cfg)) { + rw_lock_s_unlock(&dict_sys.latch); + return row_import_error(prebuilt, trx, err); + } + /* We have a schema file, try and match it with our data dictionary. */ @@ -4151,6 +4485,15 @@ row_import_for_mysql( if (err == DB_SUCCESS) { err = cfg.set_root_by_heuristic(); + + if (err == DB_SUCCESS) { + if (dberr_t err = + handle_instant_metadata(table, + cfg)) { + return row_import_error( + prebuilt, trx, err); + } + } } } } else { |