Merge branch '10.2' into 10.3
This commit is contained in:
commit
4a3d51c76c
18
.clang-format
Normal file
18
.clang-format
Normal file
@ -0,0 +1,18 @@
|
||||
SpaceBeforeAssignmentOperators: false
|
||||
SpaceAfterCStyleCast: true
|
||||
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
@ -183,6 +183,8 @@ INCLUDE(check_compiler_flag)
|
||||
OPTION(WITH_ASAN "Enable address sanitizer" OFF)
|
||||
|
||||
IF (WITH_ASAN AND NOT MSVC)
|
||||
# this flag might be set by default on some OS
|
||||
MY_CHECK_AND_SET_COMPILER_FLAG("-U_FORTIFY_SOURCE" DEBUG RELWITHDEBINFO)
|
||||
# gcc 4.8.1 and new versions of clang
|
||||
MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=address -fPIC"
|
||||
DEBUG RELWITHDEBINFO)
|
||||
@ -216,22 +218,22 @@ ENDIF()
|
||||
|
||||
OPTION(WITH_UBSAN "Enable undefined behavior sanitizer" OFF)
|
||||
IF (WITH_UBSAN)
|
||||
IF(SECURITY_HARDENED)
|
||||
MESSAGE(FATAL_ERROR "WITH_UBSAN and SECURITY_HARDENED are mutually exclusive")
|
||||
ENDIF()
|
||||
MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=undefined -fno-sanitize=alignment" DEBUG RELWITHDEBINFO)
|
||||
MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=undefined -fno-sanitize=alignment -U_FORTIFY_SOURCE" DEBUG RELWITHDEBINFO)
|
||||
ENDIF()
|
||||
|
||||
IF(NOT WITH_TSAN)
|
||||
# enable security hardening features, like most distributions do
|
||||
# in our benchmarks that costs about ~1% of performance, depending on the load
|
||||
IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "4.6")
|
||||
IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "4.6" OR WITH_ASAN OR WITH_UBSAN)
|
||||
SET(security_default OFF)
|
||||
ELSE()
|
||||
SET(security_default ON)
|
||||
ENDIF()
|
||||
OPTION(SECURITY_HARDENED "Use security-enhancing compiler features (stack protector, relro, etc)" ${security_default})
|
||||
IF(SECURITY_HARDENED)
|
||||
IF(WITH_ASAN OR WITH_UBSAN)
|
||||
MESSAGE(FATAL_ERROR "WITH_ASAN/WITH_UBSAN and SECURITY_HARDENED are mutually exclusive")
|
||||
ENDIF()
|
||||
# security-enhancing flags
|
||||
MY_CHECK_AND_SET_COMPILER_FLAG("-pie -fPIC")
|
||||
MY_CHECK_AND_SET_COMPILER_FLAG("-Wl,-z,relro,-z,now")
|
||||
|
@ -269,9 +269,6 @@ innodb_autoinc_lock_mode=2
|
||||
autoinc lock modes 0 and 1 can cause unresolved deadlock, and make
|
||||
the system unresponsive.
|
||||
|
||||
innodb_locks_unsafe_for_binlog=1
|
||||
This option is required for parallel applying.
|
||||
|
||||
5.2 WSREP OPTIONS
|
||||
|
||||
All options are optional except for wsrep_provider, wsrep_cluster_address, and
|
||||
|
@ -13,7 +13,8 @@ SET(fail_patterns
|
||||
FAIL_REGEX "warning:.*redefined"
|
||||
FAIL_REGEX "[Ww]arning: [Oo]ption"
|
||||
)
|
||||
|
||||
#The regex patterns above are not localized, thus LANG=C
|
||||
SET(ENV{LANG} C)
|
||||
MACRO (MY_CHECK_C_COMPILER_FLAG flag)
|
||||
STRING(REGEX REPLACE "[-,= +]" "_" result "have_C_${flag}")
|
||||
SET(SAVE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
|
||||
|
@ -646,6 +646,7 @@ typedef ulong ha_rows;
|
||||
|
||||
#define HA_POS_ERROR (~ (ha_rows) 0)
|
||||
#define HA_OFFSET_ERROR (~ (my_off_t) 0)
|
||||
#define HA_ROWS_MAX HA_POS_ERROR
|
||||
|
||||
#if SIZEOF_OFF_T == 4
|
||||
#define MAX_FILE_SIZE INT_MAX32
|
||||
|
1
mysql-test/main/ctype_utf8_def_upgrade.opt
Normal file
1
mysql-test/main/ctype_utf8_def_upgrade.opt
Normal file
@ -0,0 +1 @@
|
||||
--character-set-server=utf8
|
99
mysql-test/main/ctype_utf8_def_upgrade.result
Normal file
99
mysql-test/main/ctype_utf8_def_upgrade.result
Normal file
@ -0,0 +1,99 @@
|
||||
#
|
||||
# Start of 10.1 tests
|
||||
#
|
||||
#
|
||||
# MDEV-19675 Wrong charset is chosen when opening a pre-4.1 table
|
||||
#
|
||||
# Test with a saved table from 3.23
|
||||
SELECT @@character_set_database;
|
||||
@@character_set_database
|
||||
latin1
|
||||
SET @@character_set_database="latin1";
|
||||
SELECT COUNT(*) FROM t1;
|
||||
ERROR HY000: Got error 190 "Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine. You have to dump an" from storage engine MyISAM
|
||||
CHECK TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check Error Got error 190 "Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine. You have to dump an" from storage engine MyISAM
|
||||
test.t1 check error Corrupt
|
||||
REPAIR TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 repair Error Got error 190 "Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine. You have to dump an" from storage engine MyISAM
|
||||
test.t1 repair error Corrupt
|
||||
REPAIR TABLE t1 USE_FRM;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 repair status OK
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
CHECK TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`Host` char(60) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
|
||||
`Db` char(64) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
|
||||
`Select_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Insert_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Update_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Delete_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Create_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Drop_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Grant_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`References_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Index_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Alter_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
PRIMARY KEY (`Host`,`Db`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Host privileges; Merged with database privileges'
|
||||
DROP TABLE t1;
|
||||
SET @@character_set_database=DEFAULT;
|
||||
# Now do the same, but doing 'ALTER DATABASE' to create the db.opt file,
|
||||
# instead of setting variables directly.
|
||||
# Emulate a pre-4.1 database without db.opt
|
||||
SHOW CREATE DATABASE db1;
|
||||
Database Create Database
|
||||
db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8 */
|
||||
USE db1;
|
||||
SELECT @@character_set_database, 'taken from defaults' AS comment;
|
||||
@@character_set_database comment
|
||||
utf8 taken from defaults
|
||||
USE test;
|
||||
ALTER DATABASE db1 DEFAULT CHARACTER SET latin1;
|
||||
USE db1;
|
||||
SELECT @@character_set_database, 'taken from db.opt' AS comment;
|
||||
@@character_set_database comment
|
||||
latin1 taken from db.opt
|
||||
SELECT COUNT(*) FROM t1;
|
||||
ERROR HY000: Got error 190 "Incompatible key or row definition between the MariaDB .frm file and the information in the storage engine. You have to dump an" from storage engine MyISAM
|
||||
REPAIR TABLE t1 USE_FRM;
|
||||
Table Op Msg_type Msg_text
|
||||
db1.t1 repair status OK
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
CHECK TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
db1.t1 check status OK
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`Host` char(60) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
|
||||
`Db` char(64) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
|
||||
`Select_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Insert_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Update_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Delete_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Create_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Drop_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Grant_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`References_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Index_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
`Alter_priv` enum('N','Y') NOT NULL DEFAULT 'N',
|
||||
PRIMARY KEY (`Host`,`Db`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Host privileges; Merged with database privileges'
|
||||
DROP TABLE t1;
|
||||
DROP DATABASE db1;
|
||||
USE test;
|
||||
#
|
||||
# End of 10.1 tests
|
||||
#
|
61
mysql-test/main/ctype_utf8_def_upgrade.test
Normal file
61
mysql-test/main/ctype_utf8_def_upgrade.test
Normal file
@ -0,0 +1,61 @@
|
||||
let $MYSQLD_DATADIR= `select @@datadir`;
|
||||
|
||||
--echo #
|
||||
--echo # Start of 10.1 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-19675 Wrong charset is chosen when opening a pre-4.1 table
|
||||
--echo #
|
||||
|
||||
--echo # Test with a saved table from 3.23
|
||||
|
||||
SELECT @@character_set_database;
|
||||
SET @@character_set_database="latin1";
|
||||
--copy_file std_data/host_old.frm $MYSQLD_DATADIR/test/t1.frm
|
||||
--copy_file std_data/host_old.MYD $MYSQLD_DATADIR/test/t1.MYD
|
||||
--copy_file std_data/host_old.MYI $MYSQLD_DATADIR/test/t1.MYI
|
||||
|
||||
--error ER_GET_ERRNO
|
||||
SELECT COUNT(*) FROM t1;
|
||||
CHECK TABLE t1;
|
||||
REPAIR TABLE t1;
|
||||
REPAIR TABLE t1 USE_FRM;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
CHECK TABLE t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
SET @@character_set_database=DEFAULT;
|
||||
|
||||
|
||||
--echo # Now do the same, but doing 'ALTER DATABASE' to create the db.opt file,
|
||||
--echo # instead of setting variables directly.
|
||||
|
||||
--echo # Emulate a pre-4.1 database without db.opt
|
||||
--mkdir $MYSQLD_DATADIR/db1
|
||||
SHOW CREATE DATABASE db1;
|
||||
USE db1;
|
||||
SELECT @@character_set_database, 'taken from defaults' AS comment;
|
||||
USE test;
|
||||
ALTER DATABASE db1 DEFAULT CHARACTER SET latin1;
|
||||
USE db1;
|
||||
SELECT @@character_set_database, 'taken from db.opt' AS comment;
|
||||
|
||||
--copy_file std_data/host_old.frm $MYSQLD_DATADIR/db1/t1.frm
|
||||
--copy_file std_data/host_old.MYD $MYSQLD_DATADIR/db1/t1.MYD
|
||||
--copy_file std_data/host_old.MYI $MYSQLD_DATADIR/db1/t1.MYI
|
||||
|
||||
--error ER_GET_ERRNO
|
||||
SELECT COUNT(*) FROM t1;
|
||||
REPAIR TABLE t1 USE_FRM;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
CHECK TABLE t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
DROP DATABASE db1;
|
||||
USE test;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.1 tests
|
||||
--echo #
|
@ -1,4 +1,3 @@
|
||||
drop table if exists t1,t2,t3;
|
||||
set @save_derived_optimizer_switch=@@optimizer_switch;
|
||||
set optimizer_switch='derived_merge=off,derived_with_keys=off';
|
||||
select * from (select 2 from DUAL) b;
|
||||
|
@ -1,7 +1,4 @@
|
||||
# Initialize
|
||||
--disable_warnings
|
||||
drop table if exists t1,t2,t3;
|
||||
--enable_warnings
|
||||
|
||||
set @save_derived_optimizer_switch=@@optimizer_switch;
|
||||
set optimizer_switch='derived_merge=off,derived_with_keys=off';
|
||||
|
@ -3020,7 +3020,7 @@ DROP TABLE t1;
|
||||
set optimizer_switch=@exit_optimizer_switch;
|
||||
set join_cache_level=@exit_join_cache_level;
|
||||
#
|
||||
# Bug mdev-12812: EXPLAIN for query with many expensive derived
|
||||
# Bug mdev-18479: EXPLAIN for query with many expensive derived
|
||||
#
|
||||
CREATE TABLE t1
|
||||
(id int auto_increment primary key,
|
||||
@ -3321,15 +3321,15 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived17> ALL NULL NULL NULL NULL 50328437500000 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived14> ALL NULL NULL NULL NULL 27680640625000000 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived7> ALL NULL NULL NULL NULL 7798774269472204800 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived8> ALL NULL NULL NULL NULL 7798774269472204800 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived9> ALL NULL NULL NULL NULL -3222391729959550976 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived10> ALL NULL NULL NULL NULL -3222391729959550976 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived11> ALL NULL NULL NULL NULL -3222391729959550976 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived12> ALL NULL NULL NULL NULL -3222391729959550976 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived13> ALL NULL NULL NULL NULL -3222391729959550976 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived15> ALL NULL NULL NULL NULL -3222391729959550976 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived16> ALL NULL NULL NULL NULL -3222391729959550976 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived9> ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived10> ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived11> ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived12> ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived13> ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived15> ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived16> ALL NULL NULL NULL NULL 15224352343750000640 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived7> ALL NULL NULL NULL NULL 18446744073709551615 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived8> ALL NULL NULL NULL NULL 18446744073709551615 Using where; Using join buffer (incremental, BNL join)
|
||||
17 DERIVED t2 system NULL NULL NULL NULL 1
|
||||
17 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where
|
||||
17 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join)
|
||||
|
@ -1978,7 +1978,7 @@ set optimizer_switch=@exit_optimizer_switch;
|
||||
set join_cache_level=@exit_join_cache_level;
|
||||
|
||||
--echo #
|
||||
--echo # Bug mdev-12812: EXPLAIN for query with many expensive derived
|
||||
--echo # Bug mdev-18479: EXPLAIN for query with many expensive derived
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1
|
||||
|
@ -1140,7 +1140,7 @@ SELECT 1 FROM v1 right join v1 AS v2 ON RAND();
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` left join `test`.`t1` `t2` on(1 = 1) left join (`test`.`t1` left join `test`.`t1` `t2` on(1 = 1)) on(rand()) where 1
|
||||
|
@ -1966,3 +1966,36 @@ Note 1003 select 1 AS `K1`,'T1Row1' AS `Name`,`t2a`.`K2` AS `K2`,`t2a`.`K1r` AS
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2;
|
||||
set optimizer_search_depth= @tmp_mdev621;
|
||||
#
|
||||
# MDEV-19588: Nested left joins using optimized join cache
|
||||
#
|
||||
set optimizer_switch='optimize_join_buffer_size=on';
|
||||
set @save_join_cache_level= @@join_cache_level;
|
||||
set join_cache_level=2;
|
||||
CREATE TABLE t1 (i1 int, c1 varchar(20), pk int) engine=myisam;
|
||||
CREATE TABLE t2 (pk int, c1 varchar(20), i1 int) engine=myisam;
|
||||
INSERT INTO t2 VALUES (7,'a',-912),(8,'a',5);
|
||||
CREATE TABLE t3 (pk int, c1 varchar(20), i1 int) engine=myisam;
|
||||
INSERT INTO t3 VALUES
|
||||
(1,'a',-145),(2,'a',6),(3,'a',1),(7,'a',NULL),(8,'a',889),(9,'a',146),
|
||||
(10,'a',177),(16,'a',-433),(17,'a',NULL),(18,'a',2),(19,'a',3),(20,'a',5),
|
||||
(21,'a',-484),(22,'a',369),(23,'a',-192),(24,'a',-163),(25,'a',5),(26,'a',NULL);
|
||||
SELECT t3.*
|
||||
FROM t3 LEFT JOIN t1 LEFT JOIN t2 ON t1.i1 = t2.i1 ON t3.i1 = t1.i1
|
||||
WHERE t2.pk < 13 OR t3.i1 IS NULL;
|
||||
pk c1 i1
|
||||
7 a NULL
|
||||
17 a NULL
|
||||
26 a NULL
|
||||
explain extended SELECT t3.*
|
||||
FROM t3 LEFT JOIN t1 LEFT JOIN t2 ON t1.i1 = t2.i1 ON t3.i1 = t1.i1
|
||||
WHERE t2.pk < 13 OR t3.i1 IS NULL;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 18 100.00
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 0 0.00 Using where; Using join buffer (flat, BNL join)
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t3`.`pk` AS `pk`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`i1` AS `i1` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on(`test`.`t2`.`i1` = `test`.`t3`.`i1`)) on(`test`.`t1`.`i1` = `test`.`t3`.`i1`) where `test`.`t2`.`pk` < 13 or `test`.`t3`.`i1` is null
|
||||
DROP TABLE t1,t2,t3;
|
||||
set join_cache_level= @save_join_cache_level;
|
||||
set optimizer_switch=@save_optimizer_switch;
|
||||
|
@ -1380,3 +1380,37 @@ DROP VIEW v1;
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
set optimizer_search_depth= @tmp_mdev621;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-19588: Nested left joins using optimized join cache
|
||||
--echo #
|
||||
|
||||
set optimizer_switch='optimize_join_buffer_size=on';
|
||||
|
||||
set @save_join_cache_level= @@join_cache_level;
|
||||
set join_cache_level=2;
|
||||
|
||||
CREATE TABLE t1 (i1 int, c1 varchar(20), pk int) engine=myisam;
|
||||
|
||||
CREATE TABLE t2 (pk int, c1 varchar(20), i1 int) engine=myisam;
|
||||
INSERT INTO t2 VALUES (7,'a',-912),(8,'a',5);
|
||||
|
||||
CREATE TABLE t3 (pk int, c1 varchar(20), i1 int) engine=myisam;
|
||||
INSERT INTO t3 VALUES
|
||||
(1,'a',-145),(2,'a',6),(3,'a',1),(7,'a',NULL),(8,'a',889),(9,'a',146),
|
||||
(10,'a',177),(16,'a',-433),(17,'a',NULL),(18,'a',2),(19,'a',3),(20,'a',5),
|
||||
(21,'a',-484),(22,'a',369),(23,'a',-192),(24,'a',-163),(25,'a',5),(26,'a',NULL);
|
||||
|
||||
let $q=
|
||||
SELECT t3.*
|
||||
FROM t3 LEFT JOIN t1 LEFT JOIN t2 ON t1.i1 = t2.i1 ON t3.i1 = t1.i1
|
||||
WHERE t2.pk < 13 OR t3.i1 IS NULL;
|
||||
|
||||
eval $q;
|
||||
eval explain extended $q;
|
||||
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
set join_cache_level= @save_join_cache_level;
|
||||
|
||||
set optimizer_switch=@save_optimizer_switch;
|
||||
|
@ -1977,6 +1977,39 @@ Note 1003 select 1 AS `K1`,'T1Row1' AS `Name`,`t2a`.`K2` AS `K2`,`t2a`.`K1r` AS
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1,t2;
|
||||
set optimizer_search_depth= @tmp_mdev621;
|
||||
#
|
||||
# MDEV-19588: Nested left joins using optimized join cache
|
||||
#
|
||||
set optimizer_switch='optimize_join_buffer_size=on';
|
||||
set @save_join_cache_level= @@join_cache_level;
|
||||
set join_cache_level=2;
|
||||
CREATE TABLE t1 (i1 int, c1 varchar(20), pk int) engine=myisam;
|
||||
CREATE TABLE t2 (pk int, c1 varchar(20), i1 int) engine=myisam;
|
||||
INSERT INTO t2 VALUES (7,'a',-912),(8,'a',5);
|
||||
CREATE TABLE t3 (pk int, c1 varchar(20), i1 int) engine=myisam;
|
||||
INSERT INTO t3 VALUES
|
||||
(1,'a',-145),(2,'a',6),(3,'a',1),(7,'a',NULL),(8,'a',889),(9,'a',146),
|
||||
(10,'a',177),(16,'a',-433),(17,'a',NULL),(18,'a',2),(19,'a',3),(20,'a',5),
|
||||
(21,'a',-484),(22,'a',369),(23,'a',-192),(24,'a',-163),(25,'a',5),(26,'a',NULL);
|
||||
SELECT t3.*
|
||||
FROM t3 LEFT JOIN t1 LEFT JOIN t2 ON t1.i1 = t2.i1 ON t3.i1 = t1.i1
|
||||
WHERE t2.pk < 13 OR t3.i1 IS NULL;
|
||||
pk c1 i1
|
||||
7 a NULL
|
||||
17 a NULL
|
||||
26 a NULL
|
||||
explain extended SELECT t3.*
|
||||
FROM t3 LEFT JOIN t1 LEFT JOIN t2 ON t1.i1 = t2.i1 ON t3.i1 = t1.i1
|
||||
WHERE t2.pk < 13 OR t3.i1 IS NULL;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 18 100.00
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 0 0.00 Using where; Using join buffer (flat, BNL join)
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t3`.`pk` AS `pk`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`i1` AS `i1` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on(`test`.`t2`.`i1` = `test`.`t3`.`i1`)) on(`test`.`t1`.`i1` = `test`.`t3`.`i1`) where `test`.`t2`.`pk` < 13 or `test`.`t3`.`i1` is null
|
||||
DROP TABLE t1,t2,t3;
|
||||
set join_cache_level= @save_join_cache_level;
|
||||
set optimizer_switch=@save_optimizer_switch;
|
||||
CREATE TABLE t5 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b));
|
||||
CREATE TABLE t6 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b));
|
||||
CREATE TABLE t7 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b));
|
||||
|
@ -76,21 +76,21 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY p7 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY p8 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY p9 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived3> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived4> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived5> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived6> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived7> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived8> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived9> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived10> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived11> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived12> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived13> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived14> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived15> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived16> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived17> ALL NULL NULL NULL NULL -1127208515966861312 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived5> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived6> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived7> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived8> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived9> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived10> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived11> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived12> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived13> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived14> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived15> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived16> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
1 PRIMARY <derived17> ALL NULL NULL NULL NULL 18446744073709551615 Using join buffer (incremental, BNL join)
|
||||
17 DERIVED r1 ALL NULL NULL NULL NULL 2
|
||||
17 DERIVED d1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
|
||||
17 DERIVED r2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (incremental, BNL join)
|
||||
|
@ -412,7 +412,6 @@ c2_id c2_p_id c2_note c2_active
|
||||
1 1 A Note 1
|
||||
drop table t1, t2;
|
||||
connect root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK;
|
||||
connection root;
|
||||
create database mysqltest;
|
||||
create table mysqltest.t1 (a int, b int, primary key (a));
|
||||
create table mysqltest.t2 (a int, b int, primary key (a));
|
||||
@ -421,7 +420,6 @@ create user mysqltest_1@localhost;
|
||||
grant select on mysqltest.* to mysqltest_1@localhost;
|
||||
grant update on mysqltest.t1 to mysqltest_1@localhost;
|
||||
connect user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK;
|
||||
connection user1;
|
||||
update t1, t2 set t1.b=1 where t1.a=t2.a;
|
||||
update t1, t2 set t1.b=(select t3.b from t3 where t1.a=t3.a) where t1.a=t2.a;
|
||||
connection root;
|
||||
@ -456,13 +454,10 @@ create table t2 (a int);
|
||||
insert into t2 values (10), (20), (30);
|
||||
create view v1 as select a as b, a/10 as a from t2;
|
||||
connect locker,localhost,root,,test;
|
||||
connection locker;
|
||||
lock table t1 write;
|
||||
connect changer,localhost,root,,test;
|
||||
connection changer;
|
||||
alter table t1 add column c int default 100 after a;
|
||||
connect updater,localhost,root,,test;
|
||||
connection updater;
|
||||
update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a;
|
||||
connection locker;
|
||||
unlock tables;
|
||||
@ -963,7 +958,30 @@ triggered
|
||||
triggered
|
||||
drop table t1,t2, t3;
|
||||
drop user foo;
|
||||
end of 5.5 tests
|
||||
create table t1 (a int, b int);
|
||||
create table t2 (c int, d int);
|
||||
insert t1 values (1,2),(3,4);
|
||||
insert t2 values (5,6),(7,8);
|
||||
create table t0 (x int);
|
||||
insert t0 values (11), (22);
|
||||
create trigger tr1 before update on t2 for each row insert t0 values (new.c);
|
||||
connect con1, localhost, root;
|
||||
lock table t0 write;
|
||||
connection default;
|
||||
update t1 join t2 on (a=c+4) set b=d;
|
||||
disconnect con1;
|
||||
drop table t1, t2, t0;
|
||||
create table t1 (a int, b varchar(50), c varchar(50));
|
||||
insert t1 (a,b) values (1,'1'), (2,'2'), (3,'3');
|
||||
create function f1() returns varchar(50) return 'result';
|
||||
create trigger tr before update on t1 for each row set new.c = (select f1());
|
||||
create table t2 select a, b from t1;
|
||||
update t1 join t2 using (a) set t1.b = t2.b;
|
||||
drop table t1, t2;
|
||||
drop function f1;
|
||||
#
|
||||
# end of 5.5 tests
|
||||
#
|
||||
create table t1 (c1 int, c3 int);
|
||||
insert t1(c3) values (1), (2), (3), (4), (5), (6), (7), (8);
|
||||
create table t2 select * from t1;
|
||||
|
@ -354,7 +354,6 @@ drop table t1, t2;
|
||||
#
|
||||
|
||||
connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
|
||||
connection root;
|
||||
create database mysqltest;
|
||||
create table mysqltest.t1 (a int, b int, primary key (a));
|
||||
create table mysqltest.t2 (a int, b int, primary key (a));
|
||||
@ -363,7 +362,6 @@ create user mysqltest_1@localhost;
|
||||
grant select on mysqltest.* to mysqltest_1@localhost;
|
||||
grant update on mysqltest.t1 to mysqltest_1@localhost;
|
||||
connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
|
||||
connection user1;
|
||||
update t1, t2 set t1.b=1 where t1.a=t2.a;
|
||||
update t1, t2 set t1.b=(select t3.b from t3 where t1.a=t3.a) where t1.a=t2.a;
|
||||
connection root;
|
||||
@ -419,15 +417,12 @@ insert into t2 values (10), (20), (30);
|
||||
create view v1 as select a as b, a/10 as a from t2;
|
||||
|
||||
connect (locker,localhost,root,,test);
|
||||
connection locker;
|
||||
lock table t1 write;
|
||||
|
||||
connect (changer,localhost,root,,test);
|
||||
connection changer;
|
||||
send alter table t1 add column c int default 100 after a;
|
||||
|
||||
connect (updater,localhost,root,,test);
|
||||
connection updater;
|
||||
# Wait till "alter table t1 ..." of session changer is in work.
|
||||
# = There is one session waiting.
|
||||
let $wait_condition= select count(*)= 1 from information_schema.processlist
|
||||
@ -930,7 +925,38 @@ select * from t2;
|
||||
drop table t1,t2, t3;
|
||||
drop user foo;
|
||||
|
||||
--echo end of 5.5 tests
|
||||
#
|
||||
# Another test on not-opening tables unnecessary
|
||||
#
|
||||
create table t1 (a int, b int);
|
||||
create table t2 (c int, d int);
|
||||
insert t1 values (1,2),(3,4);
|
||||
insert t2 values (5,6),(7,8);
|
||||
create table t0 (x int);
|
||||
insert t0 values (11), (22);
|
||||
create trigger tr1 before update on t2 for each row insert t0 values (new.c);
|
||||
connect con1, localhost, root;
|
||||
lock table t0 write;
|
||||
connection default;
|
||||
update t1 join t2 on (a=c+4) set b=d;
|
||||
disconnect con1;
|
||||
drop table t1, t2, t0;
|
||||
|
||||
#
|
||||
# MDEV-19521 Update Table Fails with Trigger and Stored Function
|
||||
#
|
||||
create table t1 (a int, b varchar(50), c varchar(50));
|
||||
insert t1 (a,b) values (1,'1'), (2,'2'), (3,'3');
|
||||
create function f1() returns varchar(50) return 'result';
|
||||
create trigger tr before update on t1 for each row set new.c = (select f1());
|
||||
create table t2 select a, b from t1;
|
||||
update t1 join t2 using (a) set t1.b = t2.b;
|
||||
drop table t1, t2;
|
||||
drop function f1;
|
||||
|
||||
--echo #
|
||||
--echo # end of 5.5 tests
|
||||
--echo #
|
||||
|
||||
#
|
||||
# MDEV-13911 Support ORDER BY and LIMIT in multi-table update
|
||||
|
16
mysql-test/main/multi_update_debug.result
Normal file
16
mysql-test/main/multi_update_debug.result
Normal file
@ -0,0 +1,16 @@
|
||||
create table t1 (a int, b int);
|
||||
create table t2 (c int, d int);
|
||||
insert t1 values (1,2),(3,4);
|
||||
insert t2 values (5,6),(7,8);
|
||||
create table t0 (x int);
|
||||
insert t0 values (11), (22);
|
||||
create trigger tr1 before update on t1 for each row insert t0 values (new.b);
|
||||
set debug_sync='open_tables_after_open_and_process_table WAIT_FOR cont';
|
||||
update t1 join t2 on (a=c+4) set b=d;
|
||||
connect con1, localhost, root;
|
||||
set debug_sync='mdl_acquire_lock_wait SIGNAL cont';
|
||||
lock table t1 write, t0 write;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
drop table t1, t2, t0;
|
||||
set debug_sync='reset';
|
27
mysql-test/main/multi_update_debug.test
Normal file
27
mysql-test/main/multi_update_debug.test
Normal file
@ -0,0 +1,27 @@
|
||||
#
|
||||
# test MDL backoff-and-retry during multi-update
|
||||
#
|
||||
source include/have_debug_sync.inc;
|
||||
create table t1 (a int, b int);
|
||||
create table t2 (c int, d int);
|
||||
insert t1 values (1,2),(3,4);
|
||||
insert t2 values (5,6),(7,8);
|
||||
create table t0 (x int);
|
||||
insert t0 values (11), (22);
|
||||
create trigger tr1 before update on t1 for each row insert t0 values (new.b);
|
||||
|
||||
set debug_sync='open_tables_after_open_and_process_table WAIT_FOR cont';
|
||||
send update t1 join t2 on (a=c+4) set b=d;
|
||||
|
||||
connect con1, localhost, root;
|
||||
let $wait_condition= select count(*) from information_schema.processlist where state = ' debug sync point: open_tables_after_open_and_process_table'
|
||||
source include/wait_condition.inc;
|
||||
set debug_sync='mdl_acquire_lock_wait SIGNAL cont';
|
||||
lock table t1 write, t0 write;
|
||||
let $wait_condition= select count(*) from information_schema.processlist where state = 'Waiting for table metadata lock'
|
||||
source include/wait_condition.inc;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
reap;
|
||||
drop table t1, t2, t0;
|
||||
set debug_sync='reset';
|
@ -67,6 +67,23 @@ SELECT * FROM t2;
|
||||
col_int_key pk_1 pk_2 col_int
|
||||
1 2 3 4
|
||||
DROP TABLE t1,t2;
|
||||
create table t1 (id serial, size int(11)) engine=innodb;
|
||||
create table t2 (id serial, size int, account_id int) engine=innodb;
|
||||
create table t3 (id serial, size int, article_id int) engine=innodb;
|
||||
create table t4 (id serial, file_id int, article_id int) engine=innodb;
|
||||
insert t1 values(null, 400);
|
||||
insert t2 values(null, 0, 1), (null, 1, 1);
|
||||
insert t3 values(null, 100, 1);
|
||||
insert t4 values(null, 1, 2);
|
||||
create trigger file_update_article before update on t3 for each row
|
||||
update t2 set t2.size = new.size where t2.id = new.article_id;
|
||||
create trigger article_update_account before update on t2 for each row
|
||||
update t1 set t1.size = t1.size + new.size where t1.id = new.account_id;
|
||||
update t3 join t4 on t4.file_id =t3.id and t4.article_id=2 set t3.size=t3.size + 2;
|
||||
drop table t1, t2, t3, t4;
|
||||
#
|
||||
# end of 5.5 tests
|
||||
#
|
||||
|
||||
# Bug mdev-5970
|
||||
# Bug#13256831 - ERROR 1032 (HY000): CAN'T FIND RECORD
|
||||
|
@ -76,6 +76,28 @@ SELECT * FROM t2;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# MDEV-19491 update query stopped working after mariadb upgrade 10.2.23 -> 10.2.24
|
||||
#
|
||||
create table t1 (id serial, size int(11)) engine=innodb;
|
||||
create table t2 (id serial, size int, account_id int) engine=innodb;
|
||||
create table t3 (id serial, size int, article_id int) engine=innodb;
|
||||
create table t4 (id serial, file_id int, article_id int) engine=innodb;
|
||||
insert t1 values(null, 400);
|
||||
insert t2 values(null, 0, 1), (null, 1, 1);
|
||||
insert t3 values(null, 100, 1);
|
||||
insert t4 values(null, 1, 2);
|
||||
create trigger file_update_article before update on t3 for each row
|
||||
update t2 set t2.size = new.size where t2.id = new.article_id;
|
||||
create trigger article_update_account before update on t2 for each row
|
||||
update t1 set t1.size = t1.size + new.size where t1.id = new.account_id;
|
||||
update t3 join t4 on t4.file_id =t3.id and t4.article_id=2 set t3.size=t3.size + 2;
|
||||
drop table t1, t2, t3, t4;
|
||||
|
||||
--echo #
|
||||
--echo # end of 5.5 tests
|
||||
--echo #
|
||||
|
||||
--echo
|
||||
--echo # Bug mdev-5970
|
||||
--echo # Bug#13256831 - ERROR 1032 (HY000): CAN'T FIND RECORD
|
||||
|
@ -6973,7 +6973,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 );
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 system NULL NULL NULL NULL 1
|
||||
1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where
|
||||
1 PRIMARY t3 ref d d 5 test.t2.b 2 Using where; Using index
|
||||
1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index
|
||||
3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
set @tmp_mdev410=@@global.userstat;
|
||||
set global userstat=on;
|
||||
|
@ -2484,6 +2484,95 @@ SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1);
|
||||
1
|
||||
drop table t1,t2;
|
||||
drop view v1;
|
||||
#
|
||||
# MDEV-19580: function invocation in the left part of IN subquery
|
||||
#
|
||||
create table t1 (id int, a varchar(50), b int);
|
||||
insert into t1 values
|
||||
(1,'mrs',2), (2,'joe',2), (3,'paul',1), (4,'art',1);
|
||||
create table t2 (id int, a varchar(50), x int);
|
||||
insert into t2 values
|
||||
(1,'grand',1),(2,'average',1),(3,'serf',0);
|
||||
create table t3 (d1 date, d2 date, t1_id int, t2_id int );
|
||||
insert into t3 values
|
||||
('1972-01-01','1988-12-31',3,1), ('1972-01-01','1988-12-31',4,1),
|
||||
('1972-01-01','1988-12-31',1,2), ('1972-01-01','1988-12-31',2,3);
|
||||
create table t4 ( id int, a varchar(50) );
|
||||
insert into t4 values
|
||||
(1,'songwriter'),(2,'song character');
|
||||
create function f1(who int, dt date) returns int
|
||||
deterministic
|
||||
begin
|
||||
declare result int;
|
||||
select t2_id into result from t3 where dt>=d1 and dt<=d2 and t1_id=who;
|
||||
return result;
|
||||
end$$
|
||||
create function f2(who int, dt date) returns int
|
||||
begin
|
||||
declare result int;
|
||||
select t2_id into result from t3 where dt>=d1 and dt<=d2 and t1_id=who;
|
||||
return result;
|
||||
end$$
|
||||
# Deterministic function in left part of IN subquery: semi-join is OK
|
||||
select * from t1
|
||||
left join t4 on t1.b = t4.id
|
||||
where f1(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
id a b id a
|
||||
3 paul 1 1 songwriter
|
||||
4 art 1 1 songwriter
|
||||
1 mrs 2 2 song character
|
||||
explain extended select * from t1
|
||||
left join t4 on t1.b = t4.id
|
||||
where f1(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00 Using where
|
||||
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) left join `test`.`t4` on(`test`.`t4`.`id` = `test`.`t1`.`b`) where `test`.`t2`.`x` = 1 and `f1`(`test`.`t1`.`id`,'1980-01-01') = `test`.`t2`.`id`
|
||||
# Non-deterministic function in left part of IN subq: semi-join is OK
|
||||
select * from t1
|
||||
left join t4 on t1.b = t4.id
|
||||
where f2(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
id a b id a
|
||||
3 paul 1 1 songwriter
|
||||
4 art 1 1 songwriter
|
||||
1 mrs 2 2 song character
|
||||
explain extended select * from t1
|
||||
left join t4 on t1.b = t4.id
|
||||
where f2(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00 Using where
|
||||
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) left join `test`.`t4` on(`test`.`t4`.`id` = `test`.`t1`.`b`) where `test`.`t2`.`x` = 1 and `f2`(`test`.`t1`.`id`,'1980-01-01') = `test`.`t2`.`id`
|
||||
select t1.*, t4.*,
|
||||
(select max(t4.id) from t4 where t4.id=t1.b and sleep(0) = 0) as s
|
||||
from t1 left join t4 on t1.b = t4.id
|
||||
where f2(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
id a b id a s
|
||||
3 paul 1 1 songwriter 1
|
||||
4 art 1 1 songwriter 1
|
||||
1 mrs 2 2 song character 2
|
||||
explain extended select t1.*, t4.*,
|
||||
(select max(t4.id) from t4 where t4.id=t1.b and sleep(0) = 0) as s
|
||||
from t1 left join t4 on t1.b = t4.id
|
||||
where f2(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00
|
||||
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00 Using where
|
||||
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
3 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
Warnings:
|
||||
Note 1276 Field or reference 'test.t1.b' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`a` AS `a`,(/* select#2 */ select max(`test`.`t4`.`id`) from `test`.`t4` where `test`.`t4`.`id` = `test`.`t1`.`b` and sleep(0) = 0) AS `s` from `test`.`t1` semi join (`test`.`t2`) left join `test`.`t4` on(`test`.`t4`.`id` = `test`.`t1`.`b`) where `test`.`t2`.`x` = 1 and `f2`(`test`.`t1`.`id`,'1980-01-01') = `test`.`t2`.`id`
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop table t1,t2,t3,t4;
|
||||
# End of 5.5 tests
|
||||
#
|
||||
# MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT
|
||||
|
@ -6973,7 +6973,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 );
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 system NULL NULL NULL NULL 1
|
||||
1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where
|
||||
1 PRIMARY t3 ref d d 5 test.t2.b 2 Using where; Using index
|
||||
1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index
|
||||
3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
set @tmp_mdev410=@@global.userstat;
|
||||
set global userstat=on;
|
||||
|
@ -6967,7 +6967,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 );
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 system NULL NULL NULL NULL 1
|
||||
1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where
|
||||
1 PRIMARY t3 ref d d 5 test.t2.b 2 Using where; Using index
|
||||
1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index
|
||||
3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
set @tmp_mdev410=@@global.userstat;
|
||||
set global userstat=on;
|
||||
|
@ -6964,7 +6964,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 );
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 system NULL NULL NULL NULL 1
|
||||
1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where
|
||||
1 PRIMARY t3 ref d d 5 test.t2.b 2 Using where; Using index
|
||||
1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index
|
||||
3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
set @tmp_mdev410=@@global.userstat;
|
||||
set global userstat=on;
|
||||
|
@ -6979,7 +6979,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 );
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 system NULL NULL NULL NULL 1
|
||||
1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where
|
||||
1 PRIMARY t3 ref d d 5 test.t2.b 2 Using where; Using index
|
||||
1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index
|
||||
3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
set @tmp_mdev410=@@global.userstat;
|
||||
set global userstat=on;
|
||||
|
@ -6964,7 +6964,7 @@ WHERE SLEEP(0.1) OR c < 'p' OR b = ( SELECT MIN(b) FROM t2 );
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 system NULL NULL NULL NULL 1
|
||||
1 PRIMARY t2 ALL b NULL NULL NULL 2 Using where
|
||||
1 PRIMARY t3 ref d d 5 test.t2.b 2 Using where; Using index
|
||||
1 PRIMARY t3 ref d d 5 test.t2.b 2 Using index
|
||||
3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
set @tmp_mdev410=@@global.userstat;
|
||||
set global userstat=on;
|
||||
|
@ -2524,6 +2524,95 @@ SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1);
|
||||
1
|
||||
drop table t1,t2;
|
||||
drop view v1;
|
||||
#
|
||||
# MDEV-19580: function invocation in the left part of IN subquery
|
||||
#
|
||||
create table t1 (id int, a varchar(50), b int);
|
||||
insert into t1 values
|
||||
(1,'mrs',2), (2,'joe',2), (3,'paul',1), (4,'art',1);
|
||||
create table t2 (id int, a varchar(50), x int);
|
||||
insert into t2 values
|
||||
(1,'grand',1),(2,'average',1),(3,'serf',0);
|
||||
create table t3 (d1 date, d2 date, t1_id int, t2_id int );
|
||||
insert into t3 values
|
||||
('1972-01-01','1988-12-31',3,1), ('1972-01-01','1988-12-31',4,1),
|
||||
('1972-01-01','1988-12-31',1,2), ('1972-01-01','1988-12-31',2,3);
|
||||
create table t4 ( id int, a varchar(50) );
|
||||
insert into t4 values
|
||||
(1,'songwriter'),(2,'song character');
|
||||
create function f1(who int, dt date) returns int
|
||||
deterministic
|
||||
begin
|
||||
declare result int;
|
||||
select t2_id into result from t3 where dt>=d1 and dt<=d2 and t1_id=who;
|
||||
return result;
|
||||
end$$
|
||||
create function f2(who int, dt date) returns int
|
||||
begin
|
||||
declare result int;
|
||||
select t2_id into result from t3 where dt>=d1 and dt<=d2 and t1_id=who;
|
||||
return result;
|
||||
end$$
|
||||
# Deterministic function in left part of IN subquery: semi-join is OK
|
||||
select * from t1
|
||||
left join t4 on t1.b = t4.id
|
||||
where f1(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
id a b id a
|
||||
3 paul 1 1 songwriter
|
||||
4 art 1 1 songwriter
|
||||
1 mrs 2 2 song character
|
||||
explain extended select * from t1
|
||||
left join t4 on t1.b = t4.id
|
||||
where f1(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00 Using where
|
||||
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) left join `test`.`t4` on(`test`.`t4`.`id` = `test`.`t1`.`b`) where `test`.`t2`.`x` = 1 and `f1`(`test`.`t1`.`id`,'1980-01-01') = `test`.`t2`.`id`
|
||||
# Non-deterministic function in left part of IN subq: semi-join is OK
|
||||
select * from t1
|
||||
left join t4 on t1.b = t4.id
|
||||
where f2(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
id a b id a
|
||||
3 paul 1 1 songwriter
|
||||
4 art 1 1 songwriter
|
||||
1 mrs 2 2 song character
|
||||
explain extended select * from t1
|
||||
left join t4 on t1.b = t4.id
|
||||
where f2(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00 Using where
|
||||
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) left join `test`.`t4` on(`test`.`t4`.`id` = `test`.`t1`.`b`) where `test`.`t2`.`x` = 1 and `f2`(`test`.`t1`.`id`,'1980-01-01') = `test`.`t2`.`id`
|
||||
select t1.*, t4.*,
|
||||
(select max(t4.id) from t4 where t4.id=t1.b and sleep(0) = 0) as s
|
||||
from t1 left join t4 on t1.b = t4.id
|
||||
where f2(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
id a b id a s
|
||||
3 paul 1 1 songwriter 1
|
||||
4 art 1 1 songwriter 1
|
||||
1 mrs 2 2 song character 2
|
||||
explain extended select t1.*, t4.*,
|
||||
(select max(t4.id) from t4 where t4.id=t1.b and sleep(0) = 0) as s
|
||||
from t1 left join t4 on t1.b = t4.id
|
||||
where f2(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00
|
||||
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00 Using where
|
||||
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
3 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
Warnings:
|
||||
Note 1276 Field or reference 'test.t1.b' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`a` AS `a`,(/* select#2 */ select max(`test`.`t4`.`id`) from `test`.`t4` where `test`.`t4`.`id` = `test`.`t1`.`b` and sleep(0) = 0) AS `s` from `test`.`t1` semi join (`test`.`t2`) left join `test`.`t4` on(`test`.`t4`.`id` = `test`.`t1`.`b`) where `test`.`t2`.`x` = 1 and `f2`(`test`.`t1`.`id`,'1980-01-01') = `test`.`t2`.`id`
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop table t1,t2,t3,t4;
|
||||
# End of 5.5 tests
|
||||
#
|
||||
# MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT
|
||||
|
@ -2238,6 +2238,81 @@ explain SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1);
|
||||
SELECT 1 FROM t1 where t1.id IN (SELECT v1.i1 from v1);
|
||||
drop table t1,t2;
|
||||
drop view v1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-19580: function invocation in the left part of IN subquery
|
||||
--echo #
|
||||
|
||||
create table t1 (id int, a varchar(50), b int);
|
||||
insert into t1 values
|
||||
(1,'mrs',2), (2,'joe',2), (3,'paul',1), (4,'art',1);
|
||||
|
||||
create table t2 (id int, a varchar(50), x int);
|
||||
insert into t2 values
|
||||
(1,'grand',1),(2,'average',1),(3,'serf',0);
|
||||
|
||||
create table t3 (d1 date, d2 date, t1_id int, t2_id int );
|
||||
insert into t3 values
|
||||
('1972-01-01','1988-12-31',3,1), ('1972-01-01','1988-12-31',4,1),
|
||||
('1972-01-01','1988-12-31',1,2), ('1972-01-01','1988-12-31',2,3);
|
||||
|
||||
create table t4 ( id int, a varchar(50) );
|
||||
insert into t4 values
|
||||
(1,'songwriter'),(2,'song character');
|
||||
|
||||
delimiter $$;
|
||||
|
||||
create function f1(who int, dt date) returns int
|
||||
deterministic
|
||||
begin
|
||||
declare result int;
|
||||
select t2_id into result from t3 where dt>=d1 and dt<=d2 and t1_id=who;
|
||||
return result;
|
||||
end$$
|
||||
|
||||
create function f2(who int, dt date) returns int
|
||||
begin
|
||||
declare result int;
|
||||
select t2_id into result from t3 where dt>=d1 and dt<=d2 and t1_id=who;
|
||||
return result;
|
||||
end$$
|
||||
|
||||
delimiter ;$$
|
||||
|
||||
--echo # Deterministic function in left part of IN subquery: semi-join is OK
|
||||
|
||||
let $q1=
|
||||
select * from t1
|
||||
left join t4 on t1.b = t4.id
|
||||
where f1(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
|
||||
eval $q1;
|
||||
eval explain extended $q1;
|
||||
|
||||
--echo # Non-deterministic function in left part of IN subq: semi-join is OK
|
||||
|
||||
let $q2=
|
||||
select * from t1
|
||||
left join t4 on t1.b = t4.id
|
||||
where f2(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
|
||||
eval $q2;
|
||||
eval explain extended $q2;
|
||||
|
||||
let $q3=
|
||||
select t1.*, t4.*,
|
||||
(select max(t4.id) from t4 where t4.id=t1.b and sleep(0) = 0) as s
|
||||
from t1 left join t4 on t1.b = t4.id
|
||||
where f2(t1.id, '1980-01-01') in (select id from t2 where x=1);
|
||||
|
||||
eval $q3;
|
||||
eval explain extended $q3;
|
||||
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop table t1,t2,t3,t4;
|
||||
|
||||
--echo # End of 5.5 tests
|
||||
--echo #
|
||||
--echo # MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,3 +0,0 @@
|
||||
--innodb-tablespaces-encryption
|
||||
--innodb-encrypt-tables=off
|
||||
--innodb-encryption-threads=0
|
@ -1,231 +0,0 @@
|
||||
-- source include/have_innodb.inc
|
||||
-- source include/have_example_key_management_plugin.inc
|
||||
-- source include/big_test.inc
|
||||
|
||||
# embedded does not support restart
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
--disable_query_log
|
||||
let $innodb_encryption_threads_orig = `SELECT @@global.innodb_encryption_threads`;
|
||||
--enable_query_log
|
||||
|
||||
# empty the change buffer and the undo logs to avoid extra reads
|
||||
SET GLOBAL innodb_fast_shutdown=0;
|
||||
--source include/restart_mysqld.inc
|
||||
|
||||
SHOW VARIABLES LIKE 'innodb_encrypt%';
|
||||
|
||||
#
|
||||
# This will create 100 tables where that could be
|
||||
# encrypted an unencrypt
|
||||
#
|
||||
create database innodb_encrypted_1;
|
||||
use innodb_encrypted_1;
|
||||
show status like 'innodb_pages0_read%';
|
||||
set autocommit=0;
|
||||
let $tables = 100;
|
||||
|
||||
--disable_query_log
|
||||
while ($tables)
|
||||
{
|
||||
eval create table t_$tables (a int not null primary key, b varchar(200)) engine=innodb
|
||||
stats_persistent=0;
|
||||
commit;
|
||||
let $rows = 100;
|
||||
while($rows)
|
||||
{
|
||||
eval insert into t_$tables values ($rows, substring(MD5(RAND()), -64));
|
||||
dec $rows;
|
||||
}
|
||||
commit;
|
||||
dec $tables;
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
set autocommit=1;
|
||||
commit work;
|
||||
show status like 'innodb_pages0_read%';
|
||||
#
|
||||
# Verify
|
||||
#
|
||||
--echo # should be empty
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE NAME LIKE 'innodb_encrypted%';
|
||||
|
||||
#
|
||||
# This will create 100 tables that are encrypted always
|
||||
#
|
||||
create database innodb_encrypted_2;
|
||||
use innodb_encrypted_2;
|
||||
show status like 'innodb_pages0_read%';
|
||||
set autocommit=0;
|
||||
|
||||
--disable_query_log
|
||||
let $tables = 100;
|
||||
while ($tables)
|
||||
{
|
||||
eval create table t_$tables (a int not null primary key, b varchar(200)) engine=innodb
|
||||
stats_persistent=0 encrypted=yes;
|
||||
commit;
|
||||
let $rows = 100;
|
||||
while($rows)
|
||||
{
|
||||
eval insert into t_$tables values ($rows, substring(MD5(RAND()), -64));
|
||||
dec $rows;
|
||||
}
|
||||
commit;
|
||||
dec $tables;
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
commit work;
|
||||
set autocommit=1;
|
||||
show status like 'innodb_pages0_read%';
|
||||
#
|
||||
# Verify
|
||||
#
|
||||
--echo # should contain 100 tables
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
|
||||
--echo # should contain 0 tables
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
|
||||
|
||||
#
|
||||
# This will create 100 tables that are not encrypted
|
||||
#
|
||||
create database innodb_encrypted_3;
|
||||
use innodb_encrypted_3;
|
||||
show status like 'innodb_pages0_read%';
|
||||
set autocommit=0;
|
||||
|
||||
--disable_query_log
|
||||
let $tables = 100;
|
||||
while ($tables)
|
||||
{
|
||||
eval create table t_$tables (a int not null primary key, b varchar(200)) engine=innodb
|
||||
stats_persistent=0 encrypted=no;
|
||||
commit;
|
||||
let $rows = 100;
|
||||
while($rows)
|
||||
{
|
||||
eval insert into t_$tables values ($rows, substring(MD5(RAND()), -64));
|
||||
dec $rows;
|
||||
}
|
||||
commit;
|
||||
dec $tables;
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
commit work;
|
||||
set autocommit=1;
|
||||
show status like 'innodb_pages0_read%';
|
||||
#
|
||||
# Verify
|
||||
#
|
||||
--echo # should contain 100 tables
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
|
||||
--echo # should contain 100 tables
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
|
||||
|
||||
use test;
|
||||
show status like 'innodb_pages0_read%';
|
||||
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
|
||||
|
||||
SET GLOBAL innodb_encrypt_tables = on;
|
||||
SET GLOBAL innodb_encryption_threads=4;
|
||||
|
||||
--let $wait_timeout= 600
|
||||
--let $wait_condition=SELECT COUNT(*) = 100 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
|
||||
--source include/wait_condition.inc
|
||||
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
|
||||
show status like 'innodb_pages0_read%';
|
||||
|
||||
--echo # Success!
|
||||
--echo # Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0
|
||||
-- let $restart_parameters=--innodb_encrypt_tables=0 --innodb_encryption_threads=0
|
||||
-- source include/restart_mysqld.inc
|
||||
|
||||
--echo # Restart Success!
|
||||
|
||||
SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read';
|
||||
use test;
|
||||
SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read';
|
||||
use innodb_encrypted_1;
|
||||
SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read';
|
||||
use innodb_encrypted_2;
|
||||
SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read';
|
||||
use innodb_encrypted_3;
|
||||
SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read';
|
||||
|
||||
use innodb_encrypted_1;
|
||||
|
||||
--disable_result_log
|
||||
--disable_query_log
|
||||
let $tables = 100;
|
||||
while ($tables)
|
||||
{
|
||||
eval select * from t_$tables;
|
||||
dec $tables;
|
||||
}
|
||||
--enable_query_log
|
||||
--enable_result_log
|
||||
|
||||
SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read';
|
||||
|
||||
use innodb_encrypted_2;
|
||||
|
||||
--disable_result_log
|
||||
--disable_query_log
|
||||
let $tables = 100;
|
||||
while ($tables)
|
||||
{
|
||||
eval select * from t_$tables;
|
||||
dec $tables;
|
||||
}
|
||||
--enable_query_log
|
||||
--enable_result_log
|
||||
|
||||
SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read';
|
||||
|
||||
use innodb_encrypted_3;
|
||||
|
||||
--disable_result_log
|
||||
--disable_query_log
|
||||
let $tables = 100;
|
||||
while ($tables)
|
||||
{
|
||||
eval select * from t_$tables;
|
||||
dec $tables;
|
||||
}
|
||||
--enable_query_log
|
||||
--enable_result_log
|
||||
|
||||
SELECT variable_value <= 303 FROM information_schema.global_status WHERE variable_name = 'innodb_pages0_read';
|
||||
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
|
||||
|
||||
SET GLOBAL innodb_encrypt_tables = off;
|
||||
SET GLOBAL innodb_encryption_threads=4;
|
||||
|
||||
--let $wait_timeout= 600
|
||||
--let $wait_condition=SELECT COUNT(*) = 100 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
|
||||
--source include/wait_condition.inc
|
||||
|
||||
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%' ORDER BY NAME;
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
use test;
|
||||
drop database innodb_encrypted_1;
|
||||
drop database innodb_encrypted_2;
|
||||
drop database innodb_encrypted_3;
|
||||
|
||||
--disable_query_log
|
||||
EVAL SET GLOBAL innodb_encryption_threads = $innodb_encryption_threads_orig;
|
||||
--enable_query_log
|
@ -15,6 +15,7 @@ MW-328A : MDEV-17847 Galera test failure on MW-328[A|B|C]
|
||||
MW-328B : MDEV-17847 Galera test failure on MW-328[A|B|C]
|
||||
MW-328C : MDEV-17847 Galera test failure on MW-328[A|B|C]
|
||||
MW-329 : wsrep_local_replays not stable
|
||||
MW-336 : MDEV-19746 Galera test failures because of wsrep_slave_threads identification
|
||||
MW-416 : MDEV-13549 Galera test failures
|
||||
MW-44 : MDEV-15809 Test failure on galera.MW-44
|
||||
galera_account_management : MariaDB 10.0 does not support ALTER USER
|
||||
@ -35,6 +36,7 @@ galera_ssl_upgrade : MDEV-13549 Galera test failures
|
||||
galera_sst_mysqldump_with_key : MDEV-16890 Galera test failure
|
||||
galera_var_node_address : MDEV-17151 Galera test failure
|
||||
galera_var_notify_cmd : MDEV-13549 Galera test failures
|
||||
galera_var_slave_threads : MDEV-19746 Galera test failures because of wsrep_slave_threads identification
|
||||
galera_wan : MDEV-17259: Test failure on galera.galera_wan
|
||||
partition : MDEV-13549 regularly showing auto_increment mismatch
|
||||
pxc-421: Lock timeout exceeded
|
||||
|
@ -47,6 +47,8 @@ tr1 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE
|
||||
DROP TABLE t1;
|
||||
connection node_1;
|
||||
CREATE EVENT event1 ON SCHEDULE AT '2038-01-01 23:59:59' DO SELECT 1;
|
||||
Warnings:
|
||||
Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it.
|
||||
connection node_2;
|
||||
SHOW CREATE EVENT event1;
|
||||
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
|
||||
|
@ -271,319 +271,13 @@ vb=@c,wb=@c,xb=@c,yb=@c,zb=@c,
|
||||
ac=@c,bc=@c,cc=@c,dc=@c,ec=@c,fc=@c,gc=@c,hc=@c,ic=@c,jc=@c,
|
||||
kc=@c,lc=@c,mc=@c,nc=@c,oc=@c,pc=@c,qc=@c,rc=@c,sc=@c,tc=@c,uc=@c,
|
||||
vc=@c,wc=@c,xc=@c,yc=@c,zc=@c;
|
||||
UPDATE t1 SET a=@e,b=@e,c=@e,d=@e,e=@e,f=@e,g=@e,h=@e,i=@e,j=@e,
|
||||
k=@e,l=@e,m=@e,n=@e,o=@e,p=@e,q=@e,r=@e,s=@e,t=@e,u=@e,
|
||||
v=@e,w=@e,x=@e,y=@e,z=@e,
|
||||
aa=@e,ba=@e,ca=@e,da=@e,ea=@e,fa=@e,ga=@e,ha=@e,ia=@e,ja=@e,
|
||||
ka=@e,la=@e,ma=@e,na=@e,oa=@e,pa=@e,qa=@e,ra=@e,sa=@e,ta=@e,ua=@e,
|
||||
va=@e,wa=@e,xa=@e,ya=@e,za=@e,
|
||||
ab=@e,bb=@e,cb=@e,db=@e,eb=@e,fb=@e,gb=@e,hb=@e,ib=@e,jb=@e,
|
||||
kb=@e,lb=@e,mb=@e,nb=@e,ob=@e,pb=@e,qb=@e,rb=@e,sb=@e,tb=@e,ub=@e,
|
||||
vb=@e,wb=@e,xb=@e,yb=@e,zb=@e,
|
||||
ac=@e,bc=@e,cc=@e,dc=@e,ec=@e,fc=@e,gc=@e,hc=@e,ic=@e,jc=@e,
|
||||
kc=@e,lc=@e,mc=@e,nc=@e,oc=@e,pc=@e,qc=@e,rc=@e,sc=@e,tc=@e,uc=@e,
|
||||
vc=@e,wc=@e,xc=@e,yc=@e,zc=@e;
|
||||
UPDATE t2 SET a=@l,b=@l,c=@l,d=@l,e=@l,f=@l,g=@l,h=@l,i=@l,j=@l,
|
||||
k=@l,l=@l,m=@l,n=@l,o=@l,p=@l,q=@l,r=@l,s=@l,t=@l,u=@l,
|
||||
v=@l,w=@l,x=@l,y=@l,z=@l,
|
||||
aa=@l,ba=@l,ca=@l,da=@l,ea=@l,fa=@l,ga=@l,ha=@l,ia=@l,ja=@l,
|
||||
ka=@l,la=@l,ma=@l,na=@l,oa=@l,pa=@l,qa=@l,ra=@l,sa=@l,ta=@l,ua=@l,
|
||||
va=@l,wa=@l,xa=@l,ya=@l,za=@l,
|
||||
ab=@l,bb=@l,cb=@l,db=@l,eb=@l,fb=@l,gb=@l,hb=@l,ib=@l,jb=@l,
|
||||
kb=@l,lb=@l,mb=@l,nb=@l,ob=@l,pb=@l,qb=@l,rb=@l,sb=@l,tb=@l,ub=@l,
|
||||
vb=@l,wb=@l,xb=@l,yb=@l,zb=@l,
|
||||
ac=@l,bc=@l,cc=@l,dc=@l,ec=@l,fc=@l,gc=@l,hc=@l,ic=@l,jc=@l,
|
||||
kc=@l,lc=@l,mc=@l,nc=@l,oc=@l,pc=@l,qc=@l,rc=@l,sc=@l,tc=@l,uc=@l,
|
||||
vc=@l,wc=@l,xc=@l,yc=@l,zc=@l;
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
UPDATE t1 SET a=@f,b=@f,c=@f,d=@f,e=@f;
|
||||
UPDATE t1 SET f=@f,g=@f,h=@f,i=@f,j=@f;
|
||||
UPDATE t1 SET k=@f,l=@f,m=@f,n=@f,o=@f;
|
||||
UPDATE t1 SET p=@f,q=@f,r=@f,s=@f,t=@f,u=@f;
|
||||
UPDATE t1 SET v=@f,w=@f,x=@f,y=@f,z=@f;
|
||||
UPDATE t1 SET aa=@f,ba=@f,ca=@f,da=@f;
|
||||
UPDATE t1 SET ea=@f,fa=@f,ga=@f,ha=@f,ia=@f,ja=@f;
|
||||
UPDATE t1 SET ka=@f,la=@f,ma=@f,na=@f,oa=@f,pa=@f;
|
||||
UPDATE t1 SET qa=@f,ra=@f,sa=@f,ta=@f,ua=@f;
|
||||
UPDATE t1 SET va=@f,wa=@f,xa=@f,ya=@f,za=@f;
|
||||
UPDATE t1 SET ab=@f,bb=@f,cb=@f,db=@f;
|
||||
UPDATE t1 SET eb=@f,fb=@f,gb=@f,hb=@f,ib=@f,ja=@f;
|
||||
UPDATE t1 SET kb=@f,lb=@f,mb=@f,nb=@f,ob=@f,pa=@f;
|
||||
UPDATE t1 SET qb=@f,rb=@f,sb=@f,tb=@f,ub=@f;
|
||||
UPDATE t1 SET vb=@f,wb=@f,xb=@f,yb=@f,zb=@f;
|
||||
UPDATE t1 SET ac=@f,bc=@f,cc=@f,dc=@f;
|
||||
UPDATE t1 SET ec=@f,fc=@f,gc=@f,hc=@f,ic=@f,jc=@f;
|
||||
UPDATE t1 SET kc=@f,lc=@f,mc=@f,nc=@f,oc=@f,pc=@f;
|
||||
UPDATE t1 SET qc=@f,rc=@f,sc=@f,tc=@f,uc=@f;
|
||||
UPDATE t1 SET vc=@f,wc=@f,xc=@f,yc=@f,zc=@f;
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
UPDATE t2 SET a=@f,b=@f,c=@f,d=@f,e=@f;
|
||||
UPDATE t2 SET f=@f,g=@f,h=@f,i=@f,j=@f;
|
||||
UPDATE t2 SET k=@f,l=@f,m=@f,n=@f,o=@f;
|
||||
UPDATE t2 SET p=@f,q=@f,r=@f,s=@f,t=@f,u=@f;
|
||||
UPDATE t2 SET v=@f,w=@f,x=@f,y=@f,z=@f;
|
||||
UPDATE t2 SET aa=@f,ba=@f,ca=@f,da=@f;
|
||||
UPDATE t2 SET ea=@f,fa=@f,ga=@f,ha=@f,ia=@f,ja=@f;
|
||||
UPDATE t2 SET ka=@f,la=@f,ma=@f,na=@f,oa=@f,pa=@f;
|
||||
UPDATE t2 SET qa=@f,ra=@f,sa=@f,ta=@f,ua=@f;
|
||||
UPDATE t2 SET va=@f,wa=@f,xa=@f,ya=@f,za=@f;
|
||||
UPDATE t2 SET ab=@f,bb=@f,cb=@f,db=@f;
|
||||
UPDATE t2 SET eb=@f,fb=@f,gb=@f,hb=@f,ib=@f,ja=@f;
|
||||
UPDATE t2 SET kb=@f,lb=@f,mb=@f,nb=@f,ob=@f,pa=@f;
|
||||
UPDATE t2 SET qb=@f,rb=@f,sb=@f,tb=@f,ub=@f;
|
||||
UPDATE t2 SET vb=@f,wb=@f,xb=@f,yb=@f,zb=@f;
|
||||
UPDATE t2 SET ac=@f,bc=@f,cc=@f,dc=@f;
|
||||
UPDATE t2 SET ec=@f,fc=@f,gc=@f,hc=@f,ic=@f,jc=@f;
|
||||
UPDATE t2 SET kc=@f,lc=@f,mc=@f,nc=@f,oc=@f,pc=@f;
|
||||
UPDATE t2 SET qc=@f,rc=@f,sc=@f,tc=@f,uc=@f;
|
||||
UPDATE t2 SET vc=@f,wc=@f,xc=@f,yc=@f,zc=@f;
|
||||
COMMIT;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` blob DEFAULT NULL,
|
||||
`b` blob DEFAULT NULL,
|
||||
`c` blob DEFAULT NULL,
|
||||
`d` blob DEFAULT NULL,
|
||||
`e` blob DEFAULT NULL,
|
||||
`f` blob DEFAULT NULL,
|
||||
`g` blob DEFAULT NULL,
|
||||
`h` blob DEFAULT NULL,
|
||||
`i` blob DEFAULT NULL,
|
||||
`j` blob DEFAULT NULL,
|
||||
`k` blob DEFAULT NULL,
|
||||
`l` blob DEFAULT NULL,
|
||||
`m` blob DEFAULT NULL,
|
||||
`n` blob DEFAULT NULL,
|
||||
`o` blob DEFAULT NULL,
|
||||
`p` blob DEFAULT NULL,
|
||||
`q` blob DEFAULT NULL,
|
||||
`r` blob DEFAULT NULL,
|
||||
`s` blob DEFAULT NULL,
|
||||
`t` blob DEFAULT NULL,
|
||||
`u` blob DEFAULT NULL,
|
||||
`v` blob DEFAULT NULL,
|
||||
`w` blob DEFAULT NULL,
|
||||
`x` blob DEFAULT NULL,
|
||||
`y` blob DEFAULT NULL,
|
||||
`z` blob DEFAULT NULL,
|
||||
`aa` blob DEFAULT NULL,
|
||||
`ba` blob DEFAULT NULL,
|
||||
`ca` blob DEFAULT NULL,
|
||||
`da` blob DEFAULT NULL,
|
||||
`ea` blob DEFAULT NULL,
|
||||
`fa` blob DEFAULT NULL,
|
||||
`ga` blob DEFAULT NULL,
|
||||
`ha` blob DEFAULT NULL,
|
||||
`ia` blob DEFAULT NULL,
|
||||
`ja` blob DEFAULT NULL,
|
||||
`ka` blob DEFAULT NULL,
|
||||
`la` blob DEFAULT NULL,
|
||||
`ma` blob DEFAULT NULL,
|
||||
`na` blob DEFAULT NULL,
|
||||
`oa` blob DEFAULT NULL,
|
||||
`pa` blob DEFAULT NULL,
|
||||
`qa` blob DEFAULT NULL,
|
||||
`ra` blob DEFAULT NULL,
|
||||
`sa` blob DEFAULT NULL,
|
||||
`ta` blob DEFAULT NULL,
|
||||
`ua` blob DEFAULT NULL,
|
||||
`va` blob DEFAULT NULL,
|
||||
`wa` blob DEFAULT NULL,
|
||||
`xa` blob DEFAULT NULL,
|
||||
`ya` blob DEFAULT NULL,
|
||||
`za` blob DEFAULT NULL,
|
||||
`ab` blob DEFAULT NULL,
|
||||
`bb` blob DEFAULT NULL,
|
||||
`cb` blob DEFAULT NULL,
|
||||
`db` blob DEFAULT NULL,
|
||||
`eb` blob DEFAULT NULL,
|
||||
`fb` blob DEFAULT NULL,
|
||||
`gb` blob DEFAULT NULL,
|
||||
`hb` blob DEFAULT NULL,
|
||||
`ib` blob DEFAULT NULL,
|
||||
`jb` blob DEFAULT NULL,
|
||||
`kb` blob DEFAULT NULL,
|
||||
`lb` blob DEFAULT NULL,
|
||||
`mb` blob DEFAULT NULL,
|
||||
`nb` blob DEFAULT NULL,
|
||||
`ob` blob DEFAULT NULL,
|
||||
`pb` blob DEFAULT NULL,
|
||||
`qb` blob DEFAULT NULL,
|
||||
`rb` blob DEFAULT NULL,
|
||||
`sb` blob DEFAULT NULL,
|
||||
`tb` blob DEFAULT NULL,
|
||||
`ub` blob DEFAULT NULL,
|
||||
`vb` blob DEFAULT NULL,
|
||||
`wb` blob DEFAULT NULL,
|
||||
`xb` blob DEFAULT NULL,
|
||||
`yb` blob DEFAULT NULL,
|
||||
`zb` blob DEFAULT NULL,
|
||||
`ac` blob DEFAULT NULL,
|
||||
`bc` blob DEFAULT NULL,
|
||||
`cc` blob DEFAULT NULL,
|
||||
`dc` blob DEFAULT NULL,
|
||||
`ec` blob DEFAULT NULL,
|
||||
`fc` blob DEFAULT NULL,
|
||||
`gc` blob DEFAULT NULL,
|
||||
`hc` blob DEFAULT NULL,
|
||||
`ic` blob DEFAULT NULL,
|
||||
`jc` blob DEFAULT NULL,
|
||||
`kc` blob DEFAULT NULL,
|
||||
`lc` blob DEFAULT NULL,
|
||||
`mc` blob DEFAULT NULL,
|
||||
`nc` blob DEFAULT NULL,
|
||||
`oc` blob DEFAULT NULL,
|
||||
`pc` blob DEFAULT NULL,
|
||||
`qc` blob DEFAULT NULL,
|
||||
`rc` blob DEFAULT NULL,
|
||||
`sc` blob DEFAULT NULL,
|
||||
`tc` blob DEFAULT NULL,
|
||||
`uc` blob DEFAULT NULL,
|
||||
`vc` blob DEFAULT NULL,
|
||||
`wc` blob DEFAULT NULL,
|
||||
`xc` blob DEFAULT NULL,
|
||||
`yc` blob DEFAULT NULL,
|
||||
`zc` blob DEFAULT NULL,
|
||||
KEY `t1a` (`a`(767),`b`(767)),
|
||||
KEY `t1c` (`c`(767),`d`(767)),
|
||||
KEY `t1e` (`e`(767),`f`(767)),
|
||||
KEY `t1f2` (`g`(767),`h`(767)),
|
||||
KEY `t1f4` (`i`(767),`j`(767)),
|
||||
KEY `t1k` (`k`(767),`m`(767)),
|
||||
KEY `t1f8` (`n`(767),`o`(767)),
|
||||
KEY `t1f11` (`p`(767),`q`(767)),
|
||||
KEY `t1f13` (`r`(767),`s`(767)),
|
||||
KEY `t1f15` (`t`(767),`u`(767)),
|
||||
KEY `t1f18` (`w`(767),`x`(767)),
|
||||
KEY `t1f20` (`y`(767),`z`(767)),
|
||||
KEY `ta1a6` (`aa`(767),`ba`(767)),
|
||||
KEY `tc1c6` (`ca`(767),`da`(767)),
|
||||
KEY `te1e6` (`ea`(767),`fa`(767))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
|
||||
show create table t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`a` blob DEFAULT NULL,
|
||||
`b` blob DEFAULT NULL,
|
||||
`c` blob DEFAULT NULL,
|
||||
`d` blob DEFAULT NULL,
|
||||
`e` blob DEFAULT NULL,
|
||||
`f` blob DEFAULT NULL,
|
||||
`g` blob DEFAULT NULL,
|
||||
`h` blob DEFAULT NULL,
|
||||
`i` blob DEFAULT NULL,
|
||||
`j` blob DEFAULT NULL,
|
||||
`k` blob DEFAULT NULL,
|
||||
`l` blob DEFAULT NULL,
|
||||
`m` blob DEFAULT NULL,
|
||||
`n` blob DEFAULT NULL,
|
||||
`o` blob DEFAULT NULL,
|
||||
`p` blob DEFAULT NULL,
|
||||
`q` blob DEFAULT NULL,
|
||||
`r` blob DEFAULT NULL,
|
||||
`s` blob DEFAULT NULL,
|
||||
`t` blob DEFAULT NULL,
|
||||
`u` blob DEFAULT NULL,
|
||||
`v` blob DEFAULT NULL,
|
||||
`w` blob DEFAULT NULL,
|
||||
`x` blob DEFAULT NULL,
|
||||
`y` blob DEFAULT NULL,
|
||||
`z` blob DEFAULT NULL,
|
||||
`aa` blob DEFAULT NULL,
|
||||
`ba` blob DEFAULT NULL,
|
||||
`ca` blob DEFAULT NULL,
|
||||
`da` blob DEFAULT NULL,
|
||||
`ea` blob DEFAULT NULL,
|
||||
`fa` blob DEFAULT NULL,
|
||||
`ga` blob DEFAULT NULL,
|
||||
`ha` blob DEFAULT NULL,
|
||||
`ia` blob DEFAULT NULL,
|
||||
`ja` blob DEFAULT NULL,
|
||||
`ka` blob DEFAULT NULL,
|
||||
`la` blob DEFAULT NULL,
|
||||
`ma` blob DEFAULT NULL,
|
||||
`na` blob DEFAULT NULL,
|
||||
`oa` blob DEFAULT NULL,
|
||||
`pa` blob DEFAULT NULL,
|
||||
`qa` blob DEFAULT NULL,
|
||||
`ra` blob DEFAULT NULL,
|
||||
`sa` blob DEFAULT NULL,
|
||||
`ta` blob DEFAULT NULL,
|
||||
`ua` blob DEFAULT NULL,
|
||||
`va` blob DEFAULT NULL,
|
||||
`wa` blob DEFAULT NULL,
|
||||
`xa` blob DEFAULT NULL,
|
||||
`ya` blob DEFAULT NULL,
|
||||
`za` blob DEFAULT NULL,
|
||||
`ab` blob DEFAULT NULL,
|
||||
`bb` blob DEFAULT NULL,
|
||||
`cb` blob DEFAULT NULL,
|
||||
`db` blob DEFAULT NULL,
|
||||
`eb` blob DEFAULT NULL,
|
||||
`fb` blob DEFAULT NULL,
|
||||
`gb` blob DEFAULT NULL,
|
||||
`hb` blob DEFAULT NULL,
|
||||
`ib` blob DEFAULT NULL,
|
||||
`jb` blob DEFAULT NULL,
|
||||
`kb` blob DEFAULT NULL,
|
||||
`lb` blob DEFAULT NULL,
|
||||
`mb` blob DEFAULT NULL,
|
||||
`nb` blob DEFAULT NULL,
|
||||
`ob` blob DEFAULT NULL,
|
||||
`pb` blob DEFAULT NULL,
|
||||
`qb` blob DEFAULT NULL,
|
||||
`rb` blob DEFAULT NULL,
|
||||
`sb` blob DEFAULT NULL,
|
||||
`tb` blob DEFAULT NULL,
|
||||
`ub` blob DEFAULT NULL,
|
||||
`vb` blob DEFAULT NULL,
|
||||
`wb` blob DEFAULT NULL,
|
||||
`xb` blob DEFAULT NULL,
|
||||
`yb` blob DEFAULT NULL,
|
||||
`zb` blob DEFAULT NULL,
|
||||
`ac` blob DEFAULT NULL,
|
||||
`bc` blob DEFAULT NULL,
|
||||
`cc` blob DEFAULT NULL,
|
||||
`dc` blob DEFAULT NULL,
|
||||
`ec` blob DEFAULT NULL,
|
||||
`fc` blob DEFAULT NULL,
|
||||
`gc` blob DEFAULT NULL,
|
||||
`hc` blob DEFAULT NULL,
|
||||
`ic` blob DEFAULT NULL,
|
||||
`jc` blob DEFAULT NULL,
|
||||
`kc` blob DEFAULT NULL,
|
||||
`lc` blob DEFAULT NULL,
|
||||
`mc` blob DEFAULT NULL,
|
||||
`nc` blob DEFAULT NULL,
|
||||
`oc` blob DEFAULT NULL,
|
||||
`pc` blob DEFAULT NULL,
|
||||
`qc` blob DEFAULT NULL,
|
||||
`rc` blob DEFAULT NULL,
|
||||
`sc` blob DEFAULT NULL,
|
||||
`tc` blob DEFAULT NULL,
|
||||
`uc` blob DEFAULT NULL,
|
||||
`vc` blob DEFAULT NULL,
|
||||
`wc` blob DEFAULT NULL,
|
||||
`xc` blob DEFAULT NULL,
|
||||
`yc` blob DEFAULT NULL,
|
||||
`zc` blob DEFAULT NULL,
|
||||
KEY `t2a` (`a`(767),`b`(767)),
|
||||
KEY `t2c` (`c`(767),`d`(767)),
|
||||
KEY `t2e` (`e`(767),`f`(767)),
|
||||
KEY `t2f2` (`g`(767),`h`(767)),
|
||||
KEY `t2f4` (`i`(767),`j`(767)),
|
||||
KEY `t2k` (`k`(767),`m`(767)),
|
||||
KEY `t2f8` (`n`(767),`o`(767)),
|
||||
KEY `t2f11` (`p`(767),`q`(767)),
|
||||
KEY `t2f13` (`r`(767),`s`(767)),
|
||||
KEY `t2f15` (`t`(767),`u`(767)),
|
||||
KEY `t2f18` (`w`(767),`x`(767)),
|
||||
KEY `t2f20` (`y`(767),`z`(767)),
|
||||
KEY `ta2a6` (`aa`(767),`ba`(767)),
|
||||
KEY `tc2c6` (`ca`(767),`da`(767)),
|
||||
KEY `te2e6` (`ea`(767),`fa`(767))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
|
||||
connect con1,localhost,root,,;
|
||||
SET GLOBAL innodb_flush_log_at_trx_commit=1;
|
||||
DELETE FROM t2 LIMIT 1;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
check table t1,t2;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
test.t2 check status OK
|
||||
drop table t1,t2;
|
||||
|
@ -300,84 +300,15 @@ UPDATE t1 SET a=@c,b=@c,c=@c,d=@c,e=@c,f=@c,g=@c,h=@c,i=@c,j=@c,
|
||||
kc=@c,lc=@c,mc=@c,nc=@c,oc=@c,pc=@c,qc=@c,rc=@c,sc=@c,tc=@c,uc=@c,
|
||||
vc=@c,wc=@c,xc=@c,yc=@c,zc=@c;
|
||||
|
||||
connect (con1,localhost,root,,);
|
||||
SET GLOBAL innodb_flush_log_at_trx_commit=1;
|
||||
DELETE FROM t2 LIMIT 1;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
|
||||
--let $shutdown_timeout=0
|
||||
--source include/restart_mysqld.inc
|
||||
--let $shutdown_timeout=
|
||||
|
||||
UPDATE t1 SET a=@e,b=@e,c=@e,d=@e,e=@e,f=@e,g=@e,h=@e,i=@e,j=@e,
|
||||
k=@e,l=@e,m=@e,n=@e,o=@e,p=@e,q=@e,r=@e,s=@e,t=@e,u=@e,
|
||||
v=@e,w=@e,x=@e,y=@e,z=@e,
|
||||
aa=@e,ba=@e,ca=@e,da=@e,ea=@e,fa=@e,ga=@e,ha=@e,ia=@e,ja=@e,
|
||||
ka=@e,la=@e,ma=@e,na=@e,oa=@e,pa=@e,qa=@e,ra=@e,sa=@e,ta=@e,ua=@e,
|
||||
va=@e,wa=@e,xa=@e,ya=@e,za=@e,
|
||||
ab=@e,bb=@e,cb=@e,db=@e,eb=@e,fb=@e,gb=@e,hb=@e,ib=@e,jb=@e,
|
||||
kb=@e,lb=@e,mb=@e,nb=@e,ob=@e,pb=@e,qb=@e,rb=@e,sb=@e,tb=@e,ub=@e,
|
||||
vb=@e,wb=@e,xb=@e,yb=@e,zb=@e,
|
||||
ac=@e,bc=@e,cc=@e,dc=@e,ec=@e,fc=@e,gc=@e,hc=@e,ic=@e,jc=@e,
|
||||
kc=@e,lc=@e,mc=@e,nc=@e,oc=@e,pc=@e,qc=@e,rc=@e,sc=@e,tc=@e,uc=@e,
|
||||
vc=@e,wc=@e,xc=@e,yc=@e,zc=@e;
|
||||
|
||||
UPDATE t2 SET a=@l,b=@l,c=@l,d=@l,e=@l,f=@l,g=@l,h=@l,i=@l,j=@l,
|
||||
k=@l,l=@l,m=@l,n=@l,o=@l,p=@l,q=@l,r=@l,s=@l,t=@l,u=@l,
|
||||
v=@l,w=@l,x=@l,y=@l,z=@l,
|
||||
aa=@l,ba=@l,ca=@l,da=@l,ea=@l,fa=@l,ga=@l,ha=@l,ia=@l,ja=@l,
|
||||
ka=@l,la=@l,ma=@l,na=@l,oa=@l,pa=@l,qa=@l,ra=@l,sa=@l,ta=@l,ua=@l,
|
||||
va=@l,wa=@l,xa=@l,ya=@l,za=@l,
|
||||
ab=@l,bb=@l,cb=@l,db=@l,eb=@l,fb=@l,gb=@l,hb=@l,ib=@l,jb=@l,
|
||||
kb=@l,lb=@l,mb=@l,nb=@l,ob=@l,pb=@l,qb=@l,rb=@l,sb=@l,tb=@l,ub=@l,
|
||||
vb=@l,wb=@l,xb=@l,yb=@l,zb=@l,
|
||||
ac=@l,bc=@l,cc=@l,dc=@l,ec=@l,fc=@l,gc=@l,hc=@l,ic=@l,jc=@l,
|
||||
kc=@l,lc=@l,mc=@l,nc=@l,oc=@l,pc=@l,qc=@l,rc=@l,sc=@l,tc=@l,uc=@l,
|
||||
vc=@l,wc=@l,xc=@l,yc=@l,zc=@l;
|
||||
|
||||
COMMIT;
|
||||
|
||||
BEGIN;
|
||||
UPDATE t1 SET a=@f,b=@f,c=@f,d=@f,e=@f;
|
||||
UPDATE t1 SET f=@f,g=@f,h=@f,i=@f,j=@f;
|
||||
UPDATE t1 SET k=@f,l=@f,m=@f,n=@f,o=@f;
|
||||
UPDATE t1 SET p=@f,q=@f,r=@f,s=@f,t=@f,u=@f;
|
||||
UPDATE t1 SET v=@f,w=@f,x=@f,y=@f,z=@f;
|
||||
UPDATE t1 SET aa=@f,ba=@f,ca=@f,da=@f;
|
||||
UPDATE t1 SET ea=@f,fa=@f,ga=@f,ha=@f,ia=@f,ja=@f;
|
||||
UPDATE t1 SET ka=@f,la=@f,ma=@f,na=@f,oa=@f,pa=@f;
|
||||
UPDATE t1 SET qa=@f,ra=@f,sa=@f,ta=@f,ua=@f;
|
||||
UPDATE t1 SET va=@f,wa=@f,xa=@f,ya=@f,za=@f;
|
||||
UPDATE t1 SET ab=@f,bb=@f,cb=@f,db=@f;
|
||||
UPDATE t1 SET eb=@f,fb=@f,gb=@f,hb=@f,ib=@f,ja=@f;
|
||||
UPDATE t1 SET kb=@f,lb=@f,mb=@f,nb=@f,ob=@f,pa=@f;
|
||||
UPDATE t1 SET qb=@f,rb=@f,sb=@f,tb=@f,ub=@f;
|
||||
UPDATE t1 SET vb=@f,wb=@f,xb=@f,yb=@f,zb=@f;
|
||||
UPDATE t1 SET ac=@f,bc=@f,cc=@f,dc=@f;
|
||||
UPDATE t1 SET ec=@f,fc=@f,gc=@f,hc=@f,ic=@f,jc=@f;
|
||||
UPDATE t1 SET kc=@f,lc=@f,mc=@f,nc=@f,oc=@f,pc=@f;
|
||||
UPDATE t1 SET qc=@f,rc=@f,sc=@f,tc=@f,uc=@f;
|
||||
UPDATE t1 SET vc=@f,wc=@f,xc=@f,yc=@f,zc=@f;
|
||||
COMMIT;
|
||||
|
||||
BEGIN;
|
||||
UPDATE t2 SET a=@f,b=@f,c=@f,d=@f,e=@f;
|
||||
UPDATE t2 SET f=@f,g=@f,h=@f,i=@f,j=@f;
|
||||
UPDATE t2 SET k=@f,l=@f,m=@f,n=@f,o=@f;
|
||||
UPDATE t2 SET p=@f,q=@f,r=@f,s=@f,t=@f,u=@f;
|
||||
UPDATE t2 SET v=@f,w=@f,x=@f,y=@f,z=@f;
|
||||
UPDATE t2 SET aa=@f,ba=@f,ca=@f,da=@f;
|
||||
UPDATE t2 SET ea=@f,fa=@f,ga=@f,ha=@f,ia=@f,ja=@f;
|
||||
UPDATE t2 SET ka=@f,la=@f,ma=@f,na=@f,oa=@f,pa=@f;
|
||||
UPDATE t2 SET qa=@f,ra=@f,sa=@f,ta=@f,ua=@f;
|
||||
UPDATE t2 SET va=@f,wa=@f,xa=@f,ya=@f,za=@f;
|
||||
UPDATE t2 SET ab=@f,bb=@f,cb=@f,db=@f;
|
||||
UPDATE t2 SET eb=@f,fb=@f,gb=@f,hb=@f,ib=@f,ja=@f;
|
||||
UPDATE t2 SET kb=@f,lb=@f,mb=@f,nb=@f,ob=@f,pa=@f;
|
||||
UPDATE t2 SET qb=@f,rb=@f,sb=@f,tb=@f,ub=@f;
|
||||
UPDATE t2 SET vb=@f,wb=@f,xb=@f,yb=@f,zb=@f;
|
||||
UPDATE t2 SET ac=@f,bc=@f,cc=@f,dc=@f;
|
||||
UPDATE t2 SET ec=@f,fc=@f,gc=@f,hc=@f,ic=@f,jc=@f;
|
||||
UPDATE t2 SET kc=@f,lc=@f,mc=@f,nc=@f,oc=@f,pc=@f;
|
||||
UPDATE t2 SET qc=@f,rc=@f,sc=@f,tc=@f,uc=@f;
|
||||
UPDATE t2 SET vc=@f,wc=@f,xc=@f,yc=@f,zc=@f;
|
||||
COMMIT;
|
||||
|
||||
show create table t1;
|
||||
show create table t2;
|
||||
check table t1,t2;
|
||||
drop table t1,t2;
|
||||
|
@ -9,6 +9,7 @@ call mtr.add_suppression("\\[ERROR\\] InnoDB: Plugin initialization aborted at s
|
||||
call mtr.add_suppression("\\[ERROR\\] Plugin 'InnoDB' (init function|registration)");
|
||||
call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption");
|
||||
call mtr.add_suppression("\\[ERROR\\] mysqld.*: Index for table 't1' is corrupt; try to repair it");
|
||||
call mtr.add_suppression("InnoDB: Error code: [0-9][0-9][0-9]* btr_pcur_open_low level: 0 called from file: ");
|
||||
--enable_query_log
|
||||
CREATE TABLE t1 (pk INT PRIMARY KEY, c CHAR(255))ENGINE=InnoDB STATS_PERSISTENT=0;
|
||||
|
||||
@ -46,8 +47,6 @@ EOF
|
||||
SELECT * FROM t1 WHERE PK = 1;
|
||||
|
||||
let $restart_parameters=--innodb-force-recovery=1;
|
||||
# Work around MDEV-19435 to avoid crash in row_purge_reset_trx_id()
|
||||
let $restart_parameters=--innodb-force-recovery=2;
|
||||
--source include/restart_mysqld.inc
|
||||
SELECT * FROM t1 WHERE PK = 1;
|
||||
--error ER_NOT_KEYFILE
|
||||
|
@ -14,7 +14,6 @@ rpl_spec_variables : BUG#11755836 2009-10-27 jasonh rpl_spec_variables fa
|
||||
rpl_get_master_version_and_clock : Bug#11766137 Jan 05 2011 joro Valgrind warnings rpl_get_master_version_and_clock
|
||||
rpl_partition_archive : MDEV-5077 2013-09-27 svoj Cannot exchange partition with archive table
|
||||
rpl_row_binlog_max_cache_size : MDEV-11092
|
||||
rpl_blackhole : MDEV-11094
|
||||
rpl_row_index_choice : MDEV-11666
|
||||
rpl_parallel2 : fails after MDEV-16172
|
||||
rpl_semi_sync_after_sync : fails after MDEV-16172
|
||||
|
@ -11,7 +11,7 @@
|
||||
# executing statement. If difference is >0, then something was
|
||||
# written to the binary log on the slave.
|
||||
|
||||
connection slave;
|
||||
# On Connection Slave
|
||||
let $before = query_get_value("SHOW MASTER STATUS", Position, 1);
|
||||
|
||||
connection master;
|
||||
|
97
mysql-test/suite/rpl/include/rpl_blackhole_basic.test
Normal file
97
mysql-test/suite/rpl/include/rpl_blackhole_basic.test
Normal file
@ -0,0 +1,97 @@
|
||||
# PURPOSE. Test that blackhole works with replication in all three
|
||||
# modes: STATEMENT, MIXED, and ROW.
|
||||
#
|
||||
# METHOD. We start by creating a table on the master and then change
|
||||
# the engine to use blackhole on the slave.
|
||||
#
|
||||
# After insert/update/delete of one or more rows, the test the
|
||||
# proceeds to check that replication is running after replicating an
|
||||
# change, that the blackhole engine does not contain anything (which
|
||||
# is just a check that the correct engine is used), and that something
|
||||
# is written to the binary log.
|
||||
#
|
||||
# Whe check INSERT, UPDATE, and DELETE statement for tables with no
|
||||
# key (forcing a range search on the slave), primary keys (using a
|
||||
# primary key lookup), and index/key with multiple matches (forcing an
|
||||
# index search).
|
||||
|
||||
# We start with no primary key
|
||||
CREATE TABLE t1 (a INT, b INT, c INT);
|
||||
CREATE TABLE t2 (a INT, b INT, c INT);
|
||||
|
||||
sync_slave_with_master;
|
||||
ALTER TABLE t1 ENGINE=BLACKHOLE;
|
||||
|
||||
connection master;
|
||||
INSERT INTO t2 VALUES (1,9,1), (2,9,2), (3,9,3), (4,9,4);
|
||||
sync_slave_with_master;
|
||||
|
||||
# Test insert, no primary key
|
||||
let $statement = INSERT INTO t1 VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4);
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test update, no primary key
|
||||
let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 1;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test delete, no primary key
|
||||
let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 1;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test INSERT-SELECT into Blackhole, no primary key
|
||||
let $statement = INSERT INTO t1 SELECT * FROM t2;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
#
|
||||
# The MASTER has MyISAM as the engine for both tables. The SLAVE has Blackhole
|
||||
# on t1 (transactional engine) and MyISAM on t2 (non-transactional engine).
|
||||
#
|
||||
# In MIXED mode, the command "INSERT INTO t2 SELECT * FROM t1" is logged as
|
||||
# statement on the master. On the slave, it is tagged as unsafe because the
|
||||
# statement mixes both transactional and non-transactional engines and as such
|
||||
# its changes are logged as rows. However, due to the nature of the blackhole
|
||||
# engine, no rows are returned and thus any chain replication would make the
|
||||
# next master on the chain diverge.
|
||||
#
|
||||
# Fo this reason, we have disabled the statement.
|
||||
#
|
||||
# Test INSERT-SELECT from Blackhole, no primary key
|
||||
# let $statement = INSERT INTO t2 SELECT * FROM t1;
|
||||
# source include/rpl_blackhole.test;
|
||||
#
|
||||
|
||||
connection master;
|
||||
ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a,b);
|
||||
sync_slave_with_master;
|
||||
|
||||
# Test insert, primary key
|
||||
let $statement = INSERT INTO t1 VALUES (1,2,1),(2,2,2),(3,2,3),(4,2,4);
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test update, primary key
|
||||
let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 2;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test delete, primary key
|
||||
let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 2;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
connection master;
|
||||
ALTER TABLE t1 DROP PRIMARY KEY, ADD KEY key_t1 (a);
|
||||
sync_slave_with_master;
|
||||
|
||||
# Test insert, key
|
||||
let $statement = INSERT INTO t1 VALUES (1,3,1),(2,3,2),(3,3,3),(4,3,4);
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test update, key
|
||||
let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 3;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test delete, key
|
||||
let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 3;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
connection master;
|
||||
DROP TABLE t1,t2;
|
||||
sync_slave_with_master;
|
@ -8,7 +8,6 @@ ALTER TABLE t1 ENGINE=BLACKHOLE;
|
||||
connection master;
|
||||
INSERT INTO t2 VALUES (1,9,1), (2,9,2), (3,9,3), (4,9,4);
|
||||
connection slave;
|
||||
connection slave;
|
||||
connection master;
|
||||
INSERT INTO t1 VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4);
|
||||
connection slave;
|
||||
@ -17,7 +16,6 @@ SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection slave;
|
||||
connection master;
|
||||
UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 1;
|
||||
connection slave;
|
||||
@ -26,7 +24,6 @@ SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection slave;
|
||||
connection master;
|
||||
DELETE FROM t1 WHERE a % 2 = 0 AND b = 1;
|
||||
connection slave;
|
||||
@ -35,7 +32,6 @@ SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection slave;
|
||||
connection master;
|
||||
INSERT INTO t1 SELECT * FROM t2;
|
||||
connection slave;
|
||||
@ -55,7 +51,6 @@ SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection slave;
|
||||
connection master;
|
||||
UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 2;
|
||||
connection slave;
|
||||
@ -64,7 +59,6 @@ SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection slave;
|
||||
connection master;
|
||||
DELETE FROM t1 WHERE a % 2 = 0 AND b = 2;
|
||||
connection slave;
|
||||
@ -84,7 +78,6 @@ SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection slave;
|
||||
connection master;
|
||||
UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 3;
|
||||
connection slave;
|
||||
@ -93,7 +86,6 @@ SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection slave;
|
||||
connection master;
|
||||
DELETE FROM t1 WHERE a % 2 = 0 AND b = 3;
|
||||
connection slave;
|
||||
@ -104,4 +96,5 @@ COUNT(*)
|
||||
>>> Something was written to binary log <<<
|
||||
connection master;
|
||||
DROP TABLE t1,t2;
|
||||
connection slave;
|
||||
include/rpl_end.inc
|
||||
|
457
mysql-test/suite/rpl/r/rpl_blackhole_row_annotate.result
Normal file
457
mysql-test/suite/rpl/r/rpl_blackhole_row_annotate.result
Normal file
@ -0,0 +1,457 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
SET timestamp=1000000000;
|
||||
RESET MASTER;
|
||||
connection slave;
|
||||
SET timestamp=1000000000;
|
||||
RESET MASTER;
|
||||
connection master;
|
||||
CREATE TABLE t1 (a INT, b INT, c INT);
|
||||
CREATE TABLE t2 (a INT, b INT, c INT);
|
||||
connection slave;
|
||||
ALTER TABLE t1 ENGINE=BLACKHOLE;
|
||||
connection master;
|
||||
INSERT INTO t2 VALUES (1,9,1), (2,9,2), (3,9,3), (4,9,4);
|
||||
connection slave;
|
||||
connection master;
|
||||
INSERT INTO t1 VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4);
|
||||
connection slave;
|
||||
# Expect 0
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection master;
|
||||
UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 1;
|
||||
connection slave;
|
||||
# Expect 0
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection master;
|
||||
DELETE FROM t1 WHERE a % 2 = 0 AND b = 1;
|
||||
connection slave;
|
||||
# Expect 0
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection master;
|
||||
INSERT INTO t1 SELECT * FROM t2;
|
||||
connection slave;
|
||||
# Expect 0
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection master;
|
||||
ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a,b);
|
||||
connection slave;
|
||||
connection master;
|
||||
INSERT INTO t1 VALUES (1,2,1),(2,2,2),(3,2,3),(4,2,4);
|
||||
connection slave;
|
||||
# Expect 0
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection master;
|
||||
UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 2;
|
||||
connection slave;
|
||||
# Expect 0
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection master;
|
||||
DELETE FROM t1 WHERE a % 2 = 0 AND b = 2;
|
||||
connection slave;
|
||||
# Expect 0
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection master;
|
||||
ALTER TABLE t1 DROP PRIMARY KEY, ADD KEY key_t1 (a);
|
||||
connection slave;
|
||||
connection master;
|
||||
INSERT INTO t1 VALUES (1,3,1),(2,3,2),(3,3,3),(4,3,4);
|
||||
connection slave;
|
||||
# Expect 0
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection master;
|
||||
UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 3;
|
||||
connection slave;
|
||||
# Expect 0
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection master;
|
||||
DELETE FROM t1 WHERE a % 2 = 0 AND b = 3;
|
||||
connection slave;
|
||||
# Expect 0
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
>>> Something was written to binary log <<<
|
||||
connection master;
|
||||
DROP TABLE t1,t2;
|
||||
connection slave;
|
||||
connection slave;
|
||||
FLUSH LOGS;
|
||||
show binlog events in 'slave-bin.000001' from <start_pos>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
slave-bin.000001 # Gtid_list 2 # []
|
||||
slave-bin.000001 # Binlog_checkpoint 2 # slave-bin.000001
|
||||
slave-bin.000001 # Gtid 1 # GTID 0-1-1
|
||||
slave-bin.000001 # Query 1 # use `test`; CREATE TABLE t1 (a INT, b INT, c INT)
|
||||
slave-bin.000001 # Gtid 1 # GTID 0-1-2
|
||||
slave-bin.000001 # Query 1 # use `test`; CREATE TABLE t2 (a INT, b INT, c INT)
|
||||
slave-bin.000001 # Gtid 2 # GTID 0-2-3
|
||||
slave-bin.000001 # Query 2 # use `test`; ALTER TABLE t1 ENGINE=BLACKHOLE
|
||||
slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-3
|
||||
slave-bin.000001 # Annotate_rows 1 # INSERT INTO t2 VALUES (1,9,1), (2,9,2), (3,9,3), (4,9,4)
|
||||
slave-bin.000001 # Table_map 1 # table_id: # (test.t2)
|
||||
slave-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F
|
||||
slave-bin.000001 # Query 1 # COMMIT
|
||||
slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-4
|
||||
slave-bin.000001 # Annotate_rows 1 # INSERT INTO t1 VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4)
|
||||
slave-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
slave-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F
|
||||
slave-bin.000001 # Query 1 # COMMIT
|
||||
slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-5
|
||||
slave-bin.000001 # Annotate_rows 1 # UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 1
|
||||
slave-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
slave-bin.000001 # Update_rows_v1 1 # table_id: # flags: STMT_END_F
|
||||
slave-bin.000001 # Query 1 # COMMIT
|
||||
slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-6
|
||||
slave-bin.000001 # Annotate_rows 1 # DELETE FROM t1 WHERE a % 2 = 0 AND b = 1
|
||||
slave-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
slave-bin.000001 # Delete_rows_v1 1 # table_id: # flags: STMT_END_F
|
||||
slave-bin.000001 # Query 1 # COMMIT
|
||||
slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-7
|
||||
slave-bin.000001 # Annotate_rows 1 # INSERT INTO t1 SELECT * FROM t2
|
||||
slave-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
slave-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F
|
||||
slave-bin.000001 # Query 1 # COMMIT
|
||||
slave-bin.000001 # Gtid 1 # GTID 0-1-8
|
||||
slave-bin.000001 # Query 1 # use `test`; ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a,b)
|
||||
slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-9
|
||||
slave-bin.000001 # Annotate_rows 1 # INSERT INTO t1 VALUES (1,2,1),(2,2,2),(3,2,3),(4,2,4)
|
||||
slave-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
slave-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F
|
||||
slave-bin.000001 # Query 1 # COMMIT
|
||||
slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-10
|
||||
slave-bin.000001 # Annotate_rows 1 # UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 2
|
||||
slave-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
slave-bin.000001 # Update_rows_v1 1 # table_id: # flags: STMT_END_F
|
||||
slave-bin.000001 # Query 1 # COMMIT
|
||||
slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-11
|
||||
slave-bin.000001 # Annotate_rows 1 # DELETE FROM t1 WHERE a % 2 = 0 AND b = 2
|
||||
slave-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
slave-bin.000001 # Delete_rows_v1 1 # table_id: # flags: STMT_END_F
|
||||
slave-bin.000001 # Query 1 # COMMIT
|
||||
slave-bin.000001 # Gtid 1 # GTID 0-1-12
|
||||
slave-bin.000001 # Query 1 # use `test`; ALTER TABLE t1 DROP PRIMARY KEY, ADD KEY key_t1 (a)
|
||||
slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-13
|
||||
slave-bin.000001 # Annotate_rows 1 # INSERT INTO t1 VALUES (1,3,1),(2,3,2),(3,3,3),(4,3,4)
|
||||
slave-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
slave-bin.000001 # Write_rows_v1 1 # table_id: # flags: STMT_END_F
|
||||
slave-bin.000001 # Query 1 # COMMIT
|
||||
slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-14
|
||||
slave-bin.000001 # Annotate_rows 1 # UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 3
|
||||
slave-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
slave-bin.000001 # Update_rows_v1 1 # table_id: # flags: STMT_END_F
|
||||
slave-bin.000001 # Query 1 # COMMIT
|
||||
slave-bin.000001 # Gtid 1 # BEGIN GTID 0-1-15
|
||||
slave-bin.000001 # Annotate_rows 1 # DELETE FROM t1 WHERE a % 2 = 0 AND b = 3
|
||||
slave-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
slave-bin.000001 # Delete_rows_v1 1 # table_id: # flags: STMT_END_F
|
||||
slave-bin.000001 # Query 1 # COMMIT
|
||||
slave-bin.000001 # Gtid 1 # GTID 0-1-16
|
||||
slave-bin.000001 # Query 1 # use `test`; DROP TABLE IF EXISTS `t1`,`t2` /* generated by server */
|
||||
slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4
|
||||
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
|
||||
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
|
||||
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
|
||||
DELIMITER /*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
|
||||
ROLLBACK/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Gtid list []
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Binlog checkpoint slave-bin.000001
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-1 ddl
|
||||
/*!100101 SET @@session.skip_parallel_replication=0*//*!*/;
|
||||
/*!100001 SET @@session.gtid_domain_id=0*//*!*/;
|
||||
/*!100001 SET @@session.server_id=1*//*!*/;
|
||||
/*!100001 SET @@session.gtid_seq_no=1*//*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
use `test`/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.pseudo_thread_id=#/*!*/;
|
||||
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1/*!*/;
|
||||
SET @@session.sql_mode=1411383296/*!*/;
|
||||
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
|
||||
/*!\C latin1 *//*!*/;
|
||||
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
|
||||
SET @@session.lc_time_names=0/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
CREATE TABLE t1 (a INT, b INT, c INT)
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-2 ddl
|
||||
/*!100001 SET @@session.gtid_seq_no=2*//*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
CREATE TABLE t2 (a INT, b INT, c INT)
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-2-3 ddl
|
||||
/*!100001 SET @@session.server_id=2*//*!*/;
|
||||
/*!100001 SET @@session.gtid_seq_no=3*//*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
ALTER TABLE t1 ENGINE=BLACKHOLE
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-3 trans
|
||||
/*!100001 SET @@session.server_id=1*//*!*/;
|
||||
/*!100001 SET @@session.gtid_seq_no=3*//*!*/;
|
||||
BEGIN
|
||||
/*!*/;
|
||||
# at #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Annotate_rows:
|
||||
#Q> INSERT INTO t2 VALUES (1,9,1), (2,9,2), (3,9,3), (4,9,4)
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Table_map: `test`.`t2` mapped to number #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F
|
||||
# Number of rows: 4
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-4 trans
|
||||
/*!100001 SET @@session.gtid_seq_no=4*//*!*/;
|
||||
BEGIN
|
||||
/*!*/;
|
||||
# at #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Annotate_rows:
|
||||
#Q> INSERT INTO t1 VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4)
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F
|
||||
# Number of rows: 4
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-5 trans
|
||||
/*!100001 SET @@session.gtid_seq_no=5*//*!*/;
|
||||
BEGIN
|
||||
/*!*/;
|
||||
# at #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Annotate_rows:
|
||||
#Q> UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 1
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Update_rows: table id # flags: STMT_END_F
|
||||
# Number of rows: 2
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-6 trans
|
||||
/*!100001 SET @@session.gtid_seq_no=6*//*!*/;
|
||||
BEGIN
|
||||
/*!*/;
|
||||
# at #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Annotate_rows:
|
||||
#Q> DELETE FROM t1 WHERE a % 2 = 0 AND b = 1
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F
|
||||
# Number of rows: 2
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-7 trans
|
||||
/*!100001 SET @@session.gtid_seq_no=7*//*!*/;
|
||||
BEGIN
|
||||
/*!*/;
|
||||
# at #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Annotate_rows:
|
||||
#Q> INSERT INTO t1 SELECT * FROM t2
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F
|
||||
# Number of rows: 4
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-8 ddl
|
||||
/*!100001 SET @@session.gtid_seq_no=8*//*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a,b)
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-9 trans
|
||||
/*!100001 SET @@session.gtid_seq_no=9*//*!*/;
|
||||
BEGIN
|
||||
/*!*/;
|
||||
# at #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Annotate_rows:
|
||||
#Q> INSERT INTO t1 VALUES (1,2,1),(2,2,2),(3,2,3),(4,2,4)
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F
|
||||
# Number of rows: 4
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-10 trans
|
||||
/*!100001 SET @@session.gtid_seq_no=10*//*!*/;
|
||||
BEGIN
|
||||
/*!*/;
|
||||
# at #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Annotate_rows:
|
||||
#Q> UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 2
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Update_rows: table id # flags: STMT_END_F
|
||||
# Number of rows: 2
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-11 trans
|
||||
/*!100001 SET @@session.gtid_seq_no=11*//*!*/;
|
||||
BEGIN
|
||||
/*!*/;
|
||||
# at #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Annotate_rows:
|
||||
#Q> DELETE FROM t1 WHERE a % 2 = 0 AND b = 2
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F
|
||||
# Number of rows: 2
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-12 ddl
|
||||
/*!100001 SET @@session.gtid_seq_no=12*//*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
ALTER TABLE t1 DROP PRIMARY KEY, ADD KEY key_t1 (a)
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-13 trans
|
||||
/*!100001 SET @@session.gtid_seq_no=13*//*!*/;
|
||||
BEGIN
|
||||
/*!*/;
|
||||
# at #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Annotate_rows:
|
||||
#Q> INSERT INTO t1 VALUES (1,3,1),(2,3,2),(3,3,3),(4,3,4)
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F
|
||||
# Number of rows: 4
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-14 trans
|
||||
/*!100001 SET @@session.gtid_seq_no=14*//*!*/;
|
||||
BEGIN
|
||||
/*!*/;
|
||||
# at #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Annotate_rows:
|
||||
#Q> UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 3
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Update_rows: table id # flags: STMT_END_F
|
||||
# Number of rows: 2
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-15 trans
|
||||
/*!100001 SET @@session.gtid_seq_no=15*//*!*/;
|
||||
BEGIN
|
||||
/*!*/;
|
||||
# at #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Annotate_rows:
|
||||
#Q> DELETE FROM t1 WHERE a % 2 = 0 AND b = 3
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Delete_rows: table id # flags: STMT_END_F
|
||||
# Number of rows: 2
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
COMMIT
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-16 ddl
|
||||
/*!100001 SET @@session.gtid_seq_no=16*//*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
DROP TABLE IF EXISTS `t1`,`t2` /* generated by server */
|
||||
/*!*/;
|
||||
# at #
|
||||
#010909 4:46:40 server id # end_log_pos # CRC32 XXX Rotate to slave-bin.000002 pos: 4
|
||||
DELIMITER ;
|
||||
# End of log file
|
||||
ROLLBACK /* added by mysqlbinlog */;
|
||||
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
|
||||
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
|
||||
include/rpl_end.inc
|
@ -20,81 +20,6 @@ source include/master-slave.inc;
|
||||
|
||||
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
|
||||
|
||||
# We start with no primary key
|
||||
CREATE TABLE t1 (a INT, b INT, c INT);
|
||||
CREATE TABLE t2 (a INT, b INT, c INT);
|
||||
source include/rpl_blackhole_basic.test;
|
||||
|
||||
sync_slave_with_master;
|
||||
ALTER TABLE t1 ENGINE=BLACKHOLE;
|
||||
|
||||
connection master;
|
||||
INSERT INTO t2 VALUES (1,9,1), (2,9,2), (3,9,3), (4,9,4);
|
||||
sync_slave_with_master;
|
||||
|
||||
# Test insert, no primary key
|
||||
let $statement = INSERT INTO t1 VALUES (1,1,1),(2,1,2),(3,1,3),(4,1,4);
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test update, no primary key
|
||||
let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 1;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test delete, no primary key
|
||||
let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 1;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test INSERT-SELECT into Blackhole, no primary key
|
||||
let $statement = INSERT INTO t1 SELECT * FROM t2;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
#
|
||||
# The MASTER has MyISAM as the engine for both tables. The SLAVE has Blackhole
|
||||
# on t1 (transactional engine) and MyISAM on t2 (non-transactional engine).
|
||||
#
|
||||
# In MIXED mode, the command "INSERT INTO t2 SELECT * FROM t1" is logged as
|
||||
# statement on the master. On the slave, it is tagged as unsafe because the
|
||||
# statement mixes both transactional and non-transactional engines and as such
|
||||
# its changes are logged as rows. However, due to the nature of the blackhole
|
||||
# engine, no rows are returned and thus any chain replication would make the
|
||||
# next master on the chain diverge.
|
||||
#
|
||||
# Fo this reason, we have disabled the statement.
|
||||
#
|
||||
# Test INSERT-SELECT from Blackhole, no primary key
|
||||
# let $statement = INSERT INTO t2 SELECT * FROM t1;
|
||||
# source include/rpl_blackhole.test;
|
||||
#
|
||||
|
||||
connection master;
|
||||
ALTER TABLE t1 ADD PRIMARY KEY pk_t1 (a,b);
|
||||
|
||||
# Test insert, primary key
|
||||
let $statement = INSERT INTO t1 VALUES (1,2,1),(2,2,2),(3,2,3),(4,2,4);
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test update, primary key
|
||||
let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 2;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test delete, primary key
|
||||
let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 2;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
connection master;
|
||||
ALTER TABLE t1 DROP PRIMARY KEY, ADD KEY key_t1 (a);
|
||||
|
||||
# Test insert, key
|
||||
let $statement = INSERT INTO t1 VALUES (1,3,1),(2,3,2),(3,3,3),(4,3,4);
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test update, key
|
||||
let $statement = UPDATE t1 SET c = 2*c WHERE a % 2 = 0 AND b = 3;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
# Test delete, key
|
||||
let $statement = DELETE FROM t1 WHERE a % 2 = 0 AND b = 3;
|
||||
source include/rpl_blackhole.test;
|
||||
|
||||
connection master;
|
||||
DROP TABLE t1,t2;
|
||||
--source include/rpl_end.inc
|
||||
|
@ -0,0 +1 @@
|
||||
--binlog_annotate_row_events --timezone=GMT-3
|
@ -0,0 +1 @@
|
||||
--binlog_annotate_row_events --replicate_annotate_row_events
|
49
mysql-test/suite/rpl/t/rpl_blackhole_row_annotate.test
Normal file
49
mysql-test/suite/rpl/t/rpl_blackhole_row_annotate.test
Normal file
@ -0,0 +1,49 @@
|
||||
# ==== Purpose ====
|
||||
#
|
||||
# Test verifies that when "replicate_annotate_row_events" are enabled on slave
|
||||
# the DML operations on blackhole engine will be successful. It also ensures
|
||||
# that Annotate events are logged into slave's binary log.
|
||||
#
|
||||
# ==== Implementation ====
|
||||
#
|
||||
# Steps:
|
||||
# 0 - Enable "replicate_annotate_row_events" on slave and do DML operations
|
||||
# on master.
|
||||
# 1 - Slave server will successfully apply the DML operations and it is in
|
||||
# sync with master.
|
||||
# 2 - Verify that the "show binlog events" prints all annotate events.
|
||||
# 3 - Stream the slave's binary log using "mysqlbinlog" tool and verify
|
||||
# that the Annotate events are being displayed.
|
||||
#
|
||||
# ==== References ====
|
||||
#
|
||||
# MDEV-11094: Blackhole table updates on slave fail when row annotation is
|
||||
# enabled
|
||||
|
||||
source include/have_blackhole.inc;
|
||||
source include/have_binlog_format_row.inc;
|
||||
source include/binlog_start_pos.inc;
|
||||
source include/master-slave.inc;
|
||||
|
||||
SET timestamp=1000000000;
|
||||
RESET MASTER;
|
||||
connection slave;
|
||||
SET timestamp=1000000000;
|
||||
RESET MASTER;
|
||||
|
||||
connection master;
|
||||
source include/rpl_blackhole_basic.test;
|
||||
|
||||
# Verify on slave.
|
||||
connection slave;
|
||||
FLUSH LOGS;
|
||||
--replace_column 2 # 5 #
|
||||
--replace_result $binlog_start_pos <start_pos>
|
||||
--replace_regex /table_id: [0-9]+/table_id: #/ /\/\* xid=.* \*\//\/* xid= *\//
|
||||
--eval show binlog events in 'slave-bin.000001' from $binlog_start_pos
|
||||
|
||||
let $MYSQLD_DATADIR= `select @@datadir`;
|
||||
--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /CRC32 0x[0-9a-f]*/CRC32 XXX/
|
||||
--exec $MYSQL_BINLOG --base64-output=decode-rows $MYSQLD_DATADIR/slave-bin.000001
|
||||
|
||||
source include/rpl_end.inc;
|
@ -1,2 +1,14 @@
|
||||
wsrep.foreign_key : Sporadic failure "WSREP has not yet prepared node for application use"
|
||||
##############################################################################
|
||||
#
|
||||
# List the test cases that are to be disabled temporarily.
|
||||
#
|
||||
# Separate the test case name and the comment with ':'.
|
||||
#
|
||||
# <testcasename> : MDEV-<xxxx> <comment>
|
||||
#
|
||||
# Do not use any TAB characters for whitespace.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
foreign_key : Sporadic failure "WSREP has not yet prepared node for application use"
|
||||
variables : MDEV-19746 Galera test failures because of wsrep_slave_threads identification
|
||||
|
@ -112,7 +112,6 @@ encryption.innodb_encryption_discard_import : MDEV-16116
|
||||
encryption.innodb_encryption_filekeys : MDEV-15673 - Timeout
|
||||
encryption.innodb_encryption_row_compressed : MDEV-16113 - Crash
|
||||
encryption.innodb_first_page : MDEV-10689 - Crash
|
||||
encryption.innodb_lotoftables : MDEV-16111 - Wrong result
|
||||
encryption.innodb_onlinealter_encryption : MDEV-17287 - SIGABRT on server restart
|
||||
encryption.innodb_scrub : MDEV-8139 - scrubbing tests need fixing
|
||||
encryption.innodb_scrub_background : MDEV-8139 - scrubbing tests need fixing
|
||||
|
@ -5,7 +5,6 @@
|
||||
wsrep-on=1
|
||||
binlog-format=row
|
||||
innodb-autoinc-lock-mode=2
|
||||
innodb-locks-unsafe-for-binlog=1
|
||||
wsrep-cluster-address=gcomm://
|
||||
wsrep_provider=@ENV.WSREP_PROVIDER
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
|
||||
Copyright (c) 2009, 2018, MariaDB Corporation.
|
||||
Copyright (c) 2009, 2019, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -213,6 +213,32 @@ redo:
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Storage_engine_name::resolve_storage_engine_with_error(THD *thd,
|
||||
handlerton **ha,
|
||||
bool tmp_table)
|
||||
{
|
||||
if (plugin_ref plugin= ha_resolve_by_name(thd, &m_storage_engine_name,
|
||||
tmp_table))
|
||||
{
|
||||
*ha= plugin_hton(plugin);
|
||||
return false;
|
||||
}
|
||||
|
||||
*ha= NULL;
|
||||
if (thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION)
|
||||
{
|
||||
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), m_storage_engine_name.str);
|
||||
return true;
|
||||
}
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_UNKNOWN_STORAGE_ENGINE,
|
||||
ER_THD(thd, ER_UNKNOWN_STORAGE_ENGINE),
|
||||
m_storage_engine_name.str);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
plugin_ref ha_lock_engine(THD *thd, const handlerton *hton)
|
||||
{
|
||||
if (hton)
|
||||
|
@ -129,6 +129,13 @@ void Json_writer::add_ll(longlong val)
|
||||
add_unquoted_str(buf);
|
||||
}
|
||||
|
||||
void Json_writer::add_ull(ulonglong val)
|
||||
{
|
||||
char buf[64];
|
||||
my_snprintf(buf, sizeof(buf), "%llu", val);
|
||||
add_unquoted_str(buf);
|
||||
}
|
||||
|
||||
|
||||
/* Add a memory size, printing in Kb, Kb, Gb if necessary */
|
||||
void Json_writer::add_size(longlong val)
|
||||
|
@ -108,6 +108,7 @@ public:
|
||||
void add_str(const String &str);
|
||||
|
||||
void add_ll(longlong val);
|
||||
void add_ull(ulonglong val);
|
||||
void add_size(longlong val);
|
||||
void add_double(double val);
|
||||
void add_bool(bool val);
|
||||
|
@ -1233,7 +1233,7 @@ bool Master_info_index::init_all_master_info()
|
||||
if (!err_num) // No Error on read Master_info
|
||||
{
|
||||
if (global_system_variables.log_warnings > 1)
|
||||
sql_print_information("Reading of all Master_info entries succeded");
|
||||
sql_print_information("Reading of all Master_info entries succeeded");
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (succ_num) // Have some Error and some Success
|
||||
|
@ -359,6 +359,18 @@ bool Sql_cmd_alter_table::execute(THD *thd)
|
||||
SELECT_LEX *select_lex= &lex->select_lex;
|
||||
/* first table of first SELECT_LEX */
|
||||
TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first;
|
||||
|
||||
const bool used_engine= lex->create_info.used_fields & HA_CREATE_USED_ENGINE;
|
||||
DBUG_ASSERT((m_storage_engine_name.str != NULL) == used_engine);
|
||||
if (used_engine)
|
||||
{
|
||||
if (resolve_storage_engine_with_error(thd, &lex->create_info.db_type,
|
||||
lex->create_info.tmp_table()))
|
||||
return true; // Engine not found, substitution is not allowed
|
||||
if (!lex->create_info.db_type) // Not found, but substitution is allowed
|
||||
lex->create_info.used_fields&= ~HA_CREATE_USED_ENGINE;
|
||||
}
|
||||
|
||||
/*
|
||||
Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
|
||||
so we have to use a copy of this structure to make execution
|
||||
|
@ -355,7 +355,8 @@ protected:
|
||||
Sql_cmd_alter_table represents the generic ALTER TABLE statement.
|
||||
@todo move Alter_info and other ALTER specific structures from Lex here.
|
||||
*/
|
||||
class Sql_cmd_alter_table : public Sql_cmd_common_alter_table
|
||||
class Sql_cmd_alter_table : public Sql_cmd_common_alter_table,
|
||||
public Storage_engine_name
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@ -367,6 +368,8 @@ public:
|
||||
~Sql_cmd_alter_table()
|
||||
{}
|
||||
|
||||
Storage_engine_name *option_storage_engine_name() { return this; }
|
||||
|
||||
bool execute(THD *thd);
|
||||
};
|
||||
|
||||
|
@ -4045,8 +4045,7 @@ open_tables_check_upgradable_mdl(THD *thd, TABLE_LIST *tables_start,
|
||||
*/
|
||||
|
||||
bool open_tables(THD *thd, const DDL_options_st &options,
|
||||
TABLE_LIST **start, uint *counter,
|
||||
Sroutine_hash_entry **sroutine_to_open_list, uint flags,
|
||||
TABLE_LIST **start, uint *counter, uint flags,
|
||||
Prelocking_strategy *prelocking_strategy)
|
||||
{
|
||||
/*
|
||||
@ -4089,9 +4088,10 @@ restart:
|
||||
|
||||
has_prelocking_list= thd->lex->requires_prelocking();
|
||||
table_to_open= start;
|
||||
sroutine_to_open= sroutine_to_open_list;
|
||||
sroutine_to_open= &thd->lex->sroutines_list.first;
|
||||
*counter= 0;
|
||||
THD_STAGE_INFO(thd, stage_opening_tables);
|
||||
prelocking_strategy->reset(thd);
|
||||
|
||||
/*
|
||||
If we are executing LOCK TABLES statement or a DDL statement
|
||||
@ -4149,8 +4149,7 @@ restart:
|
||||
elements in prelocking list/set.
|
||||
*/
|
||||
while (*table_to_open ||
|
||||
(thd->locked_tables_mode <= LTM_LOCK_TABLES &&
|
||||
*sroutine_to_open))
|
||||
(thd->locked_tables_mode <= LTM_LOCK_TABLES && *sroutine_to_open))
|
||||
{
|
||||
/*
|
||||
For every table in the list of tables to open, try to find or open
|
||||
@ -4270,6 +4269,8 @@ restart:
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((error= prelocking_strategy->handle_end(thd)))
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -241,17 +241,7 @@ lock_table_names(THD *thd, TABLE_LIST *table_list,
|
||||
}
|
||||
bool open_tables(THD *thd, const DDL_options_st &options,
|
||||
TABLE_LIST **tables, uint *counter,
|
||||
Sroutine_hash_entry **sroutine_to_open, uint flags,
|
||||
Prelocking_strategy *prelocking_strategy);
|
||||
|
||||
static inline bool
|
||||
open_tables(THD *thd, const DDL_options_st &options, TABLE_LIST **tables,
|
||||
uint *counter, uint flags, Prelocking_strategy *prelocking_strategy)
|
||||
{
|
||||
return open_tables(thd, options, tables, counter,
|
||||
&thd->lex->sroutines_list.first, flags,
|
||||
prelocking_strategy);
|
||||
}
|
||||
uint flags, Prelocking_strategy *prelocking_strategy);
|
||||
|
||||
static inline bool
|
||||
open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags,
|
||||
@ -400,6 +390,7 @@ class Prelocking_strategy
|
||||
public:
|
||||
virtual ~Prelocking_strategy() { }
|
||||
|
||||
virtual void reset(THD *thd) { };
|
||||
virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
|
||||
Sroutine_hash_entry *rt, sp_head *sp,
|
||||
bool *need_prelocking) = 0;
|
||||
@ -407,6 +398,7 @@ public:
|
||||
TABLE_LIST *table_list, bool *need_prelocking) = 0;
|
||||
virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
|
||||
TABLE_LIST *table_list, bool *need_prelocking)= 0;
|
||||
virtual bool handle_end(THD *thd) { return 0; };
|
||||
};
|
||||
|
||||
|
||||
|
@ -117,6 +117,32 @@ enum enum_sql_command {
|
||||
SQLCOM_END
|
||||
};
|
||||
|
||||
|
||||
class Storage_engine_name
|
||||
{
|
||||
protected:
|
||||
LEX_CSTRING m_storage_engine_name;
|
||||
public:
|
||||
Storage_engine_name()
|
||||
{
|
||||
m_storage_engine_name.str= NULL;
|
||||
m_storage_engine_name.length= 0;
|
||||
}
|
||||
Storage_engine_name(const LEX_CSTRING &name)
|
||||
:m_storage_engine_name(name)
|
||||
{ }
|
||||
Storage_engine_name(const LEX_STRING &name)
|
||||
{
|
||||
m_storage_engine_name.str= name.str;
|
||||
m_storage_engine_name.length= name.length;
|
||||
}
|
||||
bool resolve_storage_engine_with_error(THD *thd,
|
||||
handlerton **ha,
|
||||
bool tmp_table);
|
||||
bool is_set() { return m_storage_engine_name.str != NULL; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@class Sql_cmd - Representation of an SQL command.
|
||||
|
||||
@ -160,6 +186,11 @@ public:
|
||||
*/
|
||||
virtual bool execute(THD *thd) = 0;
|
||||
|
||||
virtual Storage_engine_name *option_storage_engine_name()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
Sql_cmd()
|
||||
{}
|
||||
@ -176,6 +207,26 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class Sql_cmd_create_table_like: public Sql_cmd,
|
||||
public Storage_engine_name
|
||||
{
|
||||
public:
|
||||
Storage_engine_name *option_storage_engine_name() { return this; }
|
||||
bool execute(THD *thd);
|
||||
};
|
||||
|
||||
class Sql_cmd_create_table: public Sql_cmd_create_table_like
|
||||
{
|
||||
public:
|
||||
enum_sql_command sql_command_code() const { return SQLCOM_CREATE_TABLE; }
|
||||
};
|
||||
|
||||
class Sql_cmd_create_sequence: public Sql_cmd_create_table_like
|
||||
{
|
||||
public:
|
||||
enum_sql_command sql_command_code() const { return SQLCOM_CREATE_SEQUENCE; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Sql_cmd_call represents the CALL statement.
|
||||
|
@ -1282,7 +1282,7 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai
|
||||
if (rows_set)
|
||||
{
|
||||
item_list.push_back(new (mem_root)
|
||||
Item_int(thd, (longlong) (ulonglong) rows,
|
||||
Item_int(thd, (ulonglong) rows,
|
||||
MY_INT64_NUM_DECIMAL_DIGITS),
|
||||
mem_root);
|
||||
}
|
||||
@ -1657,7 +1657,7 @@ void Explain_table_access::print_explain_json(Explain_query *query,
|
||||
|
||||
/* `rows` */
|
||||
if (rows_set)
|
||||
writer->add_member("rows").add_ll(rows);
|
||||
writer->add_member("rows").add_ull(rows);
|
||||
|
||||
/* `r_rows` */
|
||||
if (is_analyze)
|
||||
@ -2295,7 +2295,7 @@ void Explain_update::print_explain_json(Explain_query *query,
|
||||
}
|
||||
|
||||
/* `rows` */
|
||||
writer->add_member("rows").add_ll(rows);
|
||||
writer->add_member("rows").add_ull(rows);
|
||||
|
||||
|
||||
if (mrr_type.length() != 0)
|
||||
@ -2324,7 +2324,7 @@ void Explain_update::print_explain_json(Explain_query *query,
|
||||
r_rows= 0;
|
||||
r_filtered= buf_tracker.get_filtered_after_where() * 100.0;
|
||||
}
|
||||
writer->add_member("r_rows").add_ll(r_rows);
|
||||
writer->add_member("r_rows").add_ull(r_rows);
|
||||
writer->add_member("r_filtered").add_double(r_filtered);
|
||||
}
|
||||
else /* Not doing buffering */
|
||||
|
@ -2147,7 +2147,8 @@ enum_nested_loop_state JOIN_CACHE::join_records(bool skip_last)
|
||||
}
|
||||
|
||||
finish:
|
||||
if (outer_join_first_inner)
|
||||
if (outer_join_first_inner &&
|
||||
join_tab->first_inner == join_tab->first_unmatched)
|
||||
{
|
||||
/*
|
||||
All null complemented rows have been already generated for all
|
||||
|
@ -4745,7 +4745,10 @@ void SELECT_LEX::increase_derived_records(ha_rows records)
|
||||
break;
|
||||
default:
|
||||
// usual UNION
|
||||
result->est_records+= records;
|
||||
if (HA_ROWS_MAX - records > result->est_records)
|
||||
result->est_records+= records;
|
||||
else
|
||||
result->est_records= HA_ROWS_MAX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
285
sql/sql_parse.cc
285
sql/sql_parse.cc
@ -4064,289 +4064,6 @@ mysql_execute_command(THD *thd)
|
||||
res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_MUTEX);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_CREATE_SEQUENCE:
|
||||
case SQLCOM_CREATE_TABLE:
|
||||
{
|
||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||
bool link_to_local;
|
||||
TABLE_LIST *create_table= first_table;
|
||||
TABLE_LIST *select_tables= lex->create_last_non_select_table->next_global;
|
||||
|
||||
if (lex->tmp_table())
|
||||
{
|
||||
status_var_decrement(thd->status_var.com_stat[SQLCOM_CREATE_TABLE]);
|
||||
status_var_increment(thd->status_var.com_create_tmp_table);
|
||||
}
|
||||
|
||||
/*
|
||||
Code below (especially in mysql_create_table() and select_create
|
||||
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
|
||||
use a copy of this structure to make execution prepared statement-
|
||||
safe. A shallow copy is enough as this code won't modify any memory
|
||||
referenced from this structure.
|
||||
*/
|
||||
Table_specification_st create_info(lex->create_info);
|
||||
/*
|
||||
We need to copy alter_info for the same reasons of re-execution
|
||||
safety, only in case of Alter_info we have to do (almost) a deep
|
||||
copy.
|
||||
*/
|
||||
Alter_info alter_info(lex->alter_info, thd->mem_root);
|
||||
if (unlikely(thd->is_fatal_error))
|
||||
{
|
||||
/* If out of memory when creating a copy of alter_info. */
|
||||
res= 1;
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
|
||||
/* Check privileges */
|
||||
if ((res= create_table_precheck(thd, select_tables, create_table)))
|
||||
goto end_with_restore_list;
|
||||
|
||||
/* Might have been updated in create_table_precheck */
|
||||
create_info.alias= create_table->alias;
|
||||
|
||||
/* Fix names if symlinked or relocated tables */
|
||||
if (append_file_to_dir(thd, &create_info.data_file_name,
|
||||
&create_table->table_name) ||
|
||||
append_file_to_dir(thd, &create_info.index_file_name,
|
||||
&create_table->table_name))
|
||||
goto end_with_restore_list;
|
||||
|
||||
/*
|
||||
If no engine type was given, work out the default now
|
||||
rather than at parse-time.
|
||||
*/
|
||||
if (!(create_info.used_fields & HA_CREATE_USED_ENGINE))
|
||||
create_info.use_default_db_type(thd);
|
||||
|
||||
/*
|
||||
If we are using SET CHARSET without DEFAULT, add an implicit
|
||||
DEFAULT to not confuse old users. (This may change).
|
||||
*/
|
||||
if ((create_info.used_fields &
|
||||
(HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
|
||||
HA_CREATE_USED_CHARSET)
|
||||
{
|
||||
create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
|
||||
create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
|
||||
create_info.default_table_charset= create_info.table_charset;
|
||||
create_info.table_charset= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
If we are a slave, we should add OR REPLACE if we don't have
|
||||
IF EXISTS. This will help a slave to recover from
|
||||
CREATE TABLE OR EXISTS failures by dropping the table and
|
||||
retrying the create.
|
||||
*/
|
||||
if (thd->slave_thread &&
|
||||
slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT &&
|
||||
!lex->create_info.if_not_exists())
|
||||
{
|
||||
create_info.add(DDL_options_st::OPT_OR_REPLACE);
|
||||
create_info.add(DDL_options_st::OPT_OR_REPLACE_SLAVE_GENERATED);
|
||||
}
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
thd->work_part_info= 0;
|
||||
{
|
||||
partition_info *part_info= thd->lex->part_info;
|
||||
if (part_info && !(part_info= part_info->get_clone(thd)))
|
||||
{
|
||||
res= -1;
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
thd->work_part_info= part_info;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (select_lex->item_list.elements) // With select
|
||||
{
|
||||
select_result *result;
|
||||
|
||||
/*
|
||||
CREATE TABLE...IGNORE/REPLACE SELECT... can be unsafe, unless
|
||||
ORDER BY PRIMARY KEY clause is used in SELECT statement. We therefore
|
||||
use row based logging if mixed or row based logging is available.
|
||||
TODO: Check if the order of the output of the select statement is
|
||||
deterministic. Waiting for BUG#42415
|
||||
*/
|
||||
if(lex->ignore)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_IGNORE_SELECT);
|
||||
|
||||
if(lex->duplicates == DUP_REPLACE)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_REPLACE_SELECT);
|
||||
|
||||
/*
|
||||
If:
|
||||
a) we inside an SP and there was NAME_CONST substitution,
|
||||
b) binlogging is on (STMT mode),
|
||||
c) we log the SP as separate statements
|
||||
raise a warning, as it may cause problems
|
||||
(see 'NAME_CONST issues' in 'Binary Logging of Stored Programs')
|
||||
*/
|
||||
if (thd->query_name_consts && mysql_bin_log.is_open() &&
|
||||
thd->wsrep_binlog_format() == BINLOG_FORMAT_STMT &&
|
||||
!mysql_bin_log.is_query_in_union(thd, thd->query_id))
|
||||
{
|
||||
List_iterator_fast<Item> it(select_lex->item_list);
|
||||
Item *item;
|
||||
uint splocal_refs= 0;
|
||||
/* Count SP local vars in the top-level SELECT list */
|
||||
while ((item= it++))
|
||||
{
|
||||
if (item->get_item_splocal())
|
||||
splocal_refs++;
|
||||
}
|
||||
/*
|
||||
If it differs from number of NAME_CONST substitution applied,
|
||||
we may have a SOME_FUNC(NAME_CONST()) in the SELECT list,
|
||||
that may cause a problem with binary log (see BUG#35383),
|
||||
raise a warning.
|
||||
*/
|
||||
if (splocal_refs != thd->query_name_consts)
|
||||
push_warning(thd,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_UNKNOWN_ERROR,
|
||||
"Invoked routine ran a statement that may cause problems with "
|
||||
"binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' "
|
||||
"section of the manual.");
|
||||
}
|
||||
|
||||
select_lex->options|= SELECT_NO_UNLOCK;
|
||||
unit->set_limit(select_lex);
|
||||
|
||||
/*
|
||||
Disable non-empty MERGE tables with CREATE...SELECT. Too
|
||||
complicated. See Bug #26379. Empty MERGE tables are read-only
|
||||
and don't allow CREATE...SELECT anyway.
|
||||
*/
|
||||
if (create_info.used_fields & HA_CREATE_USED_UNION)
|
||||
{
|
||||
my_error(ER_WRONG_OBJECT, MYF(0), create_table->db.str,
|
||||
create_table->table_name.str, "BASE TABLE");
|
||||
res= 1;
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
|
||||
/* Copy temporarily the statement flags to thd for lock_table_names() */
|
||||
uint save_thd_create_info_options= thd->lex->create_info.options;
|
||||
thd->lex->create_info.options|= create_info.options;
|
||||
res= open_and_lock_tables(thd, create_info, lex->query_tables, TRUE, 0);
|
||||
thd->lex->create_info.options= save_thd_create_info_options;
|
||||
if (unlikely(res))
|
||||
{
|
||||
/* Got error or warning. Set res to 1 if error */
|
||||
if (!(res= thd->is_error()))
|
||||
my_ok(thd); // CREATE ... IF NOT EXISTS
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
|
||||
/* Ensure we don't try to create something from which we select from */
|
||||
if (create_info.or_replace() && !create_info.tmp_table())
|
||||
{
|
||||
TABLE_LIST *duplicate;
|
||||
if (unlikely((duplicate= unique_table(thd, lex->query_tables,
|
||||
lex->query_tables->next_global,
|
||||
CHECK_DUP_FOR_CREATE |
|
||||
CHECK_DUP_SKIP_TEMP_TABLE))))
|
||||
{
|
||||
update_non_unique_table_error(lex->query_tables, "CREATE",
|
||||
duplicate);
|
||||
res= TRUE;
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
}
|
||||
{
|
||||
/*
|
||||
Remove target table from main select and name resolution
|
||||
context. This can't be done earlier as it will break view merging in
|
||||
statements like "CREATE TABLE IF NOT EXISTS existing_view SELECT".
|
||||
*/
|
||||
lex->unlink_first_table(&link_to_local);
|
||||
|
||||
/* Store reference to table in case of LOCK TABLES */
|
||||
create_info.table= create_table->table;
|
||||
|
||||
/*
|
||||
select_create is currently not re-execution friendly and
|
||||
needs to be created for every execution of a PS/SP.
|
||||
Note: In wsrep-patch, CTAS is handled like a regular transaction.
|
||||
*/
|
||||
if (unlikely((result= new (thd->mem_root)
|
||||
select_create(thd, create_table,
|
||||
&create_info,
|
||||
&alter_info,
|
||||
select_lex->item_list,
|
||||
lex->duplicates,
|
||||
lex->ignore,
|
||||
select_tables))))
|
||||
{
|
||||
/*
|
||||
CREATE from SELECT give its SELECT_LEX for SELECT,
|
||||
and item_list belong to SELECT
|
||||
*/
|
||||
if (!(res= handle_select(thd, lex, result, 0)))
|
||||
{
|
||||
if (create_info.tmp_table())
|
||||
thd->variables.option_bits|= OPTION_KEEP_LOG;
|
||||
}
|
||||
delete result;
|
||||
}
|
||||
lex->link_first_table_back(create_table, link_to_local);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* regular create */
|
||||
if (create_info.like())
|
||||
{
|
||||
/* CREATE TABLE ... LIKE ... */
|
||||
res= mysql_create_like_table(thd, create_table, select_tables,
|
||||
&create_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (create_info.vers_fix_system_fields(thd, &alter_info, *create_table) ||
|
||||
create_info.vers_check_system_fields(thd, &alter_info, *create_table))
|
||||
goto end_with_restore_list;
|
||||
|
||||
/*
|
||||
In STATEMENT format, we probably have to replicate also temporary
|
||||
tables, like mysql replication does. Also check if the requested
|
||||
engine is allowed/supported.
|
||||
*/
|
||||
if (WSREP(thd) &&
|
||||
!check_engine(thd, create_table->db.str, create_table->table_name.str,
|
||||
&create_info) &&
|
||||
(!thd->is_current_stmt_binlog_format_row() ||
|
||||
!create_info.tmp_table()))
|
||||
{
|
||||
WSREP_TO_ISOLATION_BEGIN(create_table->db.str, create_table->table_name.str, NULL);
|
||||
}
|
||||
/* Regular CREATE TABLE */
|
||||
res= mysql_create_table(thd, create_table, &create_info, &alter_info);
|
||||
}
|
||||
|
||||
if (!res)
|
||||
{
|
||||
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
|
||||
if (create_info.tmp_table())
|
||||
thd->variables.option_bits|= OPTION_KEEP_LOG;
|
||||
/* in case of create temp tables if @@session_track_state_change is
|
||||
ON then send session state notification in OK packet */
|
||||
if(create_info.options & HA_LEX_CREATE_TMP_TABLE)
|
||||
{
|
||||
SESSION_TRACKER_CHANGED(thd, SESSION_STATE_CHANGE_TRACKER, NULL);
|
||||
}
|
||||
my_ok(thd);
|
||||
}
|
||||
}
|
||||
|
||||
end_with_restore_list:
|
||||
break;
|
||||
}
|
||||
case SQLCOM_CREATE_INDEX:
|
||||
case SQLCOM_DROP_INDEX:
|
||||
/*
|
||||
@ -6287,6 +6004,8 @@ end_with_restore_list:
|
||||
case SQLCOM_OPTIMIZE:
|
||||
case SQLCOM_REPAIR:
|
||||
case SQLCOM_TRUNCATE:
|
||||
case SQLCOM_CREATE_TABLE:
|
||||
case SQLCOM_CREATE_SEQUENCE:
|
||||
case SQLCOM_ALTER_TABLE:
|
||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||
/* fall through */
|
||||
|
@ -214,7 +214,8 @@ static COND *make_cond_for_table_from_pred(THD *thd, Item *root_cond,
|
||||
table_map used_table,
|
||||
int join_tab_idx_arg,
|
||||
bool exclude_expensive_cond,
|
||||
bool retain_ref_cond);
|
||||
bool retain_ref_cond,
|
||||
bool is_top_and_level);
|
||||
|
||||
static Item* part_of_refkey(TABLE *form,Field *field);
|
||||
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
|
||||
@ -5078,7 +5079,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
|
||||
{
|
||||
ha_rows records= 1;
|
||||
double records= 1;
|
||||
SELECT_LEX_UNIT *unit= join->select_lex->master_unit();
|
||||
|
||||
/* Find an optimal join order of the non-constant tables. */
|
||||
@ -5103,10 +5104,11 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
||||
table/view.
|
||||
*/
|
||||
for (i= 0; i < join->table_count ; i++)
|
||||
records*= join->best_positions[i].records_read ?
|
||||
(ha_rows)join->best_positions[i].records_read : 1;
|
||||
set_if_smaller(records, unit->select_limit_cnt);
|
||||
join->select_lex->increase_derived_records(records);
|
||||
if (double rr= join->best_positions[i].records_read)
|
||||
records= COST_MULT(records, rr);
|
||||
ha_rows rows= records > HA_ROWS_MAX ? HA_ROWS_MAX : (ha_rows) records;
|
||||
set_if_smaller(rows, unit->select_limit_cnt);
|
||||
join->select_lex->increase_derived_records(rows);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8258,18 +8260,23 @@ double JOIN::get_examined_rows()
|
||||
{
|
||||
double examined_rows;
|
||||
double prev_fanout= 1;
|
||||
double records;
|
||||
JOIN_TAB *tab= first_breadth_first_tab();
|
||||
JOIN_TAB *prev_tab= tab;
|
||||
|
||||
examined_rows= (double)tab->get_examined_rows();
|
||||
records= (double)tab->get_examined_rows();
|
||||
|
||||
while ((tab= next_breadth_first_tab(first_breadth_first_tab(),
|
||||
top_join_tab_count, tab)))
|
||||
{
|
||||
prev_fanout *= prev_tab->records_read;
|
||||
examined_rows+= tab->get_examined_rows() * prev_fanout;
|
||||
prev_fanout= COST_MULT(prev_fanout, prev_tab->records_read);
|
||||
records=
|
||||
COST_ADD(records,
|
||||
COST_MULT((double) (tab->get_examined_rows()), prev_fanout));
|
||||
prev_tab= tab;
|
||||
}
|
||||
examined_rows= (double)
|
||||
(records > (double) HA_ROWS_MAX ? HA_ROWS_MAX : (ha_rows) records);
|
||||
return examined_rows;
|
||||
}
|
||||
|
||||
@ -10582,12 +10589,6 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
||||
RAND_TABLE_BIT;
|
||||
}
|
||||
|
||||
/*
|
||||
Following force including random expression in last table condition.
|
||||
It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
|
||||
*/
|
||||
if (tab == join->join_tab + last_top_base_tab_idx)
|
||||
current_map|= RAND_TABLE_BIT;
|
||||
used_tables|=current_map;
|
||||
|
||||
if (tab->type == JT_REF && tab->quick &&
|
||||
@ -10629,6 +10630,20 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
||||
{
|
||||
tmp= make_cond_for_table(thd, cond, used_tables, current_map, i,
|
||||
FALSE, FALSE);
|
||||
if (tab == join->join_tab + last_top_base_tab_idx)
|
||||
{
|
||||
/*
|
||||
This pushes conjunctive conditions of WHERE condition such that:
|
||||
- their used_tables() contain RAND_TABLE_BIT
|
||||
- the conditions does not refer to any fields
|
||||
(such like rand() > 0.5)
|
||||
*/
|
||||
table_map rand_table_bit= (table_map) RAND_TABLE_BIT;
|
||||
COND *rand_cond= make_cond_for_table(thd, cond, used_tables,
|
||||
rand_table_bit, -1,
|
||||
FALSE, FALSE);
|
||||
add_cond_and_fix(thd, &tmp, rand_cond);
|
||||
}
|
||||
}
|
||||
/* Add conditions added by add_not_null_conds(). */
|
||||
if (tab->select_cond)
|
||||
@ -10964,6 +10979,21 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
||||
current_map,
|
||||
/*(inner_tab - first_tab)*/ -1,
|
||||
FALSE, FALSE);
|
||||
if (tab == last_tab)
|
||||
{
|
||||
/*
|
||||
This pushes conjunctive conditions of ON expression of an outer
|
||||
join such that:
|
||||
- their used_tables() contain RAND_TABLE_BIT
|
||||
- the conditions does not refer to any fields
|
||||
(such like rand() > 0.5)
|
||||
*/
|
||||
table_map rand_table_bit= (table_map) RAND_TABLE_BIT;
|
||||
COND *rand_cond= make_cond_for_table(thd, on_expr, used_tables2,
|
||||
rand_table_bit, -1,
|
||||
FALSE, FALSE);
|
||||
add_cond_and_fix(thd, &tmp_cond, rand_cond);
|
||||
}
|
||||
bool is_sjm_lookup_tab= FALSE;
|
||||
if (inner_tab->bush_children)
|
||||
{
|
||||
@ -12589,6 +12619,8 @@ ha_rows JOIN_TAB::get_examined_rows()
|
||||
else
|
||||
examined_rows= records_read;
|
||||
|
||||
if (examined_rows >= (double) HA_ROWS_MAX)
|
||||
return HA_ROWS_MAX;
|
||||
return (ha_rows) examined_rows;
|
||||
}
|
||||
|
||||
@ -21282,7 +21314,7 @@ make_cond_for_table(THD *thd, Item *cond, table_map tables,
|
||||
return make_cond_for_table_from_pred(thd, cond, cond, tables, used_table,
|
||||
join_tab_idx_arg,
|
||||
exclude_expensive_cond,
|
||||
retain_ref_cond);
|
||||
retain_ref_cond, true);
|
||||
}
|
||||
|
||||
|
||||
@ -21292,9 +21324,12 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
|
||||
int join_tab_idx_arg,
|
||||
bool exclude_expensive_cond __attribute__
|
||||
((unused)),
|
||||
bool retain_ref_cond)
|
||||
bool retain_ref_cond,
|
||||
bool is_top_and_level)
|
||||
|
||||
{
|
||||
table_map rand_table_bit= (table_map) RAND_TABLE_BIT;
|
||||
|
||||
if (used_table && !(cond->used_tables() & used_table))
|
||||
return (COND*) 0; // Already checked
|
||||
|
||||
@ -21310,11 +21345,28 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
/*
|
||||
Special handling of top level conjuncts with RAND_TABLE_BIT:
|
||||
if such a conjunct contains a reference to a field that is not
|
||||
an outer field then it is pushed to the corresponding table by
|
||||
the same rule as all other conjuncts. Otherwise, if the conjunct
|
||||
is used in WHERE is is pushed to the last joined table, if is it
|
||||
is used in ON condition of an outer join it is pushed into the
|
||||
last inner table of the outer join. Such conjuncts are pushed in
|
||||
a call of make_cond_for_table_from_pred() with the
|
||||
parameter 'used_table' equal to PSEUDO_TABLE_BITS.
|
||||
*/
|
||||
if (is_top_and_level && used_table == rand_table_bit &&
|
||||
(item->used_tables() & ~OUTER_REF_TABLE_BIT) != rand_table_bit)
|
||||
{
|
||||
/* The conjunct with RAND_TABLE_BIT has been allready pushed */
|
||||
continue;
|
||||
}
|
||||
Item *fix=make_cond_for_table_from_pred(thd, root_cond, item,
|
||||
tables, used_table,
|
||||
join_tab_idx_arg,
|
||||
join_tab_idx_arg,
|
||||
exclude_expensive_cond,
|
||||
retain_ref_cond);
|
||||
retain_ref_cond, false);
|
||||
if (fix)
|
||||
new_cond->argument_list()->push_back(fix, thd->mem_root);
|
||||
}
|
||||
@ -21339,6 +21391,13 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
|
||||
}
|
||||
else
|
||||
{ // Or list
|
||||
if (is_top_and_level && used_table == rand_table_bit &&
|
||||
(cond->used_tables() & ~OUTER_REF_TABLE_BIT) != rand_table_bit)
|
||||
{
|
||||
/* This top level formula with RAND_TABLE_BIT has been already pushed */
|
||||
return (COND*) 0;
|
||||
}
|
||||
|
||||
Item_cond_or *new_cond=new (thd->mem_root) Item_cond_or(thd);
|
||||
if (!new_cond)
|
||||
return (COND*) 0; // OOM /* purecov: inspected */
|
||||
@ -21350,7 +21409,7 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
|
||||
tables, 0L,
|
||||
join_tab_idx_arg,
|
||||
exclude_expensive_cond,
|
||||
retain_ref_cond);
|
||||
retain_ref_cond, false);
|
||||
if (!fix)
|
||||
return (COND*) 0; // Always true
|
||||
new_cond->argument_list()->push_back(fix, thd->mem_root);
|
||||
@ -21367,6 +21426,13 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
|
||||
}
|
||||
}
|
||||
|
||||
if (is_top_and_level && used_table == rand_table_bit &&
|
||||
(cond->used_tables() & ~OUTER_REF_TABLE_BIT) != rand_table_bit)
|
||||
{
|
||||
/* This top level formula with RAND_TABLE_BIT has been already pushed */
|
||||
return (COND*) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Because the following test takes a while and it can be done
|
||||
table_count times, we mark each item that we have examined with the result
|
||||
@ -25377,10 +25443,10 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta,
|
||||
}
|
||||
else
|
||||
{
|
||||
double examined_rows= (double)get_examined_rows();
|
||||
ha_rows examined_rows= get_examined_rows();
|
||||
|
||||
eta->rows_set= true;
|
||||
eta->rows= (ha_rows) examined_rows;
|
||||
eta->rows= examined_rows;
|
||||
|
||||
/* "filtered" */
|
||||
float f= 0.0;
|
||||
|
311
sql/sql_table.cc
311
sql/sql_table.cc
@ -10830,3 +10830,314 @@ bool check_engine(THD *thd, const char *db_name,
|
||||
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
|
||||
bool Sql_cmd_create_table_like::execute(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("Sql_cmd_create_table::execute");
|
||||
LEX *lex= thd->lex;
|
||||
TABLE_LIST *all_tables= lex->query_tables;
|
||||
SELECT_LEX *select_lex= &lex->select_lex;
|
||||
TABLE_LIST *first_table= select_lex->table_list.first;
|
||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||
bool link_to_local;
|
||||
TABLE_LIST *create_table= first_table;
|
||||
TABLE_LIST *select_tables= lex->create_last_non_select_table->next_global;
|
||||
/* most outer SELECT_LEX_UNIT of query */
|
||||
SELECT_LEX_UNIT *unit= &lex->unit;
|
||||
int res= 0;
|
||||
|
||||
const bool used_engine= lex->create_info.used_fields & HA_CREATE_USED_ENGINE;
|
||||
DBUG_ASSERT((m_storage_engine_name.str != NULL) == used_engine);
|
||||
if (used_engine)
|
||||
{
|
||||
if (resolve_storage_engine_with_error(thd, &lex->create_info.db_type,
|
||||
lex->create_info.tmp_table()))
|
||||
DBUG_RETURN(true); // Engine not found, substitution is not allowed
|
||||
|
||||
if (!lex->create_info.db_type) // Not found, but substitution is allowed
|
||||
{
|
||||
lex->create_info.use_default_db_type(thd);
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_USING_OTHER_HANDLER,
|
||||
ER_THD(thd, ER_WARN_USING_OTHER_HANDLER),
|
||||
hton_name(lex->create_info.db_type)->str,
|
||||
create_table->table_name.str);
|
||||
}
|
||||
}
|
||||
|
||||
if (lex->tmp_table())
|
||||
{
|
||||
status_var_decrement(thd->status_var.com_stat[SQLCOM_CREATE_TABLE]);
|
||||
status_var_increment(thd->status_var.com_create_tmp_table);
|
||||
}
|
||||
|
||||
/*
|
||||
Code below (especially in mysql_create_table() and select_create
|
||||
methods) may modify HA_CREATE_INFO structure in LEX, so we have to
|
||||
use a copy of this structure to make execution prepared statement-
|
||||
safe. A shallow copy is enough as this code won't modify any memory
|
||||
referenced from this structure.
|
||||
*/
|
||||
Table_specification_st create_info(lex->create_info);
|
||||
/*
|
||||
We need to copy alter_info for the same reasons of re-execution
|
||||
safety, only in case of Alter_info we have to do (almost) a deep
|
||||
copy.
|
||||
*/
|
||||
Alter_info alter_info(lex->alter_info, thd->mem_root);
|
||||
|
||||
if (unlikely(thd->is_fatal_error))
|
||||
{
|
||||
/* If out of memory when creating a copy of alter_info. */
|
||||
res= 1;
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
|
||||
/* Check privileges */
|
||||
if ((res= create_table_precheck(thd, select_tables, create_table)))
|
||||
goto end_with_restore_list;
|
||||
|
||||
/* Might have been updated in create_table_precheck */
|
||||
create_info.alias= create_table->alias;
|
||||
|
||||
/* Fix names if symlinked or relocated tables */
|
||||
if (append_file_to_dir(thd, &create_info.data_file_name,
|
||||
&create_table->table_name) ||
|
||||
append_file_to_dir(thd, &create_info.index_file_name,
|
||||
&create_table->table_name))
|
||||
goto end_with_restore_list;
|
||||
|
||||
/*
|
||||
If no engine type was given, work out the default now
|
||||
rather than at parse-time.
|
||||
*/
|
||||
if (!(create_info.used_fields & HA_CREATE_USED_ENGINE))
|
||||
create_info.use_default_db_type(thd);
|
||||
/*
|
||||
If we are using SET CHARSET without DEFAULT, add an implicit
|
||||
DEFAULT to not confuse old users. (This may change).
|
||||
*/
|
||||
if ((create_info.used_fields &
|
||||
(HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
|
||||
HA_CREATE_USED_CHARSET)
|
||||
{
|
||||
create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
|
||||
create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
|
||||
create_info.default_table_charset= create_info.table_charset;
|
||||
create_info.table_charset= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
If we are a slave, we should add OR REPLACE if we don't have
|
||||
IF EXISTS. This will help a slave to recover from
|
||||
CREATE TABLE OR EXISTS failures by dropping the table and
|
||||
retrying the create.
|
||||
*/
|
||||
if (thd->slave_thread &&
|
||||
slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT &&
|
||||
!lex->create_info.if_not_exists())
|
||||
{
|
||||
create_info.add(DDL_options_st::OPT_OR_REPLACE);
|
||||
create_info.add(DDL_options_st::OPT_OR_REPLACE_SLAVE_GENERATED);
|
||||
}
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
thd->work_part_info= 0;
|
||||
{
|
||||
partition_info *part_info= thd->lex->part_info;
|
||||
if (part_info && !(part_info= part_info->get_clone(thd)))
|
||||
{
|
||||
res= -1;
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
thd->work_part_info= part_info;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (select_lex->item_list.elements) // With select
|
||||
{
|
||||
select_result *result;
|
||||
|
||||
/*
|
||||
CREATE TABLE...IGNORE/REPLACE SELECT... can be unsafe, unless
|
||||
ORDER BY PRIMARY KEY clause is used in SELECT statement. We therefore
|
||||
use row based logging if mixed or row based logging is available.
|
||||
TODO: Check if the order of the output of the select statement is
|
||||
deterministic. Waiting for BUG#42415
|
||||
*/
|
||||
if(lex->ignore)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_IGNORE_SELECT);
|
||||
|
||||
if(lex->duplicates == DUP_REPLACE)
|
||||
lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_REPLACE_SELECT);
|
||||
|
||||
/*
|
||||
If:
|
||||
a) we inside an SP and there was NAME_CONST substitution,
|
||||
b) binlogging is on (STMT mode),
|
||||
c) we log the SP as separate statements
|
||||
raise a warning, as it may cause problems
|
||||
(see 'NAME_CONST issues' in 'Binary Logging of Stored Programs')
|
||||
*/
|
||||
if (thd->query_name_consts && mysql_bin_log.is_open() &&
|
||||
thd->wsrep_binlog_format() == BINLOG_FORMAT_STMT &&
|
||||
!mysql_bin_log.is_query_in_union(thd, thd->query_id))
|
||||
{
|
||||
List_iterator_fast<Item> it(select_lex->item_list);
|
||||
Item *item;
|
||||
uint splocal_refs= 0;
|
||||
/* Count SP local vars in the top-level SELECT list */
|
||||
while ((item= it++))
|
||||
{
|
||||
if (item->get_item_splocal())
|
||||
splocal_refs++;
|
||||
}
|
||||
/*
|
||||
If it differs from number of NAME_CONST substitution applied,
|
||||
we may have a SOME_FUNC(NAME_CONST()) in the SELECT list,
|
||||
that may cause a problem with binary log (see BUG#35383),
|
||||
raise a warning.
|
||||
*/
|
||||
if (splocal_refs != thd->query_name_consts)
|
||||
push_warning(thd,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_UNKNOWN_ERROR,
|
||||
"Invoked routine ran a statement that may cause problems with "
|
||||
"binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' "
|
||||
"section of the manual.");
|
||||
}
|
||||
|
||||
select_lex->options|= SELECT_NO_UNLOCK;
|
||||
unit->set_limit(select_lex);
|
||||
|
||||
/*
|
||||
Disable non-empty MERGE tables with CREATE...SELECT. Too
|
||||
complicated. See Bug #26379. Empty MERGE tables are read-only
|
||||
and don't allow CREATE...SELECT anyway.
|
||||
*/
|
||||
if (create_info.used_fields & HA_CREATE_USED_UNION)
|
||||
{
|
||||
my_error(ER_WRONG_OBJECT, MYF(0), create_table->db.str,
|
||||
create_table->table_name.str, "BASE TABLE");
|
||||
res= 1;
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
|
||||
/* Copy temporarily the statement flags to thd for lock_table_names() */
|
||||
uint save_thd_create_info_options= thd->lex->create_info.options;
|
||||
thd->lex->create_info.options|= create_info.options;
|
||||
res= open_and_lock_tables(thd, create_info, lex->query_tables, TRUE, 0);
|
||||
thd->lex->create_info.options= save_thd_create_info_options;
|
||||
if (unlikely(res))
|
||||
{
|
||||
/* Got error or warning. Set res to 1 if error */
|
||||
if (!(res= thd->is_error()))
|
||||
my_ok(thd); // CREATE ... IF NOT EXISTS
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
|
||||
/* Ensure we don't try to create something from which we select from */
|
||||
if (create_info.or_replace() && !create_info.tmp_table())
|
||||
{
|
||||
if (TABLE_LIST *duplicate= unique_table(thd, lex->query_tables,
|
||||
lex->query_tables->next_global,
|
||||
CHECK_DUP_FOR_CREATE |
|
||||
CHECK_DUP_SKIP_TEMP_TABLE))
|
||||
{
|
||||
update_non_unique_table_error(lex->query_tables, "CREATE",
|
||||
duplicate);
|
||||
res= TRUE;
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
}
|
||||
{
|
||||
/*
|
||||
Remove target table from main select and name resolution
|
||||
context. This can't be done earlier as it will break view merging in
|
||||
statements like "CREATE TABLE IF NOT EXISTS existing_view SELECT".
|
||||
*/
|
||||
lex->unlink_first_table(&link_to_local);
|
||||
|
||||
/* Store reference to table in case of LOCK TABLES */
|
||||
create_info.table= create_table->table;
|
||||
|
||||
/*
|
||||
select_create is currently not re-execution friendly and
|
||||
needs to be created for every execution of a PS/SP.
|
||||
Note: In wsrep-patch, CTAS is handled like a regular transaction.
|
||||
*/
|
||||
if ((result= new (thd->mem_root) select_create(thd, create_table,
|
||||
&create_info,
|
||||
&alter_info,
|
||||
select_lex->item_list,
|
||||
lex->duplicates,
|
||||
lex->ignore,
|
||||
select_tables)))
|
||||
{
|
||||
/*
|
||||
CREATE from SELECT give its SELECT_LEX for SELECT,
|
||||
and item_list belong to SELECT
|
||||
*/
|
||||
if (!(res= handle_select(thd, lex, result, 0)))
|
||||
{
|
||||
if (create_info.tmp_table())
|
||||
thd->variables.option_bits|= OPTION_KEEP_LOG;
|
||||
}
|
||||
delete result;
|
||||
}
|
||||
lex->link_first_table_back(create_table, link_to_local);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* regular create */
|
||||
if (create_info.like())
|
||||
{
|
||||
/* CREATE TABLE ... LIKE ... */
|
||||
res= mysql_create_like_table(thd, create_table, select_tables,
|
||||
&create_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (create_info.vers_fix_system_fields(thd, &alter_info, *create_table) ||
|
||||
create_info.vers_check_system_fields(thd, &alter_info, *create_table))
|
||||
goto end_with_restore_list;
|
||||
|
||||
/*
|
||||
In STATEMENT format, we probably have to replicate also temporary
|
||||
tables, like mysql replication does. Also check if the requested
|
||||
engine is allowed/supported.
|
||||
*/
|
||||
if (WSREP(thd) &&
|
||||
!check_engine(thd, create_table->db.str, create_table->table_name.str,
|
||||
&create_info) &&
|
||||
(!thd->is_current_stmt_binlog_format_row() ||
|
||||
!create_info.tmp_table()))
|
||||
{
|
||||
WSREP_TO_ISOLATION_BEGIN(create_table->db.str, create_table->table_name.str, NULL)
|
||||
}
|
||||
/* Regular CREATE TABLE */
|
||||
res= mysql_create_table(thd, create_table, &create_info, &alter_info);
|
||||
}
|
||||
if (!res)
|
||||
{
|
||||
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
|
||||
if (create_info.tmp_table())
|
||||
thd->variables.option_bits|= OPTION_KEEP_LOG;
|
||||
/* in case of create temp tables if @@session_track_state_change is
|
||||
ON then send session state notification in OK packet */
|
||||
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
|
||||
{
|
||||
SESSION_TRACKER_CHANGED(thd, SESSION_STATE_CHANGE_TRACKER, NULL);
|
||||
}
|
||||
my_ok(thd);
|
||||
}
|
||||
}
|
||||
|
||||
end_with_restore_list:
|
||||
DBUG_RETURN(res);
|
||||
|
||||
WSREP_ERROR_LABEL:
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
|
@ -1516,108 +1516,81 @@ static bool multi_update_check_table_access(THD *thd, TABLE_LIST *table,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
make update specific preparation and checks after opening tables
|
||||
|
||||
SYNOPSIS
|
||||
mysql_multi_update_prepare()
|
||||
thd thread handler
|
||||
|
||||
RETURN
|
||||
FALSE OK
|
||||
TRUE Error
|
||||
*/
|
||||
|
||||
int mysql_multi_update_prepare(THD *thd)
|
||||
class Multiupdate_prelocking_strategy : public DML_prelocking_strategy
|
||||
{
|
||||
bool done;
|
||||
bool has_prelocking_list;
|
||||
public:
|
||||
void reset(THD *thd);
|
||||
bool handle_end(THD *thd);
|
||||
};
|
||||
|
||||
void Multiupdate_prelocking_strategy::reset(THD *thd)
|
||||
{
|
||||
done= false;
|
||||
has_prelocking_list= thd->lex->requires_prelocking();
|
||||
}
|
||||
|
||||
/**
|
||||
Determine what tables could be updated in the multi-update
|
||||
|
||||
For these tables we'll need to open triggers and continue prelocking
|
||||
until all is open.
|
||||
*/
|
||||
bool Multiupdate_prelocking_strategy::handle_end(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("Multiupdate_prelocking_strategy::handle_end");
|
||||
if (done)
|
||||
DBUG_RETURN(0);
|
||||
|
||||
LEX *lex= thd->lex;
|
||||
TABLE_LIST *table_list= lex->query_tables;
|
||||
TABLE_LIST *tl;
|
||||
List<Item> *fields= &lex->select_lex.item_list;
|
||||
table_map tables_for_update;
|
||||
bool update_view= 0;
|
||||
DML_prelocking_strategy prelocking_strategy;
|
||||
bool has_prelocking_list= thd->lex->requires_prelocking();
|
||||
SELECT_LEX *select_lex= &lex->select_lex;
|
||||
TABLE_LIST *table_list= lex->query_tables, *tl;
|
||||
|
||||
/*
|
||||
if this multi-update was converted from usual update, here is table
|
||||
counter else junk will be assigned here, but then replaced with real
|
||||
count in open_tables()
|
||||
*/
|
||||
uint table_count= lex->table_count;
|
||||
const bool using_lock_tables= thd->locked_tables_mode != LTM_NONE;
|
||||
bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI);
|
||||
DBUG_ENTER("mysql_multi_update_prepare");
|
||||
done= true;
|
||||
|
||||
/* following need for prepared statements, to run next time multi-update */
|
||||
thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
|
||||
if (mysql_handle_derived(lex, DT_INIT) ||
|
||||
mysql_handle_derived(lex, DT_MERGE_FOR_INSERT) ||
|
||||
mysql_handle_derived(lex, DT_PREPARE))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/*
|
||||
Open tables and create derived ones, but do not lock and fill them yet.
|
||||
|
||||
During prepare phase acquire only S metadata locks instead of SW locks to
|
||||
keep prepare of multi-UPDATE compatible with concurrent LOCK TABLES WRITE
|
||||
and global read lock.
|
||||
*/
|
||||
if ((original_multiupdate && open_tables(thd, &table_list, &table_count,
|
||||
thd->stmt_arena->is_stmt_prepare()
|
||||
? MYSQL_OPEN_FORCE_SHARED_MDL : 0,
|
||||
&prelocking_strategy)) ||
|
||||
mysql_handle_derived(lex, DT_INIT))
|
||||
DBUG_RETURN(TRUE);
|
||||
/*
|
||||
setup_tables() need for VIEWs. JOIN::prepare() will call setup_tables()
|
||||
second time, but this call will do nothing (there are check for second
|
||||
call in setup_tables()).
|
||||
*/
|
||||
|
||||
//We need to merge for insert prior to prepare.
|
||||
if (mysql_handle_derived(lex, DT_MERGE_FOR_INSERT))
|
||||
DBUG_RETURN(TRUE);
|
||||
if (setup_tables_and_check_access(thd, &select_lex->context,
|
||||
&select_lex->top_join_list, table_list, select_lex->leaf_tables,
|
||||
FALSE, UPDATE_ACL, SELECT_ACL, FALSE))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
if (mysql_handle_derived(lex, DT_PREPARE))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
if (setup_tables_and_check_access(thd, &lex->select_lex.context,
|
||||
&lex->select_lex.top_join_list,
|
||||
table_list,
|
||||
lex->select_lex.leaf_tables, FALSE,
|
||||
UPDATE_ACL, SELECT_ACL, FALSE))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
if (lex->select_lex.handle_derived(thd->lex, DT_MERGE))
|
||||
DBUG_RETURN(TRUE);
|
||||
if (select_lex->handle_derived(thd->lex, DT_MERGE))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
List<Item> *fields= &lex->select_lex.item_list;
|
||||
if (setup_fields_with_no_wrap(thd, Ref_ptr_array(),
|
||||
*fields, MARK_COLUMNS_WRITE, 0, 0))
|
||||
DBUG_RETURN(TRUE);
|
||||
DBUG_RETURN(1);
|
||||
|
||||
// Check if we have a view in the list ...
|
||||
for (tl= table_list; tl ; tl= tl->next_local)
|
||||
{
|
||||
if (tl->view)
|
||||
{
|
||||
update_view= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ... and pass this knowlage in check_fields call
|
||||
if (check_fields(thd, *fields, tl != NULL ))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
if (check_fields(thd, *fields, update_view))
|
||||
{
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
table_map tables_for_update= thd->table_map_for_update= get_table_map(fields);
|
||||
|
||||
thd->table_map_for_update= tables_for_update= get_table_map(fields);
|
||||
|
||||
if (unsafe_key_update(lex->select_lex.leaf_tables, tables_for_update))
|
||||
DBUG_RETURN(true);
|
||||
|
||||
TABLE_LIST **new_tables= lex->query_tables_last;
|
||||
DBUG_ASSERT(*new_tables== NULL);
|
||||
if (unsafe_key_update(select_lex->leaf_tables, tables_for_update))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/*
|
||||
Setup timestamp handling and locking mode
|
||||
*/
|
||||
List_iterator<TABLE_LIST> ti(lex->select_lex.leaf_tables);
|
||||
List_iterator<TABLE_LIST> ti(select_lex->leaf_tables);
|
||||
const bool using_lock_tables= thd->locked_tables_mode != LTM_NONE;
|
||||
while ((tl= ti++))
|
||||
{
|
||||
TABLE *table= tl->table;
|
||||
@ -1632,7 +1605,7 @@ int mysql_multi_update_prepare(THD *thd)
|
||||
{
|
||||
my_error(ER_NON_UPDATABLE_TABLE, MYF(0),
|
||||
tl->top_table()->alias.str, "UPDATE");
|
||||
DBUG_RETURN(TRUE);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
DBUG_PRINT("info",("setting table `%s` for update",
|
||||
@ -1644,8 +1617,8 @@ int mysql_multi_update_prepare(THD *thd)
|
||||
tl->updating= 1;
|
||||
if (tl->belong_to_view)
|
||||
tl->belong_to_view->updating= 1;
|
||||
if (extend_table_list(thd, tl, &prelocking_strategy, has_prelocking_list))
|
||||
DBUG_RETURN(TRUE);
|
||||
if (extend_table_list(thd, tl, this, has_prelocking_list))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1677,19 +1650,6 @@ int mysql_multi_update_prepare(THD *thd)
|
||||
through all leaf tables but also through all view hierarchy.
|
||||
*/
|
||||
|
||||
uint addon_table_count= 0;
|
||||
if (*new_tables)
|
||||
{
|
||||
Sroutine_hash_entry **new_routines= thd->lex->sroutines_list.next;
|
||||
DBUG_ASSERT(*new_routines == NULL);
|
||||
if (open_tables(thd, thd->lex->create_info, new_tables,
|
||||
&addon_table_count, new_routines,
|
||||
thd->stmt_arena->is_stmt_prepare()
|
||||
? MYSQL_OPEN_FORCE_SHARED_MDL : 0,
|
||||
&prelocking_strategy))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
for (tl= table_list; tl; tl= tl->next_local)
|
||||
{
|
||||
bool not_used= false;
|
||||
@ -1702,23 +1662,67 @@ int mysql_multi_update_prepare(THD *thd)
|
||||
/* check single table update for view compound from several tables */
|
||||
for (tl= table_list; tl; tl= tl->next_local)
|
||||
{
|
||||
TABLE_LIST *for_update= 0;
|
||||
if (tl->is_jtbm())
|
||||
continue;
|
||||
if (tl->is_merged_derived())
|
||||
if (tl->is_merged_derived() &&
|
||||
tl->check_single_table(&for_update, tables_for_update, tl))
|
||||
{
|
||||
TABLE_LIST *for_update= 0;
|
||||
if (tl->check_single_table(&for_update, tables_for_update, tl))
|
||||
{
|
||||
my_error(ER_VIEW_MULTIUPDATE, MYF(0),
|
||||
tl->view_db.str, tl->view_name.str);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
my_error(ER_VIEW_MULTIUPDATE, MYF(0), tl->view_db.str, tl->view_name.str);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
make update specific preparation and checks after opening tables
|
||||
|
||||
SYNOPSIS
|
||||
mysql_multi_update_prepare()
|
||||
thd thread handler
|
||||
|
||||
RETURN
|
||||
FALSE OK
|
||||
TRUE Error
|
||||
*/
|
||||
|
||||
int mysql_multi_update_prepare(THD *thd)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
TABLE_LIST *table_list= lex->query_tables;
|
||||
TABLE_LIST *tl;
|
||||
Multiupdate_prelocking_strategy prelocking_strategy;
|
||||
uint table_count= lex->table_count;
|
||||
DBUG_ENTER("mysql_multi_update_prepare");
|
||||
|
||||
/*
|
||||
Open tables and create derived ones, but do not lock and fill them yet.
|
||||
|
||||
During prepare phase acquire only S metadata locks instead of SW locks to
|
||||
keep prepare of multi-UPDATE compatible with concurrent LOCK TABLES WRITE
|
||||
and global read lock.
|
||||
*/
|
||||
if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI)
|
||||
{
|
||||
if (open_tables(thd, &table_list, &table_count,
|
||||
thd->stmt_arena->is_stmt_prepare() ? MYSQL_OPEN_FORCE_SHARED_MDL : 0,
|
||||
&prelocking_strategy))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* following need for prepared statements, to run next time multi-update */
|
||||
thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
|
||||
prelocking_strategy.reset(thd);
|
||||
if (prelocking_strategy.handle_end(thd))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
/* now lock and fill tables */
|
||||
if (!thd->stmt_arena->is_stmt_prepare() &&
|
||||
lock_tables(thd, table_list, table_count + addon_table_count, 0))
|
||||
lock_tables(thd, table_list, table_count, 0))
|
||||
{
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
@ -1731,7 +1735,7 @@ int mysql_multi_update_prepare(THD *thd)
|
||||
*/
|
||||
lex->select_lex.exclude_from_table_unique_test= TRUE;
|
||||
/* We only need SELECT privilege for columns in the values list */
|
||||
ti.rewind();
|
||||
List_iterator<TABLE_LIST> ti(lex->select_lex.leaf_tables);
|
||||
while ((tl= ti++))
|
||||
{
|
||||
if (tl->is_jtbm())
|
||||
@ -1764,25 +1768,18 @@ int mysql_multi_update_prepare(THD *thd)
|
||||
Setup multi-update handling and call SELECT to do the join
|
||||
*/
|
||||
|
||||
bool mysql_multi_update(THD *thd,
|
||||
TABLE_LIST *table_list,
|
||||
List<Item> *fields,
|
||||
List<Item> *values,
|
||||
COND *conds,
|
||||
ulonglong options,
|
||||
bool mysql_multi_update(THD *thd, TABLE_LIST *table_list, List<Item> *fields,
|
||||
List<Item> *values, COND *conds, ulonglong options,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
bool ignore,
|
||||
SELECT_LEX_UNIT *unit,
|
||||
SELECT_LEX *select_lex,
|
||||
multi_update **result)
|
||||
bool ignore, SELECT_LEX_UNIT *unit,
|
||||
SELECT_LEX *select_lex, multi_update **result)
|
||||
{
|
||||
bool res;
|
||||
DBUG_ENTER("mysql_multi_update");
|
||||
|
||||
|
||||
if (!(*result= new (thd->mem_root) multi_update(thd, table_list,
|
||||
&thd->lex->select_lex.leaf_tables,
|
||||
fields, values,
|
||||
handle_duplicates, ignore)))
|
||||
fields, values, handle_duplicates, ignore)))
|
||||
{
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
@ -1792,8 +1789,8 @@ bool mysql_multi_update(THD *thd,
|
||||
|
||||
res= mysql_select(thd,
|
||||
table_list, select_lex->with_wild, total_list, conds,
|
||||
select_lex->order_list.elements, select_lex->order_list.first,
|
||||
(ORDER *)NULL, (Item *) NULL, (ORDER *)NULL,
|
||||
select_lex->order_list.elements,
|
||||
select_lex->order_list.first, NULL, NULL, NULL,
|
||||
options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
|
||||
OPTION_SETUP_TABLES_DONE,
|
||||
*result, unit, select_lex);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
||||
Copyright (c) 2010, 2016, MariaDB
|
||||
Copyright (c) 2010, 2019, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -2693,6 +2693,8 @@ create:
|
||||
create_or_replace opt_temporary TABLE_SYM opt_if_not_exists table_ident
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
if (!(lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_create_table()))
|
||||
MYSQL_YYABORT;
|
||||
lex->create_info.init();
|
||||
if (unlikely(lex->set_command_with_check(SQLCOM_CREATE_TABLE, $2,
|
||||
$1 | $4)))
|
||||
@ -2716,21 +2718,13 @@ create:
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
lex->current_select= &lex->select_lex;
|
||||
if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
|
||||
!lex->create_info.db_type)
|
||||
{
|
||||
lex->create_info.use_default_db_type(thd);
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_USING_OTHER_HANDLER,
|
||||
ER_THD(thd, ER_WARN_USING_OTHER_HANDLER),
|
||||
hton_name(lex->create_info.db_type)->str,
|
||||
$5->table.str);
|
||||
}
|
||||
create_table_set_open_action_and_adjust_tables(lex);
|
||||
}
|
||||
| create_or_replace opt_temporary SEQUENCE_SYM opt_if_not_exists table_ident
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
if (!(lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_create_sequence()))
|
||||
MYSQL_YYABORT;
|
||||
lex->create_info.init();
|
||||
if (unlikely(lex->set_command_with_check(SQLCOM_CREATE_SEQUENCE, $2,
|
||||
$1 | $4)))
|
||||
@ -2777,17 +2771,6 @@ create:
|
||||
Lex->create_info.sequence= 1;
|
||||
|
||||
lex->current_select= &lex->select_lex;
|
||||
if (unlikely((lex->create_info.used_fields &
|
||||
HA_CREATE_USED_ENGINE) &&
|
||||
!lex->create_info.db_type))
|
||||
{
|
||||
lex->create_info.use_default_db_type(thd);
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_USING_OTHER_HANDLER,
|
||||
ER_THD(thd, ER_WARN_USING_OTHER_HANDLER),
|
||||
hton_name(lex->create_info.db_type)->str,
|
||||
$5->table.str);
|
||||
}
|
||||
create_table_set_open_action_and_adjust_tables(lex);
|
||||
}
|
||||
| create_or_replace opt_unique INDEX_SYM opt_if_not_exists ident
|
||||
@ -6222,10 +6205,20 @@ create_table_options:
|
||||
;
|
||||
|
||||
create_table_option:
|
||||
ENGINE_SYM opt_equal storage_engines
|
||||
ENGINE_SYM opt_equal ident_or_text
|
||||
{
|
||||
Lex->create_info.db_type= $3;
|
||||
Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE;
|
||||
LEX *lex= Lex;
|
||||
if (!lex->m_sql_cmd)
|
||||
{
|
||||
DBUG_ASSERT(lex->sql_command == SQLCOM_ALTER_TABLE);
|
||||
if (!(lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table()))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
Storage_engine_name *opt=
|
||||
lex->m_sql_cmd->option_storage_engine_name();
|
||||
DBUG_ASSERT(opt); // Expect a proper Sql_cmd
|
||||
*opt= Storage_engine_name($3);
|
||||
lex->create_info.used_fields|= HA_CREATE_USED_ENGINE;
|
||||
}
|
||||
| MAX_ROWS opt_equal ulonglong_num
|
||||
{
|
||||
@ -6520,21 +6513,10 @@ default_collation:
|
||||
storage_engines:
|
||||
ident_or_text
|
||||
{
|
||||
plugin_ref plugin= ha_resolve_by_name(thd, &$1,
|
||||
thd->lex->create_info.tmp_table());
|
||||
|
||||
if (likely(plugin))
|
||||
$$= plugin_hton(plugin);
|
||||
else
|
||||
{
|
||||
if (thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION)
|
||||
my_yyabort_error((ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str));
|
||||
$$= 0;
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_UNKNOWN_STORAGE_ENGINE,
|
||||
ER_THD(thd, ER_UNKNOWN_STORAGE_ENGINE),
|
||||
$1.str);
|
||||
}
|
||||
if (Storage_engine_name($1).
|
||||
resolve_storage_engine_with_error(thd, &$$,
|
||||
thd->lex->create_info.tmp_table()))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
@ -8454,11 +8436,6 @@ alter_list_item:
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->alter_info.flags|= ALTER_OPTIONS;
|
||||
if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
|
||||
!lex->create_info.db_type)
|
||||
{
|
||||
lex->create_info.used_fields&= ~HA_CREATE_USED_ENGINE;
|
||||
}
|
||||
}
|
||||
| FORCE_SYM
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
||||
Copyright (c) 2010, 2016, MariaDB
|
||||
Copyright (c) 2010, 2019, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -2115,6 +2115,8 @@ create:
|
||||
create_or_replace opt_temporary TABLE_SYM opt_if_not_exists table_ident
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
if (!(lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_create_table()))
|
||||
MYSQL_YYABORT;
|
||||
lex->create_info.init();
|
||||
if (unlikely(lex->set_command_with_check(SQLCOM_CREATE_TABLE, $2,
|
||||
$1 | $4)))
|
||||
@ -2138,21 +2140,13 @@ create:
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
lex->current_select= &lex->select_lex;
|
||||
if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
|
||||
!lex->create_info.db_type)
|
||||
{
|
||||
lex->create_info.use_default_db_type(thd);
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_USING_OTHER_HANDLER,
|
||||
ER_THD(thd, ER_WARN_USING_OTHER_HANDLER),
|
||||
hton_name(lex->create_info.db_type)->str,
|
||||
$5->table.str);
|
||||
}
|
||||
create_table_set_open_action_and_adjust_tables(lex);
|
||||
}
|
||||
| create_or_replace opt_temporary SEQUENCE_SYM opt_if_not_exists table_ident
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
if (!(lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_create_sequence()))
|
||||
MYSQL_YYABORT;
|
||||
lex->create_info.init();
|
||||
if (unlikely(lex->set_command_with_check(SQLCOM_CREATE_SEQUENCE, $2,
|
||||
$1 | $4)))
|
||||
@ -2199,17 +2193,6 @@ create:
|
||||
Lex->create_info.sequence= 1;
|
||||
|
||||
lex->current_select= &lex->select_lex;
|
||||
if (unlikely((lex->create_info.used_fields &
|
||||
HA_CREATE_USED_ENGINE) &&
|
||||
!lex->create_info.db_type))
|
||||
{
|
||||
lex->create_info.use_default_db_type(thd);
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WARN_USING_OTHER_HANDLER,
|
||||
ER_THD(thd, ER_WARN_USING_OTHER_HANDLER),
|
||||
hton_name(lex->create_info.db_type)->str,
|
||||
$5->table.str);
|
||||
}
|
||||
create_table_set_open_action_and_adjust_tables(lex);
|
||||
}
|
||||
| create_or_replace opt_unique INDEX_SYM opt_if_not_exists ident
|
||||
@ -6068,10 +6051,20 @@ create_table_options:
|
||||
;
|
||||
|
||||
create_table_option:
|
||||
ENGINE_SYM opt_equal storage_engines
|
||||
ENGINE_SYM opt_equal ident_or_text
|
||||
{
|
||||
Lex->create_info.db_type= $3;
|
||||
Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE;
|
||||
LEX *lex= Lex;
|
||||
if (!lex->m_sql_cmd)
|
||||
{
|
||||
DBUG_ASSERT(lex->sql_command == SQLCOM_ALTER_TABLE);
|
||||
if (!(lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table()))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
Storage_engine_name *opt=
|
||||
lex->m_sql_cmd->option_storage_engine_name();
|
||||
DBUG_ASSERT(opt); // Expect a proper Sql_cmd
|
||||
*opt= Storage_engine_name($3);
|
||||
lex->create_info.used_fields|= HA_CREATE_USED_ENGINE;
|
||||
}
|
||||
| MAX_ROWS opt_equal ulonglong_num
|
||||
{
|
||||
@ -6366,21 +6359,10 @@ default_collation:
|
||||
storage_engines:
|
||||
ident_or_text
|
||||
{
|
||||
plugin_ref plugin= ha_resolve_by_name(thd, &$1,
|
||||
thd->lex->create_info.tmp_table());
|
||||
|
||||
if (likely(plugin))
|
||||
$$= plugin_hton(plugin);
|
||||
else
|
||||
{
|
||||
if (thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION)
|
||||
my_yyabort_error((ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str));
|
||||
$$= 0;
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_UNKNOWN_STORAGE_ENGINE,
|
||||
ER_THD(thd, ER_UNKNOWN_STORAGE_ENGINE),
|
||||
$1.str);
|
||||
}
|
||||
if (Storage_engine_name($1).
|
||||
resolve_storage_engine_with_error(thd, &$$,
|
||||
thd->lex->create_info.tmp_table()))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
@ -8391,11 +8373,6 @@ alter_list_item:
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->alter_info.flags|= ALTER_OPTIONS;
|
||||
if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
|
||||
!lex->create_info.db_type)
|
||||
{
|
||||
lex->create_info.used_fields&= ~HA_CREATE_USED_ENGINE;
|
||||
}
|
||||
}
|
||||
| FORCE_SYM
|
||||
{
|
||||
|
23
sql/table.cc
23
sql/table.cc
@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
|
||||
Copyright (c) 2008, 2018, MariaDB
|
||||
Copyright (c) 2008, 2019, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -1386,8 +1386,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
}
|
||||
if (!share->table_charset)
|
||||
{
|
||||
const CHARSET_INFO *cs= thd->variables.collation_database;
|
||||
/* unknown charset in frm_image[38] or pre-3.23 frm */
|
||||
if (use_mb(default_charset_info))
|
||||
if (use_mb(cs))
|
||||
{
|
||||
/* Warn that we may be changing the size of character columns */
|
||||
sql_print_warning("'%s' had no or invalid character set, "
|
||||
@ -1395,7 +1396,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||
"so character column sizes may have changed",
|
||||
share->path.str);
|
||||
}
|
||||
share->table_charset= default_charset_info;
|
||||
share->table_charset= cs;
|
||||
}
|
||||
|
||||
share->db_record_offset= 1;
|
||||
@ -2720,8 +2721,20 @@ static bool sql_unusable_for_discovery(THD *thd, handlerton *engine,
|
||||
if (create_info->data_file_name || create_info->index_file_name)
|
||||
return 1;
|
||||
// ... engine
|
||||
if (create_info->db_type && create_info->db_type != engine)
|
||||
return 1;
|
||||
DBUG_ASSERT(lex->m_sql_cmd);
|
||||
if (lex->create_info.used_fields & HA_CREATE_USED_ENGINE)
|
||||
{
|
||||
/*
|
||||
TODO: we could just compare engine names here, without resolving.
|
||||
But this optimization is too late for 10.1.
|
||||
*/
|
||||
Storage_engine_name *opt= lex->m_sql_cmd->option_storage_engine_name();
|
||||
DBUG_ASSERT(opt); // lex->m_sql_cmd must be an Sql_cmd_create_table instance
|
||||
if (opt->resolve_storage_engine_with_error(thd, &create_info->db_type,
|
||||
false) ||
|
||||
(create_info->db_type && create_info->db_type != engine))
|
||||
return 1;
|
||||
}
|
||||
// ... WITH SYSTEM VERSIONING
|
||||
if (create_info->versioned())
|
||||
return 1;
|
||||
|
@ -25,6 +25,24 @@
|
||||
#include "ha_blackhole.h"
|
||||
#include "sql_class.h" // THD, SYSTEM_THREAD_SLAVE_SQL
|
||||
|
||||
/**
|
||||
Checks if the param 'thd' is pointing to slave applier thread and row based
|
||||
replication is in use.
|
||||
|
||||
A row event will have its thd->query() == NULL except in cases where
|
||||
replicate_annotate_row_events is enabled. In the later case the thd->query()
|
||||
will be pointing to the query, received through replicated annotate event
|
||||
from master.
|
||||
|
||||
@param thd pointer to a THD instance
|
||||
|
||||
@return TRUE if thread is slave applier and row based replication is in use
|
||||
*/
|
||||
static bool is_row_based_replication(THD *thd)
|
||||
{
|
||||
return thd->system_thread == SYSTEM_THREAD_SLAVE_SQL &&
|
||||
(thd->query() == NULL || thd->variables.binlog_annotate_row_events);
|
||||
}
|
||||
/* Static declarations for handlerton */
|
||||
|
||||
static handler *blackhole_create_handler(handlerton *hton,
|
||||
@ -109,7 +127,7 @@ int ha_blackhole::update_row(const uchar *old_data, const uchar *new_data)
|
||||
{
|
||||
DBUG_ENTER("ha_blackhole::update_row");
|
||||
THD *thd= ha_thd();
|
||||
if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
|
||||
if (is_row_based_replication(thd))
|
||||
DBUG_RETURN(0);
|
||||
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
|
||||
}
|
||||
@ -118,7 +136,7 @@ int ha_blackhole::delete_row(const uchar *buf)
|
||||
{
|
||||
DBUG_ENTER("ha_blackhole::delete_row");
|
||||
THD *thd= ha_thd();
|
||||
if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
|
||||
if (is_row_based_replication(thd))
|
||||
DBUG_RETURN(0);
|
||||
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
|
||||
}
|
||||
@ -135,7 +153,7 @@ int ha_blackhole::rnd_next(uchar *buf)
|
||||
int rc;
|
||||
DBUG_ENTER("ha_blackhole::rnd_next");
|
||||
THD *thd= ha_thd();
|
||||
if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
|
||||
if (is_row_based_replication(thd))
|
||||
rc= 0;
|
||||
else
|
||||
rc= HA_ERR_END_OF_FILE;
|
||||
@ -220,7 +238,7 @@ int ha_blackhole::index_read_map(uchar * buf, const uchar * key,
|
||||
int rc;
|
||||
DBUG_ENTER("ha_blackhole::index_read");
|
||||
THD *thd= ha_thd();
|
||||
if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
|
||||
if (is_row_based_replication(thd))
|
||||
rc= 0;
|
||||
else
|
||||
rc= HA_ERR_END_OF_FILE;
|
||||
@ -235,7 +253,7 @@ int ha_blackhole::index_read_idx_map(uchar * buf, uint idx, const uchar * key,
|
||||
int rc;
|
||||
DBUG_ENTER("ha_blackhole::index_read_idx");
|
||||
THD *thd= ha_thd();
|
||||
if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
|
||||
if (is_row_based_replication(thd))
|
||||
rc= 0;
|
||||
else
|
||||
rc= HA_ERR_END_OF_FILE;
|
||||
@ -249,7 +267,7 @@ int ha_blackhole::index_read_last_map(uchar * buf, const uchar * key,
|
||||
int rc;
|
||||
DBUG_ENTER("ha_blackhole::index_read_last");
|
||||
THD *thd= ha_thd();
|
||||
if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL)
|
||||
if (is_row_based_replication(thd))
|
||||
rc= 0;
|
||||
else
|
||||
rc= HA_ERR_END_OF_FILE;
|
||||
|
10
storage/innobase/.clang-format
Normal file
10
storage/innobase/.clang-format
Normal file
@ -0,0 +1,10 @@
|
||||
UseTab: Always
|
||||
TabWidth: 8
|
||||
IndentWidth: 8
|
||||
BreakBeforeBinaryOperators: All
|
||||
PointerAlignment: Left
|
||||
AlwaysBreakAfterReturnType: TopLevel
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterFunction: true
|
||||
AccessModifierOffset: -8
|
@ -4850,6 +4850,23 @@ evict_from_pool:
|
||||
and block->lock. */
|
||||
buf_wait_for_read(fix_block);
|
||||
|
||||
if (fix_block->page.id != page_id) {
|
||||
|
||||
buf_block_unfix(fix_block);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (!fsp_is_system_temporary(page_id.space())) {
|
||||
rw_lock_s_unlock(&fix_block->debug_latch);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
if (err) {
|
||||
*err = DB_PAGE_CORRUPTED;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mtr_memo_type_t fix_type;
|
||||
|
||||
switch (rw_latch) {
|
||||
@ -5820,14 +5837,18 @@ buf_corrupt_page_release(buf_page_t* bpage, const fil_space_t* space)
|
||||
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
|
||||
const ibool uncompressed = (buf_page_get_state(bpage)
|
||||
== BUF_BLOCK_FILE_PAGE);
|
||||
page_id_t old_page_id = bpage->id;
|
||||
|
||||
/* First unfix and release lock on the bpage */
|
||||
buf_pool_mutex_enter(buf_pool);
|
||||
mutex_enter(buf_page_get_mutex(bpage));
|
||||
ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ);
|
||||
ut_ad(bpage->buf_fix_count == 0);
|
||||
ut_ad(bpage->id.space() == space->id);
|
||||
|
||||
/* buf_fix_count can be greater than zero. Because other thread
|
||||
can wait in buf_page_wait_read() for the page to be read. */
|
||||
|
||||
bpage->id.set_corrupt_id();
|
||||
/* Set BUF_IO_NONE before we remove the block from LRU list */
|
||||
buf_page_set_io_fix(bpage, BUF_IO_NONE);
|
||||
|
||||
@ -5844,7 +5865,7 @@ buf_corrupt_page_release(buf_page_t* bpage, const fil_space_t* space)
|
||||
}
|
||||
|
||||
/* After this point bpage can't be referenced. */
|
||||
buf_LRU_free_one_page(bpage);
|
||||
buf_LRU_free_one_page(bpage, old_page_id);
|
||||
|
||||
ut_ad(buf_pool->n_pend_reads > 0);
|
||||
buf_pool->n_pend_reads--;
|
||||
|
@ -2165,25 +2165,31 @@ buf_LRU_block_free_hashed_page(
|
||||
buf_page_mutex_exit(block);
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Remove one page from LRU list and put it to free list */
|
||||
void
|
||||
buf_LRU_free_one_page(
|
||||
/*==================*/
|
||||
buf_page_t* bpage) /*!< in/out: block, must contain a file page and
|
||||
be in a state where it can be freed; there
|
||||
may or may not be a hash index to the page */
|
||||
/** Remove one page from LRU list and put it to free list.
|
||||
@param[in,out] bpage block, must contain a file page and be in
|
||||
a freeable state; there may or may not be a
|
||||
hash index to the page
|
||||
@param[in] old_page_id page number before bpage->id was invalidated */
|
||||
void buf_LRU_free_one_page(buf_page_t* bpage, page_id_t old_page_id)
|
||||
{
|
||||
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
|
||||
|
||||
rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool, bpage->id);
|
||||
rw_lock_t* hash_lock = buf_page_hash_lock_get(buf_pool,
|
||||
old_page_id);
|
||||
BPageMutex* block_mutex = buf_page_get_mutex(bpage);
|
||||
|
||||
ut_ad(buf_pool_mutex_own(buf_pool));
|
||||
|
||||
rw_lock_x_lock(hash_lock);
|
||||
|
||||
while (buf_block_get_fix(bpage) > 0) {
|
||||
/* Wait for other threads to release the fix count
|
||||
before releasing the bpage from LRU list. */
|
||||
}
|
||||
|
||||
mutex_enter(block_mutex);
|
||||
|
||||
bpage->id = old_page_id;
|
||||
|
||||
if (buf_LRU_block_remove_hashed(bpage, true)) {
|
||||
buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
|
||||
}
|
||||
|
@ -63,13 +63,14 @@ buf_read_page_handle_error(
|
||||
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
|
||||
const bool uncompressed = (buf_page_get_state(bpage)
|
||||
== BUF_BLOCK_FILE_PAGE);
|
||||
const page_id_t old_page_id = bpage->id;
|
||||
|
||||
/* First unfix and release lock on the bpage */
|
||||
buf_pool_mutex_enter(buf_pool);
|
||||
mutex_enter(buf_page_get_mutex(bpage));
|
||||
ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ);
|
||||
ut_ad(bpage->buf_fix_count == 0);
|
||||
|
||||
bpage->id.set_corrupt_id();
|
||||
/* Set BUF_IO_NONE before we remove the block from LRU list */
|
||||
buf_page_set_io_fix(bpage, BUF_IO_NONE);
|
||||
|
||||
@ -82,7 +83,7 @@ buf_read_page_handle_error(
|
||||
mutex_exit(buf_page_get_mutex(bpage));
|
||||
|
||||
/* remove the block from LRU list */
|
||||
buf_LRU_free_one_page(bpage);
|
||||
buf_LRU_free_one_page(bpage, old_page_id);
|
||||
|
||||
ut_ad(buf_pool->n_pend_reads > 0);
|
||||
buf_pool->n_pend_reads--;
|
||||
|
@ -21032,7 +21032,6 @@ ib_senderrf(
|
||||
...) /*!< Args */
|
||||
{
|
||||
va_list args;
|
||||
char* str = NULL;
|
||||
const char* format = my_get_err_msg(code);
|
||||
|
||||
/* If the caller wants to push a message to the client then
|
||||
@ -21045,7 +21044,7 @@ ib_senderrf(
|
||||
|
||||
va_start(args, code);
|
||||
|
||||
myf l = Sql_condition::WARN_LEVEL_NOTE;
|
||||
myf l;
|
||||
|
||||
switch (level) {
|
||||
case IB_LOG_LEVEL_INFO:
|
||||
@ -21054,14 +21053,6 @@ ib_senderrf(
|
||||
case IB_LOG_LEVEL_WARN:
|
||||
l = ME_JUST_WARNING;
|
||||
break;
|
||||
case IB_LOG_LEVEL_ERROR:
|
||||
sd_notifyf(0, "STATUS=InnoDB: Error: %s", str);
|
||||
l = 0;
|
||||
break;
|
||||
case IB_LOG_LEVEL_FATAL:
|
||||
l = 0;
|
||||
sd_notifyf(0, "STATUS=InnoDB: Fatal: %s", str);
|
||||
break;
|
||||
default:
|
||||
l = 0;
|
||||
break;
|
||||
@ -21070,7 +21061,6 @@ ib_senderrf(
|
||||
my_printv_error(code, format, MYF(l), args);
|
||||
|
||||
va_end(args);
|
||||
free(str);
|
||||
|
||||
if (level == IB_LOG_LEVEL_FATAL) {
|
||||
ut_error;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2013, 2018, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2019, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
@ -609,31 +609,27 @@ buf_block_buf_fix_inc_func(
|
||||
@return the count */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_block_fix(
|
||||
buf_page_t* bpage);
|
||||
buf_block_fix(buf_page_t* bpage);
|
||||
|
||||
/** Increments the bufferfix count.
|
||||
@param[in,out] block block to bufferfix
|
||||
@return the count */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_block_fix(
|
||||
buf_block_t* block);
|
||||
buf_block_fix(buf_block_t* block);
|
||||
|
||||
/** Decrements the bufferfix count.
|
||||
@param[in,out] bpage block to bufferunfix
|
||||
@return the remaining buffer-fix count */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_block_unfix(
|
||||
buf_page_t* bpage);
|
||||
buf_block_unfix(buf_page_t* bpage);
|
||||
/** Decrements the bufferfix count.
|
||||
@param[in,out] block block to bufferunfix
|
||||
@return the remaining buffer-fix count */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_block_unfix(
|
||||
buf_block_t* block);
|
||||
buf_block_unfix(buf_block_t* block);
|
||||
|
||||
# ifdef UNIV_DEBUG
|
||||
/** Increments the bufferfix count.
|
||||
@ -1435,7 +1431,7 @@ public:
|
||||
page_size_t size;
|
||||
|
||||
/** Count of how manyfold this block is currently bufferfixed. */
|
||||
ib_uint32_t buf_fix_count;
|
||||
int32 buf_fix_count;
|
||||
|
||||
/** type of pending I/O operation; also protected by
|
||||
buf_pool->mutex for writes only */
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2008, Google Inc.
|
||||
Copyright (c) 2014, 2018, MariaDB Corporation.
|
||||
Copyright (c) 2014, 2019, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
@ -950,10 +950,11 @@ buf_block_get_modify_clock(
|
||||
@return the count */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_block_fix(
|
||||
buf_page_t* bpage)
|
||||
buf_block_fix(buf_page_t* bpage)
|
||||
{
|
||||
return uint32(my_atomic_add32((int32*) &bpage->buf_fix_count, 1) + 1);
|
||||
return uint32(my_atomic_add32_explicit(
|
||||
&bpage->buf_fix_count, 1,
|
||||
MY_MEMORY_ORDER_RELAXED)) + 1;
|
||||
}
|
||||
|
||||
/** Increments the bufferfix count.
|
||||
@ -961,10 +962,30 @@ buf_block_fix(
|
||||
@return the count */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_block_fix(
|
||||
buf_block_t* block)
|
||||
buf_block_fix(buf_block_t* block)
|
||||
{
|
||||
return(buf_block_fix(&block->page));
|
||||
return buf_block_fix(&block->page);
|
||||
}
|
||||
|
||||
/** Get the bufferfix count.
|
||||
@param[in] bpage block to bufferfix
|
||||
@return the count */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_block_get_fix(buf_page_t* bpage)
|
||||
{
|
||||
return my_atomic_load32_explicit(&bpage->buf_fix_count,
|
||||
MY_MEMORY_ORDER_RELAXED);
|
||||
}
|
||||
|
||||
/** Get the bufferfix count.
|
||||
@param[in] bpage block to bufferfix
|
||||
@return the count */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_block_get_fix(buf_block_t* block)
|
||||
{
|
||||
return buf_block_get_fix(&block->page);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
@ -998,11 +1019,11 @@ buf_block_buf_fix_inc_func(
|
||||
@return the remaining buffer-fix count */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_block_unfix(
|
||||
buf_page_t* bpage)
|
||||
buf_block_unfix(buf_page_t* bpage)
|
||||
{
|
||||
uint32 count = uint32(my_atomic_add32((int32*) &bpage->buf_fix_count,
|
||||
-1));
|
||||
uint32 count = uint32(my_atomic_add32_explicit(
|
||||
&bpage->buf_fix_count,
|
||||
-1, MY_MEMORY_ORDER_RELAXED));
|
||||
ut_ad(count != 0);
|
||||
return count - 1;
|
||||
}
|
||||
@ -1012,10 +1033,9 @@ buf_block_unfix(
|
||||
@return the remaining buffer-fix count */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
buf_block_unfix(
|
||||
buf_block_t* block)
|
||||
buf_block_unfix(buf_block_t* block)
|
||||
{
|
||||
return(buf_block_unfix(&block->page));
|
||||
return buf_block_unfix(&block->page);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
|
@ -202,14 +202,12 @@ void
|
||||
buf_LRU_stat_update(void);
|
||||
/*=====================*/
|
||||
|
||||
/******************************************************************//**
|
||||
Remove one page from LRU list and put it to free list */
|
||||
void
|
||||
buf_LRU_free_one_page(
|
||||
/*==================*/
|
||||
buf_page_t* bpage) /*!< in/out: block, must contain a file page and
|
||||
be in a state where it can be freed; there
|
||||
may or may not be a hash index to the page */
|
||||
/** Remove one page from LRU list and put it to free list.
|
||||
@param[in,out] bpage block, must contain a file page and be in
|
||||
a freeable state; there may or may not be a
|
||||
hash index to the page
|
||||
@param[in] old_page_id page number before bpage->id was invalidated */
|
||||
void buf_LRU_free_one_page(buf_page_t* bpage, page_id_t old_page_id)
|
||||
MY_ATTRIBUTE((nonnull));
|
||||
|
||||
/******************************************************************//**
|
||||
|
@ -175,6 +175,12 @@ public:
|
||||
ut_ad(page_no <= 0xFFFFFFFFU);
|
||||
}
|
||||
|
||||
/** Set the FIL_NULL for the space and page_no */
|
||||
void set_corrupt_id()
|
||||
{
|
||||
m_space = m_page_no = ULINT32_UNDEFINED;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Tablespace id. */
|
||||
|
@ -1033,9 +1033,12 @@ row_search_on_row_ref(
|
||||
if (UNIV_UNLIKELY(ref->info_bits != 0)) {
|
||||
ut_ad(ref->info_bits == REC_INFO_METADATA);
|
||||
ut_ad(ref->n_fields <= index->n_uniq);
|
||||
btr_pcur_open_at_index_side(true, index, mode, pcur, true, 0,
|
||||
mtr);
|
||||
btr_pcur_move_to_next_user_rec(pcur, mtr);
|
||||
if (btr_pcur_open_at_index_side(
|
||||
true, index, mode, pcur, true, 0, mtr)
|
||||
!= DB_SUCCESS
|
||||
|| !btr_pcur_move_to_next_user_rec(pcur, mtr)) {
|
||||
return FALSE;
|
||||
}
|
||||
/* We do not necessarily have index->is_instant() here,
|
||||
because we could be executing a rollback of an
|
||||
instant ADD COLUMN operation. The function
|
||||
@ -1046,7 +1049,10 @@ row_search_on_row_ref(
|
||||
& REC_INFO_MIN_REC_FLAG;
|
||||
} else {
|
||||
ut_a(ref->n_fields == index->n_uniq);
|
||||
btr_pcur_open(index, ref, PAGE_CUR_LE, mode, pcur, mtr);
|
||||
if (btr_pcur_open(index, ref, PAGE_CUR_LE, mode, pcur, mtr)
|
||||
!= DB_SUCCESS) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
low_match = btr_pcur_get_low_match(pcur);
|
||||
|
@ -668,12 +668,8 @@ int toku_logger_find_logfiles (const char *directory, char ***resultp, int *n_lo
|
||||
snprintf(fname, fnamelen, "%s/%s", directory, de->d_name);
|
||||
result[n_results++] = fname;
|
||||
}
|
||||
// Return them in increasing order. Set width to allow for newer log file names ("xxx.tokulog13")
|
||||
// which are one character longer than old log file names ("xxx.tokulog2"). The comparison function
|
||||
// won't look beyond the terminating NUL, so an extra character in the comparison string doesn't matter.
|
||||
// Allow room for terminating NUL after "xxx.tokulog13" even if result[0] is of form "xxx.tokulog2."
|
||||
int width = sizeof(result[0]+2);
|
||||
qsort(result, n_results, width, logfilenamecompare);
|
||||
// Return them in increasing order.
|
||||
qsort(result, n_results, sizeof(result[0]), logfilenamecompare);
|
||||
*resultp = result;
|
||||
*n_logfiles = n_results;
|
||||
result[n_results]=0; // make a trailing null
|
||||
|
Loading…
x
Reference in New Issue
Block a user