1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems, Inc.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
#include <drizzled/function/min_max.h>
23
#include <drizzled/item/cmpfunc.h>
24
#include <drizzled/session.h>
29
void Item_func_min_max::fix_length_and_dec()
32
bool datetime_found= false;
36
cmp_type=args[0]->result_type();
38
for (uint32_t i=0 ; i < arg_count ; i++)
40
set_if_bigger(max_length, args[i]->max_length);
41
set_if_bigger(decimals, args[i]->decimals);
42
set_if_bigger(max_int_part, args[i]->decimal_int_part());
43
if (args[i]->maybe_null)
45
cmp_type=item_cmp_type(cmp_type,args[i]->result_type());
46
if (args[i]->result_type() != ROW_RESULT && args[i]->is_datetime())
49
if (!datetime_item || args[i]->field_type() == DRIZZLE_TYPE_DATETIME)
50
datetime_item= args[i];
53
if (cmp_type == STRING_RESULT)
55
agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
58
session= getSessionPtr();
59
compare_as_dates= true;
62
else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT))
63
max_length= class_decimal_precision_to_length(max_int_part+decimals, decimals,
65
cached_field_type= agg_field_type(args, arg_count);
70
Compare item arguments in the DATETIME context.
74
value [out] found least/greatest DATE/DATETIME value
77
Compare item arguments as DATETIME values and return the index of the
78
least/greatest argument in the arguments array.
79
The correct integer DATE/DATETIME value of the found argument is
80
stored to the value pointer, if latter is provided.
83
0 If one of arguments is NULL or there was a execution error
84
# index of the least/greatest argument
87
uint32_t Item_func_min_max::cmp_datetimes(uint64_t *value)
90
uint32_t min_max_idx= 0;
92
for (uint32_t i=0; i < arg_count ; i++)
96
uint64_t res= get_datetime_value(session, &arg, 0, datetime_item,
99
/* Check if we need to stop (because of error or KILL) and stop the loop */
100
if (session->is_error())
106
if ((null_value= args[i]->null_value))
108
if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0)
117
if (datetime_item->field_type() == DRIZZLE_TYPE_DATE)
124
String *Item_func_min_max::val_str(String *str)
127
if (compare_as_dates)
130
uint32_t min_max_idx= cmp_datetimes(NULL);
133
str_res= args[min_max_idx]->val_str(str);
134
if (args[min_max_idx]->null_value)
136
// check if the call to val_str() above returns a NULL value
140
str_res->set_charset(collation.collation);
146
int64_t nr=val_int();
149
str->set_int(nr, unsigned_flag, &my_charset_bin);
155
type::Decimal dec_buf, *dec_val= val_decimal(&dec_buf);
158
class_decimal2string(dec_val, 0, str);
164
double nr= val_real();
167
str->set_real(nr,decimals,&my_charset_bin);
175
for (uint32_t i=0; i < arg_count ; i++)
178
res=args[i]->val_str(str);
182
res2= args[i]->val_str(res == str ? &tmp_value : str);
185
int cmp= sortcmp(res,res2,collation.collation);
186
if ((cmp_sign < 0 ? cmp : -cmp) < 0)
190
if ((null_value= args[i]->null_value))
193
res->set_charset(collation.collation);
198
// This case should never be chosen
203
return 0; // Keep compiler happy
207
double Item_func_min_max::val_real()
211
if (compare_as_dates)
214
(void)cmp_datetimes(&result);
215
return (double)result;
217
for (uint32_t i=0; i < arg_count ; i++)
220
value= args[i]->val_real();
223
double tmp= args[i]->val_real();
224
if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0)
227
if ((null_value= args[i]->null_value))
234
int64_t Item_func_min_max::val_int()
238
if (compare_as_dates)
241
(void)cmp_datetimes(&result);
242
return (int64_t)result;
244
for (uint32_t i=0; i < arg_count ; i++)
247
value=args[i]->val_int();
250
int64_t tmp=args[i]->val_int();
251
if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0)
254
if ((null_value= args[i]->null_value))
261
type::Decimal *Item_func_min_max::val_decimal(type::Decimal *dec)
264
type::Decimal tmp_buf, *tmp, *res= NULL;
266
if (compare_as_dates)
269
(void)cmp_datetimes(&value);
270
uint64_t2decimal(value, dec);
273
for (uint32_t i=0; i < arg_count ; i++)
276
res= args[i]->val_decimal(dec);
279
tmp= args[i]->val_decimal(&tmp_buf); // Zero if NULL
280
if (tmp && (class_decimal_cmp(tmp, res) * cmp_sign) < 0)
284
/* Move value out of tmp_buf as this will be reused on next loop */
285
class_decimal2decimal(tmp, dec);
292
if ((null_value= args[i]->null_value))
301
} /* namespace drizzled */