Merge 10.4 into 10.5

This commit is contained in:
Marko Mäkelä 2021-10-27 09:48:22 +03:00
commit 44f9736e0b
32 changed files with 1092 additions and 221 deletions

View File

@ -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

View File

@ -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);

File diff suppressed because one or more lines are too long

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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';

View File

@ -634,6 +634,15 @@ select * from information_schema.optimizer_trace;
--enable_result_log
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 #

View File

@ -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'

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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(*)

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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 {