1 /* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
2 Copyright (c) 2009, 2020, MariaDB
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
16
17 /**
18 @file
19
20 @brief
21 This file defines all numerical functions
22 */
23
24 #ifdef USE_PRAGMA_IMPLEMENTATION
25 #pragma implementation // gcc: Class implementation
26 #endif
27
28 #include "sql_plugin.h"
29 #include "sql_priv.h"
30 /*
31 It is necessary to include set_var.h instead of item.h because there
32 are dependencies on include order for set_var.h and item.h. This
33 will be resolved later.
34 */
35 #include "sql_class.h" // set_var.h: THD
36 #include "set_var.h"
37 #include "slave.h" // for wait_for_master_pos
38 #include "sql_show.h" // append_identifier
39 #include "strfunc.h" // find_type
40 #include "sql_parse.h" // is_update_query
41 #include "sql_acl.h" // EXECUTE_ACL
42 #include "mysqld.h" // LOCK_short_uuid_generator
43 #include "rpl_mi.h"
44 #include "sql_time.h"
45 #include <m_ctype.h>
46 #include <hash.h>
47 #include <time.h>
48 #include <ft_global.h>
49 #include <my_bit.h>
50
51 #include "sp_head.h"
52 #include "sp_rcontext.h"
53 #include "sp.h"
54 #include "set_var.h"
55 #include "debug_sync.h"
56 #include "sql_base.h"
57 #include "sql_cte.h"
58
59 #ifdef NO_EMBEDDED_ACCESS_CHECKS
60 #define sp_restore_security_context(A,B) while (0) {}
61 #endif
62
63 bool check_reserved_words(const LEX_CSTRING *name)
Create_func_arg0()64 {
65 if (lex_string_eq(name, STRING_WITH_LEN("GLOBAL")) ||
66 lex_string_eq(name, STRING_WITH_LEN("LOCAL")) ||
67 lex_string_eq(name, STRING_WITH_LEN("SESSION")))
68 return TRUE;
69 return FALSE;
70 }
71
72
73 /**
74 Test if the sum of arguments overflows the ulonglong range.
75 */
76 static inline bool test_if_sum_overflows_ull(ulonglong arg1, ulonglong arg2)
77 {
78 return ULONGLONG_MAX - arg1 < arg2;
79 }
80
81
82 /**
83 Allocate memory for arguments using tmp_args or thd->alloc().
84 @retval false - success
85 @retval true - error (arg_count is set to 0 for conveniece)
86 */
87 bool Item_args::alloc_arguments(THD *thd, uint count)
88 {
Create_func_arg1()89 if (count <= 2)
90 {
91 args= tmp_arg;
92 return false;
93 }
94 if ((args= (Item**) thd->alloc(sizeof(Item*) * count)) == NULL)
95 {
96 arg_count= 0;
97 return true;
98 }
99 return false;
100 }
101
102
103 void Item_args::set_arguments(THD *thd, List<Item> &list)
104 {
105 if (alloc_arguments(thd, list.elements))
106 return;
107 List_iterator_fast<Item> li(list);
108 Item *item;
109 for (arg_count= 0; (item= li++); )
110 args[arg_count++]= item;
111 }
112
113
Create_func_arg2()114 Item_args::Item_args(THD *thd, const Item_args *other)
115 :arg_count(other->arg_count)
116 {
117 if (arg_count <= 2)
118 {
119 args= tmp_arg;
120 }
121 else if (!(args= (Item**) thd->alloc(sizeof(Item*) * arg_count)))
122 {
123 arg_count= 0;
124 return;
125 }
126 if (arg_count)
127 memcpy(args, other->args, sizeof(Item*) * arg_count);
128 }
129
130
131 void Item_func::sync_with_sum_func_and_with_field(List<Item> &list)
132 {
133 List_iterator_fast<Item> li(list);
134 Item *item;
135 while ((item= li++))
136 {
137 with_sum_func|= item->with_sum_func;
138 with_window_func|= item->with_window_func;
139 with_field|= item->with_field;
Create_func_arg3()140 with_param|= item->with_param;
141 }
~Create_func_arg3()142 }
143
144
145 bool Item_func::check_argument_types_like_args0() const
146 {
147 if (arg_count < 2)
148 return false;
149 uint cols= args[0]->cols();
150 bool is_scalar= args[0]->type_handler()->is_scalar_type();
151 for (uint i= 1; i < arg_count; i++)
152 {
153 if (is_scalar != args[i]->type_handler()->is_scalar_type())
154 {
155 my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
156 args[0]->type_handler()->name().ptr(),
157 args[i]->type_handler()->name().ptr(), func_name());
158 return true;
159 }
160 if (args[i]->check_cols(cols))
161 return true;
162 }
163 return false;
164 }
165
166
167 bool Item_func::check_argument_types_or_binary(const Type_handler *handler,
168 uint start, uint end) const
169 {
170 for (uint i= start; i < end ; i++)
171 {
172 DBUG_ASSERT(i < arg_count);
173 if (args[i]->check_type_or_binary(func_name(), handler))
174 return true;
175 }
176 return false;
177 }
178
179
180 bool Item_func::check_argument_types_traditional_scalar(uint start,
181 uint end) const
182 {
Create_func_no_geom()183 for (uint i= start; i < end ; i++)
184 {
~Create_func_no_geom()185 DBUG_ASSERT(i < arg_count);
186 if (args[i]->check_type_traditional_scalar(func_name()))
187 return true;
188 }
189 return false;
190 }
191
192
193 bool Item_func::check_argument_types_can_return_int(uint start,
194 uint end) const
195 {
196 for (uint i= start; i < end ; i++)
197 {
198 DBUG_ASSERT(i < arg_count);
199 if (args[i]->check_type_can_return_int(func_name()))
200 return true;
201 }
202 return false;
203 }
Create_func_abs()204
205
206 bool Item_func::check_argument_types_can_return_real(uint start,
207 uint end) const
208 {
209 for (uint i= start; i < end ; i++)
210 {
211 DBUG_ASSERT(i < arg_count);
212 if (args[i]->check_type_can_return_real(func_name()))
213 return true;
214 }
215 return false;
216 }
Create_func_acos()217
218
219 bool Item_func::check_argument_types_can_return_text(uint start,
220 uint end) const
221 {
222 for (uint i= start; i < end ; i++)
223 {
224 DBUG_ASSERT(i < arg_count);
225 if (args[i]->check_type_can_return_text(func_name()))
226 return true;
227 }
228 return false;
229 }
Create_func_addtime()230
231
232 bool Item_func::check_argument_types_can_return_str(uint start,
233 uint end) const
234 {
235 for (uint i= start; i < end ; i++)
236 {
237 DBUG_ASSERT(i < arg_count);
238 if (args[i]->check_type_can_return_str(func_name()))
239 return true;
240 }
241 return false;
242 }
Create_func_aes_encrypt()243
244
245 bool Item_func::check_argument_types_can_return_date(uint start,
246 uint end) const
247 {
248 for (uint i= start; i < end ; i++)
249 {
250 DBUG_ASSERT(i < arg_count);
251 if (args[i]->check_type_can_return_date(func_name()))
252 return true;
253 }
254 return false;
255 }
Create_func_aes_decrypt()256
257
258 bool Item_func::check_argument_types_can_return_time(uint start,
259 uint end) const
260 {
261 for (uint i= start; i < end ; i++)
262 {
263 DBUG_ASSERT(i < arg_count);
264 if (args[i]->check_type_can_return_time(func_name()))
265 return true;
266 }
267 return false;
268 }
269
Create_func_area()270
271 bool Item_func::check_argument_types_scalar(uint start, uint end) const
272 {
273 for (uint i= start; i < end; i++)
274 {
275 DBUG_ASSERT(i < arg_count);
276 if (args[i]->check_type_scalar(func_name()))
277 return true;
278 }
279 return false;
280 }
281
282
283 /*
284 Resolve references to table column for a function and its argument
Create_func_as_wkb()285
286 SYNOPSIS:
287 fix_fields()
288 thd Thread object
289 ref Pointer to where this object is used. This reference
290 is used if we want to replace this object with another
291 one (for example in the summary functions).
292
293 DESCRIPTION
294 Call fix_fields() for all arguments to the function. The main intention
295 is to allow all Item_field() objects to setup pointers to the table fields.
296
297 Sets as a side effect the following class variables:
298 maybe_null Set if any argument may return NULL
299 with_sum_func Set if any of the arguments contains a sum function
300 with_window_func Set if any of the arguments contain a window function
301 with_field Set if any of the arguments contains or is a field
302 used_tables_cache Set to union of the tables used by arguments
303
304 str_value.charset If this is a string function, set this to the
305 character set for the first argument.
306 If any argument is binary, this is set to binary
307
308 If for any item any of the defaults are wrong, then this can
309 be fixed in the fix_length_and_dec() function that is called
310 after this one or by writing a specialized fix_fields() for the
311 item.
312
313 RETURN VALUES
314 FALSE ok
315 TRUE Got error. Stored with my_error().
316 */
317
318 bool
319 Item_func::fix_fields(THD *thd, Item **ref)
320 {
321 DBUG_ASSERT(fixed == 0);
322 Item **arg,**arg_end;
323 uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
324
325 /*
326 The Used_tables_and_const_cache of "this" was initialized by
327 the constructor, or by Item_func::cleanup().
328 */
329 DBUG_ASSERT(used_tables_cache == 0);
330 DBUG_ASSERT(const_item_cache == true);
331
332 not_null_tables_cache= 0;
333
334 /*
335 Use stack limit of STACK_MIN_SIZE * 2 since
336 on some platforms a recursive call to fix_fields
337 requires more than STACK_MIN_SIZE bytes (e.g. for
338 MIPS, it takes about 22kB to make one recursive
339 call to Item_func::fix_fields())
340 */
341 if (check_stack_overrun(thd, STACK_MIN_SIZE * 2, buff))
342 return TRUE; // Fatal error if flag is set!
343 if (arg_count)
344 { // Print purify happy
345 for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
346 {
347 Item *item;
348 /*
349 We can't yet set item to *arg as fix_fields may change *arg
350 We shouldn't call fix_fields() twice, so check 'fixed' field first
351 */
352 if ((*arg)->fix_fields_if_needed(thd, arg))
353 return TRUE; /* purecov: inspected */
354 item= *arg;
355
356 if (item->maybe_null)
357 maybe_null=1;
358
359 with_sum_func= with_sum_func || item->with_sum_func;
360 with_param= with_param || item->with_param;
361 with_window_func= with_window_func || item->with_window_func;
362 with_field= with_field || item->with_field;
363 used_tables_and_const_cache_join(item);
364 not_null_tables_cache|= item->not_null_tables();
365 m_with_subquery|= item->with_subquery();
366 }
367 }
368 if (check_arguments())
369 return true;
370 if (fix_length_and_dec())
371 return TRUE;
372 fixed= 1;
373 return FALSE;
374 }
375
376 void
377 Item_func::quick_fix_field()
378 {
Create_func_bit_count()379 Item **arg,**arg_end;
~Create_func_bit_count()380 if (arg_count)
381 {
382 for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
383 {
384 if (!(*arg)->fixed)
385 (*arg)->quick_fix_field();
386 }
387 }
388 fixed= 1;
389 }
390
391
Create_func_bit_length()392 bool
393 Item_func::eval_not_null_tables(void *opt_arg)
394 {
395 Item **arg,**arg_end;
396 not_null_tables_cache= 0;
397 if (arg_count)
398 {
399 for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
400 {
401 not_null_tables_cache|= (*arg)->not_null_tables();
402 }
403 }
404 return FALSE;
405 }
~Create_func_ceiling()406
407
408 void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref,
409 bool merge)
410 {
411 Item **arg,**arg_end;
412
413 used_tables_and_const_cache_init();
414 not_null_tables_cache= 0;
415
416 if (arg_count)
417 {
418 for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
419 {
420 (*arg)->fix_after_pullout(new_parent, arg, merge);
421 Item *item= *arg;
422
423 used_tables_and_const_cache_join(item);
424 not_null_tables_cache|= item->not_null_tables();
425 }
426 }
427 }
428
429
430 void Item_func::traverse_cond(Cond_traverser traverser,
431 void *argument, traverse_order order)
Create_func_chr()432 {
433 if (arg_count)
434 {
435 Item **arg,**arg_end;
436
437 switch (order) {
438 case(PREFIX):
439 (*traverser)(this, argument);
440 for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
441 {
442 (*arg)->traverse_cond(traverser, argument, order);
443 }
444 break;
445 case (POSTFIX):
446 for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
447 {
448 (*arg)->traverse_cond(traverser, argument, order);
449 }
450 (*traverser)(this, argument);
451 }
452 }
453 else
454 (*traverser)(this, argument);
455 }
456
457
Create_func_pointonsurface()458 bool Item_args::transform_args(THD *thd, Item_transformer transformer, uchar *arg)
459 {
460 for (uint i= 0; i < arg_count; i++)
461 {
462 Item *new_item= args[i]->transform(thd, transformer, arg);
463 if (!new_item)
464 return true;
465 /*
466 THD::change_item_tree() should be called only if the tree was
467 really transformed, i.e. when a new item has been created.
468 Otherwise we'll be allocating a lot of unnecessary memory for
469 change records at each execution.
470 */
471 if (args[i] != new_item)
472 thd->change_item_tree(&args[i], new_item);
473 }
474 return false;
475 }
476
477
478 /**
479 Transform an Item_func object with a transformer callback function.
480
481 The function recursively applies the transform method to each
482 argument of the Item_func node.
483 If the call of the method for an argument item returns a new item
484 the old item is substituted for a new one.
485 After this the transformer is applied to the root node
486 of the Item_func object.
Create_func_coercibility()487 @param transformer the transformer callback function to be applied to
488 the nodes of the tree of the object
489 @param argument parameter to be passed to the transformer
490
491 @return
492 Item returned as the result of transformation of the root node
493 */
494
495 Item *Item_func::transform(THD *thd, Item_transformer transformer, uchar *argument)
496 {
497 DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
498 if (transform_args(thd, transformer, argument))
499 return 0;
500 return (this->*transformer)(thd, argument);
501 }
502
503
504 /**
505 Compile Item_func object with a processor and a transformer
506 callback functions.
507
508 First the function applies the analyzer to the root node of
509 the Item_func object. Then if the analyzer succeeds (returns TRUE)
510 the function recursively applies the compile method to each argument
Create_func_dyncol_exists()511 of the Item_func node.
512 If the call of the method for an argument item returns a new item
513 the old item is substituted for a new one.
514 After this the transformer is applied to the root node
515 of the Item_func object.
516 The compile function is not called if the analyzer returns NULL
517 in the parameter arg_p.
518
519 @param analyzer the analyzer callback function to be applied to the
520 nodes of the tree of the object
521 @param[in,out] arg_p parameter to be passed to the processor
522 @param transformer the transformer callback function to be applied to the
523 nodes of the tree of the object
524 @param arg_t parameter to be passed to the transformer
525
526 @return
527 Item returned as the result of transformation of the root node
528 */
529
530 Item *Item_func::compile(THD *thd, Item_analyzer analyzer, uchar **arg_p,
531 Item_transformer transformer, uchar *arg_t)
532 {
533 if (!(this->*analyzer)(arg_p))
534 return 0;
535 if (*arg_p && arg_count)
536 {
537 Item **arg,**arg_end;
538 for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
539 {
540 /*
541 The same parameter value of arg_p must be passed
542 to analyze any argument of the condition formula.
543 */
544 uchar *arg_v= *arg_p;
545 Item *new_item= (*arg)->compile(thd, analyzer, &arg_v, transformer,
546 arg_t);
547 if (new_item && *arg != new_item)
548 thd->change_item_tree(arg, new_item);
549 }
550 }
551 return (this->*transformer)(thd, arg_t);
552 }
553
554
555 void Item_args::propagate_equal_fields(THD *thd,
556 const Item::Context &ctx,
557 COND_EQUAL *cond)
558 {
559 uint i;
560 for (i= 0; i < arg_count; i++)
Create_func_concat()561 args[i]->propagate_equal_fields_and_change_item_tree(thd, ctx, cond,
562 &args[i]);
563 }
564
565
566 Sql_mode_dependency Item_args::value_depends_on_sql_mode_bit_or() const
567 {
568 Sql_mode_dependency res;
569 for (uint i= 0; i < arg_count; i++)
570 res|= args[i]->value_depends_on_sql_mode();
571 return res;
572 }
573
Create_func_concat_operator_oracle()574
575 /**
576 See comments in Item_cond::split_sum_func()
577 */
578
579 void Item_func::split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
580 List<Item> &fields, uint flags)
581 {
582 Item **arg, **arg_end;
583 for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
584 (*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg,
585 flags | SPLIT_SUM_SKIP_REGISTERED);
586 }
Create_func_decode_histogram()587
588
589 table_map Item_func::not_null_tables() const
590 {
591 return not_null_tables_cache;
592 }
593
594
595 void Item_func::print(String *str, enum_query_type query_type)
596 {
597 str->append(func_name());
598 str->append('(');
599 print_args(str, 0, query_type);
Create_func_decode_oracle()600 str->append(')');
~Create_func_decode_oracle()601 }
602
603
604 void Item_func::print_args(String *str, uint from, enum_query_type query_type)
605 {
606 for (uint i=from ; i < arg_count ; i++)
607 {
608 if (i != from)
609 str->append(',');
610 args[i]->print(str, query_type);
611 }
612 }
Create_func_concat_ws()613
614
615 void Item_func::print_op(String *str, enum_query_type query_type)
616 {
617 for (uint i=0 ; i < arg_count-1 ; i++)
618 {
619 args[i]->print_parenthesised(str, query_type, precedence());
620 str->append(' ');
621 str->append(func_name());
622 str->append(' ');
623 }
624 args[arg_count-1]->print_parenthesised(str, query_type, higher_precedence());
625 }
Create_func_connection_id()626
627
628 bool Item_func::eq(const Item *item, bool binary_cmp) const
629 {
630 /* Assume we don't have rtti */
631 if (this == item)
632 return 1;
633 /*
634 Ensure that we are comparing two functions and that the function
635 is deterministic.
636 */
637 if (item->type() != FUNC_ITEM || (used_tables() & RAND_TABLE_BIT))
638 return 0;
639 Item_func *item_func=(Item_func*) item;
640 Item_func::Functype func_type;
641 if ((func_type= functype()) != item_func->functype() ||
642 arg_count != item_func->arg_count ||
643 (func_type != Item_func::FUNC_SP &&
644 func_name() != item_func->func_name()) ||
645 (func_type == Item_func::FUNC_SP &&
646 my_strcasecmp(system_charset_info, func_name(), item_func->func_name())))
647 return 0;
648 return Item_args::eq(item_func, binary_cmp);
649 }
650
651
652 /*
Create_func_contains()653 bool Item_func::is_expensive_processor(uchar *arg)
654 {
655 return is_expensive();
656 }
657 */
658
659 my_decimal *Item_func::val_decimal(my_decimal *decimal_value)
660 {
661 DBUG_ASSERT(fixed);
662 longlong nr= val_int();
663 if (null_value)
664 return 0; /* purecov: inspected */
665 int2my_decimal(E_DEC_FATAL_ERROR, nr, unsigned_flag, decimal_value);
666 return decimal_value;
667 }
~Create_func_nvl2()668
669
670 bool Item_hybrid_func::fix_attributes(Item **items, uint nitems)
671 {
672 bool rc= Item_hybrid_func::type_handler()->
673 Item_hybrid_func_fix_attributes(current_thd,
674 func_name(), this, this,
675 items, nitems);
676 DBUG_ASSERT(!rc || current_thd->is_error());
677 return rc;
678 }
679
Create_func_conv()680
681 String *Item_real_func::val_str(String *str)
682 {
683 DBUG_ASSERT(fixed == 1);
684 double nr= val_real();
685 if (null_value)
686 return 0; /* purecov: inspected */
687 str->set_real(nr, decimals, collation.collation);
688 return str;
689 }
690
691
692 my_decimal *Item_real_func::val_decimal(my_decimal *decimal_value)
Create_func_convert_tz()693 {
694 DBUG_ASSERT(fixed);
695 double nr= val_real();
696 if (null_value)
697 return 0; /* purecov: inspected */
698 double2my_decimal(E_DEC_FATAL_ERROR, nr, decimal_value);
699 return decimal_value;
700 }
701
702
703 #ifdef HAVE_DLOPEN
704 void Item_udf_func::fix_num_length_and_dec()
705 {
Create_func_cos()706 uint fl_length= 0;
~Create_func_cos()707 decimals=0;
708 for (uint i=0 ; i < arg_count ; i++)
709 {
710 set_if_bigger(decimals,args[i]->decimals);
711 set_if_bigger(fl_length, args[i]->max_length);
712 }
713 max_length=float_length(decimals);
714 if (fl_length > max_length)
715 {
716 decimals= NOT_FIXED_DEC;
717 max_length= float_length(NOT_FIXED_DEC);
718 }
Create_func_cot()719 }
720 #endif
721
722
723 void Item_func::signal_divide_by_null()
724 {
725 THD *thd= current_thd;
726 if (thd->variables.sql_mode & MODE_ERROR_FOR_DIVISION_BY_ZERO)
727 push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_DIVISION_BY_ZERO,
728 ER_THD(thd, ER_DIVISION_BY_ZERO));
729 null_value= 1;
730 }
731
Create_func_crc32()732
733 Item *Item_func::get_tmp_table_item(THD *thd)
734 {
735 if (!with_sum_func && !const_item())
736 return new (thd->mem_root) Item_temptable_field(thd, result_field);
737 return copy_or_same(thd);
738 }
739
740 double Item_int_func::val_real()
741 {
742 DBUG_ASSERT(fixed == 1);
743
744 return unsigned_flag ? (double) ((ulonglong) val_int()) : (double) val_int();
745 }
Create_func_crosses()746
747
748 String *Item_int_func::val_str(String *str)
749 {
750 DBUG_ASSERT(fixed == 1);
751 longlong nr=val_int();
752 if (null_value)
753 return 0;
754 str->set_int(nr, unsigned_flag, collation.collation);
755 return str;
756 }
757
758
759 bool Item_func_connection_id::fix_length_and_dec()
Create_func_datediff()760 {
761 if (Item_long_func::fix_length_and_dec())
762 return TRUE;
763 max_length= 10;
764 return FALSE;
765 }
766
767
768 bool Item_func_connection_id::fix_fields(THD *thd, Item **ref)
769 {
770 if (Item_int_func::fix_fields(thd, ref))
771 return TRUE;
772 thd->thread_specific_used= TRUE;
Create_func_dayname()773 value= thd->variables.pseudo_thread_id;
~Create_func_dayname()774 return FALSE;
775 }
776
777
778 bool Item_num_op::fix_type_handler(const Type_aggregator *aggregator)
779 {
780 DBUG_ASSERT(arg_count == 2);
781 const Type_handler *h0= args[0]->cast_to_int_type_handler();
782 const Type_handler *h1= args[1]->cast_to_int_type_handler();
783 if (!aggregate_for_num_op(aggregator, h0, h1))
784 return false;
785 my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
Create_func_dayofmonth()786 h0->name().ptr(), h1->name().ptr(), func_name());
~Create_func_dayofmonth()787 return true;
788 }
789
790
791 bool Item_func_plus::fix_length_and_dec(void)
792 {
793 DBUG_ENTER("Item_func_plus::fix_length_and_dec");
794 DBUG_PRINT("info", ("name %s", func_name()));
795 const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_plus;
796 DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_for_result;);
797 DBUG_ASSERT(aggregator->is_commutative());
798 if (fix_type_handler(aggregator))
Create_func_dayofweek()799 DBUG_RETURN(TRUE);
~Create_func_dayofweek()800 if (Item_func_plus::type_handler()->Item_func_plus_fix_length_and_dec(this))
801 DBUG_RETURN(TRUE);
802 DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr()));
803 DBUG_RETURN(FALSE);
804 }
805
806
807 String *Item_func_hybrid_field_type::val_str_from_decimal_op(String *str)
808 {
809 my_decimal decimal_value, *val;
810 if (!(val= decimal_op_with_null_check(&decimal_value)))
811 return 0; // null is set
Create_func_dayofyear()812 DBUG_ASSERT(!null_value);
~Create_func_dayofyear()813 my_decimal_round(E_DEC_FATAL_ERROR, val, decimals, FALSE, val);
814 str->set_charset(collation.collation);
815 my_decimal2string(E_DEC_FATAL_ERROR, val, 0, 0, 0, str);
816 return str;
817 }
818
819 double Item_func_hybrid_field_type::val_real_from_decimal_op()
820 {
821 my_decimal decimal_value, *val;
822 if (!(val= decimal_op_with_null_check(&decimal_value)))
823 return 0.0; // null is set
824 double result;
Create_func_degrees()825 my_decimal2double(E_DEC_FATAL_ERROR, val, &result);
~Create_func_degrees()826 return result;
827 }
828
829 longlong Item_func_hybrid_field_type::val_int_from_decimal_op()
830 {
831 my_decimal decimal_value, *val;
832 if (!(val= decimal_op_with_null_check(&decimal_value)))
833 return 0; // null is set
834 longlong result;
835 my_decimal2int(E_DEC_FATAL_ERROR, val, unsigned_flag, &result);
836 return result;
837 }
Create_func_des_decrypt()838
839 bool Item_func_hybrid_field_type::get_date_from_decimal_op(MYSQL_TIME *ltime,
840 ulonglong fuzzydate)
841 {
842 my_decimal value, *res;
843 if (!(res= decimal_op_with_null_check(&value)) ||
844 decimal_to_datetime_with_warn(res, ltime, fuzzydate,
845 field_table_or_null(),
846 field_name_or_null()))
847 return make_zero_mysql_time(ltime, fuzzydate);
848 return (null_value= 0);
849 }
850
Create_func_des_encrypt()851
852 String *Item_func_hybrid_field_type::val_str_from_int_op(String *str)
853 {
854 longlong nr= int_op();
855 if (null_value)
856 return 0; /* purecov: inspected */
857 str->set_int(nr, unsigned_flag, collation.collation);
858 return str;
859 }
860
861 double Item_func_hybrid_field_type::val_real_from_int_op()
862 {
863 longlong result= int_op();
864 return unsigned_flag ? (double) ((ulonglong) result) : (double) result;
Create_func_dimension()865 }
866
867 my_decimal *
868 Item_func_hybrid_field_type::val_decimal_from_int_op(my_decimal *dec)
869 {
870 longlong result= int_op();
871 if (null_value)
872 return NULL;
873 int2my_decimal(E_DEC_FATAL_ERROR, result, unsigned_flag, dec);
874 return dec;
875 }
876
877 bool Item_func_hybrid_field_type::get_date_from_int_op(MYSQL_TIME *ltime,
878 ulonglong fuzzydate)
879 {
Create_func_mbr_disjoint()880 longlong value= int_op();
~Create_func_mbr_disjoint()881 bool neg= !unsigned_flag && value < 0;
882 if (null_value || int_to_datetime_with_warn(neg, neg ? -value : value,
883 ltime, fuzzydate,
884 field_table_or_null(),
885 field_name_or_null()))
886 return make_zero_mysql_time(ltime, fuzzydate);
887 return (null_value= 0);
888 }
889
890
891 String *Item_func_hybrid_field_type::val_str_from_real_op(String *str)
892 {
Create_func_disjoint()893 double nr= real_op();
~Create_func_disjoint()894 if (null_value)
895 return 0; /* purecov: inspected */
896 str->set_real(nr, decimals, collation.collation);
897 return str;
898 }
899
900 longlong Item_func_hybrid_field_type::val_int_from_real_op()
901 {
902 return Converter_double_to_longlong(real_op(), unsigned_flag).result();
903 }
904
905 my_decimal *
Create_func_distance()906 Item_func_hybrid_field_type::val_decimal_from_real_op(my_decimal *dec)
907 {
908 double result= (double) real_op();
909 if (null_value)
910 return NULL;
911 double2my_decimal(E_DEC_FATAL_ERROR, result, dec);
912 return dec;
913 }
914
915 bool Item_func_hybrid_field_type::get_date_from_real_op(MYSQL_TIME *ltime,
916 ulonglong fuzzydate)
917 {
Create_func_distance_sphere()918 double value= real_op();
~Create_func_distance_sphere()919 if (null_value || double_to_datetime_with_warn(value, ltime, fuzzydate,
920 field_table_or_null(),
921 field_name_or_null()))
922 return make_zero_mysql_time(ltime, fuzzydate);
923 return (null_value= 0);
924 }
925
926
927 String *Item_func_hybrid_field_type::val_str_from_date_op(String *str)
928 {
929 MYSQL_TIME ltime;
930 if (date_op_with_null_check(<ime) ||
931 (null_value= str->alloc(MAX_DATE_STRING_REP_LENGTH)))
932 return (String *) 0;
Create_func_elt()933 str->length(my_TIME_to_str(<ime, const_cast<char*>(str->ptr()), decimals));
~Create_func_elt()934 str->set_charset(&my_charset_bin);
935 DBUG_ASSERT(!null_value);
936 return str;
937 }
938
939 double Item_func_hybrid_field_type::val_real_from_date_op()
940 {
941 MYSQL_TIME ltime;
942 if (date_op_with_null_check(<ime))
943 return 0;
944 return TIME_to_double(<ime);
945 }
Create_func_encode()946
947 longlong Item_func_hybrid_field_type::val_int_from_date_op()
948 {
949 MYSQL_TIME ltime;
950 if (date_op_with_null_check(<ime))
951 return 0;
952 return TIME_to_ulonglong(<ime);
953 }
954
955 my_decimal *
956 Item_func_hybrid_field_type::val_decimal_from_date_op(my_decimal *dec)
957 {
958 MYSQL_TIME ltime;
Create_func_encrypt()959 if (date_op_with_null_check(<ime))
960 {
961 my_decimal_set_zero(dec);
962 return 0;
963 }
964 return date2my_decimal(<ime, dec);
965 }
966
967
968 String *Item_func_hybrid_field_type::val_str_from_time_op(String *str)
969 {
970 MYSQL_TIME ltime;
971 if (time_op_with_null_check(<ime) ||
972 (null_value= my_TIME_to_str(<ime, str, decimals)))
Create_func_endpoint()973 return NULL;
~Create_func_endpoint()974 return str;
975 }
976
977 double Item_func_hybrid_field_type::val_real_from_time_op()
978 {
979 MYSQL_TIME ltime;
980 return time_op_with_null_check(<ime) ? 0 : TIME_to_double(<ime);
981 }
982
983 longlong Item_func_hybrid_field_type::val_int_from_time_op()
984 {
985 MYSQL_TIME ltime;
986 return time_op_with_null_check(<ime) ? 0 : TIME_to_ulonglong(<ime);
987 }
Create_func_envelope()988
989 my_decimal *
990 Item_func_hybrid_field_type::val_decimal_from_time_op(my_decimal *dec)
991 {
992 MYSQL_TIME ltime;
993 if (time_op_with_null_check(<ime))
994 {
995 my_decimal_set_zero(dec);
996 return 0;
997 }
998 return date2my_decimal(<ime, dec);
999 }
Create_func_boundary()1000
1001
1002 double Item_func_hybrid_field_type::val_real_from_str_op()
1003 {
1004 String *res= str_op_with_null_check(&str_value);
1005 return res ? double_from_string_with_check(res) : 0.0;
1006 }
1007
1008 longlong Item_func_hybrid_field_type::val_int_from_str_op()
1009 {
1010 String *res= str_op_with_null_check(&str_value);
1011 return res ? longlong_from_string_with_check(res) : 0;
1012 }
1013
1014 my_decimal *
Create_func_mbr_equals()1015 Item_func_hybrid_field_type::val_decimal_from_str_op(my_decimal *decimal_value)
1016 {
1017 String *res= str_op_with_null_check(&str_value);
1018 return res ? decimal_from_string_with_check(decimal_value, res) : 0;
1019 }
1020
1021 bool Item_func_hybrid_field_type::get_date_from_str_op(MYSQL_TIME *ltime,
1022 ulonglong fuzzydate)
1023 {
1024 StringBuffer<40> tmp;
1025 String *res;
1026 if (!(res= str_op_with_null_check(&tmp)) ||
1027 str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(),
Create_func_equals()1028 ltime, fuzzydate))
1029 return make_zero_mysql_time(ltime, fuzzydate);
1030 return (null_value= 0);
1031 }
1032
1033
1034 void Item_func_signed::print(String *str, enum_query_type query_type)
1035 {
1036 str->append(STRING_WITH_LEN("cast("));
1037 args[0]->print(str, query_type);
1038 str->append(STRING_WITH_LEN(" as signed)"));
1039
1040 }
1041
Create_func_exp()1042
1043 void Item_func_unsigned::print(String *str, enum_query_type query_type)
1044 {
1045 str->append(STRING_WITH_LEN("cast("));
1046 args[0]->print(str, query_type);
1047 str->append(STRING_WITH_LEN(" as unsigned)"));
1048
1049 }
1050
1051
1052 String *Item_decimal_typecast::val_str(String *str)
1053 {
1054 my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
Create_func_export_set()1055 if (null_value)
1056 return NULL;
1057 my_decimal2string(E_DEC_FATAL_ERROR, tmp, 0, 0, 0, str);
1058 return str;
1059 }
1060
1061
1062 double Item_decimal_typecast::val_real()
1063 {
1064 my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
1065 double res;
1066 if (null_value)
1067 return 0.0;
1068 my_decimal2double(E_DEC_FATAL_ERROR, tmp, &res);
Create_func_exteriorring()1069 return res;
~Create_func_exteriorring()1070 }
1071
1072
1073 longlong Item_decimal_typecast::val_int()
1074 {
1075 my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
1076 longlong res;
1077 if (null_value)
1078 return 0;
1079 my_decimal2int(E_DEC_FATAL_ERROR, tmp, unsigned_flag, &res);
1080 return res;
1081 }
1082
Create_func_field()1083
1084 my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
1085 {
1086 my_decimal tmp_buf, *tmp= args[0]->val_decimal(&tmp_buf);
1087 bool sign;
1088 uint precision;
1089
1090 if ((null_value= args[0]->null_value))
1091 return NULL;
1092 my_decimal_round(E_DEC_FATAL_ERROR, tmp, decimals, FALSE, dec);
1093 sign= dec->sign();
1094 if (unsigned_flag)
1095 {
1096 if (sign)
1097 {
1098 my_decimal_set_zero(dec);
1099 goto err;
1100 }
1101 }
1102 precision= my_decimal_length_to_precision(max_length,
1103 decimals, unsigned_flag);
1104 if (precision - decimals < (uint) my_decimal_intg(dec))
1105 {
1106 max_my_decimal(dec, precision, decimals);
1107 dec->sign(sign);
1108 goto err;
1109 }
1110 return dec;
1111
1112 err:
1113 THD *thd= current_thd;
1114 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
1115 ER_WARN_DATA_OUT_OF_RANGE,
1116 ER_THD(thd, ER_WARN_DATA_OUT_OF_RANGE),
1117 name.str, 1L);
1118 return dec;
1119 }
1120
1121
Create_func_format()1122 void Item_decimal_typecast::print(String *str, enum_query_type query_type)
1123 {
1124 char len_buf[20*3 + 1];
1125 char *end;
1126
1127 uint precision= my_decimal_length_to_precision(max_length, decimals,
1128 unsigned_flag);
1129 str->append(STRING_WITH_LEN("cast("));
1130 args[0]->print(str, query_type);
1131 str->append(STRING_WITH_LEN(" as decimal("));
1132
1133 end=int10_to_str(precision, len_buf,10);
1134 str->append(len_buf, (uint32) (end - len_buf));
1135
1136 str->append(',');
1137
1138 end=int10_to_str(decimals, len_buf,10);
1139 str->append(len_buf, (uint32) (end - len_buf));
1140
1141 str->append(')');
1142 str->append(')');
1143 }
1144
1145
1146 double Item_real_typecast::val_real_with_truncate(double max_value)
1147 {
Create_func_from_base64()1148 int error;
~Create_func_from_base64()1149 double tmp= args[0]->val_real();
1150 if ((null_value= args[0]->null_value))
1151 return 0.0;
1152
1153 if (unlikely((error= truncate_double(&tmp, max_length, decimals,
1154 false/*unsigned_flag*/, max_value))))
1155 {
1156 /*
1157 We don't want automatic escalation from a warning to an error
1158 in this scenario:
1159 INSERT INTO t1 (float_field) VALUES (CAST(1e100 AS FLOAT));
1160 The above statement should work even in the strict mode.
Create_func_from_days()1161 So let's use a note rather than a warning.
1162 */
1163 THD *thd= current_thd;
1164 push_warning_printf(thd,
1165 Sql_condition::WARN_LEVEL_NOTE,
1166 ER_WARN_DATA_OUT_OF_RANGE,
1167 ER_THD(thd, ER_WARN_DATA_OUT_OF_RANGE),
1168 name.str, (ulong) 1);
1169 if (error < 0)
1170 {
1171 null_value= 1; // Illegal value
1172 tmp= 0.0;
1173 }
Create_func_from_unixtime()1174 }
1175 return tmp;
1176 }
1177
1178
1179 void Item_real_typecast::print(String *str, enum_query_type query_type)
1180 {
1181 char len_buf[20*3 + 1];
1182 char *end;
1183
1184 str->append(STRING_WITH_LEN("cast("));
1185 args[0]->print(str, query_type);
1186 str->append(STRING_WITH_LEN(" as "));
1187 str->append(type_handler()->name().ptr());
Create_func_geometry_from_text()1188 if (decimals != NOT_FIXED_DEC)
1189 {
1190 str->append('(');
1191 end= int10_to_str(max_length, len_buf,10);
1192 str->append(len_buf, (uint32) (end - len_buf));
1193 str->append(',');
1194 end= int10_to_str(decimals, len_buf,10);
1195 str->append(len_buf, (uint32) (end - len_buf));
1196 str->append(')');
1197 }
1198 str->append(')');
1199 }
1200
1201 double Item_func_plus::real_op()
1202 {
Create_func_geometry_from_wkb()1203 double value= args[0]->val_real() + args[1]->val_real();
~Create_func_geometry_from_wkb()1204 if ((null_value=args[0]->null_value || args[1]->null_value))
1205 return 0.0;
1206 return check_float_overflow(value);
1207 }
1208
1209
1210 longlong Item_func_plus::int_op()
1211 {
1212 longlong val0= args[0]->val_int();
1213 longlong val1= args[1]->val_int();
1214 longlong res= val0 + val1;
1215 bool res_unsigned= FALSE;
1216
1217 if ((null_value= args[0]->null_value || args[1]->null_value))
Create_func_geometry_from_json()1218 return 0;
~Create_func_geometry_from_json()1219
1220 /*
1221 First check whether the result can be represented as a
1222 (bool unsigned_flag, longlong value) pair, then check if it is compatible
1223 with this Item's unsigned_flag by calling check_integer_overflow().
1224 */
1225 if (args[0]->unsigned_flag)
1226 {
1227 if (args[1]->unsigned_flag || val1 >= 0)
1228 {
1229 if (test_if_sum_overflows_ull((ulonglong) val0, (ulonglong) val1))
1230 goto err;
1231 res_unsigned= TRUE;
1232 }
1233 else
1234 {
1235 /* val1 is negative */
1236 if ((ulonglong) val0 > (ulonglong) LONGLONG_MAX)
1237 res_unsigned= TRUE;
1238 }
1239 }
1240 else
1241 {
1242 if (args[1]->unsigned_flag)
1243 {
1244 if (val0 >= 0)
1245 {
Create_func_geometry_type()1246 if (test_if_sum_overflows_ull((ulonglong) val0, (ulonglong) val1))
1247 goto err;
1248 res_unsigned= TRUE;
1249 }
1250 else
1251 {
1252 if ((ulonglong) val1 > (ulonglong) LONGLONG_MAX)
1253 res_unsigned= TRUE;
1254 }
1255 }
1256 else
1257 {
1258 if (val0 >=0 && val1 >= 0)
1259 res_unsigned= TRUE;
1260 else if (val0 < 0 && val1 < 0 && res >= 0)
Create_func_geometryn()1261 goto err;
~Create_func_geometryn()1262 }
1263 }
1264 return check_integer_overflow(res, res_unsigned);
1265
1266 err:
1267 return raise_integer_overflow();
1268 }
1269
1270
1271 /**
1272 Calculate plus of two decimals.
1273
1274 @param decimal_value Buffer that can be used to store result
Create_func_get_lock()1275
1276 @retval
1277 0 Value was NULL; In this case null_value is set
1278 @retval
1279 \# Value of operation as a decimal
1280 */
1281
1282 my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
1283 {
1284 my_decimal value1, *val1;
1285 my_decimal value2, *val2;
1286 val1= args[0]->val_decimal(&value1);
1287 if ((null_value= args[0]->null_value))
1288 return 0;
1289 val2= args[1]->val_decimal(&value2);
1290 if (!(null_value= (args[1]->null_value ||
1291 check_decimal_overflow(my_decimal_add(E_DEC_FATAL_ERROR &
1292 ~E_DEC_OVERFLOW,
1293 decimal_value,
1294 val1, val2)) > 3)))
1295 return decimal_value;
1296 return 0;
1297 }
1298
1299 /**
1300 Set precision of results for additive operations (+ and -)
1301 */
1302 void Item_func_additive_op::result_precision()
1303 {
Create_func_glength()1304 decimals= MY_MAX(args[0]->decimal_scale(), args[1]->decimal_scale());
~Create_func_glength()1305 int arg1_int= args[0]->decimal_precision() - args[0]->decimal_scale();
1306 int arg2_int= args[1]->decimal_precision() - args[1]->decimal_scale();
1307 int precision= MY_MAX(arg1_int, arg2_int) + 1 + decimals;
1308
1309 DBUG_ASSERT(arg1_int >= 0);
1310 DBUG_ASSERT(arg2_int >= 0);
1311
1312 max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
1313 unsigned_flag);
1314 }
1315
1316
1317 /**
Create_func_greatest()1318 The following function is here to allow the user to force
1319 subtraction of UNSIGNED BIGINT to return negative values.
1320 */
1321 void Item_func_minus::fix_unsigned_flag()
1322 {
1323 if (unsigned_flag &&
1324 (current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION))
1325 unsigned_flag=0;
1326 }
1327
1328
1329 bool Item_func_minus::fix_length_and_dec()
1330 {
Create_func_hex()1331 DBUG_ENTER("Item_func_minus::fix_length_and_dec");
~Create_func_hex()1332 DBUG_PRINT("info", ("name %s", func_name()));
1333 const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_minus;
1334 DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_non_commutative_test;);
1335 DBUG_ASSERT(!aggregator->is_commutative());
1336 if (fix_type_handler(aggregator))
1337 DBUG_RETURN(TRUE);
1338 if (Item_func_minus::type_handler()->Item_func_minus_fix_length_and_dec(this))
1339 DBUG_RETURN(TRUE);
1340 DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr()));
1341 if ((m_depends_on_sql_mode_no_unsigned_subtraction= unsigned_flag) &&
1342 (current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION))
1343 unsigned_flag= false;
Create_func_ifnull()1344 DBUG_RETURN(FALSE);
~Create_func_ifnull()1345 }
1346
1347
1348 Sql_mode_dependency Item_func_minus::value_depends_on_sql_mode() const
1349 {
1350 Sql_mode_dependency dep= Item_func_additive_op::value_depends_on_sql_mode();
1351 if (m_depends_on_sql_mode_no_unsigned_subtraction)
1352 dep|= Sql_mode_dependency(0, MODE_NO_UNSIGNED_SUBTRACTION);
1353 return dep;
1354 }
1355
1356
Create_func_inet_ntoa()1357 double Item_func_minus::real_op()
1358 {
1359 double value= args[0]->val_real() - args[1]->val_real();
1360 if ((null_value=args[0]->null_value || args[1]->null_value))
1361 return 0.0;
1362 return check_float_overflow(value);
1363 }
1364
1365
1366 longlong Item_func_minus::int_op()
1367 {
1368 longlong val0= args[0]->val_int();
1369 longlong val1= args[1]->val_int();
Create_func_inet_aton()1370 longlong res= val0 - val1;
~Create_func_inet_aton()1371 bool res_unsigned= FALSE;
1372
1373 if ((null_value= args[0]->null_value || args[1]->null_value))
1374 return 0;
1375
1376 /*
1377 First check whether the result can be represented as a
1378 (bool unsigned_flag, longlong value) pair, then check if it is compatible
1379 with this Item's unsigned_flag by calling check_integer_overflow().
1380 */
1381 if (args[0]->unsigned_flag)
1382 {
Create_func_inet6_aton()1383 if (args[1]->unsigned_flag)
1384 {
1385 if ((ulonglong) val0 < (ulonglong) val1)
1386 {
1387 if (res >= 0)
1388 goto err;
1389 }
1390 else
1391 res_unsigned= TRUE;
1392 }
1393 else
1394 {
1395 if (val1 >= 0)
Create_func_inet6_ntoa()1396 {
1397 if ((ulonglong) val0 > (ulonglong) val1)
1398 res_unsigned= TRUE;
1399 }
1400 else
1401 {
1402 if (test_if_sum_overflows_ull((ulonglong) val0, (ulonglong) -val1))
1403 goto err;
1404 res_unsigned= TRUE;
1405 }
1406 }
1407 }
1408 else
Create_func_is_ipv4()1409 {
1410 if (args[1]->unsigned_flag)
1411 {
1412 if ((ulonglong) (val0 - LONGLONG_MIN) < (ulonglong) val1)
1413 goto err;
1414 }
1415 else
1416 {
1417 if (val0 > 0 && val1 < 0)
1418 res_unsigned= TRUE;
1419 else if (val0 < 0 && val1 > 0 && res >= 0)
1420 goto err;
1421 }
1422 }
~Create_func_is_ipv6()1423 return check_integer_overflow(res, res_unsigned);
1424
1425 err:
1426 return raise_integer_overflow();
1427 }
1428
1429
1430 /**
1431 See Item_func_plus::decimal_op for comments.
1432 */
1433
1434 my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value)
Create_func_is_ipv4_compat()1435 {
1436 my_decimal value1, *val1;
1437 my_decimal value2, *val2=
1438
1439 val1= args[0]->val_decimal(&value1);
1440 if ((null_value= args[0]->null_value))
1441 return 0;
1442 val2= args[1]->val_decimal(&value2);
1443 if (!(null_value= (args[1]->null_value ||
1444 (check_decimal_overflow(my_decimal_sub(E_DEC_FATAL_ERROR &
1445 ~E_DEC_OVERFLOW,
1446 decimal_value, val1,
1447 val2)) > 3))))
1448 return decimal_value;
1449 return 0;
1450 }
1451
1452
1453 double Item_func_mul::real_op()
1454 {
1455 DBUG_ASSERT(fixed == 1);
1456 double value= args[0]->val_real() * args[1]->val_real();
1457 if ((null_value=args[0]->null_value || args[1]->null_value))
1458 return 0.0;
1459 return check_float_overflow(value);
1460 }
Create_func_instr()1461
1462
1463 longlong Item_func_mul::int_op()
1464 {
1465 DBUG_ASSERT(fixed == 1);
1466 longlong a= args[0]->val_int();
1467 longlong b= args[1]->val_int();
1468 longlong res;
1469 ulonglong res0, res1;
1470 ulong a0, a1, b0, b1;
1471 bool res_unsigned= FALSE;
1472 bool a_negative= FALSE, b_negative= FALSE;
1473
1474 if ((null_value= args[0]->null_value || args[1]->null_value))
1475 return 0;
1476
1477 /*
1478 First check whether the result can be represented as a
1479 (bool unsigned_flag, longlong value) pair, then check if it is compatible
1480 with this Item's unsigned_flag by calling check_integer_overflow().
1481
1482 Let a = a1 * 2^32 + a0 and b = b1 * 2^32 + b0. Then
1483 a * b = (a1 * 2^32 + a0) * (b1 * 2^32 + b0) = a1 * b1 * 2^64 +
1484 + (a1 * b0 + a0 * b1) * 2^32 + a0 * b0;
1485 We can determine if the above sum overflows the ulonglong range by
1486 sequentially checking the following conditions:
1487 1. If both a1 and b1 are non-zero.
1488 2. Otherwise, if (a1 * b0 + a0 * b1) is greater than ULONG_MAX.
1489 3. Otherwise, if (a1 * b0 + a0 * b1) * 2^32 + a0 * b0 is greater than
1490 ULONGLONG_MAX.
1491
1492 Since we also have to take the unsigned_flag for a and b into account,
1493 it is easier to first work with absolute values and set the
1494 correct sign later.
1495 */
1496 if (!args[0]->unsigned_flag && a < 0)
1497 {
1498 a_negative= TRUE;
1499 a= -a;
1500 }
1501 if (!args[1]->unsigned_flag && b < 0)
1502 {
1503 b_negative= TRUE;
1504 b= -b;
1505 }
1506
1507 a0= 0xFFFFFFFFUL & a;
1508 a1= ((ulonglong) a) >> 32;
1509 b0= 0xFFFFFFFFUL & b;
1510 b1= ((ulonglong) b) >> 32;
1511
1512 if (a1 && b1)
1513 goto err;
1514
1515 res1= (ulonglong) a1 * b0 + (ulonglong) a0 * b1;
1516 if (res1 > 0xFFFFFFFFUL)
1517 goto err;
1518
1519 res1= res1 << 32;
1520 res0= (ulonglong) a0 * b0;
1521
1522 if (test_if_sum_overflows_ull(res1, res0))
1523 goto err;
1524 res= res1 + res0;
1525
1526 if (a_negative != b_negative)
1527 {
1528 if ((ulonglong) res > (ulonglong) LONGLONG_MIN + 1)
1529 goto err;
1530 res= -res;
1531 }
1532 else
1533 res_unsigned= TRUE;
1534
1535 return check_integer_overflow(res, res_unsigned);
1536
1537 err:
1538 return raise_integer_overflow();
1539 }
1540
1541
Create_func_difference()1542 /** See Item_func_plus::decimal_op for comments. */
1543
1544 my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value)
1545 {
1546 my_decimal value1, *val1;
1547 my_decimal value2, *val2;
1548 val1= args[0]->val_decimal(&value1);
1549 if ((null_value= args[0]->null_value))
1550 return 0;
1551 val2= args[1]->val_decimal(&value2);
1552 if (!(null_value= (args[1]->null_value ||
1553 (check_decimal_overflow(my_decimal_mul(E_DEC_FATAL_ERROR &
1554 ~E_DEC_OVERFLOW,
1555 decimal_value, val1,
1556 val2)) > 3))))
1557 return decimal_value;
1558 return 0;
1559 }
1560
1561
1562 void Item_func_mul::result_precision()
1563 {
1564 decimals= MY_MIN(args[0]->decimal_scale() + args[1]->decimal_scale(),
1565 DECIMAL_MAX_SCALE);
1566 uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
1567 uint precision= MY_MIN(est_prec, DECIMAL_MAX_PRECISION);
Create_func_symdifference()1568 max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
1569 unsigned_flag);
1570 }
1571
1572
1573 bool Item_func_mul::fix_length_and_dec(void)
1574 {
1575 DBUG_ENTER("Item_func_mul::fix_length_and_dec");
1576 DBUG_PRINT("info", ("name %s", func_name()));
1577 const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_mul;
1578 DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_for_result;);
1579 DBUG_ASSERT(aggregator->is_commutative());
1580 if (fix_type_handler(aggregator))
Create_func_buffer()1581 DBUG_RETURN(TRUE);
~Create_func_buffer()1582 if (Item_func_mul::type_handler()->Item_func_mul_fix_length_and_dec(this))
1583 DBUG_RETURN(TRUE);
1584 DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr()));
1585 DBUG_RETURN(FALSE);
1586 }
1587
1588
1589 double Item_func_div::real_op()
1590 {
1591 DBUG_ASSERT(fixed == 1);
1592 double value= args[0]->val_real();
1593 double val2= args[1]->val_real();
1594 if ((null_value= args[0]->null_value || args[1]->null_value))
Create_func_is_free_lock()1595 return 0.0;
~Create_func_is_free_lock()1596 if (val2 == 0.0)
1597 {
1598 signal_divide_by_null();
1599 return 0.0;
1600 }
1601 return check_float_overflow(value/val2);
1602 }
1603
1604
1605 my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
1606 {
1607 my_decimal value1, *val1;
Create_func_is_used_lock()1608 my_decimal value2, *val2;
~Create_func_is_used_lock()1609 int err;
1610
1611 val1= args[0]->val_decimal(&value1);
1612 if ((null_value= args[0]->null_value))
1613 return 0;
1614 val2= args[1]->val_decimal(&value2);
1615 if ((null_value= args[1]->null_value))
1616 return 0;
1617 if ((err= check_decimal_overflow(my_decimal_div(E_DEC_FATAL_ERROR &
1618 ~E_DEC_OVERFLOW &
1619 ~E_DEC_DIV_ZERO,
1620 decimal_value,
1621 val1, val2,
Create_func_isclosed()1622 prec_increment))) > 3)
1623 {
1624 if (err == E_DEC_DIV_ZERO)
1625 signal_divide_by_null();
1626 null_value= 1;
1627 return 0;
1628 }
1629 return decimal_value;
1630 }
1631
1632
1633 void Item_func_div::result_precision()
1634 {
Create_func_isring()1635 /*
1636 We need to add args[1]->divisor_precision_increment(),
1637 to properly handle the cases like this:
1638 SELECT 5.05 / 0.014; -> 360.714286
1639 i.e. when the divisor has a zero integer part
1640 and non-zero digits appear only after the decimal point.
1641 Precision in this example is calculated as
1642 args[0]->decimal_precision() + // 3
1643 args[1]->divisor_precision_increment() + // 3
1644 prec_increment // 4
1645 which gives 10 decimals digits.
1646 */
1647 uint precision=MY_MIN(args[0]->decimal_precision() +
1648 args[1]->divisor_precision_increment() + prec_increment,
1649 DECIMAL_MAX_PRECISION);
Create_func_isempty()1650 decimals= MY_MIN(args[0]->decimal_scale() + prec_increment, DECIMAL_MAX_SCALE);
~Create_func_isempty()1651 max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
1652 unsigned_flag);
1653 }
1654
1655
1656 void Item_func_div::fix_length_and_dec_double(void)
1657 {
1658 Item_num_op::fix_length_and_dec_double();
1659 decimals= MY_MAX(args[0]->decimals, args[1]->decimals) + prec_increment;
1660 set_if_smaller(decimals, NOT_FIXED_DEC);
1661 uint tmp= float_length(decimals);
1662 if (decimals == NOT_FIXED_DEC)
1663 max_length= tmp;
Create_func_isnull()1664 else
1665 {
1666 max_length=args[0]->max_length - args[0]->decimals + decimals;
1667 set_if_smaller(max_length, tmp);
1668 }
1669 }
1670
1671
1672 void Item_func_div::fix_length_and_dec_int(void)
1673 {
1674 set_handler(&type_handler_newdecimal);
1675 DBUG_PRINT("info", ("Type changed: %s", type_handler()->name().ptr()));
1676 Item_num_op::fix_length_and_dec_decimal();
1677 }
Create_func_issimple()1678
1679
1680 bool Item_func_div::fix_length_and_dec()
1681 {
1682 DBUG_ENTER("Item_func_div::fix_length_and_dec");
1683 DBUG_PRINT("info", ("name %s", func_name()));
1684 prec_increment= current_thd->variables.div_precincrement;
1685 maybe_null= 1; // division by zero
1686
1687 const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_div;
1688 DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_non_commutative_test;);
1689 DBUG_ASSERT(!aggregator->is_commutative());
1690 if (fix_type_handler(aggregator))
1691 DBUG_RETURN(TRUE);
1692 if (Item_func_div::type_handler()->Item_func_div_fix_length_and_dec(this))
1693 DBUG_RETURN(TRUE);
1694 DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr()));
1695 DBUG_RETURN(FALSE);
1696 }
1697
1698
1699 /* Integer division */
1700 longlong Item_func_int_div::val_int()
1701 {
1702 DBUG_ASSERT(fixed == 1);
1703
1704 /*
Create_func_json_valid()1705 Perform division using DECIMAL math if either of the operands has a
1706 non-integer type
1707 */
1708 if (args[0]->result_type() != INT_RESULT ||
1709 args[1]->result_type() != INT_RESULT)
1710 {
1711 my_decimal tmp;
1712 my_decimal *val0p= args[0]->val_decimal(&tmp);
1713 if ((null_value= args[0]->null_value))
1714 return 0;
1715 my_decimal val0= *val0p;
1716
1717 my_decimal *val1p= args[1]->val_decimal(&tmp);
1718 if ((null_value= args[1]->null_value))
1719 return 0;
1720 my_decimal val1= *val1p;
1721
1722 int err;
1723 if ((err= my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, &tmp,
1724 &val0, &val1, 0)) > 3)
1725 {
1726 if (err == E_DEC_DIV_ZERO)
1727 signal_divide_by_null();
1728 return 0;
1729 }
1730
1731 my_decimal truncated;
1732 const bool do_truncate= true;
1733 if (my_decimal_round(E_DEC_FATAL_ERROR, &tmp, 0, do_truncate, &truncated))
1734 DBUG_ASSERT(false);
1735
1736 longlong res;
1737 if (my_decimal2int(E_DEC_FATAL_ERROR, &truncated, unsigned_flag, &res) &
1738 E_DEC_OVERFLOW)
1739 raise_integer_overflow();
1740 return res;
1741 }
1742
1743 Longlong_hybrid val0= args[0]->to_longlong_hybrid();
Create_func_json_detailed()1744 Longlong_hybrid val1= args[1]->to_longlong_hybrid();
~Create_func_json_detailed()1745 if ((null_value= (args[0]->null_value || args[1]->null_value)))
1746 return 0;
1747 if (val1 == 0)
1748 {
1749 signal_divide_by_null();
1750 return 0;
1751 }
1752
1753 bool res_negative= val0.neg() != val1.neg();
1754 ulonglong res= val0.abs() / val1.abs();
1755 if (res_negative)
1756 {
Create_func_json_type()1757 if (res > (ulonglong) LONGLONG_MAX)
1758 return raise_integer_overflow();
1759 res= (ulonglong) (-(longlong) res);
1760 }
1761 return check_integer_overflow(res, !res_negative);
1762 }
1763
1764
1765 bool Item_func_int_div::fix_length_and_dec()
1766 {
1767 uint32 prec= args[0]->decimal_int_part();
1768 set_if_smaller(prec, MY_INT64_NUM_DECIMAL_DIGITS);
1769 fix_char_length(prec);
Create_func_json_depth()1770 maybe_null=1;
~Create_func_json_depth()1771 unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag;
1772 return false;
1773 }
1774
1775
1776 longlong Item_func_mod::int_op()
1777 {
1778 DBUG_ASSERT(fixed == 1);
1779 Longlong_hybrid val0= args[0]->to_longlong_hybrid();
1780 Longlong_hybrid val1= args[1]->to_longlong_hybrid();
1781
1782 if ((null_value= args[0]->null_value || args[1]->null_value))
Create_func_json_value()1783 return 0; /* purecov: inspected */
~Create_func_json_value()1784 if (val1 == 0)
1785 {
1786 signal_divide_by_null();
1787 return 0;
1788 }
1789
1790 /*
1791 '%' is calculated by integer division internally. Since dividing
1792 LONGLONG_MIN by -1 generates SIGFPE, we calculate using unsigned values and
1793 then adjust the sign appropriately.
1794 */
1795 ulonglong res= val0.abs() % val1.abs();
Create_func_json_query()1796 return check_integer_overflow(val0.neg() ? -(longlong) res : res,
1797 !val0.neg());
1798 }
1799
1800 double Item_func_mod::real_op()
1801 {
1802 DBUG_ASSERT(fixed == 1);
1803 double value= args[0]->val_real();
1804 double val2= args[1]->val_real();
1805 if ((null_value= args[0]->null_value || args[1]->null_value))
1806 return 0.0; /* purecov: inspected */
1807 if (val2 == 0.0)
1808 {
Create_func_json_keys()1809 signal_divide_by_null();
~Create_func_json_keys()1810 return 0.0;
1811 }
1812 return fmod(value,val2);
1813 }
1814
1815
1816 my_decimal *Item_func_mod::decimal_op(my_decimal *decimal_value)
1817 {
1818 my_decimal value1, *val1;
1819 my_decimal value2, *val2;
1820
1821 val1= args[0]->val_decimal(&value1);
Create_func_json_contains()1822 if ((null_value= args[0]->null_value))
1823 return 0;
1824 val2= args[1]->val_decimal(&value2);
1825 if ((null_value= args[1]->null_value))
1826 return 0;
1827 switch (my_decimal_mod(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value,
1828 val1, val2)) {
1829 case E_DEC_TRUNCATED:
1830 case E_DEC_OK:
1831 return decimal_value;
1832 case E_DEC_DIV_ZERO:
1833 signal_divide_by_null();
1834 /* fall through */
Create_func_json_contains_path()1835 default:
1836 null_value= 1;
1837 return 0;
1838 }
1839 }
1840
1841
1842 void Item_func_mod::result_precision()
1843 {
1844 unsigned_flag= args[0]->unsigned_flag;
1845 decimals= MY_MAX(args[0]->decimal_scale(), args[1]->decimal_scale());
1846 uint prec= MY_MAX(args[0]->decimal_precision(), args[1]->decimal_precision());
1847 fix_char_length(my_decimal_precision_to_length_no_truncation(prec, decimals,
Create_func_json_extract()1848 unsigned_flag));
~Create_func_json_extract()1849 }
1850
1851
1852 bool Item_func_mod::fix_length_and_dec()
1853 {
1854 DBUG_ENTER("Item_func_mod::fix_length_and_dec");
1855 DBUG_PRINT("info", ("name %s", func_name()));
1856 maybe_null= true; // division by zero
1857 const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_mod;
1858 DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_non_commutative_test;);
1859 DBUG_ASSERT(!aggregator->is_commutative());
1860 if (fix_type_handler(aggregator))
1861 DBUG_RETURN(TRUE);
1862 if (Item_func_mod::type_handler()->Item_func_mod_fix_length_and_dec(this))
1863 DBUG_RETURN(TRUE);
1864 DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr()));
1865 DBUG_RETURN(FALSE);
1866 }
1867
1868
1869 double Item_func_neg::real_op()
1870 {
1871 double value= args[0]->val_real();
1872 null_value= args[0]->null_value;
1873 return -value;
Create_func_json_array()1874 }
1875
1876
1877 longlong Item_func_neg::int_op()
1878 {
1879 longlong value= args[0]->val_int();
1880 if ((null_value= args[0]->null_value))
1881 return 0;
1882 if (args[0]->unsigned_flag &&
1883 (ulonglong) value > (ulonglong) LONGLONG_MAX + 1)
1884 return raise_integer_overflow();
1885
1886 if (value == LONGLONG_MIN)
1887 {
1888 if (args[0]->unsigned_flag != unsigned_flag)
1889 /* negation of LONGLONG_MIN is LONGLONG_MIN. */
1890 return LONGLONG_MIN;
1891 else
1892 return raise_integer_overflow();
1893 }
1894
1895 return check_integer_overflow(-value, !args[0]->unsigned_flag && value < 0);
1896 }
1897
1898
1899 my_decimal *Item_func_neg::decimal_op(my_decimal *decimal_value)
Create_func_json_array_insert()1900 {
1901 my_decimal val, *value= args[0]->val_decimal(&val);
1902 if (!(null_value= args[0]->null_value))
1903 {
1904 my_decimal2decimal(value, decimal_value);
1905 my_decimal_neg(decimal_value);
1906 return decimal_value;
1907 }
1908 return 0;
1909 }
1910
1911
1912 void Item_func_neg::fix_length_and_dec_int()
Create_func_json_insert()1913 {
1914 max_length= args[0]->max_length + 1;
1915 set_handler(type_handler_long_or_longlong());
1916
1917 /*
1918 If this is in integer context keep the context as integer if possible
1919 (This is how multiplication and other integer functions works)
1920 Use val() to get value as arg_type doesn't mean that item is
1921 Item_int or Item_float due to existence of Item_param.
1922 */
1923 if (args[0]->const_item())
1924 {
1925 longlong val= args[0]->val_int();
1926 if ((ulonglong) val >= (ulonglong) LONGLONG_MIN &&
1927 ((ulonglong) val != (ulonglong) LONGLONG_MIN ||
1928 args[0]->type() != INT_ITEM))
1929 {
1930 /*
1931 Ensure that result is converted to DECIMAL, as longlong can't hold
1932 the negated number
1933 */
1934 set_handler_by_result_type(DECIMAL_RESULT);
1935 DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT"));
1936 }
1937 }
1938 unsigned_flag= false;
1939 }
~Create_func_json_replace()1940
1941
1942 void Item_func_neg::fix_length_and_dec_double()
1943 {
1944 set_handler(&type_handler_double);
1945 decimals= args[0]->decimals; // Preserve NOT_FIXED_DEC
1946 max_length= args[0]->max_length + 1;
1947 // Limit length with something reasonable
1948 uint32 mlen= type_handler()->max_display_length(this);
1949 set_if_smaller(max_length, mlen);
1950 unsigned_flag= false;
1951 }
Create_func_json_remove()1952
1953
1954 void Item_func_neg::fix_length_and_dec_decimal()
1955 {
1956 set_handler(&type_handler_newdecimal);
1957 decimals= args[0]->decimal_scale(); // Do not preserve NOT_FIXED_DEC
1958 max_length= args[0]->max_length + 1;
1959 unsigned_flag= false;
1960 }
1961
1962
1963 bool Item_func_neg::fix_length_and_dec()
1964 {
Create_func_json_object()1965 DBUG_ENTER("Item_func_neg::fix_length_and_dec");
~Create_func_json_object()1966 DBUG_PRINT("info", ("name %s", func_name()));
1967 if (args[0]->cast_to_int_type_handler()->
1968 Item_func_neg_fix_length_and_dec(this))
1969 DBUG_RETURN(TRUE);
1970 DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr()));
1971 DBUG_RETURN(FALSE);
1972 }
1973
1974
1975 double Item_func_abs::real_op()
1976 {
1977 double value= args[0]->val_real();
Create_func_json_length()1978 null_value= args[0]->null_value;
~Create_func_json_length()1979 return fabs(value);
1980 }
1981
1982
1983 longlong Item_func_abs::int_op()
1984 {
1985 longlong value= args[0]->val_int();
1986 if ((null_value= args[0]->null_value))
1987 return 0;
1988 if (unsigned_flag)
1989 return value;
1990 /* -LONGLONG_MIN = LONGLONG_MAX + 1 => outside of signed longlong range */
Create_func_json_merge()1991 if (value == LONGLONG_MIN)
1992 return raise_integer_overflow();
1993 return (value >= 0) ? value : -value;
1994 }
1995
1996
1997 my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value)
1998 {
1999 my_decimal val, *value= args[0]->val_decimal(&val);
2000 if (!(null_value= args[0]->null_value))
2001 {
2002 my_decimal2decimal(value, decimal_value);
2003 if (decimal_value->sign())
Create_func_json_merge_patch()2004 my_decimal_neg(decimal_value);
~Create_func_json_merge_patch()2005 return decimal_value;
2006 }
2007 return 0;
2008 }
2009
2010 void Item_func_abs::fix_length_and_dec_int()
2011 {
2012 max_length= args[0]->max_length;
2013 unsigned_flag= args[0]->unsigned_flag;
2014 set_handler(type_handler_long_or_longlong());
2015 }
2016
Create_func_json_quote()2017
2018 void Item_func_abs::fix_length_and_dec_double()
2019 {
2020 set_handler(&type_handler_double);
2021 decimals= args[0]->decimals; // Preserve NOT_FIXED_DEC
2022 max_length= float_length(decimals);
2023 unsigned_flag= args[0]->unsigned_flag;
2024 }
2025
2026
2027 void Item_func_abs::fix_length_and_dec_decimal()
2028 {
2029 set_handler(&type_handler_newdecimal);
Create_func_json_unquote()2030 decimals= args[0]->decimal_scale(); // Do not preserve NOT_FIXED_DEC
~Create_func_json_unquote()2031 max_length= args[0]->max_length;
2032 unsigned_flag= args[0]->unsigned_flag;
2033 }
2034
2035
2036 bool Item_func_abs::fix_length_and_dec()
2037 {
2038 DBUG_ENTER("Item_func_abs::fix_length_and_dec");
2039 DBUG_PRINT("info", ("name %s", func_name()));
2040 if (args[0]->cast_to_int_type_handler()->
2041 Item_func_abs_fix_length_and_dec(this))
2042 DBUG_RETURN(TRUE);
Create_func_last_day()2043 DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr()));
~Create_func_last_day()2044 DBUG_RETURN(FALSE);
2045 }
2046
2047
2048 /** Gateway to natural LOG function. */
2049 double Item_func_ln::val_real()
2050 {
2051 DBUG_ASSERT(fixed == 1);
2052 double value= args[0]->val_real();
2053 if ((null_value= args[0]->null_value))
2054 return 0.0;
2055 if (value <= 0.0)
Create_func_last_insert_id()2056 {
2057 signal_divide_by_null();
2058 return 0.0;
2059 }
2060 return log(value);
2061 }
2062
2063 /**
2064 Extended but so slower LOG function.
2065
2066 We have to check if all values are > zero and first one is not one
2067 as these are the cases then result is not a number.
2068 */
Create_func_lcase()2069 double Item_func_log::val_real()
2070 {
2071 DBUG_ASSERT(fixed == 1);
2072 double value= args[0]->val_real();
2073 if ((null_value= args[0]->null_value))
2074 return 0.0;
2075 if (value <= 0.0)
2076 {
2077 signal_divide_by_null();
2078 return 0.0;
2079 }
2080 if (arg_count == 2)
2081 {
2082 double value2= args[1]->val_real();
2083 if ((null_value= args[1]->null_value))
2084 return 0.0;
2085 if (value2 <= 0.0 || value == 1.0)
2086 {
2087 signal_divide_by_null();
2088 return 0.0;
2089 }
2090 return log(value2) / log(value);
2091 }
2092 return log(value);
2093 }
2094
Create_func_length()2095 double Item_func_log2::val_real()
2096 {
2097 DBUG_ASSERT(fixed == 1);
2098 double value= args[0]->val_real();
2099
2100 if ((null_value=args[0]->null_value))
2101 return 0.0;
2102 if (value <= 0.0)
2103 {
2104 signal_divide_by_null();
2105 return 0.0;
2106 }
2107 return log(value) / M_LN2;
2108 }
2109
2110 double Item_func_log10::val_real()
2111 {
2112 DBUG_ASSERT(fixed == 1);
2113 double value= args[0]->val_real();
2114 if ((null_value= args[0]->null_value))
2115 return 0.0;
2116 if (value <= 0.0)
2117 {
2118 signal_divide_by_null();
2119 return 0.0;
2120 }
Create_func_like_range_min()2121 return log10(value);
~Create_func_like_range_min()2122 }
2123
2124 double Item_func_exp::val_real()
2125 {
2126 DBUG_ASSERT(fixed == 1);
2127 double value= args[0]->val_real();
2128 if ((null_value=args[0]->null_value))
2129 return 0.0; /* purecov: inspected */
2130 return check_float_overflow(exp(value));
2131 }
2132
2133 double Item_func_sqrt::val_real()
Create_func_like_range_max()2134 {
2135 DBUG_ASSERT(fixed == 1);
2136 double value= args[0]->val_real();
2137 if ((null_value=(args[0]->null_value || value < 0)))
2138 return 0.0; /* purecov: inspected */
2139 return sqrt(value);
2140 }
2141
2142 double Item_func_pow::val_real()
2143 {
2144 DBUG_ASSERT(fixed == 1);
2145 double value= args[0]->val_real();
2146 double val2= args[1]->val_real();
2147 if ((null_value=(args[0]->null_value || args[1]->null_value)))
Create_func_ln()2148 return 0.0; /* purecov: inspected */
~Create_func_ln()2149 return check_float_overflow(pow(value,val2));
2150 }
2151
2152 // Trigonometric functions
2153
2154 double Item_func_acos::val_real()
2155 {
2156 DBUG_ASSERT(fixed == 1);
2157 /* One can use this to defer SELECT processing. */
2158 DEBUG_SYNC(current_thd, "before_acos_function");
2159 // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug)
2160 volatile double value= args[0]->val_real();
Create_func_load_file()2161 if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0))))
2162 return 0.0;
2163 return acos(value);
2164 }
2165
2166 double Item_func_asin::val_real()
2167 {
2168 DBUG_ASSERT(fixed == 1);
2169 // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug)
2170 volatile double value= args[0]->val_real();
2171 if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0))))
2172 return 0.0;
2173 return asin(value);
Create_func_locate()2174 }
2175
2176 double Item_func_atan::val_real()
2177 {
2178 DBUG_ASSERT(fixed == 1);
2179 double value= args[0]->val_real();
2180 if ((null_value=args[0]->null_value))
2181 return 0.0;
2182 if (arg_count == 2)
2183 {
2184 double val2= args[1]->val_real();
2185 if ((null_value=args[1]->null_value))
2186 return 0.0;
2187 return check_float_overflow(atan2(value,val2));
2188 }
2189 return atan(value);
2190 }
2191
2192 double Item_func_cos::val_real()
2193 {
2194 DBUG_ASSERT(fixed == 1);
2195 double value= args[0]->val_real();
2196 if ((null_value=args[0]->null_value))
2197 return 0.0;
2198 return cos(value);
2199 }
Create_func_log10()2200
2201 double Item_func_sin::val_real()
2202 {
2203 DBUG_ASSERT(fixed == 1);
2204 double value= args[0]->val_real();
2205 if ((null_value=args[0]->null_value))
2206 return 0.0;
2207 return sin(value);
2208 }
2209
2210 double Item_func_tan::val_real()
2211 {
2212 DBUG_ASSERT(fixed == 1);
Create_func_log2()2213 double value= args[0]->val_real();
~Create_func_log2()2214 if ((null_value=args[0]->null_value))
2215 return 0.0;
2216 return check_float_overflow(tan(value));
2217 }
2218
2219
2220 double Item_func_cot::val_real()
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)2221 {
2222 DBUG_ASSERT(fixed == 1);
2223 double value= args[0]->val_real();
2224 if ((null_value=args[0]->null_value))
2225 return 0.0;
2226 return check_float_overflow(1.0 / tan(value));
2227 }
2228
2229
2230 // Shift-functions, same as << and >> in C/C++
Create_func_lpad()2231
2232
2233 longlong Item_func_shift_left::val_int()
2234 {
2235 DBUG_ASSERT(fixed == 1);
2236 uint shift;
2237 ulonglong res= ((ulonglong) args[0]->val_int() <<
2238 (shift=(uint) args[1]->val_int()));
2239 if (args[0]->null_value || args[1]->null_value)
2240 {
2241 null_value=1;
2242 return 0;
2243 }
2244 null_value=0;
2245 return (shift < sizeof(longlong)*8 ? (longlong) res : 0);
2246 }
2247
2248 longlong Item_func_shift_right::val_int()
2249 {
2250 DBUG_ASSERT(fixed == 1);
2251 uint shift;
2252 ulonglong res= (ulonglong) args[0]->val_int() >>
2253 (shift=(uint) args[1]->val_int());
2254 if (args[0]->null_value || args[1]->null_value)
2255 {
2256 null_value=1;
Create_func_ltrim()2257 return 0;
~Create_func_ltrim()2258 }
2259 null_value=0;
2260 return (shift < sizeof(longlong)*8 ? (longlong) res : 0);
2261 }
2262
2263
2264 longlong Item_func_bit_neg::val_int()
2265 {
2266 DBUG_ASSERT(fixed == 1);
2267 ulonglong res= (ulonglong) args[0]->val_int();
2268 if ((null_value=args[0]->null_value))
2269 return 0;
Create_func_ltrim_oracle()2270 return ~res;
~Create_func_ltrim_oracle()2271 }
2272
2273
2274 // Conversion functions
2275
2276 void Item_func_int_val::fix_length_and_dec_int_or_decimal()
2277 {
2278 /*
2279 The INT branch of this code should be revised.
2280 It creates too large data types, e.g.
2281 CREATE OR REPLACE TABLE t2 AS SELECT FLOOR(9999999.999) AS fa;
2282 results in a BININT(10) column, while INT(7) should probably be enough.
2283 */
2284 ulonglong tmp_max_length= (ulonglong ) args[0]->max_length -
2285 (args[0]->decimals ? args[0]->decimals + 1 : 0) + 2;
2286 max_length= tmp_max_length > (ulonglong) UINT_MAX32 ?
2287 (uint32) UINT_MAX32 : (uint32) tmp_max_length;
2288 uint tmp= float_length(decimals);
2289 set_if_smaller(max_length,tmp);
2290 decimals= 0;
2291
2292 /*
2293 -2 because in most high position can't be used any digit for longlong
2294 and one position for increasing value during operation
2295 */
2296 if (args[0]->max_length - args[0]->decimals >= DECIMAL_LONGLONG_DIGITS - 2)
2297 {
2298 fix_char_length(
2299 my_decimal_precision_to_length_no_truncation(
2300 args[0]->decimal_int_part(), 0, false));
2301 set_handler(&type_handler_newdecimal);
2302 }
2303 else
2304 {
2305 unsigned_flag= args[0]->unsigned_flag;
2306 set_handler(type_handler_long_or_longlong());
2307 }
2308 }
Create_func_make_set()2309
2310
2311 void Item_func_int_val::fix_length_and_dec_double()
2312 {
2313 set_handler(&type_handler_double);
2314 max_length= float_length(0);
2315 decimals= 0;
2316 }
2317
2318
2319 bool Item_func_int_val::fix_length_and_dec()
2320 {
2321 DBUG_ENTER("Item_func_int_val::fix_length_and_dec");
Create_func_master_pos_wait()2322 DBUG_PRINT("info", ("name %s", func_name()));
~Create_func_master_pos_wait()2323 if (args[0]->cast_to_int_type_handler()->
2324 Item_func_int_val_fix_length_and_dec(this))
2325 DBUG_RETURN(TRUE);
2326 DBUG_PRINT("info", ("Type: %s", type_handler()->name().ptr()));
2327 DBUG_RETURN(FALSE);
2328 }
2329
2330
2331 longlong Item_func_ceiling::int_op()
2332 {
2333 longlong result;
2334 switch (args[0]->result_type()) {
Create_func_master_gtid_wait()2335 case INT_RESULT:
2336 result= args[0]->val_int();
2337 null_value= args[0]->null_value;
2338 break;
2339 case DECIMAL_RESULT:
2340 {
2341 my_decimal dec_buf, *dec;
2342 if ((dec= Item_func_ceiling::decimal_op(&dec_buf)))
2343 my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result);
2344 else
2345 result= 0;
2346 break;
2347 }
Create_func_md5()2348 default:
2349 result= (longlong)Item_func_ceiling::real_op();
2350 };
2351 return result;
2352 }
2353
2354
2355 double Item_func_ceiling::real_op()
2356 {
2357 /*
2358 the volatile's for BUG #3051 to calm optimizer down (because of gcc's
2359 bug)
2360 */
Create_func_monthname()2361 volatile double value= args[0]->val_real();
~Create_func_monthname()2362 null_value= args[0]->null_value;
2363 return ceil(value);
2364 }
2365
2366
2367 my_decimal *Item_func_ceiling::decimal_op(my_decimal *decimal_value)
2368 {
2369 my_decimal val, *value= args[0]->val_decimal(&val);
2370 if (!(null_value= (args[0]->null_value ||
2371 my_decimal_ceiling(E_DEC_FATAL_ERROR, value,
2372 decimal_value) > 1)))
2373 return decimal_value;
Create_func_name_const()2374 return 0;
~Create_func_name_const()2375 }
2376
2377
2378 longlong Item_func_floor::int_op()
2379 {
2380 longlong result;
2381 switch (args[0]->result_type()) {
2382 case INT_RESULT:
2383 result= args[0]->val_int();
2384 null_value= args[0]->null_value;
2385 break;
2386 case DECIMAL_RESULT:
2387 {
2388 my_decimal dec_buf, *dec;
2389 if ((dec= Item_func_floor::decimal_op(&dec_buf)))
2390 my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result);
2391 else
2392 result= 0;
2393 break;
2394 }
2395 default:
2396 result= (longlong)Item_func_floor::real_op();
2397 };
2398 return result;
2399 }
2400
Create_func_numgeometries()2401
2402 double Item_func_floor::real_op()
2403 {
2404 /*
2405 the volatile's for BUG #3051 to calm optimizer down (because of gcc's
2406 bug)
2407 */
2408 volatile double value= args[0]->val_real();
2409 null_value= args[0]->null_value;
2410 return floor(value);
2411 }
2412
2413
2414 my_decimal *Item_func_floor::decimal_op(my_decimal *decimal_value)
2415 {
Create_func_numinteriorring()2416 my_decimal val, *value= args[0]->val_decimal(&val);
~Create_func_numinteriorring()2417 if (!(null_value= (args[0]->null_value ||
2418 my_decimal_floor(E_DEC_FATAL_ERROR, value,
2419 decimal_value) > 1)))
2420 return decimal_value;
2421 return 0;
2422 }
2423
2424
2425 void Item_func_round::fix_length_and_dec_decimal(uint decimals_to_set)
2426 {
2427 int decimals_delta= args[0]->decimals - decimals_to_set;
2428 int length_increase= (decimals_delta <= 0 || truncate) ? 0 : 1;
2429 int precision= args[0]->decimal_precision() + length_increase -
2430 decimals_delta;
Create_func_numpoints()2431 DBUG_ASSERT(decimals_to_set <= DECIMAL_MAX_SCALE);
~Create_func_numpoints()2432 set_handler(&type_handler_newdecimal);
2433 unsigned_flag= args[0]->unsigned_flag;
2434 decimals= decimals_to_set;
2435 if (!precision)
2436 precision= 1; // DECIMAL(0,0) -> DECIMAL(1,0)
2437 max_length= my_decimal_precision_to_length_no_truncation(precision,
2438 decimals,
2439 unsigned_flag);
2440 }
2441
2442 void Item_func_round::fix_length_and_dec_double(uint decimals_to_set)
2443 {
2444 set_handler(&type_handler_double);
Create_func_oct()2445 unsigned_flag= args[0]->unsigned_flag;
~Create_func_oct()2446 decimals= decimals_to_set;
2447 max_length= float_length(decimals_to_set);
2448 }
2449
2450
2451 void Item_func_round::fix_arg_decimal()
2452 {
2453 if (args[1]->const_item())
2454 {
2455 Longlong_hybrid dec= args[1]->to_longlong_hybrid();
2456 if (args[1]->null_value)
2457 fix_length_and_dec_double(NOT_FIXED_DEC);
Create_func_ord()2458 else
2459 fix_length_and_dec_decimal(dec.to_uint(DECIMAL_MAX_SCALE));
2460 }
2461 else
2462 {
2463 set_handler(&type_handler_newdecimal);
2464 unsigned_flag= args[0]->unsigned_flag;
2465 decimals= args[0]->decimals;
2466 max_length= float_length(args[0]->decimals) + 1;
2467 }
2468 }
2469
2470
2471 void Item_func_round::fix_arg_double()
Create_func_mbr_overlaps()2472 {
2473 if (args[1]->const_item())
2474 {
2475 Longlong_hybrid dec= args[1]->to_longlong_hybrid();
2476 fix_length_and_dec_double(args[1]->null_value ? NOT_FIXED_DEC :
2477 dec.to_uint(NOT_FIXED_DEC));
2478 }
2479 else
2480 fix_length_and_dec_double(args[0]->decimals);
2481 }
2482
2483
2484 void Item_func_round::fix_arg_int()
Create_func_overlaps()2485 {
2486 if (args[1]->const_item())
2487 {
2488 Longlong_hybrid val1= args[1]->to_longlong_hybrid();
2489 if (args[1]->null_value)
2490 fix_length_and_dec_double(NOT_FIXED_DEC);
2491 else if ((!val1.to_uint(DECIMAL_MAX_SCALE) && truncate) ||
2492 args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS)
2493 {
2494 // Length can increase in some cases: ROUND(9,-1) -> 10
2495 int length_can_increase= MY_TEST(!truncate && val1.neg());
2496 max_length= args[0]->max_length + length_can_increase;
2497 // Here we can keep INT_RESULT
2498 unsigned_flag= args[0]->unsigned_flag;
2499 decimals= 0;
2500 set_handler(type_handler_long_or_longlong());
2501 }
2502 else
2503 fix_length_and_dec_decimal(val1.to_uint(DECIMAL_MAX_SCALE));
2504 }
2505 else
2506 fix_length_and_dec_double(args[0]->decimals);
2507 }
2508
2509
2510 double my_double_round(double value, longlong dec, bool dec_unsigned,
2511 bool truncate)
Create_func_period_diff()2512 {
2513 double tmp;
2514 bool dec_negative= (dec < 0) && !dec_unsigned;
2515 ulonglong abs_dec= dec_negative ? -dec : dec;
2516 /*
2517 tmp2 is here to avoid return the value with 80 bit precision
2518 This will fix that the test round(0.1,1) = round(0.1,1) is true
2519 Tagging with volatile is no guarantee, it may still be optimized away...
2520 */
2521 volatile double tmp2;
2522
2523 tmp=(abs_dec < array_elements(log_10) ?
2524 log_10[abs_dec] : pow(10.0,(double) abs_dec));
2525
2526 // Pre-compute these, to avoid optimizing away e.g. 'floor(v/tmp) * tmp'.
2527 volatile double value_div_tmp= value / tmp;
2528 volatile double value_mul_tmp= value * tmp;
2529
2530 if (!dec_negative && std::isinf(tmp)) // "dec" is too large positive number
2531 return value;
2532
2533 if (dec_negative && std::isinf(tmp))
2534 tmp2= 0.0;
2535 else if (!dec_negative && std::isinf(value_mul_tmp))
2536 tmp2= value;
2537 else if (truncate)
2538 {
2539 if (value >= 0.0)
2540 tmp2= dec < 0 ? floor(value_div_tmp) * tmp : floor(value_mul_tmp) / tmp;
2541 else
2542 tmp2= dec < 0 ? ceil(value_div_tmp) * tmp : ceil(value_mul_tmp) / tmp;
2543 }
2544 else
2545 tmp2=dec < 0 ? rint(value_div_tmp) * tmp : rint(value_mul_tmp) / tmp;
2546
2547 return tmp2;
2548 }
2549
2550
2551 double Item_func_round::real_op()
2552 {
Create_func_pow()2553 double value= args[0]->val_real();
~Create_func_pow()2554
2555 if (!(null_value= args[0]->null_value))
2556 {
2557 longlong dec= args[1]->val_int();
2558 if (!(null_value= args[1]->null_value))
2559 return my_double_round(value, dec, args[1]->unsigned_flag, truncate);
2560 }
2561 return 0.0;
2562 }
2563
2564 /*
2565 Rounds a given value to a power of 10 specified as the 'to' argument,
Create_func_quote()2566 avoiding overflows when the value is close to the ulonglong range boundary.
2567 */
2568
2569 static inline ulonglong my_unsigned_round(ulonglong value, ulonglong to)
2570 {
2571 ulonglong tmp= value / to * to;
2572 return (value - tmp < (to >> 1)) ? tmp : tmp + to;
2573 }
2574
2575
2576 longlong Item_func_round::int_op()
2577 {
2578 longlong value= args[0]->val_int();
Create_func_regexp_instr()2579 longlong dec= args[1]->val_int();
~Create_func_regexp_instr()2580 decimals= 0;
2581 ulonglong abs_dec;
2582 if ((null_value= args[0]->null_value || args[1]->null_value))
2583 return 0;
2584 if ((dec >= 0) || args[1]->unsigned_flag)
2585 return value; // integer have not digits after point
2586
2587 abs_dec= -dec;
2588 longlong tmp;
2589
2590 if(abs_dec >= array_elements(log_10_int))
2591 return 0;
Create_func_regexp_replace()2592
2593 tmp= log_10_int[abs_dec];
2594
2595 if (truncate)
2596 value= (unsigned_flag) ?
2597 ((ulonglong) value / tmp) * tmp : (value / tmp) * tmp;
2598 else
2599 value= (unsigned_flag || value >= 0) ?
2600 my_unsigned_round((ulonglong) value, tmp) :
2601 -(longlong) my_unsigned_round((ulonglong) -value, tmp);
2602 return value;
2603 }
2604
Create_func_regexp_substr()2605
2606 my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value)
2607 {
2608 my_decimal val, *value= args[0]->val_decimal(&val);
2609 longlong dec= args[1]->val_int();
2610 if (dec >= 0 || args[1]->unsigned_flag)
2611 dec= MY_MIN((ulonglong) dec, decimals);
2612 else if (dec < INT_MIN)
2613 dec= INT_MIN;
2614
2615 if (!(null_value= (args[0]->null_value || args[1]->null_value ||
2616 my_decimal_round(E_DEC_FATAL_ERROR, value, (int) dec,
2617 truncate, decimal_value) > 1)))
2618 return decimal_value;
2619 return 0;
2620 }
2621
2622
2623 void Item_func_rand::seed_random(Item *arg)
2624 {
2625 /*
2626 TODO: do not do reinit 'rand' for every execute of PS/SP if
2627 args[0] is a constant.
2628 */
2629 uint32 tmp= (uint32) arg->val_int();
2630 #ifdef WITH_WSREP
Create_func_rand()2631 if (WSREP_ON)
2632 {
2633 THD *thd= current_thd;
2634 if (WSREP(thd))
2635 {
2636 if (thd->wsrep_exec_mode==REPL_RECV)
2637 tmp= thd->wsrep_rand;
2638 else
2639 thd->wsrep_rand= tmp;
2640 }
2641 }
2642 #endif /* WITH_WSREP */
2643
Create_func_release_lock()2644 my_rnd_init(rand, (uint32) (tmp*0x10001L+55555555L),
2645 (uint32) (tmp*0x10000001L));
2646 }
2647
2648
2649 bool Item_func_rand::fix_fields(THD *thd,Item **ref)
2650 {
2651 if (Item_real_func::fix_fields(thd, ref))
2652 return TRUE;
2653 used_tables_cache|= RAND_TABLE_BIT;
2654 if (arg_count)
2655 { // Only use argument once in query
2656 /*
Create_func_replace_oracle()2657 Allocate rand structure once: we must use thd->stmt_arena
2658 to create rand in proper mem_root if it's a prepared statement or
2659 stored procedure.
2660
2661 No need to send a Rand log event if seed was given eg: RAND(seed),
2662 as it will be replicated in the query as such.
2663 */
2664 if (!rand && !(rand= (struct my_rnd_struct*)
2665 thd->stmt_arena->alloc(sizeof(*rand))))
2666 return TRUE;
2667 }
2668 else
2669 {
Create_func_reverse()2670 /*
2671 Save the seed only the first time RAND() is used in the query
2672 Once events are forwarded rather than recreated,
2673 the following can be skipped if inside the slave thread
2674 */
2675 if (!thd->rand_used)
2676 {
2677 thd->rand_used= 1;
2678 thd->rand_saved_seed1= thd->rand.seed1;
2679 thd->rand_saved_seed2= thd->rand.seed2;
2680 }
2681 rand= &thd->rand;
2682 }
Create_func_round()2683 return FALSE;
~Create_func_round()2684 }
2685
2686 void Item_func_rand::update_used_tables()
2687 {
2688 Item_real_func::update_used_tables();
2689 used_tables_cache|= RAND_TABLE_BIT;
2690 }
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)2691
2692
2693 double Item_func_rand::val_real()
2694 {
2695 DBUG_ASSERT(fixed == 1);
2696 if (arg_count)
2697 {
2698 if (!args[0]->const_item())
2699 seed_random(args[0]);
2700 else if (first_eval)
2701 {
2702 /*
2703 Constantness of args[0] may be set during JOIN::optimize(), if arg[0]
2704 is a field item of "constant" table. Thus, we have to evaluate
2705 seed_random() for constant arg there but not at the fix_fields method.
2706 */
2707 first_eval= FALSE;
2708 seed_random(args[0]);
2709 }
2710 }
2711 return my_rnd(rand);
2712 }
2713
2714 longlong Item_func_sign::val_int()
2715 {
2716 DBUG_ASSERT(fixed == 1);
2717 double value= args[0]->val_real();
2718 null_value=args[0]->null_value;
2719 return value < 0.0 ? -1 : (value > 0 ? 1 : 0);
2720 }
2721
2722
2723 double Item_func_units::val_real()
2724 {
2725 DBUG_ASSERT(fixed == 1);
2726 double value= args[0]->val_real();
Create_func_rtrim()2727 if ((null_value=args[0]->null_value))
2728 return 0;
2729 return check_float_overflow(value * mul + add);
2730 }
2731
2732
2733 bool Item_func_min_max::fix_attributes(Item **items, uint nitems)
2734 {
2735 bool rc= Item_func_min_max::type_handler()->
2736 Item_func_min_max_fix_attributes(current_thd, this, items, nitems);
2737 DBUG_ASSERT(!rc || current_thd->is_error());
2738 return rc;
2739 }
Create_func_rtrim_oracle()2740
2741
2742 /*
2743 Compare item arguments using DATETIME/DATE/TIME representation.
2744
2745 DESCRIPTION
2746 Compare item arguments as DATETIME values and return the index of the
2747 least/greatest argument in the arguments array.
2748 The correct DATE/DATETIME value of the found argument is
2749 stored to the value pointer, if latter is provided.
2750
2751 RETURN
2752 1 If one of arguments is NULL or there was a execution error
2753 0 Otherwise
2754 */
2755
2756 bool Item_func_min_max::get_date_native(MYSQL_TIME *ltime, ulonglong fuzzy_date)
2757 {
2758 longlong UNINIT_VAR(min_max);
2759 DBUG_ASSERT(fixed == 1);
2760
2761 for (uint i=0; i < arg_count ; i++)
2762 {
2763 longlong res= args[i]->val_datetime_packed();
2764
2765 /* Check if we need to stop (because of error or KILL) and stop the loop */
2766 if (unlikely(args[i]->null_value))
2767 return (null_value= 1);
2768
2769 if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0)
2770 min_max= res;
2771 }
2772 unpack_time(min_max, ltime, mysql_timestamp_type());
2773
2774 if (!(fuzzy_date & TIME_TIME_ONLY) &&
2775 unlikely((null_value= check_date_with_warn(ltime, fuzzy_date,
2776 MYSQL_TIMESTAMP_ERROR))))
2777 return true;
2778
2779 return (null_value= 0);
2780 }
2781
2782
2783 bool Item_func_min_max::get_time_native(MYSQL_TIME *ltime)
2784 {
2785 DBUG_ASSERT(fixed == 1);
2786
2787 Time value(args[0]);
2788 if (!value.is_valid_time())
2789 return (null_value= true);
2790
2791 for (uint i= 1; i < arg_count ; i++)
Create_func_sign()2792 {
2793 Time tmp(args[i]);
2794 if (!tmp.is_valid_time())
2795 return (null_value= true);
2796
2797 int cmp= value.cmp(&tmp);
2798 if ((cmp_sign < 0 ? cmp : -cmp) < 0)
2799 value= tmp;
2800 }
2801 value.copy_to_mysql_time(ltime);
2802 return (null_value= 0);
2803 }
2804
Create_func_sin()2805
2806 String *Item_func_min_max::val_str_native(String *str)
2807 {
2808 String *UNINIT_VAR(res);
2809 for (uint i=0; i < arg_count ; i++)
2810 {
2811 if (i == 0)
2812 res=args[i]->val_str(str);
2813 else
2814 {
2815 String *res2;
2816 res2= args[i]->val_str(res == str ? &tmp_value : str);
2817 if (res2)
2818 {
2819 int cmp= sortcmp(res,res2,collation.collation);
2820 if ((cmp_sign < 0 ? cmp : -cmp) < 0)
2821 res=res2;
2822 }
2823 }
2824 if ((null_value= args[i]->null_value))
2825 return 0;
2826 }
2827 res->set_charset(collation.collation);
2828 return res;
2829 }
2830
Create_func_soundex()2831
2832 double Item_func_min_max::val_real_native()
2833 {
2834 double value=0.0;
2835 for (uint i=0; i < arg_count ; i++)
2836 {
2837 if (i == 0)
2838 value= args[i]->val_real();
2839 else
2840 {
2841 double tmp= args[i]->val_real();
2842 if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0)
2843 value=tmp;
2844 }
2845 if ((null_value= args[i]->null_value))
2846 break;
2847 }
2848 return value;
2849 }
2850
2851
2852 longlong Item_func_min_max::val_int_native()
2853 {
2854 DBUG_ASSERT(fixed == 1);
2855 longlong value=0;
2856 for (uint i=0; i < arg_count ; i++)
Create_func_sqrt()2857 {
2858 if (i == 0)
2859 value=args[i]->val_int();
2860 else
2861 {
2862 longlong tmp=args[i]->val_int();
2863 if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0)
2864 value=tmp;
2865 }
2866 if ((null_value= args[i]->null_value))
2867 break;
2868 }
2869 return value;
2870 }
Create_func_srid()2871
2872
2873 my_decimal *Item_func_min_max::val_decimal_native(my_decimal *dec)
2874 {
2875 DBUG_ASSERT(fixed == 1);
2876 my_decimal tmp_buf, *tmp, *UNINIT_VAR(res);
2877
2878 for (uint i=0; i < arg_count ; i++)
2879 {
2880 if (i == 0)
2881 res= args[i]->val_decimal(dec);
2882 else
2883 {
2884 tmp= args[i]->val_decimal(&tmp_buf); // Zero if NULL
2885 if (tmp && (my_decimal_cmp(tmp, res) * cmp_sign) < 0)
2886 {
2887 if (tmp == &tmp_buf)
2888 {
2889 /* Move value out of tmp_buf as this will be reused on next loop */
2890 my_decimal2decimal(tmp, dec);
2891 res= dec;
2892 }
2893 else
2894 res= tmp;
2895 }
2896 }
2897 if ((null_value= args[i]->null_value))
2898 {
2899 res= 0;
2900 break;
2901 }
2902 }
2903 return res;
2904 }
2905
2906
2907 longlong Item_func_bit_length::val_int()
2908 {
2909 DBUG_ASSERT(fixed == 1);
2910 String *res= args[0]->val_str(&value);
2911 return (null_value= !res) ? 0 : (longlong) res->length() * 8;
2912 }
Create_func_strcmp()2913
2914
2915 longlong Item_func_octet_length::val_int()
2916 {
2917 DBUG_ASSERT(fixed == 1);
2918 String *res=args[0]->val_str(&value);
2919 if (!res)
2920 {
2921 null_value=1;
2922 return 0; /* purecov: inspected */
2923 }
2924 null_value=0;
2925 return (longlong) res->length();
2926 }
~Create_func_substr_index()2927
2928
2929 longlong Item_func_char_length::val_int()
2930 {
2931 DBUG_ASSERT(fixed == 1);
2932 String *res=args[0]->val_str(&value);
2933 if (!res)
2934 {
2935 null_value=1;
2936 return 0; /* purecov: inspected */
2937 }
2938 null_value=0;
2939 return (longlong) res->numchars();
2940 }
~Create_func_substr_oracle()2941
2942
2943 longlong Item_func_coercibility::val_int()
2944 {
2945 DBUG_ASSERT(fixed == 1);
2946 null_value= 0;
2947 return (longlong) args[0]->collation.derivation;
2948 }
2949
2950
2951 longlong Item_func_locate::val_int()
2952 {
Create_func_subtime()2953 DBUG_ASSERT(fixed == 1);
~Create_func_subtime()2954 String *a=args[0]->val_str(&value1);
2955 String *b=args[1]->val_str(&value2);
2956 if (!a || !b)
2957 {
2958 null_value=1;
2959 return 0; /* purecov: inspected */
2960 }
2961 null_value=0;
2962 /* must be longlong to avoid truncation */
2963 longlong start= 0;
2964 longlong start0= 0;
2965 my_match_t match;
Create_func_tan()2966
2967 if (arg_count == 3)
2968 {
2969 start0= start= args[2]->val_int() - 1;
2970
2971 if ((start < 0) || (start > a->length()))
2972 return 0;
2973
2974 /* start is now sufficiently valid to pass to charpos function */
2975 start= a->charpos((int) start);
2976
2977 if (start + b->length() > a->length())
2978 return 0;
2979 }
~Create_func_time_format()2980
2981 if (!b->length()) // Found empty string at start
2982 return start + 1;
2983
2984 if (!cmp_collation.collation->coll->instr(cmp_collation.collation,
2985 a->ptr()+start,
2986 (uint) (a->length()-start),
2987 b->ptr(), b->length(),
2988 &match, 1))
2989 return 0;
2990 return (longlong) match.mb_len + start0 + 1;
2991 }
Create_func_time_to_sec()2992
2993
2994 void Item_func_locate::print(String *str, enum_query_type query_type)
2995 {
2996 str->append(STRING_WITH_LEN("locate("));
2997 args[1]->print(str, query_type);
2998 str->append(',');
2999 args[0]->print(str, query_type);
3000 if (arg_count == 3)
3001 {
3002 str->append(',');
3003 args[2]->print(str, query_type);
3004 }
3005 str->append(')');
3006 }
3007
3008
3009 longlong Item_func_field::val_int()
3010 {
3011 DBUG_ASSERT(fixed == 1);
3012
3013 if (cmp_type == STRING_RESULT)
3014 {
3015 String *field;
3016 if (!(field= args[0]->val_str(&value)))
3017 return 0;
Create_func_to_base64()3018 for (uint i=1 ; i < arg_count ; i++)
~Create_func_to_base64()3019 {
3020 String *tmp_value=args[i]->val_str(&tmp);
3021 if (tmp_value && !sortcmp(field,tmp_value,cmp_collation.collation))
3022 return (longlong) (i);
3023 }
3024 }
3025 else if (cmp_type == INT_RESULT)
3026 {
3027 longlong val= args[0]->val_int();
3028 if (args[0]->null_value)
3029 return 0;
3030 for (uint i=1; i < arg_count ; i++)
Create_func_to_days()3031 {
3032 if (val == args[i]->val_int() && !args[i]->null_value)
3033 return (longlong) (i);
3034 }
3035 }
3036 else if (cmp_type == DECIMAL_RESULT)
3037 {
3038 my_decimal dec_arg_buf, *dec_arg,
3039 dec_buf, *dec= args[0]->val_decimal(&dec_buf);
3040 if (args[0]->null_value)
3041 return 0;
3042 for (uint i=1; i < arg_count; i++)
Create_func_to_seconds()3043 {
3044 dec_arg= args[i]->val_decimal(&dec_arg_buf);
3045 if (!args[i]->null_value && !my_decimal_cmp(dec_arg, dec))
3046 return (longlong) (i);
3047 }
3048 }
3049 else
3050 {
3051 double val= args[0]->val_real();
3052 if (args[0]->null_value)
3053 return 0;
3054 for (uint i=1; i < arg_count ; i++)
3055 {
3056 if (val == args[i]->val_real() && !args[i]->null_value)
Create_func_touches()3057 return (longlong) (i);
~Create_func_touches()3058 }
3059 }
3060 return 0;
3061 }
3062
3063
3064 bool Item_func_field::fix_length_and_dec()
3065 {
3066 maybe_null=0; max_length=3;
3067 cmp_type= args[0]->result_type();
3068 for (uint i=1; i < arg_count ; i++)
3069 cmp_type= item_cmp_type(cmp_type, args[i]->result_type());
3070 if (cmp_type == STRING_RESULT)
Create_func_ucase()3071 return agg_arg_charsets_for_comparison(cmp_collation, args, arg_count);
~Create_func_ucase()3072 return FALSE;
3073 }
3074
3075
3076 longlong Item_func_ascii::val_int()
3077 {
3078 DBUG_ASSERT(fixed == 1);
3079 String *res=args[0]->val_str(&value);
3080 if (!res)
3081 {
3082 null_value=1;
3083 return 0;
Create_func_uncompress()3084 }
3085 null_value=0;
3086 return (longlong) (res->length() ? (uchar) (*res)[0] : (uchar) 0);
3087 }
3088
3089 longlong Item_func_ord::val_int()
3090 {
3091 DBUG_ASSERT(fixed == 1);
3092 String *res=args[0]->val_str(&value);
3093 if (!res)
3094 {
3095 null_value=1;
3096 return 0;
Create_func_uncompressed_length()3097 }
3098 null_value=0;
3099 if (!res->length()) return 0;
3100 #ifdef USE_MB
3101 if (use_mb(res->charset()))
3102 {
3103 const char *str=res->ptr();
3104 uint32 n=0, l=my_ismbchar(res->charset(),str,str+res->length());
3105 if (!l)
3106 return (longlong)((uchar) *str);
3107 while (l--)
3108 n=(n<<8)|(uint32)((uchar) *str++);
3109 return (longlong) n;
Create_func_unhex()3110 }
3111 #endif
3112 return (longlong) ((uchar) (*res)[0]);
3113 }
3114
3115 /* Search after a string in a string of strings separated by ',' */
3116 /* Returns number of found type >= 1 or 0 if not found */
3117 /* This optimizes searching in enums to bit testing! */
3118
3119 bool Item_func_find_in_set::fix_length_and_dec()
3120 {
3121 decimals=0;
3122 max_length=3; // 1-999
Create_func_unix_timestamp()3123 if (args[0]->const_item() && args[1]->type() == FIELD_ITEM)
3124 {
3125 Field *field= ((Item_field*) args[1])->field;
3126 if (field->real_type() == MYSQL_TYPE_SET)
3127 {
3128 String *find=args[0]->val_str(&value);
3129 if (find)
3130 {
3131 // find is not NULL pointer so args[0] is not a null-value
3132 DBUG_ASSERT(!args[0]->null_value);
3133 enum_value= find_type(((Field_enum*) field)->typelib,find->ptr(),
3134 find->length(), 0);
3135 enum_bit=0;
3136 if (enum_value)
3137 enum_bit=1LL << (enum_value-1);
3138 }
3139 }
3140 }
3141 return agg_arg_charsets_for_comparison(cmp_collation, args, 2);
3142 }
3143
3144 static const char separator=',';
3145
3146 longlong Item_func_find_in_set::val_int()
3147 {
3148 DBUG_ASSERT(fixed == 1);
Create_func_uuid_short()3149 if (enum_value)
3150 {
3151 // enum_value is set iff args[0]->const_item() in fix_length_and_dec().
3152 DBUG_ASSERT(args[0]->const_item());
3153
3154 ulonglong tmp= (ulonglong) args[1]->val_int();
3155 null_value= args[1]->null_value;
3156 /*
3157 No need to check args[0]->null_value since enum_value is set iff
3158 args[0] is a non-null const item. Note: no DBUG_ASSERT on
3159 args[0]->null_value here because args[0] may have been replaced
3160 by an Item_cache on which val_int() has not been called. See
3161 BUG#11766317
3162 */
3163 if (!null_value)
3164 {
3165 if (tmp & enum_bit)
3166 return enum_value;
3167 }
3168 return 0L;
3169 }
3170
3171 String *find=args[0]->val_str(&value);
3172 String *buffer=args[1]->val_str(&value2);
3173 if (!find || !buffer)
3174 {
Create_func_weekday()3175 null_value=1;
~Create_func_weekday()3176 return 0; /* purecov: inspected */
3177 }
3178 null_value=0;
3179
3180 if ((int) (buffer->length() - find->length()) >= 0)
3181 {
3182 my_wc_t wc= 0;
3183 CHARSET_INFO *cs= cmp_collation.collation;
3184 const char *str_begin= buffer->ptr();
3185 const char *str_end= buffer->ptr();
3186 const char *real_end= str_end+buffer->length();
3187 const uchar *find_str= (const uchar *) find->ptr();
Create_func_weekofyear()3188 uint find_str_len= find->length();
~Create_func_weekofyear()3189 int position= 0;
3190 while (1)
3191 {
3192 int symbol_len;
3193 if ((symbol_len= cs->cset->mb_wc(cs, &wc, (uchar*) str_end,
3194 (uchar*) real_end)) > 0)
3195 {
3196 const char *substr_end= str_end + symbol_len;
3197 bool is_last_item= (substr_end == real_end);
3198 bool is_separator= (wc == (my_wc_t) separator);
3199 if (is_separator || is_last_item)
3200 {
3201 position++;
Create_func_mbr_within()3202 if (is_last_item && !is_separator)
3203 str_end= substr_end;
3204 if (!my_strnncoll(cs, (const uchar *) str_begin,
3205 (uint) (str_end - str_begin),
3206 find_str, find_str_len))
3207 return (longlong) position;
3208 else
3209 str_begin= substr_end;
3210 }
3211 str_end= substr_end;
3212 }
3213 else if (str_end - str_begin == 0 &&
3214 find_str_len == 0 &&
Create_func_within()3215 wc == (my_wc_t) separator)
3216 return (longlong) ++position;
3217 else
3218 return 0;
3219 }
3220 }
3221 return 0;
3222 }
3223
3224 longlong Item_func_bit_count::val_int()
3225 {
3226 DBUG_ASSERT(fixed == 1);
3227 ulonglong value= (ulonglong) args[0]->val_int();
3228 if ((null_value= args[0]->null_value))
3229 return 0; /* purecov: inspected */
Create_func_x()3230 return (longlong) my_count_bits(value);
~Create_func_x()3231 }
3232
3233
3234 /****************************************************************************
3235 ** Functions to handle dynamic loadable functions
3236 ** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su>
3237 ** Rewritten by monty.
3238 ****************************************************************************/
3239
3240 #ifdef HAVE_DLOPEN
3241
3242 void udf_handler::cleanup()
3243 {
3244 if (!not_original)
3245 {
3246 if (initialized)
3247 {
3248 if (u_d->func_deinit != NULL)
3249 {
3250 Udf_func_deinit deinit= u_d->func_deinit;
3251 (*deinit)(&initid);
3252 }
3253 free_udf(u_d);
3254 initialized= FALSE;
3255 }
3256 if (buffers) // Because of bug in ecc
3257 delete [] buffers;
3258 buffers= 0;
3259 }
3260 }
3261
3262
3263 bool
3264 udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
3265 uint arg_count, Item **arguments)
3266 {
3267 uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
3268 DBUG_ENTER("Item_udf_func::fix_fields");
3269
3270 if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
Create_func_y()3271 DBUG_RETURN(TRUE); // Fatal error flag is set!
~Create_func_y()3272
3273 udf_func *tmp_udf=find_udf(u_d->name.str,u_d->name.length,1);
3274
3275 if (!tmp_udf)
3276 {
3277 my_error(ER_CANT_FIND_UDF, MYF(0), u_d->name.str);
3278 DBUG_RETURN(TRUE);
3279 }
3280 u_d=tmp_udf;
3281 args=arguments;
3282
3283 /* Fix all arguments */
3284 func->maybe_null=0;
Create_func_year_week()3285 func->used_tables_and_const_cache_init();
~Create_func_year_week()3286
3287 if ((f_args.arg_count=arg_count))
3288 {
3289 if (!(f_args.arg_type= (Item_result*)
3290 thd->alloc(f_args.arg_count*sizeof(Item_result))))
3291
3292 {
3293 free_udf(u_d);
3294 DBUG_RETURN(TRUE);
3295 }
3296 uint i;
3297 Item **arg,**arg_end;
3298 for (i=0, arg=arguments, arg_end=arguments+arg_count;
3299 arg != arg_end ;
3300 arg++,i++)
3301 {
3302 if ((*arg)->fix_fields_if_needed_for_scalar(thd, arg))
3303 DBUG_RETURN(true);
3304 // we can't assign 'item' before, because fix_fields() can change arg
3305 Item *item= *arg;
3306 /*
3307 TODO: We should think about this. It is not always
3308 right way just to set an UDF result to return my_charset_bin
3309 if one argument has binary sorting order.
3310 The result collation should be calculated according to arguments
3311 derivations in some cases and should not in other cases.
3312 Moreover, some arguments can represent a numeric input
3313 which doesn't effect the result character set and collation.
3314 There is no a general rule for UDF. Everything depends on
3315 the particular user defined function.
3316 */
3317 if (item->collation.collation->state & MY_CS_BINSORT)
3318 func->collation.set(&my_charset_bin);
3319 if (item->maybe_null)
3320 func->maybe_null=1;
3321 func->with_sum_func= func->with_sum_func || item->with_sum_func;
3322 func->with_window_func= func->with_window_func ||
3323 item->with_window_func;
3324 func->with_field= func->with_field || item->with_field;
3325 func->with_param= func->with_param || item->with_param;
3326 func->With_subquery_cache::join(item);
3327 func->used_tables_and_const_cache_join(item);
3328 f_args.arg_type[i]=item->result_type();
3329 }
3330 if (!(buffers=new (thd->mem_root) String[arg_count]) ||
3331 !multi_alloc_root(thd->mem_root,
3332 &f_args.args, arg_count * sizeof(char *),
3333 &f_args.lengths, arg_count * sizeof(long),
3334 &f_args.maybe_null, arg_count * sizeof(char),
3335 &num_buffer, arg_count * sizeof(double),
3336 &f_args.attributes, arg_count * sizeof(char *),
3337 &f_args.attribute_lengths, arg_count * sizeof(long),
3338 NullS))
3339 {
3340 free_udf(u_d);
3341 DBUG_RETURN(TRUE);
3342 }
3343 }
3344 if (func->fix_length_and_dec())
3345 DBUG_RETURN(TRUE);
3346 initid.max_length=func->max_length;
3347 initid.maybe_null=func->maybe_null;
3348 initid.const_item=func->const_item_cache;
3349 initid.decimals=func->decimals;
3350 initid.ptr=0;
3351 for (uint i1= 0 ; i1 < arg_count ; i1++)
3352 buffers[i1].set_thread_specific();
3353
3354 if (u_d->func_init)
3355 {
3356 char init_msg_buff[MYSQL_ERRMSG_SIZE];
3357 char *to=num_buffer;
3358 for (uint i=0; i < arg_count; i++)
3359 {
3360 /*
3361 For a constant argument i, args->args[i] points to the argument value.
3362 For non-constant, args->args[i] is NULL.
3363 */
3364 f_args.args[i]= NULL; /* Non-const unless updated below. */
3365
3366 f_args.lengths[i]= arguments[i]->max_length;
3367 f_args.maybe_null[i]= (char) arguments[i]->maybe_null;
3368 f_args.attributes[i]= arguments[i]->name.str;
create_func(THD * thd,LEX_CSTRING * name,List<Item> * item_list)3369 f_args.attribute_lengths[i]= (ulong)arguments[i]->name.length;
3370
3371 if (arguments[i]->const_item())
3372 {
3373 switch (arguments[i]->result_type()) {
3374 case STRING_RESULT:
3375 case DECIMAL_RESULT:
3376 {
3377 String *res= arguments[i]->val_str(&buffers[i]);
create(THD * thd,udf_func * udf,List<Item> * item_list)3378 if (arguments[i]->null_value)
3379 continue;
3380 f_args.args[i]= (char*) res->c_ptr_safe();
3381 f_args.lengths[i]= res->length();
3382 break;
3383 }
3384 case INT_RESULT:
3385 *((longlong*) to)= arguments[i]->val_int();
3386 if (arguments[i]->null_value)
3387 continue;
3388 f_args.args[i]= to;
3389 to+= ALIGN_SIZE(sizeof(longlong));
3390 break;
3391 case REAL_RESULT:
3392 *((double*) to)= arguments[i]->val_real();
3393 if (arguments[i]->null_value)
3394 continue;
3395 f_args.args[i]= to;
3396 to+= ALIGN_SIZE(sizeof(double));
3397 break;
3398 case ROW_RESULT:
3399 case TIME_RESULT:
3400 DBUG_ASSERT(0); // This case should never be chosen
3401 break;
3402 }
3403 }
3404 }
3405 Udf_func_init init= u_d->func_init;
3406 if (unlikely((error=(uchar) init(&initid, &f_args, init_msg_buff))))
3407 {
3408 my_error(ER_CANT_INITIALIZE_UDF, MYF(0),
3409 u_d->name.str, init_msg_buff);
3410 free_udf(u_d);
3411 DBUG_RETURN(TRUE);
3412 }
3413 func->max_length=MY_MIN(initid.max_length,MAX_BLOB_WIDTH);
3414 func->maybe_null=initid.maybe_null;
3415 /*
3416 The above call for init() can reset initid.const_item to "false",
3417 e.g. when the UDF function wants to be non-deterministic.
3418 See sequence_init() in udf_example.cc.
3419 */
3420 func->const_item_cache= initid.const_item;
3421 func->decimals=MY_MIN(initid.decimals,NOT_FIXED_DEC);
3422 }
3423 initialized=1;
3424 if (unlikely(error))
3425 {
3426 my_error(ER_CANT_INITIALIZE_UDF, MYF(0),
3427 u_d->name.str, ER_THD(thd, ER_UNKNOWN_ERROR));
3428 DBUG_RETURN(TRUE);
3429 }
3430 DBUG_RETURN(FALSE);
3431 }
3432
3433
3434 bool udf_handler::get_arguments()
3435 {
3436 if (unlikely(error))
3437 return 1; // Got an error earlier
3438 char *to= num_buffer;
3439 uint str_count=0;
3440 for (uint i=0; i < f_args.arg_count; i++)
3441 {
3442 f_args.args[i]=0;
3443 switch (f_args.arg_type[i]) {
3444 case STRING_RESULT:
3445 case DECIMAL_RESULT:
3446 {
3447 String *res=args[i]->val_str(&buffers[str_count++]);
3448 if (!(args[i]->null_value))
3449 {
3450 f_args.args[i]= (char*) res->ptr();
3451 f_args.lengths[i]= res->length();
3452 }
3453 else
3454 {
3455 f_args.lengths[i]= 0;
3456 }
3457 break;
3458 }
3459 case INT_RESULT:
3460 *((longlong*) to) = args[i]->val_int();
3461 if (!args[i]->null_value)
3462 {
3463 f_args.args[i]=to;
3464 to+= ALIGN_SIZE(sizeof(longlong));
3465 }
3466 break;
3467 case REAL_RESULT:
3468 *((double*) to)= args[i]->val_real();
3469 if (!args[i]->null_value)
3470 {
3471 f_args.args[i]=to;
3472 to+= ALIGN_SIZE(sizeof(double));
3473 }
3474 break;
3475 case ROW_RESULT:
3476 case TIME_RESULT:
3477 DBUG_ASSERT(0); // This case should never be chosen
3478 break;
create_with_db(THD * thd,LEX_CSTRING * db,LEX_CSTRING * name,bool use_explicit_name,List<Item> * item_list)3479 }
3480 }
3481 return 0;
3482 }
3483
3484 /**
3485 @return
3486 (String*)NULL in case of NULL values
3487 */
3488 String *udf_handler::val_str(String *str,String *save_str)
3489 {
3490 uchar is_null_tmp=0;
3491 ulong res_length;
3492 DBUG_ENTER("udf_handler::val_str");
3493
3494 if (get_arguments())
3495 DBUG_RETURN(0);
3496 char * (*func)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *)=
3497 (char* (*)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *))
3498 u_d->func;
3499
3500 if ((res_length=str->alloced_length()) < MAX_FIELD_WIDTH)
3501 { // This happens VERY seldom
3502 if (str->alloc(MAX_FIELD_WIDTH))
3503 {
3504 error=1;
3505 DBUG_RETURN(0);
3506 }
3507 }
3508 char *res=func(&initid, &f_args, (char*) str->ptr(), &res_length,
3509 &is_null_tmp, &error);
3510 DBUG_PRINT("info", ("udf func returned, res_length: %lu", res_length));
3511 if (is_null_tmp || !res || unlikely(error)) // The !res is for safety
3512 {
3513 DBUG_PRINT("info", ("Null or error"));
3514 DBUG_RETURN(0);
3515 }
3516 if (res == str->ptr())
3517 {
3518 str->length(res_length);
3519 DBUG_PRINT("exit", ("str: %*.s", (int) str->length(), str->ptr()));
3520 DBUG_RETURN(str);
3521 }
3522 save_str->set(res, res_length, str->charset());
3523 DBUG_PRINT("exit", ("save_str: %s", save_str->ptr()));
3524 DBUG_RETURN(save_str);
3525 }
3526
create_func(THD * thd,LEX_CSTRING * name,List<Item> * item_list)3527
3528 /*
3529 For the moment, UDF functions are returning DECIMAL values as strings
3530 */
3531
3532 my_decimal *udf_handler::val_decimal(my_bool *null_value, my_decimal *dec_buf)
3533 {
3534 char buf[DECIMAL_MAX_STR_LENGTH+1], *end;
3535 ulong res_length= DECIMAL_MAX_STR_LENGTH;
3536
3537 if (get_arguments())
3538 {
3539 *null_value=1;
3540 return 0;
3541 }
3542 char *(*func)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *)=
3543 (char* (*)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *))
3544 u_d->func;
3545
3546 char *res= func(&initid, &f_args, buf, &res_length, &is_null, &error);
3547 if (is_null || unlikely(error))
3548 {
3549 *null_value= 1;
3550 return 0;
3551 }
3552 end= res+ res_length;
3553 str2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf, &end);
3554 return dec_buf;
3555 }
3556
3557
create_func(THD * thd,LEX_CSTRING * name,List<Item> * item_list)3558 void Item_udf_func::cleanup()
3559 {
3560 udf.cleanup();
3561 Item_func::cleanup();
3562 }
3563
3564
3565 void Item_udf_func::print(String *str, enum_query_type query_type)
3566 {
3567 str->append(func_name());
3568 str->append('(');
3569 for (uint i=0 ; i < arg_count ; i++)
3570 {
3571 if (i != 0)
3572 str->append(',');
3573 args[i]->print_item_w_name(str, query_type);
3574 }
3575 str->append(')');
3576 }
3577
3578
3579 double Item_func_udf_float::val_real()
3580 {
3581 double res;
3582 my_bool tmp_null_value;
3583 DBUG_ASSERT(fixed == 1);
create_func(THD * thd,LEX_CSTRING * name,List<Item> * item_list)3584 DBUG_ENTER("Item_func_udf_float::val");
3585 DBUG_PRINT("info",("result_type: %d arg_count: %d",
3586 args[0]->result_type(), arg_count));
3587 res= udf.val(&tmp_null_value);
3588 null_value= tmp_null_value;
3589 DBUG_RETURN(res);
3590 }
3591
3592
3593 String *Item_func_udf_float::val_str(String *str)
3594 {
3595 DBUG_ASSERT(fixed == 1);
3596 double nr= val_real();
3597 if (null_value)
3598 return 0; /* purecov: inspected */
3599 str->set_real(nr,decimals,&my_charset_bin);
3600 return str;
3601 }
3602
3603
3604 longlong Item_func_udf_int::val_int()
3605 {
3606 longlong res;
3607 my_bool tmp_null_value;
3608 DBUG_ASSERT(fixed == 1);
3609 DBUG_ENTER("Item_func_udf_int::val_int");
3610 res= udf.val_int(&tmp_null_value);
3611 null_value= tmp_null_value;
create_func(THD * thd,LEX_CSTRING * name,List<Item> * item_list)3612 DBUG_RETURN(res);
3613 }
3614
3615
3616 String *Item_func_udf_int::val_str(String *str)
3617 {
3618 DBUG_ASSERT(fixed == 1);
3619 longlong nr=val_int();
3620 if (null_value)
3621 return 0;
3622 str->set_int(nr, unsigned_flag, &my_charset_bin);
3623 return str;
3624 }
3625
3626
3627 longlong Item_func_udf_decimal::val_int()
3628 {
3629 my_bool tmp_null_value;
3630 longlong result;
3631 my_decimal dec_buf, *dec= udf.val_decimal(&tmp_null_value, &dec_buf);
3632 null_value= tmp_null_value;
3633 if (null_value)
3634 return 0;
3635 my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result);
3636 return result;
3637 }
3638
3639
3640 double Item_func_udf_decimal::val_real()
3641 {
3642 my_bool tmp_null_value;
3643 double result;
create_1_arg(THD * thd,Item * arg1)3644 my_decimal dec_buf, *dec= udf.val_decimal(&tmp_null_value, &dec_buf);
3645 null_value= tmp_null_value;
3646 if (null_value)
3647 return 0.0;
3648 my_decimal2double(E_DEC_FATAL_ERROR, dec, &result);
3649 return result;
3650 }
3651
3652
create_1_arg(THD * thd,Item * arg1)3653 my_decimal *Item_func_udf_decimal::val_decimal(my_decimal *dec_buf)
3654 {
3655 my_decimal *res;
3656 my_bool tmp_null_value;
3657 DBUG_ASSERT(fixed == 1);
3658 DBUG_ENTER("Item_func_udf_decimal::val_decimal");
3659 DBUG_PRINT("info",("result_type: %d arg_count: %d",
3660 args[0]->result_type(), arg_count));
3661
3662 res= udf.val_decimal(&tmp_null_value, dec_buf);
3663 null_value= tmp_null_value;
3664 DBUG_RETURN(res);
3665 }
3666
3667
3668 String *Item_func_udf_decimal::val_str(String *str)
3669 {
3670 my_bool tmp_null_value;
create_2_arg(THD * thd,Item * arg1,Item * arg2)3671 my_decimal dec_buf, *dec= udf.val_decimal(&tmp_null_value, &dec_buf);
3672 null_value= tmp_null_value;
3673 if (null_value)
3674 return 0;
3675 if (str->length() < DECIMAL_MAX_STR_LENGTH)
3676 str->length(DECIMAL_MAX_STR_LENGTH);
3677 my_decimal_round(E_DEC_FATAL_ERROR, dec, decimals, FALSE, &dec_buf);
3678 my_decimal2string(E_DEC_FATAL_ERROR, &dec_buf, 0, 0, '0', str);
3679 return str;
create_2_arg(THD * thd,Item * arg1,Item * arg2)3680 }
3681
3682
3683 /* Default max_length is max argument length */
3684
3685 bool Item_func_udf_str::fix_length_and_dec()
3686 {
3687 DBUG_ENTER("Item_func_udf_str::fix_length_and_dec");
3688 max_length=0;
3689 for (uint i = 0; i < arg_count; i++)
3690 set_if_bigger(max_length,args[i]->max_length);
3691 DBUG_RETURN(FALSE);
3692 }
3693
3694 String *Item_func_udf_str::val_str(String *str)
3695 {
3696 DBUG_ASSERT(fixed == 1);
3697 String *res=udf.val_str(str,&str_value);
3698 null_value = !res;
3699 return res;
3700 }
create_1_arg(THD * thd,Item * arg1)3701
3702
3703 /**
3704 @note
3705 This has to come last in the udf_handler methods, or C for AIX
3706 version 6.0.0.0 fails to compile with debugging enabled. (Yes, really.)
3707 */
3708
3709 udf_handler::~udf_handler()
3710 {
3711 /* Everything should be properly cleaned up by this moment. */
3712 DBUG_ASSERT(not_original || !(initialized || buffers));
3713 }
3714
3715 #else
3716 bool udf_handler::get_arguments() { return 0; }
3717 #endif /* HAVE_DLOPEN */
3718
3719
3720 longlong Item_master_pos_wait::val_int()
3721 {
create_1_arg(THD * thd,Item * arg1)3722 DBUG_ASSERT(fixed == 1);
3723 THD* thd = current_thd;
3724 String *log_name = args[0]->val_str(&value);
3725 int event_count= 0;
3726
3727 null_value=0;
3728 if (thd->slave_thread || !log_name || !log_name->length())
3729 {
3730 null_value = 1;
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)3731 return 0;
3732 }
3733 #ifdef HAVE_REPLICATION
3734 longlong pos = (ulong)args[1]->val_int();
3735 longlong timeout = (arg_count>=3) ? args[2]->val_int() : 0 ;
3736 String connection_name_buff;
3737 LEX_CSTRING connection_name;
3738 Master_info *mi= NULL;
3739 if (arg_count >= 4)
3740 {
3741 String *con;
3742 if (!(con= args[3]->val_str(&connection_name_buff)))
3743 goto err;
3744
3745 connection_name.str= con->ptr();
3746 connection_name.length= con->length();
3747 if (check_master_connection_name(&connection_name))
3748 {
3749 my_error(ER_WRONG_ARGUMENTS, MYF(ME_JUST_WARNING),
3750 "MASTER_CONNECTION_NAME");
3751 goto err;
3752 }
3753 }
3754 else
3755 connection_name= thd->variables.default_master_connection;
3756
3757 if (!(mi= get_master_info(&connection_name, Sql_condition::WARN_LEVEL_WARN)))
3758 goto err;
3759
3760 if ((event_count = mi->rli.wait_for_pos(thd, log_name, pos, timeout)) == -2)
3761 {
3762 null_value = 1;
3763 event_count=0;
3764 }
3765 mi->release();
3766 #endif
3767 return event_count;
create_2_arg(THD * thd,Item * arg1,Item * arg2)3768
3769 #ifdef HAVE_REPLICATION
3770 err:
3771 {
3772 null_value = 1;
3773 return 0;
3774 }
3775 #endif
3776 }
3777
create_1_arg(THD * thd,Item * arg1)3778
3779 longlong Item_master_gtid_wait::val_int()
3780 {
3781 DBUG_ASSERT(fixed == 1);
3782 longlong result= 0;
3783 String *gtid_pos __attribute__((unused)) = args[0]->val_str(&value);
3784
3785 if (args[0]->null_value)
3786 {
3787 null_value= 1;
3788 return 0;
3789 }
3790
3791 null_value=0;
3792 #ifdef HAVE_REPLICATION
3793 THD* thd= current_thd;
3794 longlong timeout_us;
3795
3796 if (arg_count==2 && !args[1]->null_value)
3797 timeout_us= (longlong)(1e6*args[1]->val_real());
3798 else
3799 timeout_us= (longlong)-1;
3800
3801 result= rpl_global_gtid_waiting.wait_for_pos(thd, gtid_pos, timeout_us);
3802 #else
3803 null_value= 0;
3804 #endif /* REPLICATION */
3805 return result;
3806 }
3807
3808
3809 /**
3810 Enables a session to wait on a condition until a timeout or a network
3811 disconnect occurs.
3812
3813 @remark The connection is polled every m_interrupt_interval nanoseconds.
3814 */
create_1_arg(THD * thd,Item * arg1)3815
3816 class Interruptible_wait
3817 {
3818 THD *m_thd;
3819 struct timespec m_abs_timeout;
3820 static const ulonglong m_interrupt_interval;
3821
3822 public:
3823 Interruptible_wait(THD *thd)
3824 : m_thd(thd) {}
3825
3826 ~Interruptible_wait() {}
3827
3828 public:
3829 /**
3830 Set the absolute timeout.
3831
3832 @param timeout The amount of time in nanoseconds to wait
3833 */
3834 void set_timeout(ulonglong timeout)
3835 {
3836 /*
3837 Calculate the absolute system time at the start so it can
3838 be controlled in slices. It relies on the fact that once
3839 the absolute time passes, the timed wait call will fail
3840 automatically with a timeout error.
3841 */
3842 set_timespec_nsec(m_abs_timeout, timeout);
3843 }
3844
3845 /** The timed wait. */
3846 int wait(mysql_cond_t *, mysql_mutex_t *);
3847 };
3848
3849
3850 /** Time to wait before polling the connection status. */
3851 const ulonglong Interruptible_wait::m_interrupt_interval= 5 * 1000000000ULL;
3852
create_1_arg(THD * thd,Item * arg1)3853
3854 /**
3855 Wait for a given condition to be signaled.
3856
3857 @param cond The condition variable to wait on.
3858 @param mutex The associated mutex.
3859
3860 @remark The absolute timeout is preserved across calls.
3861
3862 @retval return value from mysql_cond_timedwait
3863 */
3864
3865 int Interruptible_wait::wait(mysql_cond_t *cond, mysql_mutex_t *mutex)
3866 {
3867 int error;
3868 struct timespec timeout;
3869
3870 while (1)
3871 {
3872 /* Wait for a fixed interval. */
3873 set_timespec_nsec(timeout, m_interrupt_interval);
3874
3875 /* But only if not past the absolute timeout. */
3876 if (cmp_timespec(timeout, m_abs_timeout) > 0)
3877 timeout= m_abs_timeout;
3878
3879 error= mysql_cond_timedwait(cond, mutex, &timeout);
3880 if (m_thd->check_killed())
3881 break;
3882 if (error == ETIMEDOUT || error == ETIME)
3883 {
3884 /* Return error if timed out or connection is broken. */
3885 if (!cmp_timespec(timeout, m_abs_timeout) || !m_thd->is_connected())
3886 break;
3887 }
3888 /* Otherwise, propagate status to the caller. */
3889 else
3890 break;
3891 }
3892
3893 return error;
3894 }
3895
3896
3897 /**
create_2_arg(THD * thd,Item * arg1,Item * arg2)3898 For locks with EXPLICIT duration, MDL returns a new ticket
3899 every time a lock is granted. This allows to implement recursive
3900 locks without extra allocation or additional data structures, such
3901 as below. However, if there are too many tickets in the same
3902 MDL_context, MDL_context::find_ticket() is getting too slow,
3903 since it's using a linear search.
3904 This is why a separate structure is allocated for a user
3905 level lock, and before requesting a new lock from MDL,
3906 GET_LOCK() checks thd->ull_hash if such lock is already granted,
3907 and if so, simply increments a reference counter.
3908 */
3909
3910 class User_level_lock
3911 {
3912 public:
3913 MDL_ticket *lock;
3914 int refs;
3915 };
3916
3917
3918 /** Extract a hash key from User_level_lock. */
3919
3920 uchar *ull_get_key(const uchar *ptr, size_t *length,
3921 my_bool not_used __attribute__((unused)))
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)3922 {
3923 User_level_lock *ull = (User_level_lock*) ptr;
3924 MDL_key *key = ull->lock->get_key();
3925 *length= key->length();
3926 return (uchar*) key->ptr();
3927 }
3928
3929
3930 /**
3931 Release all user level locks for this THD.
3932 */
3933
3934 void mysql_ull_cleanup(THD *thd)
3935 {
3936 User_level_lock *ull;
3937 DBUG_ENTER("mysql_ull_cleanup");
3938
3939 for (uint i= 0; i < thd->ull_hash.records; i++)
3940 {
3941 ull = (User_level_lock*) my_hash_element(&thd->ull_hash, i);
3942 thd->mdl_context.release_lock(ull->lock);
3943 my_free(ull);
3944 }
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)3945
3946 my_hash_free(&thd->ull_hash);
3947
3948 DBUG_VOID_RETURN;
3949 }
3950
3951
3952 /**
3953 Set explicit duration for metadata locks corresponding to
3954 user level locks to protect them from being released at the end
3955 of transaction.
3956 */
3957
3958 void mysql_ull_set_explicit_lock_duration(THD *thd)
3959 {
3960 User_level_lock *ull;
3961 DBUG_ENTER("mysql_ull_set_explicit_lock_duration");
3962
3963 for (uint i= 0; i < thd->ull_hash.records; i++)
3964 {
create_2_arg(THD * thd,Item * arg1,Item * arg2)3965 ull= (User_level_lock*) my_hash_element(&thd->ull_hash, i);
3966 thd->mdl_context.set_lock_duration(ull->lock, MDL_EXPLICIT);
3967 }
3968 DBUG_VOID_RETURN;
3969 }
3970
3971
3972 /**
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)3973 When MDL detects a lock wait timeout, it pushes
3974 an error into the statement diagnostics area.
3975 For GET_LOCK(), lock wait timeout is not an error,
3976 but a special return value (0).
3977 Similarly, killing get_lock wait is not an error either,
3978 but a return value NULL.
3979 Capture and suppress lock wait timeouts and kills.
3980 */
3981
3982 class Lock_wait_timeout_handler: public Internal_error_handler
3983 {
3984 public:
3985 Lock_wait_timeout_handler() :m_lock_wait_timeout(false) {}
3986
3987 bool m_lock_wait_timeout;
3988
3989 bool handle_condition(THD * /* thd */, uint sql_errno,
3990 const char * /* sqlstate */,
3991 Sql_condition::enum_warning_level* /* level */,
3992 const char *message,
3993 Sql_condition ** /* cond_hdl */);
3994 };
3995
3996 bool
3997 Lock_wait_timeout_handler::
3998 handle_condition(THD *thd, uint sql_errno,
3999 const char * /* sqlstate */,
4000 Sql_condition::enum_warning_level* /* level */,
4001 const char *message,
4002 Sql_condition ** /* cond_hdl */)
4003 {
4004 if (sql_errno == ER_LOCK_WAIT_TIMEOUT)
4005 {
4006 m_lock_wait_timeout= true;
4007 return true; /* condition handled */
4008 }
4009 if (thd->is_killed())
create_1_arg(THD * thd,Item * arg1)4010 return true;
4011
4012 return false;
4013 }
4014
4015
4016 static int ull_name_ok(String *name)
4017 {
4018 if (!name || !name->length())
create_builder(THD * thd)4019 return 0;
4020
4021 if (name->length() > NAME_LEN)
4022 {
4023 my_error(ER_TOO_LONG_IDENT, MYF(0), name->c_ptr_safe());
4024 return 0;
4025 }
4026 return 1;
4027 }
4028
4029
create_2_arg(THD * thd,Item * arg1,Item * arg2)4030 /**
4031 Get a user level lock.
4032
4033 @retval
4034 1 : Got lock
4035 @retval
4036 0 : Timeout
4037 @retval
4038 NULL : Error
4039 */
4040
4041 longlong Item_func_get_lock::val_int()
4042 {
4043 DBUG_ASSERT(fixed == 1);
4044 String *res= args[0]->val_str(&value);
4045 double timeout= args[1]->val_real();
4046 THD *thd= current_thd;
4047 User_level_lock *ull;
4048 DBUG_ENTER("Item_func_get_lock::val_int");
4049
4050 null_value= 1;
4051 /*
4052 In slave thread no need to get locks, everything is serialized. Anyway
4053 there is no way to make GET_LOCK() work on slave like it did on master
4054 (i.e. make it return exactly the same value) because we don't have the
4055 same other concurrent threads environment. No matter what we return here,
4056 it's not guaranteed to be same as on master.
4057 */
4058 if (thd->slave_thread)
4059 {
4060 null_value= 0;
4061 DBUG_RETURN(1);
4062 }
4063
4064 if (args[1]->null_value ||
4065 (!args[1]->unsigned_flag && ((longlong) timeout < 0)))
4066 {
4067 char buf[22];
4068 if (args[1]->null_value)
4069 strmov(buf, "NULL");
4070 else
4071 llstr(((longlong) timeout), buf);
4072 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
4073 ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
4074 "timeout", buf, "get_lock");
4075 null_value= 1;
4076 DBUG_RETURN(0);
4077 }
4078
4079 if (!ull_name_ok(res))
4080 DBUG_RETURN(0);
4081 DBUG_PRINT("enter", ("lock: %.*s", res->length(), res->ptr()));
4082 /* HASH entries are of type User_level_lock. */
4083 if (! my_hash_inited(&thd->ull_hash) &&
4084 my_hash_init(&thd->ull_hash, &my_charset_bin,
4085 16 /* small hash */, 0, 0, ull_get_key, NULL, 0))
4086 {
4087 DBUG_RETURN(0);
4088 }
4089
4090 MDL_request ull_request;
4091 ull_request.init(MDL_key::USER_LOCK, res->c_ptr_safe(), "",
4092 MDL_SHARED_NO_WRITE, MDL_EXPLICIT);
4093 MDL_key *ull_key = &ull_request.key;
4094
4095
4096 if ((ull= (User_level_lock*)
4097 my_hash_search(&thd->ull_hash, ull_key->ptr(), ull_key->length())))
4098 {
4099 /* Recursive lock */
4100 ull->refs++;
4101 null_value = 0;
4102 DBUG_PRINT("info", ("recursive lock, ref-count: %d", (int) ull->refs));
4103 DBUG_RETURN(1);
4104 }
4105
4106 Lock_wait_timeout_handler lock_wait_timeout_handler;
4107 thd->push_internal_handler(&lock_wait_timeout_handler);
4108 bool error= thd->mdl_context.acquire_lock(&ull_request, timeout);
4109 (void) thd->pop_internal_handler();
4110 if (unlikely(error))
4111 {
4112 if (lock_wait_timeout_handler.m_lock_wait_timeout)
4113 null_value= 0;
4114 DBUG_RETURN(0);
4115 }
4116
4117 ull= (User_level_lock*) my_malloc(sizeof(User_level_lock),
4118 MYF(MY_WME|MY_THREAD_SPECIFIC));
4119 if (ull == NULL)
4120 {
4121 thd->mdl_context.release_lock(ull_request.ticket);
4122 DBUG_RETURN(0);
4123 }
4124
4125 ull->lock= ull_request.ticket;
4126 ull->refs= 1;
4127
4128 if (my_hash_insert(&thd->ull_hash, (uchar*) ull))
4129 {
4130 thd->mdl_context.release_lock(ull->lock);
4131 my_free(ull);
4132 DBUG_RETURN(0);
4133 }
4134 null_value= 0;
4135
4136 DBUG_RETURN(1);
4137 }
create_1_arg(THD * thd,Item * arg1)4138
4139
4140 /**
4141 Release a user level lock.
4142 @return
4143 - 1 if lock released
4144 - 0 if lock wasn't held
4145 - (SQL) NULL if no such lock
4146 */
4147
4148 longlong Item_func_release_lock::val_int()
4149 {
4150 DBUG_ASSERT(fixed == 1);
4151 String *res= args[0]->val_str(&value);
4152 THD *thd= current_thd;
4153 DBUG_ENTER("Item_func_release_lock::val_int");
4154 null_value= 1;
4155
4156 if (!ull_name_ok(res))
4157 DBUG_RETURN(0);
4158
4159 DBUG_PRINT("enter", ("lock: %.*s", res->length(), res->ptr()));
4160
4161 MDL_key ull_key;
4162 ull_key.mdl_key_init(MDL_key::USER_LOCK, res->c_ptr_safe(), "");
4163
4164 User_level_lock *ull;
4165
4166 if (!my_hash_inited(&thd->ull_hash) ||
4167 !(ull=
4168 (User_level_lock*) my_hash_search(&thd->ull_hash,
4169 ull_key.ptr(), ull_key.length())))
4170 {
4171 null_value= thd->mdl_context.get_lock_owner(&ull_key) == 0;
4172 DBUG_RETURN(0);
4173 }
4174 DBUG_PRINT("info", ("ref count: %d", (int) ull->refs));
4175 null_value= 0;
4176 if (--ull->refs == 0)
4177 {
4178 my_hash_delete(&thd->ull_hash, (uchar*) ull);
4179 thd->mdl_context.release_lock(ull->lock);
4180 my_free(ull);
4181 }
4182 DBUG_RETURN(1);
4183 }
4184
4185
4186 /**
4187 Check a user level lock.
4188
4189 Sets null_value=TRUE on error.
4190
4191 @retval
4192 1 Available
4193 @retval
4194 0 Already taken, or error
4195 */
4196
4197 longlong Item_func_is_free_lock::val_int()
4198 {
4199 DBUG_ASSERT(fixed == 1);
4200 String *res= args[0]->val_str(&value);
4201 THD *thd= current_thd;
4202 null_value= 1;
4203
4204 if (!ull_name_ok(res))
4205 return 0;
4206
4207 MDL_key ull_key;
4208 ull_key.mdl_key_init(MDL_key::USER_LOCK, res->c_ptr_safe(), "");
4209
4210 null_value= 0;
4211 return thd->mdl_context.get_lock_owner(&ull_key) == 0;
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)4212 }
4213
4214
4215 longlong Item_func_is_used_lock::val_int()
4216 {
4217 DBUG_ASSERT(fixed == 1);
4218 String *res= args[0]->val_str(&value);
4219 THD *thd= current_thd;
4220 null_value= 1;
4221
4222 if (!ull_name_ok(res))
4223 return 0;
4224
4225 MDL_key ull_key;
4226 ull_key.mdl_key_init(MDL_key::USER_LOCK, res->c_ptr_safe(), "");
4227 ulong thread_id = thd->mdl_context.get_lock_owner(&ull_key);
4228 if (thread_id == 0)
4229 return 0;
4230
4231 null_value= 0;
4232 return thread_id;
4233 }
4234
4235
4236 longlong Item_func_last_insert_id::val_int()
4237 {
4238 THD *thd= current_thd;
4239 DBUG_ASSERT(fixed == 1);
4240 if (arg_count)
4241 {
4242 longlong value= args[0]->val_int();
4243 null_value= args[0]->null_value;
4244 /*
4245 LAST_INSERT_ID(X) must affect the client's mysql_insert_id() as
4246 documented in the manual. We don't want to touch
4247 first_successful_insert_id_in_cur_stmt because it would make
4248 LAST_INSERT_ID(X) take precedence over an generated auto_increment
4249 value for this row.
create_1_arg(THD * thd,Item * arg1)4250 */
4251 thd->arg_of_last_insert_id_function= TRUE;
4252 thd->first_successful_insert_id_in_prev_stmt= value;
4253 return value;
4254 }
4255 return
4256 static_cast<longlong>(thd->read_first_successful_insert_id_in_prev_stmt());
4257 }
4258
4259
4260 bool Item_func_last_insert_id::fix_fields(THD *thd, Item **ref)
create_2_arg(THD * thd,Item * arg1,Item * arg2)4261 {
4262 thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
4263 return Item_int_func::fix_fields(thd, ref);
4264 }
4265
4266
4267 /* This function is just used to test speed of different functions */
4268
4269 longlong Item_func_benchmark::val_int()
4270 {
create_2_arg(THD * thd,Item * arg1,Item * arg2)4271 DBUG_ASSERT(fixed == 1);
4272 char buff[MAX_FIELD_WIDTH];
4273 String tmp(buff,sizeof(buff), &my_charset_bin);
4274 my_decimal tmp_decimal;
4275 THD *thd= current_thd;
4276 ulonglong loop_count;
4277
4278 loop_count= (ulonglong) args[0]->val_int();
4279
4280 if (args[0]->null_value ||
create_2_arg(THD * thd,Item * arg1,Item * arg2)4281 (!args[0]->unsigned_flag && (((longlong) loop_count) < 0)))
4282 {
4283 if (!args[0]->null_value)
4284 {
4285 char buff[22];
4286 llstr(((longlong) loop_count), buff);
4287 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
4288 ER_WRONG_VALUE_FOR_TYPE,
4289 ER_THD(thd, ER_WRONG_VALUE_FOR_TYPE),
4290 "count", buff, "benchmark");
4291 }
4292
4293 null_value= 1;
4294 return 0;
4295 }
4296
4297 null_value=0;
4298 for (ulonglong loop=0 ; loop < loop_count && !thd->killed; loop++)
4299 {
4300 switch (args[1]->result_type()) {
4301 case REAL_RESULT:
4302 (void) args[1]->val_real();
4303 break;
4304 case INT_RESULT:
4305 (void) args[1]->val_int();
4306 break;
4307 case STRING_RESULT:
4308 (void) args[1]->val_str(&tmp);
4309 break;
4310 case DECIMAL_RESULT:
4311 (void) args[1]->val_decimal(&tmp_decimal);
create_2_arg(THD * thd,Item * arg1,Item * arg2)4312 break;
4313 case ROW_RESULT:
4314 case TIME_RESULT:
4315 DBUG_ASSERT(0); // This case should never be chosen
4316 return 0;
4317 }
4318 }
4319 return 0;
4320 }
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)4321
4322
4323 void Item_func_benchmark::print(String *str, enum_query_type query_type)
4324 {
4325 str->append(STRING_WITH_LEN("benchmark("));
4326 args[0]->print(str, query_type);
4327 str->append(',');
4328 args[1]->print(str, query_type);
4329 str->append(')');
4330 }
4331
4332
4333 mysql_mutex_t LOCK_item_func_sleep;
4334
4335 #ifdef HAVE_PSI_INTERFACE
4336 static PSI_mutex_key key_LOCK_item_func_sleep;
4337
4338 static PSI_mutex_info item_func_sleep_mutexes[]=
4339 {
4340 { &key_LOCK_item_func_sleep, "LOCK_user_locks", PSI_FLAG_GLOBAL}
4341 };
4342
4343
4344 static void init_item_func_sleep_psi_keys(void)
4345 {
4346 const char* category= "sql";
4347 int count;
4348
4349 if (PSI_server == NULL)
4350 return;
4351
4352 count= array_elements(item_func_sleep_mutexes);
4353 PSI_server->register_mutex(category, item_func_sleep_mutexes, count);
4354 }
4355 #endif
4356
4357 static bool item_func_sleep_inited= 0;
4358
4359
create_1_arg(THD * thd,Item * arg1)4360 void item_func_sleep_init(void)
4361 {
4362 #ifdef HAVE_PSI_INTERFACE
4363 init_item_func_sleep_psi_keys();
4364 #endif
4365
4366 mysql_mutex_init(key_LOCK_item_func_sleep, &LOCK_item_func_sleep, MY_MUTEX_INIT_SLOW);
4367 item_func_sleep_inited= 1;
4368 }
4369
4370
4371 void item_func_sleep_free(void)
create_1_arg(THD * thd,Item * arg1)4372 {
4373 if (item_func_sleep_inited)
4374 {
4375 item_func_sleep_inited= 0;
4376 mysql_mutex_destroy(&LOCK_item_func_sleep);
4377 }
4378 }
4379
4380
create_1_arg(THD * thd,Item * arg1)4381 /** This function is just used to create tests with time gaps. */
4382
4383 longlong Item_func_sleep::val_int()
4384 {
4385 THD *thd= current_thd;
4386 Interruptible_wait timed_cond(thd);
4387 mysql_cond_t cond;
4388 double timeout;
4389 int error;
4390
4391 DBUG_ASSERT(fixed == 1);
4392
4393 timeout= args[0]->val_real();
4394 /*
4395 On 64-bit OSX mysql_cond_timedwait() waits forever
4396 if passed abstime time has already been exceeded by
4397 the system time.
4398 When given a very short timeout (< 10 mcs) just return
4399 immediately.
4400 We assume that the lines between this test and the call
4401 to mysql_cond_timedwait() will be executed in less than 0.00001 sec.
4402 */
4403 if (timeout < 0.00001)
4404 return 0;
4405
4406 timed_cond.set_timeout((ulonglong) (timeout * 1000000000.0));
4407
4408 mysql_cond_init(key_item_func_sleep_cond, &cond, NULL);
4409 mysql_mutex_lock(&LOCK_item_func_sleep);
4410
4411 THD_STAGE_INFO(thd, stage_user_sleep);
4412 thd->mysys_var->current_mutex= &LOCK_item_func_sleep;
4413 thd->mysys_var->current_cond= &cond;
4414
4415 error= 0;
4416 thd_wait_begin(thd, THD_WAIT_SLEEP);
4417 while (!thd->killed)
4418 {
4419 error= timed_cond.wait(&cond, &LOCK_item_func_sleep);
4420 if (error == ETIMEDOUT || error == ETIME)
4421 break;
4422 error= 0;
4423 }
4424 thd_wait_end(thd);
4425 mysql_mutex_unlock(&LOCK_item_func_sleep);
4426 mysql_mutex_lock(&thd->mysys_var->mutex);
4427 thd->mysys_var->current_mutex= 0;
4428 thd->mysys_var->current_cond= 0;
4429 mysql_mutex_unlock(&thd->mysys_var->mutex);
4430
4431 mysql_cond_destroy(&cond);
4432
4433 DBUG_EXECUTE_IF("sleep_inject_query_done_debug_sync", {
4434 debug_sync_set_action
4435 (thd, STRING_WITH_LEN("dispatch_command_end SIGNAL query_done"));
4436 };);
4437
4438 return MY_TEST(!error); // Return 1 killed
4439 }
4440
4441
4442 bool Item_func_user_var::check_vcol_func_processor(void *arg)
4443 {
4444 return mark_unsupported_function("@", name.str, arg, VCOL_NON_DETERMINISTIC);
4445 }
4446
4447 #define extra_size sizeof(double)
4448
4449 user_var_entry *get_variable(HASH *hash, LEX_CSTRING *name,
4450 bool create_if_not_exists)
4451 {
4452 user_var_entry *entry;
4453
4454 if (!(entry = (user_var_entry*) my_hash_search(hash, (uchar*) name->str,
4455 name->length)) &&
4456 create_if_not_exists)
4457 {
4458 size_t size=ALIGN_SIZE(sizeof(user_var_entry))+name->length+1+extra_size;
4459 if (!my_hash_inited(hash))
4460 return 0;
4461 if (!(entry = (user_var_entry*) my_malloc(size,
4462 MYF(MY_WME | ME_FATALERROR |
4463 MY_THREAD_SPECIFIC))))
4464 return 0;
4465 entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+
4466 extra_size;
4467 entry->name.length=name->length;
4468 entry->value=0;
4469 entry->length=0;
4470 entry->update_query_id=0;
4471 entry->set_charset(NULL);
4472 entry->unsigned_flag= 0;
4473 /*
4474 If we are here, we were called from a SET or a query which sets a
4475 variable. Imagine it is this:
create_1_arg(THD * thd,Item * arg1)4476 INSERT INTO t SELECT @a:=10, @a:=@a+1.
4477 Then when we have a Item_func_get_user_var (because of the @a+1) so we
4478 think we have to write the value of @a to the binlog. But before that,
4479 we have a Item_func_set_user_var to create @a (@a:=10), in this we mark
4480 the variable as "already logged" (line below) so that it won't be logged
4481 by Item_func_get_user_var (because that's not necessary).
4482 */
4483 entry->used_query_id=current_thd->query_id;
4484 entry->type=STRING_RESULT;
4485 memcpy((char*) entry->name.str, name->str, name->length+1);
4486 if (my_hash_insert(hash,(uchar*) entry))
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)4487 {
4488 my_free(entry);
4489 return 0;
4490 }
4491 }
4492 return entry;
4493 }
4494
4495
4496 void Item_func_set_user_var::cleanup()
4497 {
4498 Item_func::cleanup();
4499 m_var_entry= NULL;
4500 }
4501
4502
4503 bool Item_func_set_user_var::set_entry(THD *thd, bool create_if_not_exists)
4504 {
4505 if (m_var_entry && thd->thread_id == entry_thread_id)
4506 goto end; // update entry->update_query_id for PS
4507 if (!(m_var_entry= get_variable(&thd->user_vars, &name, create_if_not_exists)))
create_2_arg(THD * thd,Item * arg1,Item * arg2)4508 {
4509 entry_thread_id= 0;
4510 return TRUE;
4511 }
4512 entry_thread_id= thd->thread_id;
4513 /*
4514 Remember the last query which updated it, this way a query can later know
4515 if this variable is a constant item in the query (it is if update_query_id
4516 is different from query_id).
create_1_arg(THD * thd,Item * arg1)4517 */
4518 end:
4519 m_var_entry->update_query_id= thd->query_id;
4520 return FALSE;
4521 }
4522
4523
4524 /*
4525 When a user variable is updated (in a SET command or a query like
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)4526 SELECT @a:= ).
4527 */
4528
4529 bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref)
4530 {
4531 DBUG_ASSERT(fixed == 0);
4532 /* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
4533 if (Item_func::fix_fields(thd, ref) || set_entry(thd, TRUE))
4534 return TRUE;
4535 /*
4536 As it is wrong and confusing to associate any
4537 character set with NULL, @a should be latin2
4538 after this query sequence:
4539
4540 SET @a=_latin2'string';
4541 SET @a=NULL;
4542
4543 I.e. the second query should not change the charset
4544 to the current default value, but should keep the
4545 original value assigned during the first query.
4546 In order to do it, we don't copy charset
4547 from the argument if the argument is NULL
4548 and the variable has previously been initialized.
4549 */
4550 null_item= (args[0]->type() == NULL_ITEM);
4551 if (!m_var_entry->charset() || !null_item)
4552 m_var_entry->set_charset(args[0]->collation.derivation == DERIVATION_NUMERIC ?
4553 default_charset() : args[0]->collation.collation);
4554 collation.set(m_var_entry->charset(), DERIVATION_IMPLICIT);
4555 switch (args[0]->result_type()) {
4556 case STRING_RESULT:
4557 case TIME_RESULT:
4558 set_handler(type_handler_long_blob.
4559 type_handler_adjusted_to_max_octet_length(max_length,
4560 collation.collation));
4561 break;
4562 case REAL_RESULT:
4563 set_handler(&type_handler_double);
4564 break;
4565 case INT_RESULT:
4566 set_handler(Type_handler::type_handler_long_or_longlong(max_char_length()));
4567 break;
4568 case DECIMAL_RESULT:
4569 set_handler(&type_handler_newdecimal);
4570 break;
4571 case ROW_RESULT:
4572 DBUG_ASSERT(0);
4573 set_handler(&type_handler_row);
4574 break;
4575 }
4576 if (thd->lex->current_select)
4577 {
4578 /*
4579 When this function is used in a derived table/view force the derived
4580 table to be materialized to preserve possible side-effect of setting a
4581 user variable.
4582 */
4583 SELECT_LEX_UNIT *unit= thd->lex->current_select->master_unit();
4584 TABLE_LIST *derived;
4585 for (derived= unit->derived;
4586 derived;
4587 derived= unit->derived)
4588 {
4589 derived->set_materialized_derived();
4590 derived->prohibit_cond_pushdown= true;
4591 if (unit->with_element && unit->with_element->is_recursive)
4592 break;
4593 unit= derived->select_lex->master_unit();
4594 }
4595 }
4596
4597 return FALSE;
4598 }
4599
4600
4601 bool
4602 Item_func_set_user_var::fix_length_and_dec()
4603 {
4604 maybe_null=args[0]->maybe_null;
4605 decimals=args[0]->decimals;
4606 collation.set(DERIVATION_IMPLICIT);
4607 if (args[0]->collation.derivation == DERIVATION_NUMERIC)
4608 fix_length_and_charset(args[0]->max_char_length(), default_charset());
4609 else
4610 {
4611 fix_length_and_charset(args[0]->max_char_length(),
4612 args[0]->collation.collation);
4613 }
4614 unsigned_flag= args[0]->unsigned_flag;
4615 return FALSE;
4616 }
4617
4618
4619 /*
4620 Mark field in read_map
4621
4622 NOTES
4623 This is used by filesort to register used fields in a a temporary
4624 column read set or to register used fields in a view
4625 */
4626
4627 bool Item_func_set_user_var::register_field_in_read_map(void *arg)
4628 {
4629 if (result_field)
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)4630 {
4631 TABLE *table= (TABLE *) arg;
4632 if (result_field->table == table || !table)
4633 bitmap_set_bit(result_field->table->read_set, result_field->field_index);
4634 if (result_field->vcol_info)
4635 return result_field->vcol_info->
4636 expr->walk(&Item::register_field_in_read_map, 1, arg);
4637 }
4638 return 0;
4639 }
4640
4641 /*
4642 Mark field in bitmap supplied as *arg
4643
4644 */
4645
4646 bool Item_func_set_user_var::register_field_in_bitmap(void *arg)
4647 {
4648 MY_BITMAP *bitmap = (MY_BITMAP *) arg;
4649 DBUG_ASSERT(bitmap);
4650 if (result_field)
4651 {
4652 if (!bitmap)
4653 return 1;
4654 bitmap_set_bit(bitmap, result_field->field_index);
4655 }
4656 return 0;
4657 }
4658
4659 /**
4660 Set value to user variable.
4661
4662 @param entry pointer to structure representing variable
4663 @param set_null should we set NULL value ?
4664 @param ptr pointer to buffer with new value
4665 @param length length of new value
4666 @param type type of new value
4667 @param cs charset info for new value
4668 @param dv derivation for new value
4669 @param unsigned_arg indicates if a value of type INT_RESULT is unsigned
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)4670
4671 @note Sets error and fatal error if allocation fails.
4672
4673 @retval
4674 false success
4675 @retval
4676 true failure
4677 */
4678
4679 bool
4680 update_hash(user_var_entry *entry, bool set_null, void *ptr, size_t length,
4681 Item_result type, CHARSET_INFO *cs,
4682 bool unsigned_arg)
4683 {
4684 if (set_null)
4685 {
4686 char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
4687 if (entry->value && entry->value != pos)
4688 my_free(entry->value);
4689 entry->value= 0;
4690 entry->length= 0;
4691 }
4692 else
4693 {
4694 if (type == STRING_RESULT)
4695 length++; // Store strings with end \0
4696 if (length <= extra_size)
4697 {
4698 /* Save value in value struct */
4699 char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
4700 if (entry->value != pos)
4701 {
4702 if (entry->value)
4703 my_free(entry->value);
4704 entry->value=pos;
4705 }
4706 }
4707 else
4708 {
4709 /* Allocate variable */
4710 if (entry->length != length)
4711 {
4712 char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
4713 if (entry->value == pos)
4714 entry->value=0;
4715 entry->value= (char*) my_realloc(entry->value, length,
4716 MYF(MY_ALLOW_ZERO_PTR | MY_WME |
4717 ME_FATALERROR |
4718 MY_THREAD_SPECIFIC));
4719 if (!entry->value)
4720 return 1;
4721 }
4722 }
4723 if (type == STRING_RESULT)
4724 {
4725 length--; // Fix length change above
4726 entry->value[length]= 0; // Store end \0
4727 }
4728 if (length)
4729 memmove(entry->value, ptr, length);
4730 if (type == DECIMAL_RESULT)
4731 ((my_decimal*)entry->value)->fix_buffer_pointer();
4732 entry->length= length;
4733 entry->set_charset(cs);
4734 entry->unsigned_flag= unsigned_arg;
4735 }
4736 entry->type=type;
4737 return 0;
4738 }
4739
4740
4741 bool
4742 Item_func_set_user_var::update_hash(void *ptr, size_t length,
4743 Item_result res_type,
4744 CHARSET_INFO *cs,
4745 bool unsigned_arg)
4746 {
4747 /*
4748 If we set a variable explicitly to NULL then keep the old
4749 result type of the variable
4750 */
4751 if (args[0]->type() == Item::FIELD_ITEM)
4752 {
4753 /* args[0]->null_value may be outdated */
4754 null_value= ((Item_field*)args[0])->field->is_null();
4755 }
4756 else
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)4757 null_value= args[0]->null_value;
4758 if (null_value && null_item)
4759 res_type= m_var_entry->type; // Don't change type of item
4760 if (::update_hash(m_var_entry, null_value,
4761 ptr, length, res_type, cs, unsigned_arg))
4762 {
4763 null_value= 1;
4764 return 1;
4765 }
4766 return 0;
4767 }
4768
4769
4770 /** Get the value of a variable as a double. */
4771
4772 double user_var_entry::val_real(bool *null_value)
4773 {
4774 if ((*null_value= (value == 0)))
4775 return 0.0;
4776
4777 switch (type) {
4778 case REAL_RESULT:
4779 return *(double*) value;
4780 case INT_RESULT:
4781 return (double) *(longlong*) value;
4782 case DECIMAL_RESULT:
4783 {
4784 double result;
4785 my_decimal2double(E_DEC_FATAL_ERROR, (my_decimal *)value, &result);
4786 return result;
4787 }
4788 case STRING_RESULT:
4789 return my_atof(value); // This is null terminated
4790 case ROW_RESULT:
4791 case TIME_RESULT:
4792 DBUG_ASSERT(0); // Impossible
4793 break;
4794 }
4795 return 0.0; // Impossible
4796 }
4797
4798
4799 /** Get the value of a variable as an integer. */
4800
4801 longlong user_var_entry::val_int(bool *null_value) const
4802 {
4803 if ((*null_value= (value == 0)))
4804 return 0;
create_1_arg(THD * thd,Item * arg1)4805
4806 switch (type) {
4807 case REAL_RESULT:
4808 return (longlong) *(double*) value;
4809 case INT_RESULT:
4810 return *(longlong*) value;
4811 case DECIMAL_RESULT:
4812 {
4813 longlong result;
4814 my_decimal2int(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, &result);
4815 return result;
4816 }
4817 case STRING_RESULT:
4818 {
4819 int error;
4820 return my_strtoll10(value, (char**) 0, &error);// String is null terminated
4821 }
4822 case ROW_RESULT:
4823 case TIME_RESULT:
4824 DBUG_ASSERT(0); // Impossible
4825 break;
4826 }
create_2_arg(THD * thd,Item * arg1,Item * arg2)4827 return 0; // Impossible
4828 }
4829
4830
4831 /** Get the value of a variable as a string. */
4832
4833 String *user_var_entry::val_str(bool *null_value, String *str,
4834 uint decimals)
4835 {
4836 if ((*null_value= (value == 0)))
4837 return (String*) 0;
4838
create_1_arg(THD * thd,Item * arg1)4839 switch (type) {
4840 case REAL_RESULT:
4841 str->set_real(*(double*) value, decimals, charset());
4842 break;
4843 case INT_RESULT:
4844 if (!unsigned_flag)
4845 str->set(*(longlong*) value, charset());
4846 else
4847 str->set(*(ulonglong*) value, charset());
4848 break;
4849 case DECIMAL_RESULT:
4850 str_set_decimal((my_decimal *) value, str, charset());
4851 break;
4852 case STRING_RESULT:
4853 if (str->copy(value, length, charset()))
4854 str= 0; // EOM error
4855 break;
4856 case ROW_RESULT:
4857 case TIME_RESULT:
4858 DBUG_ASSERT(0); // Impossible
4859 break;
4860 }
4861 return(str);
4862 }
4863
4864 /** Get the value of a variable as a decimal. */
4865
4866 my_decimal *user_var_entry::val_decimal(bool *null_value, my_decimal *val)
4867 {
4868 if ((*null_value= (value == 0)))
4869 return 0;
4870
4871 switch (type) {
4872 case REAL_RESULT:
4873 double2my_decimal(E_DEC_FATAL_ERROR, *(double*) value, val);
4874 break;
4875 case INT_RESULT:
4876 int2my_decimal(E_DEC_FATAL_ERROR, *(longlong*) value, 0, val);
4877 break;
4878 case DECIMAL_RESULT:
4879 my_decimal2decimal((my_decimal *) value, val);
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)4880 break;
4881 case STRING_RESULT:
4882 str2my_decimal(E_DEC_FATAL_ERROR, value, length, charset(), val);
4883 break;
4884 case ROW_RESULT:
4885 case TIME_RESULT:
4886 DBUG_ASSERT(0); // Impossible
4887 break;
4888 }
4889 return(val);
4890 }
4891
4892 /**
4893 This functions is invoked on SET \@variable or
4894 \@variable:= expression.
4895
4896 Evaluate (and check expression), store results.
4897
4898 @note
4899 For now it always return OK. All problem with value evaluating
4900 will be caught by thd->is_error() check in sql_set_variables().
create_1_arg(THD * thd,Item * arg1)4901
4902 @retval
4903 FALSE OK.
4904 */
4905
4906 bool
4907 Item_func_set_user_var::check(bool use_result_field)
4908 {
4909 DBUG_ENTER("Item_func_set_user_var::check");
4910 if (use_result_field && !result_field)
4911 use_result_field= FALSE;
4912
4913 switch (result_type()) {
4914 case REAL_RESULT:
4915 {
4916 save_result.vreal= use_result_field ? result_field->val_real() :
4917 args[0]->val_real();
4918 break;
4919 }
4920 case INT_RESULT:
4921 {
4922 save_result.vint= use_result_field ? result_field->val_int() :
4923 args[0]->val_int();
4924 unsigned_flag= (use_result_field ?
4925 ((Field_num*)result_field)->unsigned_flag:
4926 args[0]->unsigned_flag);
4927 break;
4928 }
4929 case STRING_RESULT:
4930 {
4931 save_result.vstr= use_result_field ? result_field->val_str(&value) :
4932 args[0]->val_str(&value);
4933 break;
4934 }
4935 case DECIMAL_RESULT:
4936 {
4937 save_result.vdec= use_result_field ?
4938 result_field->val_decimal(&decimal_buff) :
4939 args[0]->val_decimal(&decimal_buff);
4940 break;
4941 }
4942 case ROW_RESULT:
4943 case TIME_RESULT:
4944 DBUG_ASSERT(0); // This case should never be chosen
4945 break;
4946 }
4947 DBUG_RETURN(FALSE);
4948 }
4949
4950
4951 /**
4952 @brief Evaluate and store item's result.
4953 This function is invoked on "SELECT ... INTO @var ...".
4954
create_1_arg(THD * thd,Item * arg1)4955 @param item An item to get value from.
4956 */
4957
4958 void Item_func_set_user_var::save_item_result(Item *item)
4959 {
4960 DBUG_ENTER("Item_func_set_user_var::save_item_result");
4961
4962 switch (args[0]->result_type()) {
4963 case REAL_RESULT:
4964 save_result.vreal= item->val_result();
4965 break;
4966 case INT_RESULT:
4967 save_result.vint= item->val_int_result();
4968 unsigned_flag= item->unsigned_flag;
4969 break;
4970 case STRING_RESULT:
4971 save_result.vstr= item->str_result(&value);
4972 break;
4973 case DECIMAL_RESULT:
4974 save_result.vdec= item->val_decimal_result(&decimal_buff);
4975 break;
4976 case ROW_RESULT:
4977 case TIME_RESULT:
4978 DBUG_ASSERT(0); // This case should never be chosen
4979 break;
4980 }
4981 DBUG_VOID_RETURN;
4982 }
4983
4984
4985 /**
4986 This functions is invoked on
4987 SET \@variable or \@variable:= expression.
4988
4989 @note
4990 We have to store the expression as such in the variable, independent of
create_2_arg(THD * thd,Item * arg1,Item * arg2)4991 the value method used by the user
4992
4993 @retval
4994 0 OK
4995 @retval
4996 1 EOM Error
4997
4998 */
4999
5000 bool
5001 Item_func_set_user_var::update()
5002 {
5003 bool res= 0;
5004 DBUG_ENTER("Item_func_set_user_var::update");
5005
5006 switch (result_type()) {
5007 case REAL_RESULT:
5008 {
5009 res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
5010 REAL_RESULT, default_charset(), 0);
5011 break;
5012 }
5013 case INT_RESULT:
5014 {
5015 res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
5016 INT_RESULT, default_charset(), unsigned_flag);
5017 break;
5018 }
5019 case STRING_RESULT:
5020 {
5021 if (!save_result.vstr) // Null value
5022 res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin, 0);
5023 else
5024 res= update_hash((void*) save_result.vstr->ptr(),
5025 save_result.vstr->length(), STRING_RESULT,
5026 save_result.vstr->charset(), 0);
5027 break;
5028 }
5029 case DECIMAL_RESULT:
5030 {
5031 if (!save_result.vdec) // Null value
5032 res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin, 0);
5033 else
5034 res= update_hash((void*) save_result.vdec,
5035 sizeof(my_decimal), DECIMAL_RESULT,
5036 default_charset(), 0);
5037 break;
5038 }
5039 case ROW_RESULT:
5040 case TIME_RESULT:
5041 DBUG_ASSERT(0); // This case should never be chosen
5042 break;
5043 }
5044 DBUG_RETURN(res);
5045 }
5046
5047
5048 double Item_func_set_user_var::val_real()
5049 {
5050 DBUG_ASSERT(fixed == 1);
5051 check(0);
create_2_arg(THD * thd,Item * arg1,Item * arg2)5052 update(); // Store expression
5053 return m_var_entry->val_real(&null_value);
5054 }
5055
5056 longlong Item_func_set_user_var::val_int()
5057 {
5058 DBUG_ASSERT(fixed == 1);
5059 check(0);
5060 update(); // Store expression
5061 return m_var_entry->val_int(&null_value);
create_2_arg(THD * thd,Item * arg1,Item * arg2)5062 }
5063
5064 String *Item_func_set_user_var::val_str(String *str)
5065 {
5066 DBUG_ASSERT(fixed == 1);
5067 check(0);
5068 update(); // Store expression
5069 return m_var_entry->val_str(&null_value, str, decimals);
5070 }
5071
create_2_arg(THD * thd,Item * arg1,Item * arg2)5072
5073 my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val)
5074 {
5075 DBUG_ASSERT(fixed == 1);
5076 check(0);
5077 update(); // Store expression
5078 return m_var_entry->val_decimal(&null_value, val);
5079 }
5080
5081
create_2_arg(THD * thd,Item * arg1,Item * arg2)5082 double Item_func_set_user_var::val_result()
5083 {
5084 DBUG_ASSERT(fixed == 1);
5085 check(TRUE);
5086 update(); // Store expression
5087 return m_var_entry->val_real(&null_value);
5088 }
5089
5090 longlong Item_func_set_user_var::val_int_result()
5091 {
create_1_arg(THD * thd,Item * arg1)5092 DBUG_ASSERT(fixed == 1);
5093 check(TRUE);
5094 update(); // Store expression
5095 return m_var_entry->val_int(&null_value);
5096 }
5097
5098 bool Item_func_set_user_var::val_bool_result()
5099 {
5100 DBUG_ASSERT(fixed == 1);
5101 check(TRUE);
5102 update(); // Store expression
create_1_arg(THD * thd,Item * arg1)5103 return m_var_entry->val_int(&null_value) != 0;
5104 }
5105
5106 String *Item_func_set_user_var::str_result(String *str)
5107 {
5108 DBUG_ASSERT(fixed == 1);
5109 check(TRUE);
5110 update(); // Store expression
5111 return m_var_entry->val_str(&null_value, str, decimals);
5112 }
5113
5114
create_1_arg(THD * thd,Item * arg1)5115 my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val)
5116 {
5117 DBUG_ASSERT(fixed == 1);
5118 check(TRUE);
5119 update(); // Store expression
5120 return m_var_entry->val_decimal(&null_value, val);
5121 }
5122
5123
create_1_arg(THD * thd,Item * arg1)5124 bool Item_func_set_user_var::is_null_result()
5125 {
5126 DBUG_ASSERT(fixed == 1);
5127 check(TRUE);
5128 update(); // Store expression
5129 return is_null();
5130 }
5131
5132
create_1_arg(THD * thd,Item * arg1)5133 void Item_func_set_user_var::print(String *str, enum_query_type query_type)
5134 {
5135 str->append(STRING_WITH_LEN("@"));
5136 str->append(&name);
5137 str->append(STRING_WITH_LEN(":="));
5138 args[0]->print_parenthesised(str, query_type, precedence());
5139 }
5140
5141
5142 void Item_func_set_user_var::print_as_stmt(String *str,
create_1_arg(THD * thd,Item * arg1)5143 enum_query_type query_type)
5144 {
5145 str->append(STRING_WITH_LEN("set @"));
5146 str->append(&name);
5147 str->append(STRING_WITH_LEN(":="));
5148 args[0]->print_parenthesised(str, query_type, precedence());
5149 }
5150
5151 bool Item_func_set_user_var::send(Protocol *protocol, st_value *buffer)
5152 {
create_1_arg(THD * thd,Item * arg1)5153 if (result_field)
5154 {
5155 check(1);
5156 update();
5157 return protocol->store(result_field);
5158 }
5159 return Item::send(protocol, buffer);
5160 }
5161
5162 void Item_func_set_user_var::make_send_field(THD *thd, Send_field *tmp_field)
create_2_arg(THD * thd,Item * arg1,Item * arg2)5163 {
5164 if (result_field)
5165 {
5166 result_field->make_send_field(tmp_field);
5167 DBUG_ASSERT(tmp_field->table_name != 0);
5168 if (Item::name.str)
5169 tmp_field->col_name= Item::name; // Use user supplied name
5170 }
5171 else
5172 Item::make_send_field(thd, tmp_field);
5173 }
5174
5175
5176 /*
5177 Save the value of a user variable into a field
5178
5179 SYNOPSIS
5180 save_in_field()
5181 field target field to save the value to
5182 no_conversion flag indicating whether conversions are allowed
5183
5184 DESCRIPTION
5185 Save the function value into a field and update the user variable
5186 accordingly. If a result field is defined and the target field doesn't
5187 coincide with it then the value from the result field will be used as
5188 the new value of the user variable.
5189
5190 The reason to have this method rather than simply using the result
5191 field in the val_xxx() methods is that the value from the result field
5192 not always can be used when the result field is defined.
5193 Let's consider the following cases:
5194 1) when filling a tmp table the result field is defined but the value of it
5195 is undefined because it has to be produced yet. Thus we can't use it.
5196 2) on execution of an INSERT ... SELECT statement the save_in_field()
5197 function will be called to fill the data in the new record. If the SELECT
5198 part uses a tmp table then the result field is defined and should be
create_1_arg(THD * thd,Item * arg1)5199 used in order to get the correct result.
5200
5201 The difference between the SET_USER_VAR function and regular functions
5202 like CONCAT is that the Item_func objects for the regular functions are
5203 replaced by Item_field objects after the values of these functions have
5204 been stored in a tmp table. Yet an object of the Item_field class cannot
5205 be used to update a user variable.
5206 Due to this we have to handle the result field in a special way here and
5207 in the Item_func_set_user_var::send() function.
5208
5209 RETURN VALUES
5210 FALSE Ok
5211 TRUE Error
5212 */
5213
5214 int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
5215 bool can_use_result_field)
5216 {
5217 bool use_result_field= (!can_use_result_field ? 0 :
5218 (result_field && result_field != field));
5219 int error;
5220
5221 /* Update the value of the user variable */
5222 check(use_result_field);
5223 update();
5224
5225 if (result_type() == STRING_RESULT ||
5226 (result_type() == REAL_RESULT &&
5227 field->result_type() == STRING_RESULT))
5228 {
5229 String *result;
5230 CHARSET_INFO *cs= collation.collation;
5231 char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns
5232 str_value.set_quick(buff, sizeof(buff), cs);
5233 result= m_var_entry->val_str(&null_value, &str_value, decimals);
5234
5235 if (null_value)
5236 {
5237 str_value.set_quick(0, 0, cs);
5238 return set_field_to_null_with_conversions(field, no_conversions);
5239 }
5240
5241 /* NOTE: If null_value == FALSE, "result" must be not NULL. */
5242
5243 field->set_notnull();
5244 error=field->store(result->ptr(),result->length(),cs);
5245 str_value.set_quick(0, 0, cs);
5246 }
5247 else if (result_type() == REAL_RESULT)
5248 {
5249 double nr= m_var_entry->val_real(&null_value);
5250 if (null_value)
5251 return set_field_to_null(field);
5252 field->set_notnull();
5253 error=field->store(nr);
5254 }
5255 else if (result_type() == DECIMAL_RESULT)
5256 {
5257 my_decimal decimal_value;
5258 my_decimal *val= m_var_entry->val_decimal(&null_value, &decimal_value);
5259 if (null_value)
5260 return set_field_to_null(field);
5261 field->set_notnull();
5262 error=field->store_decimal(val);
5263 }
5264 else
5265 {
5266 longlong nr= m_var_entry->val_int(&null_value);
5267 if (null_value)
5268 return set_field_to_null_with_conversions(field, no_conversions);
5269 field->set_notnull();
5270 error=field->store(nr, unsigned_flag);
5271 }
5272 return error;
5273 }
5274
5275
5276 String *
5277 Item_func_get_user_var::val_str(String *str)
5278 {
5279 DBUG_ASSERT(fixed == 1);
5280 DBUG_ENTER("Item_func_get_user_var::val_str");
create_1_arg(THD * thd,Item * arg1)5281 if (!m_var_entry)
5282 DBUG_RETURN((String*) 0); // No such variable
5283 DBUG_RETURN(m_var_entry->val_str(&null_value, str, decimals));
5284 }
5285
5286
5287 double Item_func_get_user_var::val_real()
5288 {
5289 DBUG_ASSERT(fixed == 1);
5290 if (!m_var_entry)
create_1_arg(THD * thd,Item * arg1)5291 return 0.0; // No such variable
5292 return (m_var_entry->val_real(&null_value));
5293 }
5294
5295
5296 my_decimal *Item_func_get_user_var::val_decimal(my_decimal *dec)
5297 {
5298 DBUG_ASSERT(fixed == 1);
5299 if (!m_var_entry)
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5300 return 0;
5301 return m_var_entry->val_decimal(&null_value, dec);
5302 }
5303
5304
5305 longlong Item_func_get_user_var::val_int()
5306 {
5307 DBUG_ASSERT(fixed == 1);
5308 if (!m_var_entry)
5309 return 0; // No such variable
5310 return (m_var_entry->val_int(&null_value));
5311 }
5312
5313
5314 /**
5315 Get variable by name and, if necessary, put the record of variable
5316 use into the binary log.
5317
5318 When a user variable is invoked from an update query (INSERT, UPDATE etc),
5319 stores this variable and its value in thd->user_var_events, so that it can be
5320 written to the binlog (will be written just before the query is written, see
5321 log.cc).
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5322
5323 @param thd Current thread
5324 @param name Variable name
5325 @param[out] out_entry variable structure or NULL. The pointer is set
5326 regardless of whether function succeeded or not.
5327
5328 @retval
5329 0 OK
5330 @retval
5331 1 Failed to put appropriate record into binary log
5332
5333 */
5334
5335 static int
5336 get_var_with_binlog(THD *thd, enum_sql_command sql_command,
5337 LEX_CSTRING *name, user_var_entry **out_entry)
5338 {
5339 BINLOG_USER_VAR_EVENT *user_var_event;
5340 user_var_entry *var_entry;
5341 var_entry= get_variable(&thd->user_vars, name, 0);
5342
5343 /*
5344 Any reference to user-defined variable which is done from stored
5345 function or trigger affects their execution and the execution of the
5346 calling statement. We must log all such variables even if they are
5347 not involved in table-updating statements.
5348 */
5349 if (!(opt_bin_log &&
5350 (is_update_query(sql_command) || thd->in_sub_stmt)))
5351 {
5352 *out_entry= var_entry;
5353 return 0;
5354 }
5355
5356 if (!var_entry)
5357 {
5358 /*
5359 If the variable does not exist, it's NULL, but we want to create it so
5360 that it gets into the binlog (if it didn't, the slave could be
5361 influenced by a variable of the same name previously set by another
5362 thread).
5363 We create it like if it had been explicitly set with SET before.
5364 The 'new' mimics what sql_yacc.yy does when 'SET @a=10;'.
5365 sql_set_variables() is what is called from 'case SQLCOM_SET_OPTION'
5366 in dispatch_command()). Instead of building a one-element list to pass to
5367 sql_set_variables(), we could instead manually call check() and update();
5368 this would save memory and time; but calling sql_set_variables() makes
5369 one unique place to maintain (sql_set_variables()).
5370
5371 Manipulation with lex is necessary since free_underlaid_joins
5372 is going to release memory belonging to the main query.
5373 */
5374
5375 List<set_var_base> tmp_var_list;
5376 LEX *sav_lex= thd->lex, lex_tmp;
5377 thd->lex= &lex_tmp;
5378 lex_start(thd);
5379 tmp_var_list.push_back(new (thd->mem_root)
5380 set_var_user(new (thd->mem_root)
5381 Item_func_set_user_var(thd, name,
5382 new (thd->mem_root) Item_null(thd))),
5383 thd->mem_root);
5384 /* Create the variable if the above allocations succeeded */
5385 if (unlikely(thd->is_fatal_error) ||
5386 unlikely(sql_set_variables(thd, &tmp_var_list, false)))
5387 {
5388 thd->lex= sav_lex;
5389 goto err;
5390 }
5391 thd->lex= sav_lex;
5392 if (unlikely(!(var_entry= get_variable(&thd->user_vars, name, 0))))
5393 goto err;
5394 }
5395 else if (var_entry->used_query_id == thd->query_id ||
5396 mysql_bin_log.is_query_in_union(thd, var_entry->used_query_id))
5397 {
5398 /*
5399 If this variable was already stored in user_var_events by this query
5400 (because it's used in more than one place in the query), don't store
5401 it.
5402 */
5403 *out_entry= var_entry;
5404 return 0;
5405 }
5406
5407 size_t size;
5408 /*
5409 First we need to store value of var_entry, when the next situation
5410 appears:
5411 > set @a:=1;
5412 > insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
5413 We have to write to binlog value @a= 1.
5414
5415 We allocate the user_var_event on user_var_events_alloc pool, not on
5416 the this-statement-execution pool because in SPs user_var_event objects
5417 may need to be valid after current [SP] statement execution pool is
5418 destroyed.
5419 */
5420 size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
5421 if (unlikely(!(user_var_event= (BINLOG_USER_VAR_EVENT *)
5422 alloc_root(thd->user_var_events_alloc, size))))
5423 goto err;
5424
5425 user_var_event->value= (char*) user_var_event +
5426 ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT));
5427 user_var_event->user_var_event= var_entry;
5428 user_var_event->type= var_entry->type;
5429 user_var_event->charset_number= var_entry->charset()->number;
5430 user_var_event->unsigned_flag= var_entry->unsigned_flag;
5431 if (!var_entry->value)
5432 {
5433 /* NULL value*/
5434 user_var_event->length= 0;
5435 user_var_event->value= 0;
5436 }
5437 else
5438 {
5439 user_var_event->length= var_entry->length;
5440 memcpy(user_var_event->value, var_entry->value,
5441 var_entry->length);
5442 }
5443 /* Mark that this variable has been used by this query */
5444 var_entry->used_query_id= thd->query_id;
5445 if (insert_dynamic(&thd->user_var_events, (uchar*) &user_var_event))
5446 goto err;
5447
5448 *out_entry= var_entry;
5449 return 0;
5450
5451 err:
5452 *out_entry= var_entry;
5453 return 1;
5454 }
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5455
5456 bool Item_func_get_user_var::fix_length_and_dec()
5457 {
5458 THD *thd=current_thd;
5459 int error;
5460 maybe_null=1;
5461 decimals=NOT_FIXED_DEC;
5462 max_length=MAX_BLOB_WIDTH;
5463
5464 error= get_var_with_binlog(thd, thd->lex->sql_command, &name, &m_var_entry);
5465
5466 /*
5467 If the variable didn't exist it has been created as a STRING-type.
5468 'm_var_entry' is NULL only if there occurred an error during the call to
5469 get_var_with_binlog.
5470 */
5471 if (likely(!error && m_var_entry))
5472 {
5473 unsigned_flag= m_var_entry->unsigned_flag;
5474 max_length= (uint32)m_var_entry->length;
5475 collation.set(m_var_entry->charset(), DERIVATION_IMPLICIT);
5476 set_handler_by_result_type(m_var_entry->type);
5477 switch (result_type()) {
5478 case REAL_RESULT:
5479 fix_char_length(DBL_DIG + 8);
5480 break;
5481 case INT_RESULT:
5482 fix_char_length(MAX_BIGINT_WIDTH);
5483 decimals=0;
5484 break;
5485 case STRING_RESULT:
5486 max_length= MAX_BLOB_WIDTH - 1;
5487 break;
5488 case DECIMAL_RESULT:
5489 fix_char_length(DECIMAL_MAX_STR_LENGTH);
5490 decimals= DECIMAL_MAX_SCALE;
5491 break;
5492 case ROW_RESULT: // Keep compiler happy
5493 case TIME_RESULT:
5494 DBUG_ASSERT(0); // This case should never be chosen
5495 break;
5496 }
5497 }
5498 else
5499 {
5500 collation.set(&my_charset_bin, DERIVATION_IMPLICIT);
5501 null_value= 1;
5502 set_handler(&type_handler_long_blob);
5503 max_length= MAX_BLOB_WIDTH;
5504 }
5505 return false;
5506 }
5507
5508
5509 bool Item_func_get_user_var::const_item() const
5510 {
5511 return (!m_var_entry ||
5512 current_thd->query_id != m_var_entry->update_query_id);
5513 }
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5514
5515
5516 void Item_func_get_user_var::print(String *str, enum_query_type query_type)
5517 {
5518 str->append(STRING_WITH_LEN("@"));
5519 append_identifier(current_thd, str, &name);
5520 }
5521
5522
5523 bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
5524 {
5525 /* Assume we don't have rtti */
5526 if (this == item)
5527 return 1; // Same item is same.
5528 /* Check if other type is also a get_user_var() object */
5529 if (item->type() != FUNC_ITEM ||
5530 ((Item_func*) item)->functype() != functype())
5531 return 0;
5532 Item_func_get_user_var *other=(Item_func_get_user_var*) item;
5533 return (name.length == other->name.length &&
5534 !memcmp(name.str, other->name.str, name.length));
5535 }
5536
5537
5538 bool Item_func_get_user_var::set_value(THD *thd,
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5539 sp_rcontext * /*ctx*/, Item **it)
5540 {
5541 LEX_CSTRING tmp_name= get_name();
5542 Item_func_set_user_var *suv= new (thd->mem_root) Item_func_set_user_var(thd, &tmp_name, *it);
5543 /*
5544 Item_func_set_user_var is not fixed after construction, call
5545 fix_fields().
5546 */
5547 return (!suv || suv->fix_fields(thd, it) || suv->check(0) || suv->update());
5548 }
5549
5550
5551 bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref)
5552 {
5553 DBUG_ASSERT(fixed == 0);
5554 DBUG_ASSERT(thd->lex->exchange);
5555 if (Item::fix_fields(thd, ref) ||
5556 !(entry= get_variable(&thd->user_vars, &org_name, 1)))
5557 return TRUE;
5558 entry->type= STRING_RESULT;
5559 /*
5560 Let us set the same collation which is used for loading
5561 of fields in LOAD DATA INFILE.
5562 (Since Item_user_var_as_out_param is used only there).
5563 */
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5564 entry->set_charset(thd->lex->exchange->cs ?
5565 thd->lex->exchange->cs :
5566 thd->variables.collation_database);
5567 entry->update_query_id= thd->query_id;
5568 return FALSE;
5569 }
5570
5571
5572 void Item_user_var_as_out_param::set_null_value(CHARSET_INFO* cs)
5573 {
5574 ::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs, 0 /* unsigned_arg */);
5575 }
5576
5577
5578 void Item_user_var_as_out_param::set_value(const char *str, uint length,
5579 CHARSET_INFO* cs)
5580 {
5581 ::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs,
5582 0 /* unsigned_arg */);
5583 }
5584
5585
5586 double Item_user_var_as_out_param::val_real()
5587 {
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5588 DBUG_ASSERT(0);
5589 return 0.0;
5590 }
5591
5592
5593 longlong Item_user_var_as_out_param::val_int()
5594 {
5595 DBUG_ASSERT(0);
5596 return 0;
5597 }
5598
5599
5600 String* Item_user_var_as_out_param::val_str(String *str)
5601 {
5602 DBUG_ASSERT(0);
5603 return 0;
5604 }
5605
5606
5607 my_decimal* Item_user_var_as_out_param::val_decimal(my_decimal *decimal_buffer)
5608 {
5609 DBUG_ASSERT(0);
5610 return 0;
5611 }
5612
5613
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5614 bool Item_user_var_as_out_param::get_date(MYSQL_TIME *ltime, ulonglong fuzzy)
5615 {
5616 DBUG_ASSERT(0);
5617 return true;
5618 }
5619
5620
5621 void Item_user_var_as_out_param::load_data_print_for_log_event(THD *thd,
5622 String *str)
5623 const
5624 {
5625 str->append('@');
5626 append_identifier(thd, str, &org_name);
5627 }
5628
5629
5630 Item_func_get_system_var::
5631 Item_func_get_system_var(THD *thd, sys_var *var_arg, enum_var_type var_type_arg,
5632 LEX_CSTRING *component_arg, const char *name_arg,
5633 size_t name_len_arg):
5634 Item_func(thd), var(var_arg), var_type(var_type_arg),
5635 orig_var_type(var_type_arg), component(*component_arg), cache_present(0)
5636 {
5637 /* set_name() will allocate the name */
5638 set_name(thd, name_arg, (uint) name_len_arg, system_charset_info);
5639 }
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5640
5641
5642 bool Item_func_get_system_var::is_written_to_binlog()
5643 {
5644 return var->is_written_to_binlog(var_type);
5645 }
5646
5647
5648 void Item_func_get_system_var::update_null_value()
5649 {
5650 THD *thd= current_thd;
5651 int save_no_errors= thd->no_errors;
5652 thd->no_errors= TRUE;
5653 Item::update_null_value();
5654 thd->no_errors= save_no_errors;
5655 }
5656
5657
5658 bool Item_func_get_system_var::fix_length_and_dec()
5659 {
5660 const char *cptr;
5661 maybe_null= TRUE;
5662 max_length= 0;
5663
5664 if (var->check_type(var_type))
5665 {
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5666 if (var_type != OPT_DEFAULT)
5667 {
5668 my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0),
5669 var->name.str, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
5670 return TRUE;
5671 }
5672 /* As there was no local variable, return the global value */
5673 var_type= OPT_GLOBAL;
5674 }
5675
5676 switch (var->show_type())
5677 {
5678 case SHOW_HA_ROWS:
5679 case SHOW_UINT:
5680 case SHOW_ULONG:
5681 case SHOW_ULONGLONG:
5682 unsigned_flag= TRUE;
5683 /* fall through */
5684 case SHOW_SINT:
5685 case SHOW_SLONG:
5686 case SHOW_SLONGLONG:
5687 collation.set_numeric();
5688 fix_char_length(MY_INT64_NUM_DECIMAL_DIGITS);
5689 decimals=0;
5690 break;
5691 case SHOW_CHAR:
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5692 case SHOW_CHAR_PTR:
5693 mysql_mutex_lock(&LOCK_global_system_variables);
5694 cptr= var->show_type() == SHOW_CHAR ?
5695 reinterpret_cast<const char*>(var->value_ptr(current_thd, var_type,
5696 &component)) :
5697 *reinterpret_cast<const char* const*>(var->value_ptr(current_thd,
5698 var_type,
5699 &component));
5700 if (cptr)
5701 max_length= (uint32)system_charset_info->cset->numchars(system_charset_info,
5702 cptr,
5703 cptr + strlen(cptr));
5704 mysql_mutex_unlock(&LOCK_global_system_variables);
5705 collation.set(system_charset_info, DERIVATION_SYSCONST);
5706 max_length*= system_charset_info->mbmaxlen;
5707 decimals=NOT_FIXED_DEC;
5708 break;
5709 case SHOW_LEX_STRING:
5710 {
5711 mysql_mutex_lock(&LOCK_global_system_variables);
5712 const LEX_STRING *ls=
5713 reinterpret_cast<const LEX_STRING*>(var->value_ptr(current_thd,
5714 var_type,
5715 &component));
5716 max_length= (uint32)system_charset_info->cset->numchars(system_charset_info,
5717 ls->str,
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5718 ls->str + ls->length);
5719 mysql_mutex_unlock(&LOCK_global_system_variables);
5720 collation.set(system_charset_info, DERIVATION_SYSCONST);
5721 max_length*= system_charset_info->mbmaxlen;
5722 decimals=NOT_FIXED_DEC;
5723 }
5724 break;
5725 case SHOW_BOOL:
5726 case SHOW_MY_BOOL:
5727 collation.set_numeric();
5728 fix_char_length(1);
5729 decimals=0;
5730 break;
5731 case SHOW_DOUBLE:
5732 decimals= 6;
5733 collation.set_numeric();
5734 fix_char_length(DBL_DIG + 6);
5735 break;
5736 default:
5737 my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str);
5738 break;
5739 }
5740 return FALSE;
5741 }
5742
5743
5744 void Item_func_get_system_var::print(String *str, enum_query_type query_type)
5745 {
5746 if (name.length)
5747 str->append(&name);
5748 else
5749 {
5750 str->append(STRING_WITH_LEN("@@"));
5751 if (component.length)
5752 {
5753 str->append(&component);
5754 str->append('.');
create_1_arg(THD * thd,Item * arg1)5755 }
5756 else if (var_type == SHOW_OPT_GLOBAL && var->scope() != sys_var::GLOBAL)
5757 {
5758 str->append(STRING_WITH_LEN("global."));
5759 }
5760 str->append(&var->name);
5761 }
5762 }
5763
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5764 bool Item_func_get_system_var::check_vcol_func_processor(void *arg)
5765 {
5766 return mark_unsupported_function("@@", var->name.str, arg, VCOL_SESSION_FUNC);
5767 }
5768
5769
5770 const Type_handler *Item_func_get_system_var::type_handler() const
5771 {
5772 switch (var->show_type())
5773 {
5774 case SHOW_BOOL:
5775 case SHOW_MY_BOOL:
5776 case SHOW_SINT:
5777 case SHOW_SLONG:
5778 case SHOW_SLONGLONG:
5779 case SHOW_UINT:
5780 case SHOW_ULONG:
5781 case SHOW_ULONGLONG:
5782 case SHOW_HA_ROWS:
5783 return &type_handler_longlong;
5784 case SHOW_CHAR:
create_1_arg(THD * thd,Item * arg1)5785 case SHOW_CHAR_PTR:
5786 case SHOW_LEX_STRING:
5787 return &type_handler_varchar;
5788 case SHOW_DOUBLE:
5789 return &type_handler_double;
5790 default:
5791 my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str);
5792 return &type_handler_varchar; // keep the compiler happy
5793 }
5794 }
5795
create_1_arg(THD * thd,Item * arg1)5796
5797 longlong Item_func_get_system_var::val_int()
5798 {
5799 THD *thd= current_thd;
5800
5801 DBUG_EXECUTE_IF("simulate_non_gtid_aware_master",
5802 {
5803 if (0 == strcmp("gtid_domain_id", var->name.str))
5804 {
5805 my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str);
5806 return 0;
5807 }
5808 });
5809 if (cache_present && thd->query_id == used_query_id)
5810 {
5811 if (cache_present & GET_SYS_VAR_CACHE_LONG)
5812 {
5813 null_value= cached_null_value;
5814 return cached_llval;
5815 }
5816 else if (cache_present & GET_SYS_VAR_CACHE_DOUBLE)
5817 {
5818 null_value= cached_null_value;
5819 cached_llval= (longlong) cached_dval;
5820 cache_present|= GET_SYS_VAR_CACHE_LONG;
5821 return cached_llval;
5822 }
5823 else if (cache_present & GET_SYS_VAR_CACHE_STRING)
5824 {
5825 null_value= cached_null_value;
5826 if (!null_value)
5827 cached_llval= longlong_from_string_with_check(&cached_strval);
5828 else
5829 cached_llval= 0;
5830 cache_present|= GET_SYS_VAR_CACHE_LONG;
5831 return cached_llval;
5832 }
5833 }
5834
5835 cached_llval= var->val_int(&null_value, thd, var_type, &component);
5836 cache_present |= GET_SYS_VAR_CACHE_LONG;
5837 used_query_id= thd->query_id;
5838 cached_null_value= null_value;
5839 return cached_llval;
5840 }
5841
5842
5843 String* Item_func_get_system_var::val_str(String* str)
5844 {
5845 THD *thd= current_thd;
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5846
5847 if (cache_present && thd->query_id == used_query_id)
5848 {
5849 if (cache_present & GET_SYS_VAR_CACHE_STRING)
5850 {
5851 null_value= cached_null_value;
5852 return null_value ? NULL : &cached_strval;
5853 }
5854 else if (cache_present & GET_SYS_VAR_CACHE_LONG)
5855 {
5856 null_value= cached_null_value;
5857 if (!null_value)
5858 cached_strval.set (cached_llval, collation.collation);
5859 cache_present|= GET_SYS_VAR_CACHE_STRING;
5860 return null_value ? NULL : &cached_strval;
5861 }
5862 else if (cache_present & GET_SYS_VAR_CACHE_DOUBLE)
5863 {
5864 null_value= cached_null_value;
5865 if (!null_value)
5866 cached_strval.set_real (cached_dval, decimals, collation.collation);
5867 cache_present|= GET_SYS_VAR_CACHE_STRING;
5868 return null_value ? NULL : &cached_strval;
5869 }
5870 }
5871
5872 str= var->val_str(&cached_strval, thd, var_type, &component);
5873 cache_present|= GET_SYS_VAR_CACHE_STRING;
5874 used_query_id= thd->query_id;
5875 cached_null_value= null_value= !str;
5876 return str;
5877 }
5878
5879
5880 double Item_func_get_system_var::val_real()
5881 {
5882 THD *thd= current_thd;
5883
5884 if (cache_present && thd->query_id == used_query_id)
5885 {
5886 if (cache_present & GET_SYS_VAR_CACHE_DOUBLE)
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5887 {
5888 null_value= cached_null_value;
5889 return cached_dval;
5890 }
5891 else if (cache_present & GET_SYS_VAR_CACHE_LONG)
5892 {
5893 null_value= cached_null_value;
5894 cached_dval= (double)cached_llval;
5895 cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
5896 return cached_dval;
5897 }
5898 else if (cache_present & GET_SYS_VAR_CACHE_STRING)
5899 {
5900 null_value= cached_null_value;
5901 if (!null_value)
5902 cached_dval= double_from_string_with_check(&cached_strval);
5903 else
5904 cached_dval= 0;
5905 cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
5906 return cached_dval;
5907 }
5908 }
5909
5910 cached_dval= var->val_real(&null_value, thd, var_type, &component);
5911 cache_present |= GET_SYS_VAR_CACHE_DOUBLE;
5912 used_query_id= thd->query_id;
5913 cached_null_value= null_value;
5914 return cached_dval;
5915 }
5916
5917
5918 bool Item_func_get_system_var::eq(const Item *item, bool binary_cmp) const
5919 {
5920 /* Assume we don't have rtti */
5921 if (this == item)
5922 return 1; // Same item is same.
5923 /* Check if other type is also a get_user_var() object */
create_1_arg(THD * thd,Item * arg1)5924 if (item->type() != FUNC_ITEM ||
5925 ((Item_func*) item)->functype() != functype())
5926 return 0;
5927 Item_func_get_system_var *other=(Item_func_get_system_var*) item;
5928 return (var == other->var && var_type == other->var_type);
5929 }
5930
5931
5932 void Item_func_get_system_var::cleanup()
create_1_arg(THD * thd,Item * arg1)5933 {
5934 Item_func::cleanup();
5935 cache_present= 0;
5936 var_type= orig_var_type;
5937 cached_strval.free();
5938 }
5939
5940 /**
5941 @retval
5942 0 ok
5943 1 OOM error
create_native_std(THD * thd,LEX_CSTRING * name,List<Item> * item_list)5944 */
5945
5946 bool Item_func_match::init_search(THD *thd, bool no_order)
5947 {
5948 DBUG_ENTER("Item_func_match::init_search");
5949
5950 if (!table->file->get_table()) // the handler isn't opened yet
5951 DBUG_RETURN(0);
5952
5953 /* Check if init_search() has been called before */
5954 if (ft_handler)
5955 {
5956 if (join_key)
5957 table->file->ft_handler= ft_handler;
5958 DBUG_RETURN(0);
5959 }
5960
5961 if (key == NO_SUCH_KEY)
5962 {
5963 List<Item> fields;
5964 fields.push_back(new (thd->mem_root)
5965 Item_string(thd, " ", 1, cmp_collation.collation),
5966 thd->mem_root);
5967 for (uint i= 1; i < arg_count; i++)
5968 fields.push_back(args[i]);
5969 concat_ws= new (thd->mem_root) Item_func_concat_ws(thd, fields);
5970 if (unlikely(thd->is_fatal_error))
5971 DBUG_RETURN(1); // OOM in new or push_back
5972 /*
5973 Above function used only to get value and do not need fix_fields for it:
5974 Item_string - basic constant
5975 fields - fix_fields() was already called for this arguments
5976 Item_func_concat_ws - do not need fix_fields() to produce value
5977 */
5978 concat_ws->quick_fix_field();
5979 }
5980
5981 if (master)
5982 {
5983 join_key= master->join_key= join_key | master->join_key;
5984 if (master->init_search(thd, no_order))
5985 DBUG_RETURN(1);
5986 ft_handler= master->ft_handler;
5987 join_key= master->join_key;
5988 DBUG_RETURN(0);
5989 }
5990
5991 String *ft_tmp= 0;
5992
5993 // MATCH ... AGAINST (NULL) is meaningless, but possible
5994 if (!(ft_tmp=key_item()->val_str(&value)))
5995 {
5996 ft_tmp= &value;
5997 value.set("", 0, cmp_collation.collation);
5998 }
5999
6000 if (ft_tmp->charset() != cmp_collation.collation)
6001 {
6002 uint dummy_errors;
6003 if (search_value.copy(ft_tmp->ptr(), ft_tmp->length(), ft_tmp->charset(),
6004 cmp_collation.collation, &dummy_errors))
6005 DBUG_RETURN(1);
6006 ft_tmp= &search_value;
6007 }
6008
6009 if (join_key && !no_order)
6010 flags|=FT_SORTED;
6011
6012 if (key != NO_SUCH_KEY)
6013 THD_STAGE_INFO(table->in_use, stage_fulltext_initialization);
6014
6015 ft_handler= table->file->ft_init_ext(flags, key, ft_tmp);
6016
6017 if (join_key)
6018 table->file->ft_handler=ft_handler;
6019
6020 DBUG_RETURN(0);
6021 }
6022
6023
create_2_arg(THD * thd,Item * arg1,Item * arg2)6024 bool Item_func_match::fix_fields(THD *thd, Item **ref)
6025 {
6026 DBUG_ASSERT(fixed == 0);
6027 Item *UNINIT_VAR(item); // Safe as arg_count is > 1
6028
6029 status_var_increment(thd->status_var.feature_fulltext);
6030
6031 maybe_null=1;
6032 join_key=0;
6033
6034 /*
6035 const_item is assumed in quite a bit of places, so it would be difficult
6036 to remove; If it would ever to be removed, this should include
6037 modifications to find_best and auto_close as complement to auto_init code
6038 above.
6039 */
6040 if (Item_func::fix_fields(thd, ref) ||
6041 !args[0]->const_during_execution())
6042 {
6043 my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST");
6044 return TRUE;
6045 }
6046
6047 bool allows_multi_table_search= true;
6048 const_item_cache=0;
6049 table= 0;
6050 for (uint i=1 ; i < arg_count ; i++)
6051 {
6052 item= args[i]= args[i]->real_item();
6053 /*
6054 When running in PS mode, some Item_field's can already be replaced
6055 to Item_func_conv_charset during PREPARE time. This is possible
6056 in case of "MATCH (f1,..,fN) AGAINST (... IN BOOLEAN MODE)"
6057 when running without any fulltext indexes and when fields f1..fN
6058 have different character sets.
6059 So we check for FIELD_ITEM only during prepare time and in non-PS mode,
6060 and do not check in PS execute time.
6061 */
6062 if (!thd->stmt_arena->is_stmt_execute() &&
6063 item->type() != Item::FIELD_ITEM)
6064 {
6065 my_error(ER_WRONG_ARGUMENTS, MYF(0), "MATCH");
6066 return TRUE;
6067 }
6068 /*
6069 During the prepare-time execution of fix_fields() of a PS query some
6070 Item_fields's could have been already replaced to Item_func_conv_charset
6071 (by the call for agg_arg_charsets_for_comparison below()).
6072 But agg_arg_charsets_for_comparison() is written in a way that
6073 at least *one* of the Item_field's is not replaced.
6074 This makes sure that "table" gets initialized during PS execution time.
6075 */
6076 if (item->type() == Item::FIELD_ITEM)
6077 table= ((Item_field *)item)->field->table;
6078
6079 allows_multi_table_search &= allows_search_on_non_indexed_columns(table);
6080 }
6081
6082 /*
6083 Check that all columns come from the same table.
6084 We've already checked that columns in MATCH are fields so
6085 PARAM_TABLE_BIT can only appear from AGAINST argument.
6086 */
6087 if ((used_tables_cache & ~PARAM_TABLE_BIT) != item->used_tables())
6088 key=NO_SUCH_KEY;
6089
6090 if (key == NO_SUCH_KEY && !allows_multi_table_search)
6091 {
6092 my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH");
6093 return TRUE;
6094 }
6095 if (!(table->file->ha_table_flags() & HA_CAN_FULLTEXT))
6096 {
6097 my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0), table->file->table_type());
6098 return 1;
6099 }
6100 table->fulltext_searched=1;
6101 return agg_arg_charsets_for_comparison(cmp_collation, args+1, arg_count-1);
6102 }
6103
6104 bool Item_func_match::fix_index()
6105 {
6106 Item_field *item;
6107 uint ft_to_key[MAX_KEY], ft_cnt[MAX_KEY], fts=0, keynr;
6108 uint max_cnt=0, mkeys=0, i;
6109
6110 /*
6111 We will skip execution if the item is not fixed
6112 with fix_field
6113 */
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)6114 if (!fixed)
6115 return false;
6116
6117 if (key == NO_SUCH_KEY)
6118 return 0;
6119
6120 if (!table)
6121 goto err;
6122
6123 for (keynr=0 ; keynr < table->s->keys ; keynr++)
6124 {
6125 if ((table->key_info[keynr].flags & HA_FULLTEXT) &&
6126 (flags & FT_BOOL ? table->keys_in_use_for_query.is_set(keynr) :
6127 table->s->keys_in_use.is_set(keynr)))
6128
6129 {
6130 ft_to_key[fts]=keynr;
6131 ft_cnt[fts]=0;
6132 fts++;
6133 }
6134 }
6135
6136 if (!fts)
6137 goto err;
6138
6139 for (i=1; i < arg_count; i++)
6140 {
6141 if (args[i]->type() != FIELD_ITEM)
6142 goto err;
6143 item=(Item_field*)args[i];
6144 for (keynr=0 ; keynr < fts ; keynr++)
6145 {
6146 KEY *ft_key=&table->key_info[ft_to_key[keynr]];
6147 uint key_parts=ft_key->user_defined_key_parts;
6148
6149 for (uint part=0 ; part < key_parts ; part++)
6150 {
6151 if (item->field->eq(ft_key->key_part[part].field))
6152 ft_cnt[keynr]++;
6153 }
6154 }
create_1_arg(THD * thd,Item * arg1)6155 }
6156
6157 for (keynr=0 ; keynr < fts ; keynr++)
6158 {
6159 if (ft_cnt[keynr] > max_cnt)
6160 {
6161 mkeys=0;
6162 max_cnt=ft_cnt[mkeys]=ft_cnt[keynr];
6163 ft_to_key[mkeys]=ft_to_key[keynr];
create_1_arg(THD * thd,Item * arg1)6164 continue;
6165 }
6166 if (max_cnt && ft_cnt[keynr] == max_cnt)
6167 {
6168 mkeys++;
6169 ft_cnt[mkeys]=ft_cnt[keynr];
6170 ft_to_key[mkeys]=ft_to_key[keynr];
6171 continue;
6172 }
create_2_arg(THD * thd,Item * arg1,Item * arg2)6173 }
6174
6175 for (keynr=0 ; keynr <= mkeys ; keynr++)
6176 {
6177 // partial keys doesn't work
6178 if (max_cnt < arg_count-1 ||
6179 max_cnt < table->key_info[ft_to_key[keynr]].user_defined_key_parts)
6180 continue;
6181
create_2_arg(THD * thd,Item * arg1,Item * arg2)6182 key=ft_to_key[keynr];
6183
6184 return 0;
6185 }
6186
6187 err:
6188 if (allows_search_on_non_indexed_columns(table))
6189 {
6190 key=NO_SUCH_KEY;
6191 return 0;
create_1_arg(THD * thd,Item * arg1)6192 }
6193 my_message(ER_FT_MATCHING_KEY_NOT_FOUND,
6194 ER(ER_FT_MATCHING_KEY_NOT_FOUND), MYF(0));
6195 return 1;
6196 }
6197
6198
6199 bool Item_func_match::eq(const Item *item, bool binary_cmp) const
6200 {
6201 if (item->type() != FUNC_ITEM ||
6202 ((Item_func*)item)->functype() != FT_FUNC ||
create_1_arg(THD * thd,Item * arg1)6203 flags != ((Item_func_match*)item)->flags)
6204 return 0;
6205
6206 Item_func_match *ifm=(Item_func_match*) item;
6207
6208 if (key == ifm->key && table == ifm->table &&
6209 key_item()->eq(ifm->key_item(), binary_cmp))
6210 return 1;
6211
6212 return 0;
6213 }
create_1_arg(THD * thd,Item * arg1)6214
6215
6216 double Item_func_match::val_real()
6217 {
6218 DBUG_ASSERT(fixed == 1);
6219 DBUG_ENTER("Item_func_match::val");
6220 if (ft_handler == NULL)
6221 DBUG_RETURN(-1.0);
6222
6223 if (key != NO_SUCH_KEY && table->null_row) /* NULL row from an outer join */
6224 DBUG_RETURN(0.0);
6225
6226 if (join_key)
6227 {
6228 if (table->file->ft_handler)
6229 DBUG_RETURN(ft_handler->please->get_relevance(ft_handler));
6230 join_key=0;
6231 }
6232
6233 if (key == NO_SUCH_KEY)
6234 {
6235 String *a= concat_ws->val_str(&value);
6236 if ((null_value= (a == 0)) || !a->length())
6237 DBUG_RETURN(0);
6238 DBUG_RETURN(ft_handler->please->find_relevance(ft_handler,
6239 (uchar *)a->ptr(), a->length()));
6240 }
6241 DBUG_RETURN(ft_handler->please->find_relevance(ft_handler,
6242 table->record[0], 0));
6243 }
6244
create_2_arg(THD * thd,Item * arg1,Item * arg2)6245 void Item_func_match::print(String *str, enum_query_type query_type)
6246 {
6247 str->append(STRING_WITH_LEN("(match "));
6248 print_args(str, 1, query_type);
6249 str->append(STRING_WITH_LEN(" against ("));
6250 args[0]->print(str, query_type);
6251 if (flags & FT_BOOL)
6252 str->append(STRING_WITH_LEN(" in boolean mode"));
6253 else if (flags & FT_EXPAND)
6254 str->append(STRING_WITH_LEN(" with query expansion"));
6255 str->append(STRING_WITH_LEN("))"));
6256 }
6257
6258 longlong Item_func_bit_xor::val_int()
6259 {
6260 DBUG_ASSERT(fixed == 1);
6261 ulonglong arg1= (ulonglong) args[0]->val_int();
6262 ulonglong arg2= (ulonglong) args[1]->val_int();
6263 if ((null_value= (args[0]->null_value || args[1]->null_value)))
6264 return 0;
6265 return (longlong) (arg1 ^ arg2);
create_2_arg(THD * thd,Item * arg1,Item * arg2)6266 }
6267
6268
6269 /***************************************************************************
6270 System variables
6271 ****************************************************************************/
6272
6273 /**
6274 Return value of an system variable base[.name] as a constant item.
6275
6276 @param thd Thread handler
6277 @param var_type global / session
6278 @param name Name of base or system variable
6279 @param component Component.
6280
6281 @note
6282 If component.str = 0 then the variable name is in 'name'
6283
6284 @return
6285 - 0 : error
6286 - # : constant item
6287 */
6288
6289
6290 Item *get_system_var(THD *thd, enum_var_type var_type,
6291 const LEX_CSTRING *name,
6292 const LEX_CSTRING *component)
6293 {
6294 sys_var *var;
6295 LEX_CSTRING base_name, component_name;
6296
6297 if (component->str)
6298 {
6299 base_name= *component;
6300 component_name= *name;
6301 }
6302 else
6303 {
6304 base_name= *name;
6305 component_name= *component; // Empty string
6306 }
6307
6308 if (!(var= find_sys_var(thd, base_name.str, base_name.length)))
6309 return 0;
6310 if (component->str)
6311 {
6312 if (!var->is_struct())
6313 {
6314 my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), base_name.str);
6315 return 0;
6316 }
6317 }
6318 thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
6319
6320 set_if_smaller(component_name.length, MAX_SYS_VAR_LENGTH);
6321
6322 return new (thd->mem_root) Item_func_get_system_var(thd, var, var_type,
6323 &component_name,
6324 NULL, 0);
6325 }
6326
6327
6328 longlong Item_func_row_count::val_int()
6329 {
6330 DBUG_ASSERT(fixed == 1);
6331 THD *thd= current_thd;
create_3_arg(THD * thd,Item * arg1,Item * arg2,Item * arg3)6332
6333 return thd->get_row_count_func();
6334 }
6335
6336
6337
6338
6339 Item_func_sp::Item_func_sp(THD *thd, Name_resolution_context *context_arg,
6340 sp_name *name, const Sp_handler *sph):
create_2_arg(THD * thd,Item * arg1,Item * arg2)6341 Item_func(thd), Item_sp(thd, context_arg, name), m_handler(sph)
6342 {
6343 maybe_null= 1;
6344 }
6345
6346
6347 Item_func_sp::Item_func_sp(THD *thd, Name_resolution_context *context_arg,
6348 sp_name *name_arg, const Sp_handler *sph,
6349 List<Item> &list):
create_1_arg(THD * thd,Item * arg1)6350 Item_func(thd, list), Item_sp(thd, context_arg, name_arg), m_handler(sph)
6351 {
6352 maybe_null= 1;
6353 }
6354
6355
6356 void
6357 Item_func_sp::cleanup()
6358 {
6359 Item_sp::cleanup();
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)6360 Item_func::cleanup();
6361 }
6362
6363 const char *
6364 Item_func_sp::func_name() const
6365 {
6366 THD *thd= current_thd;
6367 return Item_sp::func_name(thd);
6368 }
6369
6370
6371 void my_missing_function_error(const LEX_CSTRING &token, const char *func_name)
6372 {
6373 if (token.length && is_lex_native_function (&token))
6374 my_error(ER_FUNC_INEXISTENT_NAME_COLLISION, MYF(0), func_name);
6375 else
6376 my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", func_name);
6377 }
6378
6379
6380 /**
6381 @note
6382 Deterministic stored procedures are considered inexpensive.
6383 Consequently such procedures may be evaluated during optimization,
6384 if they are constant (checked by the optimizer).
6385 */
6386
6387 bool Item_func_sp::is_expensive()
6388 {
6389 return !m_sp->detistic() ||
6390 current_thd->locked_tables_mode < LTM_LOCK_TABLES;
6391 }
6392
6393
6394 /**
6395 @brief Initialize local members with values from the Field interface.
6396
6397 @note called from Item::fix_fields.
6398 */
6399
6400 bool Item_func_sp::fix_length_and_dec()
6401 {
6402 DBUG_ENTER("Item_func_sp::fix_length_and_dec");
6403
6404 DBUG_ASSERT(sp_result_field);
6405 Type_std_attributes::set(sp_result_field->type_std_attributes());
6406 // There is a bug in the line below. See MDEV-11292 for details.
6407 collation.derivation= DERIVATION_COERCIBLE;
6408 maybe_null= 1;
6409
create_1_arg(THD * thd,Item * arg1)6410 DBUG_RETURN(FALSE);
6411 }
6412
6413
6414 bool
6415 Item_func_sp::execute()
6416 {
6417 /* Execute function and store the return value in the field. */
6418 return Item_sp::execute(current_thd, &null_value, args, arg_count);
6419 }
6420
create_3_arg(THD * thd,Item * arg1,Item * arg2,Item * arg3)6421
6422 void
6423 Item_func_sp::make_send_field(THD *thd, Send_field *tmp_field)
6424 {
6425 DBUG_ENTER("Item_func_sp::make_send_field");
6426 DBUG_ASSERT(sp_result_field);
6427 sp_result_field->make_send_field(tmp_field);
6428 if (name.str)
6429 {
6430 DBUG_ASSERT(name.length == strlen(name.str));
6431 tmp_field->col_name= name;
6432 }
6433 DBUG_VOID_RETURN;
6434 }
6435
6436
6437 const Type_handler *Item_func_sp::type_handler() const
6438 {
6439 DBUG_ENTER("Item_func_sp::type_handler");
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)6440 DBUG_PRINT("info", ("m_sp = %p", (void *) m_sp));
6441 DBUG_ASSERT(sp_result_field);
6442 // This converts ENUM/SET to STRING
6443 const Type_handler *handler= sp_result_field->type_handler();
6444 DBUG_RETURN(handler->type_handler_for_item_field());
6445 }
6446
6447
6448 longlong Item_func_found_rows::val_int()
6449 {
6450 DBUG_ASSERT(fixed == 1);
6451 return current_thd->found_rows();
6452 }
6453
6454
6455 longlong Item_func_oracle_sql_rowcount::val_int()
6456 {
6457 DBUG_ASSERT(fixed == 1);
6458 THD *thd= current_thd;
6459 /*
6460 In case when a query like this:
6461 INSERT a INTO @va FROM t1;
6462 returns multiple rows, SQL%ROWCOUNT should report 1 rather than -1.
6463 */
6464 longlong rows= thd->get_row_count_func();
6465 return rows != -1 ? rows : // ROW_COUNT()
6466 thd->found_rows(); // FOUND_ROWS()
6467 }
6468
6469
6470 longlong Item_func_sqlcode::val_int()
6471 {
6472 DBUG_ASSERT(fixed);
6473 DBUG_ASSERT(!null_value);
6474 Diagnostics_area::Sql_condition_iterator it=
6475 current_thd->get_stmt_da()->sql_conditions();
6476 const Sql_condition *err;
6477 if ((err= it++))
6478 return err->get_sql_errno();
6479 return 0;
create_native_std(THD * thd,LEX_CSTRING * name,List<Item> * item_list)6480 }
6481
6482
6483 bool
6484 Item_func_sp::fix_fields(THD *thd, Item **ref)
6485 {
6486 bool res;
6487 DBUG_ENTER("Item_func_sp::fix_fields");
6488 DBUG_ASSERT(fixed == 0);
6489 sp_head *sp= m_handler->sp_find_routine(thd, m_name, true);
6490
6491 /*
6492 Checking privileges to execute the function while creating view and
6493 executing the function of select.
6494 */
6495 if (!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) ||
6496 (thd->lex->sql_command == SQLCOM_CREATE_VIEW))
6497 {
6498 Security_context *save_security_ctx= thd->security_ctx;
6499 if (context->security_ctx)
6500 thd->security_ctx= context->security_ctx;
6501
6502 /*
6503 If the routine is not found, let's still check EXECUTE_ACL to decide
6504 whether to return "Access denied" or "Routine does not exist".
6505 */
6506 res= sp ? sp->check_execute_access(thd) :
6507 check_routine_access(thd, EXECUTE_ACL, &m_name->m_db,
6508 &m_name->m_name,
6509 &sp_handler_function, false);
6510 thd->security_ctx= save_security_ctx;
6511
6512 if (res)
6513 {
6514 context->process_error(thd);
6515 DBUG_RETURN(res);
6516 }
6517 }
6518
6519
6520 /* Custom aggregates are transformed into an Item_sum_sp. We can not do this
6521 earlier as we have no way of knowing what kind of Item we should create
6522 when parsing the query.
6523
6524 TODO(cvicentiu): See if this limitation can be lifted.
6525 */
6526
6527 DBUG_ASSERT(m_sp == NULL);
6528 if (!(m_sp= sp))
6529 {
6530 my_missing_function_error(m_name->m_name, ErrConvDQName(m_name).ptr());
6531 context->process_error(thd);
6532 DBUG_RETURN(TRUE);
6533 }
6534
6535 /*
6536 We must call init_result_field before Item_func::fix_fields()
6537 to make m_sp and result_field members available to fix_length_and_dec(),
6538 which is called from Item_func::fix_fields().
6539 */
6540 res= init_result_field(thd, max_length, maybe_null, &null_value, &name);
6541
6542 if (res)
6543 DBUG_RETURN(TRUE);
6544
6545 if (m_sp->agg_type() == GROUP_AGGREGATE)
6546 {
6547 Item_sum_sp *item_sp;
6548 Query_arena *arena, backup;
6549 arena= thd->activate_stmt_arena_if_needed(&backup);
6550
6551 if (arg_count)
6552 {
6553 List<Item> list;
6554 for (uint i= 0; i < arg_count; i++)
6555 list.push_back(args[i]);
6556 item_sp= new (thd->mem_root) Item_sum_sp(thd, context, m_name, sp, list);
6557 }
6558 else
6559 item_sp= new (thd->mem_root) Item_sum_sp(thd, context, m_name, sp);
6560
6561 if (arena)
6562 thd->restore_active_arena(arena, &backup);
6563 if (!item_sp)
6564 DBUG_RETURN(TRUE);
6565 *ref= item_sp;
6566 item_sp->name= name;
6567 bool err= item_sp->fix_fields(thd, ref);
6568 if (err)
6569 DBUG_RETURN(TRUE);
6570
6571 DBUG_RETURN(FALSE);
6572 }
6573
6574 res= Item_func::fix_fields(thd, ref);
6575
6576 if (res)
6577 DBUG_RETURN(TRUE);
6578
6579 if (thd->lex->is_view_context_analysis())
6580 {
6581 /*
6582 Here we check privileges of the stored routine only during view
6583 creation, in order to validate the view. A runtime check is
6584 performed in Item_func_sp::execute(), and this method is not
6585 called during context analysis. Notice, that during view
6586 creation we do not infer into stored routine bodies and do not
6587 check privileges of its statements, which would probably be a
6588 good idea especially if the view has SQL SECURITY DEFINER and
6589 the used stored procedure has SQL SECURITY DEFINER.
6590 */
6591 res= sp_check_access(thd);
6592 #ifndef NO_EMBEDDED_ACCESS_CHECKS
6593 /*
6594 Try to set and restore the security context to see whether it's valid
6595 */
6596 Security_context *save_secutiry_ctx;
6597 res= set_routine_security_ctx(thd, m_sp, &save_secutiry_ctx);
6598 if (!res)
6599 m_sp->m_security_ctx.restore_security_context(thd, save_secutiry_ctx);
6600
6601 #endif /* ! NO_EMBEDDED_ACCESS_CHECKS */
6602 }
6603
6604 if (!m_sp->detistic())
6605 {
6606 used_tables_cache |= RAND_TABLE_BIT;
6607 const_item_cache= FALSE;
6608 }
6609
6610 DBUG_RETURN(res);
6611 }
6612
6613
6614 void Item_func_sp::update_used_tables()
6615 {
create_1_arg(THD * thd,Item * arg1)6616 Item_func::update_used_tables();
6617
6618 if (!m_sp->detistic())
6619 {
6620 used_tables_cache |= RAND_TABLE_BIT;
6621 const_item_cache= FALSE;
6622 }
6623 }
6624
create_1_arg(THD * thd,Item * arg1)6625 bool Item_func_sp::check_vcol_func_processor(void *arg)
6626 {
6627 return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
6628 }
6629
6630 /*
6631 uuid_short handling.
6632
6633 The short uuid is defined as a longlong that contains the following bytes:
create_1_arg(THD * thd,Item * arg1)6634
6635 Bytes Comment
6636 1 Server_id & 255
6637 4 Startup time of server in seconds
6638 3 Incrementor
6639
6640 This means that an uuid is guaranteed to be unique
6641 even in a replication environment if the following holds:
6642
6643 - The last byte of the server id is unique
6644 - If you between two shutdown of the server don't get more than
6645 an average of 2^24 = 16M calls to uuid_short() per second.
6646 */
6647
6648 ulonglong uuid_value;
6649
6650 void uuid_short_init()
6651 {
6652 uuid_value= ((((ulonglong) global_system_variables.server_id) << 56) +
6653 (((ulonglong) server_start_time) << 24));
6654 }
create_1_arg(THD * thd,Item * arg1)6655
6656
6657 longlong Item_func_uuid_short::val_int()
6658 {
6659 ulonglong val;
6660 mysql_mutex_lock(&LOCK_short_uuid_generator);
6661 val= uuid_value++;
6662 mysql_mutex_unlock(&LOCK_short_uuid_generator);
6663 return (longlong) val;
6664 }
6665
create_2_arg(THD * thd,Item * arg1,Item * arg2)6666
6667 /**
6668 Last_value - return last argument.
6669 */
6670
6671 void Item_func_last_value::evaluate_sideeffects()
6672 {
6673 DBUG_ASSERT(fixed == 1 && arg_count > 0);
6674 for (uint i= 0; i < arg_count-1 ; i++)
6675 args[i]->val_int();
6676 }
6677
6678 String *Item_func_last_value::val_str(String *str)
6679 {
6680 String *tmp;
6681 evaluate_sideeffects();
6682 tmp= last_value->val_str(str);
6683 null_value= last_value->null_value;
create_3_arg(THD * thd,Item * arg1,Item * arg2,Item * arg3)6684 return tmp;
6685 }
6686
6687 longlong Item_func_last_value::val_int()
6688 {
6689 longlong tmp;
6690 evaluate_sideeffects();
6691 tmp= last_value->val_int();
6692 null_value= last_value->null_value;
create_native(THD * thd,LEX_CSTRING * name,List<Item> * item_list)6693 return tmp;
6694 }
6695
6696 double Item_func_last_value::val_real()
6697 {
6698 double tmp;
6699 evaluate_sideeffects();
6700 tmp= last_value->val_real();
6701 null_value= last_value->null_value;
6702 return tmp;
6703 }
6704
6705 my_decimal *Item_func_last_value::val_decimal(my_decimal *decimal_value)
6706 {
6707 my_decimal *tmp;
6708 evaluate_sideeffects();
6709 tmp= last_value->val_decimal(decimal_value);
6710 null_value= last_value->null_value;
6711 return tmp;
6712 }
6713
6714
6715 bool Item_func_last_value::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
6716 {
6717 evaluate_sideeffects();
6718 bool tmp= last_value->get_date(ltime, fuzzydate);
6719 null_value= last_value->null_value;
6720 return tmp;
6721 }
6722
6723
6724 bool Item_func_last_value::fix_length_and_dec()
6725 {
6726 last_value= args[arg_count -1];
create_2_arg(THD * thd,Item * arg1,Item * arg2)6727 Type_std_attributes::set(last_value);
6728 maybe_null= last_value->maybe_null;
6729 return FALSE;
6730 }
6731
6732
6733 void Cursor_ref::print_func(String *str, const char *func_name)
6734 {
6735 append_identifier(current_thd, str, &m_cursor_name);
create_1_arg(THD * thd,Item * arg1)6736 str->append(func_name);
6737 }
6738
6739
6740 sp_cursor *Cursor_ref::get_open_cursor_or_error()
6741 {
6742 THD *thd= current_thd;
6743 sp_cursor *c= thd->spcont->get_cursor(m_cursor_offset);
6744 DBUG_ASSERT(c);
create_2_arg(THD * thd,Item * arg1,Item * arg2)6745 if (!c/*safety*/ || !c->is_open())
6746 {
6747 my_message(ER_SP_CURSOR_NOT_OPEN, ER_THD(thd, ER_SP_CURSOR_NOT_OPEN),
6748 MYF(0));
6749 return NULL;
6750 }
6751 return c;
6752 }
6753
create_1_arg(THD * thd,Item * arg1)6754
6755 longlong Item_func_cursor_isopen::val_int()
6756 {
6757 sp_cursor *c= current_thd->spcont->get_cursor(m_cursor_offset);
6758 DBUG_ASSERT(c != NULL);
6759 return c ? c->is_open() : 0;
6760 }
6761
6762
create_2_arg(THD * thd,Item * arg1,Item * arg2)6763 longlong Item_func_cursor_found::val_int()
6764 {
6765 sp_cursor *c= get_open_cursor_or_error();
6766 return !(null_value= (!c || c->fetch_count() == 0)) && c->found();
6767 }
6768
6769
6770 longlong Item_func_cursor_notfound::val_int()
6771 {
create_1_arg(THD * thd,Item * arg1)6772 sp_cursor *c= get_open_cursor_or_error();
6773 return !(null_value= (!c || c->fetch_count() == 0)) && !c->found();
6774 }
6775
6776
6777 longlong Item_func_cursor_rowcount::val_int()
6778 {
6779 sp_cursor *c= get_open_cursor_or_error();
6780 return !(null_value= !c) ? c->row_count() : 0;
create_1_arg(THD * thd,Item * arg1)6781 }
6782
6783 /*****************************************************************************
6784 SEQUENCE functions
6785 *****************************************************************************/
6786
6787 longlong Item_func_nextval::val_int()
6788 {
6789 longlong value;
6790 int error;
6791 const char *key;
6792 uint length= get_table_def_key(table_list, &key);
6793 THD *thd;
6794 SEQUENCE_LAST_VALUE *entry;
6795 char buff[80];
6796 String key_buff(buff,sizeof(buff), &my_charset_bin);
6797 DBUG_ENTER("Item_func_nextval::val_int");
6798 update_table();
6799 DBUG_ASSERT(table && table->s->sequence);
6800 thd= table->in_use;
6801
6802 if (thd->count_cuted_fields == CHECK_FIELD_EXPRESSION)
6803 {
6804 /* Alter table checking if function works */
6805 null_value= 0;
6806 DBUG_RETURN(0);
6807 }
6808
6809 if (table->s->tmp_table != NO_TMP_TABLE)
6810 {
6811 /*
6812 Temporary tables has an extra \0 at end to distinguish it from
6813 normal tables
6814 */
6815 key_buff.copy(key, length, &my_charset_bin);
6816 key_buff.append((char) 0);
6817 key= key_buff.ptr();
6818 length++;
6819 }
6820
6821 if (!(entry= ((SEQUENCE_LAST_VALUE*)
6822 my_hash_search(&thd->sequences, (uchar*) key, length))))
6823 {
6824 if (!(key= (char*) my_memdup(key, length, MYF(MY_WME))) ||
6825 !(entry= new SEQUENCE_LAST_VALUE((uchar*) key, length)))
6826 {
6827 /* EOM, error given */
6828 my_free((char*) key);
6829 delete entry;
6830 null_value= 1;
6831 DBUG_RETURN(0);
6832 }
6833 if (my_hash_insert(&thd->sequences, (uchar*) entry))
6834 {
6835 /* EOM, error given */
6836 delete entry;
6837 null_value= 1;
6838 DBUG_RETURN(0);
6839 }
6840 }
6841 entry->null_value= null_value= 0;
6842 value= table->s->sequence->next_value(table, 0, &error);
6843 entry->value= value;
6844 entry->set_version(table);
6845
6846 if (unlikely(error)) // Warning already printed
6847 entry->null_value= null_value= 1; // For not strict mode
6848 DBUG_RETURN(value);
6849 }
6850
6851
6852 /* Print for nextval and lastval */
6853
6854 void Item_func_nextval::print(String *str, enum_query_type query_type)
6855 {
6856 char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME];
6857 LEX_CSTRING d_name= table_list->db;
6858 LEX_CSTRING t_name= table_list->table_name;
6859 bool use_db_name= d_name.str && d_name.str[0];
6860 THD *thd= current_thd; // Don't trust 'table'
6861
6862 str->append(func_name());
6863 str->append('(');
6864
6865 /*
6866 for next_val we assume that table_list has been updated to contain
6867 the current db.
6868 */
6869
6870 if (lower_case_table_names > 0)
6871 {
6872 strmake(t_name_buff, t_name.str, MAX_ALIAS_NAME-1);
6873 t_name.length= my_casedn_str(files_charset_info, t_name_buff);
6874 t_name.str= t_name_buff;
6875 if (use_db_name)
6876 {
6877 strmake(d_name_buff, d_name.str, MAX_ALIAS_NAME-1);
6878 d_name.length= my_casedn_str(files_charset_info, d_name_buff);
6879 d_name.str= d_name_buff;
6880 }
6881 }
6882
create_builder(THD * thd)6883 if (use_db_name)
6884 {
6885 append_identifier(thd, str, &d_name);
6886 str->append('.');
6887 }
6888 append_identifier(thd, str, &t_name);
6889 str->append(')');
6890 }
6891
6892
6893 /* Return last used value for sequence or NULL if sequence hasn't been used */
6894
create_builder(THD * thd)6895 longlong Item_func_lastval::val_int()
6896 {
6897 const char *key;
6898 SEQUENCE_LAST_VALUE *entry;
6899 uint length= get_table_def_key(table_list, &key);
6900 THD *thd;
6901 char buff[80];
6902 String key_buff(buff,sizeof(buff), &my_charset_bin);
6903 DBUG_ENTER("Item_func_lastval::val_int");
6904 update_table();
6905 thd= table->in_use;
6906
6907 if (table->s->tmp_table != NO_TMP_TABLE)
6908 {
6909 /*
6910 Temporary tables has an extra \0 at end to distinguish it from
6911 normal tables
6912 */
6913 key_buff.copy(key, length, &my_charset_bin);
6914 key_buff.append((char) 0);
6915 key= key_buff.ptr();
6916 length++;
6917 }
6918
6919 if (!(entry= ((SEQUENCE_LAST_VALUE*)
6920 my_hash_search(&thd->sequences, (uchar*) key, length))))
6921 {
6922 /* Sequence not used */
6923 null_value= 1;
6924 DBUG_RETURN(0);
6925 }
6926 if (entry->check_version(table))
6927 {
6928 /* Table droped and re-created, remove current version */
6929 my_hash_delete(&thd->sequences, (uchar*) entry);
6930 null_value= 1;
6931 DBUG_RETURN(0);
6932 }
6933
6934 null_value= entry->null_value;
6935 DBUG_RETURN(entry->value);
6936 }
6937
6938
6939 /*
6940 Sets next value to be returned from sequences
create_2_arg(THD * thd,Item * arg1,Item * arg2)6941
6942 SELECT setval(foo, 42, 0); Next nextval will return 43
6943 SELECT setval(foo, 42, 0, true); Same as above
6944 SELECT setval(foo, 42, 0, false); Next nextval will return 42
6945 */
6946
6947 longlong Item_func_setval::val_int()
6948 {
6949 longlong value;
6950 int error;
6951 THD *thd;
6952 DBUG_ENTER("Item_func_setval::val_int");
6953
6954 update_table();
6955 DBUG_ASSERT(table && table->s->sequence);
6956 thd= table->in_use;
6957
6958 if (unlikely(thd->count_cuted_fields == CHECK_FIELD_EXPRESSION))
6959 {
6960 /* Alter table checking if function works */
6961 null_value= 0;
6962 DBUG_RETURN(0);
6963 }
6964
6965 value= nextval;
6966 error= table->s->sequence->set_value(table, nextval, round, is_used);
6967 if (unlikely(error))
6968 {
6969 null_value= 1;
6970 value= 0;
6971 }
6972 DBUG_RETURN(value);
6973 }
6974
6975
6976 /* Print for setval */
6977
6978 void Item_func_setval::print(String *str, enum_query_type query_type)
6979 {
6980 char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME];
6981 LEX_CSTRING d_name= table_list->db;
create_3_arg(THD * thd,Item * arg1,Item * arg2,Item * arg3)6982 LEX_CSTRING t_name= table_list->table_name;
6983 bool use_db_name= d_name.str && d_name.str[0];
6984 THD *thd= current_thd; // Don't trust 'table'
6985
6986 str->append(func_name());
6987 str->append('(');
6988
6989 /*
6990 for next_val we assume that table_list has been updated to contain
6991 the current db.
create_1_arg(THD * thd,Item * arg1)6992 */
6993
6994 if (lower_case_table_names > 0)
6995 {
6996 strmake(t_name_buff, t_name.str, MAX_ALIAS_NAME-1);
6997 t_name.length= my_casedn_str(files_charset_info, t_name_buff);
6998 t_name.str= t_name_buff;
6999 if (use_db_name)
7000 {
7001 strmake(d_name_buff, d_name.str, MAX_ALIAS_NAME-1);
7002 d_name.length= my_casedn_str(files_charset_info, d_name_buff);
7003 d_name.str= d_name_buff;
7004 }
7005 }
7006
7007 if (use_db_name)
7008 {
7009 append_identifier(thd, str, &d_name);
7010 str->append('.');
7011 }
7012 append_identifier(thd, str, &t_name);
7013 str->append(',');
7014 str->append_longlong(nextval);
7015 str->append(',');
7016 str->append_longlong(is_used);
7017 str->append(',');
7018 str->append_ulonglong(round);
7019 str->append(')');
7020 }
7021