Skip to content

Commit

Permalink
MDEV-12826 Add Type_handler::val_int_signed_typecast() and Type_handl…
Browse files Browse the repository at this point in the history
…er::val_int_unsigned_typecast()
  • Loading branch information
Alexander Barkov committed May 17, 2017
1 parent fba7fbb commit 278c3ea
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 65 deletions.
62 changes: 62 additions & 0 deletions sql/item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
14 changes: 12 additions & 2 deletions sql/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -880,14 +880,24 @@ class Item: public Value_source,
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.
Expand Down
63 changes: 0 additions & 63 deletions sql/item_func.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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("));
Expand All @@ -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);
Expand Down
64 changes: 64 additions & 0 deletions sql/sql_type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand Down
23 changes: 23 additions & 0 deletions sql/sql_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,9 @@ class Type_handler
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;

Expand Down Expand Up @@ -1060,6 +1063,16 @@ class Type_handler_row: public Type_handler
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);
Expand Down Expand Up @@ -1253,6 +1266,8 @@ class Type_handler_real_result: public Type_handler_numeric
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;
Expand Down Expand Up @@ -1324,6 +1339,8 @@ class Type_handler_decimal_result: public Type_handler_numeric
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;
Expand Down Expand Up @@ -1389,6 +1406,8 @@ class Type_handler_int_result: public Type_handler_numeric
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;
Expand Down Expand Up @@ -1457,6 +1476,8 @@ class Type_handler_temporal_result: public Type_handler
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;
Expand Down Expand Up @@ -1557,6 +1578,8 @@ class Type_handler_string_result: public Type_handler
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;
Expand Down

0 comments on commit 278c3ea

Please sign in to comment.