diff options
author | Michael Widenius <monty@mariadb.org> | 2019-09-22 04:08:48 +0300 |
---|---|---|
committer | Michael Widenius <monty@mariadb.org> | 2019-09-22 04:08:48 +0300 |
commit | 1bbe8c5e0f6823acd4780d7563e8c02f8b4c5a01 (patch) | |
tree | 640662e33767ac08186f6b1a5cf95c77faf560e7 /sql/field.cc | |
parent | ba7725dace48d403187eb2a418a2081703fe5c9d (diff) | |
download | mariadb-git-1bbe8c5e0f6823acd4780d7563e8c02f8b4c5a01.tar.gz |
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.
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/sql/field.cc b/sql/field.cc index 0d9797143fa..14d78433503 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -71,7 +71,7 @@ const char field_separator=','; ptr < table->record[0] + table->s->reclength)))) #define ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED \ - DBUG_ASSERT(is_stat_field || !table || \ + DBUG_ASSERT(!table || \ (!table->write_set || \ bitmap_is_set(table->write_set, field_index) || \ (!(ptr >= table->record[0] && \ @@ -2406,8 +2406,7 @@ Field *Field::clone(MEM_ROOT *root, TABLE *new_table) -Field *Field::clone(MEM_ROOT *root, TABLE *new_table, my_ptrdiff_t diff, - bool stat_flag) +Field *Field::clone(MEM_ROOT *root, TABLE *new_table, my_ptrdiff_t diff) { Field *tmp; if ((tmp= (Field*) memdup_root(root,(char*) this,size_of()))) @@ -2415,7 +2414,6 @@ Field *Field::clone(MEM_ROOT *root, TABLE *new_table, my_ptrdiff_t diff, tmp->init(new_table); tmp->move_field_offset(diff); } - tmp->is_stat_field= stat_flag; return tmp; } @@ -2853,7 +2851,7 @@ int Field_decimal::store(const char *from_arg, size_t len, CHARSET_INFO *cs) /* Write digits of the frac_% parts ; - Depending on get_thd()->count_cutted_fields, we may also want + Depending on get_thd()->count_cuted_fields, we may also want to know if some non-zero tail of these parts will be truncated (for example, 0.002->0.00 will generate a warning, while 0.000->0.00 will not) @@ -6991,7 +6989,8 @@ Field_longstr::check_string_copy_error(const String_copier *copier, if (likely(!(pos= copier->most_important_error_pos()))) return FALSE; - if (!is_stat_field) + /* Ignore errors from internal expressions */ + if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION) { convert_to_printable(tmp, sizeof(tmp), pos, (end - pos), cs, 6); set_warning_truncated_wrong_value("string", tmp); @@ -7024,8 +7023,9 @@ int Field_longstr::report_if_important_data(const char *pstr, const char *end, bool count_spaces) { - THD *thd= get_thd(); - if ((pstr < end) && thd->count_cuted_fields > CHECK_FIELD_EXPRESSION) + THD *thd; + if ((pstr < end) && + (thd= get_thd())->count_cuted_fields > CHECK_FIELD_EXPRESSION) { if (test_if_important_data(field_charset, pstr, end)) { @@ -7036,7 +7036,8 @@ Field_longstr::report_if_important_data(const char *pstr, const char *end, return 2; } else if (count_spaces) - { /* If we lost only spaces then produce a NOTE, not a WARNING */ + { + /* If we lost only spaces then produce a NOTE, not a WARNING */ set_note(WARN_DATA_TRUNCATED, 1); return 2; } @@ -11381,13 +11382,17 @@ void Field::set_warning_truncated_wrong_value(const char *type_arg, const char *value) { THD *thd= get_thd(); - const char *db_name= table->s->db.str; - const char *table_name= table->s->table_name.str; + const char *db_name; + const char *table_name; + /* + table has in the past been 0 in case of wrong calls when processing + statistics tables. Let's protect against that. + */ + DBUG_ASSERT(table); - if (!db_name) - db_name= ""; - if (!table_name) - table_name= ""; + db_name= (table && table->s->db.str) ? table->s->db.str : ""; + table_name= ((table && table->s->table_name.str) ? table->s->table_name.str : + ""); push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, |