diff options
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r-- | sql/item_func.cc | 108 |
1 files changed, 49 insertions, 59 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc index 8bb1009ac2c..b37156efa02 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -940,8 +940,7 @@ longlong Item_func_signed::val_int() longlong value; int error; - if (args[0]->cast_to_int_type() != STRING_RESULT || - args[0]->result_as_longlong()) + if (args[0]->cast_to_int_type() != STRING_RESULT) { value= args[0]->val_int(); null_value= args[0]->null_value; @@ -982,8 +981,7 @@ longlong Item_func_unsigned::val_int() value= 0; return value; } - else if (args[0]->cast_to_int_type() != STRING_RESULT || - args[0]->result_as_longlong()) + else if (args[0]->cast_to_int_type() != STRING_RESULT) { value= args[0]->val_int(); null_value= args[0]->null_value; @@ -2220,7 +2218,6 @@ double Item_func_units::val_real() void Item_func_min_max::fix_length_and_dec() { int max_int_part=0; - bool datetime_found= FALSE; decimals=0; max_length=0; maybe_null=0; @@ -2234,21 +2231,17 @@ void Item_func_min_max::fix_length_and_dec() if (args[i]->maybe_null) maybe_null=1; cmp_type=item_cmp_type(cmp_type,args[i]->result_type()); - if (args[i]->result_type() != ROW_RESULT && args[i]->is_datetime()) + if (args[i]->cmp_type() == TIME_RESULT) { - datetime_found= TRUE; - if (!datetime_item || args[i]->field_type() == MYSQL_TYPE_DATETIME) - datetime_item= args[i]; + if (!compare_as_dates || args[i]->field_type() == MYSQL_TYPE_DATETIME) + compare_as_dates= args[i]; } } if (cmp_type == STRING_RESULT) { agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1); - if (datetime_found) - { + if (compare_as_dates) thd= current_thd; - compare_as_dates= TRUE; - } } else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT)) max_length= my_decimal_precision_to_length_no_truncation(max_int_part + @@ -2256,7 +2249,11 @@ void Item_func_min_max::fix_length_and_dec() unsigned_flag); else if (cmp_type == REAL_RESULT) max_length= float_length(decimals); - cached_field_type= agg_field_type(args, arg_count); + + if (compare_as_dates) + cached_field_type= compare_as_dates->field_type(); + else + cached_field_type= agg_field_type(args, arg_count); } @@ -2265,52 +2262,45 @@ void Item_func_min_max::fix_length_and_dec() SYNOPSIS cmp_datetimes() - value [out] found least/greatest DATE/DATETIME value DESCRIPTION Compare item arguments as DATETIME values and return the index of the least/greatest argument in the arguments array. - The correct integer DATE/DATETIME value of the found argument is + The correct DATE/DATETIME value of the found argument is stored to the value pointer, if latter is provided. RETURN - 0 If one of arguments is NULL or there was a execution error - # index of the least/greatest argument + 1 If one of arguments is NULL or there was a execution error + 0 Otherwise */ -uint Item_func_min_max::cmp_datetimes(ulonglong *value) +bool Item_func_min_max::cmp_datetimes(MYSQL_TIME *ltime) { longlong UNINIT_VAR(min_max); - uint min_max_idx= 0; for (uint i=0; i < arg_count ; i++) { Item **arg= args + i; bool is_null; - longlong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null); + longlong res= get_datetime_value(thd, &arg, 0, compare_as_dates, &is_null); /* Check if we need to stop (because of error or KILL) and stop the loop */ if (thd->is_error()) { null_value= 1; - return 0; + return 1; } if ((null_value= args[i]->null_value)) - return 0; + return 1; if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0) - { min_max= res; - min_max_idx= i; - } } - if (value) - { - *value= min_max; - if (datetime_item->field_type() == MYSQL_TYPE_DATE) - *value/= 1000000L; - } - return min_max_idx; + unpack_time(min_max, ltime); + if (compare_as_dates->field_type() == MYSQL_TYPE_DATE) + ltime->time_type= MYSQL_TIMESTAMP_DATE; + + return 0; } @@ -2319,19 +2309,14 @@ String *Item_func_min_max::val_str(String *str) DBUG_ASSERT(fixed == 1); if (compare_as_dates) { - String *str_res; - uint min_max_idx= cmp_datetimes(NULL); - if (null_value) + MYSQL_TIME ltime; + if (cmp_datetimes(<ime)) return 0; - str_res= args[min_max_idx]->val_str(str); - if (args[min_max_idx]->null_value) - { - // check if the call to val_str() above returns a NULL value - null_value= 1; - return NULL; - } - str_res->set_charset(collation.collation); - return str_res; + + char buf[MAX_DATE_STRING_REP_LENGTH]; + int len= my_TIME_to_str(<ime, buf, decimals); + str->copy(buf, len, collation.collation); + return str; } switch (cmp_type) { case INT_RESULT: @@ -2398,9 +2383,11 @@ double Item_func_min_max::val_real() double value=0.0; if (compare_as_dates) { - ulonglong result= 0; - (void)cmp_datetimes(&result); - return (double)result; + MYSQL_TIME ltime; + if (cmp_datetimes(<ime)) + return 0; + + return TIME_to_double(<ime); } for (uint i=0; i < arg_count ; i++) { @@ -2425,9 +2412,11 @@ longlong Item_func_min_max::val_int() longlong value=0; if (compare_as_dates) { - ulonglong result= 0; - (void)cmp_datetimes(&result); - return (longlong)result; + MYSQL_TIME ltime; + if (cmp_datetimes(<ime)) + return 0; + + return TIME_to_ulonglong(<ime); } for (uint i=0; i < arg_count ; i++) { @@ -2453,10 +2442,11 @@ my_decimal *Item_func_min_max::val_decimal(my_decimal *dec) if (compare_as_dates) { - ulonglong value= 0; - (void)cmp_datetimes(&value); - ulonglong2decimal(value, dec); - return dec; + MYSQL_TIME ltime; + if (cmp_datetimes(<ime)) + return 0; + + return date2my_decimal(<ime, dec); } for (uint i=0; i < arg_count ; i++) { @@ -3979,7 +3969,7 @@ double user_var_entry::val_real(my_bool *null_value) } case STRING_RESULT: return my_atof(value); // This is null terminated - case ROW_RESULT: + default: DBUG_ASSERT(1); // Impossible break; } @@ -4010,7 +4000,7 @@ longlong user_var_entry::val_int(my_bool *null_value) const int error; return my_strtoll10(value, (char**) 0, &error);// String is null terminated } - case ROW_RESULT: + default: DBUG_ASSERT(1); // Impossible break; } @@ -4042,7 +4032,7 @@ String *user_var_entry::val_str(my_bool *null_value, String *str, case STRING_RESULT: if (str->copy(value, length, collation.collation)) str= 0; // EOM error - case ROW_RESULT: + default: DBUG_ASSERT(1); // Impossible break; } @@ -4069,7 +4059,7 @@ my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val) case STRING_RESULT: str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val); break; - case ROW_RESULT: + default: DBUG_ASSERT(1); // Impossible break; } |