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