Merge branch '10.2' into 10.3

This commit is contained in:
Oleksandr Byelkin 2019-06-14 07:36:47 +02:00
commit 4a3d51c76c
83 changed files with 2196 additions and 2611 deletions

18
.clang-format Normal file
View 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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1 @@
--character-set-server=utf8

View 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
#

View 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 #

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +0,0 @@
--innodb-tablespaces-encryption
--innodb-encrypt-tables=off
--innodb-encryption-threads=0

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View 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

View File

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

View File

@ -0,0 +1 @@
--binlog_annotate_row_events --timezone=GMT-3

View File

@ -0,0 +1 @@
--binlog_annotate_row_events --replicate_annotate_row_events

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
}
/*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,10 @@
UseTab: Always
TabWidth: 8
IndentWidth: 8
BreakBeforeBinaryOperators: All
PointerAlignment: Left
AlwaysBreakAfterReturnType: TopLevel
BreakBeforeBraces: Custom
BraceWrapping:
AfterFunction: true
AccessModifierOffset: -8

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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. */

View File

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

View File

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