Commit 278c3ea7 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-12826 Add Type_handler::val_int_signed_typecast() and...

MDEV-12826 Add Type_handler::val_int_signed_typecast() and Type_handler::val_int_unsigned_typecast()
parent fba7fbbc
......@@ -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;
......
......@@ -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.
......
......@@ -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);
......
......@@ -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 *
......
......@@ -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;
......@@ -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);
......@@ -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;
......@@ -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;
......@@ -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;
......@@ -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;
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment