00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <drizzled/check_stack_overrun.h>
00023 #include <drizzled/current_session.h>
00024 #include <drizzled/error.h>
00025 #include <drizzled/field/decimal.h>
00026 #include <drizzled/field/double.h>
00027 #include <drizzled/field/int32.h>
00028 #include <drizzled/field/int64.h>
00029 #include <drizzled/field/size.h>
00030 #include <drizzled/function/math/int.h>
00031 #include <drizzled/item/field.h>
00032 #include <drizzled/session.h>
00033 #include <drizzled/sql_list.h>
00034 #include <drizzled/sql_string.h>
00035
00036 #include <limits>
00037 #include <algorithm>
00038
00039 using namespace std;
00040
00041 namespace drizzled
00042 {
00043
00044
00045 Item_func::Item_func(void):
00046 allowed_arg_cols(1), arg_count(0),
00047 const_item_cache(false)
00048 {
00049 with_sum_func= 0;
00050 collation.set(DERIVATION_SYSCONST);
00051 }
00052
00053 Item_func::Item_func(Item *a):
00054 allowed_arg_cols(1), arg_count(1),
00055 const_item_cache(false)
00056 {
00057 args= tmp_arg;
00058 args[0]= a;
00059 with_sum_func= a->with_sum_func;
00060 collation.set(DERIVATION_SYSCONST);
00061 }
00062
00063 Item_func::Item_func(Item *a,Item *b):
00064 allowed_arg_cols(1), arg_count(2),
00065 const_item_cache(false)
00066 {
00067 args= tmp_arg;
00068 args[0]= a; args[1]= b;
00069 with_sum_func= a->with_sum_func || b->with_sum_func;
00070 collation.set(DERIVATION_SYSCONST);
00071 }
00072
00073 Item_func::Item_func(Item *a,Item *b,Item *c):
00074 allowed_arg_cols(1),
00075 const_item_cache(false)
00076 {
00077 arg_count= 0;
00078 if ((args= (Item**) memory::sql_alloc(sizeof(Item*)*3)))
00079 {
00080 arg_count= 3;
00081 args[0]= a; args[1]= b; args[2]= c;
00082 with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func;
00083 }
00084 collation.set(DERIVATION_SYSCONST);
00085 }
00086
00087 Item_func::Item_func(Item *a,Item *b,Item *c,Item *d):
00088 allowed_arg_cols(1),
00089 const_item_cache(false)
00090 {
00091 arg_count= 0;
00092 if ((args= (Item**) memory::sql_alloc(sizeof(Item*)*4)))
00093 {
00094 arg_count= 4;
00095 args[0]= a; args[1]= b; args[2]= c; args[3]= d;
00096 with_sum_func= a->with_sum_func || b->with_sum_func ||
00097 c->with_sum_func || d->with_sum_func;
00098 }
00099 collation.set(DERIVATION_SYSCONST);
00100 }
00101
00102 Item_func::Item_func(Item *a,Item *b,Item *c,Item *d,Item* e):
00103 allowed_arg_cols(1),
00104 const_item_cache(false)
00105 {
00106 arg_count= 5;
00107 if ((args= (Item**) memory::sql_alloc(sizeof(Item*)*5)))
00108 {
00109 args[0]= a; args[1]= b; args[2]= c; args[3]= d; args[4]= e;
00110 with_sum_func= a->with_sum_func || b->with_sum_func ||
00111 c->with_sum_func || d->with_sum_func || e->with_sum_func ;
00112 }
00113 collation.set(DERIVATION_SYSCONST);
00114 }
00115
00116
00117 void Item_func::set_arguments(List<Item> &list)
00118 {
00119 allowed_arg_cols= 1;
00120 arg_count=list.size();
00121 args= tmp_arg;
00122 if (arg_count <= 2 || (args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
00123 {
00124 List<Item>::iterator li(list.begin());
00125 Item **save_args= args;
00126
00127 while (Item* item=li++)
00128 {
00129 *(save_args++)= item;
00130 with_sum_func|=item->with_sum_func;
00131 }
00132 }
00133 list.clear();
00134 }
00135
00136 Item_func::Item_func(List<Item> &list) :
00137 allowed_arg_cols(1),
00138 const_item_cache(false)
00139 {
00140 collation.set(DERIVATION_SYSCONST);
00141 set_arguments(list);
00142 }
00143
00144 Item_func::Item_func(Session *session, Item_func *item) :
00145 Item_result_field(session, item),
00146 allowed_arg_cols(item->allowed_arg_cols),
00147 arg_count(item->arg_count),
00148 used_tables_cache(item->used_tables_cache),
00149 not_null_tables_cache(item->not_null_tables_cache),
00150 const_item_cache(item->const_item_cache)
00151 {
00152 if (arg_count)
00153 {
00154 if (arg_count <=2)
00155 args= tmp_arg;
00156 else
00157 {
00158 args= new (getSession().mem) Item*[arg_count];
00159 }
00160 memcpy(args, item->args, sizeof(Item*)*arg_count);
00161 }
00162 collation.set(DERIVATION_SYSCONST);
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 bool
00200 Item_func::fix_fields(Session *session, Item **)
00201 {
00202 assert(fixed == 0);
00203 Item **arg,**arg_end;
00204 void *save_session_marker= session->session_marker;
00205 unsigned char buff[STACK_BUFF_ALLOC];
00206 session->session_marker= 0;
00207 used_tables_cache= not_null_tables_cache= 0;
00208 const_item_cache= true;
00209
00210 if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
00211 return true;
00212 if (arg_count)
00213 {
00214 for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
00215 {
00216 Item *item;
00217
00218
00219
00220
00221 if ((!(*arg)->fixed && (*arg)->fix_fields(session, arg)))
00222 return true;
00223 item= *arg;
00224
00225 if (allowed_arg_cols)
00226 {
00227 if (item->check_cols(allowed_arg_cols))
00228 return 1;
00229 }
00230 else
00231 {
00232
00233 assert(arg == args);
00234 allowed_arg_cols= item->cols();
00235 assert(allowed_arg_cols);
00236 }
00237
00238 if (item->maybe_null)
00239 maybe_null=1;
00240
00241 with_sum_func= with_sum_func || item->with_sum_func;
00242 used_tables_cache|= item->used_tables();
00243 not_null_tables_cache|= item->not_null_tables();
00244 const_item_cache&= item->const_item();
00245 with_subselect|= item->with_subselect;
00246 }
00247 }
00248 fix_length_and_dec();
00249 if (session->is_error())
00250 return true;
00251 fixed= 1;
00252 session->session_marker= save_session_marker;
00253 return false;
00254 }
00255
00256
00257 void Item_func::fix_after_pullout(Select_Lex *new_parent,
00258 Item **)
00259 {
00260 Item **arg,**arg_end;
00261
00262 used_tables_cache= not_null_tables_cache= 0;
00263 const_item_cache= false;
00264
00265 if (arg_count)
00266 {
00267 for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
00268 {
00269 (*arg)->fix_after_pullout(new_parent, arg);
00270 Item *item= *arg;
00271
00272 used_tables_cache|= item->used_tables();
00273 not_null_tables_cache|= item->not_null_tables();
00274 const_item_cache&= item->const_item();
00275 }
00276 }
00277 }
00278
00279
00280 bool Item_func::walk(Item_processor processor, bool walk_subquery,
00281 unsigned char *argument)
00282 {
00283 if (arg_count)
00284 {
00285 Item **arg,**arg_end;
00286 for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
00287 {
00288 if ((*arg)->walk(processor, walk_subquery, argument))
00289 return 1;
00290 }
00291 }
00292 return (this->*processor)(argument);
00293 }
00294
00295 void Item_func::traverse_cond(Cond_traverser traverser,
00296 void *argument, traverse_order order)
00297 {
00298 if (arg_count)
00299 {
00300 Item **arg,**arg_end;
00301
00302 switch (order) {
00303 case (T_PREFIX):
00304 (*traverser)(this, argument);
00305 for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
00306 {
00307 (*arg)->traverse_cond(traverser, argument, order);
00308 }
00309 break;
00310 case (T_POSTFIX):
00311 for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
00312 {
00313 (*arg)->traverse_cond(traverser, argument, order);
00314 }
00315 (*traverser)(this, argument);
00316 }
00317 }
00318 else
00319 (*traverser)(this, argument);
00320 }
00321
00322
00340 Item *Item_func::transform(Item_transformer transformer, unsigned char *argument)
00341 {
00342 if (arg_count)
00343 {
00344 Item **arg,**arg_end;
00345 for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
00346 {
00347 Item *new_item= (*arg)->transform(transformer, argument);
00348 if (!new_item)
00349 return 0;
00350 *arg= new_item;
00351 }
00352 }
00353 return (this->*transformer)(argument);
00354 }
00355
00356
00381 Item *Item_func::compile(Item_analyzer analyzer, unsigned char **arg_p,
00382 Item_transformer transformer, unsigned char *arg_t)
00383 {
00384 if (!(this->*analyzer)(arg_p))
00385 return 0;
00386 if (arg_count)
00387 {
00388 Item **arg,**arg_end;
00389 for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
00390 {
00391
00392
00393
00394
00395 unsigned char *arg_v= *arg_p;
00396 Item *new_item= (*arg)->compile(analyzer, &arg_v, transformer, arg_t);
00397 if (new_item && *arg != new_item)
00398 *arg= new_item;
00399 }
00400 }
00401 return (this->*transformer)(arg_t);
00402 }
00403
00408 void Item_func::split_sum_func(Session *session, Item **ref_pointer_array,
00409 List<Item> &fields)
00410 {
00411 Item **arg, **arg_end;
00412 for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
00413 (*arg)->split_sum_func(session, ref_pointer_array, fields, arg, true);
00414 }
00415
00416
00417 void Item_func::update_used_tables()
00418 {
00419 used_tables_cache=0;
00420 const_item_cache= true;
00421 for (uint32_t i=0 ; i < arg_count ; i++)
00422 {
00423 args[i]->update_used_tables();
00424 used_tables_cache|=args[i]->used_tables();
00425 const_item_cache&=args[i]->const_item();
00426 }
00427 }
00428
00429
00430 table_map Item_func::used_tables() const
00431 {
00432 return used_tables_cache;
00433 }
00434
00435
00436 table_map Item_func::not_null_tables() const
00437 {
00438 return not_null_tables_cache;
00439 }
00440
00441
00442 void Item_func::print(String *str)
00443 {
00444 str->append(func_name());
00445 str->append('(');
00446 print_args(str, 0);
00447 str->append(')');
00448 }
00449
00450
00451 void Item_func::print_args(String *str, uint32_t from)
00452 {
00453 for (uint32_t i=from ; i < arg_count ; i++)
00454 {
00455 if (i != from)
00456 str->append(',');
00457 args[i]->print(str);
00458 }
00459 }
00460
00461
00462 void Item_func::print_op(String *str)
00463 {
00464 str->append('(');
00465 for (uint32_t i=0 ; i < arg_count-1 ; i++)
00466 {
00467 args[i]->print(str);
00468 str->append(' ');
00469 str->append(func_name());
00470 str->append(' ');
00471 }
00472 args[arg_count-1]->print(str);
00473 str->append(')');
00474 }
00475
00476
00477 bool Item_func::eq(const Item *item, bool binary_cmp) const
00478 {
00479
00480 if (this == item)
00481 return 1;
00482 if (item->type() != FUNC_ITEM)
00483 return 0;
00484 Item_func *item_func=(Item_func*) item;
00485 Item_func::Functype func_type;
00486 if ((func_type= functype()) != item_func->functype() ||
00487 arg_count != item_func->arg_count ||
00488 (func_type != Item_func::FUNC_SP &&
00489 func_name() != item_func->func_name()) ||
00490 (func_type == Item_func::FUNC_SP &&
00491 system_charset_info->strcasecmp(func_name(), item_func->func_name())))
00492 return 0;
00493 for (uint32_t i=0; i < arg_count ; i++)
00494 if (!args[i]->eq(item_func->args[i], binary_cmp))
00495 return 0;
00496 return 1;
00497 }
00498
00499
00500 bool Item_func::get_arg0_date(type::Time <ime, uint32_t fuzzy_date)
00501 {
00502 return (null_value=args[0]->get_date(ltime, fuzzy_date));
00503 }
00504
00505
00506 bool Item_func::get_arg0_time(type::Time <ime)
00507 {
00508 return (null_value= args[0]->get_time(ltime));
00509 }
00510
00511
00512 bool Item_func::is_null()
00513 {
00514 update_null_value();
00515 return null_value;
00516 }
00517
00518
00519 Field *Item_func::tmp_table_field(Table *table)
00520 {
00521 Field *field= NULL;
00522
00523 switch (result_type()) {
00524 case INT_RESULT:
00525 if (unsigned_flag)
00526 {
00527 field= new field::Size(max_length, maybe_null, name, true);
00528 }
00529 else if (max_length > MY_INT32_NUM_DECIMAL_DIGITS)
00530 {
00531 field= new field::Int64(max_length, maybe_null, name, false);
00532 }
00533 else
00534 {
00535 field= new field::Int32(max_length, maybe_null, name, false);
00536 }
00537
00538 break;
00539
00540 case REAL_RESULT:
00541 field= new Field_double(max_length, maybe_null, name, decimals);
00542 break;
00543
00544 case STRING_RESULT:
00545 return make_string_field(table);
00546
00547 case DECIMAL_RESULT:
00548 field= new Field_decimal(class_decimal_precision_to_length(decimal_precision(), decimals, unsigned_flag),
00549 maybe_null, name, decimals, unsigned_flag);
00550 break;
00551 case ROW_RESULT:
00552
00553 assert(0);
00554 break;
00555 }
00556
00557 if (field)
00558 field->init(table);
00559
00560 return field;
00561 }
00562
00563
00564 type::Decimal *Item_func::val_decimal(type::Decimal *decimal_value)
00565 {
00566 assert(fixed);
00567 int2_class_decimal(E_DEC_FATAL_ERROR, val_int(), unsigned_flag, decimal_value);
00568 return decimal_value;
00569 }
00570
00571
00572 bool Item_func::agg_arg_collations(DTCollation &c, Item **items,
00573 uint32_t nitems, uint32_t flags)
00574 {
00575 return agg_item_collations(c, func_name(), items, nitems, flags, 1);
00576 }
00577
00578
00579 bool Item_func::agg_arg_collations_for_comparison(DTCollation &c,
00580 Item **items,
00581 uint32_t nitems,
00582 uint32_t flags)
00583 {
00584 return agg_item_collations_for_comparison(c, func_name(),
00585 items, nitems, flags);
00586 }
00587
00588
00589 bool Item_func::agg_arg_charsets(DTCollation &c, Item **items, uint32_t nitems,
00590 uint32_t flags, int item_sep)
00591 {
00592 return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep);
00593 }
00594
00595
00596 double Item_func::fix_result(double value)
00597 {
00598 static double fix_infinity= numeric_limits<double>::infinity();
00599
00600 if (value != fix_infinity && value != -fix_infinity)
00601 return value;
00602 null_value=1;
00603 return 0.0;
00604 }
00605
00606
00607 void Item_func::fix_num_length_and_dec()
00608 {
00609 uint32_t fl_length= 0;
00610 decimals=0;
00611 for (uint32_t i=0 ; i < arg_count ; i++)
00612 {
00613 set_if_bigger(decimals,args[i]->decimals);
00614 set_if_bigger(fl_length, args[i]->max_length);
00615 }
00616 max_length=float_length(decimals);
00617 if (fl_length > max_length)
00618 {
00619 decimals= NOT_FIXED_DEC;
00620 max_length= float_length(NOT_FIXED_DEC);
00621 }
00622 }
00623
00629 void Item_func::count_decimal_length()
00630 {
00631 int max_int_part= 0;
00632 decimals= 0;
00633 unsigned_flag= 1;
00634 for (uint32_t i= 0 ; i < arg_count ; i++)
00635 {
00636 set_if_bigger(decimals, args[i]->decimals);
00637 set_if_bigger(max_int_part, args[i]->decimal_int_part());
00638 set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
00639 }
00640 int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
00641 max_length= class_decimal_precision_to_length(precision, decimals,
00642 unsigned_flag);
00643 }
00644
00645
00650 void Item_func::count_only_length()
00651 {
00652 max_length= 0;
00653 unsigned_flag= 0;
00654 for (uint32_t i=0 ; i < arg_count ; i++)
00655 {
00656 set_if_bigger(max_length, args[i]->max_length);
00657 set_if_bigger(unsigned_flag, args[i]->unsigned_flag);
00658 }
00659 }
00660
00661
00667 void Item_func::count_real_length()
00668 {
00669 uint32_t length= 0;
00670 decimals= 0;
00671 max_length= 0;
00672 for (uint32_t i=0 ; i < arg_count ; i++)
00673 {
00674 if (decimals != NOT_FIXED_DEC)
00675 {
00676 set_if_bigger(decimals, args[i]->decimals);
00677 set_if_bigger(length, (args[i]->max_length - args[i]->decimals));
00678 }
00679 set_if_bigger(max_length, args[i]->max_length);
00680 }
00681 if (decimals != NOT_FIXED_DEC)
00682 {
00683 max_length= length;
00684 length+= decimals;
00685 if (length < max_length)
00686 max_length= UINT32_MAX;
00687 else
00688 max_length= length;
00689 }
00690 }
00691
00692
00693
00694 void Item_func::signal_divide_by_null()
00695 {
00696 my_error(ER_DIVISION_BY_ZERO, MYF(0));
00697 null_value= 0;
00698 }
00699
00700
00701 Item *Item_func::get_tmp_table_item(Session *session)
00702 {
00703 if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
00704 return new Item_field(result_field);
00705 return copy_or_same(session);
00706 }
00707
00708
00709 }