mirror of
https://github.com/MariaDB/server.git
synced 2026-04-23 08:45:33 +02:00
MDEV-16910 Add class VDec
Adding classes VDec and VDec2_lazy, according to the task description. This patch removes around 250 duplicate code lines.
This commit is contained in:
parent
01e4426a63
commit
cb7b5fbf1c
26 changed files with 595 additions and 847 deletions
90
sql/field.cc
90
sql/field.cc
|
|
@ -1933,14 +1933,6 @@ Field::unpack(uchar* to, const uchar *from, const uchar *from_end,
|
|||
}
|
||||
|
||||
|
||||
my_decimal *Field::val_decimal(my_decimal *decimal)
|
||||
{
|
||||
/* This never have to be called */
|
||||
DBUG_ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Field_num::add_zerofill_and_unsigned(String &res) const
|
||||
{
|
||||
if (unsigned_flag)
|
||||
|
|
@ -3170,7 +3162,7 @@ void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value,
|
|||
Otherwise sets maximal number that can be stored in the field.
|
||||
|
||||
@param decimal_value my_decimal
|
||||
@param [OUT] native_error the error returned by my_decimal2binary().
|
||||
@param [OUT] native_error the error returned by my_decimal::to_binary().
|
||||
|
||||
@retval
|
||||
0 ok
|
||||
|
|
@ -3208,8 +3200,8 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value,
|
|||
}
|
||||
#endif
|
||||
|
||||
*native_error= my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
|
||||
decimal_value, ptr, precision, dec);
|
||||
*native_error= decimal_value->to_binary(ptr, precision, dec,
|
||||
E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW);
|
||||
|
||||
if (unlikely(*native_error == E_DEC_OVERFLOW))
|
||||
{
|
||||
|
|
@ -3217,7 +3209,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value,
|
|||
DBUG_PRINT("info", ("overflow"));
|
||||
set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
set_value_on_overflow(&buff, decimal_value->sign());
|
||||
my_decimal2binary(E_DEC_FATAL_ERROR, &buff, ptr, precision, dec);
|
||||
buff.to_binary(ptr, precision, dec);
|
||||
error= 1;
|
||||
}
|
||||
DBUG_EXECUTE("info", print_decimal_buff(decimal_value, (uchar *) ptr,
|
||||
|
|
@ -3382,37 +3374,6 @@ int Field_new_decimal::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg)
|
|||
}
|
||||
|
||||
|
||||
double Field_new_decimal::val_real(void)
|
||||
{
|
||||
ASSERT_COLUMN_MARKED_FOR_READ;
|
||||
double dbl;
|
||||
my_decimal decimal_value;
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), &dbl);
|
||||
return dbl;
|
||||
}
|
||||
|
||||
|
||||
longlong Field_new_decimal::val_int(void)
|
||||
{
|
||||
ASSERT_COLUMN_MARKED_FOR_READ;
|
||||
longlong i;
|
||||
my_decimal decimal_value;
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value),
|
||||
unsigned_flag, &i);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
ulonglong Field_new_decimal::val_uint(void)
|
||||
{
|
||||
ASSERT_COLUMN_MARKED_FOR_READ;
|
||||
longlong i;
|
||||
my_decimal decimal_value;
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), true, &i);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value)
|
||||
{
|
||||
ASSERT_COLUMN_MARKED_FOR_READ;
|
||||
|
|
@ -3425,27 +3386,6 @@ my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value)
|
|||
}
|
||||
|
||||
|
||||
String *Field_new_decimal::val_str(String *val_buffer,
|
||||
String *val_ptr __attribute__((unused)))
|
||||
{
|
||||
ASSERT_COLUMN_MARKED_FOR_READ;
|
||||
my_decimal decimal_value;
|
||||
uint fixed_precision= zerofill ? precision : 0;
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, val_decimal(&decimal_value),
|
||||
fixed_precision, dec, '0', val_buffer);
|
||||
val_buffer->set_charset(&my_charset_numeric);
|
||||
return val_buffer;
|
||||
}
|
||||
|
||||
|
||||
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.str);
|
||||
}
|
||||
|
||||
|
||||
int Field_new_decimal::cmp(const uchar *a,const uchar*b)
|
||||
{
|
||||
return memcmp(a, b, bin_size);
|
||||
|
|
@ -3600,8 +3540,8 @@ Item *Field_new_decimal::get_equal_const_item(THD *thd, const Context &ctx,
|
|||
if (const_item->field_type() != MYSQL_TYPE_NEWDECIMAL ||
|
||||
const_item->decimal_scale() != decimals())
|
||||
{
|
||||
my_decimal *val, val_buffer, val_buffer2;
|
||||
if (!(val= const_item->val_decimal(&val_buffer)))
|
||||
VDec val(const_item);
|
||||
if (val.is_null())
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
return const_item;
|
||||
|
|
@ -3611,9 +3551,9 @@ Item *Field_new_decimal::get_equal_const_item(THD *thd, const Context &ctx,
|
|||
See comments about truncation in the same place in
|
||||
Field_time::get_equal_const_item().
|
||||
*/
|
||||
my_decimal_round(E_DEC_FATAL_ERROR, val, decimals(), true, &val_buffer2);
|
||||
return new (thd->mem_root) Item_decimal(thd, field_name.str,
|
||||
&val_buffer2,
|
||||
my_decimal tmp;
|
||||
val.round_to(&tmp, decimals(), TRUNCATE);
|
||||
return new (thd->mem_root) Item_decimal(thd, field_name.str, &tmp,
|
||||
decimals(), field_length);
|
||||
}
|
||||
break;
|
||||
|
|
@ -4853,13 +4793,6 @@ Converter_double_to_longlong::push_warning(THD *thd,
|
|||
}
|
||||
|
||||
|
||||
int Field_real::store_decimal(const my_decimal *dm)
|
||||
{
|
||||
double dbl;
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, dm, &dbl);
|
||||
return store(dbl);
|
||||
}
|
||||
|
||||
int Field_real::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg)
|
||||
{
|
||||
return store(TIME_to_double(ltime));
|
||||
|
|
@ -7115,9 +7048,8 @@ uint Field_str::is_equal(Create_field *new_field)
|
|||
|
||||
int Field_longstr::store_decimal(const my_decimal *d)
|
||||
{
|
||||
char buff[DECIMAL_MAX_STR_LENGTH+1];
|
||||
String str(buff, sizeof(buff), &my_charset_numeric);
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
|
||||
StringBuffer<DECIMAL_MAX_STR_LENGTH+1> str;
|
||||
d->to_string(&str);
|
||||
return store(str.ptr(), str.length(), str.charset());
|
||||
}
|
||||
|
||||
|
|
|
|||
40
sql/field.h
40
sql/field.h
|
|
@ -813,7 +813,7 @@ public:
|
|||
return nr < 0 ? 0 : (ulonglong) nr;
|
||||
}
|
||||
virtual bool val_bool(void)= 0;
|
||||
virtual my_decimal *val_decimal(my_decimal *);
|
||||
virtual my_decimal *val_decimal(my_decimal *)=0;
|
||||
inline String *val_str(String *str) { return val_str(str, str); }
|
||||
/*
|
||||
val_str(buf1, buf2) gets two buffers and should use them as follows:
|
||||
|
|
@ -1956,7 +1956,7 @@ public:
|
|||
return Field_num::memcpy_field_possible(from) &&
|
||||
field_length >= from->field_length;
|
||||
}
|
||||
int store_decimal(const my_decimal *);
|
||||
int store_decimal(const my_decimal *dec) { return store(dec->to_double()); }
|
||||
int store_time_dec(const MYSQL_TIME *ltime, uint dec);
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
my_decimal *val_decimal(my_decimal *);
|
||||
|
|
@ -2039,8 +2039,8 @@ public:
|
|||
}
|
||||
int save_in_field(Field *to)
|
||||
{
|
||||
my_decimal buff;
|
||||
return to->store_decimal(val_decimal(&buff));
|
||||
my_decimal tmp(ptr, precision, dec);
|
||||
return to->store_decimal(&tmp);
|
||||
}
|
||||
bool memcpy_field_possible(const Field *from) const
|
||||
{
|
||||
|
|
@ -2056,17 +2056,33 @@ public:
|
|||
int store(longlong nr, bool unsigned_val);
|
||||
int store_time_dec(const MYSQL_TIME *ltime, uint dec);
|
||||
int store_decimal(const my_decimal *);
|
||||
double val_real(void);
|
||||
longlong val_int(void);
|
||||
ulonglong val_uint(void);
|
||||
double val_real(void)
|
||||
{
|
||||
return my_decimal(ptr, precision, dec).to_double();
|
||||
}
|
||||
longlong val_int(void)
|
||||
{
|
||||
return my_decimal(ptr, precision, dec).to_longlong(unsigned_flag);
|
||||
}
|
||||
ulonglong val_uint(void)
|
||||
{
|
||||
return (ulonglong) my_decimal(ptr, precision, dec).to_longlong(true);
|
||||
}
|
||||
my_decimal *val_decimal(my_decimal *);
|
||||
String *val_str(String*, String *);
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
String *val_str(String *val_buffer, String *val_ptr __attribute__((unused)))
|
||||
{
|
||||
uint fixed_precision= zerofill ? precision : 0;
|
||||
return my_decimal(ptr, precision, dec).
|
||||
to_string(val_buffer, fixed_precision, dec, '0');
|
||||
}
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
||||
{
|
||||
return my_decimal(ptr, precision, dec).
|
||||
to_datetime_with_warn(ltime, fuzzydate, field_name.str);
|
||||
}
|
||||
bool val_bool()
|
||||
{
|
||||
my_decimal decimal_value;
|
||||
my_decimal *val= val_decimal(&decimal_value);
|
||||
return val ? !my_decimal_is_zero(val) : 0;
|
||||
return my_decimal(ptr, precision, dec).to_bool();
|
||||
}
|
||||
int cmp(const uchar *, const uchar *);
|
||||
void sort_string(uchar *buff, uint length);
|
||||
|
|
|
|||
|
|
@ -413,8 +413,8 @@ void Field::do_field_real(Copy_field *copy)
|
|||
|
||||
void Field::do_field_decimal(Copy_field *copy)
|
||||
{
|
||||
my_decimal value;
|
||||
copy->to_field->store_decimal(copy->from_field->val_decimal(&value));
|
||||
my_decimal value(copy->from_field);
|
||||
copy->to_field->store_decimal(&value);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1114,8 +1114,7 @@ Type_handler_decimal_result::make_sort_key(uchar *to, Item *item,
|
|||
}
|
||||
*to++= 1;
|
||||
}
|
||||
my_decimal2binary(E_DEC_FATAL_ERROR, dec_val, to,
|
||||
item->max_length - (item->decimals ? 1 : 0),
|
||||
dec_val->to_binary(to, item->max_length - (item->decimals ? 1 : 0),
|
||||
item->decimals);
|
||||
}
|
||||
|
||||
|
|
|
|||
171
sql/item.cc
171
sql/item.cc
|
|
@ -253,17 +253,6 @@ String *Item::val_string_from_int(String *str)
|
|||
}
|
||||
|
||||
|
||||
String *Item::val_string_from_decimal(String *str)
|
||||
{
|
||||
my_decimal dec_buf, *dec= val_decimal(&dec_buf);
|
||||
if (null_value)
|
||||
return 0;
|
||||
my_decimal_round(E_DEC_FATAL_ERROR, dec, decimals, FALSE, &dec_buf);
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, &dec_buf, 0, 0, 0, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
longlong Item::val_int_from_str(int *error)
|
||||
{
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
|
|
@ -345,41 +334,6 @@ my_decimal *Item::val_decimal_from_string(my_decimal *decimal_value)
|
|||
}
|
||||
|
||||
|
||||
double Item::val_real_from_decimal()
|
||||
{
|
||||
/* Note that fix_fields may not be called for Item_avg_field items */
|
||||
double result;
|
||||
my_decimal value_buff, *dec_val= val_decimal(&value_buff);
|
||||
if (null_value)
|
||||
return 0.0;
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, dec_val, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
longlong Item::val_int_from_decimal()
|
||||
{
|
||||
/* Note that fix_fields may not be called for Item_avg_field items */
|
||||
longlong result;
|
||||
my_decimal value, *dec_val= val_decimal(&value);
|
||||
if (null_value)
|
||||
return 0;
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, dec_val, unsigned_flag, &result);
|
||||
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;
|
||||
|
|
@ -1404,17 +1358,6 @@ bool Item::get_date_from_real(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
|||
}
|
||||
|
||||
|
||||
bool Item::get_date_from_decimal(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
||||
{
|
||||
my_decimal value, *res;
|
||||
if (!(res= val_decimal(&value)) ||
|
||||
decimal_to_datetime_with_warn(res, ltime, fuzzydate,
|
||||
field_name_or_null()))
|
||||
return null_value|= make_zero_date(ltime, fuzzydate);
|
||||
return null_value= false;
|
||||
}
|
||||
|
||||
|
||||
bool Item::get_date_from_string(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
||||
{
|
||||
char buff[40];
|
||||
|
|
@ -1463,10 +1406,8 @@ bool Item::get_seconds(ulonglong *sec, ulong *sec_part)
|
|||
*sec_part= 0;
|
||||
return neg;
|
||||
}
|
||||
my_decimal tmp, *dec= val_decimal(&tmp);
|
||||
if (!dec)
|
||||
return 0;
|
||||
return my_decimal2seconds(dec, sec, sec_part);
|
||||
VDec tmp(this);
|
||||
return tmp.is_null() ? 0 : my_decimal2seconds(tmp.ptr(), sec, sec_part);
|
||||
}
|
||||
|
||||
const MY_LOCALE *Item::locale_from_val_str()
|
||||
|
|
@ -3737,7 +3678,7 @@ Item_decimal::Item_decimal(THD *thd, const char *str, const my_decimal *val_arg,
|
|||
}
|
||||
|
||||
|
||||
Item_decimal::Item_decimal(THD *thd, my_decimal *value_par):
|
||||
Item_decimal::Item_decimal(THD *thd, const my_decimal *value_par):
|
||||
Item_num(thd)
|
||||
{
|
||||
my_decimal2decimal(value_par, &decimal_value);
|
||||
|
|
@ -3750,44 +3691,15 @@ Item_decimal::Item_decimal(THD *thd, my_decimal *value_par):
|
|||
|
||||
|
||||
Item_decimal::Item_decimal(THD *thd, const uchar *bin, int precision, int scale):
|
||||
Item_num(thd)
|
||||
Item_num(thd),
|
||||
decimal_value(bin, precision, scale)
|
||||
{
|
||||
binary2my_decimal(E_DEC_FATAL_ERROR, bin,
|
||||
&decimal_value, precision, scale);
|
||||
decimals= (uint8) decimal_value.frac;
|
||||
max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
|
||||
unsigned_flag);
|
||||
}
|
||||
|
||||
|
||||
longlong Item_decimal::val_int()
|
||||
{
|
||||
longlong result;
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
double Item_decimal::val_real()
|
||||
{
|
||||
double result;
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
String *Item_decimal::val_str(String *result)
|
||||
{
|
||||
result->set_charset(&my_charset_numeric);
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Item_decimal::print(String *str, enum_query_type query_type)
|
||||
{
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, &str_value);
|
||||
str->append(str_value);
|
||||
}
|
||||
|
||||
|
||||
void Item_decimal::set_decimal_value(my_decimal *value_par)
|
||||
{
|
||||
my_decimal2decimal(value_par, &decimal_value);
|
||||
|
|
@ -4405,11 +4317,7 @@ double Item_param::PValue::val_real() const
|
|||
case INT_RESULT:
|
||||
return (double) integer;
|
||||
case DECIMAL_RESULT:
|
||||
{
|
||||
double result;
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, &m_decimal, &result);
|
||||
return result;
|
||||
}
|
||||
return m_decimal.to_double();
|
||||
case STRING_RESULT:
|
||||
return double_from_string_with_check(&m_string);
|
||||
case TIME_RESULT:
|
||||
|
|
@ -4434,11 +4342,7 @@ longlong Item_param::PValue::val_int(const Type_std_attributes *attr) const
|
|||
case INT_RESULT:
|
||||
return integer;
|
||||
case DECIMAL_RESULT:
|
||||
{
|
||||
longlong i;
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, &m_decimal, attr->unsigned_flag, &i);
|
||||
return i;
|
||||
}
|
||||
return m_decimal.to_longlong(attr->unsigned_flag);
|
||||
case STRING_RESULT:
|
||||
return longlong_from_string_with_check(&m_string);
|
||||
case TIME_RESULT:
|
||||
|
|
@ -4488,7 +4392,7 @@ String *Item_param::PValue::val_str(String *str,
|
|||
str->set(integer, &my_charset_bin);
|
||||
return str;
|
||||
case DECIMAL_RESULT:
|
||||
if (my_decimal2string(E_DEC_FATAL_ERROR, &m_decimal, 0, 0, 0, str) <= 1)
|
||||
if (m_decimal.to_string_native(str, 0, 0, 0) <= 1)
|
||||
return str;
|
||||
return NULL;
|
||||
case TIME_RESULT:
|
||||
|
|
@ -4529,8 +4433,7 @@ const String *Item_param::value_query_val_str(THD *thd, String *str) const
|
|||
str->set_real(value.real, NOT_FIXED_DEC, &my_charset_bin);
|
||||
return str;
|
||||
case DECIMAL_RESULT:
|
||||
if (my_decimal2string(E_DEC_FATAL_ERROR, &value.m_decimal,
|
||||
0, 0, 0, str) > 1)
|
||||
if (value.m_decimal.to_string_native(str, 0, 0, 0) > 1)
|
||||
return &my_null_string;
|
||||
return str;
|
||||
case TIME_RESULT:
|
||||
|
|
@ -5093,37 +4996,19 @@ int Item_copy_decimal::save_in_field(Field *field, bool no_conversions)
|
|||
|
||||
String *Item_copy_decimal::val_str(String *result)
|
||||
{
|
||||
if (null_value)
|
||||
return (String *) 0;
|
||||
result->set_charset(&my_charset_bin);
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, &cached_value, 0, 0, 0, result);
|
||||
return result;
|
||||
return null_value ? NULL : cached_value.to_string(result);
|
||||
}
|
||||
|
||||
|
||||
double Item_copy_decimal::val_real()
|
||||
{
|
||||
if (null_value)
|
||||
return 0.0;
|
||||
else
|
||||
{
|
||||
double result;
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, &cached_value, &result);
|
||||
return result;
|
||||
}
|
||||
return null_value ? 0.0 : cached_value.to_double();
|
||||
}
|
||||
|
||||
|
||||
longlong Item_copy_decimal::val_int()
|
||||
{
|
||||
if (null_value)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
longlong result;
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, &cached_value, unsigned_flag, &result);
|
||||
return result;
|
||||
}
|
||||
return null_value ? 0 : cached_value.to_longlong(unsigned_flag);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -6797,12 +6682,11 @@ int Item::save_real_in_field(Field *field, bool no_conversions)
|
|||
|
||||
int Item::save_decimal_in_field(Field *field, bool no_conversions)
|
||||
{
|
||||
my_decimal decimal_value;
|
||||
my_decimal *value= val_decimal(&decimal_value);
|
||||
if (null_value)
|
||||
VDec value(this);
|
||||
if (value.is_null())
|
||||
return set_field_to_null_with_conversions(field, no_conversions);
|
||||
field->set_notnull();
|
||||
return field->store_decimal(value);
|
||||
return field->store_decimal(value.ptr());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -10168,30 +10052,18 @@ bool Item_cache_decimal::cache_value()
|
|||
|
||||
double Item_cache_decimal::val_real()
|
||||
{
|
||||
double res;
|
||||
if (!has_value())
|
||||
return 0.0;
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &res);
|
||||
return res;
|
||||
return !has_value() ? 0.0 : decimal_value.to_double();
|
||||
}
|
||||
|
||||
longlong Item_cache_decimal::val_int()
|
||||
{
|
||||
longlong res;
|
||||
if (!has_value())
|
||||
return 0;
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &res);
|
||||
return res;
|
||||
return !has_value() ? 0 : decimal_value.to_longlong(unsigned_flag);
|
||||
}
|
||||
|
||||
String* Item_cache_decimal::val_str(String *str)
|
||||
{
|
||||
if (!has_value())
|
||||
return NULL;
|
||||
my_decimal_round(E_DEC_FATAL_ERROR, &decimal_value, decimals, FALSE,
|
||||
&decimal_value);
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, str);
|
||||
return str;
|
||||
return !has_value() ? NULL :
|
||||
decimal_value.to_string_round(str, decimals, &decimal_value);
|
||||
}
|
||||
|
||||
my_decimal *Item_cache_decimal::val_decimal(my_decimal *val)
|
||||
|
|
@ -10212,9 +10084,8 @@ Item *Item_cache_decimal::convert_to_basic_const_item(THD *thd)
|
|||
new_item= (Item*) new (thd->mem_root) Item_null(thd);
|
||||
else
|
||||
{
|
||||
my_decimal decimal_value;
|
||||
my_decimal *result= val_decimal(&decimal_value);
|
||||
new_item= (Item*) new (thd->mem_root) Item_decimal(thd, result);
|
||||
VDec tmp(this);
|
||||
new_item= (Item*) new (thd->mem_root) Item_decimal(thd, tmp.ptr());
|
||||
}
|
||||
return new_item;
|
||||
}
|
||||
|
|
|
|||
25
sql/item.h
25
sql/item.h
|
|
@ -863,6 +863,7 @@ protected:
|
|||
null_value= MY_TEST(rc || item->null_value);
|
||||
return rc;
|
||||
}
|
||||
public:
|
||||
/*
|
||||
This method is used if the item was not null but convertion to
|
||||
TIME/DATE/DATETIME failed. We return a zero date if allowed,
|
||||
|
|
@ -870,7 +871,6 @@ protected:
|
|||
*/
|
||||
bool make_zero_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
|
||||
public:
|
||||
/*
|
||||
Cache val_str() into the own buffer, e.g. to evaluate constant
|
||||
expressions with subqueries in the ORDER/GROUP clauses.
|
||||
|
|
@ -1197,7 +1197,6 @@ public:
|
|||
{
|
||||
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();
|
||||
/*
|
||||
|
|
@ -1378,18 +1377,15 @@ public:
|
|||
/* Helper functions, see item_sum.cc */
|
||||
String *val_string_from_real(String *str);
|
||||
String *val_string_from_int(String *str);
|
||||
String *val_string_from_decimal(String *str);
|
||||
my_decimal *val_decimal_from_real(my_decimal *decimal_value);
|
||||
my_decimal *val_decimal_from_int(my_decimal *decimal_value);
|
||||
my_decimal *val_decimal_from_string(my_decimal *decimal_value);
|
||||
longlong val_int_from_decimal();
|
||||
longlong val_int_from_real()
|
||||
{
|
||||
DBUG_ASSERT(is_fixed());
|
||||
return Converter_double_to_longlong_with_warn(val_real(), false).result();
|
||||
}
|
||||
longlong val_int_from_str(int *error);
|
||||
double val_real_from_decimal();
|
||||
|
||||
int save_time_in_field(Field *field, bool no_conversions);
|
||||
int save_date_in_field(Field *field, bool no_conversions);
|
||||
|
|
@ -1613,7 +1609,6 @@ public:
|
|||
bool get_date_from_int(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
bool get_date_from_year(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
bool get_date_from_real(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
bool get_date_from_decimal(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
bool get_date_from_string(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
bool get_time(MYSQL_TIME *ltime)
|
||||
{ return get_date(ltime, Time::flags_for_get_date()); }
|
||||
|
|
@ -4068,20 +4063,24 @@ public:
|
|||
CHARSET_INFO *charset);
|
||||
Item_decimal(THD *thd, const char *str, const my_decimal *val_arg,
|
||||
uint decimal_par, uint length);
|
||||
Item_decimal(THD *thd, my_decimal *value_par);
|
||||
Item_decimal(THD *thd, const my_decimal *value_par);
|
||||
Item_decimal(THD *thd, longlong val, bool unsig);
|
||||
Item_decimal(THD *thd, double val, int precision, int scale);
|
||||
Item_decimal(THD *thd, const uchar *bin, int precision, int scale);
|
||||
|
||||
const Type_handler *type_handler() const { return &type_handler_newdecimal; }
|
||||
longlong val_int();
|
||||
double val_real();
|
||||
String *val_str(String*);
|
||||
longlong val_int() { return decimal_value.to_longlong(unsigned_flag); }
|
||||
double val_real() { return decimal_value.to_double(); }
|
||||
String *val_str(String *to) { return decimal_value.to_string(to); }
|
||||
my_decimal *val_decimal(my_decimal *val) { return &decimal_value; }
|
||||
const my_decimal *const_ptr_my_decimal() const { return &decimal_value; }
|
||||
int save_in_field(Field *field, bool no_conversions);
|
||||
Item *clone_item(THD *thd);
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
virtual void print(String *str, enum_query_type query_type)
|
||||
{
|
||||
decimal_value.to_string(&str_value);
|
||||
str->append(str_value);
|
||||
}
|
||||
Item *neg(THD *thd);
|
||||
uint decimal_precision() const { return decimal_value.precision(); }
|
||||
void set_decimal_value(my_decimal *value_par);
|
||||
|
|
@ -5955,7 +5954,7 @@ public:
|
|||
longlong val_int();
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
||||
{
|
||||
return get_date_from_decimal(ltime, fuzzydate);
|
||||
return VDec(this).to_datetime_with_warn(ltime, fuzzydate, this);
|
||||
}
|
||||
void copy();
|
||||
Item *get_copy(THD *thd)
|
||||
|
|
@ -6637,7 +6636,7 @@ public:
|
|||
String* val_str(String *str);
|
||||
my_decimal *val_decimal(my_decimal *);
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
||||
{ return get_date_from_decimal(ltime, fuzzydate); }
|
||||
{ return VDec(this).to_datetime_with_warn(ltime, fuzzydate, this); }
|
||||
bool cache_value();
|
||||
Item *convert_to_basic_const_item(THD *thd);
|
||||
Item *get_copy(THD *thd)
|
||||
|
|
|
|||
|
|
@ -225,16 +225,15 @@ Cached_item_decimal::Cached_item_decimal(Item *it)
|
|||
|
||||
bool Cached_item_decimal::cmp()
|
||||
{
|
||||
my_decimal tmp;
|
||||
my_decimal *ptmp= item->val_decimal(&tmp);
|
||||
if (null_value != item->null_value ||
|
||||
(!item->null_value && my_decimal_cmp(&value, ptmp)))
|
||||
VDec tmp(item);
|
||||
if (null_value != tmp.is_null() ||
|
||||
(!tmp.is_null() && tmp.cmp(&value)))
|
||||
{
|
||||
null_value= item->null_value;
|
||||
null_value= tmp.is_null();
|
||||
/* Save only not null values */
|
||||
if (!null_value)
|
||||
{
|
||||
my_decimal2decimal(ptmp, &value);
|
||||
my_decimal2decimal(tmp.ptr(), &value);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
|
@ -245,17 +244,9 @@ bool Cached_item_decimal::cmp()
|
|||
|
||||
int Cached_item_decimal::cmp_read_only()
|
||||
{
|
||||
my_decimal tmp;
|
||||
my_decimal *ptmp= item->val_decimal(&tmp);
|
||||
VDec tmp(item);
|
||||
if (null_value)
|
||||
{
|
||||
if (item->null_value)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if (item->null_value)
|
||||
return 1;
|
||||
return my_decimal_cmp(&value, ptmp);
|
||||
return tmp.is_null() ? 0 : -1;
|
||||
return tmp.is_null() ? 1 : value.cmp(tmp.ptr());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -795,17 +795,15 @@ int Arg_comparator::compare_real()
|
|||
|
||||
int Arg_comparator::compare_decimal()
|
||||
{
|
||||
my_decimal decimal1;
|
||||
my_decimal *val1= (*a)->val_decimal(&decimal1);
|
||||
if (!(*a)->null_value)
|
||||
VDec val1(*a);
|
||||
if (!val1.is_null())
|
||||
{
|
||||
my_decimal decimal2;
|
||||
my_decimal *val2= (*b)->val_decimal(&decimal2);
|
||||
if (!(*b)->null_value)
|
||||
VDec val2(*b);
|
||||
if (!val2.is_null())
|
||||
{
|
||||
if (set_null)
|
||||
owner->null_value= 0;
|
||||
return my_decimal_cmp(val1, val2);
|
||||
return val1.cmp(val2);
|
||||
}
|
||||
}
|
||||
if (set_null)
|
||||
|
|
@ -824,12 +822,10 @@ int Arg_comparator::compare_e_real()
|
|||
|
||||
int Arg_comparator::compare_e_decimal()
|
||||
{
|
||||
my_decimal decimal1, decimal2;
|
||||
my_decimal *val1= (*a)->val_decimal(&decimal1);
|
||||
my_decimal *val2= (*b)->val_decimal(&decimal2);
|
||||
if ((*a)->null_value || (*b)->null_value)
|
||||
return MY_TEST((*a)->null_value && (*b)->null_value);
|
||||
return MY_TEST(my_decimal_cmp(val1, val2) == 0);
|
||||
VDec val1(*a), val2(*b);
|
||||
if (val1.is_null() || val1.is_null())
|
||||
return MY_TEST(val1.is_null() && val2.is_null());
|
||||
return MY_TEST(val1.cmp(val2) == 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1951,11 +1947,11 @@ longlong Item_func_interval::val_int()
|
|||
((el->result_type() == DECIMAL_RESULT) ||
|
||||
(el->result_type() == INT_RESULT)))
|
||||
{
|
||||
my_decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf);
|
||||
VDec e_dec(el);
|
||||
/* Skip NULL ranges. */
|
||||
if (el->null_value)
|
||||
if (e_dec.is_null())
|
||||
continue;
|
||||
if (my_decimal_cmp(e_dec, dec) > 0)
|
||||
if (e_dec.cmp(dec) > 0)
|
||||
return i - 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -2180,21 +2176,19 @@ bool Item_func_between::val_int_cmp_int_finalize(longlong value,
|
|||
|
||||
longlong Item_func_between::val_int_cmp_decimal()
|
||||
{
|
||||
my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
|
||||
a_buf, *a_dec, b_buf, *b_dec;
|
||||
if ((null_value=args[0]->null_value))
|
||||
VDec dec(args[0]);
|
||||
if ((null_value= dec.is_null()))
|
||||
return 0; /* purecov: inspected */
|
||||
a_dec= args[1]->val_decimal(&a_buf);
|
||||
b_dec= args[2]->val_decimal(&b_buf);
|
||||
if (!args[1]->null_value && !args[2]->null_value)
|
||||
return (longlong) ((my_decimal_cmp(dec, a_dec) >= 0 &&
|
||||
my_decimal_cmp(dec, b_dec) <= 0) != negated);
|
||||
if (args[1]->null_value && args[2]->null_value)
|
||||
VDec a_dec(args[1]), b_dec(args[2]);
|
||||
if (!a_dec.is_null() && !b_dec.is_null())
|
||||
return (longlong) ((dec.cmp(a_dec) >= 0 &&
|
||||
dec.cmp(b_dec) <= 0) != negated);
|
||||
if (a_dec.is_null() && b_dec.is_null())
|
||||
null_value= true;
|
||||
else if (args[1]->null_value)
|
||||
null_value= (my_decimal_cmp(dec, b_dec) <= 0);
|
||||
else if (a_dec.is_null())
|
||||
null_value= (dec.cmp(b_dec) <= 0);
|
||||
else
|
||||
null_value= (my_decimal_cmp(dec, a_dec) >= 0);
|
||||
null_value= (dec.cmp(a_dec) >= 0);
|
||||
return (longlong) (!null_value && negated);
|
||||
}
|
||||
|
||||
|
|
@ -3971,9 +3965,8 @@ int cmp_item_decimal::cmp_not_null(const Value *val)
|
|||
|
||||
int cmp_item_decimal::cmp(Item *arg)
|
||||
{
|
||||
my_decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
|
||||
return (m_null_value || arg->null_value) ?
|
||||
UNKNOWN : (my_decimal_cmp(&value, tmp) != 0);
|
||||
VDec tmp(arg);
|
||||
return m_null_value || tmp.is_null() ? UNKNOWN : (tmp.cmp(&value) != 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
301
sql/item_func.cc
301
sql/item_func.cc
|
|
@ -809,50 +809,6 @@ bool Item_func_plus::fix_length_and_dec(void)
|
|||
}
|
||||
|
||||
|
||||
String *Item_func_hybrid_field_type::val_str_from_decimal_op(String *str)
|
||||
{
|
||||
my_decimal decimal_value, *val;
|
||||
if (!(val= decimal_op_with_null_check(&decimal_value)))
|
||||
return 0; // null is set
|
||||
DBUG_ASSERT(!null_value);
|
||||
my_decimal_round(E_DEC_FATAL_ERROR, val, decimals, FALSE, val);
|
||||
str->set_charset(collation.collation);
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, val, 0, 0, 0, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
double Item_func_hybrid_field_type::val_real_from_decimal_op()
|
||||
{
|
||||
my_decimal decimal_value, *val;
|
||||
if (!(val= decimal_op_with_null_check(&decimal_value)))
|
||||
return 0.0; // null is set
|
||||
double result;
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, val, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
longlong Item_func_hybrid_field_type::val_int_from_decimal_op()
|
||||
{
|
||||
my_decimal decimal_value, *val;
|
||||
if (!(val= decimal_op_with_null_check(&decimal_value)))
|
||||
return 0; // null is set
|
||||
longlong result;
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, val, unsigned_flag, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Item_func_hybrid_field_type::get_date_from_decimal_op(MYSQL_TIME *ltime,
|
||||
ulonglong fuzzydate)
|
||||
{
|
||||
my_decimal value, *res;
|
||||
if (!(res= decimal_op_with_null_check(&value)) ||
|
||||
decimal_to_datetime_with_warn(res, ltime, fuzzydate,
|
||||
field_name_or_null()))
|
||||
return make_zero_mysql_time(ltime, fuzzydate);
|
||||
return (null_value= 0);
|
||||
}
|
||||
|
||||
|
||||
String *Item_func_hybrid_field_type::val_str_from_int_op(String *str)
|
||||
{
|
||||
longlong nr= int_op();
|
||||
|
|
@ -1051,47 +1007,15 @@ void Item_func_unsigned::print(String *str, enum_query_type query_type)
|
|||
}
|
||||
|
||||
|
||||
String *Item_decimal_typecast::val_str(String *str)
|
||||
{
|
||||
my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
|
||||
if (null_value)
|
||||
return NULL;
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, tmp, 0, 0, 0, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
double Item_decimal_typecast::val_real()
|
||||
{
|
||||
my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
|
||||
double res;
|
||||
if (null_value)
|
||||
return 0.0;
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, tmp, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
longlong Item_decimal_typecast::val_int()
|
||||
{
|
||||
my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
|
||||
longlong res;
|
||||
if (null_value)
|
||||
return 0;
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, tmp, unsigned_flag, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
|
||||
{
|
||||
my_decimal tmp_buf, *tmp= args[0]->val_decimal(&tmp_buf);
|
||||
VDec tmp(args[0]);
|
||||
bool sign;
|
||||
uint precision;
|
||||
|
||||
if ((null_value= args[0]->null_value))
|
||||
if ((null_value= tmp.is_null()))
|
||||
return NULL;
|
||||
my_decimal_round(E_DEC_FATAL_ERROR, tmp, decimals, FALSE, dec);
|
||||
tmp.round_to(dec, decimals, HALF_UP);
|
||||
sign= dec->sign();
|
||||
if (unsigned_flag)
|
||||
{
|
||||
|
|
@ -1275,17 +1199,13 @@ err:
|
|||
|
||||
my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
my_decimal value1, *val1;
|
||||
my_decimal value2, *val2;
|
||||
val1= args[0]->val_decimal(&value1);
|
||||
if ((null_value= args[0]->null_value))
|
||||
return 0;
|
||||
val2= args[1]->val_decimal(&value2);
|
||||
if (!(null_value= (args[1]->null_value ||
|
||||
VDec2_lazy val(args[0], args[1]);
|
||||
if (!(null_value= (val.has_null() ||
|
||||
check_decimal_overflow(my_decimal_add(E_DEC_FATAL_ERROR &
|
||||
~E_DEC_OVERFLOW,
|
||||
decimal_value,
|
||||
val1, val2)) > 3)))
|
||||
val.m_a.ptr(),
|
||||
val.m_b.ptr())) > 3)))
|
||||
return decimal_value;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1415,18 +1335,13 @@ err:
|
|||
|
||||
my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
my_decimal value1, *val1;
|
||||
my_decimal value2, *val2=
|
||||
|
||||
val1= args[0]->val_decimal(&value1);
|
||||
if ((null_value= args[0]->null_value))
|
||||
return 0;
|
||||
val2= args[1]->val_decimal(&value2);
|
||||
if (!(null_value= (args[1]->null_value ||
|
||||
(check_decimal_overflow(my_decimal_sub(E_DEC_FATAL_ERROR &
|
||||
VDec2_lazy val(args[0], args[1]);
|
||||
if (!(null_value= (val.has_null() ||
|
||||
check_decimal_overflow(my_decimal_sub(E_DEC_FATAL_ERROR &
|
||||
~E_DEC_OVERFLOW,
|
||||
decimal_value, val1,
|
||||
val2)) > 3))))
|
||||
decimal_value,
|
||||
val.m_a.ptr(),
|
||||
val.m_b.ptr())) > 3)))
|
||||
return decimal_value;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1525,17 +1440,13 @@ err:
|
|||
|
||||
my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
my_decimal value1, *val1;
|
||||
my_decimal value2, *val2;
|
||||
val1= args[0]->val_decimal(&value1);
|
||||
if ((null_value= args[0]->null_value))
|
||||
return 0;
|
||||
val2= args[1]->val_decimal(&value2);
|
||||
if (!(null_value= (args[1]->null_value ||
|
||||
(check_decimal_overflow(my_decimal_mul(E_DEC_FATAL_ERROR &
|
||||
VDec2_lazy val(args[0], args[1]);
|
||||
if (!(null_value= (val.has_null() ||
|
||||
check_decimal_overflow(my_decimal_mul(E_DEC_FATAL_ERROR &
|
||||
~E_DEC_OVERFLOW,
|
||||
decimal_value, val1,
|
||||
val2)) > 3))))
|
||||
decimal_value,
|
||||
val.m_a.ptr(),
|
||||
val.m_b.ptr())) > 3)))
|
||||
return decimal_value;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1586,21 +1497,15 @@ double Item_func_div::real_op()
|
|||
|
||||
my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
my_decimal value1, *val1;
|
||||
my_decimal value2, *val2;
|
||||
int err;
|
||||
|
||||
val1= args[0]->val_decimal(&value1);
|
||||
if ((null_value= args[0]->null_value))
|
||||
return 0;
|
||||
val2= args[1]->val_decimal(&value2);
|
||||
if ((null_value= args[1]->null_value))
|
||||
VDec2_lazy val(args[0], args[1]);
|
||||
if ((null_value= val.has_null()))
|
||||
return 0;
|
||||
if ((err= check_decimal_overflow(my_decimal_div(E_DEC_FATAL_ERROR &
|
||||
~E_DEC_OVERFLOW &
|
||||
~E_DEC_DIV_ZERO,
|
||||
decimal_value,
|
||||
val1, val2,
|
||||
val.m_a.ptr(), val.m_b.ptr(),
|
||||
prec_increment))) > 3)
|
||||
{
|
||||
if (err == E_DEC_DIV_ZERO)
|
||||
|
|
@ -1690,20 +1595,14 @@ longlong Item_func_int_div::val_int()
|
|||
if (args[0]->result_type() != INT_RESULT ||
|
||||
args[1]->result_type() != INT_RESULT)
|
||||
{
|
||||
my_decimal tmp;
|
||||
my_decimal *val0p= args[0]->val_decimal(&tmp);
|
||||
if ((null_value= args[0]->null_value))
|
||||
VDec2_lazy val(args[0], args[1]);
|
||||
if ((null_value= val.has_null()))
|
||||
return 0;
|
||||
my_decimal val0= *val0p;
|
||||
|
||||
my_decimal *val1p= args[1]->val_decimal(&tmp);
|
||||
if ((null_value= args[1]->null_value))
|
||||
return 0;
|
||||
my_decimal val1= *val1p;
|
||||
|
||||
int err;
|
||||
my_decimal tmp;
|
||||
if ((err= my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, &tmp,
|
||||
&val0, &val1, 0)) > 3)
|
||||
val.m_a.ptr(), val.m_b.ptr(), 0)) > 3)
|
||||
{
|
||||
if (err == E_DEC_DIV_ZERO)
|
||||
signal_divide_by_null();
|
||||
|
|
@ -1711,8 +1610,7 @@ longlong Item_func_int_div::val_int()
|
|||
}
|
||||
|
||||
my_decimal truncated;
|
||||
const bool do_truncate= true;
|
||||
if (my_decimal_round(E_DEC_FATAL_ERROR, &tmp, 0, do_truncate, &truncated))
|
||||
if (tmp.round_to(&truncated, 0, TRUNCATE))
|
||||
DBUG_ASSERT(false);
|
||||
|
||||
longlong res;
|
||||
|
|
@ -1814,17 +1712,11 @@ double Item_func_mod::real_op()
|
|||
|
||||
my_decimal *Item_func_mod::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
my_decimal value1, *val1;
|
||||
my_decimal value2, *val2;
|
||||
|
||||
val1= args[0]->val_decimal(&value1);
|
||||
if ((null_value= args[0]->null_value))
|
||||
return 0;
|
||||
val2= args[1]->val_decimal(&value2);
|
||||
if ((null_value= args[1]->null_value))
|
||||
VDec2_lazy val(args[0], args[1]);
|
||||
if ((null_value= val.has_null()))
|
||||
return 0;
|
||||
switch (my_decimal_mod(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value,
|
||||
val1, val2)) {
|
||||
val.m_a.ptr(), val.m_b.ptr())) {
|
||||
case E_DEC_TRUNCATED:
|
||||
case E_DEC_OK:
|
||||
return decimal_value;
|
||||
|
|
@ -1894,10 +1786,10 @@ longlong Item_func_neg::int_op()
|
|||
|
||||
my_decimal *Item_func_neg::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
my_decimal val, *value= args[0]->val_decimal(&val);
|
||||
if (!(null_value= args[0]->null_value))
|
||||
VDec value(args[0]);
|
||||
if (!(null_value= value.is_null()))
|
||||
{
|
||||
my_decimal2decimal(value, decimal_value);
|
||||
my_decimal2decimal(value.ptr(), decimal_value);
|
||||
my_decimal_neg(decimal_value);
|
||||
return decimal_value;
|
||||
}
|
||||
|
|
@ -1992,10 +1884,10 @@ longlong Item_func_abs::int_op()
|
|||
|
||||
my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
my_decimal val, *value= args[0]->val_decimal(&val);
|
||||
if (!(null_value= args[0]->null_value))
|
||||
VDec value(args[0]);
|
||||
if (!(null_value= value.is_null()))
|
||||
{
|
||||
my_decimal2decimal(value, decimal_value);
|
||||
my_decimal2decimal(value.ptr(), decimal_value);
|
||||
if (decimal_value->sign())
|
||||
my_decimal_neg(decimal_value);
|
||||
return decimal_value;
|
||||
|
|
@ -2317,25 +2209,15 @@ bool Item_func_int_val::fix_length_and_dec()
|
|||
|
||||
longlong Item_func_ceiling::int_op()
|
||||
{
|
||||
longlong result;
|
||||
switch (args[0]->result_type()) {
|
||||
case INT_RESULT:
|
||||
result= args[0]->val_int();
|
||||
null_value= args[0]->null_value;
|
||||
break;
|
||||
return val_int_from_item(args[0]);
|
||||
case DECIMAL_RESULT:
|
||||
{
|
||||
my_decimal dec_buf, *dec;
|
||||
if ((dec= Item_func_ceiling::decimal_op(&dec_buf)))
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result);
|
||||
else
|
||||
result= 0;
|
||||
return VDec_op(this).to_longlong(unsigned_flag);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
result= (longlong)Item_func_ceiling::real_op();
|
||||
};
|
||||
return result;
|
||||
return (longlong) Item_func_ceiling::real_op();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2353,10 +2235,9 @@ double Item_func_ceiling::real_op()
|
|||
|
||||
my_decimal *Item_func_ceiling::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
my_decimal val, *value= args[0]->val_decimal(&val);
|
||||
if (!(null_value= (args[0]->null_value ||
|
||||
my_decimal_ceiling(E_DEC_FATAL_ERROR, value,
|
||||
decimal_value) > 1)))
|
||||
VDec value(args[0]);
|
||||
if (!(null_value= (value.is_null() ||
|
||||
value.round_to(decimal_value, 0, CEILING) > 1)))
|
||||
return decimal_value;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2364,25 +2245,19 @@ my_decimal *Item_func_ceiling::decimal_op(my_decimal *decimal_value)
|
|||
|
||||
longlong Item_func_floor::int_op()
|
||||
{
|
||||
longlong result;
|
||||
switch (args[0]->result_type()) {
|
||||
case INT_RESULT:
|
||||
result= args[0]->val_int();
|
||||
null_value= args[0]->null_value;
|
||||
break;
|
||||
return val_int_from_item(args[0]);
|
||||
case DECIMAL_RESULT:
|
||||
{
|
||||
my_decimal dec_buf, *dec;
|
||||
if ((dec= Item_func_floor::decimal_op(&dec_buf)))
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result);
|
||||
else
|
||||
result= 0;
|
||||
break;
|
||||
return (!(dec= Item_func_floor::decimal_op(&dec_buf))) ? 0 :
|
||||
dec->to_longlong(unsigned_flag);
|
||||
}
|
||||
default:
|
||||
result= (longlong)Item_func_floor::real_op();
|
||||
};
|
||||
return result;
|
||||
break;
|
||||
}
|
||||
return (longlong) Item_func_floor::real_op();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2400,10 +2275,9 @@ double Item_func_floor::real_op()
|
|||
|
||||
my_decimal *Item_func_floor::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
my_decimal val, *value= args[0]->val_decimal(&val);
|
||||
if (!(null_value= (args[0]->null_value ||
|
||||
my_decimal_floor(E_DEC_FATAL_ERROR, value,
|
||||
decimal_value) > 1)))
|
||||
VDec value(args[0]);
|
||||
if (!(null_value= (value.is_null() ||
|
||||
value.round_to(decimal_value, 0, FLOOR) > 1)))
|
||||
return decimal_value;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2592,16 +2466,16 @@ longlong Item_func_round::int_op()
|
|||
|
||||
my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
my_decimal val, *value= args[0]->val_decimal(&val);
|
||||
VDec value(args[0]);
|
||||
longlong dec= args[1]->val_int();
|
||||
if (dec >= 0 || args[1]->unsigned_flag)
|
||||
dec= MY_MIN((ulonglong) dec, decimals);
|
||||
else if (dec < INT_MIN)
|
||||
dec= INT_MIN;
|
||||
|
||||
if (!(null_value= (args[0]->null_value || args[1]->null_value ||
|
||||
my_decimal_round(E_DEC_FATAL_ERROR, value, (int) dec,
|
||||
truncate, decimal_value) > 1)))
|
||||
if (!(null_value= (value.is_null() || args[1]->null_value ||
|
||||
value.round_to(decimal_value, dec,
|
||||
truncate ? TRUNCATE : HALF_UP) > 1)))
|
||||
return decimal_value;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3021,14 +2895,14 @@ longlong Item_func_field::val_int()
|
|||
}
|
||||
else if (cmp_type == DECIMAL_RESULT)
|
||||
{
|
||||
my_decimal dec_arg_buf, *dec_arg,
|
||||
dec_buf, *dec= args[0]->val_decimal(&dec_buf);
|
||||
if (args[0]->null_value)
|
||||
VDec dec(args[0]);
|
||||
if (dec.is_null())
|
||||
return 0;
|
||||
my_decimal dec_arg_buf;
|
||||
for (uint i=1; i < arg_count; i++)
|
||||
{
|
||||
dec_arg= args[i]->val_decimal(&dec_arg_buf);
|
||||
if (!args[i]->null_value && !my_decimal_cmp(dec_arg, dec))
|
||||
my_decimal *dec_arg= args[i]->val_decimal(&dec_arg_buf);
|
||||
if (!args[i]->null_value && !dec.cmp(dec_arg))
|
||||
return (longlong) (i);
|
||||
}
|
||||
}
|
||||
|
|
@ -3610,32 +3484,6 @@ String *Item_func_udf_int::val_str(String *str)
|
|||
}
|
||||
|
||||
|
||||
longlong Item_func_udf_decimal::val_int()
|
||||
{
|
||||
my_bool tmp_null_value;
|
||||
longlong result;
|
||||
my_decimal dec_buf, *dec= udf.val_decimal(&tmp_null_value, &dec_buf);
|
||||
null_value= tmp_null_value;
|
||||
if (null_value)
|
||||
return 0;
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
double Item_func_udf_decimal::val_real()
|
||||
{
|
||||
my_bool tmp_null_value;
|
||||
double result;
|
||||
my_decimal dec_buf, *dec= udf.val_decimal(&tmp_null_value, &dec_buf);
|
||||
null_value= tmp_null_value;
|
||||
if (null_value)
|
||||
return 0.0;
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, dec, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
my_decimal *Item_func_udf_decimal::val_decimal(my_decimal *dec_buf)
|
||||
{
|
||||
my_decimal *res;
|
||||
|
|
@ -3651,21 +3499,6 @@ my_decimal *Item_func_udf_decimal::val_decimal(my_decimal *dec_buf)
|
|||
}
|
||||
|
||||
|
||||
String *Item_func_udf_decimal::val_str(String *str)
|
||||
{
|
||||
my_bool tmp_null_value;
|
||||
my_decimal dec_buf, *dec= udf.val_decimal(&tmp_null_value, &dec_buf);
|
||||
null_value= tmp_null_value;
|
||||
if (null_value)
|
||||
return 0;
|
||||
if (str->length() < DECIMAL_MAX_STR_LENGTH)
|
||||
str->length(DECIMAL_MAX_STR_LENGTH);
|
||||
my_decimal_round(E_DEC_FATAL_ERROR, dec, decimals, FALSE, &dec_buf);
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, &dec_buf, 0, 0, '0', str);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/* Default max_length is max argument length */
|
||||
|
||||
bool Item_func_udf_str::fix_length_and_dec()
|
||||
|
|
@ -4763,11 +4596,7 @@ double user_var_entry::val_real(bool *null_value)
|
|||
case INT_RESULT:
|
||||
return (double) *(longlong*) value;
|
||||
case DECIMAL_RESULT:
|
||||
{
|
||||
double result;
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, (my_decimal *)value, &result);
|
||||
return result;
|
||||
}
|
||||
return ((my_decimal *)value)->to_double();
|
||||
case STRING_RESULT:
|
||||
return my_atof(value); // This is null terminated
|
||||
case ROW_RESULT:
|
||||
|
|
@ -4792,11 +4621,7 @@ longlong user_var_entry::val_int(bool *null_value) const
|
|||
case INT_RESULT:
|
||||
return *(longlong*) value;
|
||||
case DECIMAL_RESULT:
|
||||
{
|
||||
longlong result;
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, &result);
|
||||
return result;
|
||||
}
|
||||
return ((my_decimal *)value)->to_longlong(false);
|
||||
case STRING_RESULT:
|
||||
{
|
||||
int error;
|
||||
|
|
|
|||
|
|
@ -679,12 +679,6 @@ class Item_func_hybrid_field_type: public Item_hybrid_func
|
|||
DBUG_ASSERT((res != NULL) ^ null_value);
|
||||
return res;
|
||||
}
|
||||
my_decimal *decimal_op_with_null_check(my_decimal *decimal_buffer)
|
||||
{
|
||||
my_decimal *res= decimal_op(decimal_buffer);
|
||||
DBUG_ASSERT((res != NULL) ^ null_value);
|
||||
return res;
|
||||
}
|
||||
bool make_zero_mysql_time(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
||||
{
|
||||
bzero(ltime, sizeof(*ltime));
|
||||
|
|
@ -697,10 +691,6 @@ public:
|
|||
{
|
||||
return str_op_with_null_check(&str_value);
|
||||
}
|
||||
my_decimal *val_decimal_from_decimal_op(my_decimal *dec)
|
||||
{
|
||||
return decimal_op_with_null_check(dec);
|
||||
}
|
||||
longlong val_int_from_int_op()
|
||||
{
|
||||
return int_op();
|
||||
|
|
@ -711,7 +701,6 @@ public:
|
|||
}
|
||||
|
||||
// Value methods that involve conversion
|
||||
String *val_str_from_decimal_op(String *str);
|
||||
String *val_str_from_real_op(String *str);
|
||||
String *val_str_from_int_op(String *str);
|
||||
String *val_str_from_date_op(String *str);
|
||||
|
|
@ -725,19 +714,16 @@ public:
|
|||
|
||||
longlong val_int_from_str_op();
|
||||
longlong val_int_from_real_op();
|
||||
longlong val_int_from_decimal_op();
|
||||
longlong val_int_from_date_op();
|
||||
longlong val_int_from_time_op();
|
||||
|
||||
double val_real_from_str_op();
|
||||
double val_real_from_decimal_op();
|
||||
double val_real_from_date_op();
|
||||
double val_real_from_time_op();
|
||||
double val_real_from_int_op();
|
||||
|
||||
bool get_date_from_str_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
bool get_date_from_real_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
bool get_date_from_decimal_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
bool get_date_from_int_op(MYSQL_TIME *ltime, ulonglong fuzzydate);
|
||||
|
||||
public:
|
||||
|
|
@ -1179,12 +1165,12 @@ public:
|
|||
fix_char_length(my_decimal_precision_to_length_no_truncation(len, dec,
|
||||
unsigned_flag));
|
||||
}
|
||||
String *val_str(String *str);
|
||||
double val_real();
|
||||
longlong val_int();
|
||||
String *val_str(String *str) { return VDec(this).to_string(str); }
|
||||
double val_real() { return VDec(this).to_double(); }
|
||||
longlong val_int() { return VDec(this).to_longlong(unsigned_flag); }
|
||||
my_decimal *val_decimal(my_decimal*);
|
||||
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
||||
{ return get_date_from_decimal(ltime, fuzzydate); }
|
||||
{ return VDec(this).to_datetime_with_warn(ltime, fuzzydate, this); }
|
||||
const Type_handler *type_handler() const { return &type_handler_newdecimal; }
|
||||
void fix_length_and_dec_generic() {}
|
||||
bool fix_length_and_dec()
|
||||
|
|
@ -2204,6 +2190,18 @@ protected:
|
|||
udf_handler udf;
|
||||
bool is_expensive_processor(void *arg) { return TRUE; }
|
||||
|
||||
class VDec_udf: public Dec_ptr_and_buffer
|
||||
{
|
||||
public:
|
||||
VDec_udf(Item_udf_func *func, udf_handler *udf)
|
||||
{
|
||||
my_bool tmp_null_value;
|
||||
m_ptr= udf->val_decimal(&tmp_null_value, &m_buffer);
|
||||
DBUG_ASSERT(is_null() == tmp_null_value);
|
||||
func->null_value= is_null();
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
Item_udf_func(THD *thd, udf_func *udf_arg):
|
||||
Item_func(thd), udf(udf_arg) {}
|
||||
|
|
@ -2343,10 +2341,19 @@ public:
|
|||
Item_udf_func(thd, udf_arg) {}
|
||||
Item_func_udf_decimal(THD *thd, udf_func *udf_arg, List<Item> &list):
|
||||
Item_udf_func(thd, udf_arg, list) {}
|
||||
longlong val_int();
|
||||
double val_real();
|
||||
longlong val_int()
|
||||
{
|
||||
return VDec_udf(this, &udf).to_longlong(unsigned_flag);
|
||||
}
|
||||
double val_real()
|
||||
{
|
||||
return VDec_udf(this, &udf).to_double();
|
||||
}
|
||||
my_decimal *val_decimal(my_decimal *);
|
||||
String *val_str(String *str);
|
||||
String *val_str(String *str)
|
||||
{
|
||||
return VDec_udf(this, &udf).to_string_round(str, decimals);
|
||||
}
|
||||
const Type_handler *type_handler() const { return &type_handler_newdecimal; }
|
||||
bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; }
|
||||
Item *get_copy(THD *thd)
|
||||
|
|
|
|||
|
|
@ -2655,12 +2655,10 @@ String *Item_func_format::val_str_ascii(String *str)
|
|||
if (args[0]->result_type() == DECIMAL_RESULT ||
|
||||
args[0]->result_type() == INT_RESULT)
|
||||
{
|
||||
my_decimal dec_val, rnd_dec, *res;
|
||||
res= args[0]->val_decimal(&dec_val);
|
||||
if ((null_value=args[0]->null_value))
|
||||
VDec res(args[0]);
|
||||
if ((null_value= res.is_null()))
|
||||
return 0; /* purecov: inspected */
|
||||
my_decimal_round(E_DEC_FATAL_ERROR, res, dec, false, &rnd_dec);
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, &rnd_dec, 0, 0, 0, str);
|
||||
res.to_string_round(str, dec);
|
||||
str_length= str->length();
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1640,12 +1640,7 @@ longlong Item_sum_sum::val_int()
|
|||
if (aggr)
|
||||
aggr->endup();
|
||||
if (result_type() == DECIMAL_RESULT)
|
||||
{
|
||||
longlong result;
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, unsigned_flag,
|
||||
&result);
|
||||
return result;
|
||||
}
|
||||
return dec_buffs[curr_dec_buff].to_longlong(unsigned_flag);
|
||||
return val_int_from_real();
|
||||
}
|
||||
|
||||
|
|
@ -1656,7 +1651,7 @@ double Item_sum_sum::val_real()
|
|||
if (aggr)
|
||||
aggr->endup();
|
||||
if (result_type() == DECIMAL_RESULT)
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, dec_buffs + curr_dec_buff, &sum);
|
||||
sum= dec_buffs[curr_dec_buff].to_double();
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
|
@ -1666,7 +1661,7 @@ String *Item_sum_sum::val_str(String *str)
|
|||
if (aggr)
|
||||
aggr->endup();
|
||||
if (result_type() == DECIMAL_RESULT)
|
||||
return val_string_from_decimal(str);
|
||||
return VDec(this).to_string_round(str, decimals);
|
||||
return val_string_from_real(str);
|
||||
}
|
||||
|
||||
|
|
@ -2032,7 +2027,7 @@ String *Item_sum_avg::val_str(String *str)
|
|||
if (aggr)
|
||||
aggr->endup();
|
||||
if (result_type() == DECIMAL_RESULT)
|
||||
return val_string_from_decimal(str);
|
||||
return VDec(this).to_string_round(str, decimals);
|
||||
return val_string_from_real(str);
|
||||
}
|
||||
|
||||
|
|
@ -2749,11 +2744,11 @@ void Item_sum_hybrid::reset_field()
|
|||
}
|
||||
case DECIMAL_RESULT:
|
||||
{
|
||||
my_decimal value_buff, *arg_dec= arg0->val_decimal(&value_buff);
|
||||
VDec arg_dec(arg0);
|
||||
|
||||
if (maybe_null)
|
||||
{
|
||||
if (arg0->null_value)
|
||||
if (arg_dec.is_null())
|
||||
result_field->set_null();
|
||||
else
|
||||
result_field->set_notnull();
|
||||
|
|
@ -2762,9 +2757,7 @@ void Item_sum_hybrid::reset_field()
|
|||
We must store zero in the field as we will use the field value in
|
||||
add()
|
||||
*/
|
||||
if (!arg_dec) // Null
|
||||
arg_dec= &decimal_zero;
|
||||
result_field->store_decimal(arg_dec);
|
||||
result_field->store_decimal(arg_dec.ptr_or(&decimal_zero));
|
||||
break;
|
||||
}
|
||||
case ROW_RESULT:
|
||||
|
|
@ -2787,15 +2780,10 @@ void Item_sum_sum::reset_field()
|
|||
DBUG_ASSERT (aggr->Aggrtype() != Aggregator::DISTINCT_AGGREGATOR);
|
||||
if (result_type() == DECIMAL_RESULT)
|
||||
{
|
||||
my_decimal value, *arg_val;
|
||||
if (unlikely(direct_added))
|
||||
arg_val= &direct_sum_decimal;
|
||||
result_field->store_decimal(&direct_sum_decimal);
|
||||
else
|
||||
{
|
||||
if (!(arg_val= args[0]->val_decimal(&value)))
|
||||
arg_val= &decimal_zero; // Null
|
||||
}
|
||||
result_field->store_decimal(arg_val);
|
||||
result_field->store_decimal(VDec(args[0]).ptr_or(&decimal_zero));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2848,15 +2836,9 @@ void Item_sum_avg::reset_field()
|
|||
if (result_type() == DECIMAL_RESULT)
|
||||
{
|
||||
longlong tmp;
|
||||
my_decimal value, *arg_dec= args[0]->val_decimal(&value);
|
||||
if (args[0]->null_value)
|
||||
{
|
||||
arg_dec= &decimal_zero;
|
||||
tmp= 0;
|
||||
}
|
||||
else
|
||||
tmp= 1;
|
||||
my_decimal2binary(E_DEC_FATAL_ERROR, arg_dec, res, f_precision, f_scale);
|
||||
VDec value(args[0]);
|
||||
tmp= value.is_null() ? 0 : 1;
|
||||
value.to_binary(res, f_precision, f_scale);
|
||||
res+= dec_bin_size;
|
||||
int8store(res, tmp);
|
||||
}
|
||||
|
|
@ -2923,9 +2905,8 @@ void Item_sum_sum::update_field()
|
|||
{
|
||||
if (!result_field->is_null())
|
||||
{
|
||||
my_decimal field_value;
|
||||
my_decimal *field_val= result_field->val_decimal(&field_value);
|
||||
my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, field_val);
|
||||
my_decimal field_value(result_field);
|
||||
my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, &field_value);
|
||||
result_field->store_decimal(dec_buffs);
|
||||
}
|
||||
else
|
||||
|
|
@ -2992,15 +2973,14 @@ void Item_sum_avg::update_field()
|
|||
|
||||
if (result_type() == DECIMAL_RESULT)
|
||||
{
|
||||
my_decimal value, *arg_val= args[0]->val_decimal(&value);
|
||||
if (!args[0]->null_value)
|
||||
VDec tmp(args[0]);
|
||||
if (!tmp.is_null())
|
||||
{
|
||||
binary2my_decimal(E_DEC_FATAL_ERROR, res,
|
||||
dec_buffs + 1, f_precision, f_scale);
|
||||
field_count= sint8korr(res + dec_bin_size);
|
||||
my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, arg_val, dec_buffs + 1);
|
||||
my_decimal2binary(E_DEC_FATAL_ERROR, dec_buffs,
|
||||
res, f_precision, f_scale);
|
||||
my_decimal_add(E_DEC_FATAL_ERROR, dec_buffs, tmp.ptr(), dec_buffs + 1);
|
||||
dec_buffs->to_binary(res, f_precision, f_scale);
|
||||
res+= dec_bin_size;
|
||||
field_count++;
|
||||
int8store(res, field_count);
|
||||
|
|
@ -3195,9 +3175,7 @@ my_decimal *Item_avg_field_decimal::val_decimal(my_decimal *dec_buf)
|
|||
if ((null_value= !count))
|
||||
return 0;
|
||||
|
||||
my_decimal dec_count, dec_field;
|
||||
binary2my_decimal(E_DEC_FATAL_ERROR,
|
||||
field->ptr, &dec_field, f_precision, f_scale);
|
||||
my_decimal dec_count, dec_field(field->ptr, f_precision, f_scale);
|
||||
int2my_decimal(E_DEC_FATAL_ERROR, count, 0, &dec_count);
|
||||
my_decimal_div(E_DEC_FATAL_ERROR, dec_buf,
|
||||
&dec_field, &dec_count, prec_increment);
|
||||
|
|
@ -3311,24 +3289,6 @@ my_decimal *Item_sum_udf_float::val_decimal(my_decimal *dec)
|
|||
}
|
||||
|
||||
|
||||
String *Item_sum_udf_decimal::val_str(String *str)
|
||||
{
|
||||
return val_string_from_decimal(str);
|
||||
}
|
||||
|
||||
|
||||
double Item_sum_udf_decimal::val_real()
|
||||
{
|
||||
return val_real_from_decimal();
|
||||
}
|
||||
|
||||
|
||||
longlong Item_sum_udf_decimal::val_int()
|
||||
{
|
||||
return val_int_from_decimal();
|
||||
}
|
||||
|
||||
|
||||
my_decimal *Item_sum_udf_decimal::val_decimal(my_decimal *dec_buf)
|
||||
{
|
||||
my_decimal *res;
|
||||
|
|
|
|||
|
|
@ -1450,9 +1450,18 @@ public:
|
|||
dec_bin_size(item->dec_bin_size)
|
||||
{ }
|
||||
const Type_handler *type_handler() const { return &type_handler_newdecimal; }
|
||||
double val_real() { return val_real_from_decimal(); }
|
||||
longlong val_int() { return val_int_from_decimal(); }
|
||||
String *val_str(String *str) { return val_string_from_decimal(str); }
|
||||
double val_real()
|
||||
{
|
||||
return VDec(this).to_double();
|
||||
}
|
||||
longlong val_int()
|
||||
{
|
||||
return VDec(this).to_longlong(unsigned_flag);
|
||||
}
|
||||
String *val_str(String *str)
|
||||
{
|
||||
return VDec(this).to_string_round(str, decimals);
|
||||
}
|
||||
my_decimal *val_decimal(my_decimal *);
|
||||
Item *get_copy(THD *thd)
|
||||
{ return get_item_copy<Item_avg_field_decimal>(thd, this); }
|
||||
|
|
@ -1656,9 +1665,18 @@ public:
|
|||
Item_udf_sum(thd, udf_arg, list) {}
|
||||
Item_sum_udf_decimal(THD *thd, Item_sum_udf_decimal *item)
|
||||
:Item_udf_sum(thd, item) {}
|
||||
String *val_str(String *);
|
||||
double val_real();
|
||||
longlong val_int();
|
||||
String *val_str(String *str)
|
||||
{
|
||||
return VDec(this).to_string_round(str, decimals);
|
||||
}
|
||||
double val_real()
|
||||
{
|
||||
return VDec(this).to_double();
|
||||
}
|
||||
longlong val_int()
|
||||
{
|
||||
return VDec(this).to_longlong(unsigned_flag);
|
||||
}
|
||||
my_decimal *val_decimal(my_decimal *);
|
||||
const Type_handler *type_handler() const { return &type_handler_newdecimal; }
|
||||
bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; }
|
||||
|
|
|
|||
|
|
@ -1334,16 +1334,16 @@ bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval)
|
|||
bzero((char*) interval,sizeof(*interval));
|
||||
if (int_type == INTERVAL_SECOND && args->decimals)
|
||||
{
|
||||
my_decimal decimal_value, *val;
|
||||
VDec val(args);
|
||||
ulonglong second;
|
||||
ulong second_part;
|
||||
if (!(val= args->val_decimal(&decimal_value)))
|
||||
if (val.is_null())
|
||||
return true;
|
||||
interval->neg= my_decimal2seconds(val, &second, &second_part);
|
||||
interval->neg= my_decimal2seconds(val.ptr(), &second, &second_part);
|
||||
if (second == LONGLONG_MAX)
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
ErrConvDecimal err(val);
|
||||
ErrConvDecimal err(val.ptr());
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_TRUNCATED_WRONG_VALUE,
|
||||
ER_THD(thd, ER_TRUNCATED_WRONG_VALUE), "DECIMAL",
|
||||
|
|
|
|||
|
|
@ -513,11 +513,11 @@ void Item_sum_hybrid_simple::reset_field()
|
|||
}
|
||||
case DECIMAL_RESULT:
|
||||
{
|
||||
my_decimal value_buff, *arg_dec= args[0]->val_decimal(&value_buff);
|
||||
VDec arg_dec(args[0]);
|
||||
|
||||
if (maybe_null)
|
||||
{
|
||||
if (args[0]->null_value)
|
||||
if (arg_dec.is_null())
|
||||
result_field->set_null();
|
||||
else
|
||||
result_field->set_notnull();
|
||||
|
|
@ -526,9 +526,7 @@ void Item_sum_hybrid_simple::reset_field()
|
|||
We must store zero in the field as we will use the field value in
|
||||
add()
|
||||
*/
|
||||
if (!arg_dec) // Null
|
||||
arg_dec= &decimal_zero;
|
||||
result_field->store_decimal(arg_dec);
|
||||
result_field->store_decimal(arg_dec.ptr_or(&decimal_zero));
|
||||
break;
|
||||
}
|
||||
case ROW_RESULT:
|
||||
|
|
|
|||
|
|
@ -2732,9 +2732,7 @@ log_event_print_value(IO_CACHE *file, PRINT_EVENT_INFO *print_event_info,
|
|||
goto return_null;
|
||||
|
||||
uint bin_size= my_decimal_get_binary_size(precision, decimals);
|
||||
my_decimal dec;
|
||||
binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) ptr, &dec,
|
||||
precision, decimals);
|
||||
my_decimal dec((const uchar *) ptr, precision, decimals);
|
||||
int length= DECIMAL_MAX_STR_LENGTH;
|
||||
char buff[DECIMAL_MAX_STR_LENGTH + 1];
|
||||
decimal2string(&dec, buff, &length, 0, 0, 0);
|
||||
|
|
@ -9038,11 +9036,8 @@ void User_var_log_event::pack_info(Protocol* protocol)
|
|||
String buf(buf_mem, sizeof(buf_mem), system_charset_info);
|
||||
char buf2[DECIMAL_MAX_STR_LENGTH+1];
|
||||
String str(buf2, sizeof(buf2), &my_charset_bin);
|
||||
my_decimal dec;
|
||||
buf.length(0);
|
||||
binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
|
||||
val[1]);
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
|
||||
my_decimal((const uchar *) (val + 2), val[0], val[1]).to_string(&str);
|
||||
if (user_var_append_name_part(protocol->thd, &buf, name, name_len) ||
|
||||
buf.append(buf2))
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#ifndef MYSQL_CLIENT
|
||||
#include "sql_class.h" // THD
|
||||
#include "field.h"
|
||||
#endif
|
||||
|
||||
#define DIG_BASE 1000000000
|
||||
|
|
@ -95,9 +96,8 @@ int decimal_operation_results(int result, const char *value, const char *type)
|
|||
@retval E_DEC_OOM
|
||||
*/
|
||||
|
||||
int my_decimal2string(uint mask, const my_decimal *d,
|
||||
uint fixed_prec, uint fixed_dec,
|
||||
char filler, String *str)
|
||||
int my_decimal::to_string_native(String *str, uint fixed_prec, uint fixed_dec,
|
||||
char filler, uint mask) const
|
||||
{
|
||||
/*
|
||||
Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a
|
||||
|
|
@ -113,11 +113,11 @@ int my_decimal2string(uint mask, const my_decimal *d,
|
|||
*/
|
||||
int length= (fixed_prec
|
||||
? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
|
||||
: my_decimal_string_length(d));
|
||||
: my_decimal_string_length(this));
|
||||
int result;
|
||||
if (str->alloc(length))
|
||||
return check_result(mask, E_DEC_OOM);
|
||||
result= decimal2string((decimal_t*) d, (char*) str->ptr(),
|
||||
result= decimal2string(this, (char*) str->ptr(),
|
||||
&length, (int)fixed_prec, fixed_dec,
|
||||
filler);
|
||||
str->length(length);
|
||||
|
|
@ -156,8 +156,8 @@ str_set_decimal(uint mask, const my_decimal *val,
|
|||
{
|
||||
if (!(cs->state & MY_CS_NONASCII))
|
||||
{
|
||||
/* For ASCII-compatible character sets we can use my_decimal2string */
|
||||
my_decimal2string(mask, val, fixed_prec, fixed_dec, filler, str);
|
||||
// For ASCII-compatible character sets we can use to_string_native()
|
||||
val->to_string_native(str, fixed_prec, fixed_dec, filler, mask);
|
||||
str->set_charset(cs);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -165,14 +165,13 @@ str_set_decimal(uint mask, const my_decimal *val,
|
|||
{
|
||||
/*
|
||||
For ASCII-incompatible character sets (like UCS2) we
|
||||
call my_decimal2string() on a temporary buffer first,
|
||||
call my_string_native() on a temporary buffer first,
|
||||
and then convert the result to the target character
|
||||
with help of str->copy().
|
||||
*/
|
||||
uint errors;
|
||||
char buf[DECIMAL_MAX_STR_LENGTH];
|
||||
String tmp(buf, sizeof(buf), &my_charset_latin1);
|
||||
my_decimal2string(mask, val, fixed_prec, fixed_dec, filler, &tmp);
|
||||
StringBuffer<DECIMAL_MAX_STR_LENGTH> tmp;
|
||||
val->to_string_native(&tmp, fixed_prec, fixed_dec, filler, mask);
|
||||
return str->copy(tmp.ptr(), tmp.length(), &my_charset_latin1, cs, &errors);
|
||||
}
|
||||
}
|
||||
|
|
@ -182,7 +181,7 @@ str_set_decimal(uint mask, const my_decimal *val,
|
|||
Convert from decimal to binary representation
|
||||
|
||||
SYNOPSIS
|
||||
my_decimal2binary()
|
||||
to_binary()
|
||||
mask error processing mask
|
||||
d number for conversion
|
||||
bin pointer to buffer where to write result
|
||||
|
|
@ -199,12 +198,11 @@ str_set_decimal(uint mask, const my_decimal *val,
|
|||
E_DEC_OVERFLOW
|
||||
*/
|
||||
|
||||
int my_decimal2binary(uint mask, const my_decimal *d, uchar *bin, int prec,
|
||||
int scale)
|
||||
int my_decimal::to_binary(uchar *bin, int prec, int scale, uint mask) const
|
||||
{
|
||||
int err1= E_DEC_OK, err2;
|
||||
my_decimal rounded;
|
||||
my_decimal2decimal(d, &rounded);
|
||||
my_decimal2decimal(this, &rounded);
|
||||
rounded.frac= decimal_actual_fraction(&rounded);
|
||||
if (scale < rounded.frac)
|
||||
{
|
||||
|
|
@ -368,6 +366,26 @@ int my_decimal2int(uint mask, const decimal_t *d, bool unsigned_flag,
|
|||
}
|
||||
|
||||
|
||||
longlong my_decimal::to_longlong(bool unsigned_flag) const
|
||||
{
|
||||
longlong result;
|
||||
my_decimal2int(E_DEC_FATAL_ERROR, this, unsigned_flag, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
my_decimal::my_decimal(Field *field)
|
||||
{
|
||||
init();
|
||||
DBUG_ASSERT(!field->is_null());
|
||||
#ifndef DBUG_OFF
|
||||
my_decimal *dec=
|
||||
#endif
|
||||
field->val_decimal(this);
|
||||
DBUG_ASSERT(dec == this);
|
||||
}
|
||||
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
/* routines for debugging print */
|
||||
|
||||
|
|
|
|||
134
sql/my_decimal.h
134
sql/my_decimal.h
|
|
@ -39,6 +39,7 @@ C_MODE_START
|
|||
C_MODE_END
|
||||
|
||||
class String;
|
||||
class Field;
|
||||
typedef struct st_mysql_time MYSQL_TIME;
|
||||
|
||||
/**
|
||||
|
|
@ -63,6 +64,25 @@ inline int my_decimal_int_part(uint precision, uint decimals)
|
|||
}
|
||||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
int decimal_operation_results(int result, const char *value, const char *type);
|
||||
#else
|
||||
inline int decimal_operation_results(int result, const char *value,
|
||||
const char *type)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
#endif /*MYSQL_CLIENT*/
|
||||
|
||||
|
||||
inline int check_result(uint mask, int result)
|
||||
{
|
||||
if (result & mask)
|
||||
decimal_operation_results(result, "", "DECIMAL");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
my_decimal class limits 'decimal_t' type to what we need in MySQL.
|
||||
|
||||
|
|
@ -125,6 +145,12 @@ public:
|
|||
{
|
||||
init();
|
||||
}
|
||||
my_decimal(const uchar *bin, int prec, int scale)
|
||||
{
|
||||
init();
|
||||
check_result(E_DEC_FATAL_ERROR, bin2decimal(bin, this, prec, scale));
|
||||
}
|
||||
my_decimal(Field *field);
|
||||
~my_decimal()
|
||||
{
|
||||
sanity_check();
|
||||
|
|
@ -141,7 +167,59 @@ public:
|
|||
bool sign() const { return decimal_t::sign; }
|
||||
void sign(bool s) { decimal_t::sign= s; }
|
||||
uint precision() const { return intg + frac; }
|
||||
void set_zero()
|
||||
{
|
||||
/*
|
||||
We need the up-cast here, since my_decimal has sign() member functions,
|
||||
which conflicts with decimal_t::sign
|
||||
(and decimal_make_zero is a macro, rather than a funcion).
|
||||
*/
|
||||
decimal_make_zero(static_cast<decimal_t*>(this));
|
||||
}
|
||||
int cmp(const my_decimal *other) const
|
||||
{
|
||||
return decimal_cmp(this, other);
|
||||
}
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool to_bool() const
|
||||
{
|
||||
return !decimal_is_zero(this);
|
||||
}
|
||||
double to_double() const
|
||||
{
|
||||
double res;
|
||||
decimal2double(this, &res);
|
||||
return res;
|
||||
}
|
||||
longlong to_longlong(bool unsigned_flag) const;
|
||||
// Convert to string returning decimal2string() error code
|
||||
int to_string_native(String *to, uint prec, uint dec, char filler,
|
||||
uint mask= E_DEC_FATAL_ERROR) const;
|
||||
// Convert to string returning the String pointer
|
||||
String *to_string(String *to, uint prec, uint dec, char filler) const
|
||||
{
|
||||
return to_string_native(to, prec, dec, filler) ? NULL : to;
|
||||
}
|
||||
String *to_string(String *to) const
|
||||
{
|
||||
return to_string(to, 0, 0, 0);
|
||||
}
|
||||
String *to_string_round(String *to, uint scale, my_decimal *round_buff) const
|
||||
{
|
||||
(void) round_to(round_buff, scale, HALF_UP); // QQ: check result?
|
||||
return round_buff->to_string(to);
|
||||
}
|
||||
int round_to(my_decimal *to, uint scale, decimal_round_mode mode,
|
||||
int mask= E_DEC_FATAL_ERROR) const
|
||||
{
|
||||
return check_result(mask, decimal_round(this, to, (int) scale, mode));
|
||||
}
|
||||
bool to_datetime_with_warn(MYSQL_TIME *to, ulonglong fuzzydate,
|
||||
const char *field_name);
|
||||
int to_binary(uchar *bin, int prec, int scale,
|
||||
uint mask= E_DEC_FATAL_ERROR) const;
|
||||
#endif
|
||||
/** Swap two my_decimal values */
|
||||
void swap(my_decimal &rhs)
|
||||
{
|
||||
|
|
@ -164,16 +242,6 @@ bool str_set_decimal(uint mask, const my_decimal *val, uint fixed_prec,
|
|||
|
||||
extern my_decimal decimal_zero;
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
int decimal_operation_results(int result, const char *value, const char *type);
|
||||
#else
|
||||
inline int decimal_operation_results(int result, const char *value,
|
||||
const char *type)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
#endif /*MYSQL_CLIENT*/
|
||||
|
||||
inline
|
||||
void max_my_decimal(my_decimal *to, int precision, int frac)
|
||||
{
|
||||
|
|
@ -187,13 +255,6 @@ inline void max_internal_decimal(my_decimal *to)
|
|||
max_my_decimal(to, DECIMAL_MAX_PRECISION, 0);
|
||||
}
|
||||
|
||||
inline int check_result(uint mask, int result)
|
||||
{
|
||||
if (result & mask)
|
||||
decimal_operation_results(result, "", "DECIMAL");
|
||||
return result;
|
||||
}
|
||||
|
||||
inline int check_result_and_overflow(uint mask, int result, my_decimal *val)
|
||||
{
|
||||
if (check_result(mask, result) & E_DEC_OVERFLOW)
|
||||
|
|
@ -271,10 +332,6 @@ void my_decimal2decimal(const my_decimal *from, my_decimal *to)
|
|||
}
|
||||
|
||||
|
||||
int my_decimal2binary(uint mask, const my_decimal *d, uchar *bin, int prec,
|
||||
int scale);
|
||||
|
||||
|
||||
inline
|
||||
int binary2my_decimal(uint mask, const uchar *bin, my_decimal *d, int prec,
|
||||
int scale)
|
||||
|
|
@ -286,12 +343,7 @@ int binary2my_decimal(uint mask, const uchar *bin, my_decimal *d, int prec,
|
|||
inline
|
||||
int my_decimal_set_zero(my_decimal *d)
|
||||
{
|
||||
/*
|
||||
We need the up-cast here, since my_decimal has sign() member functions,
|
||||
which conflicts with decimal_t::sign
|
||||
(and decimal_make_zero is a macro, rather than a funcion).
|
||||
*/
|
||||
decimal_make_zero(static_cast<decimal_t*>(d));
|
||||
d->set_zero();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -303,40 +355,12 @@ bool my_decimal_is_zero(const my_decimal *decimal_value)
|
|||
}
|
||||
|
||||
|
||||
inline
|
||||
int my_decimal_round(uint mask, const my_decimal *from, int scale,
|
||||
bool truncate, my_decimal *to)
|
||||
{
|
||||
return check_result(mask, decimal_round(from, to, scale,
|
||||
(truncate ? TRUNCATE : HALF_UP)));
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
int my_decimal_floor(uint mask, const my_decimal *from, my_decimal *to)
|
||||
{
|
||||
return check_result(mask, decimal_round(from, to, 0, FLOOR));
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
int my_decimal_ceiling(uint mask, const my_decimal *from, my_decimal *to)
|
||||
{
|
||||
return check_result(mask, decimal_round(from, to, 0, CEILING));
|
||||
}
|
||||
|
||||
|
||||
inline bool str_set_decimal(const my_decimal *val, String *str,
|
||||
CHARSET_INFO *cs)
|
||||
{
|
||||
return str_set_decimal(E_DEC_FATAL_ERROR, val, 0, 0, 0, str, cs);
|
||||
}
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
class String;
|
||||
int my_decimal2string(uint mask, const my_decimal *d, uint fixed_prec,
|
||||
uint fixed_dec, char filler, String *str);
|
||||
#endif
|
||||
|
||||
bool my_decimal2seconds(const my_decimal *d, ulonglong *sec, ulong *microsec);
|
||||
|
||||
|
|
|
|||
|
|
@ -1195,9 +1195,8 @@ bool Protocol_text::store_decimal(const my_decimal *d)
|
|||
field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[DECIMAL_MAX_STR_LENGTH];
|
||||
String str(buff, sizeof(buff), &my_charset_bin);
|
||||
(void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
|
||||
StringBuffer<DECIMAL_MAX_STR_LENGTH> str;
|
||||
(void) d->to_string(&str);
|
||||
return net_store_data((uchar*) str.ptr(), str.length());
|
||||
}
|
||||
|
||||
|
|
@ -1446,9 +1445,8 @@ bool Protocol_binary::store_decimal(const my_decimal *d)
|
|||
field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
|
||||
field_pos++;
|
||||
#endif
|
||||
char buff[DECIMAL_MAX_STR_LENGTH];
|
||||
String str(buff, sizeof(buff), &my_charset_bin);
|
||||
(void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
|
||||
StringBuffer<DECIMAL_MAX_STR_LENGTH> str;
|
||||
(void) d->to_string(&str);
|
||||
return store(str.ptr(), str.length(), str.charset());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -478,30 +478,28 @@ void field_real::add()
|
|||
void field_decimal::add()
|
||||
{
|
||||
/*TODO - remove rounding stuff after decimal_div returns proper frac */
|
||||
my_decimal dec_buf, *dec= item->val_decimal(&dec_buf);
|
||||
my_decimal rounded;
|
||||
VDec vdec(item);
|
||||
uint length;
|
||||
TREE_ELEMENT *element;
|
||||
|
||||
if (item->null_value)
|
||||
if (vdec.is_null())
|
||||
{
|
||||
nulls++;
|
||||
return;
|
||||
}
|
||||
|
||||
my_decimal_round(E_DEC_FATAL_ERROR, dec, item->decimals, FALSE,&rounded);
|
||||
dec= &rounded;
|
||||
my_decimal dec;
|
||||
vdec.round_to(&dec, item->decimals, HALF_UP);
|
||||
|
||||
length= my_decimal_string_length(dec);
|
||||
length= my_decimal_string_length(&dec);
|
||||
|
||||
if (decimal_is_zero(dec))
|
||||
if (decimal_is_zero(&dec))
|
||||
empty++;
|
||||
|
||||
if (room_in_tree)
|
||||
{
|
||||
uchar buf[DECIMAL_MAX_FIELD_SIZE];
|
||||
my_decimal2binary(E_DEC_FATAL_ERROR, dec, buf,
|
||||
item->max_length, item->decimals);
|
||||
dec.to_binary(buf, item->max_length, item->decimals);
|
||||
if (!(element = tree_insert(&tree, (void*)buf, 0, tree.custom_arg)))
|
||||
{
|
||||
room_in_tree = 0; // Remove tree, out of RAM ?
|
||||
|
|
@ -521,18 +519,18 @@ void field_decimal::add()
|
|||
if (!found)
|
||||
{
|
||||
found = 1;
|
||||
min_arg = max_arg = sum[0] = *dec;
|
||||
my_decimal_mul(E_DEC_FATAL_ERROR, sum_sqr, dec, dec);
|
||||
min_arg = max_arg = sum[0] = dec;
|
||||
my_decimal_mul(E_DEC_FATAL_ERROR, sum_sqr, &dec, &dec);
|
||||
cur_sum= 0;
|
||||
min_length = max_length = length;
|
||||
}
|
||||
else if (!decimal_is_zero(dec))
|
||||
else if (!decimal_is_zero(&dec))
|
||||
{
|
||||
int next_cur_sum= cur_sum ^ 1;
|
||||
my_decimal sqr_buf;
|
||||
|
||||
my_decimal_add(E_DEC_FATAL_ERROR, sum+next_cur_sum, sum+cur_sum, dec);
|
||||
my_decimal_mul(E_DEC_FATAL_ERROR, &sqr_buf, dec, dec);
|
||||
my_decimal_add(E_DEC_FATAL_ERROR, sum+next_cur_sum, sum+cur_sum, &dec);
|
||||
my_decimal_mul(E_DEC_FATAL_ERROR, &sqr_buf, &dec, &dec);
|
||||
my_decimal_add(E_DEC_FATAL_ERROR,
|
||||
sum_sqr+next_cur_sum, sum_sqr+cur_sum, &sqr_buf);
|
||||
cur_sum= next_cur_sum;
|
||||
|
|
@ -540,13 +538,13 @@ void field_decimal::add()
|
|||
min_length = length;
|
||||
if (length > max_length)
|
||||
max_length = length;
|
||||
if (my_decimal_cmp(dec, &min_arg) < 0)
|
||||
if (dec.cmp(&min_arg) < 0)
|
||||
{
|
||||
min_arg= *dec;
|
||||
min_arg= dec;
|
||||
}
|
||||
if (my_decimal_cmp(dec, &max_arg) > 0)
|
||||
if (dec.cmp(&max_arg) > 0)
|
||||
{
|
||||
max_arg= *dec;
|
||||
max_arg= dec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1000,7 +998,7 @@ void field_decimal::get_opt_type(String *answer,
|
|||
uint length;
|
||||
|
||||
my_decimal_set_zero(&zero);
|
||||
my_bool is_unsigned= (my_decimal_cmp(&zero, &min_arg) >= 0);
|
||||
my_bool is_unsigned= (zero.cmp(&min_arg) >= 0);
|
||||
|
||||
length= sprintf(buff, "DECIMAL(%d, %d)",
|
||||
(int) (max_length - (item->decimals ? 1 : 0)),
|
||||
|
|
@ -1013,14 +1011,14 @@ void field_decimal::get_opt_type(String *answer,
|
|||
|
||||
String *field_decimal::get_min_arg(String *str)
|
||||
{
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, &min_arg, 0, 0, '0', str);
|
||||
min_arg.to_string_native(str, 0, 0, '0');
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
String *field_decimal::get_max_arg(String *str)
|
||||
{
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, &max_arg, 0, 0, '0', str);
|
||||
max_arg.to_string_native(str, 0, 0, '0');
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
@ -1038,10 +1036,10 @@ String *field_decimal::avg(String *s, ha_rows rows)
|
|||
int2my_decimal(E_DEC_FATAL_ERROR, rows - nulls, FALSE, &num);
|
||||
my_decimal_div(E_DEC_FATAL_ERROR, &avg_val, sum+cur_sum, &num, prec_increment);
|
||||
/* TODO remove this after decimal_div returns proper frac */
|
||||
my_decimal_round(E_DEC_FATAL_ERROR, &avg_val,
|
||||
avg_val.round_to(&rounded_avg,
|
||||
MY_MIN(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
|
||||
FALSE,&rounded_avg);
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, &rounded_avg, 0, 0, '0', s);
|
||||
HALF_UP);
|
||||
rounded_avg.to_string_native(s, 0, 0, '0');
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
@ -1054,7 +1052,6 @@ String *field_decimal::std(String *s, ha_rows rows)
|
|||
return s;
|
||||
}
|
||||
my_decimal num, tmp, sum2, sum2d;
|
||||
double std_sqr;
|
||||
int prec_increment= current_thd->variables.div_precincrement;
|
||||
|
||||
int2my_decimal(E_DEC_FATAL_ERROR, rows - nulls, FALSE, &num);
|
||||
|
|
@ -1062,7 +1059,7 @@ String *field_decimal::std(String *s, ha_rows rows)
|
|||
my_decimal_div(E_DEC_FATAL_ERROR, &tmp, &sum2, &num, prec_increment);
|
||||
my_decimal_sub(E_DEC_FATAL_ERROR, &sum2, sum_sqr+cur_sum, &tmp);
|
||||
my_decimal_div(E_DEC_FATAL_ERROR, &tmp, &sum2, &num, prec_increment);
|
||||
my_decimal2double(E_DEC_FATAL_ERROR, &tmp, &std_sqr);
|
||||
double std_sqr= tmp.to_double();
|
||||
s->set_real(((double) std_sqr <= 0.0 ? 0.0 : sqrt(std_sqr)),
|
||||
MY_MIN(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
|
||||
|
||||
|
|
@ -1114,12 +1111,9 @@ int collect_decimal(uchar *element, element_count count,
|
|||
info->str->append(',');
|
||||
else
|
||||
info->found = 1;
|
||||
my_decimal dec;
|
||||
binary2my_decimal(E_DEC_FATAL_ERROR, element, &dec,
|
||||
info->item->max_length, info->item->decimals);
|
||||
|
||||
my_decimal dec(element, info->item->max_length, info->item->decimals);
|
||||
info->str->append('\'');
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, '0', &s);
|
||||
dec.to_string_native(&s, 0, 0, '0');
|
||||
info->str->append(s);
|
||||
info->str->append('\'');
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -3587,18 +3587,15 @@ bool select_max_min_finder_subselect::cmp_int()
|
|||
bool select_max_min_finder_subselect::cmp_decimal()
|
||||
{
|
||||
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
|
||||
my_decimal cval, *cvalue= cache->val_decimal(&cval);
|
||||
my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
|
||||
VDec cvalue(cache), mvalue(maxmin);
|
||||
|
||||
/* Ignore NULLs for ANY and keep them for ALL subqueries */
|
||||
if (cache->null_value)
|
||||
return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value);
|
||||
if (maxmin->null_value)
|
||||
if (cvalue.is_null())
|
||||
return (is_all && !mvalue.is_null()) || (!is_all && mvalue.is_null());
|
||||
if (mvalue.is_null())
|
||||
return !is_all;
|
||||
|
||||
if (fmax)
|
||||
return (my_decimal_cmp(cvalue, mvalue) > 0) ;
|
||||
return (my_decimal_cmp(cvalue,mvalue) < 0);
|
||||
return fmax ? cvalue.cmp(mvalue) > 0 : cvalue.cmp(mvalue) < 0;
|
||||
}
|
||||
|
||||
bool select_max_min_finder_subselect::cmp_str()
|
||||
|
|
|
|||
|
|
@ -5298,16 +5298,8 @@ bool Protocol_local::store_longlong(longlong value, bool unsigned_flag)
|
|||
|
||||
bool Protocol_local::store_decimal(const my_decimal *value)
|
||||
{
|
||||
char buf[DECIMAL_MAX_STR_LENGTH];
|
||||
String str(buf, sizeof (buf), &my_charset_bin);
|
||||
int rc;
|
||||
|
||||
rc= my_decimal2string(E_DEC_FATAL_ERROR, value, 0, 0, 0, &str);
|
||||
|
||||
if (rc)
|
||||
return TRUE;
|
||||
|
||||
return store_column(str.ptr(), str.length());
|
||||
StringBuffer<DECIMAL_MAX_STR_LENGTH> str;
|
||||
return value->to_string(&str) ? store_column(str.ptr(), str.length()) : true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1511,3 +1511,10 @@ void unpack_time(longlong packed, MYSQL_TIME *my_time,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool my_decimal::to_datetime_with_warn(MYSQL_TIME *to, ulonglong fuzzydate,
|
||||
const char *field_name)
|
||||
{
|
||||
return decimal_to_datetime_with_warn(this, to, fuzzydate, field_name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,6 +130,37 @@ bool Type_handler_data::init()
|
|||
Type_handler_data *type_handler_data= NULL;
|
||||
|
||||
|
||||
|
||||
void VDec::set(Item *item)
|
||||
{
|
||||
m_ptr= item->val_decimal(&m_buffer);
|
||||
DBUG_ASSERT((m_ptr == NULL) == item->null_value);
|
||||
}
|
||||
|
||||
|
||||
VDec::VDec(Item *item)
|
||||
{
|
||||
m_ptr= item->val_decimal(&m_buffer);
|
||||
DBUG_ASSERT((m_ptr == NULL) == item->null_value);
|
||||
}
|
||||
|
||||
|
||||
VDec_op::VDec_op(Item_func_hybrid_field_type *item)
|
||||
{
|
||||
m_ptr= item->decimal_op(&m_buffer);
|
||||
DBUG_ASSERT((m_ptr == NULL) == item->null_value);
|
||||
}
|
||||
|
||||
|
||||
bool Dec_ptr::to_datetime_with_warn(MYSQL_TIME *to, ulonglong fuzzydate,
|
||||
Item *item)
|
||||
{
|
||||
if (to_datetime_with_warn(to, fuzzydate, item->field_name_or_null()))
|
||||
return item->null_value|= item->make_zero_date(to, fuzzydate);
|
||||
return item->null_value= false;
|
||||
}
|
||||
|
||||
|
||||
my_decimal *Temporal::to_decimal(my_decimal *to) const
|
||||
{
|
||||
return date2my_decimal(this, to);
|
||||
|
|
@ -3419,15 +3450,6 @@ bool Type_handler_int_result::Item_val_bool(Item *item) const
|
|||
return item->val_int() != 0;
|
||||
}
|
||||
|
||||
bool Type_handler_decimal_result::Item_val_bool(Item *item) const
|
||||
{
|
||||
my_decimal decimal_value;
|
||||
my_decimal *val= item->val_decimal(&decimal_value);
|
||||
if (val)
|
||||
return !my_decimal_is_zero(val);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Type_handler_temporal_result::Item_val_bool(Item *item) const
|
||||
{
|
||||
return item->val_real() != 0.0;
|
||||
|
|
@ -3462,13 +3484,6 @@ bool Type_handler_real_result::Item_get_date(Item *item, MYSQL_TIME *ltime,
|
|||
}
|
||||
|
||||
|
||||
bool Type_handler_decimal_result::Item_get_date(Item *item, MYSQL_TIME *ltime,
|
||||
ulonglong fuzzydate) const
|
||||
{
|
||||
return item->get_date_from_decimal(ltime, fuzzydate);
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_string_result::Item_get_date(Item *item, MYSQL_TIME *ltime,
|
||||
ulonglong fuzzydate) const
|
||||
{
|
||||
|
|
@ -3532,12 +3547,6 @@ longlong Type_handler_int_result::
|
|||
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
|
||||
{
|
||||
|
|
@ -3598,7 +3607,7 @@ Type_handler_decimal_result::Item_func_hybrid_field_type_val_str(
|
|||
Item_func_hybrid_field_type *item,
|
||||
String *str) const
|
||||
{
|
||||
return item->val_str_from_decimal_op(str);
|
||||
return VDec_op(item).to_string_round(str, item->decimals);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3607,7 +3616,7 @@ Type_handler_decimal_result::Item_func_hybrid_field_type_val_real(
|
|||
Item_func_hybrid_field_type *item)
|
||||
const
|
||||
{
|
||||
return item->val_real_from_decimal_op();
|
||||
return VDec_op(item).to_double();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3616,7 +3625,7 @@ Type_handler_decimal_result::Item_func_hybrid_field_type_val_int(
|
|||
Item_func_hybrid_field_type *item)
|
||||
const
|
||||
{
|
||||
return item->val_int_from_decimal_op();
|
||||
return VDec_op(item).to_longlong(item->unsigned_flag);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3625,7 +3634,7 @@ Type_handler_decimal_result::Item_func_hybrid_field_type_val_decimal(
|
|||
Item_func_hybrid_field_type *item,
|
||||
my_decimal *dec) const
|
||||
{
|
||||
return item->val_decimal_from_decimal_op(dec);
|
||||
return VDec_op(item).to_decimal(dec);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3635,7 +3644,7 @@ Type_handler_decimal_result::Item_func_hybrid_field_type_get_date(
|
|||
MYSQL_TIME *ltime,
|
||||
ulonglong fuzzydate) const
|
||||
{
|
||||
return item->get_date_from_decimal_op(ltime, fuzzydate);
|
||||
return VDec_op(item).to_datetime_with_warn(ltime, fuzzydate, item);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -4182,7 +4191,7 @@ String *Type_handler_int_result::
|
|||
String *Type_handler_decimal_result::
|
||||
Item_func_min_max_val_str(Item_func_min_max *func, String *str) const
|
||||
{
|
||||
return func->val_string_from_decimal(str);
|
||||
return VDec(func).to_string_round(str, func->decimals);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -5628,11 +5637,10 @@ Item *Type_handler_real_result::
|
|||
Item *Type_handler_decimal_result::
|
||||
make_const_item_for_comparison(THD *thd, Item *item, const Item *cmp) const
|
||||
{
|
||||
my_decimal decimal_value;
|
||||
my_decimal *result= item->val_decimal(&decimal_value);
|
||||
if (item->null_value)
|
||||
VDec result(item);
|
||||
if (result.is_null())
|
||||
return new (thd->mem_root) Item_null(thd, item->name.str);
|
||||
return new (thd->mem_root) Item_decimal(thd, item->name.str, result,
|
||||
return new (thd->mem_root) Item_decimal(thd, item->name.str, result.ptr(),
|
||||
item->max_length, item->decimals);
|
||||
}
|
||||
|
||||
|
|
@ -6617,7 +6625,7 @@ Type_handler_decimal_result::Item_const_eq(const Item_const *a,
|
|||
{
|
||||
const my_decimal *da= a->const_ptr_my_decimal();
|
||||
const my_decimal *db= b->const_ptr_my_decimal();
|
||||
return !my_decimal_cmp(da, db) &&
|
||||
return !da->cmp(db) &&
|
||||
(!binary_cmp ||
|
||||
a->get_type_all_attributes_from_const()->decimals ==
|
||||
b->get_type_all_attributes_from_const()->decimals);
|
||||
|
|
@ -6716,18 +6724,6 @@ bool Type_handler_string_result::Item_eq_value(THD *thd,
|
|||
}
|
||||
|
||||
|
||||
bool Type_handler_decimal_result::Item_eq_value(THD *thd,
|
||||
const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const
|
||||
{
|
||||
my_decimal *va, *vb;
|
||||
my_decimal cmp_value1, cmp_value2;
|
||||
return (va= a->val_decimal(&cmp_value1)) &&
|
||||
(vb= b->val_decimal(&cmp_value2)) &&
|
||||
!my_decimal_cmp(va, vb);
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void Type_handler_var_string::
|
||||
|
|
@ -6823,19 +6819,6 @@ int Type_handler_int_result::stored_field_cmp_to_item(THD *thd,
|
|||
}
|
||||
|
||||
|
||||
int Type_handler_decimal_result::stored_field_cmp_to_item(THD *thd,
|
||||
Field *field,
|
||||
Item *item) const
|
||||
{
|
||||
my_decimal item_buf, *item_val, field_buf, *field_val;
|
||||
item_val= item->val_decimal(&item_buf);
|
||||
if (item->null_value)
|
||||
return 0;
|
||||
field_val= field->val_decimal(&field_buf);
|
||||
return my_decimal_cmp(field_val, item_val);
|
||||
}
|
||||
|
||||
|
||||
int Type_handler_real_result::stored_field_cmp_to_item(THD *thd,
|
||||
Field *field,
|
||||
Item *item) const
|
||||
|
|
|
|||
147
sql/sql_type.h
147
sql/sql_type.h
|
|
@ -90,6 +90,126 @@ enum scalar_comparison_op
|
|||
};
|
||||
|
||||
|
||||
class Dec_ptr
|
||||
{
|
||||
protected:
|
||||
my_decimal *m_ptr;
|
||||
Dec_ptr() { }
|
||||
public:
|
||||
bool is_null() const { return m_ptr == NULL; }
|
||||
const my_decimal *ptr() const { return m_ptr; }
|
||||
const my_decimal *ptr_or(const my_decimal *def) const
|
||||
{
|
||||
return m_ptr ? m_ptr : def;
|
||||
}
|
||||
my_decimal *to_decimal(my_decimal *to) const
|
||||
{
|
||||
if (!m_ptr)
|
||||
return NULL;
|
||||
*to= *m_ptr;
|
||||
return to;
|
||||
}
|
||||
double to_double() const { return m_ptr ? m_ptr->to_double() : 0.0; }
|
||||
longlong to_longlong(bool unsigned_flag)
|
||||
{ return m_ptr ? m_ptr->to_longlong(unsigned_flag) : 0; }
|
||||
bool to_bool() const { return m_ptr ? m_ptr->to_bool() : false; }
|
||||
bool to_datetime_with_warn(MYSQL_TIME *to, ulonglong fuzzydate,
|
||||
const char *field_name)
|
||||
{
|
||||
return m_ptr ? m_ptr->to_datetime_with_warn(to, fuzzydate, field_name) :
|
||||
true;
|
||||
}
|
||||
bool to_datetime_with_warn(MYSQL_TIME *to, ulonglong fuzzydate, Item *item);
|
||||
String *to_string(String *to) const
|
||||
{
|
||||
return m_ptr ? m_ptr->to_string(to) : NULL;
|
||||
}
|
||||
String *to_string(String *to, uint prec, uint dec, char filler)
|
||||
{
|
||||
return m_ptr ? m_ptr->to_string(to, prec, dec, filler) : NULL;
|
||||
}
|
||||
int to_binary(uchar *bin, int prec, int scale) const
|
||||
{
|
||||
return (m_ptr ? m_ptr : &decimal_zero)->to_binary(bin, prec, scale);
|
||||
}
|
||||
int cmp(const my_decimal *dec) const
|
||||
{
|
||||
DBUG_ASSERT(m_ptr);
|
||||
DBUG_ASSERT(dec);
|
||||
return m_ptr->cmp(dec);
|
||||
}
|
||||
int cmp(const Dec_ptr &other) const
|
||||
{
|
||||
return cmp(other.m_ptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// A helper class to handle results of val_decimal(), date_op(), etc.
|
||||
class Dec_ptr_and_buffer: public Dec_ptr
|
||||
{
|
||||
protected:
|
||||
my_decimal m_buffer;
|
||||
public:
|
||||
int round_to(my_decimal *to, uint scale, decimal_round_mode mode)
|
||||
{
|
||||
DBUG_ASSERT(m_ptr);
|
||||
return m_ptr->round_to(to, scale, mode);
|
||||
}
|
||||
int round_self(uint scale, decimal_round_mode mode)
|
||||
{
|
||||
return round_to(&m_buffer, scale, mode);
|
||||
}
|
||||
String *to_string_round(String *to, uint dec)
|
||||
{
|
||||
/*
|
||||
decimal_round() allows from==to
|
||||
So it's save even if m_ptr points to m_buffer before this call:
|
||||
*/
|
||||
return m_ptr ? m_ptr->to_string_round(to, dec, &m_buffer) : NULL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// A helper class to handle val_decimal() results.
|
||||
class VDec: public Dec_ptr_and_buffer
|
||||
{
|
||||
public:
|
||||
VDec(): Dec_ptr_and_buffer() { }
|
||||
VDec(Item *item);
|
||||
void set(Item *a);
|
||||
};
|
||||
|
||||
|
||||
// A helper class to handler decimal_op() results.
|
||||
class VDec_op: public Dec_ptr_and_buffer
|
||||
{
|
||||
public:
|
||||
VDec_op(Item_func_hybrid_field_type *item);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Get and cache val_decimal() values for two items.
|
||||
If the first value appears to be NULL, the second value is not evaluated.
|
||||
*/
|
||||
class VDec2_lazy
|
||||
{
|
||||
public:
|
||||
VDec m_a;
|
||||
VDec m_b;
|
||||
VDec2_lazy(Item *a, Item *b) :m_a(a)
|
||||
{
|
||||
if (!m_a.is_null())
|
||||
m_b.set(b);
|
||||
}
|
||||
bool has_null() const
|
||||
{
|
||||
return m_a.is_null() || m_b.is_null();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
A heler class to perform additive operations between
|
||||
two MYSQL_TIME structures and return the result as a
|
||||
|
|
@ -2289,7 +2409,11 @@ public:
|
|||
Item_result cmp_type() const { return DECIMAL_RESULT; }
|
||||
virtual ~Type_handler_decimal_result() {};
|
||||
const Type_handler *type_handler_for_comparison() const;
|
||||
int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) const;
|
||||
int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) const
|
||||
{
|
||||
VDec item_val(item);
|
||||
return item_val.is_null() ? 0 : my_decimal(field).cmp(item_val.ptr());
|
||||
}
|
||||
bool subquery_type_allows_materialization(const Item *inner,
|
||||
const Item *outer) const;
|
||||
Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const;
|
||||
|
|
@ -2304,7 +2428,11 @@ public:
|
|||
bool Item_const_eq(const Item_const *a, const Item_const *b,
|
||||
bool binary_cmp) const;
|
||||
bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const;
|
||||
Item *a, Item *b) const
|
||||
{
|
||||
VDec va(a), vb(b);
|
||||
return va.ptr() && vb.ptr() && !va.cmp(vb);
|
||||
}
|
||||
uint Item_decimal_precision(const Item *item) const;
|
||||
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||
void Item_param_set_param_func(Item_param *param,
|
||||
|
|
@ -2331,10 +2459,19 @@ 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;
|
||||
bool Item_val_bool(Item *item) const;
|
||||
bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
|
||||
bool Item_val_bool(Item *item) const
|
||||
{
|
||||
return VDec(item).to_bool();
|
||||
}
|
||||
bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const
|
||||
{
|
||||
return VDec(item).to_datetime_with_warn(ltime, fuzzydate, item);
|
||||
}
|
||||
longlong Item_val_int_signed_typecast(Item *item) const;
|
||||
longlong Item_val_int_unsigned_typecast(Item *item) const;
|
||||
longlong Item_val_int_unsigned_typecast(Item *item) const
|
||||
{
|
||||
return VDec(item).to_longlong(true);
|
||||
}
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -2745,14 +2745,10 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
|
|||
*((int*)pp->Value)= (int) Temporal_hybrid(pval).to_longlong();
|
||||
break;
|
||||
case REAL_RESULT:
|
||||
pp->Type= TYPE_DOUBLE;
|
||||
pp->Value= PlugSubAlloc(g, NULL, sizeof(double));
|
||||
*((double*)pp->Value)= pval->val_real();
|
||||
break;
|
||||
case DECIMAL_RESULT:
|
||||
pp->Type= TYPE_DOUBLE;
|
||||
pp->Value= PlugSubAlloc(g, NULL, sizeof(double));
|
||||
*((double*)pp->Value)= pval->val_real_from_decimal();
|
||||
*((double*)pp->Value)= pval->val_real();
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
DBUG_ASSERT(0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue