From 27539cd2c8b4f631cce78a4bb6f0eabe8eb1141c Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Mon, 11 Oct 2021 22:47:26 +0300 Subject: [PATCH] MDEV-26801: Valgrind/MSAN errors in Column_statistics_collected::finish ... The problem was introduced in fix for MDEV-26724. That patch has made it possible for histogram collection to fail. In particular, it fails for non-assigned characters. When histogram construction fails, we also abort the computation of COUNT(DISTINCT). When we try to use the value, we get valgrind failures. Switched the code to abort the statistics collection in this case. --- mysql-test/main/statistics_json.result | 5 +---- mysql-test/main/statistics_json.test | 1 - sql/sql_statistics.cc | 16 ++++++++++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/mysql-test/main/statistics_json.result b/mysql-test/main/statistics_json.result index 7f362f4f83c..9908d93c15b 100644 --- a/mysql-test/main/statistics_json.result +++ b/mysql-test/main/statistics_json.result @@ -7443,14 +7443,11 @@ create table t1 ( a varchar(100) character set cp1251); insert into t1 values ( _cp1251 x'88'),( _cp1251 x'98'); analyze table t1 persistent for all; Table Op Msg_type Msg_text -test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status OK -# Command succeeded but no histogram was collected: +test.t1 analyze status Operation failed select hist_type, histogram from mysql.column_stats where db_name=database() and table_name='t1'; hist_type histogram -NULL NULL drop table t1; # # ASAN use-after-poison my_strnxfrm_simple_internal / Histogram_json_hb::range_selectivity ... diff --git a/mysql-test/main/statistics_json.test b/mysql-test/main/statistics_json.test index 189374db347..7325d56e912 100644 --- a/mysql-test/main/statistics_json.test +++ b/mysql-test/main/statistics_json.test @@ -235,7 +235,6 @@ create table t1 ( a varchar(100) character set cp1251); insert into t1 values ( _cp1251 x'88'),( _cp1251 x'98'); analyze table t1 persistent for all; ---echo # Command succeeded but no histogram was collected: select hist_type, histogram from mysql.column_stats where db_name=database() and table_name='t1'; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index e1b6380d965..c62230a9af1 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -314,7 +314,7 @@ public: inline void init(THD *thd, Field * table_field); inline bool add(); - inline void finish(MEM_ROOT *mem_root, ha_rows rows, double sample_fraction); + inline bool finish(MEM_ROOT *mem_root, ha_rows rows, double sample_fraction); inline void cleanup(); }; @@ -2468,7 +2468,7 @@ bool Column_statistics_collected::add() */ inline -void Column_statistics_collected::finish(MEM_ROOT *mem_root, ha_rows rows, +bool Column_statistics_collected::finish(MEM_ROOT *mem_root, ha_rows rows, double sample_fraction) { double val; @@ -2507,6 +2507,10 @@ void Column_statistics_collected::finish(MEM_ROOT *mem_root, ha_rows rows, { delete histogram; histogram= NULL; + + delete count_distinct; + count_distinct= NULL; + return true; // Error } } @@ -2559,7 +2563,8 @@ void Column_statistics_collected::finish(MEM_ROOT *mem_root, ha_rows rows, val= 1.0; set_avg_frequency(val); set_not_null(COLUMN_STAT_AVG_FREQUENCY); - } + } + return false; } @@ -2810,7 +2815,10 @@ int collect_statistics_for_table(THD *thd, TABLE *table) continue; bitmap_set_bit(table->write_set, table_field->field_index); if (!rc) - table_field->collected_stats->finish(&table->mem_root, rows, sample_fraction); + { + rc= table_field->collected_stats->finish(&table->mem_root, rows, + sample_fraction); + } else table_field->collected_stats->cleanup(); }