revision-id: ad7bbc376ff52484fdfaaa14d22351550382a84d (mariadb-10.1.38-80-gad7bbc376ff) parent(s): 9a8b8ea66b041719c2e95ed6beaf286628c935b4 author: Varun Gupta committer: Varun Gupta timestamp: 2019-03-28 17:37:41 +0530 message: MDEV-18300: ASAN error in Field_blob::get_key_image upon UPDATE with subquery For single table updates and multi-table updates , engine independent statistics were not being read even if the statistics were collected. Fixed it, so when the optimizer_use_condition_selectivity > 2 then we would read the available statistics for update queries. --- mysql-test/r/update_innodb.result | 24 ++++++++++++++++++++++++ mysql-test/t/update_innodb.test | 29 +++++++++++++++++++++++++++++ sql/sql_statistics.cc | 1 + sql/sql_update.cc | 3 +++ 4 files changed, 57 insertions(+) diff --git a/mysql-test/r/update_innodb.result b/mysql-test/r/update_innodb.result index 0a85c6dab3e..695561122f0 100644 --- a/mysql-test/r/update_innodb.result +++ b/mysql-test/r/update_innodb.result @@ -65,3 +65,27 @@ SELECT * FROM t1; a_id b_id c_id 1 NULL NULL drop table t1,t2; +# +# MDEV-18300: ASAN error in Field_blob::get_key_image upon UPDATE with subquery +# +set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; +set @save_use_stat_tables= @@use_stat_tables; +set use_stat_tables=preferably; +set optimizer_use_condition_selectivity=4; +CREATE TABLE t1 (a INT, b CHAR(8)) ENGINE=InnoDB; +insert into t1 values (1,'foo'),(2, 'abc'); +CREATE TABLE t2 (c CHAR(8), d BLOB) ENGINE=InnoDB; +insert into t2 values ('abc', 'foo'),('edf', 'food'); +ANALYZE TABLE t1,t2; +UPDATE t1 SET a = 1 WHERE b = ( SELECT c FROM t2 WHERE d = 'foo' ); +SELECT * FROM t1; +a b +1 foo +1 abc +DROP TABLE t1, t2; +create table t1 (a int not null, b int, c int) engine=InnoDB; +create table t2 (d int, e int) engine=InnoDB; +update t1, t2 set a=NULL, b=2, c=NULL where b=d and e=200; +drop table t1,t2; +set @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; +set @@use_stat_tables= @save_use_stat_tables; diff --git a/mysql-test/t/update_innodb.test b/mysql-test/t/update_innodb.test index acc8aceab00..a29dd071cf8 100644 --- a/mysql-test/t/update_innodb.test +++ b/mysql-test/t/update_innodb.test @@ -75,3 +75,32 @@ SELECT t2.b_id FROM t1,t2 WHERE t2.c_id = t1.c_id; UPDATE t1 SET b_id = (SELECT t2.b_id FROM t2 t2 WHERE t2.c_id = t1.c_id); SELECT * FROM t1; drop table t1,t2; + +--echo # +--echo # MDEV-18300: ASAN error in Field_blob::get_key_image upon UPDATE with subquery +--echo # + +set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; +set @save_use_stat_tables= @@use_stat_tables; +set use_stat_tables=preferably; +set optimizer_use_condition_selectivity=4; + +CREATE TABLE t1 (a INT, b CHAR(8)) ENGINE=InnoDB; +insert into t1 values (1,'foo'),(2, 'abc'); +CREATE TABLE t2 (c CHAR(8), d BLOB) ENGINE=InnoDB; +insert into t2 values ('abc', 'foo'),('edf', 'food'); + +--disable_result_log +ANALYZE TABLE t1,t2; +--enable_result_log +UPDATE t1 SET a = 1 WHERE b = ( SELECT c FROM t2 WHERE d = 'foo' ); +SELECT * FROM t1; +DROP TABLE t1, t2; + +create table t1 (a int not null, b int, c int) engine=InnoDB; +create table t2 (d int, e int) engine=InnoDB; +update t1, t2 set a=NULL, b=2, c=NULL where b=d and e=200; +drop table t1,t2; + +set @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; +set @@use_stat_tables= @save_use_stat_tables; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index f4dcafdb7c3..d3a2094e272 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -4071,6 +4071,7 @@ bool is_eits_usable(Field *field) partition list of a table. We assume the selecticivity for such columns would be handled during partition pruning. */ + DBUG_ASSERT(field->table->stats_is_read); Column_statistics* col_stats= field->read_stats; return col_stats && !col_stats->no_stat_values_provided() && //(1) field->type() != MYSQL_TYPE_GEOMETRY && //(2) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 960b5cbccc5..78aa059f64f 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -301,6 +301,8 @@ int mysql_update(THD *thd, if (lock_tables(thd, table_list, table_count, 0)) DBUG_RETURN(1); + (void) read_statistics_for_tables_if_needed(thd, table_list); + if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT)) DBUG_RETURN(1); if (table_list->handle_derived(thd->lex, DT_PREPARE)) @@ -1540,6 +1542,7 @@ int mysql_multi_update_prepare(THD *thd) { DBUG_RETURN(TRUE); } + (void) read_statistics_for_tables_if_needed(thd, table_list); /* @todo: downgrade the metadata locks here. */ /*