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
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
20
#include <drizzled/server_includes.h>
25
#include <drizzled/version.h>
27
#include <drizzled/sql_string.h>
28
#include <drizzled/sql_list.h>
30
#include <drizzled/functions/int.h>
33
void Item_func::set_arguments(List<Item> &list)
36
arg_count=list.elements;
37
args= tmp_arg; // If 2 arguments
38
if (arg_count <= 2 || (args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
40
List_iterator_fast<Item> li(list);
42
Item **save_args= args;
47
with_sum_func|=item->with_sum_func;
50
list.empty(); // Fields are used
53
Item_func::Item_func(List<Item> &list)
59
Item_func::Item_func(THD *thd, Item_func *item)
60
:Item_result_field(thd, item),
61
allowed_arg_cols(item->allowed_arg_cols),
62
arg_count(item->arg_count),
63
used_tables_cache(item->used_tables_cache),
64
not_null_tables_cache(item->not_null_tables_cache),
65
const_item_cache(item->const_item_cache)
73
if (!(args=(Item**) thd->alloc(sizeof(Item*)*arg_count)))
76
memcpy(args, item->args, sizeof(Item*)*arg_count);
82
Resolve references to table column for a function and its argument
87
ref Pointer to where this object is used. This reference
88
is used if we want to replace this object with another
89
one (for example in the summary functions).
92
Call fix_fields() for all arguments to the function. The main intention
93
is to allow all Item_field() objects to setup pointers to the table fields.
95
Sets as a side effect the following class variables:
96
maybe_null Set if any argument may return NULL
97
with_sum_func Set if any of the arguments contains a sum function
98
used_tables_cache Set to union of the tables used by arguments
100
str_value.charset If this is a string function, set this to the
101
character set for the first argument.
102
If any argument is binary, this is set to binary
104
If for any item any of the defaults are wrong, then this can
105
be fixed in the fix_length_and_dec() function that is called
106
after this one or by writing a specialized fix_fields() for the
111
true Got error. Stored with my_error().
115
Item_func::fix_fields(THD *thd, Item **ref __attribute__((unused)))
118
Item **arg,**arg_end;
119
void *save_thd_marker= thd->thd_marker;
120
unsigned char buff[STACK_BUFF_ALLOC]; // Max argument in function
122
used_tables_cache= not_null_tables_cache= 0;
125
if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
126
return true; // Fatal error if flag is set!
128
{ // Print purify happy
129
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
133
We can't yet set item to *arg as fix_fields may change *arg
134
We shouldn't call fix_fields() twice, so check 'fixed' field first
136
if ((!(*arg)->fixed && (*arg)->fix_fields(thd, arg)))
137
return true; /* purecov: inspected */
140
if (allowed_arg_cols)
142
if (item->check_cols(allowed_arg_cols))
147
/* we have to fetch allowed_arg_cols from first argument */
148
assert(arg == args); // it is first argument
149
allowed_arg_cols= item->cols();
150
assert(allowed_arg_cols); // Can't be 0 any more
153
if (item->maybe_null)
156
with_sum_func= with_sum_func || item->with_sum_func;
157
used_tables_cache|= item->used_tables();
158
not_null_tables_cache|= item->not_null_tables();
159
const_item_cache&= item->const_item();
160
with_subselect|= item->with_subselect;
163
fix_length_and_dec();
164
if (thd->is_error()) // An error inside fix_length_and_dec occured
167
thd->thd_marker= save_thd_marker;
172
void Item_func::fix_after_pullout(st_select_lex *new_parent,
173
Item **ref __attribute__((unused)))
175
Item **arg,**arg_end;
177
used_tables_cache= not_null_tables_cache= 0;
182
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
184
(*arg)->fix_after_pullout(new_parent, arg);
187
used_tables_cache|= item->used_tables();
188
not_null_tables_cache|= item->not_null_tables();
189
const_item_cache&= item->const_item();
195
bool Item_func::walk(Item_processor processor, bool walk_subquery,
196
unsigned char *argument)
200
Item **arg,**arg_end;
201
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
203
if ((*arg)->walk(processor, walk_subquery, argument))
207
return (this->*processor)(argument);
210
void Item_func::traverse_cond(Cond_traverser traverser,
211
void *argument, traverse_order order)
215
Item **arg,**arg_end;
219
(*traverser)(this, argument);
220
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
222
(*arg)->traverse_cond(traverser, argument, order);
226
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
228
(*arg)->traverse_cond(traverser, argument, order);
230
(*traverser)(this, argument);
234
(*traverser)(this, argument);
239
Transform an Item_func object with a transformer callback function.
241
The function recursively applies the transform method to each
242
argument of the Item_func node.
243
If the call of the method for an argument item returns a new item
244
the old item is substituted for a new one.
245
After this the transformer is applied to the root node
246
of the Item_func object.
247
@param transformer the transformer callback function to be applied to
248
the nodes of the tree of the object
249
@param argument parameter to be passed to the transformer
252
Item returned as the result of transformation of the root node
255
Item *Item_func::transform(Item_transformer transformer, unsigned char *argument)
259
Item **arg,**arg_end;
260
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
262
Item *new_item= (*arg)->transform(transformer, argument);
267
THD::change_item_tree() should be called only if the tree was
268
really transformed, i.e. when a new item has been created.
269
Otherwise we'll be allocating a lot of unnecessary memory for
270
change records at each execution.
272
if (*arg != new_item)
273
current_thd->change_item_tree(arg, new_item);
276
return (this->*transformer)(argument);
281
Compile Item_func object with a processor and a transformer
284
First the function applies the analyzer to the root node of
285
the Item_func object. Then if the analizer succeeeds (returns true)
286
the function recursively applies the compile method to each argument
287
of the Item_func node.
288
If the call of the method for an argument item returns a new item
289
the old item is substituted for a new one.
290
After this the transformer is applied to the root node
291
of the Item_func object.
293
@param analyzer the analyzer callback function to be applied to the
294
nodes of the tree of the object
295
@param[in,out] arg_p parameter to be passed to the processor
296
@param transformer the transformer callback function to be applied to the
297
nodes of the tree of the object
298
@param arg_t parameter to be passed to the transformer
301
Item returned as the result of transformation of the root node
304
Item *Item_func::compile(Item_analyzer analyzer, unsigned char **arg_p,
305
Item_transformer transformer, unsigned char *arg_t)
307
if (!(this->*analyzer)(arg_p))
311
Item **arg,**arg_end;
312
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
315
The same parameter value of arg_p must be passed
316
to analyze any argument of the condition formula.
318
unsigned char *arg_v= *arg_p;
319
Item *new_item= (*arg)->compile(analyzer, &arg_v, transformer, arg_t);
320
if (new_item && *arg != new_item)
321
current_thd->change_item_tree(arg, new_item);
324
return (this->*transformer)(arg_t);
328
See comments in Item_cmp_func::split_sum_func()
331
void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
334
Item **arg, **arg_end;
335
for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
336
(*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg, true);
340
void Item_func::update_used_tables()
344
for (uint32_t i=0 ; i < arg_count ; i++)
346
args[i]->update_used_tables();
347
used_tables_cache|=args[i]->used_tables();
348
const_item_cache&=args[i]->const_item();
353
table_map Item_func::used_tables() const
355
return used_tables_cache;
359
table_map Item_func::not_null_tables() const
361
return not_null_tables_cache;
365
void Item_func::print(String *str, enum_query_type query_type)
367
str->append(func_name());
369
print_args(str, 0, query_type);
374
void Item_func::print_args(String *str, uint32_t from, enum_query_type query_type)
376
for (uint32_t i=from ; i < arg_count ; i++)
380
args[i]->print(str, query_type);
385
void Item_func::print_op(String *str, enum_query_type query_type)
388
for (uint32_t i=0 ; i < arg_count-1 ; i++)
390
args[i]->print(str, query_type);
392
str->append(func_name());
395
args[arg_count-1]->print(str, query_type);
400
bool Item_func::eq(const Item *item, bool binary_cmp) const
402
/* Assume we don't have rtti */
405
if (item->type() != FUNC_ITEM)
407
Item_func *item_func=(Item_func*) item;
408
Item_func::Functype func_type;
409
if ((func_type= functype()) != item_func->functype() ||
410
arg_count != item_func->arg_count ||
411
(func_type != Item_func::FUNC_SP &&
412
func_name() != item_func->func_name()) ||
413
(func_type == Item_func::FUNC_SP &&
414
my_strcasecmp(system_charset_info, func_name(), item_func->func_name())))
416
for (uint32_t i=0; i < arg_count ; i++)
417
if (!args[i]->eq(item_func->args[i], binary_cmp))
423
bool Item_func::get_arg0_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date)
425
return (null_value=args[0]->get_date(ltime, fuzzy_date));
429
bool Item_func::get_arg0_time(DRIZZLE_TIME *ltime)
431
return (null_value=args[0]->get_time(ltime));
435
bool Item_func::is_null()
442
Field *Item_func::tmp_table_field(Table *table)
446
switch (result_type()) {
448
if (max_length > MY_INT32_NUM_DECIMAL_DIGITS)
449
field= new Field_int64_t(max_length, maybe_null, name, unsigned_flag);
451
field= new Field_long(max_length, maybe_null, name, unsigned_flag);
454
field= new Field_double(max_length, maybe_null, name, decimals);
457
return make_string_field(table);
460
field= new Field_new_decimal(
461
my_decimal_precision_to_length(decimal_precision(),
464
maybe_null, name, decimals, unsigned_flag);
468
// This case should never be chosen
479
my_decimal *Item_func::val_decimal(my_decimal *decimal_value)
482
int2my_decimal(E_DEC_FATAL_ERROR, val_int(), unsigned_flag, decimal_value);
483
return decimal_value;
487
bool Item_func::agg_arg_collations(DTCollation &c, Item **items,
488
uint32_t nitems, uint32_t flags)
490
return agg_item_collations(c, func_name(), items, nitems, flags, 1);
494
bool Item_func::agg_arg_collations_for_comparison(DTCollation &c,
499
return agg_item_collations_for_comparison(c, func_name(),
500
items, nitems, flags);
504
bool Item_func::agg_arg_charsets(DTCollation &c, Item **items, uint32_t nitems,
505
uint32_t flags, int item_sep)
507
return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep);
511
double Item_func::fix_result(double value)
513
if (CMATH_C99_NAMESPACE isfinite(value))