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
22
#include <drizzled/sql_string.h>
23
#include <drizzled/sql_list.h>
25
#include <drizzled/function/math/int.h>
26
#include <drizzled/field/int32.h>
27
#include <drizzled/field/int64.h>
28
#include <drizzled/field/double.h>
29
#include <drizzled/field/decimal.h>
30
#include <drizzled/session.h>
31
#include <drizzled/error.h>
32
#include <drizzled/check_stack_overrun.h>
42
void Item_func::set_arguments(List<Item> &list)
45
arg_count=list.elements;
46
args= tmp_arg; // If 2 arguments
47
if (arg_count <= 2 || (args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
49
List_iterator_fast<Item> li(list);
51
Item **save_args= args;
56
with_sum_func|=item->with_sum_func;
59
list.empty(); // Fields are used
62
Item_func::Item_func(List<Item> &list) :
63
_session(*current_session),
66
collation.set(DERIVATION_SYSCONST);
70
Item_func::Item_func(Session *session, Item_func *item) :
71
Item_result_field(session, item),
72
_session(*current_session),
73
allowed_arg_cols(item->allowed_arg_cols),
74
arg_count(item->arg_count),
75
used_tables_cache(item->used_tables_cache),
76
not_null_tables_cache(item->not_null_tables_cache),
77
const_item_cache(item->const_item_cache)
85
if (!(args=(Item**) session->alloc(sizeof(Item*)*arg_count)))
88
memcpy(args, item->args, sizeof(Item*)*arg_count);
90
collation.set(DERIVATION_SYSCONST);
95
Resolve references to table column for a function and its argument
100
ref Pointer to where this object is used. This reference
101
is used if we want to replace this object with another
102
one (for example in the summary functions).
105
Call fix_fields() for all arguments to the function. The main intention
106
is to allow all Item_field() objects to setup pointers to the table fields.
108
Sets as a side effect the following class variables:
109
maybe_null Set if any argument may return NULL
110
with_sum_func Set if any of the arguments contains a sum function
111
used_tables_cache Set to union of the tables used by arguments
113
str_value.charset If this is a string function, set this to the
114
character set for the first argument.
115
If any argument is binary, this is set to binary
117
If for any item any of the defaults are wrong, then this can
118
be fixed in the fix_length_and_dec() function that is called
119
after this one or by writing a specialized fix_fields() for the
124
true Got error. Stored with my_error().
128
Item_func::fix_fields(Session *session, Item **)
131
Item **arg,**arg_end;
132
void *save_session_marker= session->session_marker;
133
unsigned char buff[STACK_BUFF_ALLOC]; // Max argument in function
134
session->session_marker= 0;
135
used_tables_cache= not_null_tables_cache= 0;
138
if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
139
return true; // Fatal error if flag is set!
141
{ // Print purify happy
142
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
146
We can't yet set item to *arg as fix_fields may change *arg
147
We shouldn't call fix_fields() twice, so check 'fixed' field first
149
if ((!(*arg)->fixed && (*arg)->fix_fields(session, arg)))
153
if (allowed_arg_cols)
155
if (item->check_cols(allowed_arg_cols))
160
/* we have to fetch allowed_arg_cols from first argument */
161
assert(arg == args); // it is first argument
162
allowed_arg_cols= item->cols();
163
assert(allowed_arg_cols); // Can't be 0 any more
166
if (item->maybe_null)
169
with_sum_func= with_sum_func || item->with_sum_func;
170
used_tables_cache|= item->used_tables();
171
not_null_tables_cache|= item->not_null_tables();
172
const_item_cache&= item->const_item();
173
with_subselect|= item->with_subselect;
176
fix_length_and_dec();
177
if (session->is_error()) // An error inside fix_length_and_dec occured
180
session->session_marker= save_session_marker;
185
void Item_func::fix_after_pullout(Select_Lex *new_parent,
188
Item **arg,**arg_end;
190
used_tables_cache= not_null_tables_cache= 0;
195
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
197
(*arg)->fix_after_pullout(new_parent, arg);
200
used_tables_cache|= item->used_tables();
201
not_null_tables_cache|= item->not_null_tables();
202
const_item_cache&= item->const_item();
208
bool Item_func::walk(Item_processor processor, bool walk_subquery,
209
unsigned char *argument)
213
Item **arg,**arg_end;
214
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
216
if ((*arg)->walk(processor, walk_subquery, argument))
220
return (this->*processor)(argument);
223
void Item_func::traverse_cond(Cond_traverser traverser,
224
void *argument, traverse_order order)
228
Item **arg,**arg_end;
232
(*traverser)(this, argument);
233
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
235
(*arg)->traverse_cond(traverser, argument, order);
239
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
241
(*arg)->traverse_cond(traverser, argument, order);
243
(*traverser)(this, argument);
247
(*traverser)(this, argument);
252
Transform an Item_func object with a transformer callback function.
254
The function recursively applies the transform method to each
255
argument of the Item_func node.
256
If the call of the method for an argument item returns a new item
257
the old item is substituted for a new one.
258
After this the transformer is applied to the root node
259
of the Item_func object.
260
@param transformer the transformer callback function to be applied to
261
the nodes of the tree of the object
262
@param argument parameter to be passed to the transformer
265
Item returned as the result of transformation of the root node
268
Item *Item_func::transform(Item_transformer transformer, unsigned char *argument)
272
Item **arg,**arg_end;
273
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
275
Item *new_item= (*arg)->transform(transformer, argument);
280
Session::change_item_tree() should be called only if the tree was
281
really transformed, i.e. when a new item has been created.
282
Otherwise we'll be allocating a lot of unnecessary memory for
283
change records at each execution.
285
if (*arg != new_item)
286
getSession().change_item_tree(arg, new_item);
289
return (this->*transformer)(argument);
294
Compile Item_func object with a processor and a transformer
297
First the function applies the analyzer to the root node of
298
the Item_func object. Then if the analizer succeeeds (returns true)
299
the function recursively applies the compile method to each argument
300
of the Item_func node.
301
If the call of the method for an argument item returns a new item
302
the old item is substituted for a new one.
303
After this the transformer is applied to the root node
304
of the Item_func object.
306
@param analyzer the analyzer callback function to be applied to the
307
nodes of the tree of the object
308
@param[in,out] arg_p parameter to be passed to the processor
309
@param transformer the transformer callback function to be applied to the
310
nodes of the tree of the object
311
@param arg_t parameter to be passed to the transformer
314
Item returned as the result of transformation of the root node
317
Item *Item_func::compile(Item_analyzer analyzer, unsigned char **arg_p,
318
Item_transformer transformer, unsigned char *arg_t)
320
if (!(this->*analyzer)(arg_p))
324
Item **arg,**arg_end;
325
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
328
The same parameter value of arg_p must be passed
329
to analyze any argument of the condition formula.
331
unsigned char *arg_v= *arg_p;
332
Item *new_item= (*arg)->compile(analyzer, &arg_v, transformer, arg_t);
333
if (new_item && *arg != new_item)
334
current_session->change_item_tree(arg, new_item);
337
return (this->*transformer)(arg_t);
341
See comments in Item_cmp_func::split_sum_func()
344
void Item_func::split_sum_func(Session *session, Item **ref_pointer_array,
347
Item **arg, **arg_end;
348
for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
349
(*arg)->split_sum_func(session, ref_pointer_array, fields, arg, true);
353
void Item_func::update_used_tables()
357
for (uint32_t i=0 ; i < arg_count ; i++)
359
args[i]->update_used_tables();
360
used_tables_cache|=args[i]->used_tables();
361
const_item_cache&=args[i]->const_item();
366
table_map Item_func::used_tables() const
368
return used_tables_cache;
372
table_map Item_func::not_null_tables() const
374
return not_null_tables_cache;
378
void Item_func::print(String *str, enum_query_type query_type)
380
str->append(func_name());
382
print_args(str, 0, query_type);
387
void Item_func::print_args(String *str, uint32_t from, enum_query_type query_type)
389
for (uint32_t i=from ; i < arg_count ; i++)
393
args[i]->print(str, query_type);
398
void Item_func::print_op(String *str, enum_query_type query_type)
401
for (uint32_t i=0 ; i < arg_count-1 ; i++)
403
args[i]->print(str, query_type);
405
str->append(func_name());
408
args[arg_count-1]->print(str, query_type);
413
bool Item_func::eq(const Item *item, bool binary_cmp) const
415
/* Assume we don't have rtti */
418
if (item->type() != FUNC_ITEM)
420
Item_func *item_func=(Item_func*) item;
421
Item_func::Functype func_type;
422
if ((func_type= functype()) != item_func->functype() ||
423
arg_count != item_func->arg_count ||
424
(func_type != Item_func::FUNC_SP &&
425
func_name() != item_func->func_name()) ||
426
(func_type == Item_func::FUNC_SP &&
427
my_strcasecmp(system_charset_info, func_name(), item_func->func_name())))
429
for (uint32_t i=0; i < arg_count ; i++)
430
if (!args[i]->eq(item_func->args[i], binary_cmp))
436
bool Item_func::get_arg0_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date)
438
return (null_value=args[0]->get_date(ltime, fuzzy_date));
442
bool Item_func::get_arg0_time(DRIZZLE_TIME *ltime)
444
return (null_value=args[0]->get_time(ltime));
448
bool Item_func::is_null()
455
Field *Item_func::tmp_table_field(Table *table)
459
switch (result_type()) {
461
if (max_length > MY_INT32_NUM_DECIMAL_DIGITS)
462
field= new field::Int64(max_length, maybe_null, name, unsigned_flag);
464
field= new field::Int32(max_length, maybe_null, name, unsigned_flag);
468
field= new Field_double(max_length, maybe_null, name, decimals);
472
return make_string_field(table);
475
field= new Field_decimal(my_decimal_precision_to_length(decimal_precision(),
484
// This case should never be chosen
496
my_decimal *Item_func::val_decimal(my_decimal *decimal_value)
499
int2my_decimal(E_DEC_FATAL_ERROR, val_int(), unsigned_flag, decimal_value);
500
return decimal_value;
504
bool Item_func::agg_arg_collations(DTCollation &c, Item **items,
505
uint32_t nitems, uint32_t flags)
507
return agg_item_collations(c, func_name(), items, nitems, flags, 1);
511
bool Item_func::agg_arg_collations_for_comparison(DTCollation &c,
516
return agg_item_collations_for_comparison(c, func_name(),
517
items, nitems, flags);
521
bool Item_func::agg_arg_charsets(DTCollation &c, Item **items, uint32_t nitems,
522
uint32_t flags, int item_sep)
524
return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep);
528
double Item_func::fix_result(double value)
530
static double fix_infinity= numeric_limits<double>::infinity();
532
if (value != fix_infinity && value != -fix_infinity)
539
void Item_func::fix_num_length_and_dec()
541
uint32_t fl_length= 0;
543
for (uint32_t i=0 ; i < arg_count ; i++)
545
set_if_bigger(decimals,args[i]->decimals);
546
set_if_bigger(fl_length, args[i]->max_length);
548
max_length=float_length(decimals);
549
if (fl_length > max_length)
551
decimals= NOT_FIXED_DEC;
552
max_length= float_length(NOT_FIXED_DEC);
557
Set max_length/decimals of function if function is fixed point and
558
result length/precision depends on argument ones.
561
void Item_func::count_decimal_length()
566
for (uint32_t i= 0 ; i < arg_count ; i++)
568
set_if_bigger(decimals, args[i]->decimals);
569
set_if_bigger(max_int_part, args[i]->decimal_int_part());
570
set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
572
int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
573
max_length= my_decimal_precision_to_length(precision, decimals,
579
Set max_length of if it is maximum length of its arguments.
582
void Item_func::count_only_length()
586
for (uint32_t i=0 ; i < arg_count ; i++)
588
set_if_bigger(max_length, args[i]->max_length);
589
set_if_bigger(unsigned_flag, args[i]->unsigned_flag);
595
Set max_length/decimals of function if function is floating point and
596
result length/precision depends on argument ones.
599
void Item_func::count_real_length()
604
for (uint32_t i=0 ; i < arg_count ; i++)
606
if (decimals != NOT_FIXED_DEC)
608
set_if_bigger(decimals, args[i]->decimals);
609
set_if_bigger(length, (args[i]->max_length - args[i]->decimals));
611
set_if_bigger(max_length, args[i]->max_length);
613
if (decimals != NOT_FIXED_DEC)
617
if (length < max_length) // If previous operation gave overflow
618
max_length= UINT32_MAX;
626
void Item_func::signal_divide_by_null()
628
my_error(ER_DIVISION_BY_ZERO, MYF(0));
633
Item *Item_func::get_tmp_table_item(Session *session)
635
if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
636
return new Item_field(result_field);
637
return copy_or_same(session);
641
} /* namespace drizzled */