MDEV-6439: Server crashes in Explain_union::print_explain with explain in slow log, tis620 charset Item_subselect::is_expensive() used to return FALSE (Inexpensive) whenever it saw that one of SELECTs in the Subquery's UNION is degenerate. It ignored the fact that other parts of the UNION might not be inexpensive, including the case where pther parts of the UNION have no query plan yet. For a subquery in form col >= ANY (SELECT 'foo' UNION SELECT 'bar') this would cause the query to be considered inexpensive when there is no query plan for the second part of the UNION, which in turn would cause the SELECT 'foo' to compute and free itself while still inside JOIN::optimize for that SELECT (See MDEV comment for full description). diff --git a/mysql-test/r/subselect_extra_no_semijoin.result b/mysql-test/r/subselect_extra_no_semijoin.result index 79bca38..200682b 100644 --- a/mysql-test/r/subselect_extra_no_semijoin.result +++ b/mysql-test/r/subselect_extra_no_semijoin.result @@ -482,3 +482,22 @@ DROP TABLE t1,t2; set optimizer_switch= @tmp_subselect_extra_derived; set optimizer_switch= @subselect_extra_no_sj_tmp; set @optimizer_switch_for_subselect_extra_test=null; +# +# MDEV-6439: Server crashes in Explain_union::print_explain with explain in slow log, tis620 charset +# +SET NAMES tis620; +set @tmp= @@global.slow_query_log; +SET GLOBAL slow_query_log = 1; +SET long_query_time = 0.000001; +SET log_slow_verbosity = 'explain'; +CREATE TABLE t1 (a VARCHAR(3)) ENGINE=MyISAM; +SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo'); +a +SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' ); +ERROR HY000: Illegal mix of collations (tis620_thai_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<=' +create table t2 (b int); +insert into t2 values (1),(2),(3); +SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' FROM t2); +ERROR HY000: Illegal mix of collations (tis620_thai_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<=' +drop table t1,t2; +SET GLOBAL slow_query_log=@tmp; diff --git a/mysql-test/t/subselect_extra_no_semijoin.test b/mysql-test/t/subselect_extra_no_semijoin.test index 8aba3dd..41593fb 100644 --- a/mysql-test/t/subselect_extra_no_semijoin.test +++ b/mysql-test/t/subselect_extra_no_semijoin.test @@ -6,4 +6,34 @@ set @optimizer_switch_for_subselect_extra_test='semijoin=off,firstmatch=off,loo set optimizer_switch= @subselect_extra_no_sj_tmp; -set @optimizer_switch_for_subselect_extra_test=null; \ No newline at end of file +set @optimizer_switch_for_subselect_extra_test=null; + +--echo # +--echo # MDEV-6439: Server crashes in Explain_union::print_explain with explain in slow log, tis620 charset +--echo # + +## Using a separate client connection is easier than restoring state +connect(con1,localhost,root,,); + +SET NAMES tis620; +set @tmp= @@global.slow_query_log; +SET GLOBAL slow_query_log = 1; +SET long_query_time = 0.000001; +SET log_slow_verbosity = 'explain'; + +CREATE TABLE t1 (a VARCHAR(3)) ENGINE=MyISAM; +SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo'); +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' UNION SELECT 'bar' ); + +create table t2 (b int); +insert into t2 values (1),(2),(3); + +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT * FROM t1 WHERE a >= ANY ( SELECT 'foo' FROM t2); + +drop table t1,t2; +SET GLOBAL slow_query_log=@tmp; +disconnect con1; +connection default; + diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index a8dfdff..14b2ccd 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -575,7 +575,7 @@ bool Item_subselect::is_expensive() */ if (cur_join->optimized && (cur_join->zero_result_cause || !cur_join->tables_list)) - return false; + continue; /* If a subquery is not optimized we cannot estimate its cost. A subquery is On Wed, Aug 15, 2018 at 02:16:51PM +0300, jan wrote:
revision-id: 148df3abde105671b5b33e87269298dec74a2dda (mariadb-10.1.35-12-g148df3abde1) parent(s): 678bc584a123746e7db4355132d3cf7b6c56fc70 author: Jan Lindström committer: Jan Lindström timestamp: 2018-08-15 14:16:21 +0300 message:
InnoDB adjustments - Apply patch to xtradb - Fix coding standard - Fix test case result to match 10.1
--- .../galera/r/galera_binlog_stmt_autoinc.result | 14 ----- storage/innobase/handler/ha_innodb.cc | 67 ++++++++++------------ storage/xtradb/handler/ha_innodb.cc | 57 ++++++++++++++---- 3 files changed, 76 insertions(+), 62 deletions(-)
diff --git a/mysql-test/suite/galera/r/galera_binlog_stmt_autoinc.result b/mysql-test/suite/galera/r/galera_binlog_stmt_autoinc.result index 78b40228eb0..542bd156816 100644 --- a/mysql-test/suite/galera/r/galera_binlog_stmt_autoinc.result +++ b/mysql-test/suite/galera/r/galera_binlog_stmt_autoinc.result @@ -1,8 +1,4 @@ -connection node_1; -connection node_2; -connection node_2; SET GLOBAL wsrep_forced_binlog_format='STATEMENT'; -connection node_1; SET GLOBAL wsrep_forced_binlog_format='STATEMENT'; CREATE TABLE t1 ( i int(11) NOT NULL AUTO_INCREMENT, @@ -20,7 +16,6 @@ i c 3 dummy_text 5 dummy_text 7 dummy_text -connection node_2; select * from t1; i c 1 dummy_text @@ -28,7 +23,6 @@ i c 5 dummy_text 7 dummy_text SET GLOBAL wsrep_forced_binlog_format='none'; -connection node_1; SET GLOBAL wsrep_forced_binlog_format='none'; drop table t1; SET SESSION binlog_format='STATEMENT'; @@ -54,14 +48,12 @@ i c 4 dummy_text 7 dummy_text 10 dummy_text -connection node_2; select * from t1; i c 1 dummy_text 4 dummy_text 7 dummy_text 10 dummy_text -connection node_1; SET GLOBAL wsrep_auto_increment_control='ON'; SET SESSION binlog_format='ROW'; show variables like 'binlog_format'; @@ -80,9 +72,7 @@ auto_increment_offset 1 wsrep_auto_increment_control OFF SET GLOBAL wsrep_auto_increment_control='ON'; drop table t1; -connection node_2; SET GLOBAL wsrep_forced_binlog_format='ROW'; -connection node_1; SET GLOBAL wsrep_forced_binlog_format='ROW'; CREATE TABLE t1 ( i int(11) NOT NULL AUTO_INCREMENT, @@ -100,7 +90,6 @@ i c 3 dummy_text 5 dummy_text 7 dummy_text -connection node_2; select * from t1; i c 1 dummy_text @@ -108,7 +97,6 @@ i c 5 dummy_text 7 dummy_text SET GLOBAL wsrep_forced_binlog_format='none'; -connection node_1; SET GLOBAL wsrep_forced_binlog_format='none'; drop table t1; SET SESSION binlog_format='ROW'; @@ -134,14 +122,12 @@ i c 4 dummy_text 7 dummy_text 10 dummy_text -connection node_2; select * from t1; i c 1 dummy_text 4 dummy_text 7 dummy_text 10 dummy_text -connection node_1; SET GLOBAL wsrep_auto_increment_control='ON'; show variables like 'binlog_format'; Variable_name Value diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index bee3c2ee9c0..3d569a2d1d7 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8401,26 +8401,25 @@ ha_innobase::write_row( dberr_t err;
#ifdef WITH_WSREP - /* Applier threads which are processing - ROW events and don't go through server - level autoinc processing, therefore - m_prebuilt autoinc values don't get - properly assigned. Fetch values from - server side. */ - if (wsrep_on(current_thd) && - wsrep_thd_exec_mode(current_thd) == REPL_RECV) - { - wsrep_thd_auto_increment_variables(current_thd, &offset, &increment); - } - else - { + /* Applier threads which are + processing ROW events and don't go + through server level autoinc + processing, therefore m_prebuilt + autoinc values don't get + properly assigned. Fetch values from + server side. */ + if (wsrep_on(current_thd) && + wsrep_thd_exec_mode(current_thd) == REPL_RECV) { + wsrep_thd_auto_increment_variables(current_thd, &offset, &increment); + } else { #endif /* WITH_WSREP */ - ut_a(prebuilt->autoinc_increment > 0); - offset = prebuilt->autoinc_offset; - increment = prebuilt->autoinc_increment; + ut_a(prebuilt->autoinc_increment > 0); + offset = prebuilt->autoinc_offset; + increment = prebuilt->autoinc_increment; #ifdef WITH_WSREP - } + } #endif /* WITH_WSREP */ + auto_inc = innobase_next_autoinc( auto_inc, 1, increment, offset, @@ -8943,25 +8942,22 @@ ha_innobase::update_row( ulonglong increment;
#ifdef WITH_WSREP - /* Applier threads which are processing - ROW events and don't go through server - level autoinc processing, therefore - m_prebuilt autoinc values don't get - properly assigned. Fetch values from - server side. */ - if (wsrep_on(current_thd) && - wsrep_thd_exec_mode(current_thd) == REPL_RECV) - { - wsrep_thd_auto_increment_variables( - current_thd, &offset, &increment); - } - else - { + /* Applier threads which are processing + ROW events and don't go through server + level autoinc processing, therefore + m_prebuilt autoinc values don't get + properly assigned. Fetch values from + server side. */ + if (wsrep_on(current_thd) && + wsrep_thd_exec_mode(current_thd) == REPL_RECV) { + wsrep_thd_auto_increment_variables( + current_thd, &offset, &increment); + } else { #endif /* WITH_WSREP */ - offset = prebuilt->autoinc_offset; - increment = prebuilt->autoinc_increment; + offset = prebuilt->autoinc_offset; + increment = prebuilt->autoinc_increment; #ifdef WITH_WSREP - } + } #endif /* WITH_WSREP */
auto_inc = innobase_next_autoinc( @@ -16074,8 +16070,7 @@ ha_innobase::get_auto_increment( thd_get_thread_id(ha_thd()), current, autoinc);
- if (!wsrep_on(ha_thd())) - { + if (!wsrep_on(ha_thd())) { current = autoinc - prebuilt->autoinc_increment;
current = innobase_next_autoinc( diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 3cd7cb6977b..857fc7e66f1 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -8988,8 +8988,25 @@ ha_innobase::write_row( ulonglong increment; dberr_t err;
- offset = prebuilt->autoinc_offset; - increment = prebuilt->autoinc_increment; +#ifdef WITH_WSREP + /* Applier threads which are + processing ROW events and don't go + through server level autoinc + processing, therefore m_prebuilt + autoinc values don't get + properly assigned. Fetch values from + server side. */ + if (wsrep_on(current_thd) && + wsrep_thd_exec_mode(current_thd) == REPL_RECV) { + wsrep_thd_auto_increment_variables(current_thd, &offset, &increment); + } else { +#endif /* WITH_WSREP */ + ut_a(prebuilt->autoinc_increment > 0); + offset = prebuilt->autoinc_offset; + increment = prebuilt->autoinc_increment; +#ifdef WITH_WSREP + } +#endif /* WITH_WSREP */
auto_inc = innobase_next_autoinc( auto_inc, @@ -9502,16 +9519,32 @@ ha_innobase::update_row(
/* We need the upper limit of the col type to check for whether we update the table autoinc counter or not. */ - col_max_value = innobase_get_int_col_max_value( - table->next_number_field); + col_max_value = + table->next_number_field->get_max_int_value();
if (auto_inc <= col_max_value && auto_inc != 0) {
ulonglong offset; ulonglong increment;
- offset = prebuilt->autoinc_offset; - increment = prebuilt->autoinc_increment; +#ifdef WITH_WSREP + /* Applier threads which are processing + ROW events and don't go through server + level autoinc processing, therefore + m_prebuilt autoinc values don't get + properly assigned. Fetch values from + server side. */ + if (wsrep_on(current_thd) && + wsrep_thd_exec_mode(current_thd) == REPL_RECV) { + wsrep_thd_auto_increment_variables( + current_thd, &offset, &increment); + } else { +#endif /* WITH_WSREP */ + offset = prebuilt->autoinc_offset; + increment = prebuilt->autoinc_increment; +#ifdef WITH_WSREP + } +#endif /* WITH_WSREP */
auto_inc = innobase_next_autoinc( auto_inc, 1, increment, offset, col_max_value); @@ -16742,13 +16775,13 @@ ha_innobase::get_auto_increment( increment, thd_get_thread_id(ha_thd()), current, autoinc); - if (!wsrep_on(ha_thd())) - { - current = autoinc - prebuilt->autoinc_increment; - }
- current = innobase_next_autoinc( - current, 1, increment, offset, col_max_value); + if (!wsrep_on(ha_thd())) { + current = autoinc - prebuilt->autoinc_increment; + + current = innobase_next_autoinc( + current, 1, increment, offset, col_max_value); + }
dict_table_autoinc_initialize(prebuilt->table, current);
_______________________________________________ commits mailing list commits@mariadb.org https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits
-- BR Sergei -- Sergei Petrunia, Software Developer MariaDB Corporation | Skype: sergefp | Blog: http://s.petrunia.net/blog