diff --git a/cmake/maintainer.cmake b/cmake/maintainer.cmake index 86c5f289cac..1f40324d5ca 100644 --- a/cmake/maintainer.cmake +++ b/cmake/maintainer.cmake @@ -41,9 +41,12 @@ SET(MY_WARNING_FLAGS -Wvla -Wwrite-strings -Wcast-function-type-strict - -Wframe-larger-than=16384 ) +IF(NOT (WITH_MSAN OR WITH_ASAN OR WITH_UBSAN)) + SET(MY_WARNING_FLAGS ${MY_WARNING_FLAGS} -Wframe-larger-than=16384) +ENDIF() + # Warning flags that are in testing before moving # to MY_WARNING_FLAGS if stable. SET(MY_WARNING_FLAGS_NON_FATAL diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt index 06dc8900968..00fe76433ca 100644 --- a/extra/CMakeLists.txt +++ b/extra/CMakeLists.txt @@ -82,6 +82,14 @@ IF(WITH_INNOBASE_STORAGE_ENGINE) ) + # clang ~16+ with return values being undefined is resolved by basic optimization + # compiler flags for the function mach_read_from_2 (per MDEV-36316) + IF(WITH_MSAN AND CMAKE_BUILD_TYPE STREQUAL "Debug") + SET_SOURCE_FILES_PROPERTIES( + ${INNOBASE_SOURCES} + innochecksum.cc + PROPERTIES COMPILE_FLAGS -Og) + ENDIF() MYSQL_ADD_EXECUTABLE(innochecksum innochecksum.cc ${INNOBASE_SOURCES}) TARGET_LINK_LIBRARIES(innochecksum mysys mysys_ssl) ADD_DEPENDENCIES(innochecksum GenError) diff --git a/include/my_attribute.h b/include/my_attribute.h index 2ffd65fae3d..04f6a62b4a1 100644 --- a/include/my_attribute.h +++ b/include/my_attribute.h @@ -91,9 +91,22 @@ _Pragma("GCC diagnostic ignored \"-Wframe-larger-than=\"") #define PRAGMA_REENABLE_CHECK_STACK_FRAME \ _Pragma("GCC diagnostic pop") +/* + The following check is for older gcc version that allocates + a lot of stack during startup that does not need to be checked +*/ + +#if !defined(__clang__) && __GNUC__ < 13 +#define PRAGMA_DISABLE_CHECK_STACK_FRAME_EXTRA PRAGMA_DISABLE_CHECK_STACK_FRAME #else +#define PRAGMA_DISABLE_CHECK_STACK_FRAME_EXTRA +#endif /* !defined(__clang__) && __GNUC__ < 13 */ + +#else /*! __GNUC__ */ #define PRAGMA_DISABLE_CHECK_STACK_FRAME #define PRAGMA_REENABLE_CHECK_STACK_FRAME -#endif +#define PRAGMA_DISABLE_CHECK_STACK_FRAME +#define PRAGMA_DISABLE_CHECK_STACK_FRAME_EXTRA +#endif /* __GNUC__ */ #endif /* _my_attribute_h */ diff --git a/include/my_pthread.h b/include/my_pthread.h index 5dceacb6399..9157e8204bc 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -668,7 +668,17 @@ extern void my_mutex_end(void); We need to have at least 256K stack to handle calls to myisamchk_init() with the current number of keys and key parts. */ -# if defined(__SANITIZE_ADDRESS__) || defined(WITH_UBSAN) +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif +#if defined(__clang__) && __has_feature(memory_sanitizer) && !defined(DBUG_OFF) +/* + MSAN in Debug with clang-20.1 required more memory to complete + mtr begin/end checks. The result without increase was MSAN + errors triggered on a call instruction. +*/ +# define DEFAULT_THREAD_STACK (2L<<20) +# elif defined(__SANITIZE_ADDRESS__) || defined(WITH_UBSAN) /* Optimized WITH_ASAN=ON executables produced by GCC 12.3.0, GCC 13.2.0, or clang 16.0.6 diff --git a/include/my_time.h b/include/my_time.h index 9f3e61b944f..90a8885a293 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -230,7 +230,6 @@ static inline longlong sec_part_unshift(longlong second_part, uint digits) /* Date/time rounding and truncation functions */ static inline long my_time_fraction_remainder(long nr, uint decimals) { - DBUG_ASSERT(decimals <= TIME_SECOND_PART_DIGITS); return nr % (long) log_10_int[TIME_SECOND_PART_DIGITS - decimals]; } static inline void my_datetime_trunc(MYSQL_TIME *ltime, uint decimals) diff --git a/mysql-test/include/no_msan_without_big.inc b/mysql-test/include/no_msan_without_big.inc new file mode 100644 index 00000000000..158b3986768 --- /dev/null +++ b/mysql-test/include/no_msan_without_big.inc @@ -0,0 +1,8 @@ +# Slow with MSAN, but if mtr --big-test specified, then it should complete +if (!$BIG_TEST) +{ + if (`select count(*) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like "MSAN%"`) + { + --skip Can't be run WITH_MSAN unless using --big-test + } +} diff --git a/mysql-test/include/not_msan.inc b/mysql-test/include/not_msan.inc index ca1e2c1d7bd..678139199a2 100644 --- a/mysql-test/include/not_msan.inc +++ b/mysql-test/include/not_msan.inc @@ -1,4 +1,5 @@ -# This file should only be used with tests that are too big or slow for MSAN. +# This file should only be used with tests that are too big or slow for MSAN (even with --big-test). +# Use no_msan_without_big instead unless this really won't complete in a test timeout period. if (`select count(*) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like "MSAN%"`) { diff --git a/mysql-test/include/not_msan_with_debug.inc b/mysql-test/include/not_msan_with_debug.inc new file mode 100644 index 00000000000..155e05991a0 --- /dev/null +++ b/mysql-test/include/not_msan_with_debug.inc @@ -0,0 +1,9 @@ +# This file should only be used with tests that are too big or slow for MSAN with Debug. + +if (`select count(*) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like "MSAN%"`) +{ + if (`select version() like '%debug%'`) + { + --skip Can't be run WITH_MSAN and CMAKE_BUILD_TYPE=Debug + } +} diff --git a/mysql-test/main/alter_table_lock.test b/mysql-test/main/alter_table_lock.test index bd26c1ac7d0..500cc3ced57 100644 --- a/mysql-test/main/alter_table_lock.test +++ b/mysql-test/main/alter_table_lock.test @@ -1,5 +1,3 @@ ---source include/not_msan.inc - --echo # --echo # MDEV-23836: Assertion `! is_set() || m_can_overwrite_status' in --echo # Diagnostics_area::set_error_status (interrupted ALTER TABLE under LOCK) diff --git a/mysql-test/main/backup_lock.result b/mysql-test/main/backup_lock.result index 488e81fd6d4..ced757265b2 100644 --- a/mysql-test/main/backup_lock.result +++ b/mysql-test/main/backup_lock.result @@ -266,6 +266,7 @@ col1 SET AUTOCOMMIT = 0; UPDATE t_permanent_innodb SET col1 = 9; UPDATE t_permanent_aria SET col1 = 9; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction UPDATE t_permanent_myisam SET col1 = 9; ERROR HY000: Lock wait timeout exceeded; try restarting transaction UPDATE t_permanent_aria2 SET col1 = 9; diff --git a/mysql-test/main/backup_lock.test b/mysql-test/main/backup_lock.test index f86f2f3670e..015041babaf 100644 --- a/mysql-test/main/backup_lock.test +++ b/mysql-test/main/backup_lock.test @@ -328,6 +328,7 @@ select * from t_permanent_aria2; SET AUTOCOMMIT = 0; UPDATE t_permanent_innodb SET col1 = 9; +--error ER_LOCK_WAIT_TIMEOUT UPDATE t_permanent_aria SET col1 = 9; --error ER_LOCK_WAIT_TIMEOUT UPDATE t_permanent_myisam SET col1 = 9; diff --git a/mysql-test/main/check_constraint.result b/mysql-test/main/check_constraint.result index 3ba0f12e023..601acf0c0d6 100644 --- a/mysql-test/main/check_constraint.result +++ b/mysql-test/main/check_constraint.result @@ -139,7 +139,7 @@ drop table t1; create or replace table t1( c1 int auto_increment primary key, check( c1 > 0 or c1 is null ) ); ERROR HY000: Function or expression 'AUTO_INCREMENT' cannot be used in the CHECK clause of `c1` create table t1 (a int check (@b in (select user from mysql.user))); -ERROR HY000: Function or expression 'select ...' cannot be used in the CHECK clause of `a` +ERROR 42000: CHECK does not support subqueries or stored functions create table t1 (a int check (a > @b)); ERROR HY000: Function or expression '@b' cannot be used in the CHECK clause of `a` create table t1 (a int check (a = 1)); diff --git a/mysql-test/main/check_constraint.test b/mysql-test/main/check_constraint.test index a5abe32bc05..d832a0e137e 100644 --- a/mysql-test/main/check_constraint.test +++ b/mysql-test/main/check_constraint.test @@ -87,7 +87,7 @@ create or replace table t1( c1 int auto_increment primary key, check( c1 > 0 or # # MDEV-12421 Check constraint with query crashes server and renders DB unusable # ---error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +--error ER_SUBQUERIES_NOT_SUPPORTED create table t1 (a int check (@b in (select user from mysql.user))); --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED create table t1 (a int check (a > @b)); diff --git a/mysql-test/main/cte_recursive.test b/mysql-test/main/cte_recursive.test index 4ecdaa4f0fa..6e2dd3b1f16 100644 --- a/mysql-test/main/cte_recursive.test +++ b/mysql-test/main/cte_recursive.test @@ -1,6 +1,6 @@ --source include/default_optimizer_switch.inc # This is too slow on MSAN ---source include/not_msan.inc +--source include/no_msan_without_big.inc --source include/not_valgrind.inc --source include/have_innodb.inc diff --git a/mysql-test/main/intersect_all.result b/mysql-test/main/intersect_all.result index b1afcee2651..eeb0c8b5892 100644 --- a/mysql-test/main/intersect_all.result +++ b/mysql-test/main/intersect_all.result @@ -1006,3 +1006,113 @@ NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 union all /* select#4 */ select `__4`.`a` AS `a` from (/* select#2 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where `test`.`t2`.`a` < 5 intersect all /* select#3 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where `test`.`t3`.`a` < 5) `__4` drop table t1,t2,t3; +# +# MDEV-25158 Segfault on INTERSECT ALL with UNION in Oracle mode +# +create table t3 (x int); +create table u3 (x int); +create table i3 (x int); +explain SELECT * from t3 union select * from u3 intersect all select * from i3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 system NULL NULL NULL NULL 0 Const row not found +4 UNION ALL NULL NULL NULL NULL 2 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table +3 INTERSECT NULL NULL NULL NULL NULL NULL NULL no matching row in const table +NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +set sql_mode= 'oracle'; +explain SELECT * from t3 union select * from u3 intersect all select * from i3; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 system NULL NULL NULL NULL 0 Const row not found +2 UNION u3 system NULL NULL NULL NULL 0 Const row not found +3 INTERSECT i3 system NULL NULL NULL NULL 0 Const row not found +NULL UNIT RESULT ALL NULL NULL NULL NULL NULL +select * from t3 union select * from u3 intersect select * from i3; +x +SELECT * from t3 union select * from u3 intersect all select * from i3; +x +insert into t3 values (0); +insert into i3 values (0); +Select * from t3 union select * from u3 intersect select * from i3; +x +0 +SELECT * FROM t3 UNION SELECT * FROM u3 INTERSECT ALL SELECT * FROM i3; +x +0 +drop tables t3, u3, i3; +# First line of these results is column names, not the result +# (pay attention to "affected rows") +values (1, 2) union all values (1, 2); +1 2 +1 2 +1 2 +affected rows: 2 +values (1, 2) union all values (1, 2) union values (4, 3) union all values (4, 3); +1 2 +1 2 +4 3 +4 3 +affected rows: 3 +values (1, 2) union all values (1, 2) union values (4, 3) union all values (4, 3) union all values (1, 2); +1 2 +1 2 +4 3 +4 3 +1 2 +affected rows: 4 +values (1, 2) union all values (1, 2) union values (4, 3) union all values (4, 3) union all values (1, 2) union values (1, 2); +1 2 +1 2 +4 3 +affected rows: 2 +create table t1 (a int, b int); +create table t2 like t1; +insert t1 values (1, 2), (1, 2), (1, 2), (2, 3), (2, 3), (3, 4), (3, 4); +insert t2 values (1, 2), (1, 2), (2, 3), (2, 3), (2, 3), (2, 3), (4, 5); +select * from t1 intersect select * from t2; +a b +1 2 +2 3 +select * from t1 intersect all select * from t2; +a b +1 2 +2 3 +1 2 +2 3 +# Default: first INTERSECT ALL, then UNION +# Oracle: first UNION, then INTERSECT ALL +select * from t1 union values (1, 2) intersect all select * from t2; +a b +1 2 +2 3 +select * from t1 union (values (1, 2) intersect all select * from t2); +a b +1 2 +2 3 +3 4 +(select * from t1 union values (1, 2)) intersect all select * from t2; +a b +1 2 +2 3 +select * from t1 intersect all select * from t2 union values (1, 2); +a b +1 2 +2 3 +1 2 +2 3 +select * from t1 intersect all (select * from t2 union values (1, 2)); +a b +1 2 +2 3 +(select * from t1 intersect all select * from t2) union values (1, 2); +a b +1 2 +2 3 +explain select * from t1 intersect all select * from t2 union values (1, 2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 7 +2 INTERSECT t2 ALL NULL NULL NULL NULL 7 +3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNIT RESULT ALL NULL NULL NULL NULL NULL +drop tables t1, t2; +set sql_mode= default; diff --git a/mysql-test/main/intersect_all.test b/mysql-test/main/intersect_all.test index 5d2b038fde9..8217e4ebcbc 100644 --- a/mysql-test/main/intersect_all.test +++ b/mysql-test/main/intersect_all.test @@ -325,4 +325,70 @@ select * from t2 where a < 5 intersect all select * from t3 where a < 5; -drop table t1,t2,t3; \ No newline at end of file +drop table t1,t2,t3; + +--echo # +--echo # MDEV-25158 Segfault on INTERSECT ALL with UNION in Oracle mode +--echo # +create table t3 (x int); +create table u3 (x int); +create table i3 (x int); +explain SELECT * from t3 union select * from u3 intersect all select * from i3; +set sql_mode= 'oracle'; +explain SELECT * from t3 union select * from u3 intersect all select * from i3; +select * from t3 union select * from u3 intersect select * from i3; +SELECT * from t3 union select * from u3 intersect all select * from i3; +insert into t3 values (0); +insert into i3 values (0); +Select * from t3 union select * from u3 intersect select * from i3; +SELECT * FROM t3 UNION SELECT * FROM u3 INTERSECT ALL SELECT * FROM i3; +drop tables t3, u3, i3; + +--enable_info +--echo # First line of these results is column names, not the result +--echo # (pay attention to "affected rows") + +# MSSQL: +# 1 2 +# 1 2 +values (1, 2) union all values (1, 2); + +# MSSQL: +# 1 2 +# 4 3 +# 4 3 +values (1, 2) union all values (1, 2) union values (4, 3) union all values (4, 3); + +# MSSQL: +# 1 2 +# 4 3 +# 4 3 +# 1 2 +values (1, 2) union all values (1, 2) union values (4, 3) union all values (4, 3) union all values (1, 2); + +# MSSQL: +# 1 2 +# 4 3 +values (1, 2) union all values (1, 2) union values (4, 3) union all values (4, 3) union all values (1, 2) union values (1, 2); +--disable_info + +create table t1 (a int, b int); +create table t2 like t1; +insert t1 values (1, 2), (1, 2), (1, 2), (2, 3), (2, 3), (3, 4), (3, 4); +insert t2 values (1, 2), (1, 2), (2, 3), (2, 3), (2, 3), (2, 3), (4, 5); +select * from t1 intersect select * from t2; +select * from t1 intersect all select * from t2; +--echo # Default: first INTERSECT ALL, then UNION +--echo # Oracle: first UNION, then INTERSECT ALL +# VIEW is stored and executed normal mode (see Sql_mode_save_for_frm_handling) +--disable_view_protocol +select * from t1 union values (1, 2) intersect all select * from t2; +--enable_view_protocol +select * from t1 union (values (1, 2) intersect all select * from t2); +(select * from t1 union values (1, 2)) intersect all select * from t2; +select * from t1 intersect all select * from t2 union values (1, 2); +select * from t1 intersect all (select * from t2 union values (1, 2)); +(select * from t1 intersect all select * from t2) union values (1, 2); +explain select * from t1 intersect all select * from t2 union values (1, 2); +drop tables t1, t2; +set sql_mode= default; diff --git a/mysql-test/main/join_cache_notasan.cnf b/mysql-test/main/join_cache_notasan.cnf new file mode 100644 index 00000000000..7b2fb3bcb15 --- /dev/null +++ b/mysql-test/main/join_cache_notasan.cnf @@ -0,0 +1,5 @@ +!include include/default_my.cnf + +[ENV] +MSAN_OPTIONS=allocator_may_return_null=1:abort_on_error=1 + diff --git a/mysql-test/main/join_cache_notasan.result b/mysql-test/main/join_cache_notasan.result index 3cec949f5c6..885eece83d6 100644 --- a/mysql-test/main/join_cache_notasan.result +++ b/mysql-test/main/join_cache_notasan.result @@ -1,3 +1,4 @@ +call mtr.add_suppression("MemorySanitizer failed to allocate"); # # MDEV-28217 Incorrect Join Execution When Controlling Join Buffer Size # diff --git a/mysql-test/main/join_cache_notasan.test b/mysql-test/main/join_cache_notasan.test index c2ff670f044..5271d3fae9c 100644 --- a/mysql-test/main/join_cache_notasan.test +++ b/mysql-test/main/join_cache_notasan.test @@ -4,11 +4,13 @@ --source include/have_64bit.inc # Disable asan it asan builds crashes when trying to allocate too much memory --source include/not_asan.inc ---source include/not_msan.inc # Valgrind is useful here, but very slow as lots of memory is allocated --source include/no_valgrind_without_big.inc --source include/have_innodb.inc +# MSAN runs, but ignore its notice. ER_OUTOFMEMORY is expected by tests +call mtr.add_suppression("MemorySanitizer failed to allocate"); + --echo # --echo # MDEV-28217 Incorrect Join Execution When Controlling Join Buffer Size --echo # diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 48b12dfa9db..a5ae3c067de 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -1936,7 +1936,6 @@ thread-pool-oversubscribe 3 thread-pool-prio-kickup-timer 1000 thread-pool-priority auto thread-pool-stall-limit 500 -thread-stack 299008 time-format %H:%i:%s tmp-disk-table-size 18446744073709551615 tmp-memory-table-size 16777216 diff --git a/mysql-test/main/mysqld--help.test b/mysql-test/main/mysqld--help.test index 239ee9269d6..04cf1a69e3f 100644 --- a/mysql-test/main/mysqld--help.test +++ b/mysql-test/main/mysqld--help.test @@ -30,7 +30,7 @@ perl; table-open-cache table-open-cache-instances max-connections server-uid tls-version version.* password-reuse-check provider-bzip2 provider-lzma provider-lzo - password-reuse-check-interval analyze-max-length/; + password-reuse-check-interval analyze-max-length thread-stack/; # Plugins which may or may not be there: @plugins=qw/innodb archive blackhole federated partition s3 diff --git a/mysql-test/main/sum_distinct-big.test b/mysql-test/main/sum_distinct-big.test index 8820c191ae9..54fc676740f 100644 --- a/mysql-test/main/sum_distinct-big.test +++ b/mysql-test/main/sum_distinct-big.test @@ -5,7 +5,7 @@ --source include/big_test.inc # Test will take more than one hour with valgrind --source include/not_valgrind.inc ---source include/not_msan.inc +--source include/not_msan_with_debug.inc --source include/have_innodb.inc --source include/have_sequence.inc diff --git a/mysql-test/suite/funcs_1/t/myisam_views-big.test b/mysql-test/suite/funcs_1/t/myisam_views-big.test index 60fe1b8eaba..7199542d3d6 100644 --- a/mysql-test/suite/funcs_1/t/myisam_views-big.test +++ b/mysql-test/suite/funcs_1/t/myisam_views-big.test @@ -4,8 +4,7 @@ # because of a pair of slow Solaris Sparc machines in pb2, # this test is marked as big: --source include/big_test.inc -# This test often times out with MSAN ---source include/not_msan.inc +--source include/not_msan_with_debug.inc # MyISAM tables should be used # diff --git a/mysql-test/suite/innodb_gis/t/rtree_purge.test b/mysql-test/suite/innodb_gis/t/rtree_purge.test index f89f590acf0..4efb7213e28 100644 --- a/mysql-test/suite/innodb_gis/t/rtree_purge.test +++ b/mysql-test/suite/innodb_gis/t/rtree_purge.test @@ -4,8 +4,7 @@ --source include/innodb_page_size.inc --source include/have_sequence.inc --source include/not_valgrind.inc -# This test often times out with MSAN ---source include/not_msan.inc +--source include/no_msan_without_big.inc create table t ( b point not null,d point not null, spatial key (d),spatial key (b) diff --git a/mysql-test/suite/maria/max_length.test b/mysql-test/suite/maria/max_length.test index 02df51b33d7..c6859d5267d 100644 --- a/mysql-test/suite/maria/max_length.test +++ b/mysql-test/suite/maria/max_length.test @@ -6,7 +6,7 @@ --source include/big_test.inc # This test is too slow for valgrind --source include/not_valgrind.inc ---source include/not_msan.inc +--source include/not_msan_with_debug.inc drop table if exists t1,t2; diff --git a/mysql-test/suite/perfschema/t/statement_digest_long_query.test b/mysql-test/suite/perfschema/t/statement_digest_long_query.test index efa33800b58..23ff15c9102 100644 --- a/mysql-test/suite/perfschema/t/statement_digest_long_query.test +++ b/mysql-test/suite/perfschema/t/statement_digest_long_query.test @@ -6,6 +6,7 @@ --source include/have_perfschema.inc # Test requires: sp-protocol/ps-protocol/view-protocol/cursor-protocol disabled --source include/no_protocol.inc +--source include/not_msan_with_debug.inc # Thread stack overrun on solaris let $have_solaris = `select convert(@@version_compile_os using latin1) LIKE ("solaris%")`; if ($have_solaris) diff --git a/mysql-test/suite/s3/clone.result b/mysql-test/suite/s3/clone.result new file mode 100644 index 00000000000..a33c8c4259a --- /dev/null +++ b/mysql-test/suite/s3/clone.result @@ -0,0 +1,12 @@ +# +# SELECT using ror_merged scan fails with s3 tables +# +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 'test.t1' +CREATE TABLE t1 (a INT, b INT, KEY(a), KEY(b)) ENGINE=Aria; +INSERT INTO t1 VALUES (0,0),(0,10),(3,10); +ALTER TABLE t1 ENGINE=S3; +SELECT * FROM t1 WHERE a = 99 OR b = 2; +a b +DROP TABLE t1; diff --git a/mysql-test/suite/s3/clone.test b/mysql-test/suite/s3/clone.test new file mode 100644 index 00000000000..5695257c404 --- /dev/null +++ b/mysql-test/suite/s3/clone.test @@ -0,0 +1,14 @@ +--source include/have_s3.inc +--source include/have_sequence.inc +--source include/have_innodb.inc + +--echo # +--echo # SELECT using ror_merged scan fails with s3 tables +--echo # + +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a INT, b INT, KEY(a), KEY(b)) ENGINE=Aria; +INSERT INTO t1 VALUES (0,0),(0,10),(3,10); +ALTER TABLE t1 ENGINE=S3; +SELECT * FROM t1 WHERE a = 99 OR b = 2; +DROP TABLE t1; diff --git a/mysql-test/suite/sys_vars/t/thread_stack_basic.test b/mysql-test/suite/sys_vars/t/thread_stack_basic.test index 39f120e0de1..a1f52576d15 100644 --- a/mysql-test/suite/sys_vars/t/thread_stack_basic.test +++ b/mysql-test/suite/sys_vars/t/thread_stack_basic.test @@ -3,6 +3,7 @@ # --source include/not_asan.inc --source include/not_ubsan.inc +--source include/not_msan.inc --replace_result 392192 299008 select @@global.thread_stack; --error ER_INCORRECT_GLOBAL_LOCAL_VAR diff --git a/mysql-test/suite/vcol/r/not_supported.result b/mysql-test/suite/vcol/r/not_supported.result index 37ce4865dcc..034bca6a97c 100644 --- a/mysql-test/suite/vcol/r/not_supported.result +++ b/mysql-test/suite/vcol/r/not_supported.result @@ -55,3 +55,34 @@ ERROR HY000: Function or expression 'b' cannot be used in the GENERATED ALWAYS A # # End of 10.3 tests # +# +# MDEV-29155 CREATE OR REPLACE with self-referencing CHECK hangs forever, cannot be killed +# +create table t1 (a int); +create table t2 (b int) +# create or replace table t (b int); +create table t3 (c int, check(exists(select a from t1) or exists(select b from t2))); +ERROR 42000: CHECK does not support subqueries or stored functions +create table t3 (c int, check(exists(select c from t3))); +ERROR 42000: CHECK does not support subqueries or stored functions +create table t3 (d int); +create or replace table t3 (c int, check(exists(select a from t1) or exists(select b from t2))); +ERROR 42000: CHECK does not support subqueries or stored functions +drop table t3; +create table t3 (d int); +create or replace table t3 (c int, check(exists(select c from t3))); +ERROR 42000: CHECK does not support subqueries or stored functions +drop table t3; +create table t3 (c int); +alter table t3 add check(exists(select a from t1) or exists(select b from t2)); +ERROR 42000: CHECK does not support subqueries or stored functions +alter table t3 add check(exists(select c from t3)); +ERROR 42000: CHECK does not support subqueries or stored functions +create table t3 (c int default (select a from t1)); +ERROR HY000: Function or expression 'select ...' cannot be used in the DEFAULT clause of `c` +create table t3 (c int, d int generated always as (select a from t1 limit 1)); +ERROR HY000: Function or expression 'select ...' cannot be used in the GENERATED ALWAYS AS clause of `d` +drop tables t1, t2, t3; +# +# End of 10.4 tests +# diff --git a/mysql-test/suite/vcol/t/not_supported.test b/mysql-test/suite/vcol/t/not_supported.test index d58b207a7eb..143c0160084 100644 --- a/mysql-test/suite/vcol/t/not_supported.test +++ b/mysql-test/suite/vcol/t/not_supported.test @@ -64,3 +64,36 @@ create table t1 (a int auto_increment primary key, --echo # --echo # End of 10.3 tests --echo # + +--echo # +--echo # MDEV-29155 CREATE OR REPLACE with self-referencing CHECK hangs forever, cannot be killed +--echo # +create table t1 (a int); +create table t2 (b int) +# create or replace table t (b int); +--error ER_SUBQUERIES_NOT_SUPPORTED +create table t3 (c int, check(exists(select a from t1) or exists(select b from t2))); +--error ER_SUBQUERIES_NOT_SUPPORTED +create table t3 (c int, check(exists(select c from t3))); +create table t3 (d int); +--error ER_SUBQUERIES_NOT_SUPPORTED +create or replace table t3 (c int, check(exists(select a from t1) or exists(select b from t2))); +drop table t3; +create table t3 (d int); +--error ER_SUBQUERIES_NOT_SUPPORTED +create or replace table t3 (c int, check(exists(select c from t3))); +drop table t3; +create table t3 (c int); +--error ER_SUBQUERIES_NOT_SUPPORTED +alter table t3 add check(exists(select a from t1) or exists(select b from t2)); +--error ER_SUBQUERIES_NOT_SUPPORTED +alter table t3 add check(exists(select c from t3)); +--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t3 (c int default (select a from t1)); +--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t3 (c int, d int generated always as (select a from t1 limit 1)); +drop tables t1, t2, t3; + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/sql/handler.cc b/sql/handler.cc index 705fd0370e0..82444061834 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1576,6 +1576,12 @@ uint ha_count_rw_2pc(THD *thd, bool all) /** Check if we can skip the two-phase commit. + @param thd Thread handler + @param ha_list List of all engines participating on the commit + @param all True if this is final commit (not statement commit) + @param no_rollback Set to 1 if one of the engines doing writes does + not support rollback + A helper function to evaluate if two-phase commit is mandatory. As a side effect, propagates the read-only/read-write flags of the statement transaction to its enclosing normal transaction. @@ -1594,16 +1600,21 @@ uint ha_count_rw_2pc(THD *thd, bool all) uint ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list, - bool all) + bool all, bool *no_rollback) { /* The number of storage engines that have actual changes. */ unsigned rw_ha_count= 0; Ha_trx_info *ha_info; + *no_rollback= false; for (ha_info= ha_list; ha_info; ha_info= ha_info->next()) { if (ha_info->is_trx_read_write()) + { ++rw_ha_count; + if (ha_info->is_trx_no_rollback()) + *no_rollback= true; + } if (! all) { @@ -1626,7 +1637,18 @@ ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list, information up, and the need for two-phase commit has been already established. Break the loop prematurely. */ - break; + if (*no_rollback == 0) + { + while ((ha_info= ha_info->next())) + { + if (ha_info->is_trx_read_write() && ha_info->is_trx_no_rollback()) + { + *no_rollback= 1; + break; + } + } + break; + } } } return rw_ha_count; @@ -1762,7 +1784,9 @@ int ha_commit_trans(THD *thd, bool all) if (is_real_trans) /* not a statement commit */ thd->stmt_map.close_transient_cursors(); - uint rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, ha_info, all); + bool no_rollback; + uint rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, ha_info, all, + &no_rollback); /* rw_trans is TRUE when we in a transaction changing data */ bool rw_trans= is_real_trans && rw_ha_count > 0; MDL_request mdl_backup; @@ -1775,7 +1799,7 @@ int ha_commit_trans(THD *thd, bool all) calling ha_commit_trans() from spader_commit(). */ - if (rw_trans && !thd->backup_commit_lock) + if ((rw_trans || no_rollback) && !thd->backup_commit_lock) { /* Acquire a metadata lock which will ensure that COMMIT is blocked @@ -2115,7 +2139,9 @@ int ha_commit_one_phase(THD *thd, bool all) static bool is_ro_1pc_trans(THD *thd, Ha_trx_info *ha_info, bool all, bool is_real_trans) { - uint rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, ha_info, all); + bool no_rollback; + uint rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, ha_info, all, + &no_rollback); bool rw_trans= is_real_trans && (rw_ha_count > (thd->is_current_stmt_binlog_disabled()?0U:1U)); @@ -3294,12 +3320,16 @@ int ha_delete_table(THD *thd, handlerton *hton, const char *path, handler *handler::clone(const char *name, MEM_ROOT *mem_root) { + int error= 0; handler *new_handler= get_new_handler(table->s, mem_root, ht); if (!new_handler) return NULL; if (new_handler->set_ha_share_ref(ha_share)) + { + error= ER_OUT_OF_RESOURCES; goto err; + } /* TODO: Implement a more efficient way to have more than one index open for @@ -3308,14 +3338,17 @@ handler *handler::clone(const char *name, MEM_ROOT *mem_root) This is not critical as the engines already have the table open and should be able to use the original instance of the table. */ - if (new_handler->ha_open(table, name, table->db_stat, - HA_OPEN_IGNORE_IF_LOCKED, mem_root)) + if ((error= new_handler->ha_open(table, name, + table->db_stat & HA_READ_ONLY ? + O_RDONLY : O_RDWR, + HA_OPEN_IGNORE_IF_LOCKED, mem_root))) goto err; new_handler->handler_stats= handler_stats; return new_handler; err: + new_handler->print_error(error, MYF(0)); delete new_handler; return NULL; } @@ -5145,6 +5178,9 @@ void handler::mark_trx_read_write_internal() */ if (table_share == NULL || table_share->tmp_table == NO_TMP_TABLE) ha_info->set_trx_read_write(); + /* Mark if we are using a table that cannot do rollback */ + if (ht->flags & HTON_NO_ROLLBACK) + ha_info->set_trx_no_rollback(); } } diff --git a/sql/handler.h b/sql/handler.h index 51c4de0003a..e3ffd48f4f2 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1944,6 +1944,16 @@ public: DBUG_ASSERT(is_started()); return m_flags & (int) TRX_READ_WRITE; } + void set_trx_no_rollback() + { + DBUG_ASSERT(is_started()); + m_flags|= (int) TRX_NO_ROLLBACK; + } + bool is_trx_no_rollback() const + { + DBUG_ASSERT(is_started()); + return m_flags & (int) TRX_NO_ROLLBACK; + } bool is_started() const { return m_ht != NULL; } /** Mark this transaction read-write if the argument is read-write. */ void coalesce_trx_with(const Ha_trx_info *stmt_trx) @@ -1968,7 +1978,7 @@ public: return m_ht; } private: - enum { TRX_READ_ONLY= 0, TRX_READ_WRITE= 1 }; + enum { TRX_READ_ONLY= 0, TRX_READ_WRITE= 1, TRX_NO_ROLLBACK= 2 }; /** Auxiliary, used for ha_list management */ Ha_trx_info *m_next; /** @@ -5436,7 +5446,7 @@ uint ha_count_rw_all(THD *thd, Ha_trx_info **ptr_ha_info); bool non_existing_table_error(int error); uint ha_count_rw_2pc(THD *thd, bool all); uint ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list, - bool all); + bool all, bool *no_rollback); int get_select_field_pos(Alter_info *alter_info, int select_field_count, bool versioned); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 65e088fd971..8bb2eab8bf9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8876,7 +8876,7 @@ char *set_server_version(char *buf, size_t size) bool is_log= opt_log || global_system_variables.sql_log_slow || opt_bin_log; bool is_debug= IF_DBUG(!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"), 0); const char *is_valgrind= -#ifdef HAVE_valgrind +#if defined(HAVE_valgrind) && !__has_feature(memory_sanitizer) !strstr(MYSQL_SERVER_SUFFIX_STR, "-valgrind") ? "-valgrind" : #endif ""; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 7f3fece735f..c0cdbf0fc63 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1532,14 +1532,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler, if (!(file= head->file->clone(head->s->normalized_path.str, local_alloc))) { - /* - Manually set the error flag. Note: there seems to be quite a few - places where a failure could cause the server to "hang" the client by - sending no response to a query. ATM those are not real errors because - the storage engine calls in question happen to never fail with the - existing storage engines. - */ - my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */ + /* clone() has already generated an error message */ /* Caller will free the memory */ goto failure; /* purecov: inspected */ } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 20ba2ca7a66..4b2d38449e1 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5913,7 +5913,8 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, if (rpl_master_erroneous_autoinc(this)) { DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0); - auto_inc_intervals_forced.swap(&backup->auto_inc_intervals_forced); + backup->auto_inc_intervals_forced.copy_shallow(&auto_inc_intervals_forced); + MEM_UNDEFINED(&auto_inc_intervals_forced, sizeof auto_inc_intervals_forced); } #endif @@ -5961,7 +5962,7 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup) */ if (rpl_master_erroneous_autoinc(this)) { - backup->auto_inc_intervals_forced.swap(&auto_inc_intervals_forced); + auto_inc_intervals_forced.copy_shallow(&backup->auto_inc_intervals_forced); DBUG_ASSERT(backup->auto_inc_intervals_forced.nb_elements() == 0); } #endif @@ -8524,16 +8525,19 @@ void mariadb_sleep_for_space(unsigned int seconds) { THD *thd= current_thd; PSI_stage_info old_stage; + struct timespec abstime; if (!thd) { sleep(seconds); return; } - mysql_mutex_lock(&thd->LOCK_wakeup_ready); + set_timespec(abstime, seconds); + mysql_mutex_lock(&thd->LOCK_wakeup_ready); thd->ENTER_COND(&thd->COND_wakeup_ready, &thd->LOCK_wakeup_ready, &stage_waiting_for_disk_space, &old_stage); if (!thd->killed) - mysql_cond_wait(&thd->COND_wakeup_ready, &thd->LOCK_wakeup_ready); + mysql_cond_timedwait(&thd->COND_wakeup_ready, &thd->LOCK_wakeup_ready, + &abstime); thd->EXIT_COND(&old_stage); return; } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 78ed924d313..e5b863c4502 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -9981,6 +9981,13 @@ void init_fill_schema_files_row(TABLE* table) } +/* + gcc 7.5.0 uses a lot of stack at startup to resolve Column() expressions + Note, do not use PRAGMA_REENABLE_CHECK_STACK_FRAME later on in this file + as this causes compilation to fail. +*/ +PRAGMA_DISABLE_CHECK_STACK_FRAME_EXTRA + namespace Show { ST_FIELD_INFO referential_constraints_fields_info[]= diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 61306793343..f5252e12ccd 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -474,21 +474,30 @@ int select_unit::update_counter(Field* counter, longlong value) Try to disable index @retval - true index is disabled this time + true index is disabled and unfold is needed false this time did not disable the index */ bool select_unit_ext::disable_index_if_needed(SELECT_LEX *curr_sl) { + const bool oracle_mode= thd->variables.sql_mode & MODE_ORACLE; if (is_index_enabled && - (curr_sl == curr_sl->master_unit()->union_distinct || + ((!oracle_mode && + curr_sl == curr_sl->master_unit()->union_distinct) || !curr_sl->next_select()) ) { is_index_enabled= false; - if (table->file->ha_disable_indexes(key_map(0), false)) + int error= table->file->ha_disable_indexes(key_map(0), false); + if (error) + { + table->file->print_error(error, MYF(0)); + DBUG_ASSERT(0); return false; + } table->no_keyread=1; - return true; + /* In case of Oracle mode we unfold at the last operator */ + DBUG_ASSERT(!oracle_mode || !curr_sl->next_select()); + return oracle_mode || !curr_sl->distinct; } return false; } @@ -772,8 +781,7 @@ bool select_unit_ext::send_eof() next_sl && next_sl->get_linkage() == INTERSECT_TYPE && !next_sl->distinct; - bool need_unfold= (disable_index_if_needed(curr_sl) && - !curr_sl->distinct); + bool need_unfold= disable_index_if_needed(curr_sl); if (((curr_sl->distinct && !is_next_distinct) || curr_op_type == INTERSECT_ALL || @@ -781,7 +789,8 @@ bool select_unit_ext::send_eof() !need_unfold) { if (!next_sl) - DBUG_ASSERT(curr_op_type != INTERSECT_ALL); + DBUG_ASSERT((thd->variables.sql_mode & MODE_ORACLE) || + curr_op_type != INTERSECT_ALL); bool need_update_row; if (unlikely(table->file->ha_rnd_init_with_error(1))) return 1; @@ -1295,8 +1304,8 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, uint union_part_count= 0; select_result *tmp_result; bool is_union_select; - bool have_except= false, have_intersect= false, - have_except_all_or_intersect_all= false; + bool have_except= false, have_intersect= false; + have_except_all_or_intersect_all= false; bool instantiate_tmp_table= false; bool single_tvc= !first_sl->next_select() && first_sl->tvc; bool single_tvc_wo_order= single_tvc && !first_sl->order_list.elements; @@ -2160,6 +2169,7 @@ bool st_select_lex_unit::exec() bool first_execution= !executed; DBUG_ENTER("st_select_lex_unit::exec"); bool was_executed= executed; + int error; if (executed && !uncacheable && !describe) DBUG_RETURN(FALSE); @@ -2243,17 +2253,32 @@ bool st_select_lex_unit::exec() if (likely(!saved_error)) { records_at_start= table->file->stats.records; + + /* select_unit::send_data() writes rows to (temporary) table */ if (sl->tvc) sl->tvc->exec(sl); else sl->join->exec(); + /* + Allow UNION ALL to work: disable unique key. We cannot disable indexes + in the middle of the query because enabling indexes requires table to be empty + (see heap_enable_indexes()). So there is special union_distinct property + which is the rightmost distinct UNION in the expression and we release + the unique key after the last (rightmost) distinct UNION, therefore only the + subsequent UNION ALL work as non-distinct. + */ if (sl == union_distinct && !have_except_all_or_intersect_all && !(with_element && with_element->is_recursive)) { // This is UNION DISTINCT, so there should be a fake_select_lex DBUG_ASSERT(fake_select_lex != NULL); - if (table->file->ha_disable_indexes(key_map(0), false)) + error= table->file->ha_disable_indexes(key_map(0), false); + if (error) + { + table->file->print_error(error, MYF(0)); + DBUG_ASSERT(0); DBUG_RETURN(TRUE); + } table->no_keyread=1; } if (!sl->tvc) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index be7e918706a..b2b8aca2eb6 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5843,9 +5843,12 @@ opt_check_constraint: ; check_constraint: - CHECK_SYM '(' expr ')' + CHECK_SYM '(' + { Lex->clause_that_disallows_subselect= "CHECK"; } + expr ')' { - Virtual_column_info *v= add_virtual_expression(thd, $3); + Virtual_column_info *v= add_virtual_expression(thd, $4); + Lex->clause_that_disallows_subselect= NULL; if (unlikely(!v)) MYSQL_YYABORT; $$= v; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 5bdff535250..6a1103cc2ba 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -5377,7 +5377,8 @@ static Sys_var_charptr Sys_have_santitizer( "have_sanitizer", "If the server is compiled with sanitize (compiler option), this " "variable is set to the sanitizer mode used. Possible values are " - "ASAN (Address sanitizer) or UBSAN (The Undefined Behavior Sanitizer).", + "ASAN (Address sanitizer) and/or UBSAN (Undefined Behavior Sanitizer)," + " or MSAN (memory sanitizer).", READ_ONLY GLOBAL_VAR(have_sanitizer), NO_CMD_LINE, DEFAULT(SANITIZER_MODE)); #endif /* defined(__SANITIZE_ADDRESS__) || defined(WITH_UBSAN) */ diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index ccc55458200..fe0cedae330 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1467,7 +1467,8 @@ bool wsrep_check_mode_after_open_table (THD *thd, } // Check are we inside a transaction - uint rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, thd->transaction->all.ha_list, true); + bool not_used; + uint rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, thd->transaction->all.ha_list, true, ¬_used); bool changes= wsrep_has_changes(thd); // Roll back current stmt if exists diff --git a/storage/connect/bsonudf.cpp b/storage/connect/bsonudf.cpp index 0d617799a98..1ca10979ae2 100644 --- a/storage/connect/bsonudf.cpp +++ b/storage/connect/bsonudf.cpp @@ -192,7 +192,7 @@ my_bool BJNX::SetJpath(PGLOBAL g, char* path, my_bool jb) /*********************************************************************************/ /* Analyse array processing options. */ /*********************************************************************************/ -my_bool BJNX::SetArrayOptions(PGLOBAL g, char* p, int i, PSZ nm) +my_bool BJNX::SetArrayOptions(PGLOBAL g, char* p, int i) { int n = (int)strlen(p); my_bool dg = true, b = false; @@ -340,7 +340,7 @@ my_bool BJNX::ParseJpath(PGLOBAL g) // Jpath must be explicit if (a || *p == 0 || *p == '[' || IsNum(p)) { // Analyse intermediate array processing - if (SetArrayOptions(g, p, i, Nodes[i - 1].Key)) + if (SetArrayOptions(g, p, i)) return true; } else if (*p == '*') { diff --git a/storage/connect/bsonudf.h b/storage/connect/bsonudf.h index 90cabf72e21..7d7598574c0 100644 --- a/storage/connect/bsonudf.h +++ b/storage/connect/bsonudf.h @@ -116,7 +116,7 @@ public: PBSON MakeBinResult(UDF_ARGS* args, PBVAL top, ulong len, int n = 2); protected: - my_bool SetArrayOptions(PGLOBAL g, char* p, int i, PSZ nm); + my_bool SetArrayOptions(PGLOBAL g, char* p, int i); PVAL GetColumnValue(PGLOBAL g, PBVAL row, int i); PVAL ExpandArray(PGLOBAL g, PBVAL arp, int n); PVAL CalculateArray(PGLOBAL g, PBVAL arp, int n); diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index ee92a7b94c1..f48b3ef3c2d 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -113,7 +113,7 @@ my_bool JSNX::SetJpath(PGLOBAL g, char *path, my_bool jb) /*********************************************************************************/ /* Analyse array processing options. */ /*********************************************************************************/ -my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm) +my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i) { int n = (int)strlen(p); my_bool dg = true, b = false; @@ -263,7 +263,7 @@ my_bool JSNX::ParseJpath(PGLOBAL g) // Jpath must be explicit if (a || *p == 0 || *p == '[' || IsNum(p)) { // Analyse intermediate array processing - if (SetArrayOptions(g, p, i, Nodes[i-1].Key)) + if (SetArrayOptions(g, p, i)) return true; } else if (*p == '*') { diff --git a/storage/connect/jsonudf.h b/storage/connect/jsonudf.h index 782d17acb12..a7defed8e54 100644 --- a/storage/connect/jsonudf.h +++ b/storage/connect/jsonudf.h @@ -330,7 +330,7 @@ public: char *LocateAll(PGLOBAL g, PJSON jsp, PJVAL jvp, int mx = 10); protected: - my_bool SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm); + my_bool SetArrayOptions(PGLOBAL g, char *p, int i); PVAL GetColumnValue(PGLOBAL g, PJSON row, int i); PVAL ExpandArray(PGLOBAL g, PJAR arp, int n); PVAL GetCalcValue(PGLOBAL g, PJAR bap, int n); diff --git a/storage/connect/tabxcl.cpp b/storage/connect/tabxcl.cpp index d354f556ca1..8f77ecb8357 100644 --- a/storage/connect/tabxcl.cpp +++ b/storage/connect/tabxcl.cpp @@ -186,8 +186,8 @@ bool TDBXCL::OpenDB(PGLOBAL g) /*********************************************************************/ /* Physically open the object table. */ /*********************************************************************/ - if (Tdbp->OpenDB(g)) - return TRUE; + if (Tdbp->OpenDB(g)) + return TRUE; Use = USE_OPEN; return FALSE; diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index c66c33a7818..5b0d7dcc74b 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -1078,11 +1078,11 @@ static struct st_mysql_sys_var* example_system_variables[]= { // this is an example of SHOW_SIMPLE_FUNC and of my_snprintf() service // If this function would return an array, one should use SHOW_FUNC static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var, - char *buf) + void *buf, system_status_var *, enum_var_type) { var->type= SHOW_CHAR; var->value= buf; // it's of SHOW_VAR_FUNC_BUFF_SIZE bytes - my_snprintf(buf, SHOW_VAR_FUNC_BUFF_SIZE, + my_snprintf((char*) buf, SHOW_VAR_FUNC_BUFF_SIZE, "enum_var is %lu, ulong_var is %lu, int_var is %d, " "double_var is %f, %.6b", // %b is a MySQL extension srv_enum_var, srv_ulong_var, THDVAR(thd, int_var), diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index c25db81968e..894b35542e6 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -472,6 +472,42 @@ IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_PROCESSOR MATCHES "aarc ) ENDIF() +# clang ~16+ with return values being uninitialized is resolved by basic optimization +# compiler flags. The inlining of these function means the uninitalized paths are +# elimated from mach_read_from_2 (per MDEV-36316) and i_s_dict_fill_sys_columns MDEV-36327 +IF(WITH_MSAN AND CMAKE_BUILD_TYPE STREQUAL "Debug") + SET_SOURCE_FILES_PROPERTIES( + btr/btr0btr.cc + btr/btr0bulk.cc + data/data0data.cc + dict/dict0load.cc + dict/dict0mem.cc + fil/fil0crypt.cc + fil/fil0pagecompress.cc + fsp/fsp0fsp.cc + fut/fut0lst.cc + gis/gis0rtree.cc + handler/ha_innodb.cc + handler/i_s.cc + ibuf/ibuf0ibuf.cc + log/log0recv.cc + page/page0cur.cc + page/page0page.cc + page/page0zip.cc + rem/rem0rec.cc + row/row0import.cc + row/row0mysql.cc + row/row0purge.cc + row/row0uins.cc + row/row0undo.cc + row/row0upd.cc + trx/trx0purge.cc + trx/trx0rec.cc + trx/trx0trx.cc + trx/trx0undo.cc + PROPERTIES COMPILE_FLAGS -Og) +ENDIF() + # Older gcc version insist on -mhtm flag for including the # htmxlintrin.h header. This is also true for new gcc versions # like 11.2.0 in Debian Sid diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 96f848de033..c064eb848a5 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -1157,6 +1157,7 @@ struct st_maria_plugin i_s_innodb_cmp_reset = MariaDB_PLUGIN_MATURITY_STABLE }; +PRAGMA_DISABLE_CHECK_STACK_FRAME_EXTRA namespace Show { /* Fields of the dynamic tables diff --git a/storage/maria/ma_test_big.sh b/storage/maria/ma_test_big.sh old mode 100644 new mode 100755 index 6419d05e3a4..41260151cd7 --- a/storage/maria/ma_test_big.sh +++ b/storage/maria/ma_test_big.sh @@ -4,19 +4,23 @@ # finding bugs in blob handling # +mkdir -p tmp +cd tmp set -e a=15 while test $a -le 5000 do echo $a - rm -f maria_log* - ma_test2 -s -L -K -W -P -M -T -c -b32768 -t4 -A1 -m$a > /dev/null - maria_read_log -a -s >& /dev/null - maria_chk -es test2 - maria_read_log -a -s >& /dev/null - maria_chk -es test2 + rm -f aria_log* + ../ma_test2 -s -L -K -W -P -M -T -c -b32768 -t4 -A1 -m$a > /dev/null + ../aria_read_log -a -s >& /dev/null + ../aria_chk -ess test2 + ../aria_read_log -a -s >& /dev/null + ../aria_chk -ess test2 rm test2.MA? - maria_read_log -a -s >& /dev/null - maria_chk -es test2 + ../aria_read_log -a -s >& /dev/null + ../aria_chk -ess test2 a=$((a+1)) done +cd .. +rm -r tmp diff --git a/storage/mroonga/vendor/groonga/lib/ii.c b/storage/mroonga/vendor/groonga/lib/ii.c index 8ce4857bfc2..e6c97c30bf2 100644 --- a/storage/mroonga/vendor/groonga/lib/ii.c +++ b/storage/mroonga/vendor/groonga/lib/ii.c @@ -44,6 +44,8 @@ # include #endif +#include "my_attribute.h" + #define MAX_PSEG 0x20000 #define MAX_PSEG_SMALL 0x00200 /* MAX_PSEG_MEDIUM has enough space for the following source: @@ -2833,6 +2835,8 @@ chunk_flush(grn_ctx *ctx, grn_ii *ii, chunk_info *cinfo, uint8_t *enc, uint32_t return ctx->rc; } +PRAGMA_DISABLE_CHECK_STACK_FRAME + static grn_rc chunk_merge(grn_ctx *ctx, grn_ii *ii, buffer *sb, buffer_term *bt, chunk_info *cinfo, grn_id rid, datavec *dv, @@ -2940,6 +2944,8 @@ chunk_merge(grn_ctx *ctx, grn_ii *ii, buffer *sb, buffer_term *bt, return ctx->rc; } +PRAGMA_REENABLE_CHECK_STACK_FRAME + static void buffer_merge_dump_datavec(grn_ctx *ctx, grn_ii *ii, @@ -2989,6 +2995,8 @@ buffer_merge_dump_datavec(grn_ctx *ctx, GRN_OBJ_FIN(ctx, &buffer); } +PRAGMA_DISABLE_CHECK_STACK_FRAME + /* If dc doesn't have enough space, program may be crashed. * TODO: Support auto space extension or max size check. */ @@ -3314,6 +3322,8 @@ buffer_merge(grn_ctx *ctx, grn_ii *ii, uint32_t seg, grn_hash *h, return ctx->rc; } +PRAGMA_REENABLE_CHECK_STACK_FRAME + static void fake_map(grn_ctx *ctx, grn_io *io, grn_io_win *iw, void *addr, uint32_t seg, uint32_t size) { @@ -4509,6 +4519,9 @@ grn_ii_get_disk_usage(grn_ctx *ctx, grn_ii *ii) return usage; } + +PRAGMA_DISABLE_CHECK_STACK_FRAME + #define BIT11_01(x) ((x >> 1) & 0x7ff) #define BIT31_12(x) (x >> 12) @@ -4784,6 +4797,8 @@ exit : return ctx->rc; } +PRAGMA_REENABLE_CHECK_STACK_FRAME + grn_rc grn_ii_delete_one(grn_ctx *ctx, grn_ii *ii, grn_id tid, grn_ii_updspec *u, grn_hash *h) {