diff options
-rw-r--r-- | mysql-test/r/compare.result | 4 | ||||
-rw-r--r-- | mysql-test/r/func_gconcat.result | 38 | ||||
-rw-r--r-- | mysql-test/r/func_group.result | 7 | ||||
-rw-r--r-- | mysql-test/r/type_varchar.result | 35 | ||||
-rw-r--r-- | mysql-test/t/type_varchar.test | 9 | ||||
-rw-r--r-- | sql/field.cc | 60 | ||||
-rw-r--r-- | sql/item.cc | 24 | ||||
-rw-r--r-- | sql/item.h | 6 | ||||
-rw-r--r-- | sql/item_func.h | 4 | ||||
-rw-r--r-- | sql/item_subselect.h | 2 | ||||
-rw-r--r-- | sql/item_sum.cc | 8 | ||||
-rw-r--r-- | sql/item_sum.h | 4 | ||||
-rw-r--r-- | sql/sql_string.h | 6 |
13 files changed, 183 insertions, 24 deletions
diff --git a/mysql-test/r/compare.result b/mysql-test/r/compare.result index da0ca8ddba1..c141b255716 100644 --- a/mysql-test/r/compare.result +++ b/mysql-test/r/compare.result @@ -46,6 +46,10 @@ create table t1 (a tinyint(1),b binary(1)); insert into t1 values (0x01,0x01); select * from t1 where a=b; a b +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: '' select * from t1 where a=b and b=0x01; a b +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: '' drop table if exists t1; diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 6989b89833b..53bcbfafdd5 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -64,11 +64,49 @@ grp group_concat(a order by a,d+c-ascii(c)-a) 1 1 2 2,3 3 4,5,6,7,8,9 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'a ' +Warning 1292 Truncated incorrect DOUBLE value: 'a ' +Warning 1292 Truncated incorrect DOUBLE value: 'a ' +Warning 1292 Truncated incorrect DOUBLE value: 'b ' +Warning 1292 Truncated incorrect DOUBLE value: 'b ' +Warning 1292 Truncated incorrect DOUBLE value: 'c ' +Warning 1292 Truncated incorrect DOUBLE value: 'a ' +Warning 1292 Truncated incorrect DOUBLE value: 'E ' +Warning 1292 Truncated incorrect DOUBLE value: 'b ' +Warning 1292 Truncated incorrect DOUBLE value: 'C ' +Warning 1292 Truncated incorrect DOUBLE value: 'b ' +Warning 1292 Truncated incorrect DOUBLE value: 'D ' +Warning 1292 Truncated incorrect DOUBLE value: 'd ' +Warning 1292 Truncated incorrect DOUBLE value: 'd ' +Warning 1292 Truncated incorrect DOUBLE value: 'd ' +Warning 1292 Truncated incorrect DOUBLE value: 'd ' +Warning 1292 Truncated incorrect DOUBLE value: 'c ' +Warning 1292 Truncated incorrect DOUBLE value: 'D ' select grp,group_concat(a order by d+c-ascii(c),a) from t1 group by grp; grp group_concat(a order by d+c-ascii(c),a) 1 1 2 3,2 3 7,8,4,6,9,5 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'a ' +Warning 1292 Truncated incorrect DOUBLE value: 'a ' +Warning 1292 Truncated incorrect DOUBLE value: 'a ' +Warning 1292 Truncated incorrect DOUBLE value: 'b ' +Warning 1292 Truncated incorrect DOUBLE value: 'b ' +Warning 1292 Truncated incorrect DOUBLE value: 'c ' +Warning 1292 Truncated incorrect DOUBLE value: 'a ' +Warning 1292 Truncated incorrect DOUBLE value: 'E ' +Warning 1292 Truncated incorrect DOUBLE value: 'b ' +Warning 1292 Truncated incorrect DOUBLE value: 'C ' +Warning 1292 Truncated incorrect DOUBLE value: 'b ' +Warning 1292 Truncated incorrect DOUBLE value: 'D ' +Warning 1292 Truncated incorrect DOUBLE value: 'd ' +Warning 1292 Truncated incorrect DOUBLE value: 'd ' +Warning 1292 Truncated incorrect DOUBLE value: 'd ' +Warning 1292 Truncated incorrect DOUBLE value: 'd ' +Warning 1292 Truncated incorrect DOUBLE value: 'c ' +Warning 1292 Truncated incorrect DOUBLE value: 'D ' select grp,group_concat(c order by 1) from t1 group by grp; grp group_concat(c order by 1) 1 a diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 23517f7b603..020f807ece2 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -62,6 +62,13 @@ NULL NULL 1 7 2 20.25 3 45.483163247594 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'a ' +Warning 1292 Truncated incorrect DOUBLE value: 'a ' +Warning 1292 Truncated incorrect DOUBLE value: 'b ' +Warning 1292 Truncated incorrect DOUBLE value: 'c ' +Warning 1292 Truncated incorrect DOUBLE value: 'C ' +Warning 1292 Truncated incorrect DOUBLE value: 'E ' create table t2 (grp int, a bigint unsigned, c char(10)); insert into t2 select grp,max(a)+max(grp),max(c) from t1 group by grp; replace into t2 select grp, a, c from t1 limit 2,1; diff --git a/mysql-test/r/type_varchar.result b/mysql-test/r/type_varchar.result index 1d707b83a4d..4c1aee24642 100644 --- a/mysql-test/r/type_varchar.result +++ b/mysql-test/r/type_varchar.result @@ -453,3 +453,38 @@ id name_id id en cz 2 3 2 en string 2 cz string 2 3 3 3 en string 3 cz string 3 drop table t1, t2, t3; +CREATE TABLE t1 (a CHAR(2)); +INSERT INTO t1 VALUES (10), (50), (30), ('1a'), (60), ('t'); +SELECT a,(a + 0) FROM t1 ORDER BY a; +a (a + 0) +10 10 +1a 1 +30 30 +50 50 +60 60 +t 0 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: '1a' +Warning 1292 Truncated incorrect DOUBLE value: 't ' +SELECT a,(a DIV 2) FROM t1 ORDER BY a; +a (a DIV 2) +10 5 +1a 0 +30 15 +50 25 +60 30 +t 0 +Warnings: +Warning 1292 Truncated incorrect INTEGER value: '1a' +Warning 1292 Truncated incorrect INTEGER value: 't ' +SELECT a,CAST(a AS SIGNED) FROM t1 ORDER BY a; +a CAST(a AS SIGNED) +10 10 +1a 1 +30 30 +50 50 +60 60 +t 0 +Warnings: +Warning 1292 Truncated incorrect INTEGER value: '1a' +Warning 1292 Truncated incorrect INTEGER value: 't' diff --git a/mysql-test/t/type_varchar.test b/mysql-test/t/type_varchar.test index 439e98471b2..cfb6472a7b4 100644 --- a/mysql-test/t/type_varchar.test +++ b/mysql-test/t/type_varchar.test @@ -187,3 +187,12 @@ left join t3 on t1.id=t3.id order by t3.id; --disable_metadata --enable_ps_protocol drop table t1, t2, t3; + +# +# Bug #11927: Warnings shown for CAST( chr as signed) but not (chr + 0) +# +CREATE TABLE t1 (a CHAR(2)); +INSERT INTO t1 VALUES (10), (50), (30), ('1a'), (60), ('t'); +SELECT a,(a + 0) FROM t1 ORDER BY a; +SELECT a,(a DIV 2) FROM t1 ORDER BY a; +SELECT a,CAST(a AS SIGNED) FROM t1 ORDER BY a; diff --git a/sql/field.cc b/sql/field.cc index 1cfd0843179..e9c4435b9e1 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -47,6 +47,8 @@ uchar Field_null::null[1]={1}; const char field_separator=','; #define DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE 320 +#define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128 +#define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128 #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \ ((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1))) @@ -6056,19 +6058,49 @@ int Field_longstr::store_decimal(const my_decimal *d) double Field_string::val_real(void) { - int not_used; - char *end_not_used; + int error; + char *end; CHARSET_INFO *cs= charset(); - return my_strntod(cs,ptr,field_length,&end_not_used,¬_used); + double result; + + result= my_strntod(cs,ptr,field_length,&end,&error); + if (!table->in_use->no_errors && + (error || (field_length != (uint32)(end - ptr) && + !check_if_only_end_space(cs, end, ptr + field_length)))) + { + char buf[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; + String tmp(buf, sizeof(buf), cs); + tmp.copy(ptr, field_length, cs); + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE, + ER(ER_TRUNCATED_WRONG_VALUE), + "DOUBLE", tmp.c_ptr()); + } + return result; } longlong Field_string::val_int(void) { - int not_used; - char *end_not_used; - CHARSET_INFO *cs=charset(); - return my_strntoll(cs,ptr,field_length,10,&end_not_used,¬_used); + int error; + char *end; + CHARSET_INFO *cs= charset(); + longlong result; + + result= my_strntoll(cs,ptr,field_length,10,&end,&error); + if (!table->in_use->no_errors && + (error || (field_length != (uint32)(end - ptr) && + !check_if_only_end_space(cs, end, ptr + field_length)))) + { + char buf[LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE]; + String tmp(buf, sizeof(buf), cs); + tmp.copy(ptr, field_length, cs); + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE, + ER(ER_TRUNCATED_WRONG_VALUE), + "INTEGER", tmp.c_ptr()); + } + return result; } @@ -6085,8 +6117,20 @@ String *Field_string::val_str(String *val_buffer __attribute__((unused)), my_decimal *Field_string::val_decimal(my_decimal *decimal_value) { - str2my_decimal(E_DEC_FATAL_ERROR, ptr, field_length, charset(), + int err= str2my_decimal(E_DEC_FATAL_ERROR, ptr, field_length, charset(), decimal_value); + if (!table->in_use->no_errors && err) + { + char buf[DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE]; + CHARSET_INFO *cs= charset(); + String tmp(buf, sizeof(buf), cs); + tmp.copy(ptr, field_length, cs); + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE, + ER(ER_TRUNCATED_WRONG_VALUE), + "DECIMAL", tmp.c_ptr()); + } + return decimal_value; } diff --git a/sql/item.cc b/sql/item.cc index 59d28c00416..2df85d9533e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2175,12 +2175,6 @@ void Item_string::print(String *str) } -inline bool check_if_only_end_space(CHARSET_INFO *cs, char *str, char *end) -{ - return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end; -} - - double Item_string::val_real() { DBUG_ASSERT(fixed == 1); @@ -4764,6 +4758,22 @@ bool Item_field::send(Protocol *protocol, String *buffer) } +void Item_field::update_null_value() +{ + /* + need to set no_errors to prevent warnings about type conversion + popping up. + */ + THD *thd= field->table->in_use; + int no_errors; + + no_errors= thd->no_errors; + thd->no_errors= 1; + Item::update_null_value(); + thd->no_errors= no_errors; +} + + Item_ref::Item_ref(Name_resolution_context *context_arg, Item **item, const char *table_name_arg, const char *field_name_arg) @@ -6120,7 +6130,7 @@ bool Item_cache_row::null_inside() } else { - values[i]->val_int(); + values[i]->update_null_value(); if (values[i]->null_value) return 1; } diff --git a/sql/item.h b/sql/item.h index 63d89113ec1..e0451febb1e 100644 --- a/sql/item.h +++ b/sql/item.h @@ -704,6 +704,11 @@ public: virtual bool is_null() { return 0; } /* + Make sure the null_value member has a correct value. + */ + virtual void update_null_value () { (void) val_int(); } + + /* Inform the item that there will be no distinction between its result being FALSE or NULL. @@ -1270,6 +1275,7 @@ public: bool get_date_result(TIME *ltime,uint fuzzydate); bool get_time(TIME *ltime); bool is_null() { return field->is_null(); } + void update_null_value(); Item *get_tmp_table_item(THD *thd); bool collect_item_field_processor(byte * arg); bool find_item_in_field_list_processor(byte *arg); diff --git a/sql/item_func.h b/sql/item_func.h index 9d94bc85d2c..ca835177f18 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -157,7 +157,7 @@ public: return (null_value=args[0]->get_time(ltime)); } bool is_null() { - (void) val_int(); /* Discard result. It sets null_value as side-effect. */ + update_null_value(); return null_value; } void signal_divide_by_null(); @@ -241,7 +241,7 @@ public: virtual double real_op()= 0; virtual my_decimal *decimal_op(my_decimal *)= 0; virtual String *str_op(String *)= 0; - bool is_null() { (void) val_real(); return null_value; } + bool is_null() { update_null_value(); return null_value; } }; /* function where type of result detected by first argument */ diff --git a/sql/item_subselect.h b/sql/item_subselect.h index f1be99353cc..35ded79b75d 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -91,7 +91,7 @@ public: enum Type type() const; bool is_null() { - val_int(); + update_null_value(); return null_value; } bool fix_fields(THD *thd, Item **ref); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index c2219aafd03..3fd3535ae83 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1050,7 +1050,7 @@ bool Item_sum_count::add() count++; else { - (void) args[0]->val_int(); + args[0]->update_null_value(); if (!args[0]->null_value) count++; } @@ -1957,7 +1957,7 @@ void Item_sum_count::reset_field() nr=1; else { - (void) args[0]->val_int(); + args[0]->update_null_value(); if (!args[0]->null_value) nr=1; } @@ -2067,7 +2067,7 @@ void Item_sum_count::update_field() nr++; else { - (void) args[0]->val_int(); + args[0]->update_null_value(); if (!args[0]->null_value) nr++; } @@ -2547,7 +2547,7 @@ bool Item_sum_count_distinct::setup(THD *thd) return TRUE; // End of memory if (item->const_item()) { - (void) item->val_int(); + item->update_null_value(); if (item->null_value) always_null=1; } diff --git a/sql/item_sum.h b/sql/item_sum.h index c11ef7e548a..ad05b3c9d12 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -618,7 +618,7 @@ public: double val_real(); longlong val_int(); my_decimal *val_decimal(my_decimal *); - bool is_null() { (void) val_int(); return null_value; } + bool is_null() { update_null_value(); return null_value; } String *val_str(String*); enum_field_types field_type() const { @@ -685,7 +685,7 @@ public: { /* can't be fix_fields()ed */ return (longlong) rint(val_real()); } String *val_str(String*); my_decimal *val_decimal(my_decimal *); - bool is_null() { (void) val_int(); return null_value; } + bool is_null() { update_null_value(); return null_value; } enum_field_types field_type() const { return hybrid_type == DECIMAL_RESULT ? diff --git a/sql/sql_string.h b/sql/sql_string.h index 09b8478adf8..2be2cca5427 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -363,3 +363,9 @@ public: return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length); } }; + +static inline bool check_if_only_end_space(CHARSET_INFO *cs, char *str, + char *end) +{ + return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end; +} |