revision-id: 667d1786a96a40ee5074c9f1b493c7cf05a85cca (mariadb-10.2.18-80-g667d178) parent(s): 59b87e75d04f0ed75256724c78f7fd7af2f96e9b committer: Alexey Botchkov timestamp: 2018-11-13 00:11:32 +0400 message: MDEV-14576 Include full name of object in message about incorrect value for column. The error message modified. Then the TABLE_SHARE::error_table_name() implementation taken from 10.3, to be used as a name of the table in this message. --- sql/field.cc | 17 ++++++++++------- sql/item.cc | 14 +++++++++++++- sql/item.h | 1 + sql/item_create.cc | 2 +- sql/item_func.cc | 3 +++ sql/item_strfunc.cc | 6 +++--- sql/item_timefunc.cc | 8 ++++---- sql/share/errmsg-utf8.txt | 4 ++-- sql/sql_class.cc | 9 +++++++++ sql/sql_table.cc | 3 +++ sql/sql_time.cc | 34 +++++++++++++++++++--------------- sql/sql_time.h | 12 ++++++------ sql/table.h | 10 ++++++++++ 13 files changed, 84 insertions(+), 39 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index caa84dc..4cb6eb2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2079,7 +2079,7 @@ bool Field_num::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) longlong nr= val_int(); bool neg= !(flags & UNSIGNED_FLAG) && nr < 0; return int_to_datetime_with_warn(neg, neg ? -nr : nr, ltime, fuzzydate, - field_name); + table->s, field_name); } @@ -3384,7 +3384,7 @@ bool Field_new_decimal::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { my_decimal value; return decimal_to_datetime_with_warn(val_decimal(&value), - ltime, fuzzydate, field_name); + ltime, fuzzydate, table->s, field_name); } @@ -4855,7 +4855,7 @@ bool Field_real::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) { ASSERT_COLUMN_MARKED_FOR_READ; double nr= val_real(); - return double_to_datetime_with_warn(nr, ltime, fuzzydate, field_name); + return double_to_datetime_with_warn(nr, ltime, fuzzydate, table->s, field_name); } @@ -6338,7 +6338,7 @@ bool Field_year::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) if (tmp || field_length != 4) tmp+= 1900; return int_to_datetime_with_warn(false, tmp * 10000, - ltime, fuzzydate, field_name); + ltime, fuzzydate, table->s, field_name); } @@ -8623,7 +8623,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs) my_error(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, MYF(0), Geometry::ci_collection[geom_type]->m_name.str, Geometry::ci_collection[wkb_type]->m_name.str, - field_name, + table->s->db.str, table->s->error_table_name(), field_name, (ulong) table->in_use->get_stmt_da()-> current_row_for_warning()); goto err_exit; @@ -10787,7 +10787,8 @@ void Field::set_datetime_warning(Sql_condition::enum_warning_level level, { THD *thd= get_thd(); if (thd->really_abort_on_warning() && level >= Sql_condition::WARN_LEVEL_WARN) - make_truncated_value_warning(thd, level, str, ts_type, field_name); + make_truncated_value_warning(thd, level, str, ts_type, + table->s, field_name); else set_warning(level, code, cuted_increment); } @@ -10800,7 +10801,9 @@ void Field::set_warning_truncated_wrong_value(const char *type_arg, push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, ER_THD(thd, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), - type_arg, value, field_name, + type_arg, value, + table->s->db.str, table->s->error_table_name(), + field_name, static_cast<ulong>(thd->get_stmt_da()-> current_row_for_warning())); } diff --git a/sql/item.cc b/sql/item.cc index 9ac1ed3..ad7806f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -500,6 +500,15 @@ Item::Item(THD *thd): } +const TABLE_SHARE *Item::field_table_or_null() +{ + if (real_item()->type() != Item::FIELD_ITEM) + return NULL; + + return ((Item_field *) this)->field->table->s; +} + + /** Constructor used by Item_field, Item_ref & aggregate (sum) functions. @@ -1358,6 +1367,7 @@ bool Item::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) } if (null_value || int_to_datetime_with_warn(neg, neg ? -value : value, ltime, fuzzydate, + field_table_or_null(), field_name_or_null())) goto err; return null_value= false; @@ -1366,6 +1376,7 @@ bool Item::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) { double value= val_real(); if (null_value || double_to_datetime_with_warn(value, ltime, fuzzydate, + field_table_or_null(), field_name_or_null())) goto err; return null_value= false; @@ -1375,6 +1386,7 @@ bool Item::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) my_decimal value, *res; if (!(res= val_decimal(&value)) || decimal_to_datetime_with_warn(res, ltime, fuzzydate, + field_table_or_null(), field_name_or_null())) goto err; return null_value= false; @@ -3630,7 +3642,7 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type, { ErrConvTime str(&value.time); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &str, time_type, 0); + &str, time_type, 0, 0); set_zero_time(&value.time, time_type); } maybe_null= 0; diff --git a/sql/item.h b/sql/item.h index 3a64ea1..82a5524 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1182,6 +1182,7 @@ class Item: public Value_source, virtual const char *full_name() const { return name ? name : "???"; } const char *field_name_or_null() { return real_item()->type() == Item::FIELD_ITEM ? name : NULL; } + const TABLE_SHARE *field_table_or_null(); /* *result* family of methods is analog of *val* family (see above) but diff --git a/sql/item_create.cc b/sql/item_create.cc index b6430ec..3218d4d 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -7299,7 +7299,7 @@ Item *create_temporal_literal(THD *thd, ErrConvString err(str, length, cs); make_truncated_value_warning(thd, Sql_condition::time_warn_level(status.warnings), - &err, ltime.time_type, 0); + &err, ltime.time_type, 0, 0); } return item; } diff --git a/sql/item_func.cc b/sql/item_func.cc index dcf3a6f..512c8fc 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1023,6 +1023,7 @@ bool Item_func_hybrid_field_type::get_date(MYSQL_TIME *ltime, my_decimal value, *res; if (!(res= decimal_op_with_null_check(&value)) || decimal_to_datetime_with_warn(res, ltime, fuzzydate, + field_table_or_null(), field_name_or_null())) goto err; break; @@ -1033,6 +1034,7 @@ bool Item_func_hybrid_field_type::get_date(MYSQL_TIME *ltime, bool neg= !unsigned_flag && value < 0; if (null_value || int_to_datetime_with_warn(neg, neg ? -value : value, ltime, fuzzydate, + field_table_or_null(), field_name_or_null())) goto err; break; @@ -1041,6 +1043,7 @@ bool Item_func_hybrid_field_type::get_date(MYSQL_TIME *ltime, { double value= real_op(); if (null_value || double_to_datetime_with_warn(value, ltime, fuzzydate, + field_table_or_null(), field_name_or_null())) goto err; break; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 57a1e7e..76f3a98 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -5097,7 +5097,7 @@ bool Item_dyncol_get::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) bool neg = llval < 0; if (int_to_datetime_with_warn(neg, (ulonglong)(neg ? -llval : llval), - ltime, fuzzy_date, 0 /* TODO */)) + ltime, fuzzy_date, 0, 0 /* TODO */)) goto null; return 0; } @@ -5106,12 +5106,12 @@ bool Item_dyncol_get::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) /* fall through */ case DYN_COL_DOUBLE: if (double_to_datetime_with_warn(val.x.double_value, ltime, fuzzy_date, - 0 /* TODO */)) + 0, 0 /* TODO */)) goto null; return 0; case DYN_COL_DECIMAL: if (decimal_to_datetime_with_warn((my_decimal*)&val.x.decimal.value, ltime, - fuzzy_date, 0 /* TODO */)) + fuzzy_date, 0, 0 /* TODO */)) goto null; return 0; case DYN_COL_STRING: diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index dc5a089..82dbca5 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -430,7 +430,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, val_begin, length, - cached_timestamp_type, NullS); + cached_timestamp_type, 0, NullS); break; } } while (++val != val_end); @@ -1866,13 +1866,13 @@ bool Item_func_sec_to_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) { ErrConvInteger err2(sec, unsigned_flag); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &err2, MYSQL_TIMESTAMP_TIME, NullS); + &err2, MYSQL_TIMESTAMP_TIME, 0, NullS); } else { ErrConvString err2(err); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &err2, MYSQL_TIMESTAMP_TIME, NullS); + &err2, MYSQL_TIMESTAMP_TIME, 0, NullS); } return 0; } @@ -2894,7 +2894,7 @@ bool Item_func_maketime::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) int len = (int)(ptr - buf) + sprintf(ptr, ":%02u:%02u", (uint)minute, (uint)second); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, buf, len, MYSQL_TIMESTAMP_TIME, - NullS); + 0, NullS); } return (null_value= 0); diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 0bb1974..8e54fa1 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -5449,8 +5449,8 @@ ER_DIVISION_BY_ZERO 22012 ger "Division durch 0" hindi "0 से विभाजन" ER_TRUNCATED_WRONG_VALUE_FOR_FIELD 22007 - eng "Incorrect %-.32s value: '%-.128s' for column '%.192s' at row %lu" - ger "Falscher %-.32s-Wert: '%-.128s' für Feld '%.192s' in Zeile %lu" + eng "Incorrect %-.32s value: '%-.128s' for column `%.192s`.`%.192s`.`%.192s` at row %lu" + ger "Falscher %-.32s-Wert: '%-.128s' für Feld '`%.192s`.`%.192s`.`%.192s` in Zeile %lu" ER_ILLEGAL_VALUE_FOR_TYPE 22007 eng "Illegal %s '%-.192s' value found during parsing" ger "Nicht zulässiger %s-Wert '%-.192s' beim Parsen gefunden" diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 71d5b80..8f8607d 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3009,6 +3009,10 @@ int select_export::send_data(List<Item> &items) error_pos= copier.most_important_error_pos(); if (error_pos) { + /* + TODO: + add new error message that will show user this printable_buff + char printable_buff[32]; convert_to_printable(printable_buff, sizeof(printable_buff), error_pos, res->ptr() + res->length() - error_pos, @@ -3018,6 +3022,11 @@ int select_export::send_data(List<Item> &items) ER_THD(thd, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), "string", printable_buff, item->name, static_cast<long>(row_count)); + */ + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, + ER_THD(thd, WARN_DATA_TRUNCATED), + item->name, static_cast<long>(row_count)); } else if (copier.source_end_pos() < res->ptr() + res->length()) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 02780e7..1d8ea36 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9546,6 +9546,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, goto err_new_table_cleanup; } } + new_table->s->orig_table_name= table->s->table_name.str; + /* Note: In case of MERGE table, we do not attach children. We do not copy data for MERGE tables. Only the children have data. @@ -9809,6 +9811,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, thd->abort_on_warning= true; make_truncated_value_warning(thd, Sql_condition::WARN_LEVEL_WARN, f_val, strlength(f_val), t_type, + new_table->s, alter_ctx.datetime_field->field_name); thd->abort_on_warning= save_abort_on_warning; } diff --git a/sql/sql_time.cc b/sql/sql_time.cc index cdb9f4e..aaa6dab 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -223,7 +223,7 @@ check_date_with_warn(const MYSQL_TIME *ltime, ulonglong fuzzy_date, { ErrConvTime str(ltime); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &str, ts_type, 0); + &str, ts_type, 0, 0); return true; } return false; @@ -240,7 +240,7 @@ adjust_time_range_with_warn(MYSQL_TIME *ltime, uint dec) return true; if (warnings) make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &str, MYSQL_TIMESTAMP_TIME, NullS); + &str, MYSQL_TIMESTAMP_TIME, 0, NullS); return false; } @@ -329,7 +329,7 @@ str_to_datetime_with_warn(CHARSET_INFO *cs, ret_val ? Sql_condition::WARN_LEVEL_WARN : Sql_condition::time_warn_level(status.warnings), str, length, flags & TIME_TIME_ONLY ? - MYSQL_TIMESTAMP_TIME : l_time->time_type, NullS); + MYSQL_TIMESTAMP_TIME : l_time->time_type, 0, NullS); DBUG_EXECUTE_IF("str_to_datetime_warn", push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_YES, str);); @@ -353,7 +353,7 @@ str_to_datetime_with_warn(CHARSET_INFO *cs, static bool number_to_time_with_warn(bool neg, ulonglong nr, ulong sec_part, MYSQL_TIME *ltime, ulonglong fuzzydate, const ErrConv *str, - const char *field_name) + const TABLE_SHARE *s, const char *field_name) { int was_cut; longlong res; @@ -387,14 +387,15 @@ static bool number_to_time_with_warn(bool neg, ulonglong nr, ulong sec_part, Sql_condition::WARN_LEVEL_WARN, str, res < 0 ? MYSQL_TIMESTAMP_ERROR : mysql_type_to_time_type(f_type), - field_name); + s, field_name); } return res < 0; } bool double_to_datetime_with_warn(double value, MYSQL_TIME *ltime, - ulonglong fuzzydate, const char *field_name) + ulonglong fuzzydate, + const TABLE_SHARE *s, const char *field_name) { const ErrConvDouble str(value); bool neg= value < 0; @@ -408,28 +409,30 @@ bool double_to_datetime_with_warn(double value, MYSQL_TIME *ltime, longlong nr= static_cast<ulonglong>(floor(value)); uint sec_part= static_cast<ulong>((value - floor(value))*TIME_SECOND_PART_FACTOR); return number_to_time_with_warn(neg, nr, sec_part, ltime, fuzzydate, &str, - field_name); + s, field_name); } bool decimal_to_datetime_with_warn(const my_decimal *value, MYSQL_TIME *ltime, - ulonglong fuzzydate, const char *field_name) + ulonglong fuzzydate, + const TABLE_SHARE *s, const char *field_name) { const ErrConvDecimal str(value); ulonglong nr; ulong sec_part; bool neg= my_decimal2seconds(value, &nr, &sec_part); return number_to_time_with_warn(neg, nr, sec_part, ltime, fuzzydate, &str, - field_name); + s, field_name); } bool int_to_datetime_with_warn(bool neg, ulonglong value, MYSQL_TIME *ltime, - ulonglong fuzzydate, const char *field_name) + ulonglong fuzzydate, + const TABLE_SHARE *s, const char *field_name) { const ErrConvInteger str(neg ? - (longlong) value : (longlong) value, !neg); return number_to_time_with_warn(neg, value, 0, ltime, - fuzzydate, &str, field_name); + fuzzydate, &str, s, field_name); } @@ -856,7 +859,7 @@ void make_truncated_value_warning(THD *thd, Sql_condition::enum_warning_level level, const ErrConv *sval, timestamp_type time_type, - const char *field_name) + const TABLE_SHARE *s, const char *field_name) { char warn_buff[MYSQL_ERRMSG_SIZE]; const char *type_str; @@ -877,7 +880,8 @@ void make_truncated_value_warning(THD *thd, if (field_name) cs->cset->snprintf(cs, warn_buff, sizeof(warn_buff), ER_THD(thd, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), - type_str, sval->ptr(), field_name, + type_str, sval->ptr(), + s->db.str, s->error_table_name(), field_name, (ulong) thd->get_stmt_da()->current_row_for_warning()); else { @@ -1205,7 +1209,7 @@ make_date_with_warn(MYSQL_TIME *ltime, ulonglong fuzzy_date, /* e.g. negative time */ ErrConvTime str(ltime); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &str, ts_type, 0); + &str, ts_type, 0, 0); return true; } if ((ltime->time_type= ts_type) == MYSQL_TIMESTAMP_DATE) @@ -1369,7 +1373,7 @@ time_to_datetime_with_warn(THD *thd, { ErrConvTime str(from); make_truncated_value_warning(thd, Sql_condition::WARN_LEVEL_WARN, - &str, MYSQL_TIMESTAMP_DATETIME, 0); + &str, MYSQL_TIMESTAMP_DATETIME, 0, 0); return true; } return false; diff --git a/sql/sql_time.h b/sql/sql_time.h index d560edc..260e6e3 100644 --- a/sql/sql_time.h +++ b/sql/sql_time.h @@ -44,13 +44,13 @@ bool str_to_datetime_with_warn(CHARSET_INFO *cs, const char *str, ulonglong flags); bool double_to_datetime_with_warn(double value, MYSQL_TIME *ltime, ulonglong fuzzydate, - const char *name); + const TABLE_SHARE *s, const char *name); bool decimal_to_datetime_with_warn(const my_decimal *value, MYSQL_TIME *ltime, ulonglong fuzzydate, - const char *name); + const TABLE_SHARE *s, const char *name); bool int_to_datetime_with_warn(bool neg, ulonglong value, MYSQL_TIME *ltime, ulonglong fuzzydate, - const char *name); + const TABLE_SHARE *s, const char *name); bool time_to_datetime(THD *thd, const MYSQL_TIME *tm, MYSQL_TIME *dt); bool time_to_datetime_with_warn(THD *thd, @@ -120,15 +120,15 @@ void make_truncated_value_warning(THD *thd, Sql_condition::enum_warning_level level, const ErrConv *str_val, timestamp_type time_type, - const char *field_name); + const TABLE_SHARE *s, const char *field_name); static inline void make_truncated_value_warning(THD *thd, Sql_condition::enum_warning_level level, const char *str_val, uint str_length, timestamp_type time_type, - const char *field_name) + const TABLE_SHARE *s, const char *field_name) { const ErrConvString str(str_val, str_length, &my_charset_bin); - make_truncated_value_warning(thd, level, &str, time_type, field_name); + make_truncated_value_warning(thd, level, &str, time_type, s, field_name); } extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type, diff --git a/sql/table.h b/sql/table.h index 4cd5c3b..b8bd0c8 100644 --- a/sql/table.h +++ b/sql/table.h @@ -625,6 +625,16 @@ struct TABLE_SHARE LEX_STRING normalized_path; /* unpack_filename(path) */ LEX_STRING connect_string; + const char* orig_table_name; /* Original table name for this tmp table */ + const char* error_table_name() const /* Get table name for error messages */ + { + return tmp_table ? ( + orig_table_name ? + orig_table_name : + "(temporary)") : + table_name.str; + } + /* Set of keys in use, implemented as a Bitmap. Excludes keys disabled by ALTER TABLE ... DISABLE KEYS.