Commit 9f4abde6 authored by Alexander Barkov's avatar Alexander Barkov

Sharing similar code between Item_func_ifnull and Item_func_if

parent b432c7bc
...@@ -2432,13 +2432,14 @@ void Item_func_between::print(String *str, enum_query_type query_type) ...@@ -2432,13 +2432,14 @@ void Item_func_between::print(String *str, enum_query_type query_type)
str->append(')'); str->append(')');
} }
void void
Item_func_ifnull::fix_length_and_dec() Item_func_case_abbreviation2::fix_length_and_dec(Item **args)
{ {
uint32 char_length; uint32 char_length;
agg_result_type(&cached_result_type, args, 2); agg_result_type(&cached_result_type, args, 2);
cached_field_type= agg_field_type(args, 2); cached_field_type= agg_field_type(args, 2);
maybe_null=args[1]->maybe_null; maybe_null=args[0]->maybe_null || args[1]->maybe_null;
decimals= MY_MAX(args[0]->decimals, args[1]->decimals); decimals= MY_MAX(args[0]->decimals, args[1]->decimals);
unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag; unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
...@@ -2457,7 +2458,7 @@ Item_func_ifnull::fix_length_and_dec() ...@@ -2457,7 +2458,7 @@ Item_func_ifnull::fix_length_and_dec()
switch (cached_result_type) { switch (cached_result_type) {
case STRING_RESULT: case STRING_RESULT:
if (count_string_result_length(cached_field_type, args, arg_count)) if (count_string_result_length(cached_field_type, args, 2))
return; return;
break; break;
case DECIMAL_RESULT: case DECIMAL_RESULT:
...@@ -2475,7 +2476,8 @@ Item_func_ifnull::fix_length_and_dec() ...@@ -2475,7 +2476,8 @@ Item_func_ifnull::fix_length_and_dec()
} }
uint Item_func_ifnull::decimal_precision() const
uint Item_func_case_abbreviation2::decimal_precision(Item **args) const
{ {
int arg0_int_part= args[0]->decimal_int_part(); int arg0_int_part= args[0]->decimal_int_part();
int arg1_int_part= args[1]->decimal_int_part(); int arg1_int_part= args[1]->decimal_int_part();
...@@ -2662,47 +2664,7 @@ Item_func_if::fix_length_and_dec() ...@@ -2662,47 +2664,7 @@ Item_func_if::fix_length_and_dec()
maybe_null= true; maybe_null= true;
return; return;
} }
Item_func_case_abbreviation2::fix_length_and_dec(args + 1);
agg_result_type(&cached_result_type, args + 1, 2);
cached_field_type= agg_field_type(args + 1, 2);
maybe_null= args[1]->maybe_null || args[2]->maybe_null;
decimals= MY_MAX(args[1]->decimals, args[2]->decimals);
unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
if (cached_result_type == STRING_RESULT)
{
count_string_result_length(cached_field_type, args + 1, 2);
return;
}
else
{
collation.set_numeric(); // Number
}
uint32 char_length;
if ((cached_result_type == DECIMAL_RESULT )
|| (cached_result_type == INT_RESULT))
{
int len1= args[1]->max_length - args[1]->decimals
- (args[1]->unsigned_flag ? 0 : 1);
int len2= args[2]->max_length - args[2]->decimals
- (args[2]->unsigned_flag ? 0 : 1);
char_length= MY_MAX(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
}
else
char_length= MY_MAX(args[1]->max_char_length(), args[2]->max_char_length());
fix_char_length(char_length);
}
uint Item_func_if::decimal_precision() const
{
int arg1_prec= args[1]->decimal_int_part();
int arg2_prec= args[2]->decimal_int_part();
int precision=MY_MAX(arg1_prec,arg2_prec) + decimals;
return MY_MIN(precision, DECIMAL_MAX_PRECISION);
} }
......
...@@ -756,29 +756,52 @@ class Item_func_coalesce :public Item_func_hybrid_field_type ...@@ -756,29 +756,52 @@ class Item_func_coalesce :public Item_func_hybrid_field_type
}; };
class Item_func_ifnull :public Item_func_coalesce /*
Case abbreviations that aggregate its result field type by two arguments:
IFNULL(arg1, arg2)
IF(switch, arg1, arg2)
*/
class Item_func_case_abbreviation2 :public Item_func_hybrid_field_type
{
public:
Item_func_case_abbreviation2(Item *a, Item *b)
:Item_func_hybrid_field_type(a, b) { }
Item_func_case_abbreviation2(Item *a, Item *b, Item *c)
:Item_func_hybrid_field_type(a, b, c) { }
void fix_length_and_dec(Item **args);
uint decimal_precision(Item **args) const;
};
class Item_func_ifnull :public Item_func_case_abbreviation2
{ {
protected:
bool field_type_defined;
public: public:
Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {} Item_func_ifnull(Item *a, Item *b) :Item_func_case_abbreviation2(a,b) {}
double real_op(); double real_op();
longlong int_op(); longlong int_op();
String *str_op(String *str); String *str_op(String *str);
my_decimal *decimal_op(my_decimal *); my_decimal *decimal_op(my_decimal *);
bool date_op(MYSQL_TIME *ltime,uint fuzzydate); bool date_op(MYSQL_TIME *ltime,uint fuzzydate);
void fix_length_and_dec(); void fix_length_and_dec()
{
Item_func_case_abbreviation2::fix_length_and_dec(args);
maybe_null= args[1]->maybe_null;
}
const char *func_name() const { return "ifnull"; } const char *func_name() const { return "ifnull"; }
Field *tmp_table_field(TABLE *table); Field *tmp_table_field(TABLE *table);
uint decimal_precision() const; table_map not_null_tables() const { return 0; }
uint decimal_precision() const
{
return Item_func_case_abbreviation2::decimal_precision(args);
}
}; };
class Item_func_if :public Item_func_hybrid_field_type class Item_func_if :public Item_func_case_abbreviation2
{ {
public: public:
Item_func_if(Item *a,Item *b,Item *c) Item_func_if(Item *a,Item *b,Item *c)
:Item_func_hybrid_field_type(a,b,c) :Item_func_case_abbreviation2(a, b, c)
{} {}
bool date_op(MYSQL_TIME *ltime, uint fuzzydate); bool date_op(MYSQL_TIME *ltime, uint fuzzydate);
longlong int_op(); longlong int_op();
...@@ -787,7 +810,10 @@ class Item_func_if :public Item_func_hybrid_field_type ...@@ -787,7 +810,10 @@ class Item_func_if :public Item_func_hybrid_field_type
String *str_op(String *); String *str_op(String *);
bool fix_fields(THD *, Item **); bool fix_fields(THD *, Item **);
void fix_length_and_dec(); void fix_length_and_dec();
uint decimal_precision() const; uint decimal_precision() const
{
return Item_func_case_abbreviation2::decimal_precision(args + 1);
}
const char *func_name() const { return "if"; } const char *func_name() const { return "if"; }
bool eval_not_null_tables(uchar *opt_arg); bool eval_not_null_tables(uchar *opt_arg);
void fix_after_pullout(st_select_lex *new_parent, Item **ref); void fix_after_pullout(st_select_lex *new_parent, Item **ref);
......
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