maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #10454
Please review MDEV-12199 Split Item_func_{abs|neg|int_val}::fix_length_and_dec() into methods in Type_handler
Hello Alexey,
Please review a patch for MDEV-12199.
Thanks!
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 07945d6..0b5741f 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -3720,5 +3720,34 @@ DROP TABLE t1;
SELECT ROUND(POINT(1,1));
ERROR HY000: Illegal parameter data type geometry for operation 'round'
#
+# Split
+#
+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
#
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index 7d6c3ba..d32d646 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -1880,6 +1880,40 @@ DROP TABLE t1;
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT ROUND(POINT(1,1));
+
+--echo #
+--echo # Split
+--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 #
diff --git a/sql/field.h b/sql/field.h
index 7755641..7d59373 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -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)
@@ -3461,6 +3465,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
{
diff --git a/sql/item.h b/sql/item.h
index 3908fe2..96ae714 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -699,6 +699,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
{
@@ -709,7 +713,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();
@@ -2388,9 +2391,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
{
@@ -3408,7 +3411,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; }
@@ -3450,7 +3453,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); }
@@ -3492,7 +3498,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); }
diff --git a/sql/item_func.cc b/sql/item_func.cc
index cd5b94f..3a9f61e 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -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;
}
diff --git a/sql/item_func.h b/sql/item_func.h
index f9c079a..8b53631 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -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); }
};
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 07755d6..d5e972c 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -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);
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index 6de1af2..4d4694d 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -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
+
+/***************************************************************************/
diff --git a/sql/sql_type.h b/sql/sql_type.h
index 45ffef5..bc8b170 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -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