From 273d8eb12c40a6dcd05a8148bdfba3f1fd96e764 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Wed, 18 Sep 2019 01:59:29 +0530 Subject: MDEV-20589: Server still crashes in Field::set_warning_truncated_wrong_value The flag is_stat_field is not set for the min_value and max_value of field items inside table share. This is a must requirement as we don't want to throw warnings of truncation when we read values from the statistics table to the column statistics of table share fields. --- sql/sql_statistics.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sql/sql_statistics.cc') diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 26032d8d535..578d3fac641 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1153,12 +1153,14 @@ public: case COLUMN_STAT_MIN_VALUE: table_field->read_stats->min_value->set_notnull(); stat_field->val_str(&val); + DBUG_ASSERT(table_field->read_stats->min_value->is_stat_field); table_field->read_stats->min_value->store(val.ptr(), val.length(), &my_charset_bin); break; case COLUMN_STAT_MAX_VALUE: table_field->read_stats->max_value->set_notnull(); stat_field->val_str(&val); + DBUG_ASSERT(table_field->read_stats->min_value->is_stat_field); table_field->read_stats->max_value->store(val.ptr(), val.length(), &my_charset_bin); break; @@ -2045,7 +2047,7 @@ void create_min_max_statistical_fields_for_table_share(THD *thd, Field *fld; Field *table_field= *field_ptr; my_ptrdiff_t diff= record - table_share->default_values; - if (!(fld= table_field->clone(&stats_cb->mem_root, diff))) + if (!(fld= table_field->clone(&stats_cb->mem_root, NULL, diff, TRUE))) continue; if (i == 0) table_field->read_stats->min_value= fld; -- cgit v1.2.1 From 1bbe8c5e0f6823acd4780d7563e8c02f8b4c5a01 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sun, 22 Sep 2019 04:08:48 +0300 Subject: Proper fix for disabling warnings in read_statistics_for_table(). MDEV-20589: Server still crashes in Field::set_warning_truncated_wrong_value - Use dbug_tmp_use_all_columns() to mark that all fields can be used - Remove field->is_stat_field (not needed) - Remove extra arguments to Field::clone() that should not be there - Safety fix for Field::set_warning_truncated_wrong_value() to not crash if table is zero in production builds (We have got crashes several times here so better to be safe than sorry). - Threat wrong character string warnings identical to other field conversion warnings. This removes some warnings we before got from internal conversion errors. There is no good reason why a user would get an error in case of 'key_field='wrong-utf8-string' but not for 'field=wrong-utf8-string'. The old code could also easily give thousands of no-sence warnings for one single statement. --- sql/sql_statistics.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'sql/sql_statistics.cc') diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 8d1342773f7..5e0275fa65d 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1042,7 +1042,9 @@ public: { char buff[MAX_FIELD_WIDTH]; String val(buff, sizeof(buff), &my_charset_bin); + my_bitmap_map *old_map; + old_map= dbug_tmp_use_all_columns(stat_table, stat_table->read_set); for (uint i= COLUMN_STAT_MIN_VALUE; i <= COLUMN_STAT_HISTOGRAM; i++) { Field *stat_field= stat_table->field[i]; @@ -1100,6 +1102,7 @@ public: } } } + dbug_tmp_restore_column_map(stat_table->read_set, old_map); } @@ -1973,7 +1976,7 @@ void create_min_max_statistical_fields_for_table(TABLE *table) my_ptrdiff_t diff= record-table->record[0]; if (!bitmap_is_set(table->read_set, table_field->field_index)) continue; - if (!(fld= table_field->clone(&table->mem_root, table, diff, TRUE))) + if (!(fld= table_field->clone(&table->mem_root, table, diff))) continue; if (i == 0) table_field->collected_stats->min_value= fld; @@ -2984,9 +2987,12 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables) KEY *key_info, *key_info_end; TABLE_SHARE *table_share= table->s; Table_statistics *read_stats= table_share->stats_cb.table_stats; - + enum_check_fields old_check_level= thd->count_cuted_fields; DBUG_ENTER("read_statistics_for_table"); + /* Don't write warnings for internal field conversions */ + thd->count_cuted_fields= CHECK_FIELD_IGNORE; + /* Read statistics from the statistical table table_stats */ stat_table= stat_tables[TABLE_STAT].table; Table_stat table_stat(stat_table, table); @@ -3067,6 +3073,7 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables) } table->stats_is_read= TRUE; + thd->count_cuted_fields= old_check_level; DBUG_RETURN(0); } -- cgit v1.2.1