diff options
50 files changed, 1383 insertions, 335 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 715c5f69062..7d759fb744a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (c) 2006, 2017, Oracle and/or its affiliates. -# Copyright (c) 2008, 2018, MariaDB Corporation +# Copyright (c) 2008, 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 @@ -224,6 +224,11 @@ IF (WITH_UBSAN) MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=undefined -fno-sanitize=alignment -U_FORTIFY_SOURCE" DEBUG RELWITHDEBINFO) ENDIF() +OPTION(WITH_MSAN "Enable memory sanitizer" OFF) +IF (WITH_MSAN) + MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=memory -fsanitize-memory-track-origins -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 diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 52759f8583f..696872ee32c 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, MariaDB + Copyright (c) 2009, 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 @@ -1694,6 +1694,7 @@ void abort_not_supported_test(const char *fmt, ...) cur_file->file_name, cur_file->lineno); char buff[DIE_BUFF_SIZE]; + buff[0] = '\0'; print_file_stack(buff, buff + sizeof(buff)); fprintf(stderr, "%s", buff); diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index 076e656cf78..5a1e8f81f0a 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -1,6 +1,6 @@ # Copyright (c) 2009, 2018, Oracle and/or its affiliates. -# Copyright (c) 2011, 2019, MariaDB Corporation -# +# Copyright (c) 2011, 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 Foundation; version 2 of the License. @@ -12,7 +12,7 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA INCLUDE(CMakeParseArguments) @@ -209,7 +209,7 @@ MACRO(MYSQL_ADD_PLUGIN) ELSEIF(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") TARGET_LINK_LIBRARIES (${target} mysqld) ENDIF() - ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT WITH_ASAN AND NOT WITH_TSAN AND NOT WITH_UBSAN) + ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT WITH_ASAN AND NOT WITH_TSAN AND NOT WITH_UBSAN AND NOT WITH_MSAN) TARGET_LINK_LIBRARIES (${target} "-Wl,--no-undefined") ENDIF() diff --git a/libmariadb b/libmariadb -Subproject ed3a91c139175746c5d6903d67ca902d91228f6 +Subproject dc271e5a1b9d4074e2086b776a668b6b5614f2b diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc index 9b544a25178..4d0d1e2a3a0 100644 --- a/mysql-test/lib/My/SafeProcess/safe_process.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process.cc @@ -1,4 +1,5 @@ /* Copyright (c) 2008, 2012, Oracle and/or its affiliates + Copyright (c) 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 @@ -219,6 +220,7 @@ int main(int argc, char* const argv[] ) sigemptyset(&sa.sa_mask); sa_abort.sa_handler= handle_abort; + sa_abort.sa_flags= 0; sigemptyset(&sa_abort.sa_mask); /* Install signal handlers */ sigaction(SIGTERM, &sa,NULL); diff --git a/mysql-test/main/join.result b/mysql-test/main/join.result index 098a8bbad9d..fb4f35ed555 100644 --- a/mysql-test/main/join.result +++ b/mysql-test/main/join.result @@ -2929,6 +2929,332 @@ NULL NULL NULL 9 NULL NULL NULL 5 drop table t1,t2,t3,t4,s1,s2; # +# MDEV-20265: Mix of comma joins with JOIN expressions +# (correction of the fix for MDEV-19421) +# MDEV-20330: duplicate +# +create table t1 (a int); +insert into t1 values (7), (5), (3); +create table t2 (a int); +insert into t2 values (5), (1), (7); +create table t3 (a int); +insert into t3 values (2), (7), (3); +create table t4 (a int); +insert into t4 values (4), (7), (9), (5); +create table t5 (a int); +insert into t5 values (3), (7), (9), (2); +explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a +from t1, t2 join t3 left join t4 on t3.a=t4.a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (incremental, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a` from `test`.`t1` join `test`.`t2` join `test`.`t3` left join `test`.`t4` on(`test`.`t4`.`a` = `test`.`t3`.`a`) where 1 +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a +from t1, t2 join t3 left join t4 on t3.a=t4.a; +t1_a t2_a t3_a t4_a +7 5 7 7 +5 5 7 7 +3 5 7 7 +7 1 7 7 +5 1 7 7 +3 1 7 7 +7 7 7 7 +5 7 7 7 +3 7 7 7 +7 5 2 NULL +5 5 2 NULL +3 5 2 NULL +7 1 2 NULL +5 1 2 NULL +3 1 2 NULL +7 7 2 NULL +5 7 2 NULL +3 7 2 NULL +7 5 3 NULL +5 5 3 NULL +3 5 3 NULL +7 1 3 NULL +5 1 3 NULL +3 1 3 NULL +7 7 3 NULL +5 7 3 NULL +3 7 3 NULL +explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a +from t1, t2 join t3 right join t4 on t3.a=t4.a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a` from `test`.`t1` join `test`.`t4` left join (`test`.`t2` join `test`.`t3`) on(`test`.`t3`.`a` = `test`.`t4`.`a`) where 1 +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a +from t1, t2 join t3 right join t4 on t3.a=t4.a; +t1_a t2_a t3_a t4_a +7 5 7 7 +5 5 7 7 +3 5 7 7 +7 1 7 7 +5 1 7 7 +3 1 7 7 +7 7 7 7 +5 7 7 7 +3 7 7 7 +7 NULL NULL 4 +5 NULL NULL 4 +3 NULL NULL 4 +7 NULL NULL 9 +5 NULL NULL 9 +3 NULL NULL 9 +7 NULL NULL 5 +5 NULL NULL 5 +3 NULL NULL 5 +explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1, t2 join t3 join t4 left join t5 on t4.a=t5.a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (incremental, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a`,`test`.`t5`.`a` AS `t5_a` from `test`.`t1` join `test`.`t2` join `test`.`t3` join `test`.`t4` left join `test`.`t5` on(`test`.`t5`.`a` = `test`.`t4`.`a`) where 1 +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1, t2 join t3 join t4 left join t5 on t4.a=t5.a; +t1_a t2_a t3_a t4_a t5_a +7 5 2 7 7 +5 5 2 7 7 +3 5 2 7 7 +7 1 2 7 7 +5 1 2 7 7 +3 1 2 7 7 +7 7 2 7 7 +5 7 2 7 7 +3 7 2 7 7 +7 5 7 7 7 +5 5 7 7 7 +3 5 7 7 7 +7 1 7 7 7 +5 1 7 7 7 +3 1 7 7 7 +7 7 7 7 7 +5 7 7 7 7 +3 7 7 7 7 +7 5 3 7 7 +5 5 3 7 7 +3 5 3 7 7 +7 1 3 7 7 +5 1 3 7 7 +3 1 3 7 7 +7 7 3 7 7 +5 7 3 7 7 +3 7 3 7 7 +7 5 2 9 9 +5 5 2 9 9 +3 5 2 9 9 +7 1 2 9 9 +5 1 2 9 9 +3 1 2 9 9 +7 7 2 9 9 +5 7 2 9 9 +3 7 2 9 9 +7 5 7 9 9 +5 5 7 9 9 +3 5 7 9 9 +7 1 7 9 9 +5 1 7 9 9 +3 1 7 9 9 +7 7 7 9 9 +5 7 7 9 9 +3 7 7 9 9 +7 5 3 9 9 +5 5 3 9 9 +3 5 3 9 9 +7 1 3 9 9 +5 1 3 9 9 +3 1 3 9 9 +7 7 3 9 9 +5 7 3 9 9 +3 7 3 9 9 +7 5 2 4 NULL +5 5 2 4 NULL +3 5 2 4 NULL +7 1 2 4 NULL +5 1 2 4 NULL +3 1 2 4 NULL +7 7 2 4 NULL +5 7 2 4 NULL +3 7 2 4 NULL +7 5 7 4 NULL +5 5 7 4 NULL +3 5 7 4 NULL +7 1 7 4 NULL +5 1 7 4 NULL +3 1 7 4 NULL +7 7 7 4 NULL +5 7 7 4 NULL +3 7 7 4 NULL +7 5 3 4 NULL +5 5 3 4 NULL +3 5 3 4 NULL +7 1 3 4 NULL +5 1 3 4 NULL +3 1 3 4 NULL +7 7 3 4 NULL +5 7 3 4 NULL +3 7 3 4 NULL +7 5 2 5 NULL +5 5 2 5 NULL +3 5 2 5 NULL +7 1 2 5 NULL +5 1 2 5 NULL +3 1 2 5 NULL +7 7 2 5 NULL +5 7 2 5 NULL +3 7 2 5 NULL +7 5 7 5 NULL +5 5 7 5 NULL +3 5 7 5 NULL +7 1 7 5 NULL +5 1 7 5 NULL +3 1 7 5 NULL +7 7 7 5 NULL +5 7 7 5 NULL +3 7 7 5 NULL +7 5 3 5 NULL +5 5 3 5 NULL +3 5 3 5 NULL +7 1 3 5 NULL +5 1 3 5 NULL +3 1 3 5 NULL +7 7 3 5 NULL +5 7 3 5 NULL +3 7 3 5 NULL +explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1, t2 join t3 join t4 right join t5 on t4.a=t5.a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (incremental, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a`,`test`.`t5`.`a` AS `t5_a` from `test`.`t1` join `test`.`t5` left join (`test`.`t2` join `test`.`t3` join `test`.`t4`) on(`test`.`t4`.`a` = `test`.`t5`.`a`) where 1 +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1, t2 join t3 join t4 right join t5 on t4.a=t5.a; +t1_a t2_a t3_a t4_a t5_a +7 5 2 7 7 +5 5 2 7 7 +3 5 2 7 7 +7 1 2 7 7 +5 1 2 7 7 +3 1 2 7 7 +7 7 2 7 7 +5 7 2 7 7 +3 7 2 7 7 +7 5 7 7 7 +5 5 7 7 7 +3 5 7 7 7 +7 1 7 7 7 +5 1 7 7 7 +3 1 7 7 7 +7 7 7 7 7 +5 7 7 7 7 +3 7 7 7 7 +7 5 3 7 7 +5 5 3 7 7 +3 5 3 7 7 +7 1 3 7 7 +5 1 3 7 7 +3 1 3 7 7 +7 7 3 7 7 +5 7 3 7 7 +3 7 3 7 7 +7 5 2 9 9 +5 5 2 9 9 +3 5 2 9 9 +7 1 2 9 9 +5 1 2 9 9 +3 1 2 9 9 +7 7 2 9 9 +5 7 2 9 9 +3 7 2 9 9 +7 5 7 9 9 +5 5 7 9 9 +3 5 7 9 9 +7 1 7 9 9 +5 1 7 9 9 +3 1 7 9 9 +7 7 7 9 9 +5 7 7 9 9 +3 7 7 9 9 +7 5 3 9 9 +5 5 3 9 9 +3 5 3 9 9 +7 1 3 9 9 +5 1 3 9 9 +3 1 3 9 9 +7 7 3 9 9 +5 7 3 9 9 +3 7 3 9 9 +7 NULL NULL NULL 3 +5 NULL NULL NULL 3 +3 NULL NULL NULL 3 +7 NULL NULL NULL 2 +5 NULL NULL NULL 2 +3 NULL NULL NULL 2 +explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1 left join t2 on t1.a=t2.a, t3 join t4 right join t5 on t4.a=t5.a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) +1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (incremental, BNL join) +Warnings: +Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a`,`test`.`t5`.`a` AS `t5_a` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`a` = `test`.`t1`.`a`) join `test`.`t5` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t4`.`a` = `test`.`t5`.`a`) where 1 +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1 left join t2 on t1.a=t2.a, t3 join t4 right join t5 on t4.a=t5.a; +t1_a t2_a t3_a t4_a t5_a +5 5 2 7 7 +7 7 2 7 7 +3 NULL 2 7 7 +5 5 7 7 7 +7 7 7 7 7 +3 NULL 7 7 7 +5 5 3 7 7 +7 7 3 7 7 +3 NULL 3 7 7 +5 5 2 9 9 +7 7 2 9 9 +3 NULL 2 9 9 +5 5 7 9 9 +7 7 7 9 9 +3 NULL 7 9 9 +5 5 3 9 9 +7 7 3 9 9 +3 NULL 3 9 9 +5 5 NULL NULL 3 +7 7 NULL NULL 3 +3 NULL NULL NULL 3 +5 5 NULL NULL 2 +7 7 NULL NULL 2 +3 NULL NULL NULL 2 +drop table t1,t2,t3,t4,t5; +select a.a +from (select 1 as a) a, +(select 2 as b) b +cross join +(select 3 as c) c +left join +(select 4 as d) d +on 1; +a +1 +# # End of MariaDB 5.5 tests # # diff --git a/mysql-test/main/join.test b/mysql-test/main/join.test index 9ecf97e0a0e..a2ad01639ec 100644 --- a/mysql-test/main/join.test +++ b/mysql-test/main/join.test @@ -1614,6 +1614,65 @@ eval $q; drop table t1,t2,t3,t4,s1,s2; --echo # +--echo # MDEV-20265: Mix of comma joins with JOIN expressions +--echo # (correction of the fix for MDEV-19421) +--echo # MDEV-20330: duplicate +--echo # + +create table t1 (a int); +insert into t1 values (7), (5), (3); +create table t2 (a int); +insert into t2 values (5), (1), (7); +create table t3 (a int); +insert into t3 values (2), (7), (3); +create table t4 (a int); +insert into t4 values (4), (7), (9), (5); +create table t5 (a int); +insert into t5 values (3), (7), (9), (2); + + +let $q= +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a +from t1, t2 join t3 left join t4 on t3.a=t4.a; +eval explain extended $q; +eval $q; + +let $q= +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a +from t1, t2 join t3 right join t4 on t3.a=t4.a; +eval explain extended $q; +eval $q; + +let $q= +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1, t2 join t3 join t4 left join t5 on t4.a=t5.a; +eval explain extended $q; +eval $q; + +let $q= +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1, t2 join t3 join t4 right join t5 on t4.a=t5.a; +eval explain extended $q; +eval $q; + +let $q= +select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a +from t1 left join t2 on t1.a=t2.a, t3 join t4 right join t5 on t4.a=t5.a; +eval explain extended $q; +eval $q; + +drop table t1,t2,t3,t4,t5; + +select a.a +from (select 1 as a) a, + (select 2 as b) b + cross join + (select 3 as c) c + left join + (select 4 as d) d + on 1; + +--echo # --echo # End of MariaDB 5.5 tests --echo # diff --git a/mysql-test/main/mysql_tzinfo_to_sql_symlink.result b/mysql-test/main/mysql_tzinfo_to_sql_symlink.result index 03543244105..e33a519e897 100644 --- a/mysql-test/main/mysql_tzinfo_to_sql_symlink.result +++ b/mysql-test/main/mysql_tzinfo_to_sql_symlink.result @@ -2,9 +2,15 @@ # MDEV-5226 mysql_tzinfo_to_sql errors with tzdata 2013f and above # # Verbose run -set @prep=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET GLOBAL wsrep_replicate_myisam=?', 'do ?'); -prepare set_wsrep_myisam from @prep; -set @toggle=1; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=InnoDB; +ALTER TABLE time_zone_name ENGINE=InnoDB; +ALTER TABLE time_zone_transition ENGINE=InnoDB; +ALTER TABLE time_zone_transition_type ENGINE=InnoDB; +END IF| +\d ; TRUNCATE TABLE time_zone; TRUNCATE TABLE time_zone_name; TRUNCATE TABLE time_zone_transition; @@ -28,11 +34,25 @@ Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/ignored.tab' as time zo Warning: Skipping directory 'MYSQLTEST_VARDIR/zoneinfo/posix/posix': to avoid infinite symlink recursion. ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time; ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id; -set @toggle=0; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=MyISAM; +ALTER TABLE time_zone_name ENGINE=MyISAM; +ALTER TABLE time_zone_transition ENGINE=MyISAM; +ALTER TABLE time_zone_transition_type ENGINE=MyISAM; +END IF| +\d ; # Silent run -set @prep=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET GLOBAL wsrep_replicate_myisam=?', 'do ?'); -prepare set_wsrep_myisam from @prep; -set @toggle=1; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=InnoDB; +ALTER TABLE time_zone_name ENGINE=InnoDB; +ALTER TABLE time_zone_transition ENGINE=InnoDB; +ALTER TABLE time_zone_transition_type ENGINE=InnoDB; +END IF| +\d ; TRUNCATE TABLE time_zone; TRUNCATE TABLE time_zone_name; TRUNCATE TABLE time_zone_transition; @@ -53,39 +73,83 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset, Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it. ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time; ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id; -set @toggle=0; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=MyISAM; +ALTER TABLE time_zone_name ENGINE=MyISAM; +ALTER TABLE time_zone_transition ENGINE=MyISAM; +ALTER TABLE time_zone_transition_type ENGINE=MyISAM; +END IF| +\d ; # # Testing with explicit timezonefile # -set @prep=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET GLOBAL wsrep_replicate_myisam=?', 'do ?'); -prepare set_wsrep_myisam from @prep; -set @toggle=1; execute set_wsrep_myisam using @toggle; INSERT INTO time_zone (Use_leap_seconds) VALUES ('N'); SET @time_zone_id= LAST_INSERT_ID(); INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('XXX', @time_zone_id); INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset, Is_DST, Abbreviation) VALUES (@time_zone_id, 0, 0, 0, 'GMT') ; -set @toggle=0; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=MyISAM; +ALTER TABLE time_zone_name ENGINE=MyISAM; +ALTER TABLE time_zone_transition ENGINE=MyISAM; +ALTER TABLE time_zone_transition_type ENGINE=MyISAM; +END IF| +\d ; # # Testing --leap # -set @prep=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET GLOBAL wsrep_replicate_myisam=?', 'do ?'); -prepare set_wsrep_myisam from @prep; -set @toggle=1; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone_leap_second ENGINE=InnoDB; +END IF| +\d ; TRUNCATE TABLE time_zone_leap_second; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone_leap_second ENGINE=MyISAM; +END IF| +\d ; ALTER TABLE time_zone_leap_second ORDER BY Transition_time; -set @toggle=0; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=MyISAM; +ALTER TABLE time_zone_name ENGINE=MyISAM; +ALTER TABLE time_zone_transition ENGINE=MyISAM; +ALTER TABLE time_zone_transition_type ENGINE=MyISAM; +END IF| +\d ; # # MDEV-6236 - [PATCH] mysql_tzinfo_to_sql may produce invalid SQL # -set @prep=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET GLOBAL wsrep_replicate_myisam=?', 'do ?'); -prepare set_wsrep_myisam from @prep; -set @toggle=1; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=InnoDB; +ALTER TABLE time_zone_name ENGINE=InnoDB; +ALTER TABLE time_zone_transition ENGINE=InnoDB; +ALTER TABLE time_zone_transition_type ENGINE=InnoDB; +END IF| +\d ; TRUNCATE TABLE time_zone; TRUNCATE TABLE time_zone_name; TRUNCATE TABLE time_zone_transition; TRUNCATE TABLE time_zone_transition_type; ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time; ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id; -set @toggle=0; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=MyISAM; +ALTER TABLE time_zone_name ENGINE=MyISAM; +ALTER TABLE time_zone_transition ENGINE=MyISAM; +ALTER TABLE time_zone_transition_type ENGINE=MyISAM; +END IF| +\d ; diff --git a/mysql-test/main/selectivity.result b/mysql-test/main/selectivity.result index cacef6239ff..cf340b04660 100644 --- a/mysql-test/main/selectivity.result +++ b/mysql-test/main/selectivity.result @@ -1635,3 +1635,37 @@ set @@use_stat_tables= @save_use_stat_tables; set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; drop table t1; drop function f1; +# +# MDEV-19834 Selectivity of an equality condition discounted twice +# +set @@optimizer_use_condition_selectivity=4; +set @@use_stat_tables='preferably'; +create table t1 (a int, b int, key (b), key (a)); +insert into t1 +select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000; +analyze table t1 ; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +# Check what info the optimizer has about selectivities +explain extended select * from t1 use index () where a in (17,51,5); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 2.97 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where `test`.`t1`.`a` in (17,51,5) +explain extended select * from t1 use index () where b=2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 4.76 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where `test`.`t1`.`b` = 2 +# Now, the equality is used for ref access, while the range condition +# gives selectivity data +explain extended select * from t1 where a in (17,51,5) and b=2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ref b,a b 5 const 58 2.90 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` in (17,51,5) +drop table t1; +set use_stat_tables= @save_use_stat_tables; +set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +# End of 10.1 tests diff --git a/mysql-test/main/selectivity.test b/mysql-test/main/selectivity.test index 3df49456332..f1c9d6b31b8 100644 --- a/mysql-test/main/selectivity.test +++ b/mysql-test/main/selectivity.test @@ -1,4 +1,5 @@ --source include/have_stat_tables.inc +--source include/have_sequence.inc --disable_warnings drop table if exists t0,t1,t2,t3; @@ -1102,3 +1103,26 @@ set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectiv drop table t1; drop function f1; +--echo # +--echo # MDEV-19834 Selectivity of an equality condition discounted twice +--echo # +set @@optimizer_use_condition_selectivity=4; +set @@use_stat_tables='preferably'; +create table t1 (a int, b int, key (b), key (a)); +insert into t1 +select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000; +analyze table t1 ; + +--echo # Check what info the optimizer has about selectivities +explain extended select * from t1 use index () where a in (17,51,5); +explain extended select * from t1 use index () where b=2; + +--echo # Now, the equality is used for ref access, while the range condition +--echo # gives selectivity data +explain extended select * from t1 where a in (17,51,5) and b=2; +drop table t1; + +set use_stat_tables= @save_use_stat_tables; +set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +--echo # End of 10.1 tests + diff --git a/mysql-test/main/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result index afe2571006f..f2fdd3f8381 100644 --- a/mysql-test/main/selectivity_innodb.result +++ b/mysql-test/main/selectivity_innodb.result @@ -1645,6 +1645,40 @@ set @@use_stat_tables= @save_use_stat_tables; set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; drop table t1; drop function f1; +# +# MDEV-19834 Selectivity of an equality condition discounted twice +# +set @@optimizer_use_condition_selectivity=4; +set @@use_stat_tables='preferably'; +create table t1 (a int, b int, key (b), key (a)); +insert into t1 +select (rand(1)*1000)/10, (rand(1001)*1000)/50 from seq_1_to_1000; +analyze table t1 ; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +# Check what info the optimizer has about selectivities +explain extended select * from t1 use index () where a in (17,51,5); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 2.97 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where `test`.`t1`.`a` in (17,51,5) +explain extended select * from t1 use index () where b=2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 4.76 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` USE INDEX () where `test`.`t1`.`b` = 2 +# Now, the equality is used for ref access, while the range condition +# gives selectivity data +explain extended select * from t1 where a in (17,51,5) and b=2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ref b,a b 5 const 59 2.90 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`b` = 2 and `test`.`t1`.`a` in (17,51,5) +drop table t1; +set use_stat_tables= @save_use_stat_tables; +set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +# End of 10.1 tests set optimizer_switch=@save_optimizer_switch_for_selectivity_test; set @tmp_ust= @@use_stat_tables; set @tmp_oucs= @@optimizer_use_condition_selectivity; diff --git a/mysql-test/main/type_datetime.result b/mysql-test/main/type_datetime.result index 6da0e0bf4f1..923d6a3783c 100644 --- a/mysql-test/main/type_datetime.result +++ b/mysql-test/main/type_datetime.result @@ -1156,6 +1156,17 @@ ExtractValue('foo','bar') i MIN(d) 3 1976-12-14 13:21:07 DROP TABLE t1; # +# MDEV-19034 ASAN unknown-crash in get_date_time_separator with PAD_CHAR_TO_FULL_LENGTH +# +SET SQL_MODE=DEFAULT; +CREATE OR REPLACE TABLE t1 (a CHAR(11)); +CREATE OR REPLACE TABLE t2 (b DATETIME); +INSERT INTO t1 VALUES ('2010-02-19') ; +SET SQL_MODE= 'PAD_CHAR_TO_FULL_LENGTH'; +INSERT INTO t2 SELECT * FROM t1; +DROP TABLE t1, t2; +SET SQL_MODE=DEFAULT; +# # End of 10.1 tests # # diff --git a/mysql-test/main/type_datetime.test b/mysql-test/main/type_datetime.test index eaba3640140..baf85187099 100644 --- a/mysql-test/main/type_datetime.test +++ b/mysql-test/main/type_datetime.test @@ -711,6 +711,20 @@ SELECT ExtractValue('foo','bar'), i, MIN(d) FROM t1 GROUP BY i; DROP TABLE t1; --echo # +--echo # MDEV-19034 ASAN unknown-crash in get_date_time_separator with PAD_CHAR_TO_FULL_LENGTH +--echo # + +SET SQL_MODE=DEFAULT; +CREATE OR REPLACE TABLE t1 (a CHAR(11)); +CREATE OR REPLACE TABLE t2 (b DATETIME); +INSERT INTO t1 VALUES ('2010-02-19') ; +SET SQL_MODE= 'PAD_CHAR_TO_FULL_LENGTH'; +INSERT INTO t2 SELECT * FROM t1; +DROP TABLE t1, t2; +SET SQL_MODE=DEFAULT; + + +--echo # --echo # End of 10.1 tests --echo # diff --git a/mysql-test/main/type_int.result b/mysql-test/main/type_int.result index 17488d1ef98..3a1cdf2f24b 100644 --- a/mysql-test/main/type_int.result +++ b/mysql-test/main/type_int.result @@ -1,4 +1,28 @@ # +# Start of 5.5 tests +# +# +# MDEV-15955 Assertion `field_types == 0 || field_types[field_pos] == MYSQL_TYPE_LONGLONG' failed in Protocol_text::store_longlong +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +SELECT @a := 1 FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar'); +@a := 1 +1 +SELECT COALESCE(1) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar'); +COALESCE(1) +1 +SELECT COALESCE(@a:=1) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar'); +COALESCE(@a:=1) +1 +SELECT COALESCE(@a) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar'); +COALESCE(@a) +1 +DROP TABLE t1; +# +# End of 5.5 tests +# +# # Start of 10.1 tests # # diff --git a/mysql-test/main/type_int.test b/mysql-test/main/type_int.test index 11dad45162f..008fd014afa 100644 --- a/mysql-test/main/type_int.test +++ b/mysql-test/main/type_int.test @@ -1,4 +1,25 @@ --echo # +--echo # Start of 5.5 tests +--echo # + +--echo # +--echo # MDEV-15955 Assertion `field_types == 0 || field_types[field_pos] == MYSQL_TYPE_LONGLONG' failed in Protocol_text::store_longlong +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +SELECT @a := 1 FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar'); +SELECT COALESCE(1) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar'); +SELECT COALESCE(@a:=1) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar'); +SELECT COALESCE(@a) FROM t1 ORDER BY STRCMP(STDDEV_SAMP(a), 'bar'); +DROP TABLE t1; + +--echo # +--echo # End of 5.5 tests +--echo # + + +--echo # --echo # Start of 10.1 tests --echo # diff --git a/mysql-test/suite/encryption/r/file_creation.result b/mysql-test/suite/encryption/r/file_creation.result new file mode 100644 index 00000000000..22fe271145c --- /dev/null +++ b/mysql-test/suite/encryption/r/file_creation.result @@ -0,0 +1,26 @@ +SET GLOBAL innodb_encrypt_tables = ON; +SET GLOBAL innodb_encryption_threads = 1; +SET GLOBAL innodb_max_dirty_pages_pct = 99; +SHOW VARIABLES LIKE 'innodb_encrypt%'; +Variable_name Value +innodb_encrypt_log OFF +innodb_encrypt_tables ON +innodb_encrypt_temporary_tables OFF +innodb_encryption_rotate_key_age 1 +innodb_encryption_rotation_iops 100 +innodb_encryption_threads 1 +CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(255), f3 CHAR(255), +f4 CHAR(255), f5 CHAR(255))ENGINE=INNODB; +INSERT INTO t1 VALUES(1, "mysql", "mariadb", "batman", "superman"); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +# Wait max 10 min for key encryption threads to encrypt all spaces +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize status OK +ALTER TABLE t1 FORCE; +# Kill the server +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/t/file_creation.opt b/mysql-test/suite/encryption/t/file_creation.opt new file mode 100644 index 00000000000..7d3f2da7971 --- /dev/null +++ b/mysql-test/suite/encryption/t/file_creation.opt @@ -0,0 +1 @@ +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/file_creation.test b/mysql-test/suite/encryption/t/file_creation.test new file mode 100644 index 00000000000..a0c90975a37 --- /dev/null +++ b/mysql-test/suite/encryption/t/file_creation.test @@ -0,0 +1,41 @@ +--source include/have_innodb.inc +--source include/have_example_key_management_plugin.inc + +# embedded does not support restart +-- source include/not_embedded.inc + +# +# MDEV-19348 MariaBackup prepare fails with InnoDB: Database page corruption +# on disk or a failed file read +# + +SET GLOBAL innodb_encrypt_tables = ON; +SET GLOBAL innodb_encryption_threads = 1; +SET GLOBAL innodb_max_dirty_pages_pct = 99; +SHOW VARIABLES LIKE 'innodb_encrypt%'; + +CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(255), f3 CHAR(255), + f4 CHAR(255), f5 CHAR(255))ENGINE=INNODB; + +INSERT INTO t1 VALUES(1, "mysql", "mariadb", "batman", "superman"); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; + +--let $tables_count= `select count(*) + 1 from information_schema.tables where engine = 'InnoDB'` + +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +OPTIMIZE TABLE t1; + +--source ../../suite/innodb/include/no_checkpoint_start.inc +ALTER TABLE t1 FORCE; +--let CLEANUP_IF_CHECKPOINT=DROP TABLE t1; +--source ../../suite/innodb/include/no_checkpoint_end.inc + +--source include/start_mysqld.inc +DROP TABLE t1; diff --git a/mysql-test/suite/galera/r/galera_load_data.result b/mysql-test/suite/galera/r/galera_load_data.result index f0737b944e1..8a7397c7cb5 100644 --- a/mysql-test/suite/galera/r/galera_load_data.result +++ b/mysql-test/suite/galera/r/galera_load_data.result @@ -32,49 +32,15 @@ Warnings: Note 1031 Storage engine InnoDB of the table `cardtest02`.`cardtest_tbl` doesn't have this option UNLOCK TABLES; use cardtest02; -show indexes from cardtest_tbl; -Table cardtest_tbl -Non_unique 0 -Key_name PRIMARY -Seq_in_index 1 -Column_name id -Collation A -Cardinality 301 -Sub_part NULL -Packed NULL -Null -Index_type BTREE -Comment -Index_comment -select table_rows, avg_row_length, data_length from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'; -table_rows 301 -avg_row_length 81 -data_length 24576 select count(*) from cardtest_tbl; -count(*) 301 +count(*) +301 connection node_2; set session wsrep_sync_wait=15; use cardtest02; -show indexes from cardtest_tbl; -Table cardtest_tbl -Non_unique 0 -Key_name PRIMARY -Seq_in_index 1 -Column_name id -Collation A -Cardinality 301 -Sub_part NULL -Packed NULL -Null -Index_type BTREE -Comment -Index_comment -select table_rows, avg_row_length, data_length from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'; -table_rows 301 -avg_row_length 81 -data_length 24576 select count(*) from cardtest_tbl; -count(*) 301 +count(*) +301 connection node_1; use test; drop database cardtest02; diff --git a/mysql-test/suite/galera/t/galera_load_data.test b/mysql-test/suite/galera/t/galera_load_data.test index 99f8e571ef0..d4e09582a55 100644 --- a/mysql-test/suite/galera/t/galera_load_data.test +++ b/mysql-test/suite/galera/t/galera_load_data.test @@ -1,6 +1,5 @@ --source include/galera_cluster.inc - --connection node_1 create database cardtest02; @@ -38,23 +37,44 @@ ALTER TABLE `cardtest_tbl` ENABLE KEYS; UNLOCK TABLES; use cardtest02; ---sleep 15 ---vertical_results -show indexes from cardtest_tbl; ---vertical_results -select table_rows, avg_row_length, data_length from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'; +--let $wait_timeout=600 +--let $wait_condition = SELECT table_rows = 301 from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'; +--source include/wait_condition.inc + select count(*) from cardtest_tbl; +let $cardinality1 = `SELECT cardinality from information_schema.statistics WHERE TABLE_NAME = 'cardtest_tbl'`; +let $table_rows1 = `SELECT table_rows from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'`; +let $avg_row_length1 = `SELECT avg_row_length from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'`; +let $data_length1 = `SELECT data_length from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'`; + --connection node_2 set session wsrep_sync_wait=15; use cardtest02; ---sleep 15 ---vertical_results -show indexes from cardtest_tbl; ---vertical_results -select table_rows, avg_row_length, data_length from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'; + +--let $wait_timeout=600 +--let $wait_condition = SELECT table_rows = 301 from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'; +--source include/wait_condition.inc + select count(*) from cardtest_tbl; +if (`SELECT cardinality <> $cardinality1 from information_schema.statistics WHERE TABLE_NAME = 'cardtest_tbl'`) +{ +SELECT cardinality from information_schema.statistics WHERE TABLE_NAME = 'cardtest_tbl'; +} +if (`SELECT table_rows <> $table_rows1 from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'`) +{ +SELECT table_rows from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'; +} +if (`SELECT avg_row_length <> $avg_row_length1 from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'`) +{ +SELECT avg_row_length from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'; +} +if (`SELECT data_length <> $data_length1 from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'`) +{ +SELECT data_length from information_schema.tables WHERE TABLE_NAME = 'cardtest_tbl'; +} + --connection node_1 use test; drop database cardtest02; diff --git a/mysql-test/suite/innodb/r/foreign-keys.result b/mysql-test/suite/innodb/r/foreign-keys.result index 930e6f1d819..1618540aa96 100644 --- a/mysql-test/suite/innodb/r/foreign-keys.result +++ b/mysql-test/suite/innodb/r/foreign-keys.result @@ -161,3 +161,62 @@ c d 6 30 drop table t2, t1; drop user foo; +# +# MDEV-17187 table doesn't exist in engine after ALTER other tables +# with CONSTRAINTs +# +set foreign_key_checks=on; +create table t1 (id int not null primary key) engine=innodb; +create table t2 (id int not null primary key, fid int not null, +CONSTRAINT fk_fid FOREIGN KEY (fid) REFERENCES t1 (id))engine=innodb; +insert into t1 values (1), (2), (3); +insert into t2 values (1, 1), (2, 1), (3, 2); +set foreign_key_checks=off; +alter table t2 drop index fk_fid; +set foreign_key_checks=on; +delete from t1 where id=2; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_fid` FOREIGN KEY (`fid`) REFERENCES `t1` (`id`)) +insert into t2 values(4, 99); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_fid` FOREIGN KEY (`fid`) REFERENCES `t1` (`id`)) +select * from t1; +id +1 +2 +3 +select * from t2; +id fid +1 1 +2 1 +3 2 +set foreign_key_checks=off; +delete from t1 where id=2; +insert into t2 values(4, 99); +set foreign_key_checks=on; +select * from t1; +id +1 +3 +select * from t2; +id fid +1 1 +2 1 +3 2 +4 99 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL, + `fid` int(11) NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_fid` FOREIGN KEY (`fid`) REFERENCES `t1` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1,t2; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails +drop table t1,t2; +ERROR 42S02: Unknown table 'test.t2' diff --git a/mysql-test/suite/innodb/r/innodb-fk-warnings.result b/mysql-test/suite/innodb/r/innodb-fk-warnings.result index 0832e6ae9ff..21e7c23d249 100644 --- a/mysql-test/suite/innodb/r/innodb-fk-warnings.result +++ b/mysql-test/suite/innodb/r/innodb-fk-warnings.result @@ -25,7 +25,7 @@ create table t2(a int, constraint a foreign key a (a) references t1(a)) engine=i ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message -Warning 150 Create table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' foreign key a (a) references t1(a)) engine=innodb'. +Warning 150 Create table `test`.`t2` with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' foreign key a (a) references t1(a)) engine=innodb'. Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint for `t2` drop table t1; @@ -42,7 +42,7 @@ alter table t2 add constraint b foreign key (b) references t2(b); ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message -Warning 150 Alter table '`test`.`t2`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' foreign key (b) references t2(b)'. +Warning 150 Alter table `test`.`t2` with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' foreign key (b) references t2(b)'. Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint for `t2` drop table t2, t1; diff --git a/mysql-test/suite/innodb/r/innodb_bug68148.result b/mysql-test/suite/innodb/r/innodb_bug68148.result index 88247053389..9da4ea80d08 100644 --- a/mysql-test/suite/innodb/r/innodb_bug68148.result +++ b/mysql-test/suite/innodb/r/innodb_bug68148.result @@ -19,7 +19,6 @@ main ref_table1 ref_table2 # restart and see if we can still access the main table -SET FOREIGN_KEY_CHECKS=0; ALTER TABLE `main` ADD INDEX `idx_1` (`ref_id1`); SHOW CREATE TABLE `main`; Table Create Table diff --git a/mysql-test/suite/innodb/r/innodb_bug84958.result b/mysql-test/suite/innodb/r/innodb_bug84958.result index 1a59a10eb2f..b721c73a0fc 100644 --- a/mysql-test/suite/innodb/r/innodb_bug84958.result +++ b/mysql-test/suite/innodb/r/innodb_bug84958.result @@ -4,13 +4,17 @@ # # Set up the test with a procedure and a function. # +SET @saved_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; +SET GLOBAL innodb_purge_rseg_truncate_frequency= 1; CREATE PROCEDURE insert_n(start int, end int) BEGIN DECLARE i INT DEFAULT start; +START TRANSACTION; WHILE i <= end do INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = i; SET i = i + 1; END WHILE; +COMMIT; END~~ CREATE FUNCTION num_pages_get() RETURNS INT @@ -47,13 +51,14 @@ connection default; # Connect to default and record how many pages were accessed # when selecting the record using the secondary key. # +InnoDB 4 transactions not purged SET @num_pages_1 = num_pages_get(); SELECT * FROM t1 force index (b); a b c SET @num_pages_2= num_pages_get(); -SELECT @num_pages_2 - @num_pages_1 < 500; -@num_pages_2 - @num_pages_1 < 500 -1 +SELECT IF(@num_pages_2 - @num_pages_1 < 5000, 'OK', @num_pages_2 - @num_pages_1) num_pages_diff; +num_pages_diff +OK # # Commit and show the final record. # @@ -76,6 +81,7 @@ test.t1 check status OK # disconnect con2; disconnect con3; +SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; DROP TABLE t1; DROP PROCEDURE insert_n; DROP FUNCTION num_pages_get; diff --git a/mysql-test/suite/innodb/t/foreign-keys.test b/mysql-test/suite/innodb/t/foreign-keys.test index c20798aa824..cda3966e7f9 100644 --- a/mysql-test/suite/innodb/t/foreign-keys.test +++ b/mysql-test/suite/innodb/t/foreign-keys.test @@ -204,3 +204,49 @@ connection default; select * from t2; drop table t2, t1; drop user foo; + +--echo # +--echo # MDEV-17187 table doesn't exist in engine after ALTER other tables +--echo # with CONSTRAINTs +--echo # + +set foreign_key_checks=on; +create table t1 (id int not null primary key) engine=innodb; +create table t2 (id int not null primary key, fid int not null, +CONSTRAINT fk_fid FOREIGN KEY (fid) REFERENCES t1 (id))engine=innodb; + +insert into t1 values (1), (2), (3); +insert into t2 values (1, 1), (2, 1), (3, 2); + +set foreign_key_checks=off; +alter table t2 drop index fk_fid; +set foreign_key_checks=on; + +--error ER_ROW_IS_REFERENCED_2 +delete from t1 where id=2; +--error ER_NO_REFERENCED_ROW_2 +insert into t2 values(4, 99); + +select * from t1; +select * from t2; + +set foreign_key_checks=off; +delete from t1 where id=2; +insert into t2 values(4, 99); +set foreign_key_checks=on; + +select * from t1; +select * from t2; + +show create table t1; +show create table t2; + +# Optional: test DROP TABLE without any prior ha_innobase::open(). +# This was tested manually, but it would cause --embedded to skip the test, +# and the restart would significantly increase the running time. +# --source include/restart_mysqld.inc + +--error ER_ROW_IS_REFERENCED_2 +drop table t1,t2; +--error ER_BAD_TABLE_ERROR +drop table t1,t2; diff --git a/mysql-test/suite/innodb/t/innodb_bug68148.test b/mysql-test/suite/innodb/t/innodb_bug68148.test index 531baa30e48..2741c3cba3d 100644 --- a/mysql-test/suite/innodb/t/innodb_bug68148.test +++ b/mysql-test/suite/innodb/t/innodb_bug68148.test @@ -31,8 +31,6 @@ SHOW TABLES; --echo # restart and see if we can still access the main table --source include/restart_mysqld.inc -# This is required to access the table -SET FOREIGN_KEY_CHECKS=0; ALTER TABLE `main` ADD INDEX `idx_1` (`ref_id1`); SHOW CREATE TABLE `main`; diff --git a/mysql-test/suite/innodb/t/innodb_bug84958.test b/mysql-test/suite/innodb/t/innodb_bug84958.test index 4456df21cb9..cbcc5d1abc6 100644 --- a/mysql-test/suite/innodb/t/innodb_bug84958.test +++ b/mysql-test/suite/innodb/t/innodb_bug84958.test @@ -6,15 +6,19 @@ --echo # --source include/have_innodb.inc +SET @saved_frequency= @@GLOBAL.innodb_purge_rseg_truncate_frequency; +SET GLOBAL innodb_purge_rseg_truncate_frequency= 1; DELIMITER ~~; CREATE PROCEDURE insert_n(start int, end int) BEGIN DECLARE i INT DEFAULT start; + START TRANSACTION; WHILE i <= end do INSERT INTO t1 VALUES (1, 2, 3) ON DUPLICATE KEY UPDATE c = i; SET i = i + 1; END WHILE; + COMMIT; END~~ CREATE FUNCTION num_pages_get() @@ -60,11 +64,13 @@ connection default; --echo # Connect to default and record how many pages were accessed --echo # when selecting the record using the secondary key. --echo # +--let $wait_all_purged=4 +--source include/wait_all_purged.inc SET @num_pages_1 = num_pages_get(); SELECT * FROM t1 force index (b); SET @num_pages_2= num_pages_get(); -SELECT @num_pages_2 - @num_pages_1 < 500; +SELECT IF(@num_pages_2 - @num_pages_1 < 5000, 'OK', @num_pages_2 - @num_pages_1) num_pages_diff; --echo # --echo # Commit and show the final record. @@ -81,6 +87,7 @@ CHECK TABLE t1; --echo # disconnect con2; disconnect con3; +SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; DROP TABLE t1; DROP PROCEDURE insert_n; DROP FUNCTION num_pages_get; diff --git a/mysql-test/suite/innodb_gis/r/point_basic.result b/mysql-test/suite/innodb_gis/r/point_basic.result index d88b01d514b..f24ddfeb761 100644 --- a/mysql-test/suite/innodb_gis/r/point_basic.result +++ b/mysql-test/suite/innodb_gis/r/point_basic.result @@ -1524,7 +1524,7 @@ ALTER TABLE child ADD FOREIGN KEY(p) REFERENCES parent(p); ERROR HY000: Can't create table `test`.`child` (errno: 150 "Foreign key constraint is incorrectly formed") show warnings; Level Code Message -Warning 150 Alter table '`test`.`child`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near 'FOREIGN KEY(p) REFERENCES parent(p)'. +Warning 150 Alter table `test`.`child` with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near 'FOREIGN KEY(p) REFERENCES parent(p)'. Error 1005 Can't create table `test`.`child` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint for `child` ALTER TABLE parent DROP INDEX idx1; @@ -1532,7 +1532,7 @@ ALTER TABLE child ADD FOREIGN KEY(p) REFERENCES parent(p); Got one of the listed errors show warnings; Level Code Message -Warning 150 Alter table '`test`.`child`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near 'FOREIGN KEY(p) REFERENCES parent(p)'. +Warning 150 Alter table `test`.`child` with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near 'FOREIGN KEY(p) REFERENCES parent(p)'. Error 1005 Can't create table `test`.`child` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint for `child` ALTER TABLE child DROP INDEX idx2; @@ -1540,7 +1540,7 @@ ALTER TABLE child ADD FOREIGN KEY(p) REFERENCES parent(p); Got one of the listed errors show warnings; Level Code Message -Warning 150 Alter table '`test`.`child`' with foreign key constraint failed. There is only prefix index in the referenced table where the referenced columns appear as the first columns near 'FOREIGN KEY(p) REFERENCES parent(p)'. +Warning 150 Alter table `test`.`child` with foreign key constraint failed. There is only prefix index in the referenced table where the referenced columns appear as the first columns near 'FOREIGN KEY(p) REFERENCES parent(p)'. Error 1005 Can't create table `test`.`child` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint for `child` DROP TABLE child, parent; diff --git a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result index c00a0c73ce3..9a0abd4460a 100644 --- a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result +++ b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result @@ -2,9 +2,15 @@ # MDEV-5226 mysql_tzinfo_to_sql errors with tzdata 2013f and above # # Verbose run -set @prep=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET GLOBAL wsrep_replicate_myisam=?', 'do ?'); -prepare set_wsrep_myisam from @prep; -set @toggle=1; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=InnoDB; +ALTER TABLE time_zone_name ENGINE=InnoDB; +ALTER TABLE time_zone_transition ENGINE=InnoDB; +ALTER TABLE time_zone_transition_type ENGINE=InnoDB; +END IF| +\d ; TRUNCATE TABLE time_zone; TRUNCATE TABLE time_zone_name; TRUNCATE TABLE time_zone_transition; @@ -28,11 +34,25 @@ Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/ignored.tab' as time zo Warning: Skipping directory 'MYSQLTEST_VARDIR/zoneinfo/posix/posix': to avoid infinite symlink recursion. ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time; ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id; -set @toggle=0; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=MyISAM; +ALTER TABLE time_zone_name ENGINE=MyISAM; +ALTER TABLE time_zone_transition ENGINE=MyISAM; +ALTER TABLE time_zone_transition_type ENGINE=MyISAM; +END IF| +\d ; # Silent run -set @prep=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET GLOBAL wsrep_replicate_myisam=?', 'do ?'); -prepare set_wsrep_myisam from @prep; -set @toggle=1; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=InnoDB; +ALTER TABLE time_zone_name ENGINE=InnoDB; +ALTER TABLE time_zone_transition ENGINE=InnoDB; +ALTER TABLE time_zone_transition_type ENGINE=InnoDB; +END IF| +\d ; TRUNCATE TABLE time_zone; TRUNCATE TABLE time_zone_name; TRUNCATE TABLE time_zone_transition; @@ -53,26 +73,56 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset, Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it. ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time; ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id; -set @toggle=0; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=MyISAM; +ALTER TABLE time_zone_name ENGINE=MyISAM; +ALTER TABLE time_zone_transition ENGINE=MyISAM; +ALTER TABLE time_zone_transition_type ENGINE=MyISAM; +END IF| +\d ; # # Testing with explicit timezonefile # -set @prep=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET GLOBAL wsrep_replicate_myisam=?', 'do ?'); -prepare set_wsrep_myisam from @prep; -set @toggle=1; execute set_wsrep_myisam using @toggle; INSERT INTO time_zone (Use_leap_seconds) VALUES ('N'); SET @time_zone_id= LAST_INSERT_ID(); INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('XXX', @time_zone_id); INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset, Is_DST, Abbreviation) VALUES (@time_zone_id, 0, 0, 0, 'GMT') ; -set @toggle=0; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=MyISAM; +ALTER TABLE time_zone_name ENGINE=MyISAM; +ALTER TABLE time_zone_transition ENGINE=MyISAM; +ALTER TABLE time_zone_transition_type ENGINE=MyISAM; +END IF| +\d ; # # Testing --leap # -set @prep=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET GLOBAL wsrep_replicate_myisam=?', 'do ?'); -prepare set_wsrep_myisam from @prep; -set @toggle=1; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone_leap_second ENGINE=InnoDB; +END IF| +\d ; TRUNCATE TABLE time_zone_leap_second; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone_leap_second ENGINE=MyISAM; +END IF| +\d ; ALTER TABLE time_zone_leap_second ORDER BY Transition_time; -set @toggle=0; execute set_wsrep_myisam using @toggle; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on') = 1 THEN +ALTER TABLE time_zone ENGINE=MyISAM; +ALTER TABLE time_zone_name ENGINE=MyISAM; +ALTER TABLE time_zone_transition ENGINE=MyISAM; +ALTER TABLE time_zone_transition_type ENGINE=MyISAM; +END IF| +\d ; diff --git a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result new file mode 100644 index 00000000000..4ce57c641b3 --- /dev/null +++ b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result @@ -0,0 +1,74 @@ +# +# MDEV-5226 mysql_tzinfo_to_sql errors with tzdata 2013f and above +# +# Verbose run +set @prep1=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET SESSION SQL_LOG_BIN=?, WSREP_ON=OFF;', 'do ?'); +prepare set_wsrep_write_binlog from @prep1; +set @toggle=0; execute set_wsrep_write_binlog using @toggle; +TRUNCATE TABLE time_zone; +TRUNCATE TABLE time_zone_name; +TRUNCATE TABLE time_zone_transition; +TRUNCATE TABLE time_zone_transition_type; +INSERT INTO time_zone (Use_leap_seconds) VALUES ('N'); +SET @time_zone_id= LAST_INSERT_ID(); +INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id); +INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset, Is_DST, Abbreviation) VALUES + (@time_zone_id, 0, 0, 0, 'GMT') +; +Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/garbage' as time zone. Skipping it. +Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/ignored.tab' as time zone. Skipping it. +INSERT INTO time_zone (Use_leap_seconds) VALUES ('N'); +SET @time_zone_id= LAST_INSERT_ID(); +INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('posix/GMT', @time_zone_id); +INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset, Is_DST, Abbreviation) VALUES + (@time_zone_id, 0, 0, 0, 'GMT') +; +Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it. +Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/ignored.tab' as time zone. Skipping it. +Warning: Skipping directory 'MYSQLTEST_VARDIR/zoneinfo/posix/posix': to avoid infinite symlink recursion. +ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time; +ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id; +# Silent run +set @prep1=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET SESSION SQL_LOG_BIN=?, WSREP_ON=OFF;', 'do ?'); +prepare set_wsrep_write_binlog from @prep1; +set @toggle=0; execute set_wsrep_write_binlog using @toggle; +TRUNCATE TABLE time_zone; +TRUNCATE TABLE time_zone_name; +TRUNCATE TABLE time_zone_transition; +TRUNCATE TABLE time_zone_transition_type; +INSERT INTO time_zone (Use_leap_seconds) VALUES ('N'); +SET @time_zone_id= LAST_INSERT_ID(); +INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id); +INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset, Is_DST, Abbreviation) VALUES + (@time_zone_id, 0, 0, 0, 'GMT') +; +Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/garbage' as time zone. Skipping it. +INSERT INTO time_zone (Use_leap_seconds) VALUES ('N'); +SET @time_zone_id= LAST_INSERT_ID(); +INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('posix/GMT', @time_zone_id); +INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset, Is_DST, Abbreviation) VALUES + (@time_zone_id, 0, 0, 0, 'GMT') +; +Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it. +ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time; +ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id; +# +# Testing with explicit timezonefile +# +set @prep1=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET SESSION SQL_LOG_BIN=?, WSREP_ON=OFF;', 'do ?'); +prepare set_wsrep_write_binlog from @prep1; +set @toggle=0; execute set_wsrep_write_binlog using @toggle; +INSERT INTO time_zone (Use_leap_seconds) VALUES ('N'); +SET @time_zone_id= LAST_INSERT_ID(); +INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('XXX', @time_zone_id); +INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset, Is_DST, Abbreviation) VALUES + (@time_zone_id, 0, 0, 0, 'GMT') +; +# +# Testing --leap +# +set @prep1=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET SESSION SQL_LOG_BIN=?, WSREP_ON=OFF;', 'do ?'); +prepare set_wsrep_write_binlog from @prep1; +set @toggle=0; execute set_wsrep_write_binlog using @toggle; +TRUNCATE TABLE time_zone_leap_second; +ALTER TABLE time_zone_leap_second ORDER BY Transition_time; diff --git a/mysql-test/suite/wsrep/t/mysql_tzinfo_to_sql_symlink_skip.test b/mysql-test/suite/wsrep/t/mysql_tzinfo_to_sql_symlink_skip.test new file mode 100644 index 00000000000..bb3009bd432 --- /dev/null +++ b/mysql-test/suite/wsrep/t/mysql_tzinfo_to_sql_symlink_skip.test @@ -0,0 +1,40 @@ +--source include/have_wsrep.inc +--source include/have_symlink.inc +--source include/not_windows.inc + +--echo # +--echo # MDEV-5226 mysql_tzinfo_to_sql errors with tzdata 2013f and above +--echo # + +--exec mkdir $MYSQLTEST_VARDIR/zoneinfo +--exec ln -s $MYSQLTEST_VARDIR/zoneinfo $MYSQLTEST_VARDIR/zoneinfo/posix +--copy_file std_data/zoneinfo/GMT $MYSQLTEST_VARDIR/zoneinfo/GMT +--copy_file std_data/words.dat $MYSQLTEST_VARDIR/zoneinfo/garbage +--copy_file std_data/words.dat $MYSQLTEST_VARDIR/zoneinfo/ignored.tab + +--echo # Verbose run +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--exec $MYSQL_TZINFO_TO_SQL --verbose --skip-write-binlog $MYSQLTEST_VARDIR/zoneinfo 2>&1 + +--echo # Silent run +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--exec $MYSQL_TZINFO_TO_SQL --skip-write-binlog $MYSQLTEST_VARDIR/zoneinfo 2>&1 + +--echo # +--echo # Testing with explicit timezonefile +--echo # + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--exec $MYSQL_TZINFO_TO_SQL --skip-write-binlog $MYSQLTEST_VARDIR/zoneinfo/GMT XXX 2>&1 + +--echo # +--echo # Testing --leap +--echo # + +--exec $MYSQL_TZINFO_TO_SQL --leap --skip-write-binlog $MYSQLTEST_VARDIR/zoneinfo/GMT 2>&1 + +# +# Cleanup +# + +--exec rm -rf $MYSQLTEST_VARDIR/zoneinfo diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 36b6c368f56..3a1f176485f 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -185,7 +185,7 @@ static int get_date_time_separator(uint *number_of_fields, ulonglong flags, do { s++; - } while (my_isspace(&my_charset_latin1, *s)); + } while (s < end && my_isspace(&my_charset_latin1, *s)); *str= s; return 0; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9bd2e6040f0..022c6519a8a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -8248,10 +8248,6 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd) TABLE_LIST *head= join_list->head(); if (head->nested_join && head->nested_join->nest_type & REBALANCED_NEST) { - List_iterator<TABLE_LIST> li(*join_list); - li++; - while (li++) - li.remove(); DBUG_RETURN(head); } if (unlikely(!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+ @@ -8335,13 +8331,13 @@ void st_select_lex::add_joined_table(TABLE_LIST *table) context and right-associative in another context. In this query - SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a (Q1) + SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a (Q1) JOIN is left-associative and the query Q1 is interpreted as - SELECT * FROM (t1 JOIN t2) LEFT JOIN t3 ON t2.a=t3.a. + SELECT * FROM (t1 JOIN t2) LEFT JOIN t3 ON t2.a=t3.a. While in this query - SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.b=t2.b (Q2) + SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.b=t2.b (Q2) JOIN is right-associative and the query Q2 is interpreted as - SELECT * FROM t1 JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.b=t2.b + SELECT * FROM t1 JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.b=t2.b JOIN is right-associative if it is used with ON clause or with USING clause. Otherwise it is left-associative. @@ -8387,9 +8383,9 @@ void st_select_lex::add_joined_table(TABLE_LIST *table) J LJ - ON / \ / \ - t1 LJ - ON (TQ3*) => J t2 - / \ / \ - t3 t2 t1 t3 + t1 LJ - ON (TQ3*) => t3 J + / \ / \ + t3 t2 t1 t2 With several left associative JOINs SELECT * FROM t1 JOIN t2 JOIN t3 LEFT JOIN t4 ON t3.a=t4.a (Q4) @@ -8397,15 +8393,15 @@ void st_select_lex::add_joined_table(TABLE_LIST *table) J1 LJ - ON / \ / \ - t1 LJ - ON J2 t4 + t1 J2 J2 t4 / \ => / \ - J2 t4 J1 t3 - / \ / \ - t2 t3 t1 t2 + t2 LJ - ON J1 t3 + / \ / \ + t3 t4 t1 t2 - Here's another example: - SELECT * - FROM t1 JOIN t2 LEFT JOIN t3 JOIN t4 ON t3.a=t4.a ON t2.b=t3.b (Q5) + Here's another example: + SELECT * + FROM t1 JOIN t2 LEFT JOIN t3 JOIN t4 ON t3.a=t4.a ON t2.b=t3.b (Q5) J LJ - ON / \ / \ @@ -8415,15 +8411,58 @@ void st_select_lex::add_joined_table(TABLE_LIST *table) / \ t3 t4 - If the transformed nested join node node is a natural join node like in - the following query - SELECT * FROM t1 JOIN t2 LEFT JOIN t3 USING(a) (Q6) - the transformation additionally has to take care about setting proper - references in the field natural_join for both operands of the natural - join operation. - The function also has to change the name resolution context for ON - expressions used in the transformed join expression to take into - account the tables of the left_op node. + If the transformed nested join node node is a natural join node like in + the following query + SELECT * FROM t1 JOIN t2 LEFT JOIN t3 USING(a) (Q6) + the transformation additionally has to take care about setting proper + references in the field natural_join for both operands of the natural + join operation. + + The queries that combine comma syntax for join operation with + JOIN expression require a special care. Consider the query + SELECT * FROM t1, t2 JOIN t3 LEFT JOIN t4 ON t3.a=t4.a (Q7) + This query is equivalent to the query + SELECT * FROM (t1, t2) JOIN t3 LEFT JOIN t4 ON t3.a=t4.a + The latter is transformed in the same way as query Q1 + + J LJ - ON + / \ / \ + (t1,t2) LJ - ON => J t4 + / \ / \ + t3 t4 (t1,t2) t3 + + A transformation similar to the transformation for Q3 is done for + the following query with RIGHT JOIN + SELECT * FROM t1, t2 JOIN t3 RIGHT JOIN t4 ON t3.a=t4.a (Q8) + + J LJ - ON + / \ / \ + t3 LJ - ON => t4 J + / \ / \ + t4 (t1,t2) (t1,t2) t3 + + The function also has to change the name resolution context for ON + expressions used in the transformed join expression to take into + account the tables of the left_op node. + + TODO: + A more elegant solution would be to implement the transformation that + eliminates nests for cross join operations. For Q7 it would work like this: + + J LJ - ON + / \ / \ + (t1,t2) LJ - ON => (t1,t2,t3) t4 + / \ + t3 t4 + + For Q8 with RIGHT JOIN the transformation would work similarly: + + J LJ - ON + / \ / \ + t3 LJ - ON => t4 (t1,t2,t3) + / \ + t4 (t1,t2) + */ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op, @@ -8446,7 +8485,11 @@ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op, } TABLE_LIST *tbl; - List<TABLE_LIST> *jl= &right_op->nested_join->join_list; + List<TABLE_LIST> *right_op_jl= right_op->join_list; + TABLE_LIST *r_tbl= right_op_jl->pop(); + DBUG_ASSERT(right_op == r_tbl); + TABLE_LIST *l_tbl= right_op_jl->pop(); + DBUG_ASSERT(left_op == l_tbl); TABLE_LIST *cj_nest; /* @@ -8463,6 +8506,8 @@ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op, List<TABLE_LIST> *cjl= &cj_nest->nested_join->join_list; cjl->empty(); + List<TABLE_LIST> *jl= &right_op->nested_join->join_list; + DBUG_ASSERT(jl->elements == 2); /* Look for the left most node tbl of the right_op tree */ for ( ; ; ) { @@ -8535,6 +8580,8 @@ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op, create a new top level nested join node. */ right_op->nested_join->nest_type|= REBALANCED_NEST; + if (unlikely(right_op_jl->push_front(right_op))) + DBUG_RETURN(true); DBUG_RETURN(false); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2d6a843f7ad..7dcbafd4a88 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8512,6 +8512,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, KEYUSE *keyuse= pos->key; KEYUSE *prev_ref_keyuse= keyuse; uint key= keyuse->key; + bool used_range_selectivity= false; /* Check if we have a prefix of key=const that matches a quick select. @@ -8537,6 +8538,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, keyparts++; } sel /= (double)table->quick_rows[key] / (double) table->stat_records(); + used_range_selectivity= true; } } @@ -8572,13 +8574,14 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, if (keyparts > keyuse->keypart) { /* Ok this is the keyuse that will be used for ref access */ - uint fldno; - if (is_hash_join_key_no(key)) - fldno= keyuse->keypart; - else - fldno= table->key_info[key].key_part[keyparts-1].fieldnr - 1; - if (keyuse->val->const_item()) + if (!used_range_selectivity && keyuse->val->const_item()) { + uint fldno; + if (is_hash_join_key_no(key)) + fldno= keyuse->keypart; + else + fldno= table->key_info[key].key_part[keyparts-1].fieldnr - 1; + if (table->field[fldno]->cond_selectivity > 0) { sel /= table->field[fldno]->cond_selectivity; @@ -16937,9 +16940,9 @@ static void create_tmp_field_from_item_finalize(THD *thd, static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, Item ***copy_func, bool modify_item) { - Field *UNINIT_VAR(new_field); DBUG_ASSERT(thd == table->in_use); - if ((new_field= item->create_tmp_field(false, table))) + Field* new_field= item->create_tmp_field(false, table); + if (new_field) create_tmp_field_from_item_finalize(thd, new_field, item, copy_func, modify_item); return new_field; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 9242e3b423a..8d1342773f7 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -2114,7 +2114,12 @@ int alloc_statistics_for_table(THD* thd, TABLE *table) Histogram_type hist_type= (Histogram_type) (thd->variables.histogram_type); uchar *histogram= NULL; if (hist_size > 0) - histogram= (uchar *) alloc_root(&table->mem_root, hist_size * columns); + { + if ((histogram= (uchar *) alloc_root(&table->mem_root, + hist_size * columns))) + bzero(histogram, hist_size * columns); + + } if (!table_stats || !column_stats || !index_stats || !idx_avg_frequency || (hist_size && !histogram)) diff --git a/sql/tztime.cc b/sql/tztime.cc index 09d775e7e51..3307f58818c 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -147,6 +147,7 @@ typedef struct st_time_zone_info static my_bool prepare_tz_info(TIME_ZONE_INFO *sp, MEM_ROOT *storage); +my_bool opt_leap, opt_verbose, opt_skip_write_binlog; #if defined(TZINFO2SQL) || defined(TESTTIME) @@ -2428,6 +2429,14 @@ print_tz_leaps_as_sql(const TIME_ZONE_INFO *sp) We are assuming that there are only one list of leap seconds For all timezones. */ + if (!opt_skip_write_binlog) + printf("\\d |\n" + "IF (select count(*) from information_schema.global_variables where\n" + "variable_name='wsrep_on') = 1 THEN\n" + "ALTER TABLE time_zone_leap_second ENGINE=InnoDB;\n" + "END IF|\n" + "\\d ;\n"); + printf("TRUNCATE TABLE time_zone_leap_second;\n"); if (sp->leapcnt) @@ -2440,6 +2449,14 @@ print_tz_leaps_as_sql(const TIME_ZONE_INFO *sp) printf(";\n"); } + if (!opt_skip_write_binlog) + printf("\\d |\n" + "IF (select count(*) from information_schema.global_variables where\n" + "variable_name='wsrep_on') = 1 THEN\n" + "ALTER TABLE time_zone_leap_second ENGINE=MyISAM;\n" + "END IF|\n" + "\\d ;\n"); + printf("ALTER TABLE time_zone_leap_second ORDER BY Transition_time;\n"); } @@ -2597,8 +2614,6 @@ scan_tz_dir(char * name_end, uint symlink_recursion_level, uint verbose) } -my_bool opt_leap, opt_verbose; - static const char *load_default_groups[]= { "mysql_tzinfo_to_sql", 0}; @@ -2619,6 +2634,8 @@ static struct my_option my_long_options[] = &opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-write-binlog", 'S', "Do not replicate changes to time zone tables to other nodes in a Galera cluster", + &opt_skip_write_binlog,&opt_skip_write_binlog, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -2687,11 +2704,14 @@ main(int argc, char **argv) return 1; } - // Replicate MyISAM DDL for this session, cf. lp:1161432 - // timezone info unfixable in XtraDB Cluster - printf("set @prep=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET GLOBAL wsrep_replicate_myisam=?', 'do ?');\n" - "prepare set_wsrep_myisam from @prep;\n" - "set @toggle=1; execute set_wsrep_myisam using @toggle;\n"); + if (opt_skip_write_binlog) + /* If skip_write_binlog is set and wsrep is compiled in we disable + sql_log_bin and wsrep_on to avoid Galera replicating below + truncate table clauses. This will allow user to set different + time zones to nodes in Galera cluster. */ + printf("set @prep1=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on'), 'SET SESSION SQL_LOG_BIN=?, WSREP_ON=OFF;', 'do ?');\n" + "prepare set_wsrep_write_binlog from @prep1;\n" + "set @toggle=0; execute set_wsrep_write_binlog using @toggle;\n"); if (argc == 1 && !opt_leap) { @@ -2699,6 +2719,21 @@ main(int argc, char **argv) root_name_end= strmake_buf(fullname, argv[0]); + if(!opt_skip_write_binlog) + { + // Alter time zone tables to InnoDB if wsrep_on is enabled + // to allow changes to them to replicate with Galera + printf("\\d |\n" + "IF (select count(*) from information_schema.global_variables where\n" + "variable_name='wsrep_on') = 1 THEN\n" + "ALTER TABLE time_zone ENGINE=InnoDB;\n" + "ALTER TABLE time_zone_name ENGINE=InnoDB;\n" + "ALTER TABLE time_zone_transition ENGINE=InnoDB;\n" + "ALTER TABLE time_zone_transition_type ENGINE=InnoDB;\n" + "END IF|\n" + "\\d ;\n"); + } + printf("TRUNCATE TABLE time_zone;\n"); printf("TRUNCATE TABLE time_zone_name;\n"); printf("TRUNCATE TABLE time_zone_transition;\n"); @@ -2740,8 +2775,19 @@ main(int argc, char **argv) free_root(&tz_storage, MYF(0)); } - // Reset wsrep_replicate_myisam. lp:1161432 - printf("set @toggle=0; execute set_wsrep_myisam using @toggle;\n"); + if(!opt_skip_write_binlog) + { + // Fall back to MyISAM + printf("\\d |\n" + "IF (select count(*) from information_schema.global_variables where\n" + "variable_name='wsrep_on') = 1 THEN\n" + "ALTER TABLE time_zone ENGINE=MyISAM;\n" + "ALTER TABLE time_zone_name ENGINE=MyISAM;\n" + "ALTER TABLE time_zone_transition ENGINE=MyISAM;\n" + "ALTER TABLE time_zone_transition_type ENGINE=MyISAM;\n" + "END IF|\n" + "\\d ;\n"); + } free_defaults(default_argv); my_end(0); diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index bda79ed7406..8079ebaf563 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -756,7 +756,7 @@ static ssize_t sst_prepare_other (const char* method, my_free(binlog_opt_val); my_free(binlog_index_opt_val); - if (ret < 0 || ret >= cmd_len) + if (ret < 0 || size_t(ret) >= cmd_len) { WSREP_ERROR("sst_prepare_other(): snprintf() failed: %d", ret); return (ret < 0 ? ret : -EMSGSIZE); @@ -1067,7 +1067,7 @@ static int sst_donate_mysqldump (const char* addr, (long long)seqno, wsrep_gtid_domain_id, bypass ? " " WSREP_SST_OPT_BYPASS : ""); - if (ret < 0 || ret >= cmd_len) + if (ret < 0 || size_t(ret) >= cmd_len) { WSREP_ERROR("sst_donate_mysqldump(): snprintf() failed: %d", ret); return (ret < 0 ? ret : -EMSGSIZE); @@ -1437,7 +1437,7 @@ static int sst_donate_other (const char* method, bypass ? " " WSREP_SST_OPT_BYPASS : ""); my_free(binlog_opt_val); - if (ret < 0 || ret >= cmd_len) + if (ret < 0 || size_t(ret) >= cmd_len) { WSREP_ERROR("sst_donate_other(): snprintf() failed: %d", ret); return (ret < 0 ? ret : -EMSGSIZE); diff --git a/storage/heap/hp_scan.c b/storage/heap/hp_scan.c index 3315cb05b3f..f07efe6cf67 100644 --- a/storage/heap/hp_scan.c +++ b/storage/heap/hp_scan.c @@ -50,7 +50,9 @@ int heap_scan(register HP_INFO *info, uchar *record) } else { - info->next_block+=share->block.records_in_block; + /* increase next_block to the next records_in_block boundary */ + ulong rem= info->next_block % share->block.records_in_block; + info->next_block+=share->block.records_in_block - rem; if (info->next_block >= share->records+share->deleted) { info->next_block= share->records+share->deleted; diff --git a/storage/innobase/btr/btr0scrub.cc b/storage/innobase/btr/btr0scrub.cc index 7d8966d4109..2839f4f872f 100644 --- a/storage/innobase/btr/btr0scrub.cc +++ b/storage/innobase/btr/btr0scrub.cc @@ -626,13 +626,8 @@ btr_scrub_get_table_and_index( scrub_data->current_table = NULL; } - /* argument to dict_table_open_on_index_id */ - bool dict_locked = true; - /* open table based on index_id */ - dict_table_t* table = dict_table_open_on_index_id( - index_id, - dict_locked); + dict_table_t* table = dict_table_open_on_index_id(index_id); if (table != NULL) { /* mark table as being scrubbed */ diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index cb0e8b6b488..47803ed19a1 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -427,7 +427,7 @@ dict_table_try_drop_aborted( if (table == NULL) { table = dict_table_open_on_id_low( - table_id, DICT_ERR_IGNORE_NONE, FALSE); + table_id, DICT_ERR_IGNORE_FK_NOKEY, FALSE); } else { ut_ad(table->id == table_id); } @@ -1002,7 +1002,7 @@ dict_table_open_on_id( table_id, table_op == DICT_TABLE_OP_LOAD_TABLESPACE ? DICT_ERR_IGNORE_RECOVER_LOCK - : DICT_ERR_IGNORE_NONE, + : DICT_ERR_IGNORE_FK_NOKEY, table_op == DICT_TABLE_OP_OPEN_ONLY_IF_CACHED); if (table != NULL) { @@ -1164,7 +1164,7 @@ dict_table_open_on_name( if (table != NULL) { /* If table is encrypted or corrupted */ - if (ignore_err == DICT_ERR_IGNORE_NONE + if (!(ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY) && !table->is_readable()) { /* Make life easy for drop table. */ dict_table_prevent_eviction(table); @@ -3128,11 +3128,6 @@ dict_index_build_internal_fts( } /*====================== FOREIGN KEY PROCESSING ========================*/ -#define DB_FOREIGN_KEY_IS_PREFIX_INDEX 200 -#define DB_FOREIGN_KEY_COL_NOT_NULL 201 -#define DB_FOREIGN_KEY_COLS_NOT_EQUAL 202 -#define DB_FOREIGN_KEY_INDEX_NOT_FOUND 203 - /** Check whether the dict_table_t is a partition. A partitioned table on the SQL level is composed of InnoDB tables, where each InnoDB table is a [sub]partition including its secondary indexes @@ -3239,7 +3234,7 @@ dict_foreign_find_index( /*!< in: nonzero if none of the columns must be declared NOT NULL */ - ulint* error, /*!< out: error code */ + fkerr_t* error, /*!< out: error code */ ulint* err_col_no, /*!< out: column number where error happened */ @@ -3247,17 +3242,15 @@ dict_foreign_find_index( /*!< out: index where error happened */ { - dict_index_t* index; - ut_ad(mutex_own(&dict_sys->mutex)); if (error) { - *error = DB_FOREIGN_KEY_INDEX_NOT_FOUND; + *error = FK_INDEX_NOT_FOUND; } - index = dict_table_get_first_index(table); - - while (index != NULL) { + for (dict_index_t* index = dict_table_get_first_index(table); + index; + index = dict_table_get_next_index(index)) { if (types_idx != index && !index->to_be_dropped && !dict_index_is_online_ddl(index) @@ -3265,42 +3258,17 @@ dict_foreign_find_index( table, col_names, columns, n_cols, index, types_idx, check_charsets, check_null, - error, err_col_no,err_index)) { + error, err_col_no, err_index)) { if (error) { - *error = DB_SUCCESS; + *error = FK_SUCCESS; } return(index); } - - index = dict_table_get_next_index(index); } return(NULL); } -#ifdef WITH_WSREP -dict_index_t* -wsrep_dict_foreign_find_index( -/*====================*/ - dict_table_t* table, /*!< in: table */ - const char** col_names, /*!< in: column names, or NULL - to use table->col_names */ - const char** columns,/*!< in: array of column names */ - ulint n_cols, /*!< in: number of columns */ - dict_index_t* types_idx, /*!< in: NULL or an index to whose types the - column types must match */ - ibool check_charsets, - /*!< in: whether to check charsets. - only has an effect if types_idx != NULL */ - ulint check_null) - /*!< in: nonzero if none of the columns must - be declared NOT NULL */ -{ - return dict_foreign_find_index( - table, col_names, columns, n_cols, types_idx, check_charsets, - check_null, NULL, NULL, NULL); -} -#endif /* WITH_WSREP */ /**********************************************************************//** Report an error in a foreign key definition. */ static @@ -3397,15 +3365,11 @@ dict_foreign_add_to_cache( } if (ref_table && !for_in_cache->referenced_table) { - ulint index_error; - ulint err_col; - dict_index_t *err_index=NULL; - index = dict_foreign_find_index( ref_table, NULL, for_in_cache->referenced_col_names, for_in_cache->n_fields, for_in_cache->foreign_index, - check_charsets, false, &index_error, &err_col, &err_index); + check_charsets, false); if (index == NULL && !(ignore_err & DICT_ERR_IGNORE_FK_NOKEY)) { @@ -3437,10 +3401,6 @@ dict_foreign_add_to_cache( } if (for_table && !for_in_cache->foreign_table) { - ulint index_error; - ulint err_col; - dict_index_t *err_index=NULL; - index = dict_foreign_find_index( for_table, col_names, for_in_cache->foreign_col_names, @@ -3448,8 +3408,7 @@ dict_foreign_add_to_cache( for_in_cache->referenced_index, check_charsets, for_in_cache->type & (DICT_FOREIGN_ON_DELETE_SET_NULL - | DICT_FOREIGN_ON_UPDATE_SET_NULL), - &index_error, &err_col, &err_index); + | DICT_FOREIGN_ON_UPDATE_SET_NULL)); if (index == NULL && !(ignore_err & DICT_ERR_IGNORE_FK_NOKEY)) { @@ -4161,7 +4120,7 @@ dict_foreign_push_index_error( const char* latest_foreign, /*!< in: start of latest foreign key constraint name */ const char** columns, /*!< in: foreign key columns */ - ulint index_error, /*!< in: error code */ + fkerr_t index_error, /*!< in: error code */ ulint err_col, /*!< in: column where error happened */ dict_index_t* err_index, /*!< in: index where error happened @@ -4170,37 +4129,37 @@ dict_foreign_push_index_error( FILE* ef) /*!< in: output stream */ { switch (index_error) { - case DB_FOREIGN_KEY_INDEX_NOT_FOUND: { + case FK_SUCCESS: + break; + case FK_INDEX_NOT_FOUND: fprintf(ef, - "%s table '%s' with foreign key constraint" + "%s table %s with foreign key constraint" " failed. There is no index in the referenced" " table where the referenced columns appear" " as the first columns near '%s'.\n", operation, create_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, - "%s table '%s' with foreign key constraint" + "%s table %s with foreign key constraint" " failed. There is no index in the referenced" " table where the referenced columns appear" " as the first columns near '%s'.", operation, create_name, latest_foreign); - break; - } - case DB_FOREIGN_KEY_IS_PREFIX_INDEX: { + return; + case FK_IS_PREFIX_INDEX: fprintf(ef, - "%s table '%s' with foreign key constraint" + "%s table %s with foreign key constraint" " failed. There is only prefix index in the referenced" " table where the referenced columns appear" " as the first columns near '%s'.\n", operation, create_name, latest_foreign); ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT, - "%s table '%s' with foreign key constraint" + "%s table %s with foreign key constraint" " failed. There is only prefix index in the referenced" " table where the referenced columns appear" " as the first columns near '%s'.", operation, create_name, latest_foreign); - break; - } - case DB_FOREIGN_KEY_COL_NOT_NULL: { + return; + case FK_COL_NOT_NULL: fprintf(ef, "%s table %s with foreign key constraint" " failed. You have defined a SET NULL condition but " @@ -4211,9 +4170,8 @@ dict_foreign_push_index_error( " failed. You have defined a SET NULL condition but " "column '%s' on index is defined as NOT NULL near '%s'.", operation, create_name, columns[err_col], latest_foreign); - break; - } - case DB_FOREIGN_KEY_COLS_NOT_EQUAL: { + return; + case FK_COLS_NOT_EQUAL: dict_field_t* field; const char* col_name; field = dict_index_get_nth_field(err_index, err_col); @@ -4232,11 +4190,9 @@ dict_foreign_push_index_error( " failed. Field type or character set for column '%s' " "does not mach referenced column '%s' near '%s'.", operation, create_name, columns[err_col], col_name, latest_foreign); - break; - } - default: - ut_error; + return; } + DBUG_ASSERT(!"unknown error"); } /*********************************************************************//** @@ -4268,7 +4224,7 @@ dict_create_foreign_constraints_low( const char* start_of_latest_foreign = sql_string; const char* start_of_latest_set = NULL; FILE* ef = dict_foreign_err_file; - ulint index_error = DB_SUCCESS; + fkerr_t index_error = FK_SUCCESS; dict_index_t* err_index = NULL; ulint err_col; const char* constraint_name; @@ -6720,7 +6676,7 @@ dict_foreign_qualify_index( /*!< in: nonzero if none of the columns must be declared NOT NULL */ - ulint* error, /*!< out: error code */ + fkerr_t* error, /*!< out: error code */ ulint* err_col_no, /*!< out: column number where error happened */ @@ -6748,7 +6704,7 @@ dict_foreign_qualify_index( /* We do not accept column prefix indexes here */ if (error && err_col_no && err_index) { - *error = DB_FOREIGN_KEY_IS_PREFIX_INDEX; + *error = FK_IS_PREFIX_INDEX; *err_col_no = i; *err_index = (dict_index_t*)index; } @@ -6758,7 +6714,7 @@ dict_foreign_qualify_index( if (check_null && (field->col->prtype & DATA_NOT_NULL)) { if (error && err_col_no && err_index) { - *error = DB_FOREIGN_KEY_COL_NOT_NULL; + *error = FK_COL_NOT_NULL; *err_col_no = i; *err_index = (dict_index_t*)index; } @@ -6788,7 +6744,7 @@ dict_foreign_qualify_index( dict_index_get_nth_col(types_idx, i), check_charsets)) { if (error && err_col_no && err_index) { - *error = DB_FOREIGN_KEY_COLS_NOT_EQUAL; + *error = FK_COLS_NOT_EQUAL; *err_col_no = i; *err_index = (dict_index_t*)index; } diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index 6700bca5ba4..817a4059e8a 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -3086,7 +3086,7 @@ func_exit: mem_heap_free(heap); ut_ad(!table - || ignore_err != DICT_ERR_IGNORE_NONE + || (ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY) || !table->is_readable() || !table->corrupted); @@ -3775,29 +3775,14 @@ dict_load_table_id_on_index_id( return(found); } -UNIV_INTERN -dict_table_t* -dict_table_open_on_index_id( -/*========================*/ - index_id_t index_id, /*!< in: index id */ - bool dict_locked) /*!< in: dict locked */ +dict_table_t* dict_table_open_on_index_id(index_id_t index_id) { - if (!dict_locked) { - mutex_enter(&dict_sys->mutex); - } - - ut_ad(mutex_own(&dict_sys->mutex)); table_id_t table_id; dict_table_t * table = NULL; if (dict_load_table_id_on_index_id(index_id, &table_id)) { - bool local_dict_locked = true; - table = dict_table_open_on_id(table_id, - local_dict_locked, + table = dict_table_open_on_id(table_id, true, DICT_TABLE_OP_LOAD_TABLESPACE); } - if (!dict_locked) { - mutex_exit(&dict_sys->mutex); - } return table; } diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 35b70501002..9d64f81e406 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -356,6 +356,33 @@ fil_space_destroy_crypt_data( } } +/** Fill crypt data information to the give page. +It should be called during ibd file creation. +@param[in] flags tablespace flags +@param[in,out] page first page of the tablespace */ +void +fil_space_crypt_t::fill_page0( + ulint flags, + byte* page) +{ + const uint len = sizeof(iv); + const ulint offset = FSP_HEADER_OFFSET + + fsp_header_get_encryption_offset(page_size_t(flags)); + page0_offset = offset; + + memcpy(page + offset, CRYPT_MAGIC, MAGIC_SZ); + mach_write_to_1(page + offset + MAGIC_SZ, type); + mach_write_to_1(page + offset + MAGIC_SZ + 1, len); + memcpy(page + offset + MAGIC_SZ + 2, &iv, len); + + mach_write_to_4(page + offset + MAGIC_SZ + 2 + len, + min_key_version); + mach_write_to_4(page + offset + MAGIC_SZ + 2 + len + 4, + key_id); + mach_write_to_1(page + offset + MAGIC_SZ + 2 + len + 8, + encryption); +} + /****************************************************************** Write crypt data to a page (0) @param[in] space tablespace diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index d796d2a7f2a..5bf7fb9df58 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -3076,6 +3076,19 @@ err_exit: fsp_header_init_fields(page, space_id, flags); mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space_id); + /* Create crypt data if the tablespace is either encrypted or user has + requested it to remain unencrypted. */ + if (mode == FIL_ENCRYPTION_ON || mode == FIL_ENCRYPTION_OFF || + srv_encrypt_tables) { + crypt_data = fil_space_create_crypt_data(mode, key_id); + } + + if (crypt_data) { + /* Write crypt data information in page0 while creating + ibd file. */ + crypt_data->fill_page0(flags, page); + } + const page_size_t page_size(flags); IORequest request(IORequest::WRITE); @@ -3127,13 +3140,6 @@ err_exit: } } - /* Create crypt data if the tablespace is either encrypted or user has - requested it to remain unencrypted. */ - if (mode == FIL_ENCRYPTION_ON || mode == FIL_ENCRYPTION_OFF || - srv_encrypt_tables) { - crypt_data = fil_space_create_crypt_data(mode, key_id); - } - space = fil_space_create(name, space_id, flags, FIL_TYPE_TABLESPACE, crypt_data, mode); if (!space) { diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 29cc4dc3c40..59a7c8641f8 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3110,7 +3110,7 @@ static bool innobase_query_caching_table_check( const char* norm_name) { dict_table_t* table = dict_table_open_on_name( - norm_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE); + norm_name, FALSE, FALSE, DICT_ERR_IGNORE_FK_NOKEY); if (table == NULL) { return false; @@ -6084,9 +6084,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field) int ha_innobase::open(const char* name, int, uint) { - dict_table_t* ib_table; char norm_name[FN_REFLEN]; - dict_err_ignore_t ignore_err = DICT_ERR_IGNORE_NONE; DBUG_ENTER("ha_innobase::open"); @@ -6100,15 +6098,8 @@ ha_innobase::open(const char* name, int, uint) char* is_part = is_partition(norm_name); THD* thd = ha_thd(); - - /* Check whether FOREIGN_KEY_CHECKS is set to 0. If so, the table - can be opened even if some FK indexes are missing. If not, the table - can't be opened in the same situation */ - if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) { - ignore_err = DICT_ERR_IGNORE_FK_NOKEY; - } - - ib_table = open_dict_table(name, norm_name, is_part, ignore_err); + dict_table_t* ib_table = open_dict_table(name, norm_name, is_part, + DICT_ERR_IGNORE_FK_NOKEY); DEBUG_SYNC(thd, "ib_open_after_dict_open"); @@ -10172,17 +10163,6 @@ next_record: } #ifdef WITH_WSREP -extern dict_index_t* -wsrep_dict_foreign_find_index( -/*==========================*/ - dict_table_t* table, - const char** col_names, - const char** columns, - ulint n_cols, - dict_index_t* types_idx, - ibool check_charsets, - ulint check_null); - inline const char* wsrep_key_type_to_str(wsrep_key_type type) @@ -10245,7 +10225,7 @@ wsrep_append_foreign_key( foreign->referenced_table_name_lookup); if (foreign->referenced_table) { foreign->referenced_index = - wsrep_dict_foreign_find_index( + dict_foreign_find_index( foreign->referenced_table, NULL, foreign->referenced_col_names, foreign->n_fields, @@ -10259,7 +10239,7 @@ wsrep_append_foreign_key( if (foreign->foreign_table) { foreign->foreign_index = - wsrep_dict_foreign_find_index( + dict_foreign_find_index( foreign->foreign_table, NULL, foreign->foreign_col_names, foreign->n_fields, @@ -13178,8 +13158,8 @@ innobase_rename_table( row_mysql_lock_data_dictionary(trx); } - dict_table_t* table = dict_table_open_on_name(norm_from, TRUE, FALSE, - DICT_ERR_IGNORE_NONE); + dict_table_t* table = dict_table_open_on_name( + norm_from, TRUE, FALSE, DICT_ERR_IGNORE_FK_NOKEY); /* Since DICT_BG_YIELD has sleep for 250 milliseconds, Convert lock_wait_timeout unit from second to 250 milliseconds */ @@ -14300,7 +14280,7 @@ ha_innobase::defragment_table( normalize_table_name(norm_name, name); table = dict_table_open_on_name(norm_name, FALSE, - FALSE, DICT_ERR_IGNORE_NONE); + FALSE, DICT_ERR_IGNORE_FK_NOKEY); for (index = dict_table_get_first_index(table); index; index = dict_table_get_next_index(index)) { diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 6f84f2eadf7..12a566a27c6 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -115,12 +115,7 @@ dict_table_open_on_id( /**********************************************************************//** Returns a table object based on table id. @return table, NULL if does not exist */ -UNIV_INTERN -dict_table_t* -dict_table_open_on_index_id( -/*==================*/ - table_id_t table_id, /*!< in: table id */ - bool dict_locked) /*!< in: TRUE=data dictionary locked */ +dict_table_t* dict_table_open_on_index_id(index_id_t index_id) __attribute__((warn_unused_result)); /********************************************************************//** Decrements the count of open handles to a table. */ @@ -523,6 +518,21 @@ dict_table_open_on_name( dict_err_ignore_t ignore_err) MY_ATTRIBUTE((warn_unused_result)); +/** Outcome of dict_foreign_find_index() or dict_foreign_qualify_index() */ +enum fkerr_t +{ + /** A backing index was found for a FOREIGN KEY constraint */ + FK_SUCCESS = 0, + /** There is no index that covers the columns in the constraint. */ + FK_INDEX_NOT_FOUND, + /** The index is for a prefix index, not a full column. */ + FK_IS_PREFIX_INDEX, + /** A condition of SET NULL conflicts with a NOT NULL column. */ + FK_COL_NOT_NULL, + /** The column types do not match */ + FK_COLS_NOT_EQUAL +}; + /*********************************************************************//** Tries to find an index whose first fields are the columns in the array, in the same order and is not marked for deletion and is not the same @@ -549,11 +559,11 @@ dict_foreign_find_index( /*!< in: nonzero if none of the columns must be declared NOT NULL */ - ulint* error, /*!< out: error code */ - ulint* err_col_no, + fkerr_t* error = NULL, /*!< out: error code */ + ulint* err_col_no = NULL, /*!< out: column number where error happened */ - dict_index_t** err_index) + dict_index_t** err_index = NULL) /*!< out: index where error happened */ @@ -629,7 +639,7 @@ dict_foreign_qualify_index( /*!< in: nonzero if none of the columns must be declared NOT NULL */ - ulint* error, /*!< out: error code */ + fkerr_t* error, /*!< out: error code */ ulint* err_col_no, /*!< out: column number where error happened */ diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h index cab88104b87..fec101529f9 100644 --- a/storage/innobase/include/dict0types.h +++ b/storage/innobase/include/dict0types.h @@ -67,11 +67,11 @@ Note: please define the IGNORE_ERR_* as bits, so their value can be or-ed together */ enum dict_err_ignore_t { DICT_ERR_IGNORE_NONE = 0, /*!< no error to ignore */ - DICT_ERR_IGNORE_INDEX_ROOT = 1, /*!< ignore error if index root - page is FIL_NULL or incorrect value */ - DICT_ERR_IGNORE_CORRUPT = 2, /*!< skip corrupted indexes */ - DICT_ERR_IGNORE_FK_NOKEY = 4, /*!< ignore error if any foreign + DICT_ERR_IGNORE_FK_NOKEY = 1, /*!< ignore error if any foreign key is missing */ + DICT_ERR_IGNORE_INDEX_ROOT = 2, /*!< ignore error if index root + page is FIL_NULL or incorrect value */ + DICT_ERR_IGNORE_CORRUPT = 4, /*!< skip corrupted indexes */ DICT_ERR_IGNORE_RECOVER_LOCK = 8, /*!< Used when recovering table locks for resurrected transactions. diff --git a/storage/innobase/include/fil0crypt.h b/storage/innobase/include/fil0crypt.h index 47ac35d6bce..2296945bbf9 100644 --- a/storage/innobase/include/fil0crypt.h +++ b/storage/innobase/include/fil0crypt.h @@ -180,6 +180,12 @@ struct fil_space_crypt_t : st_encryption_scheme return (encryption == FIL_ENCRYPTION_OFF); } + /** Fill crypt data information to the give page. + It should be called during ibd file creation. + @param[in] flags tablespace flags + @param[in,out] page first page of the tablespace */ + void fill_page0(ulint flags, byte* page); + /** Write crypt data to a page (0) @param[in] space tablespace @param[in,out] page0 first page of the tablespace diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 12bd2001495..bb7daf6399a 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -874,8 +874,12 @@ row_ins_foreign_report_add_err( fk_str = dict_print_info_on_foreign_key_in_create_format(trx, foreign, TRUE); fputs(fk_str.c_str(), ef); - fprintf(ef, " in parent table, in index %s", - foreign->foreign_index->name()); + if (foreign->foreign_index) { + fprintf(ef, " in parent table, in index %s", + foreign->foreign_index->name()); + } else { + fputs(" in parent table", ef); + } if (entry) { fputs(" tuple:\n", ef); /* TODO: DB_TRX_ID and DB_ROLL_PTR may be uninitialized. @@ -1656,34 +1660,51 @@ row_ins_check_foreign_constraint( || !check_table->is_readable() || check_index == NULL) { - if (!srv_read_only_mode && check_ref) { - FILE* ef = dict_foreign_err_file; - std::string fk_str; - - row_ins_set_detailed(trx, foreign); - - row_ins_foreign_trx_print(trx); - - fputs("Foreign key constraint fails for table ", ef); - ut_print_name(ef, trx, - foreign->foreign_table_name); - fputs(":\n", ef); - fk_str = dict_print_info_on_foreign_key_in_create_format( - trx, foreign, TRUE); - fputs(fk_str.c_str(), ef); - fprintf(ef, "\nTrying to add to index %s tuple:\n", - foreign->foreign_index->name()); + FILE* ef = dict_foreign_err_file; + std::string fk_str; + + row_ins_set_detailed(trx, foreign); + row_ins_foreign_trx_print(trx); + + fputs("Foreign key constraint fails for table ", ef); + ut_print_name(ef, trx, check_ref + ? foreign->foreign_table_name + : foreign->referenced_table_name); + fputs(":\n", ef); + fk_str = dict_print_info_on_foreign_key_in_create_format( + trx, foreign, TRUE); + fputs(fk_str.c_str(), ef); + if (check_ref) { + if (foreign->foreign_index) { + fprintf(ef, "\nTrying to add to index %s" + " tuple:\n", + foreign->foreign_index->name()); + } else { + fputs("\nTrying to add tuple:\n", ef); + } dtuple_print(ef, entry); fputs("\nBut the parent table ", ef); - ut_print_name(ef, trx, - foreign->referenced_table_name); - fputs("\nor its .ibd file does" + ut_print_name(ef, trx, foreign->referenced_table_name); + fputs("\nor its .ibd file or the required index does" " not currently exist!\n", ef); - mutex_exit(&dict_foreign_err_mutex); - err = DB_NO_REFERENCED_ROW; + } else { + if (foreign->referenced_index) { + fprintf(ef, "\nTrying to modify index %s" + " tuple:\n", + foreign->referenced_index->name()); + } else { + fputs("\nTrying to modify tuple:\n", ef); + } + dtuple_print(ef, entry); + fputs("\nBut the referencing table ", ef); + ut_print_name(ef, trx, foreign->foreign_table_name); + fputs("\nor its .ibd file or the required index does" + " not currently exist!\n", ef); + err = DB_ROW_IS_REFERENCED; } + mutex_exit(&dict_foreign_err_mutex); goto exit_func; } @@ -1965,6 +1986,7 @@ row_ins_check_foreign_constraints( /*==============================*/ dict_table_t* table, /*!< in: table */ dict_index_t* index, /*!< in: index */ + bool pk, /*!< in: index->is_primary() */ dtuple_t* entry, /*!< in: index entry for index */ que_thr_t* thr) /*!< in: query thread */ { @@ -1973,6 +1995,8 @@ row_ins_check_foreign_constraints( trx_t* trx; ibool got_s_lock = FALSE; + DBUG_ASSERT(index->is_primary() == pk); + trx = thr_get_trx(thr); DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd, @@ -1984,7 +2008,8 @@ row_ins_check_foreign_constraints( foreign = *it; - if (foreign->foreign_index == index) { + if (foreign->foreign_index == index + || (pk && !foreign->foreign_index)) { dict_table_t* ref_table = NULL; dict_table_t* referenced_table = foreign->referenced_table; @@ -3196,7 +3221,7 @@ row_ins_clust_index_entry( if (!index->table->foreign_set.empty()) { err = row_ins_check_foreign_constraints( - index->table, index, entry, thr); + index->table, index, true, entry, thr); if (err != DB_SUCCESS) { DBUG_RETURN(err); @@ -3277,7 +3302,7 @@ row_ins_sec_index_entry( if (!index->table->foreign_set.empty()) { err = row_ins_check_foreign_constraints(index->table, index, - entry, thr); + false, entry, thr); if (err != DB_SUCCESS) { return(err); diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 43808f157d5..836785b935b 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2901,7 +2901,7 @@ row_discard_tablespace_begin( dict_table_t* table; table = dict_table_open_on_name( - name, TRUE, FALSE, DICT_ERR_IGNORE_NONE); + name, TRUE, FALSE, DICT_ERR_IGNORE_FK_NOKEY); if (table) { dict_stats_wait_bg_to_stop_using_table(table, trx); @@ -3279,7 +3279,7 @@ row_drop_table_from_cache( dict_table_remove_from_cache(table); - if (dict_load_table(tablename, true, DICT_ERR_IGNORE_NONE)) { + if (dict_load_table(tablename, true, DICT_ERR_IGNORE_FK_NOKEY)) { ib::error() << "Not able to remove table " << ut_get_name(trx, tablename) << " from the dictionary cache!"; @@ -4193,7 +4193,7 @@ row_rename_table_for_mysql( dict_locked = trx->dict_operation_lock_mode == RW_X_LATCH; table = dict_table_open_on_name(old_name, dict_locked, FALSE, - DICT_ERR_IGNORE_NONE); + DICT_ERR_IGNORE_FK_NOKEY); /* We look for pattern #P# to see if the table is partitioned MySQL table. */ @@ -4241,7 +4241,7 @@ row_rename_table_for_mysql( par_case_name, old_name, FALSE); #endif table = dict_table_open_on_name(par_case_name, dict_locked, FALSE, - DICT_ERR_IGNORE_NONE); + DICT_ERR_IGNORE_FK_NOKEY); } if (!table) { diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index c194a4dc330..4e084400ed6 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -9005,10 +9005,12 @@ bool ha_mroonga::is_foreign_key_field(const char *table_name, grn_obj *range = grn_ctx_at(ctx, grn_obj_get_range(ctx, column)); if (!range) { + grn_obj_unlink(ctx, column); DBUG_RETURN(false); } if (!mrn::grn::is_table(range)) { + grn_obj_unlink(ctx, column); DBUG_RETURN(false); } @@ -9022,6 +9024,7 @@ bool ha_mroonga::is_foreign_key_field(const char *table_name, DBUG_RETURN(true); } + grn_obj_unlink(ctx, column); DBUG_RETURN(false); } |