Commit a4a48a37 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-12199 Split Item_func_{abs|neg|int_val}::fix_length_and_dec() into methods in Type_handler

parent ec8c38a8
......@@ -3720,5 +3720,34 @@ DROP TABLE t1;
SELECT ROUND(POINT(1,1));
ERROR HY000: Illegal parameter data type geometry for operation 'round'
#
# MDEV-12199 Split Item_func_{abs|neg|int_val}::fix_length_and_dec() into methods in Type_handler
#
CREATE TABLE t1 (a GEOMETRY);
SELECT -a FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation '-'
SELECT ABS(a) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'abs'
SELECT CEILING(a) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'ceiling'
SELECT FLOOR(a) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'floor'
SELECT -COALESCE(a) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation '-'
SELECT ABS(COALESCE(a)) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'abs'
SELECT CEILING(COALESCE(a)) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'ceiling'
SELECT FLOOR(COALESCE(a)) FROM t1;
ERROR HY000: Illegal parameter data type geometry for operation 'floor'
DROP TABLE t1;
SELECT -POINT(1,1);
ERROR HY000: Illegal parameter data type geometry for operation '-'
SELECT ABS(POINT(1,1));
ERROR HY000: Illegal parameter data type geometry for operation 'abs'
SELECT CEILING(POINT(1,1));
ERROR HY000: Illegal parameter data type geometry for operation 'ceiling'
SELECT FLOOR(POINT(1,1));
ERROR HY000: Illegal parameter data type geometry for operation 'floor'
#
# End of 10.3 tests
#
......@@ -1880,6 +1880,41 @@ DROP TABLE t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT ROUND(POINT(1,1));
--echo #
--echo # MDEV-12199 Split Item_func_{abs|neg|int_val}::fix_length_and_dec() into methods in Type_handler
--echo #
CREATE TABLE t1 (a GEOMETRY);
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT -a FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT ABS(a) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CEILING(a) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT FLOOR(a) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT -COALESCE(a) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT ABS(COALESCE(a)) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CEILING(COALESCE(a)) FROM t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT FLOOR(COALESCE(a)) FROM t1;
DROP TABLE t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT -POINT(1,1);
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT ABS(POINT(1,1));
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT CEILING(POINT(1,1));
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT FLOOR(POINT(1,1));
--echo #
--echo # End of 10.3 tests
--echo #
......@@ -851,6 +851,10 @@ class Field: public Value_source
virtual bool str_needs_quotes() { return FALSE; }
virtual Item_result result_type () const=0;
virtual Item_result cmp_type () const { return result_type(); }
virtual const Type_handler *cast_to_int_type_handler() const
{
return Type_handler::get_handler_by_field_type(type());
}
static bool type_can_have_key_part(enum_field_types);
static enum_field_types field_type_merge(enum_field_types, enum_field_types);
virtual bool eq(Field *field)
......@@ -3463,6 +3467,10 @@ class Field_enum :public Field_str {
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
enum_field_types type() const { return MYSQL_TYPE_STRING; }
enum Item_result cmp_type () const { return INT_RESULT; }
const Type_handler *cast_to_int_type_handler() const
{
return &type_handler_longlong;
}
enum ha_base_keytype key_type() const;
Copy_func *get_copy_func(const Field *from) const
{
......
......@@ -706,6 +706,10 @@ class Item: public Value_source,
{
return Type_handler::get_handler_by_field_type(field_type());
}
virtual const Type_handler *cast_to_int_type_handler() const
{
return type_handler();
}
/* result_type() of an item specifies how the value should be returned */
virtual Item_result result_type() const
{
......@@ -716,7 +720,6 @@ class Item: public Value_source,
{
return type_handler()->cmp_type();
}
virtual Item_result cast_to_int_type() const { return cmp_type(); }
enum_field_types string_field_type() const
{
return Type_handler::string_type_handler(max_length)->field_type();
......@@ -2405,9 +2408,9 @@ class Item_field :public Item_ident
{
return field->result_type();
}
Item_result cast_to_int_type() const
const Type_handler *cast_to_int_type_handler() const
{
return field->cmp_type();
return field->cast_to_int_type_handler();
}
enum_field_types field_type() const
{
......@@ -3425,7 +3428,7 @@ class Item_hex_constant: public Item_basic_constant
bool eq(const Item *item, bool binary_cmp) const
{
return item->basic_const_item() && item->type() == type() &&
item->cast_to_int_type() == cast_to_int_type() &&
item->cast_to_int_type_handler() == cast_to_int_type_handler() &&
str_value.bin_eq(&((Item_hex_constant*)item)->str_value);
}
String *val_str(String*) { DBUG_ASSERT(fixed == 1); return &str_value; }
......@@ -3467,7 +3470,10 @@ class Item_hex_hybrid: public Item_hex_constant
field->set_notnull();
return field->store_hex_hybrid(str_value.ptr(), str_value.length());
}
enum Item_result cast_to_int_type() const { return INT_RESULT; }
const Type_handler *cast_to_int_type_handler() const
{
return &type_handler_longlong;
}
void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_hex_hybrid>(thd, mem_root, this); }
......@@ -3509,7 +3515,6 @@ class Item_hex_string: public Item_hex_constant
return field->store(str_value.ptr(), str_value.length(),
collation.collation);
}
enum Item_result cast_to_int_type() const { return STRING_RESULT; }
void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_hex_string>(thd, mem_root, this); }
......
......@@ -723,8 +723,8 @@ void Item_num_op::fix_length_and_dec(void)
DBUG_ENTER("Item_num_op::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
DBUG_ASSERT(arg_count == 2);
Item_result r0= args[0]->cast_to_int_type();
Item_result r1= args[1]->cast_to_int_type();
Item_result r0= args[0]->cast_to_int_type_handler()->cmp_type();
Item_result r1= args[1]->cast_to_int_type_handler()->cmp_type();
if (r0 == REAL_RESULT || r1 == REAL_RESULT ||
r0 == STRING_RESULT || r1 ==STRING_RESULT)
......@@ -758,47 +758,6 @@ void Item_num_op::fix_length_and_dec(void)
}
/**
Set result type for a numeric function of one argument
(can be also used by a numeric function of many arguments, if the result
type depends only on the first argument)
*/
void Item_func_num1::fix_length_and_dec()
{
DBUG_ENTER("Item_func_num1::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
// Note, cast_to_int_type() can return TIME_RESULT
switch (args[0]->cast_to_int_type()) {
case INT_RESULT:
set_handler_by_result_type(INT_RESULT);
max_length= args[0]->max_length;
unsigned_flag= args[0]->unsigned_flag;
break;
case STRING_RESULT:
case REAL_RESULT:
set_handler_by_result_type(REAL_RESULT);
decimals= args[0]->decimals; // Preserve NOT_FIXED_DEC
max_length= float_length(decimals);
break;
case TIME_RESULT:
case DECIMAL_RESULT:
set_handler_by_result_type(DECIMAL_RESULT);
decimals= args[0]->decimal_scale(); // Do not preserve NOT_FIXED_DEC
max_length= args[0]->max_length;
break;
case ROW_RESULT:
DBUG_ASSERT(0);
}
DBUG_PRINT("info", ("Type: %s",
(result_type() == REAL_RESULT ? "REAL_RESULT" :
result_type() == DECIMAL_RESULT ? "DECIMAL_RESULT" :
result_type() == INT_RESULT ? "INT_RESULT" :
"--ILLEGAL!!!--")));
DBUG_VOID_RETURN;
}
String *Item_func_hybrid_field_type::val_str_from_decimal_op(String *str)
{
my_decimal decimal_value, *val;
......@@ -1025,7 +984,7 @@ longlong Item::val_int_from_str(int *error)
longlong Item::val_int_signed_typecast()
{
if (cast_to_int_type() != STRING_RESULT)
if (cast_to_int_type_handler()->cmp_type() != STRING_RESULT)
return val_int();
int error;
......@@ -1047,7 +1006,7 @@ void Item_func_unsigned::print(String *str, enum_query_type query_type)
longlong Item::val_int_unsigned_typecast()
{
if (cast_to_int_type() == DECIMAL_RESULT)
if (cast_to_int_type_handler()->cmp_type() == DECIMAL_RESULT)
{
longlong value;
my_decimal tmp, *dec= val_decimal(&tmp);
......@@ -1057,7 +1016,7 @@ longlong Item::val_int_unsigned_typecast()
value= 0;
return value;
}
else if (cast_to_int_type() != STRING_RESULT)
else if (cast_to_int_type_handler()->cmp_type() != STRING_RESULT)
{
longlong value= val_int();
if (!null_value && unsigned_flag == 0 && value < 0)
......@@ -1897,11 +1856,9 @@ my_decimal *Item_func_neg::decimal_op(my_decimal *decimal_value)
}
void Item_func_neg::fix_length_and_dec()
void Item_func_neg::fix_length_and_dec_int()
{
DBUG_ENTER("Item_func_neg::fix_length_and_dec");
Item_func_num1::fix_length_and_dec();
/* 1 add because sign can appear */
set_handler(&type_handler_longlong);
max_length= args[0]->max_length + 1;
/*
......@@ -1910,7 +1867,7 @@ void Item_func_neg::fix_length_and_dec()
Use val() to get value as arg_type doesn't mean that item is
Item_int or Item_float due to existence of Item_param.
*/
if (Item_func_neg::result_type() == INT_RESULT && args[0]->const_item())
if (args[0]->const_item())
{
longlong val= args[0]->val_int();
if ((ulonglong) val >= (ulonglong) LONGLONG_MIN &&
......@@ -1925,7 +1882,34 @@ void Item_func_neg::fix_length_and_dec()
DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT"));
}
}
unsigned_flag= 0;
unsigned_flag= false;
}
void Item_func_neg::fix_length_and_dec_double()
{
set_handler(&type_handler_double);
decimals= args[0]->decimals; // Preserve NOT_FIXED_DEC
max_length= args[0]->max_length + 1;
unsigned_flag= false;
}
void Item_func_neg::fix_length_and_dec_decimal()
{
set_handler(&type_handler_newdecimal);
decimals= args[0]->decimal_scale(); // Do not preserve NOT_FIXED_DEC
max_length= args[0]->max_length + 1;
unsigned_flag= false;
}
void Item_func_neg::fix_length_and_dec()
{
DBUG_ENTER("Item_func_neg::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
args[0]->cast_to_int_type_handler()->Item_func_neg_fix_length_and_dec(this);
DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr()));
DBUG_VOID_RETURN;
}
......@@ -1966,13 +1950,42 @@ my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value)
}
void Item_func_abs::fix_length_and_dec()
void Item_func_abs::fix_length_and_dec_int()
{
set_handler(&type_handler_longlong);
max_length= args[0]->max_length;
unsigned_flag= args[0]->unsigned_flag;
}
void Item_func_abs::fix_length_and_dec_double()
{
set_handler(&type_handler_double);
decimals= args[0]->decimals; // Preserve NOT_FIXED_DEC
max_length= float_length(decimals);
unsigned_flag= args[0]->unsigned_flag;
}
void Item_func_abs::fix_length_and_dec_decimal()
{
Item_func_num1::fix_length_and_dec();
set_handler(&type_handler_newdecimal);
decimals= args[0]->decimal_scale(); // Do not preserve NOT_FIXED_DEC
max_length= args[0]->max_length;
unsigned_flag= args[0]->unsigned_flag;
}
void Item_func_abs::fix_length_and_dec()
{
DBUG_ENTER("Item_func_abs::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
args[0]->cast_to_int_type_handler()->Item_func_abs_fix_length_and_dec(this);
DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr()));
DBUG_VOID_RETURN;
}
/** Gateway to natural LOG function. */
double Item_func_ln::val_real()
{
......@@ -2201,11 +2214,8 @@ longlong Item_func_bit_neg::val_int()
// Conversion functions
void Item_func_int_val::fix_length_and_dec()
void Item_func_int_val::fix_length_and_dec_int_or_decimal()
{
DBUG_ENTER("Item_func_int_val::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
ulonglong tmp_max_length= (ulonglong ) args[0]->max_length -
(args[0]->decimals ? args[0]->decimals + 1 : 0) + 2;
max_length= tmp_max_length > (ulonglong) 4294967295U ?
......@@ -2214,41 +2224,37 @@ void Item_func_int_val::fix_length_and_dec()
set_if_smaller(max_length,tmp);
decimals= 0;
// Note, cast_to_int_type() can return TIME_RESULT
switch (args[0]->cast_to_int_type())
/*
-2 because in most high position can't be used any digit for longlong
and one position for increasing value during operation
*/
if (args[0]->max_length - args[0]->decimals >= DECIMAL_LONGLONG_DIGITS - 2)
{
case STRING_RESULT:
case REAL_RESULT:
set_handler_by_result_type(REAL_RESULT);
max_length= float_length(decimals);
break;
case INT_RESULT:
case TIME_RESULT:
case DECIMAL_RESULT:
/*
-2 because in most high position can't be used any digit for longlong
and one position for increasing value during operation
*/
if ((args[0]->max_length - args[0]->decimals) >=
(DECIMAL_LONGLONG_DIGITS - 2))
{
set_handler_by_result_type(DECIMAL_RESULT);
}
else
{
unsigned_flag= args[0]->unsigned_flag;
set_handler_by_result_type(INT_RESULT);
}
break;
case ROW_RESULT:
DBUG_ASSERT(0);
set_handler(&type_handler_newdecimal);
}
DBUG_PRINT("info", ("Type: %s",
(result_type() == REAL_RESULT ? "REAL_RESULT" :
result_type() == DECIMAL_RESULT ? "DECIMAL_RESULT" :
result_type() == INT_RESULT ? "INT_RESULT" :
"--ILLEGAL!!!--")));
else
{
unsigned_flag= args[0]->unsigned_flag;
set_handler(&type_handler_longlong);
}
}
void Item_func_int_val::fix_length_and_dec_double()
{
set_handler(&type_handler_double);
max_length= float_length(0);
decimals= 0;
}
void Item_func_int_val::fix_length_and_dec()
{
DBUG_ENTER("Item_func_int_val::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
args[0]->cast_to_int_type_handler()->
Item_func_int_val_fix_length_and_dec(this);
DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr()));
DBUG_VOID_RETURN;
}
......
......@@ -678,7 +678,8 @@ class Item_func_num1: public Item_func_numhybrid
public:
Item_func_num1(THD *thd, Item *a): Item_func_numhybrid(thd, a) {}
Item_func_num1(THD *thd, Item *a, Item *b): Item_func_numhybrid(thd, a, b) {}
void fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) { return FALSE; }
bool check_vcol_func_processor(void *arg) { return FALSE; }
};
......@@ -974,10 +975,11 @@ class Item_func_neg :public Item_func_num1
str->append(func_name());
args[0]->print_parenthesised(str, query_type, precedence());
}
void fix_length_and_dec_int();
void fix_length_and_dec_double();
void fix_length_and_dec_decimal();
void fix_length_and_dec();
uint decimal_precision() const { return args[0]->decimal_precision(); }
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
bool need_parentheses_in_default() { return true; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_neg>(thd, mem_root, this); }
......@@ -992,9 +994,10 @@ class Item_func_abs :public Item_func_num1
longlong int_op();
my_decimal *decimal_op(my_decimal *);
const char *func_name() const { return "abs"; }
void fix_length_and_dec_int();
void fix_length_and_dec_double();
void fix_length_and_dec_decimal();
void fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_abs>(thd, mem_root, this); }
};
......@@ -1167,6 +1170,8 @@ class Item_func_int_val :public Item_func_num1
{
public:
Item_func_int_val(THD *thd, Item *a): Item_func_num1(thd, a) {}
void fix_length_and_dec_double();
void fix_length_and_dec_int_or_decimal();
void fix_length_and_dec();
};
......@@ -1179,8 +1184,6 @@ class Item_func_ceiling :public Item_func_int_val
longlong int_op();
double real_op();
my_decimal *decimal_op(my_decimal *);
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_ceiling>(thd, mem_root, this); }
};
......@@ -1194,8 +1197,6 @@ class Item_func_floor :public Item_func_int_val
longlong int_op();
double real_op();
my_decimal *decimal_op(my_decimal *);
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_floor>(thd, mem_root, this); }
};
......
......@@ -1295,7 +1295,7 @@ void Item_sum_sum::fix_length_and_dec()
DBUG_ENTER("Item_sum_sum::fix_length_and_dec");
maybe_null=null_value=1;
decimals= args[0]->decimals;
switch (args[0]->cast_to_int_type()) {
switch (args[0]->cast_to_int_type_handler()->cmp_type()) {
case REAL_RESULT:
case STRING_RESULT:
set_handler_by_field_type(MYSQL_TYPE_DOUBLE);
......
......@@ -39,9 +39,6 @@ static Type_handler_tiny_blob type_handler_tiny_blob;
static Type_handler_medium_blob type_handler_medium_blob;
static Type_handler_long_blob type_handler_long_blob;
static Type_handler_blob type_handler_blob;
#ifdef HAVE_SPATIAL
static Type_handler_geometry type_handler_geometry;
#endif
static Type_handler_enum type_handler_enum;
static Type_handler_set type_handler_set;
......@@ -55,6 +52,10 @@ Type_handler_newdecimal type_handler_newdecimal;
Type_handler_datetime type_handler_datetime;
Type_handler_bit type_handler_bit;
#ifdef HAVE_SPATIAL
Type_handler_geometry type_handler_geometry;
#endif
Type_aggregator type_aggregator_for_result;
Type_aggregator type_aggregator_for_comparison;
......@@ -2215,3 +2216,183 @@ bool Type_handler_geometry::
#endif
/***************************************************************************/
bool Type_handler_row::
Item_func_int_val_fix_length_and_dec(Item_func_int_val *item) const
{
DBUG_ASSERT(0);
return false;
}
bool Type_handler_int_result::
Item_func_int_val_fix_length_and_dec(Item_func_int_val *item) const
{
item->fix_length_and_dec_int_or_decimal();
return false;
}
bool Type_handler_real_result::
Item_func_int_val_fix_length_and_dec(Item_func_int_val *item) const
{
item->fix_length_and_dec_double();
return false;
}
bool Type_handler_decimal_result::
Item_func_int_val_fix_length_and_dec(Item_func_int_val *item) const
{
item->fix_length_and_dec_int_or_decimal();
return false;
}
bool Type_handler_temporal_result::
Item_func_int_val_fix_length_and_dec(Item_func_int_val *item) const
{
item->fix_length_and_dec_int_or_decimal();
return false;
}
bool Type_handler_string_result::
Item_func_int_val_fix_length_and_dec(Item_func_int_val *item) const
{
item->fix_length_and_dec_double();
return false;
}
#ifdef HAVE_SPATIAL
bool Type_handler_geometry::
Item_func_int_val_fix_length_and_dec(Item_func_int_val *item) const
{
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0),
type_handler_geometry.name().ptr(), item->func_name());
return true;
}
#endif
/***************************************************************************/
bool Type_handler_row::
Item_func_abs_fix_length_and_dec(Item_func_abs *item) const
{
DBUG_ASSERT(0);
return false;
}
bool Type_handler_int_result::
Item_func_abs_fix_length_and_dec(Item_func_abs *item) const
{
item->fix_length_and_dec_int();
return false;
}
bool Type_handler_real_result::
Item_func_abs_fix_length_and_dec(Item_func_abs *item) const
{
item->fix_length_and_dec_double();
return false;
}
bool Type_handler_decimal_result::
Item_func_abs_fix_length_and_dec(Item_func_abs *item) const
{
item->fix_length_and_dec_decimal();
return false;
}
bool Type_handler_temporal_result::
Item_func_abs_fix_length_and_dec(Item_func_abs *item) const
{
item->fix_length_and_dec_decimal();
return false;
}
bool Type_handler_string_result::
Item_func_abs_fix_length_and_dec(Item_func_abs *item) const
{
item->fix_length_and_dec_double();
return false;
}
#ifdef HAVE_SPATIAL
bool Type_handler_geometry::
Item_func_abs_fix_length_and_dec(Item_func_abs *item) const
{
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0),
type_handler_geometry.name().ptr(), item->func_name());
return true;
}
#endif
/***************************************************************************/
bool Type_handler_row::
Item_func_neg_fix_length_and_dec(Item_func_neg *item) const
{
DBUG_ASSERT(0);
return false;
}
bool Type_handler_int_result::
Item_func_neg_fix_length_and_dec(Item_func_neg *item) const
{
item->fix_length_and_dec_int();
return false;
}
bool Type_handler_real_result::
Item_func_neg_fix_length_and_dec(Item_func_neg *item) const
{
item->fix_length_and_dec_double();
return false;
}
bool Type_handler_decimal_result::
Item_func_neg_fix_length_and_dec(Item_func_neg *item) const
{
item->fix_length_and_dec_decimal();
return false;
}
bool Type_handler_temporal_result::
Item_func_neg_fix_length_and_dec(Item_func_neg *item) const
{
item->fix_length_and_dec_decimal();
return false;
}
bool Type_handler_string_result::
Item_func_neg_fix_length_and_dec(Item_func_neg *item) const
{
item->fix_length_and_dec_double();
return false;
}
#ifdef HAVE_SPATIAL
bool Type_handler_geometry::
Item_func_neg_fix_length_and_dec(Item_func_neg *item) const
{
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0),
type_handler_geometry.name().ptr(), item->func_name());
return true;
}
#endif
/***************************************************************************/
......@@ -36,6 +36,9 @@ class Item_bool_func2;
class Item_func_between;
class Item_func_in;
class Item_func_round;
class Item_func_int_val;
class Item_func_abs;
class Item_func_neg;
class cmp_item;
class in_vector;
class Type_std_attributes;
......@@ -447,6 +450,15 @@ class Type_handler
virtual bool
Item_func_round_fix_length_and_dec(Item_func_round *round) const= 0;
virtual bool
Item_func_int_val_fix_length_and_dec(Item_func_int_val *func) const= 0;
virtual bool
Item_func_abs_fix_length_and_dec(Item_func_abs *func) const= 0;
virtual bool
Item_func_neg_fix_length_and_dec(Item_func_neg *func) const= 0;
};
......@@ -599,6 +611,9 @@ class Type_handler_row: public Type_handler
bool Item_func_in_fix_comparator_compatible_types(THD *thd,
Item_func_in *) const;
bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
};
......@@ -668,6 +683,9 @@ class Type_handler_real_result: public Type_handler_numeric
Item_func_in *) const;
bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
};
......@@ -711,6 +729,9 @@ class Type_handler_decimal_result: public Type_handler_numeric
bool Item_func_in_fix_comparator_compatible_types(THD *thd,
Item_func_in *) const;
bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
};
......@@ -753,6 +774,9 @@ class Type_handler_int_result: public Type_handler_numeric
bool Item_func_in_fix_comparator_compatible_types(THD *thd,
Item_func_in *) const;
bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
};
......@@ -799,6 +823,9 @@ class Type_handler_temporal_result: public Type_handler
bool Item_func_in_fix_comparator_compatible_types(THD *thd,
Item_func_in *) const;
bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
};
......@@ -859,6 +886,9 @@ class Type_handler_string_result: public Type_handler
bool Item_func_in_fix_comparator_compatible_types(THD *thd,
Item_func_in *) const;
bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
};
......@@ -1274,7 +1304,12 @@ class Type_handler_geometry: public Type_handler_string_result
return false;
}
bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
};
extern Type_handler_geometry type_handler_geometry;
#endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment