diff --git a/sql/item.cc b/sql/item.cc index a9c7604d154..243c10ddcbb 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -311,6 +311,56 @@ bool Item::is_null_from_temporal() } +longlong Item::val_int_from_str(int *error) +{ + char buff[MAX_FIELD_WIDTH]; + String tmp(buff,sizeof(buff), &my_charset_bin), *res; + + /* + For a string result, we must first get the string and then convert it + to a longlong + */ + if (!(res= val_str(&tmp))) + { + *error= 0; + return 0; + } + Converter_strtoll10_with_warn cnv(NULL, Warn_filter_all(), + res->charset(), res->ptr(), res->length()); + *error= cnv.error(); + return cnv.result(); +} + + +longlong Item::val_int_signed_typecast_from_str() +{ + int error; + longlong value= val_int_from_str(&error); + if (!null_value && value < 0 && error == 0) + push_note_converted_to_negative_complement(current_thd); + return value; +} + + +longlong Item::val_int_unsigned_typecast_from_str() +{ + int error; + longlong value= val_int_from_str(&error); + if (!null_value && error < 0) + push_note_converted_to_positive_complement(current_thd); + return value; +} + + +longlong Item::val_int_unsigned_typecast_from_int() +{ + longlong value= val_int(); + if (!null_value && unsigned_flag == 0 && value < 0) + push_note_converted_to_positive_complement(current_thd); + return value; +} + + String *Item::val_string_from_date(String *str) { MYSQL_TIME ltime; @@ -428,6 +478,18 @@ longlong Item::val_int_from_decimal() return result; } + +longlong Item::val_int_unsigned_typecast_from_decimal() +{ + longlong result; + my_decimal tmp, *dec= val_decimal(&tmp); + if (null_value) + return 0; + my_decimal2int(E_DEC_FATAL_ERROR, dec, 1, &result); + return result; +} + + int Item::save_time_in_field(Field *field, bool no_conversions) { MYSQL_TIME ltime; diff --git a/sql/item.h b/sql/item.h index 2de5214c99e..f9a90f719c9 100644 --- a/sql/item.h +++ b/sql/item.h @@ -880,14 +880,24 @@ public: to negative complements. Values of non-integer data types are adjusted to the SIGNED range. */ - virtual longlong val_int_signed_typecast(); + virtual longlong val_int_signed_typecast() + { + return cast_to_int_type_handler()->Item_val_int_signed_typecast(this); + } + longlong val_int_signed_typecast_from_str(); /** Get a value for CAST(x AS UNSIGNED). Negative signed integer values are converted to positive complements. Values of non-integer data types are adjusted to the UNSIGNED range. */ - virtual longlong val_int_unsigned_typecast(); + virtual longlong val_int_unsigned_typecast() + { + return cast_to_int_type_handler()->Item_val_int_unsigned_typecast(this); + } + longlong val_int_unsigned_typecast_from_decimal(); + longlong val_int_unsigned_typecast_from_int(); + longlong val_int_unsigned_typecast_from_str(); /* This is just a shortcut to avoid the cast. You should still use unsigned_flag to check the sign of the item. diff --git a/sql/item_func.cc b/sql/item_func.cc index cb5dd172634..3461427331b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -878,41 +878,6 @@ void Item_func_signed::print(String *str, enum_query_type query_type) } -longlong Item::val_int_from_str(int *error) -{ - char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff), &my_charset_bin), *res; - - /* - For a string result, we must first get the string and then convert it - to a longlong - */ - - if (!(res= val_str(&tmp))) - { - *error= 0; - return 0; - } - Converter_strtoll10_with_warn cnv(NULL, Warn_filter_all(), - res->charset(), res->ptr(), res->length()); - *error= cnv.error(); - return cnv.result(); -} - - -longlong Item::val_int_signed_typecast() -{ - if (cast_to_int_type_handler()->cmp_type() != STRING_RESULT) - return val_int(); - - int error; - longlong value= val_int_from_str(&error); - if (!null_value && value < 0 && error == 0) - push_note_converted_to_negative_complement(current_thd); - return value; -} - - void Item_func_unsigned::print(String *str, enum_query_type query_type) { str->append(STRING_WITH_LEN("cast(")); @@ -922,34 +887,6 @@ void Item_func_unsigned::print(String *str, enum_query_type query_type) } -longlong Item::val_int_unsigned_typecast() -{ - if (cast_to_int_type_handler()->cmp_type() == DECIMAL_RESULT) - { - longlong value; - my_decimal tmp, *dec= val_decimal(&tmp); - if (!null_value) - my_decimal2int(E_DEC_FATAL_ERROR, dec, 1, &value); - else - value= 0; - return value; - } - else if (cast_to_int_type_handler()->cmp_type() != STRING_RESULT) - { - longlong value= val_int(); - if (!null_value && unsigned_flag == 0 && value < 0) - push_note_converted_to_positive_complement(current_thd); - return value; - } - - int error; - longlong value= val_int_from_str(&error); - if (!null_value && error < 0) - push_note_converted_to_positive_complement(current_thd); - return value; -} - - String *Item_decimal_typecast::val_str(String *str) { my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf); diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 90f8d674e67..1dd7d6ce391 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -2976,6 +2976,70 @@ bool Type_handler_geometry:: #endif +/*************************************************************************/ + +longlong Type_handler_real_result:: + Item_val_int_signed_typecast(Item *item) const +{ + return item->val_int(); +} + +longlong Type_handler_int_result:: + Item_val_int_signed_typecast(Item *item) const +{ + return item->val_int(); +} + +longlong Type_handler_decimal_result:: + Item_val_int_signed_typecast(Item *item) const +{ + return item->val_int(); +} + +longlong Type_handler_temporal_result:: + Item_val_int_signed_typecast(Item *item) const +{ + return item->val_int(); +} + +longlong Type_handler_string_result:: + Item_val_int_signed_typecast(Item *item) const +{ + return item->val_int_signed_typecast_from_str(); +} + +/*************************************************************************/ + +longlong Type_handler_real_result:: + Item_val_int_unsigned_typecast(Item *item) const +{ + return item->val_int_unsigned_typecast_from_int(); +} + +longlong Type_handler_int_result:: + Item_val_int_unsigned_typecast(Item *item) const +{ + return item->val_int_unsigned_typecast_from_int(); +} + +longlong Type_handler_decimal_result:: + Item_val_int_unsigned_typecast(Item *item) const +{ + return item->val_int_unsigned_typecast_from_decimal(); +} + +longlong Type_handler_temporal_result:: + Item_val_int_unsigned_typecast(Item *item) const +{ + return item->val_int_unsigned_typecast_from_int(); +} + +longlong Type_handler_string_result:: + Item_val_int_unsigned_typecast(Item *item) const +{ + return item->val_int_unsigned_typecast_from_str(); +} + /*************************************************************************/ String * diff --git a/sql/sql_type.h b/sql/sql_type.h index 28bb2a2edc9..0f035d0ebd5 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -819,6 +819,9 @@ public: virtual bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const= 0; + virtual longlong Item_val_int_signed_typecast(Item *item) const= 0; + virtual longlong Item_val_int_unsigned_typecast(Item *item) const= 0; + virtual String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const= 0; @@ -1060,6 +1063,16 @@ public: DBUG_ASSERT(0); return true; } + longlong Item_val_int_signed_typecast(Item *item) const + { + DBUG_ASSERT(0); + return 0; + } + longlong Item_val_int_unsigned_typecast(Item *item) const + { + DBUG_ASSERT(0); + return 0; + } String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const { DBUG_ASSERT(0); @@ -1253,6 +1266,8 @@ public: bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const; bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const; bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const; + longlong Item_val_int_signed_typecast(Item *item) const; + longlong Item_val_int_unsigned_typecast(Item *item) const; String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const; String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *, String *) const; @@ -1324,6 +1339,8 @@ public: bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const; bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const; bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const; + longlong Item_val_int_signed_typecast(Item *item) const; + longlong Item_val_int_unsigned_typecast(Item *item) const; String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const; String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *, String *) const; @@ -1389,6 +1406,8 @@ public: bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const; bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const; bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const; + longlong Item_val_int_signed_typecast(Item *item) const; + longlong Item_val_int_unsigned_typecast(Item *item) const; String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const; String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *, String *) const; @@ -1457,6 +1476,8 @@ public: bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const; bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const; bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const; + longlong Item_val_int_signed_typecast(Item *item) const; + longlong Item_val_int_unsigned_typecast(Item *item) const; String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const; String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *, String *) const; @@ -1557,6 +1578,8 @@ public: bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const; bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const; bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const; + longlong Item_val_int_signed_typecast(Item *item) const; + longlong Item_val_int_unsigned_typecast(Item *item) const; String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const; String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *, String *) const;