00001 /* Copyright (C) 2000-2003 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 00018 /* This file defines all numerical functions */ 00019 00020 #ifdef USE_PRAGMA_IMPLEMENTATION 00021 #pragma implementation // gcc: Class implementation 00022 #endif 00023 00024 #include "mysql_priv.h" 00025 #include "slave.h" // for wait_for_master_pos 00026 #include <m_ctype.h> 00027 #include <hash.h> 00028 #include <time.h> 00029 #include <ft_global.h> 00030 00031 #include "sp_head.h" 00032 #include "sp_rcontext.h" 00033 #include "sp.h" 00034 00035 #ifdef NO_EMBEDDED_ACCESS_CHECKS 00036 #define sp_restore_security_context(A,B) while (0) {} 00037 #endif 00038 00039 00040 bool check_reserved_words(LEX_STRING *name) 00041 { 00042 if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") || 00043 !my_strcasecmp(system_charset_info, name->str, "LOCAL") || 00044 !my_strcasecmp(system_charset_info, name->str, "SESSION")) 00045 return TRUE; 00046 return FALSE; 00047 } 00048 00049 00050 /* return TRUE if item is a constant */ 00051 00052 bool 00053 eval_const_cond(COND *cond) 00054 { 00055 return ((Item_func*) cond)->val_int() ? TRUE : FALSE; 00056 } 00057 00058 00059 void Item_func::set_arguments(List<Item> &list) 00060 { 00061 allowed_arg_cols= 1; 00062 arg_count=list.elements; 00063 args= tmp_arg; // If 2 arguments 00064 if (arg_count <= 2 || (args=(Item**) sql_alloc(sizeof(Item*)*arg_count))) 00065 { 00066 List_iterator_fast<Item> li(list); 00067 Item *item; 00068 Item **save_args= args; 00069 00070 while ((item=li++)) 00071 { 00072 *(save_args++)= item; 00073 with_sum_func|=item->with_sum_func; 00074 } 00075 } 00076 list.empty(); // Fields are used 00077 } 00078 00079 Item_func::Item_func(List<Item> &list) 00080 :allowed_arg_cols(1) 00081 { 00082 set_arguments(list); 00083 } 00084 00085 Item_func::Item_func(THD *thd, Item_func *item) 00086 :Item_result_field(thd, item), 00087 allowed_arg_cols(item->allowed_arg_cols), 00088 arg_count(item->arg_count), 00089 used_tables_cache(item->used_tables_cache), 00090 not_null_tables_cache(item->not_null_tables_cache), 00091 const_item_cache(item->const_item_cache) 00092 { 00093 if (arg_count) 00094 { 00095 if (arg_count <=2) 00096 args= tmp_arg; 00097 else 00098 { 00099 if (!(args=(Item**) thd->alloc(sizeof(Item*)*arg_count))) 00100 return; 00101 } 00102 memcpy((char*) args, (char*) item->args, sizeof(Item*)*arg_count); 00103 } 00104 } 00105 00106 00107 /* 00108 Resolve references to table column for a function and it's argument 00109 00110 SYNOPSIS: 00111 fix_fields() 00112 thd Thread object 00113 ref Pointer to where this object is used. This reference 00114 is used if we want to replace this object with another 00115 one (for example in the summary functions). 00116 00117 DESCRIPTION 00118 Call fix_fields() for all arguments to the function. The main intention 00119 is to allow all Item_field() objects to setup pointers to the table fields. 00120 00121 Sets as a side effect the following class variables: 00122 maybe_null Set if any argument may return NULL 00123 with_sum_func Set if any of the arguments contains a sum function 00124 used_tables_cache Set to union of the tables used by arguments 00125 00126 str_value.charset If this is a string function, set this to the 00127 character set for the first argument. 00128 If any argument is binary, this is set to binary 00129 00130 If for any item any of the defaults are wrong, then this can 00131 be fixed in the fix_length_and_dec() function that is called 00132 after this one or by writing a specialized fix_fields() for the 00133 item. 00134 00135 RETURN VALUES 00136 FALSE ok 00137 TRUE Got error. Stored with my_error(). 00138 */ 00139 00140 bool 00141 Item_func::fix_fields(THD *thd, Item **ref) 00142 { 00143 DBUG_ASSERT(fixed == 0); 00144 Item **arg,**arg_end; 00145 #ifndef EMBEDDED_LIBRARY // Avoid compiler warning 00146 char buff[STACK_BUFF_ALLOC]; // Max argument in function 00147 #endif 00148 00149 used_tables_cache= not_null_tables_cache= 0; 00150 const_item_cache=1; 00151 00152 if (check_stack_overrun(thd, STACK_MIN_SIZE, buff)) 00153 return TRUE; // Fatal error if flag is set! 00154 if (arg_count) 00155 { // Print purify happy 00156 for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) 00157 { 00158 Item *item; 00159 /* 00160 We can't yet set item to *arg as fix_fields may change *arg 00161 We shouldn't call fix_fields() twice, so check 'fixed' field first 00162 */ 00163 if ((!(*arg)->fixed && (*arg)->fix_fields(thd, arg))) 00164 return TRUE; /* purecov: inspected */ 00165 item= *arg; 00166 00167 if (allowed_arg_cols) 00168 { 00169 if (item->check_cols(allowed_arg_cols)) 00170 return 1; 00171 } 00172 else 00173 { 00174 /* we have to fetch allowed_arg_cols from first argument */ 00175 DBUG_ASSERT(arg == args); // it is first argument 00176 allowed_arg_cols= item->cols(); 00177 DBUG_ASSERT(allowed_arg_cols); // Can't be 0 any more 00178 } 00179 00180 if (item->maybe_null) 00181 maybe_null=1; 00182 00183 with_sum_func= with_sum_func || item->with_sum_func; 00184 used_tables_cache|= item->used_tables(); 00185 not_null_tables_cache|= item->not_null_tables(); 00186 const_item_cache&= item->const_item(); 00187 with_subselect|= item->with_subselect; 00188 } 00189 } 00190 fix_length_and_dec(); 00191 if (thd->net.report_error) // An error inside fix_length_and_dec occured 00192 return TRUE; 00193 fixed= 1; 00194 return FALSE; 00195 } 00196 00197 00198 bool Item_func::walk(Item_processor processor, bool walk_subquery, 00199 byte *argument) 00200 { 00201 if (arg_count) 00202 { 00203 Item **arg,**arg_end; 00204 for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++) 00205 { 00206 if ((*arg)->walk(processor, walk_subquery, argument)) 00207 return 1; 00208 } 00209 } 00210 return (this->*processor)(argument); 00211 } 00212 00213 void Item_func::traverse_cond(Cond_traverser traverser, 00214 void *argument, traverse_order order) 00215 { 00216 if (arg_count) 00217 { 00218 Item **arg,**arg_end; 00219 00220 switch (order) { 00221 case(PREFIX): 00222 (*traverser)(this, argument); 00223 for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++) 00224 { 00225 (*arg)->traverse_cond(traverser, argument, order); 00226 } 00227 break; 00228 case (POSTFIX): 00229 for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++) 00230 { 00231 (*arg)->traverse_cond(traverser, argument, order); 00232 } 00233 (*traverser)(this, argument); 00234 } 00235 } 00236 } 00237 00238 00239 00240 /* 00241 Transform an Item_func object with a transformer callback function 00242 00243 SYNOPSIS 00244 transform() 00245 transformer the transformer callback function to be applied to the nodes 00246 of the tree of the object 00247 argument parameter to be passed to the transformer 00248 00249 DESCRIPTION 00250 The function recursively applies the transform method with the 00251 same transformer to each argument the function. 00252 If the call of the method for a member item returns a new item 00253 the old item is substituted for a new one. 00254 After this the transform method is applied to the root node 00255 of the Item_func object. 00256 00257 RETURN VALUES 00258 Item returned as the result of transformation of the root node 00259 */ 00260 00261 Item *Item_func::transform(Item_transformer transformer, byte *argument) 00262 { 00263 if (arg_count) 00264 { 00265 Item **arg,**arg_end; 00266 for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++) 00267 { 00268 Item *new_item= (*arg)->transform(transformer, argument); 00269 if (!new_item) 00270 return 0; 00271 if (*arg != new_item) 00272 current_thd->change_item_tree(arg, new_item); 00273 } 00274 } 00275 return (this->*transformer)(argument); 00276 } 00277 00278 00279 /* See comments in Item_cmp_func::split_sum_func() */ 00280 00281 void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array, 00282 List<Item> &fields) 00283 { 00284 Item **arg, **arg_end; 00285 for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++) 00286 (*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg, TRUE); 00287 } 00288 00289 00290 void Item_func::update_used_tables() 00291 { 00292 used_tables_cache=0; 00293 const_item_cache=1; 00294 for (uint i=0 ; i < arg_count ; i++) 00295 { 00296 args[i]->update_used_tables(); 00297 used_tables_cache|=args[i]->used_tables(); 00298 const_item_cache&=args[i]->const_item(); 00299 } 00300 } 00301 00302 00303 table_map Item_func::used_tables() const 00304 { 00305 return used_tables_cache; 00306 } 00307 00308 00309 table_map Item_func::not_null_tables() const 00310 { 00311 return not_null_tables_cache; 00312 } 00313 00314 00315 void Item_func::print(String *str) 00316 { 00317 str->append(func_name()); 00318 str->append('('); 00319 print_args(str, 0); 00320 str->append(')'); 00321 } 00322 00323 00324 void Item_func::print_args(String *str, uint from) 00325 { 00326 for (uint i=from ; i < arg_count ; i++) 00327 { 00328 if (i != from) 00329 str->append(','); 00330 args[i]->print(str); 00331 } 00332 } 00333 00334 00335 void Item_func::print_op(String *str) 00336 { 00337 str->append('('); 00338 for (uint i=0 ; i < arg_count-1 ; i++) 00339 { 00340 args[i]->print(str); 00341 str->append(' '); 00342 str->append(func_name()); 00343 str->append(' '); 00344 } 00345 args[arg_count-1]->print(str); 00346 str->append(')'); 00347 } 00348 00349 00350 bool Item_func::eq(const Item *item, bool binary_cmp) const 00351 { 00352 /* Assume we don't have rtti */ 00353 if (this == item) 00354 return 1; 00355 if (item->type() != FUNC_ITEM) 00356 return 0; 00357 Item_func *item_func=(Item_func*) item; 00358 if (arg_count != item_func->arg_count || 00359 func_name() != item_func->func_name()) 00360 return 0; 00361 for (uint i=0; i < arg_count ; i++) 00362 if (!args[i]->eq(item_func->args[i], binary_cmp)) 00363 return 0; 00364 return 1; 00365 } 00366 00367 00368 Field *Item_func::tmp_table_field(TABLE *table) 00369 { 00370 Field *field; 00371 LINT_INIT(field); 00372 00373 switch (result_type()) { 00374 case INT_RESULT: 00375 if (max_length > 11) 00376 field= new Field_longlong(max_length, maybe_null, name, unsigned_flag); 00377 else 00378 field= new Field_long(max_length, maybe_null, name, unsigned_flag); 00379 break; 00380 case REAL_RESULT: 00381 field= new Field_double(max_length, maybe_null, name, decimals); 00382 break; 00383 case STRING_RESULT: 00384 return make_string_field(table); 00385 break; 00386 case DECIMAL_RESULT: 00387 field= new Field_new_decimal(my_decimal_precision_to_length(decimal_precision(), 00388 decimals, 00389 unsigned_flag), 00390 maybe_null, name, decimals, unsigned_flag); 00391 break; 00392 case ROW_RESULT: 00393 default: 00394 // This case should never be chosen 00395 DBUG_ASSERT(0); 00396 field= 0; 00397 break; 00398 } 00399 if (field) 00400 field->init(table); 00401 return field; 00402 } 00403 00404 00405 bool Item_func::is_expensive_processor(byte *arg) 00406 { 00407 return is_expensive(); 00408 } 00409 00410 00411 my_decimal *Item_func::val_decimal(my_decimal *decimal_value) 00412 { 00413 DBUG_ASSERT(fixed); 00414 int2my_decimal(E_DEC_FATAL_ERROR, val_int(), unsigned_flag, decimal_value); 00415 return decimal_value; 00416 } 00417 00418 00419 String *Item_real_func::val_str(String *str) 00420 { 00421 DBUG_ASSERT(fixed == 1); 00422 double nr= val_real(); 00423 if (null_value) 00424 return 0; /* purecov: inspected */ 00425 str->set_real(nr,decimals, &my_charset_bin); 00426 return str; 00427 } 00428 00429 00430 my_decimal *Item_real_func::val_decimal(my_decimal *decimal_value) 00431 { 00432 DBUG_ASSERT(fixed); 00433 double nr= val_real(); 00434 if (null_value) 00435 return 0; /* purecov: inspected */ 00436 double2my_decimal(E_DEC_FATAL_ERROR, nr, decimal_value); 00437 return decimal_value; 00438 } 00439 00440 00441 void Item_func::fix_num_length_and_dec() 00442 { 00443 uint fl_length= 0; 00444 decimals=0; 00445 for (uint i=0 ; i < arg_count ; i++) 00446 { 00447 set_if_bigger(decimals,args[i]->decimals); 00448 set_if_bigger(fl_length, args[i]->max_length); 00449 } 00450 max_length=float_length(decimals); 00451 if (fl_length > max_length) 00452 { 00453 decimals= NOT_FIXED_DEC; 00454 max_length= float_length(NOT_FIXED_DEC); 00455 } 00456 } 00457 00458 00459 void Item_func_numhybrid::fix_num_length_and_dec() 00460 {} 00461 00462 00463 /* 00464 Set max_length/decimals of function if function is fixed point and 00465 result length/precision depends on argument ones 00466 00467 SYNOPSIS 00468 Item_func::count_decimal_length() 00469 */ 00470 00471 void Item_func::count_decimal_length() 00472 { 00473 int max_int_part= 0; 00474 decimals= 0; 00475 unsigned_flag= 1; 00476 for (uint i=0 ; i < arg_count ; i++) 00477 { 00478 set_if_bigger(decimals, args[i]->decimals); 00479 set_if_bigger(max_int_part, args[i]->decimal_int_part()); 00480 set_if_smaller(unsigned_flag, args[i]->unsigned_flag); 00481 } 00482 int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION); 00483 max_length= my_decimal_precision_to_length(precision, decimals, 00484 unsigned_flag); 00485 } 00486 00487 00488 /* 00489 Set max_length of if it is maximum length of its arguments 00490 00491 SYNOPSIS 00492 Item_func::count_only_length() 00493 */ 00494 00495 void Item_func::count_only_length() 00496 { 00497 max_length= 0; 00498 unsigned_flag= 0; 00499 for (uint i=0 ; i < arg_count ; i++) 00500 { 00501 set_if_bigger(max_length, args[i]->max_length); 00502 set_if_bigger(unsigned_flag, args[i]->unsigned_flag); 00503 } 00504 } 00505 00506 00507 /* 00508 Set max_length/decimals of function if function is floating point and 00509 result length/precision depends on argument ones 00510 00511 SYNOPSIS 00512 Item_func::count_real_length() 00513 */ 00514 00515 void Item_func::count_real_length() 00516 { 00517 uint32 length= 0; 00518 decimals= 0; 00519 max_length= 0; 00520 for (uint i=0 ; i < arg_count ; i++) 00521 { 00522 if (decimals != NOT_FIXED_DEC) 00523 { 00524 set_if_bigger(decimals, args[i]->decimals); 00525 set_if_bigger(length, (args[i]->max_length - args[i]->decimals)); 00526 } 00527 set_if_bigger(max_length, args[i]->max_length); 00528 } 00529 if (decimals != NOT_FIXED_DEC) 00530 { 00531 max_length= length; 00532 length+= decimals; 00533 if (length < max_length) // If previous operation gave overflow 00534 max_length= UINT_MAX32; 00535 else 00536 max_length= length; 00537 } 00538 } 00539 00540 00541 00542 void Item_func::signal_divide_by_null() 00543 { 00544 THD *thd= current_thd; 00545 if (thd->variables.sql_mode & MODE_ERROR_FOR_DIVISION_BY_ZERO) 00546 push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DIVISION_BY_ZERO, 00547 ER(ER_DIVISION_BY_ZERO)); 00548 null_value= 1; 00549 } 00550 00551 00552 Item *Item_func::get_tmp_table_item(THD *thd) 00553 { 00554 if (!with_sum_func && !const_item()) 00555 return new Item_field(result_field); 00556 return copy_or_same(thd); 00557 } 00558 00559 String *Item_int_func::val_str(String *str) 00560 { 00561 DBUG_ASSERT(fixed == 1); 00562 longlong nr=val_int(); 00563 if (null_value) 00564 return 0; 00565 str->set_int(nr, unsigned_flag, &my_charset_bin); 00566 return str; 00567 } 00568 00569 00570 void Item_func_connection_id::fix_length_and_dec() 00571 { 00572 Item_int_func::fix_length_and_dec(); 00573 max_length= 10; 00574 } 00575 00576 00577 bool Item_func_connection_id::fix_fields(THD *thd, Item **ref) 00578 { 00579 if (Item_int_func::fix_fields(thd, ref)) 00580 return TRUE; 00581 00582 /* 00583 To replicate CONNECTION_ID() properly we should use 00584 pseudo_thread_id on slave, which contains the value of thread_id 00585 on master. 00586 */ 00587 value= ((thd->slave_thread) ? 00588 thd->variables.pseudo_thread_id : 00589 thd->thread_id); 00590 00591 return FALSE; 00592 } 00593 00594 00595 /* 00596 Check arguments here to determine result's type for a numeric 00597 function of two arguments. 00598 00599 SYNOPSIS 00600 Item_num_op::find_num_type() 00601 */ 00602 00603 void Item_num_op::find_num_type(void) 00604 { 00605 DBUG_ENTER("Item_num_op::find_num_type"); 00606 DBUG_PRINT("info", ("name %s", func_name())); 00607 DBUG_ASSERT(arg_count == 2); 00608 Item_result r0= args[0]->result_type(); 00609 Item_result r1= args[1]->result_type(); 00610 00611 if (r0 == REAL_RESULT || r1 == REAL_RESULT || 00612 r0 == STRING_RESULT || r1 ==STRING_RESULT) 00613 { 00614 count_real_length(); 00615 max_length= float_length(decimals); 00616 hybrid_type= REAL_RESULT; 00617 } 00618 else if (r0 == DECIMAL_RESULT || r1 == DECIMAL_RESULT) 00619 { 00620 hybrid_type= DECIMAL_RESULT; 00621 result_precision(); 00622 } 00623 else 00624 { 00625 DBUG_ASSERT(r0 == INT_RESULT && r1 == INT_RESULT); 00626 decimals= 0; 00627 hybrid_type=INT_RESULT; 00628 result_precision(); 00629 } 00630 DBUG_PRINT("info", ("Type: %s", 00631 (hybrid_type == REAL_RESULT ? "REAL_RESULT" : 00632 hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" : 00633 hybrid_type == INT_RESULT ? "INT_RESULT" : 00634 "--ILLEGAL!!!--"))); 00635 DBUG_VOID_RETURN; 00636 } 00637 00638 00639 /* 00640 Set result type for a numeric function of one argument 00641 (can be also used by a numeric function of many arguments, if the result 00642 type depends only on the first argument) 00643 00644 SYNOPSIS 00645 Item_func_num1::find_num_type() 00646 */ 00647 00648 void Item_func_num1::find_num_type() 00649 { 00650 DBUG_ENTER("Item_func_num1::find_num_type"); 00651 DBUG_PRINT("info", ("name %s", func_name())); 00652 switch (hybrid_type= args[0]->result_type()) { 00653 case INT_RESULT: 00654 unsigned_flag= args[0]->unsigned_flag; 00655 break; 00656 case STRING_RESULT: 00657 case REAL_RESULT: 00658 hybrid_type= REAL_RESULT; 00659 max_length= float_length(decimals); 00660 break; 00661 case DECIMAL_RESULT: 00662 break; 00663 default: 00664 DBUG_ASSERT(0); 00665 } 00666 DBUG_PRINT("info", ("Type: %s", 00667 (hybrid_type == REAL_RESULT ? "REAL_RESULT" : 00668 hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" : 00669 hybrid_type == INT_RESULT ? "INT_RESULT" : 00670 "--ILLEGAL!!!--"))); 00671 DBUG_VOID_RETURN; 00672 } 00673 00674 00675 void Item_func_num1::fix_num_length_and_dec() 00676 { 00677 decimals= args[0]->decimals; 00678 max_length= args[0]->max_length; 00679 } 00680 00681 00682 void Item_func_numhybrid::fix_length_and_dec() 00683 { 00684 fix_num_length_and_dec(); 00685 find_num_type(); 00686 } 00687 00688 00689 String *Item_func_numhybrid::val_str(String *str) 00690 { 00691 DBUG_ASSERT(fixed == 1); 00692 switch (hybrid_type) { 00693 case DECIMAL_RESULT: 00694 { 00695 my_decimal decimal_value, *val; 00696 if (!(val= decimal_op(&decimal_value))) 00697 return 0; // null is set 00698 my_decimal_round(E_DEC_FATAL_ERROR, val, decimals, FALSE, val); 00699 my_decimal2string(E_DEC_FATAL_ERROR, val, 0, 0, 0, str); 00700 break; 00701 } 00702 case INT_RESULT: 00703 { 00704 longlong nr= int_op(); 00705 if (null_value) 00706 return 0; /* purecov: inspected */ 00707 str->set_int(nr, unsigned_flag, &my_charset_bin); 00708 break; 00709 } 00710 case REAL_RESULT: 00711 { 00712 double nr= real_op(); 00713 if (null_value) 00714 return 0; /* purecov: inspected */ 00715 str->set_real(nr,decimals,&my_charset_bin); 00716 break; 00717 } 00718 case STRING_RESULT: 00719 return str_op(&str_value); 00720 default: 00721 DBUG_ASSERT(0); 00722 } 00723 return str; 00724 } 00725 00726 00727 double Item_func_numhybrid::val_real() 00728 { 00729 DBUG_ASSERT(fixed == 1); 00730 switch (hybrid_type) { 00731 case DECIMAL_RESULT: 00732 { 00733 my_decimal decimal_value, *val; 00734 double result; 00735 if (!(val= decimal_op(&decimal_value))) 00736 return 0.0; // null is set 00737 my_decimal2double(E_DEC_FATAL_ERROR, val, &result); 00738 return result; 00739 } 00740 case INT_RESULT: 00741 return (double)int_op(); 00742 case REAL_RESULT: 00743 return real_op(); 00744 case STRING_RESULT: 00745 { 00746 char *end_not_used; 00747 int err_not_used; 00748 String *res= str_op(&str_value); 00749 return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(), 00750 &end_not_used, &err_not_used) : 0.0); 00751 } 00752 default: 00753 DBUG_ASSERT(0); 00754 } 00755 return 0.0; 00756 } 00757 00758 00759 longlong Item_func_numhybrid::val_int() 00760 { 00761 DBUG_ASSERT(fixed == 1); 00762 switch (hybrid_type) { 00763 case DECIMAL_RESULT: 00764 { 00765 my_decimal decimal_value, *val; 00766 if (!(val= decimal_op(&decimal_value))) 00767 return 0; // null is set 00768 longlong result; 00769 my_decimal2int(E_DEC_FATAL_ERROR, val, unsigned_flag, &result); 00770 return result; 00771 } 00772 case INT_RESULT: 00773 return int_op(); 00774 case REAL_RESULT: 00775 return (longlong) rint(real_op()); 00776 case STRING_RESULT: 00777 { 00778 int err_not_used; 00779 String *res; 00780 if (!(res= str_op(&str_value))) 00781 return 0; 00782 00783 char *end= (char*) res->ptr() + res->length(); 00784 CHARSET_INFO *cs= str_value.charset(); 00785 return (*(cs->cset->strtoll10))(cs, res->ptr(), &end, &err_not_used); 00786 } 00787 default: 00788 DBUG_ASSERT(0); 00789 } 00790 return 0; 00791 } 00792 00793 00794 my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value) 00795 { 00796 my_decimal *val= decimal_value; 00797 DBUG_ASSERT(fixed == 1); 00798 switch (hybrid_type) { 00799 case DECIMAL_RESULT: 00800 val= decimal_op(decimal_value); 00801 break; 00802 case INT_RESULT: 00803 { 00804 longlong result= int_op(); 00805 int2my_decimal(E_DEC_FATAL_ERROR, result, unsigned_flag, decimal_value); 00806 break; 00807 } 00808 case REAL_RESULT: 00809 { 00810 double result= (double)real_op(); 00811 double2my_decimal(E_DEC_FATAL_ERROR, result, decimal_value); 00812 break; 00813 } 00814 case STRING_RESULT: 00815 { 00816 String *res; 00817 if (!(res= str_op(&str_value))) 00818 return NULL; 00819 00820 str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(), 00821 res->length(), res->charset(), decimal_value); 00822 break; 00823 } 00824 case ROW_RESULT: 00825 default: 00826 DBUG_ASSERT(0); 00827 } 00828 return val; 00829 } 00830 00831 00832 void Item_func_signed::print(String *str) 00833 { 00834 str->append(STRING_WITH_LEN("cast(")); 00835 args[0]->print(str); 00836 str->append(STRING_WITH_LEN(" as signed)")); 00837 00838 } 00839 00840 00841 longlong Item_func_signed::val_int_from_str(int *error) 00842 { 00843 char buff[MAX_FIELD_WIDTH], *end; 00844 String tmp(buff,sizeof(buff), &my_charset_bin), *res; 00845 longlong value; 00846 00847 /* 00848 For a string result, we must first get the string and then convert it 00849 to a longlong 00850 */ 00851 00852 if (!(res= args[0]->val_str(&tmp))) 00853 { 00854 null_value= 1; 00855 *error= 0; 00856 return 0; 00857 } 00858 null_value= 0; 00859 end= (char*) res->ptr()+ res->length(); 00860 value= my_strtoll10(res->ptr(), &end, error); 00861 if (*error > 0 || end != res->ptr()+ res->length()) 00862 push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, 00863 ER_TRUNCATED_WRONG_VALUE, 00864 ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER", 00865 res->c_ptr()); 00866 return value; 00867 } 00868 00869 00870 longlong Item_func_signed::val_int() 00871 { 00872 longlong value; 00873 int error; 00874 00875 if (args[0]->cast_to_int_type() != STRING_RESULT) 00876 { 00877 value= args[0]->val_int(); 00878 null_value= args[0]->null_value; 00879 return value; 00880 } 00881 00882 value= val_int_from_str(&error); 00883 if (value < 0 && error == 0) 00884 { 00885 push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, 00886 "Cast to signed converted positive out-of-range integer to " 00887 "it's negative complement"); 00888 } 00889 return value; 00890 } 00891 00892 00893 void Item_func_unsigned::print(String *str) 00894 { 00895 str->append(STRING_WITH_LEN("cast(")); 00896 args[0]->print(str); 00897 str->append(STRING_WITH_LEN(" as unsigned)")); 00898 00899 } 00900 00901 00902 longlong Item_func_unsigned::val_int() 00903 { 00904 longlong value; 00905 int error; 00906 00907 if (args[0]->cast_to_int_type() != STRING_RESULT) 00908 { 00909 value= args[0]->val_int(); 00910 null_value= args[0]->null_value; 00911 return value; 00912 } 00913 00914 value= val_int_from_str(&error); 00915 if (error < 0) 00916 push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, 00917 "Cast to unsigned converted negative integer to it's " 00918 "positive complement"); 00919 return value; 00920 } 00921 00922 00923 String *Item_decimal_typecast::val_str(String *str) 00924 { 00925 my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf); 00926 if (null_value) 00927 return NULL; 00928 my_decimal2string(E_DEC_FATAL_ERROR, &tmp_buf, 0, 0, 0, str); 00929 return str; 00930 } 00931 00932 00933 double Item_decimal_typecast::val_real() 00934 { 00935 my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf); 00936 double res; 00937 if (null_value) 00938 return 0.0; 00939 my_decimal2double(E_DEC_FATAL_ERROR, tmp, &res); 00940 return res; 00941 } 00942 00943 00944 longlong Item_decimal_typecast::val_int() 00945 { 00946 my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf); 00947 longlong res; 00948 if (null_value) 00949 return 0; 00950 my_decimal2int(E_DEC_FATAL_ERROR, tmp, unsigned_flag, &res); 00951 return res; 00952 } 00953 00954 00955 my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec) 00956 { 00957 my_decimal tmp_buf, *tmp= args[0]->val_decimal(&tmp_buf); 00958 bool sign; 00959 if ((null_value= args[0]->null_value)) 00960 return NULL; 00961 my_decimal_round(E_DEC_FATAL_ERROR, tmp, decimals, FALSE, dec); 00962 sign= dec->sign(); 00963 if (unsigned_flag) 00964 { 00965 if (sign) 00966 { 00967 my_decimal_set_zero(dec); 00968 goto err; 00969 } 00970 } 00971 if (max_length - 2 - decimals < (uint) my_decimal_intg(dec)) 00972 { 00973 max_my_decimal(dec, max_length - 2, decimals); 00974 dec->sign(sign); 00975 goto err; 00976 } 00977 return dec; 00978 00979 err: 00980 push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, 00981 ER_WARN_DATA_OUT_OF_RANGE, 00982 ER(ER_WARN_DATA_OUT_OF_RANGE), 00983 name, 1); 00984 return dec; 00985 } 00986 00987 00988 void Item_decimal_typecast::print(String *str) 00989 { 00990 str->append(STRING_WITH_LEN("cast(")); 00991 args[0]->print(str); 00992 str->append(STRING_WITH_LEN(" as decimal)")); 00993 } 00994 00995 00996 double Item_func_plus::real_op() 00997 { 00998 double value= args[0]->val_real() + args[1]->val_real(); 00999 if ((null_value=args[0]->null_value || args[1]->null_value)) 01000 return 0.0; 01001 return value; 01002 } 01003 01004 01005 longlong Item_func_plus::int_op() 01006 { 01007 longlong value=args[0]->val_int()+args[1]->val_int(); 01008 if ((null_value=args[0]->null_value || args[1]->null_value)) 01009 return 0; 01010 return value; 01011 } 01012 01013 01014 /* 01015 Calculate plus of two decimail's 01016 01017 SYNOPSIS 01018 decimal_op() 01019 decimal_value Buffer that can be used to store result 01020 01021 RETURN 01022 0 Value was NULL; In this case null_value is set 01023 # Value of operation as a decimal 01024 */ 01025 01026 my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value) 01027 { 01028 my_decimal value1, *val1; 01029 my_decimal value2, *val2; 01030 val1= args[0]->val_decimal(&value1); 01031 if ((null_value= args[0]->null_value)) 01032 return 0; 01033 val2= args[1]->val_decimal(&value2); 01034 if (!(null_value= (args[1]->null_value || 01035 (my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1, 01036 val2) > 3)))) 01037 return decimal_value; 01038 return 0; 01039 } 01040 01041 /* 01042 Set precision of results for additive operations (+ and -) 01043 01044 SYNOPSIS 01045 Item_func_additive_op::result_precision() 01046 */ 01047 void Item_func_additive_op::result_precision() 01048 { 01049 decimals= max(args[0]->decimals, args[1]->decimals); 01050 int max_int_part= max(args[0]->decimal_precision() - args[0]->decimals, 01051 args[1]->decimal_precision() - args[1]->decimals); 01052 int precision= min(max_int_part + 1 + decimals, DECIMAL_MAX_PRECISION); 01053 01054 /* Integer operations keep unsigned_flag if one of arguments is unsigned */ 01055 if (result_type() == INT_RESULT) 01056 unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag; 01057 else 01058 unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag; 01059 max_length= my_decimal_precision_to_length(precision, decimals, 01060 unsigned_flag); 01061 } 01062 01063 01064 /* 01065 The following function is here to allow the user to force 01066 subtraction of UNSIGNED BIGINT to return negative values. 01067 */ 01068 01069 void Item_func_minus::fix_length_and_dec() 01070 { 01071 Item_num_op::fix_length_and_dec(); 01072 if (unsigned_flag && 01073 (current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION)) 01074 unsigned_flag=0; 01075 } 01076 01077 01078 double Item_func_minus::real_op() 01079 { 01080 double value= args[0]->val_real() - args[1]->val_real(); 01081 if ((null_value=args[0]->null_value || args[1]->null_value)) 01082 return 0.0; 01083 return value; 01084 } 01085 01086 01087 longlong Item_func_minus::int_op() 01088 { 01089 longlong value=args[0]->val_int() - args[1]->val_int(); 01090 if ((null_value=args[0]->null_value || args[1]->null_value)) 01091 return 0; 01092 return value; 01093 } 01094 01095 01096 /* See Item_func_plus::decimal_op for comments */ 01097 01098 my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value) 01099 { 01100 my_decimal value1, *val1; 01101 my_decimal value2, *val2= 01102 01103 val1= args[0]->val_decimal(&value1); 01104 if ((null_value= args[0]->null_value)) 01105 return 0; 01106 val2= args[1]->val_decimal(&value2); 01107 if (!(null_value= (args[1]->null_value || 01108 (my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1, 01109 val2) > 3)))) 01110 return decimal_value; 01111 return 0; 01112 } 01113 01114 01115 double Item_func_mul::real_op() 01116 { 01117 DBUG_ASSERT(fixed == 1); 01118 double value= args[0]->val_real() * args[1]->val_real(); 01119 if ((null_value=args[0]->null_value || args[1]->null_value)) 01120 return 0.0; 01121 return value; 01122 } 01123 01124 01125 longlong Item_func_mul::int_op() 01126 { 01127 DBUG_ASSERT(fixed == 1); 01128 longlong value=args[0]->val_int()*args[1]->val_int(); 01129 if ((null_value=args[0]->null_value || args[1]->null_value)) 01130 return 0; 01131 return value; 01132 } 01133 01134 01135 /* See Item_func_plus::decimal_op for comments */ 01136 01137 my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value) 01138 { 01139 my_decimal value1, *val1; 01140 my_decimal value2, *val2; 01141 val1= args[0]->val_decimal(&value1); 01142 if ((null_value= args[0]->null_value)) 01143 return 0; 01144 val2= args[1]->val_decimal(&value2); 01145 if (!(null_value= (args[1]->null_value || 01146 (my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1, 01147 val2) > 3)))) 01148 return decimal_value; 01149 return 0; 01150 } 01151 01152 01153 void Item_func_mul::result_precision() 01154 { 01155 /* Integer operations keep unsigned_flag if one of arguments is unsigned */ 01156 if (result_type() == INT_RESULT) 01157 unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag; 01158 else 01159 unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag; 01160 decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE); 01161 int precision= min(args[0]->decimal_precision() + args[1]->decimal_precision(), 01162 DECIMAL_MAX_PRECISION); 01163 max_length= my_decimal_precision_to_length(precision, decimals,unsigned_flag); 01164 } 01165 01166 01167 double Item_func_div::real_op() 01168 { 01169 DBUG_ASSERT(fixed == 1); 01170 double value= args[0]->val_real(); 01171 double val2= args[1]->val_real(); 01172 if ((null_value= args[0]->null_value || args[1]->null_value)) 01173 return 0.0; 01174 if (val2 == 0.0) 01175 { 01176 signal_divide_by_null(); 01177 return 0.0; 01178 } 01179 return value/val2; 01180 } 01181 01182 01183 my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value) 01184 { 01185 my_decimal value1, *val1; 01186 my_decimal value2, *val2; 01187 int err; 01188 01189 val1= args[0]->val_decimal(&value1); 01190 if ((null_value= args[0]->null_value)) 01191 return 0; 01192 val2= args[1]->val_decimal(&value2); 01193 if ((null_value= args[1]->null_value)) 01194 return 0; 01195 if ((err= my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value, 01196 val1, val2, prec_increment)) > 3) 01197 { 01198 if (err == E_DEC_DIV_ZERO) 01199 signal_divide_by_null(); 01200 null_value= 1; 01201 return 0; 01202 } 01203 return decimal_value; 01204 } 01205 01206 01207 void Item_func_div::result_precision() 01208 { 01209 uint precision=min(args[0]->decimal_precision() + prec_increment, 01210 DECIMAL_MAX_PRECISION); 01211 /* Integer operations keep unsigned_flag if one of arguments is unsigned */ 01212 if (result_type() == INT_RESULT) 01213 unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag; 01214 else 01215 unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag; 01216 decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE); 01217 max_length= my_decimal_precision_to_length(precision, decimals, 01218 unsigned_flag); 01219 } 01220 01221 01222 void Item_func_div::fix_length_and_dec() 01223 { 01224 DBUG_ENTER("Item_func_div::fix_length_and_dec"); 01225 prec_increment= current_thd->variables.div_precincrement; 01226 Item_num_op::fix_length_and_dec(); 01227 switch(hybrid_type) { 01228 case REAL_RESULT: 01229 { 01230 decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment; 01231 set_if_smaller(decimals, NOT_FIXED_DEC); 01232 max_length=args[0]->max_length - args[0]->decimals + decimals; 01233 uint tmp=float_length(decimals); 01234 set_if_smaller(max_length,tmp); 01235 break; 01236 } 01237 case INT_RESULT: 01238 hybrid_type= DECIMAL_RESULT; 01239 DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT")); 01240 result_precision(); 01241 break; 01242 case DECIMAL_RESULT: 01243 result_precision(); 01244 break; 01245 default: 01246 DBUG_ASSERT(0); 01247 } 01248 maybe_null= 1; // devision by zero 01249 DBUG_VOID_RETURN; 01250 } 01251 01252 01253 /* Integer division */ 01254 longlong Item_func_int_div::val_int() 01255 { 01256 DBUG_ASSERT(fixed == 1); 01257 longlong value=args[0]->val_int(); 01258 longlong val2=args[1]->val_int(); 01259 if ((null_value= (args[0]->null_value || args[1]->null_value))) 01260 return 0; 01261 if (val2 == 0) 01262 { 01263 signal_divide_by_null(); 01264 return 0; 01265 } 01266 return (unsigned_flag ? 01267 (ulonglong) value / (ulonglong) val2 : 01268 value / val2); 01269 } 01270 01271 01272 void Item_func_int_div::fix_length_and_dec() 01273 { 01274 max_length=args[0]->max_length - args[0]->decimals; 01275 maybe_null=1; 01276 unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag; 01277 } 01278 01279 01280 longlong Item_func_mod::int_op() 01281 { 01282 DBUG_ASSERT(fixed == 1); 01283 longlong value= args[0]->val_int(); 01284 longlong val2= args[1]->val_int(); 01285 if ((null_value= args[0]->null_value || args[1]->null_value)) 01286 return 0; /* purecov: inspected */ 01287 if (val2 == 0) 01288 { 01289 signal_divide_by_null(); 01290 return 0; 01291 } 01292 return value % val2; 01293 } 01294 01295 double Item_func_mod::real_op() 01296 { 01297 DBUG_ASSERT(fixed == 1); 01298 double value= args[0]->val_real(); 01299 double val2= args[1]->val_real(); 01300 if ((null_value= args[0]->null_value || args[1]->null_value)) 01301 return 0.0; /* purecov: inspected */ 01302 if (val2 == 0.0) 01303 { 01304 signal_divide_by_null(); 01305 return 0.0; 01306 } 01307 return fmod(value,val2); 01308 } 01309 01310 01311 my_decimal *Item_func_mod::decimal_op(my_decimal *decimal_value) 01312 { 01313 my_decimal value1, *val1; 01314 my_decimal value2, *val2; 01315 01316 val1= args[0]->val_decimal(&value1); 01317 if ((null_value= args[0]->null_value)) 01318 return 0; 01319 val2= args[1]->val_decimal(&value2); 01320 if ((null_value= args[1]->null_value)) 01321 return 0; 01322 switch (my_decimal_mod(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value, 01323 val1, val2)) { 01324 case E_DEC_TRUNCATED: 01325 case E_DEC_OK: 01326 return decimal_value; 01327 case E_DEC_DIV_ZERO: 01328 signal_divide_by_null(); 01329 default: 01330 null_value= 1; 01331 return 0; 01332 } 01333 } 01334 01335 01336 void Item_func_mod::result_precision() 01337 { 01338 decimals= max(args[0]->decimals, args[1]->decimals); 01339 max_length= max(args[0]->max_length, args[1]->max_length); 01340 } 01341 01342 01343 double Item_func_neg::real_op() 01344 { 01345 double value= args[0]->val_real(); 01346 null_value= args[0]->null_value; 01347 return -value; 01348 } 01349 01350 01351 longlong Item_func_neg::int_op() 01352 { 01353 longlong value= args[0]->val_int(); 01354 null_value= args[0]->null_value; 01355 return -value; 01356 } 01357 01358 01359 my_decimal *Item_func_neg::decimal_op(my_decimal *decimal_value) 01360 { 01361 my_decimal val, *value= args[0]->val_decimal(&val); 01362 if (!(null_value= args[0]->null_value)) 01363 { 01364 my_decimal2decimal(value, decimal_value); 01365 my_decimal_neg(decimal_value); 01366 return decimal_value; 01367 } 01368 return 0; 01369 } 01370 01371 01372 void Item_func_neg::fix_num_length_and_dec() 01373 { 01374 decimals= args[0]->decimals; 01375 /* 1 add because sign can appear */ 01376 max_length= args[0]->max_length + 1; 01377 } 01378 01379 01380 void Item_func_neg::fix_length_and_dec() 01381 { 01382 DBUG_ENTER("Item_func_neg::fix_length_and_dec"); 01383 Item_func_num1::fix_length_and_dec(); 01384 01385 /* 01386 If this is in integer context keep the context as integer if possible 01387 (This is how multiplication and other integer functions works) 01388 Use val() to get value as arg_type doesn't mean that item is 01389 Item_int or Item_real due to existence of Item_param. 01390 */ 01391 if (hybrid_type == INT_RESULT && 01392 args[0]->type() == INT_ITEM && 01393 ((ulonglong) args[0]->val_int() >= (ulonglong) LONGLONG_MIN)) 01394 { 01395 /* 01396 Ensure that result is converted to DECIMAL, as longlong can't hold 01397 the negated number 01398 */ 01399 hybrid_type= DECIMAL_RESULT; 01400 DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT")); 01401 } 01402 unsigned_flag= 0; 01403 DBUG_VOID_RETURN; 01404 } 01405 01406 01407 double Item_func_abs::real_op() 01408 { 01409 double value= args[0]->val_real(); 01410 null_value= args[0]->null_value; 01411 return fabs(value); 01412 } 01413 01414 01415 longlong Item_func_abs::int_op() 01416 { 01417 longlong value= args[0]->val_int(); 01418 null_value= args[0]->null_value; 01419 return value >= 0 ? value : -value; 01420 } 01421 01422 01423 my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value) 01424 { 01425 my_decimal val, *value= args[0]->val_decimal(&val); 01426 if (!(null_value= args[0]->null_value)) 01427 { 01428 my_decimal2decimal(value, decimal_value); 01429 if (decimal_value->sign()) 01430 my_decimal_neg(decimal_value); 01431 return decimal_value; 01432 } 01433 return 0; 01434 } 01435 01436 01437 void Item_func_abs::fix_length_and_dec() 01438 { 01439 Item_func_num1::fix_length_and_dec(); 01440 } 01441 01442 01443 /* Gateway to natural LOG function */ 01444 double Item_func_ln::val_real() 01445 { 01446 DBUG_ASSERT(fixed == 1); 01447 double value= args[0]->val_real(); 01448 if ((null_value= args[0]->null_value)) 01449 return 0.0; 01450 if (value <= 0.0) 01451 { 01452 signal_divide_by_null(); 01453 return 0.0; 01454 } 01455 return log(value); 01456 } 01457 01458 /* 01459 Extended but so slower LOG function 01460 We have to check if all values are > zero and first one is not one 01461 as these are the cases then result is not a number. 01462 */ 01463 double Item_func_log::val_real() 01464 { 01465 DBUG_ASSERT(fixed == 1); 01466 double value= args[0]->val_real(); 01467 if ((null_value= args[0]->null_value)) 01468 return 0.0; 01469 if (value <= 0.0) 01470 { 01471 signal_divide_by_null(); 01472 return 0.0; 01473 } 01474 if (arg_count == 2) 01475 { 01476 double value2= args[1]->val_real(); 01477 if ((null_value= args[1]->null_value)) 01478 return 0.0; 01479 if (value2 <= 0.0 || value == 1.0) 01480 { 01481 signal_divide_by_null(); 01482 return 0.0; 01483 } 01484 return log(value2) / log(value); 01485 } 01486 return log(value); 01487 } 01488 01489 double Item_func_log2::val_real() 01490 { 01491 DBUG_ASSERT(fixed == 1); 01492 double value= args[0]->val_real(); 01493 01494 if ((null_value=args[0]->null_value)) 01495 return 0.0; 01496 if (value <= 0.0) 01497 { 01498 signal_divide_by_null(); 01499 return 0.0; 01500 } 01501 return log(value) / M_LN2; 01502 } 01503 01504 double Item_func_log10::val_real() 01505 { 01506 DBUG_ASSERT(fixed == 1); 01507 double value= args[0]->val_real(); 01508 if ((null_value= args[0]->null_value)) 01509 return 0.0; 01510 if (value <= 0.0) 01511 { 01512 signal_divide_by_null(); 01513 return 0.0; 01514 } 01515 return log10(value); 01516 } 01517 01518 double Item_func_exp::val_real() 01519 { 01520 DBUG_ASSERT(fixed == 1); 01521 double value= args[0]->val_real(); 01522 if ((null_value=args[0]->null_value)) 01523 return 0.0; /* purecov: inspected */ 01524 return exp(value); 01525 } 01526 01527 double Item_func_sqrt::val_real() 01528 { 01529 DBUG_ASSERT(fixed == 1); 01530 double value= args[0]->val_real(); 01531 if ((null_value=(args[0]->null_value || value < 0))) 01532 return 0.0; /* purecov: inspected */ 01533 return sqrt(value); 01534 } 01535 01536 double Item_func_pow::val_real() 01537 { 01538 DBUG_ASSERT(fixed == 1); 01539 double value= args[0]->val_real(); 01540 double val2= args[1]->val_real(); 01541 if ((null_value=(args[0]->null_value || args[1]->null_value))) 01542 return 0.0; /* purecov: inspected */ 01543 return pow(value,val2); 01544 } 01545 01546 // Trigonometric functions 01547 01548 double Item_func_acos::val_real() 01549 { 01550 DBUG_ASSERT(fixed == 1); 01551 // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug) 01552 volatile double value= args[0]->val_real(); 01553 if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0)))) 01554 return 0.0; 01555 return fix_result(acos(value)); 01556 } 01557 01558 double Item_func_asin::val_real() 01559 { 01560 DBUG_ASSERT(fixed == 1); 01561 // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug) 01562 volatile double value= args[0]->val_real(); 01563 if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0)))) 01564 return 0.0; 01565 return fix_result(asin(value)); 01566 } 01567 01568 double Item_func_atan::val_real() 01569 { 01570 DBUG_ASSERT(fixed == 1); 01571 double value= args[0]->val_real(); 01572 if ((null_value=args[0]->null_value)) 01573 return 0.0; 01574 if (arg_count == 2) 01575 { 01576 double val2= args[1]->val_real(); 01577 if ((null_value=args[1]->null_value)) 01578 return 0.0; 01579 return fix_result(atan2(value,val2)); 01580 } 01581 return fix_result(atan(value)); 01582 } 01583 01584 double Item_func_cos::val_real() 01585 { 01586 DBUG_ASSERT(fixed == 1); 01587 double value= args[0]->val_real(); 01588 if ((null_value=args[0]->null_value)) 01589 return 0.0; 01590 return fix_result(cos(value)); 01591 } 01592 01593 double Item_func_sin::val_real() 01594 { 01595 DBUG_ASSERT(fixed == 1); 01596 double value= args[0]->val_real(); 01597 if ((null_value=args[0]->null_value)) 01598 return 0.0; 01599 return fix_result(sin(value)); 01600 } 01601 01602 double Item_func_tan::val_real() 01603 { 01604 DBUG_ASSERT(fixed == 1); 01605 double value= args[0]->val_real(); 01606 if ((null_value=args[0]->null_value)) 01607 return 0.0; 01608 return fix_result(tan(value)); 01609 } 01610 01611 01612 // Shift-functions, same as << and >> in C/C++ 01613 01614 01615 longlong Item_func_shift_left::val_int() 01616 { 01617 DBUG_ASSERT(fixed == 1); 01618 uint shift; 01619 ulonglong res= ((ulonglong) args[0]->val_int() << 01620 (shift=(uint) args[1]->val_int())); 01621 if (args[0]->null_value || args[1]->null_value) 01622 { 01623 null_value=1; 01624 return 0; 01625 } 01626 null_value=0; 01627 return (shift < sizeof(longlong)*8 ? (longlong) res : LL(0)); 01628 } 01629 01630 longlong Item_func_shift_right::val_int() 01631 { 01632 DBUG_ASSERT(fixed == 1); 01633 uint shift; 01634 ulonglong res= (ulonglong) args[0]->val_int() >> 01635 (shift=(uint) args[1]->val_int()); 01636 if (args[0]->null_value || args[1]->null_value) 01637 { 01638 null_value=1; 01639 return 0; 01640 } 01641 null_value=0; 01642 return (shift < sizeof(longlong)*8 ? (longlong) res : LL(0)); 01643 } 01644 01645 01646 longlong Item_func_bit_neg::val_int() 01647 { 01648 DBUG_ASSERT(fixed == 1); 01649 ulonglong res= (ulonglong) args[0]->val_int(); 01650 if ((null_value=args[0]->null_value)) 01651 return 0; 01652 return ~res; 01653 } 01654 01655 01656 // Conversion functions 01657 01658 void Item_func_integer::fix_length_and_dec() 01659 { 01660 max_length=args[0]->max_length - args[0]->decimals+1; 01661 uint tmp=float_length(decimals); 01662 set_if_smaller(max_length,tmp); 01663 decimals=0; 01664 } 01665 01666 void Item_func_int_val::fix_num_length_and_dec() 01667 { 01668 max_length= args[0]->max_length - (args[0]->decimals ? 01669 args[0]->decimals + 1 : 01670 0) + 2; 01671 uint tmp= float_length(decimals); 01672 set_if_smaller(max_length,tmp); 01673 decimals= 0; 01674 } 01675 01676 01677 void Item_func_int_val::find_num_type() 01678 { 01679 DBUG_ENTER("Item_func_int_val::find_num_type"); 01680 DBUG_PRINT("info", ("name %s", func_name())); 01681 switch(hybrid_type= args[0]->result_type()) 01682 { 01683 case STRING_RESULT: 01684 case REAL_RESULT: 01685 hybrid_type= REAL_RESULT; 01686 max_length= float_length(decimals); 01687 break; 01688 case INT_RESULT: 01689 case DECIMAL_RESULT: 01690 /* 01691 -2 because in most high position can't be used any digit for longlong 01692 and one position for increasing value during operation 01693 */ 01694 if ((args[0]->max_length - args[0]->decimals) >= 01695 (DECIMAL_LONGLONG_DIGITS - 2)) 01696 { 01697 hybrid_type= DECIMAL_RESULT; 01698 } 01699 else 01700 { 01701 unsigned_flag= args[0]->unsigned_flag; 01702 hybrid_type= INT_RESULT; 01703 } 01704 break; 01705 default: 01706 DBUG_ASSERT(0); 01707 } 01708 DBUG_PRINT("info", ("Type: %s", 01709 (hybrid_type == REAL_RESULT ? "REAL_RESULT" : 01710 hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" : 01711 hybrid_type == INT_RESULT ? "INT_RESULT" : 01712 "--ILLEGAL!!!--"))); 01713 01714 DBUG_VOID_RETURN; 01715 } 01716 01717 01718 longlong Item_func_ceiling::int_op() 01719 { 01720 longlong result; 01721 switch (args[0]->result_type()) { 01722 case INT_RESULT: 01723 result= args[0]->val_int(); 01724 null_value= args[0]->null_value; 01725 break; 01726 case DECIMAL_RESULT: 01727 { 01728 my_decimal dec_buf, *dec; 01729 if ((dec= Item_func_ceiling::decimal_op(&dec_buf))) 01730 my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result); 01731 else 01732 result= 0; 01733 break; 01734 } 01735 default: 01736 result= (longlong)Item_func_ceiling::real_op(); 01737 }; 01738 return result; 01739 } 01740 01741 01742 double Item_func_ceiling::real_op() 01743 { 01744 /* 01745 the volatile's for BUG #3051 to calm optimizer down (because of gcc's 01746 bug) 01747 */ 01748 volatile double value= args[0]->val_real(); 01749 null_value= args[0]->null_value; 01750 return ceil(value); 01751 } 01752 01753 01754 my_decimal *Item_func_ceiling::decimal_op(my_decimal *decimal_value) 01755 { 01756 my_decimal val, *value= args[0]->val_decimal(&val); 01757 if (!(null_value= (args[0]->null_value || 01758 my_decimal_ceiling(E_DEC_FATAL_ERROR, value, 01759 decimal_value) > 1))) 01760 return decimal_value; 01761 return 0; 01762 } 01763 01764 01765 longlong Item_func_floor::int_op() 01766 { 01767 longlong result; 01768 switch (args[0]->result_type()) { 01769 case INT_RESULT: 01770 result= args[0]->val_int(); 01771 null_value= args[0]->null_value; 01772 break; 01773 case DECIMAL_RESULT: 01774 { 01775 my_decimal dec_buf, *dec; 01776 if ((dec= Item_func_floor::decimal_op(&dec_buf))) 01777 my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result); 01778 else 01779 result= 0; 01780 break; 01781 } 01782 default: 01783 result= (longlong)Item_func_floor::real_op(); 01784 }; 01785 return result; 01786 } 01787 01788 01789 double Item_func_floor::real_op() 01790 { 01791 /* 01792 the volatile's for BUG #3051 to calm optimizer down (because of gcc's 01793 bug) 01794 */ 01795 volatile double value= args[0]->val_real(); 01796 null_value= args[0]->null_value; 01797 return floor(value); 01798 } 01799 01800 01801 my_decimal *Item_func_floor::decimal_op(my_decimal *decimal_value) 01802 { 01803 my_decimal val, *value= args[0]->val_decimal(&val); 01804 if (!(null_value= (args[0]->null_value || 01805 my_decimal_floor(E_DEC_FATAL_ERROR, value, 01806 decimal_value) > 1))) 01807 return decimal_value; 01808 return 0; 01809 } 01810 01811 01812 void Item_func_round::fix_length_and_dec() 01813 { 01814 unsigned_flag= args[0]->unsigned_flag; 01815 if (!args[1]->const_item()) 01816 { 01817 max_length= args[0]->max_length; 01818 decimals= args[0]->decimals; 01819 hybrid_type= REAL_RESULT; 01820 return; 01821 } 01822 01823 int decimals_to_set= max((int)args[1]->val_int(), 0); 01824 if (args[0]->decimals == NOT_FIXED_DEC) 01825 { 01826 max_length= args[0]->max_length; 01827 decimals= min(decimals_to_set, NOT_FIXED_DEC); 01828 hybrid_type= REAL_RESULT; 01829 return; 01830 } 01831 01832 switch (args[0]->result_type()) { 01833 case REAL_RESULT: 01834 case STRING_RESULT: 01835 hybrid_type= REAL_RESULT; 01836 decimals= min(decimals_to_set, NOT_FIXED_DEC); 01837 max_length= float_length(decimals); 01838 break; 01839 case INT_RESULT: 01840 if (!decimals_to_set && 01841 (truncate || (args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS))) 01842 { 01843 int length_can_increase= test(!truncate && (args[1]->val_int() < 0)); 01844 max_length= args[0]->max_length + length_can_increase; 01845 /* Here we can keep INT_RESULT */ 01846 hybrid_type= INT_RESULT; 01847 decimals= 0; 01848 break; 01849 } 01850 /* fall through */ 01851 case DECIMAL_RESULT: 01852 { 01853 hybrid_type= DECIMAL_RESULT; 01854 int decimals_delta= args[0]->decimals - decimals_to_set; 01855 int precision= args[0]->decimal_precision(); 01856 int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1; 01857 01858 precision-= decimals_delta - length_increase; 01859 decimals= decimals_to_set; 01860 max_length= my_decimal_precision_to_length(precision, decimals, 01861 unsigned_flag); 01862 break; 01863 } 01864 default: 01865 DBUG_ASSERT(0); /* This result type isn't handled */ 01866 } 01867 } 01868 01869 double my_double_round(double value, int dec, bool truncate) 01870 { 01871 double tmp; 01872 uint abs_dec= abs(dec); 01873 /* 01874 tmp2 is here to avoid return the value with 80 bit precision 01875 This will fix that the test round(0.1,1) = round(0.1,1) is true 01876 */ 01877 volatile double tmp2; 01878 01879 tmp=(abs_dec < array_elements(log_10) ? 01880 log_10[abs_dec] : pow(10.0,(double) abs_dec)); 01881 01882 if (truncate) 01883 { 01884 if (value >= 0) 01885 tmp2= dec < 0 ? floor(value/tmp)*tmp : floor(value*tmp)/tmp; 01886 else 01887 tmp2= dec < 0 ? ceil(value/tmp)*tmp : ceil(value*tmp)/tmp; 01888 } 01889 else 01890 tmp2=dec < 0 ? rint(value/tmp)*tmp : rint(value*tmp)/tmp; 01891 return tmp2; 01892 } 01893 01894 01895 double Item_func_round::real_op() 01896 { 01897 double value= args[0]->val_real(); 01898 int dec= (int) args[1]->val_int(); 01899 01900 if (!(null_value= args[0]->null_value || args[1]->null_value)) 01901 return my_double_round(value, dec, truncate); 01902 01903 return 0.0; 01904 } 01905 01906 01907 longlong Item_func_round::int_op() 01908 { 01909 longlong value= args[0]->val_int(); 01910 int dec=(int) args[1]->val_int(); 01911 decimals= 0; 01912 uint abs_dec; 01913 if ((null_value= args[0]->null_value || args[1]->null_value)) 01914 return 0; 01915 if (dec >= 0) 01916 return value; // integer have not digits after point 01917 01918 abs_dec= -dec; 01919 longlong tmp; 01920 01921 if(abs_dec >= array_elements(log_10_int)) 01922 return 0; 01923 01924 tmp= log_10_int[abs_dec]; 01925 01926 if (truncate) 01927 { 01928 if (unsigned_flag) 01929 value= (ulonglong(value)/tmp)*tmp; 01930 else 01931 value= (value/tmp)*tmp; 01932 } 01933 else 01934 { 01935 if (unsigned_flag) 01936 value= ((ulonglong(value)+(tmp>>1))/tmp)*tmp; 01937 else if ( value >= 0) 01938 value= ((value+(tmp>>1))/tmp)*tmp; 01939 else 01940 value= ((value-(tmp>>1))/tmp)*tmp; 01941 } 01942 return value; 01943 } 01944 01945 01946 my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value) 01947 { 01948 my_decimal val, *value= args[0]->val_decimal(&val); 01949 int dec=(int) args[1]->val_int(); 01950 if (dec > 0) 01951 { 01952 decimals= min(dec, DECIMAL_MAX_SCALE); // to get correct output 01953 } 01954 if (!(null_value= (args[0]->null_value || args[1]->null_value || 01955 my_decimal_round(E_DEC_FATAL_ERROR, value, dec, truncate, 01956 decimal_value) > 1))) 01957 return decimal_value; 01958 return 0; 01959 } 01960 01961 01962 bool Item_func_rand::fix_fields(THD *thd,Item **ref) 01963 { 01964 if (Item_real_func::fix_fields(thd, ref)) 01965 return TRUE; 01966 used_tables_cache|= RAND_TABLE_BIT; 01967 if (arg_count) 01968 { // Only use argument once in query 01969 if (!args[0]->const_during_execution()) 01970 { 01971 my_error(ER_WRONG_ARGUMENTS, MYF(0), "RAND"); 01972 return TRUE; 01973 } 01974 /* 01975 Allocate rand structure once: we must use thd->stmt_arena 01976 to create rand in proper mem_root if it's a prepared statement or 01977 stored procedure. 01978 01979 No need to send a Rand log event if seed was given eg: RAND(seed), 01980 as it will be replicated in the query as such. 01981 */ 01982 if (!rand && !(rand= (struct rand_struct*) 01983 thd->stmt_arena->alloc(sizeof(*rand)))) 01984 return TRUE; 01985 /* 01986 PARAM_ITEM is returned if we're in statement prepare and consequently 01987 no placeholder value is set yet. 01988 */ 01989 if (args[0]->type() != PARAM_ITEM) 01990 { 01991 /* 01992 TODO: do not do reinit 'rand' for every execute of PS/SP if 01993 args[0] is a constant. 01994 */ 01995 uint32 tmp= (uint32) args[0]->val_int(); 01996 randominit(rand, (uint32) (tmp*0x10001L+55555555L), 01997 (uint32) (tmp*0x10000001L)); 01998 } 01999 } 02000 else 02001 { 02002 /* 02003 Save the seed only the first time RAND() is used in the query 02004 Once events are forwarded rather than recreated, 02005 the following can be skipped if inside the slave thread 02006 */ 02007 if (!thd->rand_used) 02008 { 02009 thd->rand_used= 1; 02010 thd->rand_saved_seed1= thd->rand.seed1; 02011 thd->rand_saved_seed2= thd->rand.seed2; 02012 } 02013 rand= &thd->rand; 02014 } 02015 return FALSE; 02016 } 02017 02018 void Item_func_rand::update_used_tables() 02019 { 02020 Item_real_func::update_used_tables(); 02021 used_tables_cache|= RAND_TABLE_BIT; 02022 } 02023 02024 02025 double Item_func_rand::val_real() 02026 { 02027 DBUG_ASSERT(fixed == 1); 02028 return my_rnd(rand); 02029 } 02030 02031 longlong Item_func_sign::val_int() 02032 { 02033 DBUG_ASSERT(fixed == 1); 02034 double value= args[0]->val_real(); 02035 null_value=args[0]->null_value; 02036 return value < 0.0 ? -1 : (value > 0 ? 1 : 0); 02037 } 02038 02039 02040 double Item_func_units::val_real() 02041 { 02042 DBUG_ASSERT(fixed == 1); 02043 double value= args[0]->val_real(); 02044 if ((null_value=args[0]->null_value)) 02045 return 0; 02046 return value*mul+add; 02047 } 02048 02049 02050 void Item_func_min_max::fix_length_and_dec() 02051 { 02052 int max_int_part=0; 02053 decimals=0; 02054 max_length=0; 02055 maybe_null=0; 02056 cmp_type=args[0]->result_type(); 02057 02058 for (uint i=0 ; i < arg_count ; i++) 02059 { 02060 set_if_bigger(max_length, args[i]->max_length); 02061 set_if_bigger(decimals, args[i]->decimals); 02062 set_if_bigger(max_int_part, args[i]->decimal_int_part()); 02063 if (args[i]->maybe_null) 02064 maybe_null=1; 02065 cmp_type=item_cmp_type(cmp_type,args[i]->result_type()); 02066 } 02067 if (cmp_type == STRING_RESULT) 02068 agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1); 02069 else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT)) 02070 max_length= my_decimal_precision_to_length(max_int_part+decimals, decimals, 02071 unsigned_flag); 02072 } 02073 02074 02075 String *Item_func_min_max::val_str(String *str) 02076 { 02077 DBUG_ASSERT(fixed == 1); 02078 switch (cmp_type) { 02079 case INT_RESULT: 02080 { 02081 longlong nr=val_int(); 02082 if (null_value) 02083 return 0; 02084 str->set_int(nr, unsigned_flag, &my_charset_bin); 02085 return str; 02086 } 02087 case DECIMAL_RESULT: 02088 { 02089 my_decimal dec_buf, *dec_val= val_decimal(&dec_buf); 02090 if (null_value) 02091 return 0; 02092 my_decimal2string(E_DEC_FATAL_ERROR, dec_val, 0, 0, 0, str); 02093 return str; 02094 } 02095 case REAL_RESULT: 02096 { 02097 double nr= val_real(); 02098 if (null_value) 02099 return 0; /* purecov: inspected */ 02100 str->set_real(nr,decimals,&my_charset_bin); 02101 return str; 02102 } 02103 case STRING_RESULT: 02104 { 02105 String *res; 02106 LINT_INIT(res); 02107 for (uint i=0; i < arg_count ; i++) 02108 { 02109 if (i == 0) 02110 res=args[i]->val_str(str); 02111 else 02112 { 02113 String *res2; 02114 res2= args[i]->val_str(res == str ? &tmp_value : str); 02115 if (res2) 02116 { 02117 int cmp= sortcmp(res,res2,collation.collation); 02118 if ((cmp_sign < 0 ? cmp : -cmp) < 0) 02119 res=res2; 02120 } 02121 } 02122 if ((null_value= args[i]->null_value)) 02123 return 0; 02124 } 02125 res->set_charset(collation.collation); 02126 return res; 02127 } 02128 case ROW_RESULT: 02129 default: 02130 // This case should never be chosen 02131 DBUG_ASSERT(0); 02132 return 0; 02133 } 02134 return 0; // Keep compiler happy 02135 } 02136 02137 02138 double Item_func_min_max::val_real() 02139 { 02140 DBUG_ASSERT(fixed == 1); 02141 double value=0.0; 02142 for (uint i=0; i < arg_count ; i++) 02143 { 02144 if (i == 0) 02145 value= args[i]->val_real(); 02146 else 02147 { 02148 double tmp= args[i]->val_real(); 02149 if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0) 02150 value=tmp; 02151 } 02152 if ((null_value= args[i]->null_value)) 02153 break; 02154 } 02155 return value; 02156 } 02157 02158 02159 longlong Item_func_min_max::val_int() 02160 { 02161 DBUG_ASSERT(fixed == 1); 02162 longlong value=0; 02163 for (uint i=0; i < arg_count ; i++) 02164 { 02165 if (i == 0) 02166 value=args[i]->val_int(); 02167 else 02168 { 02169 longlong tmp=args[i]->val_int(); 02170 if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0) 02171 value=tmp; 02172 } 02173 if ((null_value= args[i]->null_value)) 02174 break; 02175 } 02176 return value; 02177 } 02178 02179 02180 my_decimal *Item_func_min_max::val_decimal(my_decimal *dec) 02181 { 02182 DBUG_ASSERT(fixed == 1); 02183 my_decimal tmp_buf, *tmp, *res; 02184 LINT_INIT(res); 02185 02186 for (uint i=0; i < arg_count ; i++) 02187 { 02188 if (i == 0) 02189 res= args[i]->val_decimal(dec); 02190 else 02191 { 02192 tmp= args[i]->val_decimal(&tmp_buf); // Zero if NULL 02193 if (tmp && (my_decimal_cmp(tmp, res) * cmp_sign) < 0) 02194 { 02195 if (tmp == &tmp_buf) 02196 { 02197 /* Move value out of tmp_buf as this will be reused on next loop */ 02198 my_decimal2decimal(tmp, dec); 02199 res= dec; 02200 } 02201 else 02202 res= tmp; 02203 } 02204 } 02205 if ((null_value= args[i]->null_value)) 02206 { 02207 res= 0; 02208 break; 02209 } 02210 } 02211 return res; 02212 } 02213 02214 02215 longlong Item_func_length::val_int() 02216 { 02217 DBUG_ASSERT(fixed == 1); 02218 String *res=args[0]->val_str(&value); 02219 if (!res) 02220 { 02221 null_value=1; 02222 return 0; /* purecov: inspected */ 02223 } 02224 null_value=0; 02225 return (longlong) res->length(); 02226 } 02227 02228 02229 longlong Item_func_char_length::val_int() 02230 { 02231 DBUG_ASSERT(fixed == 1); 02232 String *res=args[0]->val_str(&value); 02233 if (!res) 02234 { 02235 null_value=1; 02236 return 0; /* purecov: inspected */ 02237 } 02238 null_value=0; 02239 return (longlong) res->numchars(); 02240 } 02241 02242 02243 longlong Item_func_coercibility::val_int() 02244 { 02245 DBUG_ASSERT(fixed == 1); 02246 null_value= 0; 02247 return (longlong) args[0]->collation.derivation; 02248 } 02249 02250 02251 void Item_func_locate::fix_length_and_dec() 02252 { 02253 maybe_null=0; max_length=11; 02254 agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1); 02255 } 02256 02257 02258 longlong Item_func_locate::val_int() 02259 { 02260 DBUG_ASSERT(fixed == 1); 02261 String *a=args[0]->val_str(&value1); 02262 String *b=args[1]->val_str(&value2); 02263 if (!a || !b) 02264 { 02265 null_value=1; 02266 return 0; /* purecov: inspected */ 02267 } 02268 null_value=0; 02269 uint start=0; 02270 uint start0=0; 02271 my_match_t match; 02272 02273 if (arg_count == 3) 02274 { 02275 start0= start =(uint) args[2]->val_int()-1; 02276 start=a->charpos(start); 02277 02278 if (start > a->length() || start+b->length() > a->length()) 02279 return 0; 02280 } 02281 02282 if (!b->length()) // Found empty string at start 02283 return (longlong) (start+1); 02284 02285 if (!cmp_collation.collation->coll->instr(cmp_collation.collation, 02286 a->ptr()+start, a->length()-start, 02287 b->ptr(), b->length(), 02288 &match, 1)) 02289 return 0; 02290 return (longlong) match.mblen + start0 + 1; 02291 } 02292 02293 02294 void Item_func_locate::print(String *str) 02295 { 02296 str->append(STRING_WITH_LEN("locate(")); 02297 args[1]->print(str); 02298 str->append(','); 02299 args[0]->print(str); 02300 if (arg_count == 3) 02301 { 02302 str->append(','); 02303 args[2]->print(str); 02304 } 02305 str->append(')'); 02306 } 02307 02308 02309 longlong Item_func_field::val_int() 02310 { 02311 DBUG_ASSERT(fixed == 1); 02312 02313 if (cmp_type == STRING_RESULT) 02314 { 02315 String *field; 02316 if (!(field= args[0]->val_str(&value))) 02317 return 0; 02318 for (uint i=1 ; i < arg_count ; i++) 02319 { 02320 String *tmp_value=args[i]->val_str(&tmp); 02321 if (tmp_value && !sortcmp(field,tmp_value,cmp_collation.collation)) 02322 return (longlong) (i); 02323 } 02324 } 02325 else if (cmp_type == INT_RESULT) 02326 { 02327 longlong val= args[0]->val_int(); 02328 if (args[0]->null_value) 02329 return 0; 02330 for (uint i=1; i < arg_count ; i++) 02331 { 02332 if (val == args[i]->val_int() && !args[i]->null_value) 02333 return (longlong) (i); 02334 } 02335 } 02336 else if (cmp_type == DECIMAL_RESULT) 02337 { 02338 my_decimal dec_arg_buf, *dec_arg, 02339 dec_buf, *dec= args[0]->val_decimal(&dec_buf); 02340 if (args[0]->null_value) 02341 return 0; 02342 for (uint i=1; i < arg_count; i++) 02343 { 02344 dec_arg= args[i]->val_decimal(&dec_arg_buf); 02345 if (!args[i]->null_value && !my_decimal_cmp(dec_arg, dec)) 02346 return (longlong) (i); 02347 } 02348 } 02349 else 02350 { 02351 double val= args[0]->val_real(); 02352 if (args[0]->null_value) 02353 return 0; 02354 for (uint i=1; i < arg_count ; i++) 02355 { 02356 if (val == args[i]->val_real() && !args[i]->null_value) 02357 return (longlong) (i); 02358 } 02359 } 02360 return 0; 02361 } 02362 02363 02364 void Item_func_field::fix_length_and_dec() 02365 { 02366 maybe_null=0; max_length=3; 02367 cmp_type= args[0]->result_type(); 02368 for (uint i=1; i < arg_count ; i++) 02369 cmp_type= item_cmp_type(cmp_type, args[i]->result_type()); 02370 if (cmp_type == STRING_RESULT) 02371 agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1); 02372 } 02373 02374 02375 longlong Item_func_ascii::val_int() 02376 { 02377 DBUG_ASSERT(fixed == 1); 02378 String *res=args[0]->val_str(&value); 02379 if (!res) 02380 { 02381 null_value=1; 02382 return 0; 02383 } 02384 null_value=0; 02385 return (longlong) (res->length() ? (uchar) (*res)[0] : (uchar) 0); 02386 } 02387 02388 longlong Item_func_ord::val_int() 02389 { 02390 DBUG_ASSERT(fixed == 1); 02391 String *res=args[0]->val_str(&value); 02392 if (!res) 02393 { 02394 null_value=1; 02395 return 0; 02396 } 02397 null_value=0; 02398 if (!res->length()) return 0; 02399 #ifdef USE_MB 02400 if (use_mb(res->charset())) 02401 { 02402 register const char *str=res->ptr(); 02403 register uint32 n=0, l=my_ismbchar(res->charset(),str,str+res->length()); 02404 if (!l) 02405 return (longlong)((uchar) *str); 02406 while (l--) 02407 n=(n<<8)|(uint32)((uchar) *str++); 02408 return (longlong) n; 02409 } 02410 #endif 02411 return (longlong) ((uchar) (*res)[0]); 02412 } 02413 02414 /* Search after a string in a string of strings separated by ',' */ 02415 /* Returns number of found type >= 1 or 0 if not found */ 02416 /* This optimizes searching in enums to bit testing! */ 02417 02418 void Item_func_find_in_set::fix_length_and_dec() 02419 { 02420 decimals=0; 02421 max_length=3; // 1-999 02422 if (args[0]->const_item() && args[1]->type() == FIELD_ITEM) 02423 { 02424 Field *field= ((Item_field*) args[1])->field; 02425 if (field->real_type() == FIELD_TYPE_SET) 02426 { 02427 String *find=args[0]->val_str(&value); 02428 if (find) 02429 { 02430 enum_value= find_type(((Field_enum*) field)->typelib,find->ptr(), 02431 find->length(), 0); 02432 enum_bit=0; 02433 if (enum_value) 02434 enum_bit=LL(1) << (enum_value-1); 02435 } 02436 } 02437 } 02438 agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1); 02439 } 02440 02441 static const char separator=','; 02442 02443 longlong Item_func_find_in_set::val_int() 02444 { 02445 DBUG_ASSERT(fixed == 1); 02446 if (enum_value) 02447 { 02448 ulonglong tmp=(ulonglong) args[1]->val_int(); 02449 if (!(null_value=args[1]->null_value || args[0]->null_value)) 02450 { 02451 if (tmp & enum_bit) 02452 return enum_value; 02453 } 02454 return 0L; 02455 } 02456 02457 String *find=args[0]->val_str(&value); 02458 String *buffer=args[1]->val_str(&value2); 02459 if (!find || !buffer) 02460 { 02461 null_value=1; 02462 return 0; /* purecov: inspected */ 02463 } 02464 null_value=0; 02465 02466 int diff; 02467 if ((diff=buffer->length() - find->length()) >= 0) 02468 { 02469 my_wc_t wc; 02470 CHARSET_INFO *cs= cmp_collation.collation; 02471 const char *str_begin= buffer->ptr(); 02472 const char *str_end= buffer->ptr(); 02473 const char *real_end= str_end+buffer->length(); 02474 const uchar *find_str= (const uchar *) find->ptr(); 02475 uint find_str_len= find->length(); 02476 int position= 0; 02477 while (1) 02478 { 02479 int symbol_len; 02480 if ((symbol_len= cs->cset->mb_wc(cs, &wc, (uchar*) str_end, 02481 (uchar*) real_end)) > 0) 02482 { 02483 const char *substr_end= str_end + symbol_len; 02484 bool is_last_item= (substr_end == real_end); 02485 bool is_separator= (wc == (my_wc_t) separator); 02486 if (is_separator || is_last_item) 02487 { 02488 position++; 02489 if (is_last_item && !is_separator) 02490 str_end= substr_end; 02491 if (!my_strnncoll(cs, (const uchar *) str_begin, 02492 str_end - str_begin, 02493 find_str, find_str_len)) 02494 return (longlong) position; 02495 else 02496 str_begin= substr_end; 02497 } 02498 str_end= substr_end; 02499 } 02500 else if (str_end - str_begin == 0 && 02501 find_str_len == 0 && 02502 wc == (my_wc_t) separator) 02503 return (longlong) ++position; 02504 else 02505 return LL(0); 02506 } 02507 } 02508 return 0; 02509 } 02510 02511 longlong Item_func_bit_count::val_int() 02512 { 02513 DBUG_ASSERT(fixed == 1); 02514 ulonglong value= (ulonglong) args[0]->val_int(); 02515 if ((null_value= args[0]->null_value)) 02516 return 0; /* purecov: inspected */ 02517 return (longlong) my_count_bits(value); 02518 } 02519 02520 02521 /**************************************************************************** 02522 ** Functions to handle dynamic loadable functions 02523 ** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su> 02524 ** Rewritten by monty. 02525 ****************************************************************************/ 02526 02527 #ifdef HAVE_DLOPEN 02528 02529 void udf_handler::cleanup() 02530 { 02531 if (!not_original) 02532 { 02533 if (initialized) 02534 { 02535 if (u_d->func_deinit != NULL) 02536 { 02537 Udf_func_deinit deinit= u_d->func_deinit; 02538 (*deinit)(&initid); 02539 } 02540 free_udf(u_d); 02541 initialized= FALSE; 02542 } 02543 if (buffers) // Because of bug in ecc 02544 delete [] buffers; 02545 buffers= 0; 02546 } 02547 } 02548 02549 02550 bool 02551 udf_handler::fix_fields(THD *thd, Item_result_field *func, 02552 uint arg_count, Item **arguments) 02553 { 02554 #ifndef EMBEDDED_LIBRARY // Avoid compiler warning 02555 char buff[STACK_BUFF_ALLOC]; // Max argument in function 02556 #endif 02557 DBUG_ENTER("Item_udf_func::fix_fields"); 02558 02559 if (check_stack_overrun(thd, STACK_MIN_SIZE, buff)) 02560 DBUG_RETURN(TRUE); // Fatal error flag is set! 02561 02562 udf_func *tmp_udf=find_udf(u_d->name.str,(uint) u_d->name.length,1); 02563 02564 if (!tmp_udf) 02565 { 02566 my_error(ER_CANT_FIND_UDF, MYF(0), u_d->name.str, errno); 02567 DBUG_RETURN(TRUE); 02568 } 02569 u_d=tmp_udf; 02570 args=arguments; 02571 02572 /* Fix all arguments */ 02573 func->maybe_null=0; 02574 used_tables_cache=0; 02575 const_item_cache=1; 02576 02577 if ((f_args.arg_count=arg_count)) 02578 { 02579 if (!(f_args.arg_type= (Item_result*) 02580 sql_alloc(f_args.arg_count*sizeof(Item_result)))) 02581 02582 { 02583 free_udf(u_d); 02584 DBUG_RETURN(TRUE); 02585 } 02586 uint i; 02587 Item **arg,**arg_end; 02588 for (i=0, arg=arguments, arg_end=arguments+arg_count; 02589 arg != arg_end ; 02590 arg++,i++) 02591 { 02592 if (!(*arg)->fixed && 02593 (*arg)->fix_fields(thd, arg)) 02594 DBUG_RETURN(1); 02595 // we can't assign 'item' before, because fix_fields() can change arg 02596 Item *item= *arg; 02597 if (item->check_cols(1)) 02598 DBUG_RETURN(TRUE); 02599 /* 02600 TODO: We should think about this. It is not always 02601 right way just to set an UDF result to return my_charset_bin 02602 if one argument has binary sorting order. 02603 The result collation should be calculated according to arguments 02604 derivations in some cases and should not in other cases. 02605 Moreover, some arguments can represent a numeric input 02606 which doesn't effect the result character set and collation. 02607 There is no a general rule for UDF. Everything depends on 02608 the particular user defined function. 02609 */ 02610 if (item->collation.collation->state & MY_CS_BINSORT) 02611 func->collation.set(&my_charset_bin); 02612 if (item->maybe_null) 02613 func->maybe_null=1; 02614 func->with_sum_func= func->with_sum_func || item->with_sum_func; 02615 used_tables_cache|=item->used_tables(); 02616 const_item_cache&=item->const_item(); 02617 f_args.arg_type[i]=item->result_type(); 02618 } 02619 //TODO: why all following memory is not allocated with 1 call of sql_alloc? 02620 if (!(buffers=new String[arg_count]) || 02621 !(f_args.args= (char**) sql_alloc(arg_count * sizeof(char *))) || 02622 !(f_args.lengths= (ulong*) sql_alloc(arg_count * sizeof(long))) || 02623 !(f_args.maybe_null= (char*) sql_alloc(arg_count * sizeof(char))) || 02624 !(num_buffer= (char*) sql_alloc(arg_count * 02625 ALIGN_SIZE(sizeof(double)))) || 02626 !(f_args.attributes= (char**) sql_alloc(arg_count * sizeof(char *))) || 02627 !(f_args.attribute_lengths= (ulong*) sql_alloc(arg_count * 02628 sizeof(long)))) 02629 { 02630 free_udf(u_d); 02631 DBUG_RETURN(TRUE); 02632 } 02633 } 02634 func->fix_length_and_dec(); 02635 initid.max_length=func->max_length; 02636 initid.maybe_null=func->maybe_null; 02637 initid.const_item=const_item_cache; 02638 initid.decimals=func->decimals; 02639 initid.ptr=0; 02640 02641 if (u_d->func_init) 02642 { 02643 char *to=num_buffer; 02644 for (uint i=0; i < arg_count; i++) 02645 { 02646 f_args.args[i]=0; 02647 f_args.lengths[i]= arguments[i]->max_length; 02648 f_args.maybe_null[i]= (char) arguments[i]->maybe_null; 02649 f_args.attributes[i]= arguments[i]->name; 02650 f_args.attribute_lengths[i]= arguments[i]->name_length; 02651 02652 switch(arguments[i]->type()) { 02653 case Item::STRING_ITEM: // Constant string ! 02654 { 02655 String *res=arguments[i]->val_str(&buffers[i]); 02656 if (arguments[i]->null_value) 02657 continue; 02658 f_args.args[i]= (char*) res->ptr(); 02659 break; 02660 } 02661 case Item::INT_ITEM: 02662 *((longlong*) to) = arguments[i]->val_int(); 02663 if (!arguments[i]->null_value) 02664 { 02665 f_args.args[i]=to; 02666 to+= ALIGN_SIZE(sizeof(longlong)); 02667 } 02668 break; 02669 case Item::REAL_ITEM: 02670 *((double*) to)= arguments[i]->val_real(); 02671 if (!arguments[i]->null_value) 02672 { 02673 f_args.args[i]=to; 02674 to+= ALIGN_SIZE(sizeof(double)); 02675 } 02676 break; 02677 default: // Skip these 02678 break; 02679 } 02680 } 02681 thd->net.last_error[0]=0; 02682 Udf_func_init init= u_d->func_init; 02683 if ((error=(uchar) init(&initid, &f_args, thd->net.last_error))) 02684 { 02685 my_error(ER_CANT_INITIALIZE_UDF, MYF(0), 02686 u_d->name.str, thd->net.last_error); 02687 free_udf(u_d); 02688 DBUG_RETURN(TRUE); 02689 } 02690 func->max_length=min(initid.max_length,MAX_BLOB_WIDTH); 02691 func->maybe_null=initid.maybe_null; 02692 const_item_cache=initid.const_item; 02693 func->decimals=min(initid.decimals,NOT_FIXED_DEC); 02694 } 02695 initialized=1; 02696 if (error) 02697 { 02698 my_error(ER_CANT_INITIALIZE_UDF, MYF(0), 02699 u_d->name.str, ER(ER_UNKNOWN_ERROR)); 02700 DBUG_RETURN(TRUE); 02701 } 02702 DBUG_RETURN(FALSE); 02703 } 02704 02705 02706 bool udf_handler::get_arguments() 02707 { 02708 if (error) 02709 return 1; // Got an error earlier 02710 char *to= num_buffer; 02711 uint str_count=0; 02712 for (uint i=0; i < f_args.arg_count; i++) 02713 { 02714 f_args.args[i]=0; 02715 switch (f_args.arg_type[i]) { 02716 case STRING_RESULT: 02717 case DECIMAL_RESULT: 02718 { 02719 String *res=args[i]->val_str(&buffers[str_count++]); 02720 if (!(args[i]->null_value)) 02721 { 02722 f_args.args[i]= (char*) res->ptr(); 02723 f_args.lengths[i]= res->length(); 02724 break; 02725 } 02726 } 02727 case INT_RESULT: 02728 *((longlong*) to) = args[i]->val_int(); 02729 if (!args[i]->null_value) 02730 { 02731 f_args.args[i]=to; 02732 to+= ALIGN_SIZE(sizeof(longlong)); 02733 } 02734 break; 02735 case REAL_RESULT: 02736 *((double*) to)= args[i]->val_real(); 02737 if (!args[i]->null_value) 02738 { 02739 f_args.args[i]=to; 02740 to+= ALIGN_SIZE(sizeof(double)); 02741 } 02742 break; 02743 case ROW_RESULT: 02744 default: 02745 // This case should never be chosen 02746 DBUG_ASSERT(0); 02747 break; 02748 } 02749 } 02750 return 0; 02751 } 02752 02753 /* This returns (String*) 0 in case of NULL values */ 02754 02755 String *udf_handler::val_str(String *str,String *save_str) 02756 { 02757 uchar is_null_tmp=0; 02758 ulong res_length; 02759 DBUG_ENTER("udf_handler::val_str"); 02760 02761 if (get_arguments()) 02762 DBUG_RETURN(0); 02763 char * (*func)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *)= 02764 (char* (*)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *)) 02765 u_d->func; 02766 02767 if ((res_length=str->alloced_length()) < MAX_FIELD_WIDTH) 02768 { // This happens VERY seldom 02769 if (str->alloc(MAX_FIELD_WIDTH)) 02770 { 02771 error=1; 02772 DBUG_RETURN(0); 02773 } 02774 } 02775 char *res=func(&initid, &f_args, (char*) str->ptr(), &res_length, 02776 &is_null_tmp, &error); 02777 DBUG_PRINT("info", ("udf func returned, res_length: %lu", res_length)); 02778 if (is_null_tmp || !res || error) // The !res is for safety 02779 { 02780 DBUG_PRINT("info", ("Null or error")); 02781 DBUG_RETURN(0); 02782 } 02783 if (res == str->ptr()) 02784 { 02785 str->length(res_length); 02786 DBUG_PRINT("exit", ("str: %s", str->ptr())); 02787 DBUG_RETURN(str); 02788 } 02789 save_str->set(res, res_length, str->charset()); 02790 DBUG_PRINT("exit", ("save_str: %s", save_str->ptr())); 02791 DBUG_RETURN(save_str); 02792 } 02793 02794 02795 /* 02796 For the moment, UDF functions are returning DECIMAL values as strings 02797 */ 02798 02799 my_decimal *udf_handler::val_decimal(my_bool *null_value, my_decimal *dec_buf) 02800 { 02801 char buf[DECIMAL_MAX_STR_LENGTH+1], *end; 02802 ulong res_length= DECIMAL_MAX_STR_LENGTH; 02803 02804 if (get_arguments()) 02805 { 02806 *null_value=1; 02807 return 0; 02808 } 02809 char *(*func)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *)= 02810 (char* (*)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *)) 02811 u_d->func; 02812 02813 char *res= func(&initid, &f_args, buf, &res_length, &is_null, &error); 02814 if (is_null || error) 02815 { 02816 *null_value= 1; 02817 return 0; 02818 } 02819 end= res+ res_length; 02820 str2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf, &end); 02821 return dec_buf; 02822 } 02823 02824 02825 void Item_udf_func::cleanup() 02826 { 02827 udf.cleanup(); 02828 Item_func::cleanup(); 02829 } 02830 02831 02832 double Item_func_udf_float::val_real() 02833 { 02834 DBUG_ASSERT(fixed == 1); 02835 DBUG_ENTER("Item_func_udf_float::val"); 02836 DBUG_PRINT("info",("result_type: %d arg_count: %d", 02837 args[0]->result_type(), arg_count)); 02838 DBUG_RETURN(udf.val(&null_value)); 02839 } 02840 02841 02842 String *Item_func_udf_float::val_str(String *str) 02843 { 02844 DBUG_ASSERT(fixed == 1); 02845 double nr= val_real(); 02846 if (null_value) 02847 return 0; /* purecov: inspected */ 02848 str->set_real(nr,decimals,&my_charset_bin); 02849 return str; 02850 } 02851 02852 02853 longlong Item_func_udf_int::val_int() 02854 { 02855 DBUG_ASSERT(fixed == 1); 02856 DBUG_ENTER("Item_func_udf_int::val_int"); 02857 DBUG_RETURN(udf.val_int(&null_value)); 02858 } 02859 02860 02861 String *Item_func_udf_int::val_str(String *str) 02862 { 02863 DBUG_ASSERT(fixed == 1); 02864 longlong nr=val_int(); 02865 if (null_value) 02866 return 0; 02867 str->set_int(nr, unsigned_flag, &my_charset_bin); 02868 return str; 02869 } 02870 02871 02872 longlong Item_func_udf_decimal::val_int() 02873 { 02874 my_decimal dec_buf, *dec= udf.val_decimal(&null_value, &dec_buf); 02875 longlong result; 02876 if (null_value) 02877 return 0; 02878 my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result); 02879 return result; 02880 } 02881 02882 02883 double Item_func_udf_decimal::val_real() 02884 { 02885 my_decimal dec_buf, *dec= udf.val_decimal(&null_value, &dec_buf); 02886 double result; 02887 if (null_value) 02888 return 0.0; 02889 my_decimal2double(E_DEC_FATAL_ERROR, dec, &result); 02890 return result; 02891 } 02892 02893 02894 my_decimal *Item_func_udf_decimal::val_decimal(my_decimal *dec_buf) 02895 { 02896 DBUG_ASSERT(fixed == 1); 02897 DBUG_ENTER("Item_func_udf_decimal::val_decimal"); 02898 DBUG_PRINT("info",("result_type: %d arg_count: %d", 02899 args[0]->result_type(), arg_count)); 02900 02901 DBUG_RETURN(udf.val_decimal(&null_value, dec_buf)); 02902 } 02903 02904 02905 String *Item_func_udf_decimal::val_str(String *str) 02906 { 02907 my_decimal dec_buf, *dec= udf.val_decimal(&null_value, &dec_buf); 02908 if (null_value) 02909 return 0; 02910 if (str->length() < DECIMAL_MAX_STR_LENGTH) 02911 str->length(DECIMAL_MAX_STR_LENGTH); 02912 my_decimal_round(E_DEC_FATAL_ERROR, dec, decimals, FALSE, &dec_buf); 02913 my_decimal2string(E_DEC_FATAL_ERROR, &dec_buf, 0, 0, '0', str); 02914 return str; 02915 } 02916 02917 02918 void Item_func_udf_decimal::fix_length_and_dec() 02919 { 02920 fix_num_length_and_dec(); 02921 } 02922 02923 02924 /* Default max_length is max argument length */ 02925 02926 void Item_func_udf_str::fix_length_and_dec() 02927 { 02928 DBUG_ENTER("Item_func_udf_str::fix_length_and_dec"); 02929 max_length=0; 02930 for (uint i = 0; i < arg_count; i++) 02931 set_if_bigger(max_length,args[i]->max_length); 02932 DBUG_VOID_RETURN; 02933 } 02934 02935 String *Item_func_udf_str::val_str(String *str) 02936 { 02937 DBUG_ASSERT(fixed == 1); 02938 String *res=udf.val_str(str,&str_value); 02939 null_value = !res; 02940 return res; 02941 } 02942 02943 02944 /* 02945 This has to come last in the udf_handler methods, or C for AIX 02946 version 6.0.0.0 fails to compile with debugging enabled. (Yes, really.) 02947 */ 02948 02949 udf_handler::~udf_handler() 02950 { 02951 /* Everything should be properly cleaned up by this moment. */ 02952 DBUG_ASSERT(not_original || !(initialized || buffers)); 02953 } 02954 02955 #else 02956 bool udf_handler::get_arguments() { return 0; } 02957 #endif /* HAVE_DLOPEN */ 02958 02959 /* 02960 ** User level locks 02961 */ 02962 02963 pthread_mutex_t LOCK_user_locks; 02964 static HASH hash_user_locks; 02965 02966 class User_level_lock 02967 { 02968 char *key; 02969 uint key_length; 02970 02971 public: 02972 int count; 02973 bool locked; 02974 pthread_cond_t cond; 02975 pthread_t thread; 02976 ulong thread_id; 02977 02978 User_level_lock(const char *key_arg,uint length, ulong id) 02979 :key_length(length),count(1),locked(1), thread_id(id) 02980 { 02981 key=(char*) my_memdup((byte*) key_arg,length,MYF(0)); 02982 pthread_cond_init(&cond,NULL); 02983 if (key) 02984 { 02985 if (my_hash_insert(&hash_user_locks,(byte*) this)) 02986 { 02987 my_free((gptr) key,MYF(0)); 02988 key=0; 02989 } 02990 } 02991 } 02992 ~User_level_lock() 02993 { 02994 if (key) 02995 { 02996 hash_delete(&hash_user_locks,(byte*) this); 02997 my_free((gptr) key,MYF(0)); 02998 } 02999 pthread_cond_destroy(&cond); 03000 } 03001 inline bool initialized() { return key != 0; } 03002 friend void item_user_lock_release(User_level_lock *ull); 03003 friend char *ull_get_key(const User_level_lock *ull, uint *length, 03004 my_bool not_used); 03005 }; 03006 03007 char *ull_get_key(const User_level_lock *ull, uint *length, 03008 my_bool not_used __attribute__((unused))) 03009 { 03010 *length=(uint) ull->key_length; 03011 return (char*) ull->key; 03012 } 03013 03014 03015 static bool item_user_lock_inited= 0; 03016 03017 void item_user_lock_init(void) 03018 { 03019 pthread_mutex_init(&LOCK_user_locks,MY_MUTEX_INIT_SLOW); 03020 hash_init(&hash_user_locks,system_charset_info, 03021 16,0,0,(hash_get_key) ull_get_key,NULL,0); 03022 item_user_lock_inited= 1; 03023 } 03024 03025 void item_user_lock_free(void) 03026 { 03027 if (item_user_lock_inited) 03028 { 03029 item_user_lock_inited= 0; 03030 hash_free(&hash_user_locks); 03031 pthread_mutex_destroy(&LOCK_user_locks); 03032 } 03033 } 03034 03035 void item_user_lock_release(User_level_lock *ull) 03036 { 03037 ull->locked=0; 03038 ull->thread_id= 0; 03039 if (--ull->count) 03040 pthread_cond_signal(&ull->cond); 03041 else 03042 delete ull; 03043 } 03044 03045 /* 03046 Wait until we are at or past the given position in the master binlog 03047 on the slave 03048 */ 03049 03050 longlong Item_master_pos_wait::val_int() 03051 { 03052 DBUG_ASSERT(fixed == 1); 03053 THD* thd = current_thd; 03054 String *log_name = args[0]->val_str(&value); 03055 int event_count= 0; 03056 03057 null_value=0; 03058 if (thd->slave_thread || !log_name || !log_name->length()) 03059 { 03060 null_value = 1; 03061 return 0; 03062 } 03063 longlong pos = (ulong)args[1]->val_int(); 03064 longlong timeout = (arg_count==3) ? args[2]->val_int() : 0 ; 03065 #ifdef HAVE_REPLICATION 03066 if ((event_count = active_mi->rli.wait_for_pos(thd, log_name, pos, timeout)) == -2) 03067 { 03068 null_value = 1; 03069 event_count=0; 03070 } 03071 #endif 03072 return event_count; 03073 } 03074 03075 #ifdef EXTRA_DEBUG 03076 void debug_sync_point(const char* lock_name, uint lock_timeout) 03077 { 03078 THD* thd=current_thd; 03079 User_level_lock* ull; 03080 struct timespec abstime; 03081 int lock_name_len; 03082 lock_name_len=strlen(lock_name); 03083 pthread_mutex_lock(&LOCK_user_locks); 03084 03085 if (thd->ull) 03086 { 03087 item_user_lock_release(thd->ull); 03088 thd->ull=0; 03089 } 03090 03091 /* 03092 If the lock has not been aquired by some client, we do not want to 03093 create an entry for it, since we immediately release the lock. In 03094 this case, we will not be waiting, but rather, just waste CPU and 03095 memory on the whole deal 03096 */ 03097 if (!(ull= ((User_level_lock*) hash_search(&hash_user_locks, lock_name, 03098 lock_name_len)))) 03099 { 03100 pthread_mutex_unlock(&LOCK_user_locks); 03101 return; 03102 } 03103 ull->count++; 03104 03105 /* 03106 Structure is now initialized. Try to get the lock. 03107 Set up control struct to allow others to abort locks 03108 */ 03109 thd->proc_info="User lock"; 03110 thd->mysys_var->current_mutex= &LOCK_user_locks; 03111 thd->mysys_var->current_cond= &ull->cond; 03112 03113 set_timespec(abstime,lock_timeout); 03114 while (ull->locked && !thd->killed) 03115 { 03116 int error= pthread_cond_timedwait(&ull->cond, &LOCK_user_locks, &abstime); 03117 if (error == ETIMEDOUT || error == ETIME) 03118 break; 03119 } 03120 03121 if (ull->locked) 03122 { 03123 if (!--ull->count) 03124 delete ull; // Should never happen 03125 } 03126 else 03127 { 03128 ull->locked=1; 03129 ull->thread=thd->real_id; 03130 thd->ull=ull; 03131 } 03132 pthread_mutex_unlock(&LOCK_user_locks); 03133 pthread_mutex_lock(&thd->mysys_var->mutex); 03134 thd->proc_info=0; 03135 thd->mysys_var->current_mutex= 0; 03136 thd->mysys_var->current_cond= 0; 03137 pthread_mutex_unlock(&thd->mysys_var->mutex); 03138 pthread_mutex_lock(&LOCK_user_locks); 03139 if (thd->ull) 03140 { 03141 item_user_lock_release(thd->ull); 03142 thd->ull=0; 03143 } 03144 pthread_mutex_unlock(&LOCK_user_locks); 03145 } 03146 03147 #endif 03148 03149 /* 03150 Get a user level lock. If the thread has an old lock this is first released. 03151 Returns 1: Got lock 03152 Returns 0: Timeout 03153 Returns NULL: Error 03154 */ 03155 03156 longlong Item_func_get_lock::val_int() 03157 { 03158 DBUG_ASSERT(fixed == 1); 03159 String *res=args[0]->val_str(&value); 03160 longlong timeout=args[1]->val_int(); 03161 struct timespec abstime; 03162 THD *thd=current_thd; 03163 User_level_lock *ull; 03164 int error; 03165 03166 /* 03167 In slave thread no need to get locks, everything is serialized. Anyway 03168 there is no way to make GET_LOCK() work on slave like it did on master 03169 (i.e. make it return exactly the same value) because we don't have the 03170 same other concurrent threads environment. No matter what we return here, 03171 it's not guaranteed to be same as on master. 03172 */ 03173 if (thd->slave_thread) 03174 return 1; 03175 03176 pthread_mutex_lock(&LOCK_user_locks); 03177 03178 if (!res || !res->length()) 03179 { 03180 pthread_mutex_unlock(&LOCK_user_locks); 03181 null_value=1; 03182 return 0; 03183 } 03184 null_value=0; 03185 03186 if (thd->ull) 03187 { 03188 item_user_lock_release(thd->ull); 03189 thd->ull=0; 03190 } 03191 03192 if (!(ull= ((User_level_lock *) hash_search(&hash_user_locks, 03193 (byte*) res->ptr(), 03194 res->length())))) 03195 { 03196 ull=new User_level_lock(res->ptr(),res->length(), thd->thread_id); 03197 if (!ull || !ull->initialized()) 03198 { 03199 delete ull; 03200 pthread_mutex_unlock(&LOCK_user_locks); 03201 null_value=1; // Probably out of memory 03202 return 0; 03203 } 03204 ull->thread=thd->real_id; 03205 thd->ull=ull; 03206 pthread_mutex_unlock(&LOCK_user_locks); 03207 return 1; // Got new lock 03208 } 03209 ull->count++; 03210 03211 /* 03212 Structure is now initialized. Try to get the lock. 03213 Set up control struct to allow others to abort locks. 03214 */ 03215 thd->proc_info="User lock"; 03216 thd->mysys_var->current_mutex= &LOCK_user_locks; 03217 thd->mysys_var->current_cond= &ull->cond; 03218 03219 set_timespec(abstime,timeout); 03220 error= 0; 03221 while (ull->locked && !thd->killed) 03222 { 03223 error= pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime); 03224 if (error == ETIMEDOUT || error == ETIME) 03225 break; 03226 error= 0; 03227 } 03228 03229 if (ull->locked) 03230 { 03231 if (!--ull->count) 03232 { 03233 DBUG_ASSERT(0); 03234 delete ull; // Should never happen 03235 } 03236 if (!error) // Killed (thd->killed != 0) 03237 { 03238 error=1; 03239 null_value=1; // Return NULL 03240 } 03241 } 03242 else // We got the lock 03243 { 03244 ull->locked=1; 03245 ull->thread=thd->real_id; 03246 ull->thread_id= thd->thread_id; 03247 thd->ull=ull; 03248 error=0; 03249 } 03250 pthread_mutex_unlock(&LOCK_user_locks); 03251 03252 pthread_mutex_lock(&thd->mysys_var->mutex); 03253 thd->proc_info=0; 03254 thd->mysys_var->current_mutex= 0; 03255 thd->mysys_var->current_cond= 0; 03256 pthread_mutex_unlock(&thd->mysys_var->mutex); 03257 03258 return !error ? 1 : 0; 03259 } 03260 03261 03262 /* 03263 Release a user level lock. 03264 Return: 03265 1 if lock released 03266 0 if lock wasn't held 03267 (SQL) NULL if no such lock 03268 */ 03269 03270 longlong Item_func_release_lock::val_int() 03271 { 03272 DBUG_ASSERT(fixed == 1); 03273 String *res=args[0]->val_str(&value); 03274 User_level_lock *ull; 03275 longlong result; 03276 if (!res || !res->length()) 03277 { 03278 null_value=1; 03279 return 0; 03280 } 03281 null_value=0; 03282 03283 result=0; 03284 pthread_mutex_lock(&LOCK_user_locks); 03285 if (!(ull= ((User_level_lock*) hash_search(&hash_user_locks, 03286 (const byte*) res->ptr(), 03287 res->length())))) 03288 { 03289 null_value=1; 03290 } 03291 else 03292 { 03293 if (ull->locked && pthread_equal(pthread_self(),ull->thread)) 03294 { 03295 result=1; // Release is ok 03296 item_user_lock_release(ull); 03297 current_thd->ull=0; 03298 } 03299 } 03300 pthread_mutex_unlock(&LOCK_user_locks); 03301 return result; 03302 } 03303 03304 03305 longlong Item_func_last_insert_id::val_int() 03306 { 03307 THD *thd= current_thd; 03308 DBUG_ASSERT(fixed == 1); 03309 if (arg_count) 03310 { 03311 longlong value= args[0]->val_int(); 03312 null_value= args[0]->null_value; 03313 /* 03314 LAST_INSERT_ID(X) must affect the client's mysql_insert_id() as 03315 documented in the manual. We don't want to touch 03316 first_successful_insert_id_in_cur_stmt because it would make 03317 LAST_INSERT_ID(X) take precedence over an generated auto_increment 03318 value for this row. 03319 */ 03320 thd->arg_of_last_insert_id_function= TRUE; 03321 thd->first_successful_insert_id_in_prev_stmt= value; 03322 return value; 03323 } 03324 thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT); 03325 return thd->read_first_successful_insert_id_in_prev_stmt(); 03326 } 03327 03328 /* This function is just used to test speed of different functions */ 03329 03330 longlong Item_func_benchmark::val_int() 03331 { 03332 DBUG_ASSERT(fixed == 1); 03333 char buff[MAX_FIELD_WIDTH]; 03334 String tmp(buff,sizeof(buff), &my_charset_bin); 03335 THD *thd=current_thd; 03336 03337 for (ulong loop=0 ; loop < loop_count && !thd->killed; loop++) 03338 { 03339 switch (args[0]->result_type()) { 03340 case REAL_RESULT: 03341 (void) args[0]->val_real(); 03342 break; 03343 case INT_RESULT: 03344 (void) args[0]->val_int(); 03345 break; 03346 case STRING_RESULT: 03347 (void) args[0]->val_str(&tmp); 03348 break; 03349 case ROW_RESULT: 03350 default: 03351 // This case should never be chosen 03352 DBUG_ASSERT(0); 03353 return 0; 03354 } 03355 } 03356 return 0; 03357 } 03358 03359 03360 void Item_func_benchmark::print(String *str) 03361 { 03362 str->append(STRING_WITH_LEN("benchmark(")); 03363 char buffer[20]; 03364 // my_charset_bin is good enough for numbers 03365 String st(buffer, sizeof(buffer), &my_charset_bin); 03366 st.set((ulonglong)loop_count, &my_charset_bin); 03367 str->append(st); 03368 str->append(','); 03369 args[0]->print(str); 03370 str->append(')'); 03371 } 03372 03373 03374 /* This function is just used to create tests with time gaps */ 03375 03376 longlong Item_func_sleep::val_int() 03377 { 03378 THD *thd= current_thd; 03379 struct timespec abstime; 03380 pthread_cond_t cond; 03381 int error; 03382 03383 DBUG_ASSERT(fixed == 1); 03384 03385 double time= args[0]->val_real(); 03386 set_timespec_nsec(abstime, (ulonglong)(time * ULL(1000000000))); 03387 03388 pthread_cond_init(&cond, NULL); 03389 pthread_mutex_lock(&LOCK_user_locks); 03390 03391 thd->mysys_var->current_mutex= &LOCK_user_locks; 03392 thd->mysys_var->current_cond= &cond; 03393 03394 error= 0; 03395 while (!thd->killed) 03396 { 03397 error= pthread_cond_timedwait(&cond, &LOCK_user_locks, &abstime); 03398 if (error == ETIMEDOUT || error == ETIME) 03399 break; 03400 error= 0; 03401 } 03402 03403 pthread_mutex_lock(&thd->mysys_var->mutex); 03404 thd->mysys_var->current_mutex= 0; 03405 thd->mysys_var->current_cond= 0; 03406 pthread_mutex_unlock(&thd->mysys_var->mutex); 03407 03408 pthread_mutex_unlock(&LOCK_user_locks); 03409 pthread_cond_destroy(&cond); 03410 03411 return test(!error); // Return 1 killed 03412 } 03413 03414 03415 #define extra_size sizeof(double) 03416 03417 static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, 03418 bool create_if_not_exists) 03419 { 03420 user_var_entry *entry; 03421 03422 if (!(entry = (user_var_entry*) hash_search(hash, (byte*) name.str, 03423 name.length)) && 03424 create_if_not_exists) 03425 { 03426 uint size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size; 03427 if (!hash_inited(hash)) 03428 return 0; 03429 if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME)))) 03430 return 0; 03431 entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+ 03432 extra_size; 03433 entry->name.length=name.length; 03434 entry->value=0; 03435 entry->length=0; 03436 entry->update_query_id=0; 03437 entry->collation.set(NULL, DERIVATION_IMPLICIT); 03438 entry->unsigned_flag= 0; 03439 /* 03440 If we are here, we were called from a SET or a query which sets a 03441 variable. Imagine it is this: 03442 INSERT INTO t SELECT @a:=10, @a:=@a+1. 03443 Then when we have a Item_func_get_user_var (because of the @a+1) so we 03444 think we have to write the value of @a to the binlog. But before that, 03445 we have a Item_func_set_user_var to create @a (@a:=10), in this we mark 03446 the variable as "already logged" (line below) so that it won't be logged 03447 by Item_func_get_user_var (because that's not necessary). 03448 */ 03449 entry->used_query_id=current_thd->query_id; 03450 entry->type=STRING_RESULT; 03451 memcpy(entry->name.str, name.str, name.length+1); 03452 if (my_hash_insert(hash,(byte*) entry)) 03453 { 03454 my_free((char*) entry,MYF(0)); 03455 return 0; 03456 } 03457 } 03458 return entry; 03459 } 03460 03461 /* 03462 When a user variable is updated (in a SET command or a query like 03463 SELECT @a:= ). 03464 */ 03465 03466 bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref) 03467 { 03468 DBUG_ASSERT(fixed == 0); 03469 /* fix_fields will call Item_func_set_user_var::fix_length_and_dec */ 03470 if (Item_func::fix_fields(thd, ref) || 03471 !(entry= get_variable(&thd->user_vars, name, 1))) 03472 return TRUE; 03473 /* 03474 Remember the last query which updated it, this way a query can later know 03475 if this variable is a constant item in the query (it is if update_query_id 03476 is different from query_id). 03477 */ 03478 entry->update_query_id= thd->query_id; 03479 /* 03480 As it is wrong and confusing to associate any 03481 character set with NULL, @a should be latin2 03482 after this query sequence: 03483 03484 SET @a=_latin2'string'; 03485 SET @a=NULL; 03486 03487 I.e. the second query should not change the charset 03488 to the current default value, but should keep the 03489 original value assigned during the first query. 03490 In order to do it, we don't copy charset 03491 from the argument if the argument is NULL 03492 and the variable has previously been initialized. 03493 */ 03494 null_item= (args[0]->type() == NULL_ITEM); 03495 if (!entry->collation.collation || !null_item) 03496 entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT); 03497 collation.set(entry->collation.collation, DERIVATION_IMPLICIT); 03498 cached_result_type= args[0]->result_type(); 03499 return FALSE; 03500 } 03501 03502 03503 void 03504 Item_func_set_user_var::fix_length_and_dec() 03505 { 03506 maybe_null=args[0]->maybe_null; 03507 max_length=args[0]->max_length; 03508 decimals=args[0]->decimals; 03509 collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT); 03510 } 03511 03512 03513 /* 03514 Set value to user variable. 03515 03516 SYNOPSYS 03517 update_hash() 03518 entry - pointer to structure representing variable 03519 set_null - should we set NULL value ? 03520 ptr - pointer to buffer with new value 03521 length - length of new value 03522 type - type of new value 03523 cs - charset info for new value 03524 dv - derivation for new value 03525 unsigned_arg - indiates if a value of type INT_RESULT is unsigned 03526 03527 RETURN VALUE 03528 False - success, True - failure 03529 */ 03530 03531 static bool 03532 update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length, 03533 Item_result type, CHARSET_INFO *cs, Derivation dv, 03534 bool unsigned_arg) 03535 { 03536 if (set_null) 03537 { 03538 char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry)); 03539 if (entry->value && entry->value != pos) 03540 my_free(entry->value,MYF(0)); 03541 entry->value= 0; 03542 entry->length= 0; 03543 } 03544 else 03545 { 03546 if (type == STRING_RESULT) 03547 length++; // Store strings with end \0 03548 if (length <= extra_size) 03549 { 03550 /* Save value in value struct */ 03551 char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry)); 03552 if (entry->value != pos) 03553 { 03554 if (entry->value) 03555 my_free(entry->value,MYF(0)); 03556 entry->value=pos; 03557 } 03558 } 03559 else 03560 { 03561 /* Allocate variable */ 03562 if (entry->length != length) 03563 { 03564 char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry)); 03565 if (entry->value == pos) 03566 entry->value=0; 03567 if (!(entry->value=(char*) my_realloc(entry->value, length, 03568 MYF(MY_ALLOW_ZERO_PTR)))) 03569 return 1; 03570 } 03571 } 03572 if (type == STRING_RESULT) 03573 { 03574 length--; // Fix length change above 03575 entry->value[length]= 0; // Store end \0 03576 } 03577 memcpy(entry->value,ptr,length); 03578 if (type == DECIMAL_RESULT) 03579 ((my_decimal*)entry->value)->fix_buffer_pointer(); 03580 entry->length= length; 03581 entry->collation.set(cs, dv); 03582 entry->unsigned_flag= unsigned_arg; 03583 } 03584 entry->type=type; 03585 return 0; 03586 } 03587 03588 03589 bool 03590 Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type, 03591 CHARSET_INFO *cs, Derivation dv, 03592 bool unsigned_arg) 03593 { 03594 /* 03595 If we set a variable explicitely to NULL then keep the old 03596 result type of the variable 03597 */ 03598 if ((null_value= args[0]->null_value) && null_item) 03599 type= entry->type; // Don't change type of item 03600 if (::update_hash(entry, (null_value= args[0]->null_value), 03601 ptr, length, type, cs, dv, unsigned_arg)) 03602 { 03603 current_thd->fatal_error(); // Probably end of memory 03604 null_value= 1; 03605 return 1; 03606 } 03607 return 0; 03608 } 03609 03610 03611 /* Get the value of a variable as a double */ 03612 03613 double user_var_entry::val_real(my_bool *null_value) 03614 { 03615 if ((*null_value= (value == 0))) 03616 return 0.0; 03617 03618 switch (type) { 03619 case REAL_RESULT: 03620 return *(double*) value; 03621 case INT_RESULT: 03622 return (double) *(longlong*) value; 03623 case DECIMAL_RESULT: 03624 { 03625 double result; 03626 my_decimal2double(E_DEC_FATAL_ERROR, (my_decimal *)value, &result); 03627 return result; 03628 } 03629 case STRING_RESULT: 03630 return my_atof(value); // This is null terminated 03631 case ROW_RESULT: 03632 DBUG_ASSERT(1); // Impossible 03633 break; 03634 } 03635 return 0.0; // Impossible 03636 } 03637 03638 03639 /* Get the value of a variable as an integer */ 03640 03641 longlong user_var_entry::val_int(my_bool *null_value) 03642 { 03643 if ((*null_value= (value == 0))) 03644 return LL(0); 03645 03646 switch (type) { 03647 case REAL_RESULT: 03648 return (longlong) *(double*) value; 03649 case INT_RESULT: 03650 return *(longlong*) value; 03651 case DECIMAL_RESULT: 03652 { 03653 longlong result; 03654 my_decimal2int(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, &result); 03655 return result; 03656 } 03657 case STRING_RESULT: 03658 { 03659 int error; 03660 return my_strtoll10(value, (char**) 0, &error);// String is null terminated 03661 } 03662 case ROW_RESULT: 03663 DBUG_ASSERT(1); // Impossible 03664 break; 03665 } 03666 return LL(0); // Impossible 03667 } 03668 03669 03670 /* Get the value of a variable as a string */ 03671 03672 String *user_var_entry::val_str(my_bool *null_value, String *str, 03673 uint decimals) 03674 { 03675 if ((*null_value= (value == 0))) 03676 return (String*) 0; 03677 03678 switch (type) { 03679 case REAL_RESULT: 03680 str->set_real(*(double*) value, decimals, &my_charset_bin); 03681 break; 03682 case INT_RESULT: 03683 if (!unsigned_flag) 03684 str->set(*(longlong*) value, &my_charset_bin); 03685 else 03686 str->set(*(ulonglong*) value, &my_charset_bin); 03687 break; 03688 case DECIMAL_RESULT: 03689 my_decimal2string(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, 0, 0, str); 03690 break; 03691 case STRING_RESULT: 03692 if (str->copy(value, length, collation.collation)) 03693 str= 0; // EOM error 03694 case ROW_RESULT: 03695 DBUG_ASSERT(1); // Impossible 03696 break; 03697 } 03698 return(str); 03699 } 03700 03701 /* Get the value of a variable as a decimal */ 03702 03703 my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val) 03704 { 03705 if ((*null_value= (value == 0))) 03706 return 0; 03707 03708 switch (type) { 03709 case REAL_RESULT: 03710 double2my_decimal(E_DEC_FATAL_ERROR, *(double*) value, val); 03711 break; 03712 case INT_RESULT: 03713 int2my_decimal(E_DEC_FATAL_ERROR, *(longlong*) value, 0, val); 03714 break; 03715 case DECIMAL_RESULT: 03716 val= (my_decimal *)value; 03717 break; 03718 case STRING_RESULT: 03719 str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val); 03720 break; 03721 case ROW_RESULT: 03722 DBUG_ASSERT(1); // Impossible 03723 break; 03724 } 03725 return(val); 03726 } 03727 03728 /* 03729 This functions is invoked on SET @variable or @variable:= expression. 03730 Evaluate (and check expression), store results. 03731 03732 SYNOPSYS 03733 Item_func_set_user_var::check() 03734 03735 NOTES 03736 For now it always return OK. All problem with value evaluating 03737 will be caught by thd->net.report_error check in sql_set_variables(). 03738 03739 RETURN 03740 FALSE OK. 03741 */ 03742 03743 bool 03744 Item_func_set_user_var::check() 03745 { 03746 DBUG_ENTER("Item_func_set_user_var::check"); 03747 03748 switch (cached_result_type) { 03749 case REAL_RESULT: 03750 { 03751 save_result.vreal= args[0]->val_real(); 03752 break; 03753 } 03754 case INT_RESULT: 03755 { 03756 save_result.vint= args[0]->val_int(); 03757 unsigned_flag= args[0]->unsigned_flag; 03758 break; 03759 } 03760 case STRING_RESULT: 03761 { 03762 save_result.vstr= args[0]->val_str(&value); 03763 break; 03764 } 03765 case DECIMAL_RESULT: 03766 { 03767 save_result.vdec= args[0]->val_decimal(&decimal_buff); 03768 break; 03769 } 03770 case ROW_RESULT: 03771 default: 03772 // This case should never be chosen 03773 DBUG_ASSERT(0); 03774 break; 03775 } 03776 DBUG_RETURN(FALSE); 03777 } 03778 03779 03780 /* 03781 This functions is invoked on SET @variable or @variable:= expression. 03782 03783 SYNOPSIS 03784 Item_func_set_user_var::update() 03785 03786 NOTES 03787 We have to store the expression as such in the variable, independent of 03788 the value method used by the user 03789 03790 RETURN 03791 0 OK 03792 1 EOM Error 03793 03794 */ 03795 03796 bool 03797 Item_func_set_user_var::update() 03798 { 03799 bool res; 03800 DBUG_ENTER("Item_func_set_user_var::update"); 03801 LINT_INIT(res); 03802 03803 switch (cached_result_type) { 03804 case REAL_RESULT: 03805 { 03806 res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal), 03807 REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT); 03808 break; 03809 } 03810 case INT_RESULT: 03811 { 03812 res= update_hash((void*) &save_result.vint, sizeof(save_result.vint), 03813 INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 03814 unsigned_flag); 03815 break; 03816 } 03817 case STRING_RESULT: 03818 { 03819 if (!save_result.vstr) // Null value 03820 res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin, 03821 DERIVATION_IMPLICIT); 03822 else 03823 res= update_hash((void*) save_result.vstr->ptr(), 03824 save_result.vstr->length(), STRING_RESULT, 03825 save_result.vstr->charset(), 03826 DERIVATION_IMPLICIT); 03827 break; 03828 } 03829 case DECIMAL_RESULT: 03830 { 03831 if (!save_result.vdec) // Null value 03832 res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin, 03833 DERIVATION_IMPLICIT); 03834 else 03835 res= update_hash((void*) save_result.vdec, 03836 sizeof(my_decimal), DECIMAL_RESULT, 03837 &my_charset_bin, DERIVATION_IMPLICIT); 03838 break; 03839 } 03840 case ROW_RESULT: 03841 default: 03842 // This case should never be chosen 03843 DBUG_ASSERT(0); 03844 break; 03845 } 03846 DBUG_RETURN(res); 03847 } 03848 03849 03850 double Item_func_set_user_var::val_real() 03851 { 03852 DBUG_ASSERT(fixed == 1); 03853 check(); 03854 update(); // Store expression 03855 return entry->val_real(&null_value); 03856 } 03857 03858 longlong Item_func_set_user_var::val_int() 03859 { 03860 DBUG_ASSERT(fixed == 1); 03861 check(); 03862 update(); // Store expression 03863 return entry->val_int(&null_value); 03864 } 03865 03866 String *Item_func_set_user_var::val_str(String *str) 03867 { 03868 DBUG_ASSERT(fixed == 1); 03869 check(); 03870 update(); // Store expression 03871 return entry->val_str(&null_value, str, decimals); 03872 } 03873 03874 03875 my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val) 03876 { 03877 DBUG_ASSERT(fixed == 1); 03878 check(); 03879 update(); // Store expression 03880 return entry->val_decimal(&null_value, val); 03881 } 03882 03883 03884 void Item_func_set_user_var::print(String *str) 03885 { 03886 str->append(STRING_WITH_LEN("(@")); 03887 str->append(name.str, name.length); 03888 str->append(STRING_WITH_LEN(":=")); 03889 args[0]->print(str); 03890 str->append(')'); 03891 } 03892 03893 03894 void Item_func_set_user_var::print_as_stmt(String *str) 03895 { 03896 str->append(STRING_WITH_LEN("set @")); 03897 str->append(name.str, name.length); 03898 str->append(STRING_WITH_LEN(":=")); 03899 args[0]->print(str); 03900 str->append(')'); 03901 } 03902 03903 03904 String * 03905 Item_func_get_user_var::val_str(String *str) 03906 { 03907 DBUG_ASSERT(fixed == 1); 03908 DBUG_ENTER("Item_func_get_user_var::val_str"); 03909 if (!var_entry) 03910 DBUG_RETURN((String*) 0); // No such variable 03911 DBUG_RETURN(var_entry->val_str(&null_value, str, decimals)); 03912 } 03913 03914 03915 double Item_func_get_user_var::val_real() 03916 { 03917 DBUG_ASSERT(fixed == 1); 03918 if (!var_entry) 03919 return 0.0; // No such variable 03920 return (var_entry->val_real(&null_value)); 03921 } 03922 03923 03924 my_decimal *Item_func_get_user_var::val_decimal(my_decimal *dec) 03925 { 03926 DBUG_ASSERT(fixed == 1); 03927 if (!var_entry) 03928 return 0; 03929 return var_entry->val_decimal(&null_value, dec); 03930 } 03931 03932 03933 longlong Item_func_get_user_var::val_int() 03934 { 03935 DBUG_ASSERT(fixed == 1); 03936 if (!var_entry) 03937 return LL(0); // No such variable 03938 return (var_entry->val_int(&null_value)); 03939 } 03940 03941 03942 /* 03943 Get variable by name and, if necessary, put the record of variable 03944 use into the binary log. 03945 03946 SYNOPSIS 03947 get_var_with_binlog() 03948 thd Current thread 03949 name Variable name 03950 out_entry [out] variable structure or NULL. The pointer is set 03951 regardless of whether function succeeded or not. 03952 03953 When a user variable is invoked from an update query (INSERT, UPDATE etc), 03954 stores this variable and its value in thd->user_var_events, so that it can be 03955 written to the binlog (will be written just before the query is written, see 03956 log.cc). 03957 03958 RETURN 03959 0 OK 03960 1 Failed to put appropriate record into binary log 03961 03962 */ 03963 03964 int get_var_with_binlog(THD *thd, enum_sql_command sql_command, 03965 LEX_STRING &name, user_var_entry **out_entry) 03966 { 03967 BINLOG_USER_VAR_EVENT *user_var_event; 03968 user_var_entry *var_entry; 03969 var_entry= get_variable(&thd->user_vars, name, 0); 03970 03971 if (!(opt_bin_log && is_update_query(sql_command))) 03972 { 03973 *out_entry= var_entry; 03974 return 0; 03975 } 03976 03977 if (!var_entry) 03978 { 03979 /* 03980 If the variable does not exist, it's NULL, but we want to create it so 03981 that it gets into the binlog (if it didn't, the slave could be 03982 influenced by a variable of the same name previously set by another 03983 thread). 03984 We create it like if it had been explicitly set with SET before. 03985 The 'new' mimics what sql_yacc.yy does when 'SET @a=10;'. 03986 sql_set_variables() is what is called from 'case SQLCOM_SET_OPTION' 03987 in dispatch_command()). Instead of building a one-element list to pass to 03988 sql_set_variables(), we could instead manually call check() and update(); 03989 this would save memory and time; but calling sql_set_variables() makes 03990 one unique place to maintain (sql_set_variables()). 03991 03992 Manipulation with lex is necessary since free_underlaid_joins 03993 is going to release memory belonging to the main query. 03994 */ 03995 03996 List<set_var_base> tmp_var_list; 03997 LEX *sav_lex= thd->lex, lex_tmp; 03998 thd->lex= &lex_tmp; 03999 lex_start(thd, NULL, 0); 04000 tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name, 04001 new Item_null()))); 04002 /* Create the variable */ 04003 if (sql_set_variables(thd, &tmp_var_list)) 04004 { 04005 thd->lex= sav_lex; 04006 goto err; 04007 } 04008 thd->lex= sav_lex; 04009 if (!(var_entry= get_variable(&thd->user_vars, name, 0))) 04010 goto err; 04011 } 04012 else if (var_entry->used_query_id == thd->query_id || 04013 mysql_bin_log.is_query_in_union(thd, var_entry->used_query_id)) 04014 { 04015 /* 04016 If this variable was already stored in user_var_events by this query 04017 (because it's used in more than one place in the query), don't store 04018 it. 04019 */ 04020 *out_entry= var_entry; 04021 return 0; 04022 } 04023 04024 uint size; 04025 /* 04026 First we need to store value of var_entry, when the next situation 04027 appears: 04028 > set @a:=1; 04029 > insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1); 04030 We have to write to binlog value @a= 1. 04031 04032 We allocate the user_var_event on user_var_events_alloc pool, not on 04033 the this-statement-execution pool because in SPs user_var_event objects 04034 may need to be valid after current [SP] statement execution pool is 04035 destroyed. 04036 */ 04037 size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length; 04038 if (!(user_var_event= (BINLOG_USER_VAR_EVENT *) 04039 alloc_root(thd->user_var_events_alloc, size))) 04040 goto err; 04041 04042 user_var_event->value= (char*) user_var_event + 04043 ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)); 04044 user_var_event->user_var_event= var_entry; 04045 user_var_event->type= var_entry->type; 04046 user_var_event->charset_number= var_entry->collation.collation->number; 04047 if (!var_entry->value) 04048 { 04049 /* NULL value*/ 04050 user_var_event->length= 0; 04051 user_var_event->value= 0; 04052 } 04053 else 04054 { 04055 user_var_event->length= var_entry->length; 04056 memcpy(user_var_event->value, var_entry->value, 04057 var_entry->length); 04058 } 04059 /* Mark that this variable has been used by this query */ 04060 var_entry->used_query_id= thd->query_id; 04061 if (insert_dynamic(&thd->user_var_events, (gptr) &user_var_event)) 04062 goto err; 04063 04064 *out_entry= var_entry; 04065 return 0; 04066 04067 err: 04068 *out_entry= var_entry; 04069 return 1; 04070 } 04071 04072 04073 void Item_func_get_user_var::fix_length_and_dec() 04074 { 04075 THD *thd=current_thd; 04076 int error; 04077 maybe_null=1; 04078 decimals=NOT_FIXED_DEC; 04079 max_length=MAX_BLOB_WIDTH; 04080 04081 error= get_var_with_binlog(thd, thd->lex->sql_command, name, &var_entry); 04082 04083 if (var_entry) 04084 { 04085 collation.set(var_entry->collation); 04086 switch (var_entry->type) { 04087 case REAL_RESULT: 04088 max_length= DBL_DIG + 8; 04089 break; 04090 case INT_RESULT: 04091 max_length= MAX_BIGINT_WIDTH; 04092 decimals=0; 04093 break; 04094 case STRING_RESULT: 04095 max_length= MAX_BLOB_WIDTH; 04096 break; 04097 case DECIMAL_RESULT: 04098 max_length= DECIMAL_MAX_STR_LENGTH; 04099 decimals= DECIMAL_MAX_SCALE; 04100 break; 04101 case ROW_RESULT: // Keep compiler happy 04102 default: 04103 DBUG_ASSERT(0); 04104 break; 04105 } 04106 } 04107 else 04108 { 04109 collation.set(&my_charset_bin, DERIVATION_IMPLICIT); 04110 null_value= 1; 04111 } 04112 04113 if (error) 04114 thd->fatal_error(); 04115 04116 return; 04117 } 04118 04119 04120 bool Item_func_get_user_var::const_item() const 04121 { 04122 return (!var_entry || current_thd->query_id != var_entry->update_query_id); 04123 } 04124 04125 04126 enum Item_result Item_func_get_user_var::result_type() const 04127 { 04128 user_var_entry *entry; 04129 if (!(entry = (user_var_entry*) hash_search(¤t_thd->user_vars, 04130 (byte*) name.str, 04131 name.length))) 04132 return STRING_RESULT; 04133 return entry->type; 04134 } 04135 04136 04137 void Item_func_get_user_var::print(String *str) 04138 { 04139 str->append(STRING_WITH_LEN("(@")); 04140 str->append(name.str,name.length); 04141 str->append(')'); 04142 } 04143 04144 04145 bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const 04146 { 04147 /* Assume we don't have rtti */ 04148 if (this == item) 04149 return 1; // Same item is same. 04150 /* Check if other type is also a get_user_var() object */ 04151 if (item->type() != FUNC_ITEM || 04152 ((Item_func*) item)->functype() != functype()) 04153 return 0; 04154 Item_func_get_user_var *other=(Item_func_get_user_var*) item; 04155 return (name.length == other->name.length && 04156 !memcmp(name.str, other->name.str, name.length)); 04157 } 04158 04159 04160 bool Item_func_get_user_var::set_value(THD *thd, 04161 sp_rcontext */*ctx*/, Item **it) 04162 { 04163 Item_func_set_user_var *suv= new Item_func_set_user_var(get_name(), *it); 04164 /* 04165 Item_func_set_user_var is not fixed after construction, call 04166 fix_fields(). 04167 */ 04168 return (!suv || suv->fix_fields(thd, it) || suv->check() || suv->update()); 04169 } 04170 04171 04172 bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref) 04173 { 04174 DBUG_ASSERT(fixed == 0); 04175 if (Item::fix_fields(thd, ref) || 04176 !(entry= get_variable(&thd->user_vars, name, 1))) 04177 return TRUE; 04178 entry->type= STRING_RESULT; 04179 /* 04180 Let us set the same collation which is used for loading 04181 of fields in LOAD DATA INFILE. 04182 (Since Item_user_var_as_out_param is used only there). 04183 */ 04184 entry->collation.set(thd->variables.collation_database); 04185 entry->update_query_id= thd->query_id; 04186 return FALSE; 04187 } 04188 04189 04190 void Item_user_var_as_out_param::set_null_value(CHARSET_INFO* cs) 04191 { 04192 if (::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs, 04193 DERIVATION_IMPLICIT, 0 /* unsigned_arg */)) 04194 current_thd->fatal_error(); // Probably end of memory 04195 } 04196 04197 04198 void Item_user_var_as_out_param::set_value(const char *str, uint length, 04199 CHARSET_INFO* cs) 04200 { 04201 if (::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs, 04202 DERIVATION_IMPLICIT, 0 /* unsigned_arg */)) 04203 current_thd->fatal_error(); // Probably end of memory 04204 } 04205 04206 04207 double Item_user_var_as_out_param::val_real() 04208 { 04209 DBUG_ASSERT(0); 04210 return 0.0; 04211 } 04212 04213 04214 longlong Item_user_var_as_out_param::val_int() 04215 { 04216 DBUG_ASSERT(0); 04217 return 0; 04218 } 04219 04220 04221 String* Item_user_var_as_out_param::val_str(String *str) 04222 { 04223 DBUG_ASSERT(0); 04224 return 0; 04225 } 04226 04227 04228 my_decimal* Item_user_var_as_out_param::val_decimal(my_decimal *decimal_buffer) 04229 { 04230 DBUG_ASSERT(0); 04231 return 0; 04232 } 04233 04234 04235 void Item_user_var_as_out_param::print(String *str) 04236 { 04237 str->append('@'); 04238 str->append(name.str,name.length); 04239 } 04240 04241 04242 Item_func_get_system_var:: 04243 Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg, 04244 LEX_STRING *component_arg, const char *name_arg, 04245 size_t name_len_arg) 04246 :var(var_arg), var_type(var_type_arg), component(*component_arg) 04247 { 04248 /* set_name() will allocate the name */ 04249 set_name(name_arg, name_len_arg, system_charset_info); 04250 } 04251 04252 04253 bool 04254 Item_func_get_system_var::fix_fields(THD *thd, Item **ref) 04255 { 04256 Item *item; 04257 DBUG_ENTER("Item_func_get_system_var::fix_fields"); 04258 04259 /* 04260 Evaluate the system variable and substitute the result (a basic constant) 04261 instead of this item. If the variable can not be evaluated, 04262 the error is reported in sys_var::item(). 04263 */ 04264 if (!(item= var->item(thd, var_type, &component))) 04265 DBUG_RETURN(1); // Impossible 04266 item->set_name(name, 0, system_charset_info); // don't allocate a new name 04267 thd->change_item_tree(ref, item); 04268 04269 DBUG_RETURN(0); 04270 } 04271 04272 04273 longlong Item_func_inet_aton::val_int() 04274 { 04275 DBUG_ASSERT(fixed == 1); 04276 uint byte_result = 0; 04277 ulonglong result = 0; // We are ready for 64 bit addresses 04278 const char *p,* end; 04279 char c = '.'; // we mark c to indicate invalid IP in case length is 0 04280 char buff[36]; 04281 int dot_count= 0; 04282 04283 String *s,tmp(buff,sizeof(buff),&my_charset_bin); 04284 if (!(s = args[0]->val_str(&tmp))) // If null value 04285 goto err; 04286 null_value=0; 04287 04288 end= (p = s->ptr()) + s->length(); 04289 while (p < end) 04290 { 04291 c = *p++; 04292 int digit = (int) (c - '0'); // Assume ascii 04293 if (digit >= 0 && digit <= 9) 04294 { 04295 if ((byte_result = byte_result * 10 + digit) > 255) 04296 goto err; // Wrong address 04297 } 04298 else if (c == '.') 04299 { 04300 dot_count++; 04301 result= (result << 8) + (ulonglong) byte_result; 04302 byte_result = 0; 04303 } 04304 else 04305 goto err; // Invalid character 04306 } 04307 if (c != '.') // IP number can't end on '.' 04308 { 04309 /* 04310 Handle short-forms addresses according to standard. Examples: 04311 127 -> 0.0.0.127 04312 127.1 -> 127.0.0.1 04313 127.2.1 -> 127.2.0.1 04314 */ 04315 switch (dot_count) { 04316 case 1: result<<= 8; /* Fall through */ 04317 case 2: result<<= 8; /* Fall through */ 04318 } 04319 return (result << 8) + (ulonglong) byte_result; 04320 } 04321 04322 err: 04323 null_value=1; 04324 return 0; 04325 } 04326 04327 04328 void Item_func_match::init_search(bool no_order) 04329 { 04330 DBUG_ENTER("Item_func_match::init_search"); 04331 04332 /* Check if init_search() has been called before */ 04333 if (ft_handler) 04334 DBUG_VOID_RETURN; 04335 04336 if (key == NO_SUCH_KEY) 04337 { 04338 List<Item> fields; 04339 fields.push_back(new Item_string(" ",1, cmp_collation.collation)); 04340 for (uint i=1; i < arg_count; i++) 04341 fields.push_back(args[i]); 04342 concat=new Item_func_concat_ws(fields); 04343 /* 04344 Above function used only to get value and do not need fix_fields for it: 04345 Item_string - basic constant 04346 fields - fix_fields() was already called for this arguments 04347 Item_func_concat_ws - do not need fix_fields() to produce value 04348 */ 04349 concat->quick_fix_field(); 04350 } 04351 04352 if (master) 04353 { 04354 join_key=master->join_key=join_key|master->join_key; 04355 master->init_search(no_order); 04356 ft_handler=master->ft_handler; 04357 join_key=master->join_key; 04358 DBUG_VOID_RETURN; 04359 } 04360 04361 String *ft_tmp= 0; 04362 04363 // MATCH ... AGAINST (NULL) is meaningless, but possible 04364 if (!(ft_tmp=key_item()->val_str(&value))) 04365 { 04366 ft_tmp= &value; 04367 value.set("",0,cmp_collation.collation); 04368 } 04369 04370 if (ft_tmp->charset() != cmp_collation.collation) 04371 { 04372 uint dummy_errors; 04373 search_value.copy(ft_tmp->ptr(), ft_tmp->length(), ft_tmp->charset(), 04374 cmp_collation.collation, &dummy_errors); 04375 ft_tmp= &search_value; 04376 } 04377 04378 if (join_key && !no_order) 04379 flags|=FT_SORTED; 04380 ft_handler=table->file->ft_init_ext(flags, key, ft_tmp); 04381 04382 if (join_key) 04383 table->file->ft_handler=ft_handler; 04384 04385 DBUG_VOID_RETURN; 04386 } 04387 04388 04389 bool Item_func_match::fix_fields(THD *thd, Item **ref) 04390 { 04391 DBUG_ASSERT(fixed == 0); 04392 Item *item; 04393 LINT_INIT(item); // Safe as arg_count is > 1 04394 04395 maybe_null=1; 04396 join_key=0; 04397 04398 /* 04399 const_item is assumed in quite a bit of places, so it would be difficult 04400 to remove; If it would ever to be removed, this should include 04401 modifications to find_best and auto_close as complement to auto_init code 04402 above. 04403 */ 04404 if (Item_func::fix_fields(thd, ref) || 04405 !args[0]->const_during_execution()) 04406 { 04407 my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST"); 04408 return TRUE; 04409 } 04410 04411 const_item_cache=0; 04412 for (uint i=1 ; i < arg_count ; i++) 04413 { 04414 item=args[i]; 04415 if (item->type() == Item::REF_ITEM) 04416 args[i]= item= *((Item_ref *)item)->ref; 04417 if (item->type() != Item::FIELD_ITEM) 04418 key=NO_SUCH_KEY; 04419 } 04420 /* 04421 Check that all columns come from the same table. 04422 We've already checked that columns in MATCH are fields so 04423 PARAM_TABLE_BIT can only appear from AGAINST argument. 04424 */ 04425 if ((used_tables_cache & ~PARAM_TABLE_BIT) != item->used_tables()) 04426 key=NO_SUCH_KEY; 04427 04428 if (key == NO_SUCH_KEY && !(flags & FT_BOOL)) 04429 { 04430 my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH"); 04431 return TRUE; 04432 } 04433 table=((Item_field *)item)->field->table; 04434 if (!(table->file->ha_table_flags() & HA_CAN_FULLTEXT)) 04435 { 04436 my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0)); 04437 return 1; 04438 } 04439 table->fulltext_searched=1; 04440 return agg_arg_collations_for_comparison(cmp_collation, 04441 args+1, arg_count-1, 0); 04442 } 04443 04444 bool Item_func_match::fix_index() 04445 { 04446 Item_field *item; 04447 uint ft_to_key[MAX_KEY], ft_cnt[MAX_KEY], fts=0, keynr; 04448 uint max_cnt=0, mkeys=0, i; 04449 04450 if (key == NO_SUCH_KEY) 04451 return 0; 04452 04453 if (!table) 04454 goto err; 04455 04456 for (keynr=0 ; keynr < table->s->keys ; keynr++) 04457 { 04458 if ((table->key_info[keynr].flags & HA_FULLTEXT) && 04459 (table->keys_in_use_for_query.is_set(keynr))) 04460 { 04461 ft_to_key[fts]=keynr; 04462 ft_cnt[fts]=0; 04463 fts++; 04464 } 04465 } 04466 04467 if (!fts) 04468 goto err; 04469 04470 for (i=1; i < arg_count; i++) 04471 { 04472 item=(Item_field*)args[i]; 04473 for (keynr=0 ; keynr < fts ; keynr++) 04474 { 04475 KEY *ft_key=&table->key_info[ft_to_key[keynr]]; 04476 uint key_parts=ft_key->key_parts; 04477 04478 for (uint part=0 ; part < key_parts ; part++) 04479 { 04480 if (item->field->eq(ft_key->key_part[part].field)) 04481 ft_cnt[keynr]++; 04482 } 04483 } 04484 } 04485 04486 for (keynr=0 ; keynr < fts ; keynr++) 04487 { 04488 if (ft_cnt[keynr] > max_cnt) 04489 { 04490 mkeys=0; 04491 max_cnt=ft_cnt[mkeys]=ft_cnt[keynr]; 04492 ft_to_key[mkeys]=ft_to_key[keynr]; 04493 continue; 04494 } 04495 if (max_cnt && ft_cnt[keynr] == max_cnt) 04496 { 04497 mkeys++; 04498 ft_cnt[mkeys]=ft_cnt[keynr]; 04499 ft_to_key[mkeys]=ft_to_key[keynr]; 04500 continue; 04501 } 04502 } 04503 04504 for (keynr=0 ; keynr <= mkeys ; keynr++) 04505 { 04506 // partial keys doesn't work 04507 if (max_cnt < arg_count-1 || 04508 max_cnt < table->key_info[ft_to_key[keynr]].key_parts) 04509 continue; 04510 04511 key=ft_to_key[keynr]; 04512 04513 return 0; 04514 } 04515 04516 err: 04517 if (flags & FT_BOOL) 04518 { 04519 key=NO_SUCH_KEY; 04520 return 0; 04521 } 04522 my_message(ER_FT_MATCHING_KEY_NOT_FOUND, 04523 ER(ER_FT_MATCHING_KEY_NOT_FOUND), MYF(0)); 04524 return 1; 04525 } 04526 04527 04528 bool Item_func_match::eq(const Item *item, bool binary_cmp) const 04529 { 04530 if (item->type() != FUNC_ITEM || 04531 ((Item_func*)item)->functype() != FT_FUNC || 04532 flags != ((Item_func_match*)item)->flags) 04533 return 0; 04534 04535 Item_func_match *ifm=(Item_func_match*) item; 04536 04537 if (key == ifm->key && table == ifm->table && 04538 key_item()->eq(ifm->key_item(), binary_cmp)) 04539 return 1; 04540 04541 return 0; 04542 } 04543 04544 04545 double Item_func_match::val_real() 04546 { 04547 DBUG_ASSERT(fixed == 1); 04548 DBUG_ENTER("Item_func_match::val"); 04549 if (ft_handler == NULL) 04550 DBUG_RETURN(-1.0); 04551 04552 if (key != NO_SUCH_KEY && table->null_row) /* NULL row from an outer join */ 04553 DBUG_RETURN(0.0); 04554 04555 if (join_key) 04556 { 04557 if (table->file->ft_handler) 04558 DBUG_RETURN(ft_handler->please->get_relevance(ft_handler)); 04559 join_key=0; 04560 } 04561 04562 if (key == NO_SUCH_KEY) 04563 { 04564 String *a= concat->val_str(&value); 04565 if ((null_value= (a == 0))) 04566 DBUG_RETURN(0); 04567 DBUG_RETURN(ft_handler->please->find_relevance(ft_handler, 04568 (byte *)a->ptr(), a->length())); 04569 } 04570 DBUG_RETURN(ft_handler->please->find_relevance(ft_handler, 04571 table->record[0], 0)); 04572 } 04573 04574 void Item_func_match::print(String *str) 04575 { 04576 str->append(STRING_WITH_LEN("(match ")); 04577 print_args(str, 1); 04578 str->append(STRING_WITH_LEN(" against (")); 04579 args[0]->print(str); 04580 if (flags & FT_BOOL) 04581 str->append(STRING_WITH_LEN(" in boolean mode")); 04582 else if (flags & FT_EXPAND) 04583 str->append(STRING_WITH_LEN(" with query expansion")); 04584 str->append(STRING_WITH_LEN("))")); 04585 } 04586 04587 longlong Item_func_bit_xor::val_int() 04588 { 04589 DBUG_ASSERT(fixed == 1); 04590 ulonglong arg1= (ulonglong) args[0]->val_int(); 04591 ulonglong arg2= (ulonglong) args[1]->val_int(); 04592 if ((null_value= (args[0]->null_value || args[1]->null_value))) 04593 return 0; 04594 return (longlong) (arg1 ^ arg2); 04595 } 04596 04597 04598 /*************************************************************************** 04599 System variables 04600 ****************************************************************************/ 04601 04602 /* 04603 Return value of an system variable base[.name] as a constant item 04604 04605 SYNOPSIS 04606 get_system_var() 04607 thd Thread handler 04608 var_type global / session 04609 name Name of base or system variable 04610 component Component. 04611 04612 NOTES 04613 If component.str = 0 then the variable name is in 'name' 04614 04615 RETURN 04616 0 error 04617 # constant item 04618 */ 04619 04620 04621 Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, 04622 LEX_STRING component) 04623 { 04624 sys_var *var; 04625 LEX_STRING *base_name, *component_name; 04626 04627 if (component.str) 04628 { 04629 base_name= &component; 04630 component_name= &name; 04631 } 04632 else 04633 { 04634 base_name= &name; 04635 component_name= &component; // Empty string 04636 } 04637 04638 if (!(var= find_sys_var(base_name->str, base_name->length))) 04639 return 0; 04640 if (component.str) 04641 { 04642 if (!var->is_struct()) 04643 { 04644 my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), base_name->str); 04645 return 0; 04646 } 04647 } 04648 thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT); 04649 04650 set_if_smaller(component_name->length, MAX_SYS_VAR_LENGTH); 04651 04652 return new Item_func_get_system_var(var, var_type, component_name, 04653 NULL, 0); 04654 } 04655 04656 04657 /* 04658 Check a user level lock. 04659 04660 SYNOPSIS: 04661 val_int() 04662 04663 RETURN VALUES 04664 1 Available 04665 0 Already taken 04666 NULL Error 04667 */ 04668 04669 longlong Item_func_is_free_lock::val_int() 04670 { 04671 DBUG_ASSERT(fixed == 1); 04672 String *res=args[0]->val_str(&value); 04673 User_level_lock *ull; 04674 04675 null_value=0; 04676 if (!res || !res->length()) 04677 { 04678 null_value=1; 04679 return 0; 04680 } 04681 04682 pthread_mutex_lock(&LOCK_user_locks); 04683 ull= (User_level_lock *) hash_search(&hash_user_locks, (byte*) res->ptr(), 04684 res->length()); 04685 pthread_mutex_unlock(&LOCK_user_locks); 04686 if (!ull || !ull->locked) 04687 return 1; 04688 return 0; 04689 } 04690 04691 longlong Item_func_is_used_lock::val_int() 04692 { 04693 DBUG_ASSERT(fixed == 1); 04694 String *res=args[0]->val_str(&value); 04695 User_level_lock *ull; 04696 04697 null_value=1; 04698 if (!res || !res->length()) 04699 return 0; 04700 04701 pthread_mutex_lock(&LOCK_user_locks); 04702 ull= (User_level_lock *) hash_search(&hash_user_locks, (byte*) res->ptr(), 04703 res->length()); 04704 pthread_mutex_unlock(&LOCK_user_locks); 04705 if (!ull || !ull->locked) 04706 return 0; 04707 04708 null_value=0; 04709 return ull->thread_id; 04710 } 04711 04712 04713 longlong Item_func_row_count::val_int() 04714 { 04715 DBUG_ASSERT(fixed == 1); 04716 THD *thd= current_thd; 04717 04718 return thd->row_count_func; 04719 } 04720 04721 04722 Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, sp_name *name) 04723 :Item_func(), context(context_arg), m_name(name), m_sp(NULL), 04724 result_field(NULL) 04725 { 04726 maybe_null= 1; 04727 m_name->init_qname(current_thd); 04728 dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE)); 04729 dummy_table->s= (TABLE_SHARE*) (dummy_table+1); 04730 } 04731 04732 04733 Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, 04734 sp_name *name, List<Item> &list) 04735 :Item_func(list), context(context_arg), m_name(name), m_sp(NULL), 04736 result_field(NULL) 04737 { 04738 maybe_null= 1; 04739 m_name->init_qname(current_thd); 04740 dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE)); 04741 dummy_table->s= (TABLE_SHARE*) (dummy_table+1); 04742 } 04743 04744 04745 void 04746 Item_func_sp::cleanup() 04747 { 04748 if (result_field) 04749 { 04750 delete result_field; 04751 result_field= NULL; 04752 } 04753 m_sp= NULL; 04754 Item_func::cleanup(); 04755 } 04756 04757 const char * 04758 Item_func_sp::func_name() const 04759 { 04760 THD *thd= current_thd; 04761 /* Calculate length to avoid reallocation of string for sure */ 04762 uint len= ((m_name->m_db.length + 04763 m_name->m_name.length)*2 + //characters*quoting 04764 2 + // ` and ` 04765 1 + // . 04766 1 + // end of string 04767 ALIGN_SIZE(1)); // to avoid String reallocation 04768 String qname((char *)alloc_root(thd->mem_root, len), len, 04769 system_charset_info); 04770 04771 qname.length(0); 04772 append_identifier(thd, &qname, m_name->m_db.str, m_name->m_db.length); 04773 qname.append('.'); 04774 append_identifier(thd, &qname, m_name->m_name.str, m_name->m_name.length); 04775 return qname.ptr(); 04776 } 04777 04778 04779 Field * 04780 Item_func_sp::sp_result_field(void) const 04781 { 04782 Field *field; 04783 DBUG_ENTER("Item_func_sp::sp_result_field"); 04784 DBUG_PRINT("info", ("sp: %s, flags: %x, level: %lu", 04785 (m_sp ? "YES" : "NO"), 04786 (m_sp ? m_sp->m_flags : (uint)0), 04787 (m_sp ? m_sp->m_recursion_level : (ulong)0))); 04788 04789 if (!m_sp) 04790 { 04791 THD *thd= current_thd; 04792 if (!(m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name, 04793 &thd->sp_func_cache, TRUE))) 04794 { 04795 my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); 04796 DBUG_RETURN(0); 04797 } 04798 } 04799 if (!dummy_table->alias) 04800 { 04801 char *empty_name= (char *) ""; 04802 dummy_table->alias= empty_name; 04803 dummy_table->maybe_null= maybe_null; 04804 dummy_table->in_use= current_thd; 04805 dummy_table->copy_blobs= TRUE; 04806 dummy_table->s->table_cache_key.str = empty_name; 04807 dummy_table->s->table_name.str= empty_name; 04808 dummy_table->s->db.str= empty_name; 04809 } 04810 if (!(field= m_sp->create_result_field(max_length, name, dummy_table))) 04811 my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); 04812 04813 DBUG_RETURN(field); 04814 } 04815 04816 04817 /* 04818 Execute function & store value in field 04819 04820 RETURN 04821 0 value <> NULL 04822 1 value = NULL or error 04823 */ 04824 04825 bool 04826 Item_func_sp::execute(Field **flp) 04827 { 04828 THD *thd= current_thd; 04829 Field *f; 04830 04831 /* 04832 Get field in virtual tmp table to store result. Create the field if 04833 invoked first time. 04834 */ 04835 04836 if (!(f= *flp)) 04837 { 04838 if (!(*flp= f= sp_result_field())) 04839 { 04840 /* Error set by sp_result_field() */ 04841 null_value= 1; 04842 return TRUE; 04843 } 04844 04845 f->move_field((f->pack_length() > sizeof(result_buf)) ? 04846 sql_alloc(f->pack_length()) : result_buf); 04847 f->null_ptr= (uchar *)&null_value; 04848 f->null_bit= 1; 04849 } 04850 04851 /* Execute function and store the return value in the field. */ 04852 04853 if (execute_impl(thd, f)) 04854 { 04855 null_value= 1; 04856 context->process_error(thd); 04857 return TRUE; 04858 } 04859 04860 /* Check that the field (the value) is not NULL. */ 04861 04862 null_value= f->is_null(); 04863 04864 return null_value; 04865 } 04866 04867 04868 bool 04869 Item_func_sp::execute_impl(THD *thd, Field *return_value_fld) 04870 { 04871 bool err_status= TRUE; 04872 Sub_statement_state statement_state; 04873 #ifndef NO_EMBEDDED_ACCESS_CHECKS 04874 Security_context *save_security_ctx= thd->security_ctx; 04875 #endif 04876 04877 DBUG_ENTER("Item_func_sp::execute_impl"); 04878 04879 #ifndef NO_EMBEDDED_ACCESS_CHECKS 04880 if (context->security_ctx) 04881 { 04882 /* Set view definer security context */ 04883 thd->security_ctx= context->security_ctx; 04884 } 04885 #endif 04886 if (find_and_check_access(thd)) 04887 goto error; 04888 04889 /* 04890 Disable the binlogging if this is not a SELECT statement. If this is a 04891 SELECT, leave binlogging on, so execute_function() code writes the 04892 function call into binlog. 04893 */ 04894 thd->reset_sub_statement_state(&statement_state, SUB_STMT_FUNCTION); 04895 err_status= m_sp->execute_function(thd, args, arg_count, return_value_fld); 04896 thd->restore_sub_statement_state(&statement_state); 04897 04898 error: 04899 #ifndef NO_EMBEDDED_ACCESS_CHECKS 04900 thd->security_ctx= save_security_ctx; 04901 #endif 04902 04903 DBUG_RETURN(err_status); 04904 } 04905 04906 04907 void 04908 Item_func_sp::make_field(Send_field *tmp_field) 04909 { 04910 Field *field; 04911 DBUG_ENTER("Item_func_sp::make_field"); 04912 if ((field= sp_result_field())) 04913 { 04914 field->make_field(tmp_field); 04915 delete field; 04916 DBUG_VOID_RETURN; 04917 } 04918 init_make_field(tmp_field, MYSQL_TYPE_VARCHAR); 04919 DBUG_VOID_RETURN; 04920 } 04921 04922 04923 enum enum_field_types 04924 Item_func_sp::field_type() const 04925 { 04926 Field *field; 04927 DBUG_ENTER("Item_func_sp::field_type"); 04928 04929 if (result_field) 04930 DBUG_RETURN(result_field->type()); 04931 if ((field= sp_result_field())) 04932 { 04933 enum_field_types result= field->type(); 04934 delete field; 04935 DBUG_RETURN(result); 04936 } 04937 DBUG_RETURN(MYSQL_TYPE_VARCHAR); 04938 } 04939 04940 04941 Item_result 04942 Item_func_sp::result_type() const 04943 { 04944 Field *field; 04945 DBUG_ENTER("Item_func_sp::result_type"); 04946 DBUG_PRINT("info", ("m_sp = %p", m_sp)); 04947 04948 if (result_field) 04949 DBUG_RETURN(result_field->result_type()); 04950 if ((field= sp_result_field())) 04951 { 04952 Item_result result= field->result_type(); 04953 delete field; 04954 DBUG_RETURN(result); 04955 } 04956 DBUG_RETURN(STRING_RESULT); 04957 } 04958 04959 void 04960 Item_func_sp::fix_length_and_dec() 04961 { 04962 Field *field; 04963 DBUG_ENTER("Item_func_sp::fix_length_and_dec"); 04964 04965 if (result_field) 04966 { 04967 decimals= result_field->decimals(); 04968 max_length= result_field->field_length; 04969 collation.set(result_field->charset()); 04970 DBUG_VOID_RETURN; 04971 } 04972 04973 if (!(field= sp_result_field())) 04974 { 04975 context->process_error(current_thd); 04976 DBUG_VOID_RETURN; 04977 } 04978 decimals= field->decimals(); 04979 max_length= field->field_length; 04980 collation.set(field->charset()); 04981 maybe_null= 1; 04982 delete field; 04983 DBUG_VOID_RETURN; 04984 } 04985 04986 04987 longlong Item_func_found_rows::val_int() 04988 { 04989 DBUG_ASSERT(fixed == 1); 04990 return current_thd->found_rows(); 04991 } 04992 04993 04994 Field * 04995 Item_func_sp::tmp_table_field(TABLE *t_arg) 04996 { 04997 Field *field= 0; 04998 DBUG_ENTER("Item_func_sp::tmp_table_field"); 04999 05000 if (m_sp) 05001 field= m_sp->create_result_field(max_length, (const char*) name, t_arg); 05002 05003 if (!field) 05004 field= Item_func::tmp_table_field(t_arg); 05005 05006 if (!field) 05007 my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); 05008 05009 DBUG_RETURN(field); 05010 } 05011 05012 05013 /* 05014 Find the function and check access rights to the function 05015 05016 SYNOPSIS 05017 find_and_check_access() 05018 thd thread handler 05019 05020 RETURN 05021 FALSE Access granted 05022 TRUE Requested access can't be granted or function doesn't exists 05023 05024 NOTES 05025 Checks if requested access to function can be granted to user. 05026 If function isn't found yet, it searches function first. 05027 If function can't be found or user don't have requested access 05028 error is raised. 05029 */ 05030 05031 bool 05032 Item_func_sp::find_and_check_access(THD *thd) 05033 { 05034 if (! m_sp && ! (m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name, 05035 &thd->sp_func_cache, TRUE))) 05036 { 05037 my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); 05038 return TRUE; 05039 } 05040 05041 #ifndef NO_EMBEDDED_ACCESS_CHECKS 05042 if (check_routine_access(thd, EXECUTE_ACL, 05043 m_sp->m_db.str, m_sp->m_name.str, 0, FALSE)) 05044 return TRUE; 05045 #endif 05046 05047 return FALSE; 05048 } 05049 05050 05051 bool 05052 Item_func_sp::fix_fields(THD *thd, Item **ref) 05053 { 05054 bool res; 05055 DBUG_ASSERT(fixed == 0); 05056 res= Item_func::fix_fields(thd, ref); 05057 if (!res && thd->lex->view_prepare_mode) 05058 { 05059 /* 05060 Here we check privileges of the stored routine only during view 05061 creation, in order to validate the view. A runtime check is 05062 perfomed in Item_func_sp::execute(), and this method is not 05063 called during context analysis. Notice, that during view 05064 creation we do not infer into stored routine bodies and do not 05065 check privileges of its statements, which would probably be a 05066 good idea especially if the view has SQL SECURITY DEFINER and 05067 the used stored procedure has SQL SECURITY DEFINER. 05068 */ 05069 res= find_and_check_access(thd); 05070 #ifndef NO_EMBEDDED_ACCESS_CHECKS 05071 Security_context *save_secutiry_ctx; 05072 if (!res && !(res= set_routine_security_ctx(thd, m_sp, false, 05073 &save_secutiry_ctx))) 05074 { 05075 sp_restore_security_context(thd, save_secutiry_ctx); 05076 } 05077 #endif /* ! NO_EMBEDDED_ACCESS_CHECKS */ 05078 } 05079 return res; 05080 }
1.4.7

