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/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/decimal.h>
29
#include <drizzled/field/double.h>
30
#include <drizzled/field/size.h>
31
#include <drizzled/session.h>
32
#include <drizzled/error.h>
33
#include <drizzled/check_stack_overrun.h>
43
void Item_func::set_arguments(List<Item> &list)
46
arg_count=list.elements;
47
args= tmp_arg; // If 2 arguments
48
if (arg_count <= 2 || (args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
50
List_iterator_fast<Item> li(list);
52
Item **save_args= args;
57
with_sum_func|=item->with_sum_func;
60
list.empty(); // Fields are used
63
Item_func::Item_func(List<Item> &list) :
64
_session(*current_session),
66
const_item_cache(false)
68
collation.set(DERIVATION_SYSCONST);
72
Item_func::Item_func(Session *session, Item_func *item) :
73
Item_result_field(session, item),
74
_session(*current_session),
75
allowed_arg_cols(item->allowed_arg_cols),
76
arg_count(item->arg_count),
77
used_tables_cache(item->used_tables_cache),
78
not_null_tables_cache(item->not_null_tables_cache),
79
const_item_cache(item->const_item_cache)
87
if (!(args=(Item**) session->getMemRoot()->allocate(sizeof(Item*)*arg_count)))
90
memcpy(args, item->args, sizeof(Item*)*arg_count);
92
collation.set(DERIVATION_SYSCONST);
97
Resolve references to table column for a function and its argument
101
session Thread object
102
ref Pointer to where this object is used. This reference
103
is used if we want to replace this object with another
104
one (for example in the summary functions).
107
Call fix_fields() for all arguments to the function. The main intention
108
is to allow all Item_field() objects to setup pointers to the table fields.
110
Sets as a side effect the following class variables:
111
maybe_null Set if any argument may return NULL
112
with_sum_func Set if any of the arguments contains a sum function
113
used_tables_cache Set to union of the tables used by arguments
115
str_value.charset If this is a string function, set this to the
116
character set for the first argument.
117
If any argument is binary, this is set to binary
119
If for any item any of the defaults are wrong, then this can
120
be fixed in the fix_length_and_dec() function that is called
121
after this one or by writing a specialized fix_fields() for the
126
true Got error. Stored with my_error().
130
Item_func::fix_fields(Session *session, Item **)
133
Item **arg,**arg_end;
134
void *save_session_marker= session->session_marker;
135
unsigned char buff[STACK_BUFF_ALLOC]; // Max argument in function
136
session->session_marker= 0;
137
used_tables_cache= not_null_tables_cache= 0;
138
const_item_cache= true;
140
if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
141
return true; // Fatal error if flag is set!
143
{ // Print purify happy
144
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
148
We can't yet set item to *arg as fix_fields may change *arg
149
We shouldn't call fix_fields() twice, so check 'fixed' field first
151
if ((!(*arg)->fixed && (*arg)->fix_fields(session, arg)))
155
if (allowed_arg_cols)
157
if (item->check_cols(allowed_arg_cols))
162
/* we have to fetch allowed_arg_cols from first argument */
163
assert(arg == args); // it is first argument
164
allowed_arg_cols= item->cols();
165
assert(allowed_arg_cols); // Can't be 0 any more
168
if (item->maybe_null)
171
with_sum_func= with_sum_func || item->with_sum_func;
172
used_tables_cache|= item->used_tables();
173
not_null_tables_cache|= item->not_null_tables();
174
const_item_cache&= item->const_item();
175
with_subselect|= item->with_subselect;
178
fix_length_and_dec();
179
if (session->is_error()) // An error inside fix_length_and_dec occured
182
session->session_marker= save_session_marker;
187
void Item_func::fix_after_pullout(Select_Lex *new_parent,
190
Item **arg,**arg_end;
192
used_tables_cache= not_null_tables_cache= 0;
193
const_item_cache= false;
197
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
199
(*arg)->fix_after_pullout(new_parent, arg);
202
used_tables_cache|= item->used_tables();
203
not_null_tables_cache|= item->not_null_tables();
204
const_item_cache&= item->const_item();
210
bool Item_func::walk(Item_processor processor, bool walk_subquery,
211
unsigned char *argument)
215
Item **arg,**arg_end;
216
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
218
if ((*arg)->walk(processor, walk_subquery, argument))
222
return (this->*processor)(argument);
225
void Item_func::traverse_cond(Cond_traverser traverser,
226
void *argument, traverse_order order)
230
Item **arg,**arg_end;
234
(*traverser)(this, argument);
235
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
237
(*arg)->traverse_cond(traverser, argument, order);
241
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
243
(*arg)->traverse_cond(traverser, argument, order);
245
(*traverser)(this, argument);
249
(*traverser)(this, argument);
254
Transform an Item_func object with a transformer callback function.
256
The function recursively applies the transform method to each
257
argument of the Item_func node.
258
If the call of the method for an argument item returns a new item
259
the old item is substituted for a new one.
260
After this the transformer is applied to the root node
261
of the Item_func object.
262
@param transformer the transformer callback function to be applied to
263
the nodes of the tree of the object
264
@param argument parameter to be passed to the transformer
267
Item returned as the result of transformation of the root node
270
Item *Item_func::transform(Item_transformer transformer, unsigned char *argument)
274
Item **arg,**arg_end;
275
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
277
Item *new_item= (*arg)->transform(transformer, argument);
282
Session::change_item_tree() should be called only if the tree was
283
really transformed, i.e. when a new item has been created.
284
Otherwise we'll be allocating a lot of unnecessary memory for
285
change records at each execution.
287
if (*arg != new_item)
288
getSession().change_item_tree(arg, new_item);
291
return (this->*transformer)(argument);
296
Compile Item_func object with a processor and a transformer
299
First the function applies the analyzer to the root node of
300
the Item_func object. Then if the analizer succeeeds (returns true)
301
the function recursively applies the compile method to each argument
302
of the Item_func node.
303
If the call of the method for an argument item returns a new item
304
the old item is substituted for a new one.
305
After this the transformer is applied to the root node
306
of the Item_func object.
308
@param analyzer the analyzer callback function to be applied to the
309
nodes of the tree of the object
310
@param[in,out] arg_p parameter to be passed to the processor
311
@param transformer the transformer callback function to be applied to the
312
nodes of the tree of the object
313
@param arg_t parameter to be passed to the transformer
316
Item returned as the result of transformation of the root node
319
Item *Item_func::compile(Item_analyzer analyzer, unsigned char **arg_p,
320
Item_transformer transformer, unsigned char *arg_t)
322
if (!(this->*analyzer)(arg_p))
326
Item **arg,**arg_end;
327
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
330
The same parameter value of arg_p must be passed
331
to analyze any argument of the condition formula.
333
unsigned char *arg_v= *arg_p;
334
Item *new_item= (*arg)->compile(analyzer, &arg_v, transformer, arg_t);
335
if (new_item && *arg != new_item)
336
current_session->change_item_tree(arg, new_item);
339
return (this->*transformer)(arg_t);
343
See comments in Item_cmp_func::split_sum_func()
346
void Item_func::split_sum_func(Session *session, Item **ref_pointer_array,
349
Item **arg, **arg_end;
350
for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
351
(*arg)->split_sum_func(session, ref_pointer_array, fields, arg, true);
355
void Item_func::update_used_tables()
358
const_item_cache= true;
359
for (uint32_t i=0 ; i < arg_count ; i++)
361
args[i]->update_used_tables();
362
used_tables_cache|=args[i]->used_tables();
363
const_item_cache&=args[i]->const_item();
368
table_map Item_func::used_tables() const
370
return used_tables_cache;
374
table_map Item_func::not_null_tables() const
376
return not_null_tables_cache;
380
void Item_func::print(String *str, enum_query_type query_type)
382
str->append(func_name());
384
print_args(str, 0, query_type);
389
void Item_func::print_args(String *str, uint32_t from, enum_query_type query_type)
391
for (uint32_t i=from ; i < arg_count ; i++)
395
args[i]->print(str, query_type);
400
void Item_func::print_op(String *str, enum_query_type query_type)
403
for (uint32_t i=0 ; i < arg_count-1 ; i++)
405
args[i]->print(str, query_type);
407
str->append(func_name());
410
args[arg_count-1]->print(str, query_type);
415
bool Item_func::eq(const Item *item, bool binary_cmp) const
417
/* Assume we don't have rtti */
420
if (item->type() != FUNC_ITEM)
422
Item_func *item_func=(Item_func*) item;
423
Item_func::Functype func_type;
424
if ((func_type= functype()) != item_func->functype() ||
425
arg_count != item_func->arg_count ||
426
(func_type != Item_func::FUNC_SP &&
427
func_name() != item_func->func_name()) ||
428
(func_type == Item_func::FUNC_SP &&
429
my_strcasecmp(system_charset_info, func_name(), item_func->func_name())))
431
for (uint32_t i=0; i < arg_count ; i++)
432
if (!args[i]->eq(item_func->args[i], binary_cmp))
438
bool Item_func::get_arg0_date(type::Time <ime, uint32_t fuzzy_date)
440
return (null_value=args[0]->get_date(ltime, fuzzy_date));
444
bool Item_func::get_arg0_time(type::Time <ime)
446
return (null_value= args[0]->get_time(ltime));
450
bool Item_func::is_null()
457
Field *Item_func::tmp_table_field(Table *table)
461
switch (result_type()) {
465
field= new field::Size(max_length, maybe_null, name, true);
467
else if (max_length > MY_INT32_NUM_DECIMAL_DIGITS)
469
field= new field::Int64(max_length, maybe_null, name, false);
473
field= new field::Int32(max_length, maybe_null, name, false);
479
field= new Field_double(max_length, maybe_null, name, decimals);
483
return make_string_field(table);
486
field= new Field_decimal(class_decimal_precision_to_length(decimal_precision(),
495
// This case should never be chosen
507
type::Decimal *Item_func::val_decimal(type::Decimal *decimal_value)
510
int2_class_decimal(E_DEC_FATAL_ERROR, val_int(), unsigned_flag, decimal_value);
511
return decimal_value;
515
bool Item_func::agg_arg_collations(DTCollation &c, Item **items,
516
uint32_t nitems, uint32_t flags)
518
return agg_item_collations(c, func_name(), items, nitems, flags, 1);
522
bool Item_func::agg_arg_collations_for_comparison(DTCollation &c,
527
return agg_item_collations_for_comparison(c, func_name(),
528
items, nitems, flags);
532
bool Item_func::agg_arg_charsets(DTCollation &c, Item **items, uint32_t nitems,
533
uint32_t flags, int item_sep)
535
return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep);
539
double Item_func::fix_result(double value)
541
static double fix_infinity= numeric_limits<double>::infinity();
543
if (value != fix_infinity && value != -fix_infinity)
550
void Item_func::fix_num_length_and_dec()
552
uint32_t fl_length= 0;
554
for (uint32_t i=0 ; i < arg_count ; i++)
556
set_if_bigger(decimals,args[i]->decimals);
557
set_if_bigger(fl_length, args[i]->max_length);
559
max_length=float_length(decimals);
560
if (fl_length > max_length)
562
decimals= NOT_FIXED_DEC;
563
max_length= float_length(NOT_FIXED_DEC);
568
Set max_length/decimals of function if function is fixed point and
569
result length/precision depends on argument ones.
572
void Item_func::count_decimal_length()
577
for (uint32_t i= 0 ; i < arg_count ; i++)
579
set_if_bigger(decimals, args[i]->decimals);
580
set_if_bigger(max_int_part, args[i]->decimal_int_part());
581
set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
583
int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
584
max_length= class_decimal_precision_to_length(precision, decimals,
590
Set max_length of if it is maximum length of its arguments.
593
void Item_func::count_only_length()
597
for (uint32_t i=0 ; i < arg_count ; i++)
599
set_if_bigger(max_length, args[i]->max_length);
600
set_if_bigger(unsigned_flag, args[i]->unsigned_flag);
606
Set max_length/decimals of function if function is floating point and
607
result length/precision depends on argument ones.
610
void Item_func::count_real_length()
615
for (uint32_t i=0 ; i < arg_count ; i++)
617
if (decimals != NOT_FIXED_DEC)
619
set_if_bigger(decimals, args[i]->decimals);
620
set_if_bigger(length, (args[i]->max_length - args[i]->decimals));
622
set_if_bigger(max_length, args[i]->max_length);
624
if (decimals != NOT_FIXED_DEC)
628
if (length < max_length) // If previous operation gave overflow
629
max_length= UINT32_MAX;
637
void Item_func::signal_divide_by_null()
639
my_error(ER_DIVISION_BY_ZERO, MYF(0));
644
Item *Item_func::get_tmp_table_item(Session *session)
646
if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
647
return new Item_field(result_field);
648
return copy_or_same(session);
652
} /* namespace drizzled */