summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2016-04-26 23:05:26 +0200
committerSergei Golubchik <serg@mariadb.org>2016-04-26 23:05:26 +0200
commit872649c7baab3a9f7efdda78e49c4bc7dd481d91 (patch)
tree4fffb1a99ca36ccea65e64bcaa81293c40e7539f /sql/item_cmpfunc.cc
parent4995bcffaded6a02106632fb8f259cd3d9048dc4 (diff)
parent4f1ad43992d75676687f29da96dd7c4147247a8f (diff)
downloadmariadb-git-872649c7baab3a9f7efdda78e49c4bc7dd481d91.tar.gz
Merge branch '5.5' into 10.0
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc77
1 files changed, 31 insertions, 46 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index b2c580db507..e0dbf2c5a73 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -161,10 +161,11 @@ static int cmp_row_type(Item* item1, Item* item2)
static int agg_cmp_type(Item_result *type, Item **items, uint nitems)
{
- uint i;
+ uint unsigned_count= items[0]->unsigned_flag;
type[0]= items[0]->cmp_type();
- for (i= 1 ; i < nitems ; i++)
+ for (uint i= 1 ; i < nitems ; i++)
{
+ unsigned_count+= items[i]->unsigned_flag;
type[0]= item_cmp_type(type[0], items[i]->cmp_type());
/*
When aggregating types of two row expressions we have to check
@@ -176,6 +177,12 @@ static int agg_cmp_type(Item_result *type, Item **items, uint nitems)
if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
return 1; // error found: invalid usage of rows
}
+ /**
+ If all arguments are of INT type but have different unsigned_flag values,
+ switch to DECIMAL_RESULT.
+ */
+ if (type[0] == INT_RESULT && unsigned_count != nitems && unsigned_count != 0)
+ type[0]= DECIMAL_RESULT;
return 0;
}
@@ -2621,10 +2628,7 @@ bool Item_func_ifnull::date_op(MYSQL_TIME *ltime, uint fuzzydate)
DBUG_ASSERT(fixed == 1);
if (!args[0]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES))
return (null_value= false);
- if (!args[1]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES))
- return (null_value= false);
- bzero((char*) ltime,sizeof(*ltime));
- return null_value= !(fuzzydate & TIME_FUZZY_DATES);
+ return (null_value= args[1]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES));
}
@@ -3081,24 +3085,6 @@ bool Item_func_case::fix_fields(THD *thd, Item **ref)
}
-void Item_func_case::agg_str_lengths(Item* arg)
-{
- fix_char_length(MY_MAX(max_char_length(), arg->max_char_length()));
- set_if_bigger(decimals, arg->decimals);
- unsigned_flag= unsigned_flag && arg->unsigned_flag;
-}
-
-
-void Item_func_case::agg_num_lengths(Item *arg)
-{
- uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
- arg->unsigned_flag) - arg->decimals;
- set_if_bigger(max_length, len);
- set_if_bigger(decimals, arg->decimals);
- unsigned_flag= unsigned_flag && arg->unsigned_flag;
-}
-
-
/**
Check if (*place) and new_value points to different Items and call
THD::change_item_tree() if needed.
@@ -3164,17 +3150,7 @@ void Item_func_case::fix_length_and_dec()
}
else
{
- collation.set_numeric();
- max_length=0;
- decimals=0;
- unsigned_flag= TRUE;
- for (uint i= 0; i < ncases; i+= 2)
- agg_num_lengths(args[i + 1]);
- if (else_expr_num != -1)
- agg_num_lengths(args[else_expr_num]);
- max_length= my_decimal_precision_to_length_no_truncation(max_length +
- decimals, decimals,
- unsigned_flag);
+ fix_attributes(agg, nagg);
}
/*
@@ -3374,16 +3350,12 @@ double Item_func_coalesce::real_op()
bool Item_func_coalesce::date_op(MYSQL_TIME *ltime,uint fuzzydate)
{
DBUG_ASSERT(fixed == 1);
- null_value= 0;
for (uint i= 0; i < arg_count; i++)
{
- bool res= args[i]->get_date_with_conversion(ltime,
- fuzzydate & ~TIME_FUZZY_DATES);
- if (!args[i]->null_value)
- return res;
+ if (!args[i]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES))
+ return (null_value= false);
}
- bzero((char*) ltime,sizeof(*ltime));
- return null_value|= !(fuzzydate & TIME_FUZZY_DATES);
+ return (null_value= true);
}
@@ -3406,19 +3378,32 @@ void Item_func_coalesce::fix_length_and_dec()
{
cached_field_type= agg_field_type(args, arg_count);
agg_result_type(&cached_result_type, args, arg_count);
+ fix_attributes(args, arg_count);
+}
+
+
+#if MYSQL_VERSION_ID > 100100
+#error Rename this to Item_hybrid_func::fix_attributes() when mering to 10.1
+#endif
+void Item_func_hybrid_result_type::fix_attributes(Item **items, uint nitems)
+{
switch (cached_result_type) {
case STRING_RESULT:
- if (count_string_result_length(cached_field_type, args, arg_count))
+ if (count_string_result_length(field_type(),
+ items, nitems))
return;
break;
case DECIMAL_RESULT:
- count_decimal_length();
+ collation.set_numeric();
+ count_decimal_length(items, nitems);
break;
case REAL_RESULT:
- count_real_length();
+ collation.set_numeric();
+ count_real_length(items, nitems);
break;
case INT_RESULT:
- count_only_length(args, arg_count);
+ collation.set_numeric();
+ count_only_length(items, nitems);
decimals= 0;
break;
case ROW_RESULT: