diff --git a/mysql-test/include/have_innodb.inc b/mysql-test/include/have_innodb.inc index 0de070e1994..8c9cdb54363 100644 --- a/mysql-test/include/have_innodb.inc +++ b/mysql-test/include/have_innodb.inc @@ -3,7 +3,7 @@ # will be skipped unless innodb is enabled # --disable_query_log -if (`select count(*) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like "MSAN%"`) +if (`select count(*) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like 'MSAN%'`) { SET STATEMENT sql_log_bin=0 FOR call mtr.add_suppression("InnoDB: Trying to delete tablespace.*pending operations"); diff --git a/mysql-test/main/func_debug.result b/mysql-test/main/func_debug.result index c8efcf09d41..37f2a19fc6c 100644 --- a/mysql-test/main/func_debug.result +++ b/mysql-test/main/func_debug.result @@ -912,7 +912,8 @@ a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (bigint) Note 1105 DBUG: [1] arg=2 handler=1 (decimal) -Note 1105 DBUG: types_compatible=no bisect=no +Note 1105 DBUG: found a mix of UINT and SINT +Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) Warnings: @@ -950,7 +951,8 @@ a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (bigint) Note 1105 DBUG: [1] arg=2 handler=1 (decimal) -Note 1105 DBUG: types_compatible=no bisect=no +Note 1105 DBUG: found a mix of UINT and SINT +Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) Warnings: @@ -1624,7 +1626,8 @@ a b Warnings: Note 1105 DBUG: [0] arg=1 handler=0 (bigint) Note 1105 DBUG: [1] arg=2 handler=1 (decimal) -Note 1105 DBUG: types_compatible=no bisect=no +Note 1105 DBUG: found a mix of UINT and SINT +Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; # # MDEV-11554 Wrong result for CASE on a mixture of signed and unsigned expressions diff --git a/mysql-test/main/func_in.result b/mysql-test/main/func_in.result index b18aa26777e..58dfcbcf31f 100644 --- a/mysql-test/main/func_in.result +++ b/mysql-test/main/func_in.result @@ -944,6 +944,43 @@ Warning 1292 Truncated incorrect DECIMAL value: '0x' # End of 10.4 tests # # +# Start of 10.5 tests +# +# +# MDEV-31303: Key not used +# +CREATE TABLE `a` ( +`id` bigint AUTO_INCREMENT PRIMARY KEY, +`c1` bigint unsigned, +KEY (`c1`) +); +INSERT INTO `a` VALUES (1,9223382399205928659),(2,9223384207280813348), +(3,9223385953115437234),(4,9223387250780556749),(5,9223387354282558788), +(6,9223387603870501596),(7,9223389270813433667),(8,9223389903231468827), +(9,9223390280789586779),(10,9223391591398222899),(11,9223391875473564350), +(12,9223393152250049433),(13,9223393939696790223),(14,9223394417225350415), +(15,9223397646397141015),(16,9223398025879291243),(17,9223399038671098072), +(18,9223399534968874556),(19,9223400449518009285),(20,9223400860292643549), +(21,9223400940692256924),(22,9223401073791948119),(23,9223402820804649616), +(24,9223403470951992681),(25,9223405581879567267),(26,9223405754978563829), +(27,9223405972966828221), (28, 9223372036854775808), (29, 9223372036854775807) ; +explain SELECT c1 FROM a WHERE c1 IN ( 1, 9223372036854775807 ); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE a range c1 c1 9 NULL 2 Using where; Using index +explain SELECT c1 FROM a WHERE c1 IN ( 1, 9223372036854775808 ); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE a range c1 c1 9 NULL 2 Using where; Using index +SELECT c1 FROM a WHERE c1 IN ( 1, 9223372036854775807 ); +c1 +9223372036854775807 +SELECT c1 FROM a WHERE c1 IN ( 1, 9223372036854775808 ); +c1 +9223372036854775808 +drop table `a`; +# +# End of 10.5 tests +# +# # MDEV-29662 same values in `IN` set vs equal comparison produces # the different performance # diff --git a/mysql-test/main/func_in.test b/mysql-test/main/func_in.test index 02483c482ac..6389c200b19 100644 --- a/mysql-test/main/func_in.test +++ b/mysql-test/main/func_in.test @@ -721,6 +721,40 @@ SELECT ('0x',1) IN ((0,1),(1,1)); --echo # End of 10.4 tests --echo # +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-31303: Key not used +--echo # +CREATE TABLE `a` ( + `id` bigint AUTO_INCREMENT PRIMARY KEY, + `c1` bigint unsigned, + KEY (`c1`) +); + +INSERT INTO `a` VALUES (1,9223382399205928659),(2,9223384207280813348), +(3,9223385953115437234),(4,9223387250780556749),(5,9223387354282558788), +(6,9223387603870501596),(7,9223389270813433667),(8,9223389903231468827), +(9,9223390280789586779),(10,9223391591398222899),(11,9223391875473564350), +(12,9223393152250049433),(13,9223393939696790223),(14,9223394417225350415), +(15,9223397646397141015),(16,9223398025879291243),(17,9223399038671098072), +(18,9223399534968874556),(19,9223400449518009285),(20,9223400860292643549), +(21,9223400940692256924),(22,9223401073791948119),(23,9223402820804649616), +(24,9223403470951992681),(25,9223405581879567267),(26,9223405754978563829), +(27,9223405972966828221), (28, 9223372036854775808), (29, 9223372036854775807) ; + +explain SELECT c1 FROM a WHERE c1 IN ( 1, 9223372036854775807 ); +explain SELECT c1 FROM a WHERE c1 IN ( 1, 9223372036854775808 ); +SELECT c1 FROM a WHERE c1 IN ( 1, 9223372036854775807 ); +SELECT c1 FROM a WHERE c1 IN ( 1, 9223372036854775808 ); +drop table `a`; + +--echo # +--echo # End of 10.5 tests +--echo # + --echo # --echo # MDEV-29662 same values in `IN` set vs equal comparison produces --echo # the different performance @@ -854,4 +888,3 @@ drop table t1; --echo # --echo # End of 10.6 tests --echo # - diff --git a/mysql-test/suite/innodb/r/scrub_debug.result b/mysql-test/suite/innodb/r/scrub_debug.result new file mode 100644 index 00000000000..5fbf1250b21 --- /dev/null +++ b/mysql-test/suite/innodb/r/scrub_debug.result @@ -0,0 +1,22 @@ +SET @save_debug=@@GLOBAL.INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG; +SET @save_scrub=@@GLOBAL.INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED; +SET @save_freq=@@GLOBAL.INNODB_PURGE_RSEG_TRUNCATE_FREQUENCY; +SET GLOBAL INNODB_PURGE_RSEG_TRUNCATE_FREQUENCY=1; +SET GLOBAL INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED=1; +SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG=2; +CREATE TABLE t1(f1 INT AUTO_INCREMENT PRIMARY KEY, +f2 VARCHAR(256) GENERATED ALWAYS as('repairman'), +INDEX idx(f2))ENGINE= InnoDB; +INSERT INTO t1(f1) SELECT seq FROM seq_1_to_50; +FLUSH TABLE t1 FOR EXPORT; +FOUND 108 /repairman/ in t1.ibd +UNLOCK TABLES; +ALTER TABLE t1 DROP INDEX idx; +InnoDB 0 transactions not purged +FLUSH TABLE t1 FOR EXPORT; +NOT FOUND /repairman/ in t1.ibd +UNLOCK TABLES; +DROP TABLE t1; +SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG=@save_debug; +SET GLOBAL INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED=@save_scrub; +SET GLOBAL INNODB_PURGE_RSEG_TRUNCATE_FREQUENCY = @save_freq; diff --git a/mysql-test/suite/innodb/t/scrub_debug.test b/mysql-test/suite/innodb/t/scrub_debug.test new file mode 100644 index 00000000000..141b0f0c5ba --- /dev/null +++ b/mysql-test/suite/innodb/t/scrub_debug.test @@ -0,0 +1,31 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc +--source include/have_debug.inc + +SET @save_debug=@@GLOBAL.INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG; +SET @save_scrub=@@GLOBAL.INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED; +SET @save_freq=@@GLOBAL.INNODB_PURGE_RSEG_TRUNCATE_FREQUENCY; + +SET GLOBAL INNODB_PURGE_RSEG_TRUNCATE_FREQUENCY=1; +SET GLOBAL INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED=1; +SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG=2; +let $MYSQLD_DATADIR=`select @@datadir`; +CREATE TABLE t1(f1 INT AUTO_INCREMENT PRIMARY KEY, + f2 VARCHAR(256) GENERATED ALWAYS as('repairman'), + INDEX idx(f2))ENGINE= InnoDB; +INSERT INTO t1(f1) SELECT seq FROM seq_1_to_50; +FLUSH TABLE t1 FOR EXPORT; +let SEARCH_PATTERN= repairman; +let SEARCH_FILE= $MYSQLD_DATADIR/test/t1.ibd; +-- source include/search_pattern_in_file.inc +UNLOCK TABLES; + +ALTER TABLE t1 DROP INDEX idx; +-- source include/wait_all_purged.inc +FLUSH TABLE t1 FOR EXPORT; +-- source include/search_pattern_in_file.inc +UNLOCK TABLES; +DROP TABLE t1; +SET GLOBAL INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG=@save_debug; +SET GLOBAL INNODB_IMMEDIATE_SCRUB_DATA_UNCOMPRESSED=@save_scrub; +SET GLOBAL INNODB_PURGE_RSEG_TRUNCATE_FREQUENCY = @save_freq; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 1ef5d3c9d0c..0a9227933c5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4486,6 +4486,42 @@ bool Item_func_in::fix_length_and_dec() return TRUE; } + if (!arg_types_compatible && comparator_count() == 2) + { + /* + Catch a special case: a mixture of signed and unsigned integer types. + in_longlong can handle such cases. + + Note, prepare_predicant_and_values() aggregates this mixture as follows: + - signed+unsigned produce &type_handler_newdecimal. + - signed+signed or unsigned+unsigned produce &type_handler_slonglong + So we have extactly two distinct handlers. + + The code below assumes that unsigned longlong is handled + by &type_handler_slonglong in comparison context, + which may change in the future to &type_handler_ulonglong. + The DBUG_ASSERT is needed to address this change here properly. + */ + DBUG_ASSERT(type_handler_ulonglong.type_handler_for_comparison() == + &type_handler_slonglong); + // Let's check if all arguments are of integer types + uint found_int_args= 0; + for (uint i= 0; i < arg_count; i++, found_int_args++) + { + if (args[i]->type_handler_for_comparison() != &type_handler_slonglong) + break; + } + if (found_int_args == arg_count) + { + // All arguments are integers. Switch to integer comparison. + arg_types_compatible= true; + DBUG_EXECUTE_IF("Item_func_in", + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_UNKNOWN_ERROR, "DBUG: found a mix of UINT and SINT");); + m_comparator.set_handler(&type_handler_slonglong); + } + } + if (arg_types_compatible) // Bisection condition #1 { if (m_comparator.type_handler()-> diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index 8618c7e2e0e..73595c31d5a 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -2762,18 +2762,13 @@ remove: not_full_n_used - descr_n_used); } - err = fsp_free_extent(space, page, mtr); - if (UNIV_UNLIKELY(err != DB_SUCCESS)) { - return err; - } - for (uint32_t i = 0; i < FSP_EXTENT_SIZE; i++) { if (!xdes_is_free(descr, i)) { buf_page_free(space, first_page_in_extent + i, mtr); } } - return DB_SUCCESS; + return fsp_free_extent(space, page, mtr); } /** Frees part of a segment. This function can be used to free diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index b1960e58924..aeeaa6c8e66 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -370,7 +370,6 @@ static void trx_purge_free_segment(buf_block_t *block, mtr_t &mtr) This does not matter when using multiple innodb_undo_tablespaces; innodb_undo_log_truncate=ON will be able to reclaim the space. */ - log_free_check(); mtr.start(); block->page.lock.x_lock(); ut_ad(block->page.id() == id); @@ -393,7 +392,6 @@ trx_purge_truncate_rseg_history(trx_rseg_t &rseg, fil_addr_t hdr_addr; mtr_t mtr; - log_free_check(); mtr.start(); dberr_t err; @@ -495,7 +493,6 @@ loop: mtr.commit(); ut_ad(rseg.history_size > 0); rseg.history_size--; - log_free_check(); mtr.start(); rseg_hdr->page.lock.x_lock(); ut_ad(rseg_hdr->page.id() == rseg.page_id()); @@ -571,6 +568,7 @@ TRANSACTIONAL_TARGET void trx_purge_truncate_history() if (rseg.space) { ut_ad(rseg.is_persistent()); + log_free_check(); rseg.latch.wr_lock(SRW_LOCK_CALL); if (dberr_t e= trx_purge_truncate_rseg_history(rseg, head,