1 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
2 Copyright (c) 2009, 2019, 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 Street, Fifth Floor, Boston, MA 02110-1335 USA */
16
17
18 /**
19 @file
20
21 @brief
22 This file defines all compare functions
23 */
24
25 #ifdef USE_PRAGMA_IMPLEMENTATION
26 #pragma implementation // gcc: Class implementation
27 #endif
28
29 #include "mariadb.h"
30 #include "sql_priv.h"
31 #include <m_ctype.h>
32 #include "sql_select.h"
33 #include "sql_parse.h" // check_stack_overrun
34 #include "sql_time.h" // make_truncated_value_warning
35 #include "sql_base.h" // dynamic_column_error_message
36
37 /**
38 find an temporal type (item) that others will be converted to
39 for the purpose of comparison.
40
41 this is the type that will be used in warnings like
42 "Incorrect <<TYPE>> value".
43 */
find_date_time_item(Item ** args,uint nargs,uint col)44 static Item *find_date_time_item(Item **args, uint nargs, uint col)
45 {
46 Item *date_arg= 0, **arg, **arg_end;
47 for (arg= args, arg_end= args + nargs; arg != arg_end ; arg++)
48 {
49 Item *item= arg[0]->element_index(col);
50 if (item->cmp_type() != TIME_RESULT)
51 continue;
52 if (item->field_type() == MYSQL_TYPE_DATETIME)
53 return item;
54 if (!date_arg)
55 date_arg= item;
56 }
57 return date_arg;
58 }
59
60
61 /*
62 Compare row signature of two expressions
63
64 SYNOPSIS:
65 cmp_row_type()
66 item1 the first expression
67 item2 the second expression
68
69 DESCRIPTION
70 The function checks that two expressions have compatible row signatures
71 i.e. that the number of columns they return are the same and that if they
72 are both row expressions then each component from the first expression has
73 a row signature compatible with the signature of the corresponding component
74 of the second expression.
75
76 RETURN VALUES
77 1 type incompatibility has been detected
78 0 otherwise
79 */
80
cmp_row_type(Item * item1,Item * item2)81 static int cmp_row_type(Item* item1, Item* item2)
82 {
83 uint n= item1->cols();
84 if (item2->check_cols(n))
85 return 1;
86 for (uint i=0; i<n; i++)
87 {
88 if (item2->element_index(i)->check_cols(item1->element_index(i)->cols()) ||
89 (item1->element_index(i)->result_type() == ROW_RESULT &&
90 cmp_row_type(item1->element_index(i), item2->element_index(i))))
91 return 1;
92 }
93 return 0;
94 }
95
96
97 /**
98 Aggregates result types from the array of items.
99
100 This method aggregates comparison handler from the array of items.
101 The result handler is used later for comparison of values of these items.
102
103 aggregate_for_comparison()
104 funcname the function or operator name,
105 for error reporting
106 items array of items to aggregate the type from
107 nitems number of items in the array
108 int_uint_as_dec what to do when comparing INT to UINT:
109 set the comparison handler to decimal or int.
110
111 @retval true type incompatibility has been detected
112 @retval false otherwise
113 */
114
115 bool
aggregate_for_comparison(const char * funcname,Item ** items,uint nitems,bool int_uint_as_dec)116 Type_handler_hybrid_field_type::aggregate_for_comparison(const char *funcname,
117 Item **items,
118 uint nitems,
119 bool int_uint_as_dec)
120 {
121 uint unsigned_count= items[0]->unsigned_flag;
122 /*
123 Convert sub-type to super-type (e.g. DATE to DATETIME, INT to BIGINT, etc).
124 Otherwise Predicant_to_list_comparator will treat sub-types of the same
125 super-type as different data types and won't be able to use bisection in
126 many cases.
127 */
128 set_handler(items[0]->type_handler()->type_handler_for_comparison());
129 for (uint i= 1 ; i < nitems ; i++)
130 {
131 unsigned_count+= items[i]->unsigned_flag;
132 if (aggregate_for_comparison(items[i]->type_handler()->
133 type_handler_for_comparison()))
134 {
135 /*
136 For more precise error messages if aggregation failed on the first pair
137 {items[0],items[1]}, use the name of items[0]->data_handler().
138 Otherwise use the name of this->type_handler(), which is already a
139 result of aggregation for items[0]..items[i-1].
140 */
141 my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
142 i == 1 ? items[0]->type_handler()->name().ptr() :
143 type_handler()->name().ptr(),
144 items[i]->type_handler()->name().ptr(),
145 funcname);
146 return true;
147 }
148 /*
149 When aggregating types of two row expressions we have to check
150 that they have the same cardinality and that each component
151 of the first row expression has a compatible row signature with
152 the signature of the corresponding component of the second row
153 expression.
154 */
155 if (cmp_type() == ROW_RESULT && cmp_row_type(items[0], items[i]))
156 return true; // error found: invalid usage of rows
157 }
158 /**
159 If all arguments are of INT type but have different unsigned_flag values,
160 switch to DECIMAL_RESULT.
161 */
162 if (int_uint_as_dec &&
163 cmp_type() == INT_RESULT &&
164 unsigned_count != nitems && unsigned_count != 0)
165 set_handler(&type_handler_newdecimal);
166 return 0;
167 }
168
169
170 /*
171 Collects different types for comparison of first item with each other items
172
173 SYNOPSIS
174 collect_cmp_types()
175 items Array of items to collect types from
176 nitems Number of items in the array
177 skip_nulls Don't collect types of NULL items if TRUE
178
179 DESCRIPTION
180 This function collects different result types for comparison of the first
181 item in the list with each of the remaining items in the 'items' array.
182
183 RETURN
184 0 - if row type incompatibility has been detected (see cmp_row_type)
185 Bitmap of collected types - otherwise
186 */
187
collect_cmp_types(Item ** items,uint nitems,bool skip_nulls=FALSE)188 static uint collect_cmp_types(Item **items, uint nitems, bool skip_nulls= FALSE)
189 {
190 uint i;
191 uint found_types;
192 Item_result left_cmp_type= items[0]->cmp_type();
193 DBUG_ASSERT(nitems > 1);
194 found_types= 0;
195 for (i= 1; i < nitems ; i++)
196 {
197 if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
198 continue; // Skip NULL constant items
199 if ((left_cmp_type == ROW_RESULT ||
200 items[i]->cmp_type() == ROW_RESULT) &&
201 cmp_row_type(items[0], items[i]))
202 return 0;
203 found_types|= 1U << (uint) item_cmp_type(left_cmp_type, items[i]);
204 }
205 /*
206 Even if all right-hand items are NULLs and we are skipping them all, we need
207 at least one type bit in the found_type bitmask.
208 */
209 if (skip_nulls && !found_types)
210 found_types= 1U << (uint) left_cmp_type;
211 return found_types;
212 }
213
214
215 /*
216 Test functions
217 Most of these returns 0LL if false and 1LL if true and
218 NULL if some arg is NULL.
219 */
220
val_int()221 longlong Item_func_not::val_int()
222 {
223 DBUG_ASSERT(fixed == 1);
224 bool value= args[0]->val_bool();
225 null_value=args[0]->null_value;
226 return ((!null_value && value == 0) ? 1 : 0);
227 }
228
print(String * str,enum_query_type query_type)229 void Item_func_not::print(String *str, enum_query_type query_type)
230 {
231 str->append('!');
232 args[0]->print_parenthesised(str, query_type, precedence());
233 }
234
235 /**
236 special NOT for ALL subquery.
237 */
238
239
val_int()240 longlong Item_func_not_all::val_int()
241 {
242 DBUG_ASSERT(fixed == 1);
243 bool value= args[0]->val_bool();
244
245 /*
246 return TRUE if there was records in underlying select in max/min
247 optimization (ALL subquery)
248 */
249 if (empty_underlying_subquery())
250 return 1;
251
252 null_value= args[0]->null_value;
253 return ((!null_value && value == 0) ? 1 : 0);
254 }
255
256
empty_underlying_subquery()257 bool Item_func_not_all::empty_underlying_subquery()
258 {
259 return ((test_sum_item && !test_sum_item->any_value()) ||
260 (test_sub_item && !test_sub_item->any_value()));
261 }
262
print(String * str,enum_query_type query_type)263 void Item_func_not_all::print(String *str, enum_query_type query_type)
264 {
265 if (show)
266 Item_func::print(str, query_type);
267 else
268 args[0]->print(str, query_type);
269 }
270
271
272 /**
273 Special NOP (No OPeration) for ALL subquery. It is like
274 Item_func_not_all.
275
276 @return
277 (return TRUE if underlying subquery do not return rows) but if subquery
278 returns some rows it return same value as argument (TRUE/FALSE).
279 */
280
val_int()281 longlong Item_func_nop_all::val_int()
282 {
283 DBUG_ASSERT(fixed == 1);
284 longlong value= args[0]->val_int();
285
286 /*
287 return FALSE if there was records in underlying select in max/min
288 optimization (SAME/ANY subquery)
289 */
290 if (empty_underlying_subquery())
291 return 0;
292
293 null_value= args[0]->null_value;
294 return (null_value || value == 0) ? 0 : 1;
295 }
296
297
298 /**
299 Convert a constant item to an int and replace the original item.
300
301 The function converts a constant expression or string to an integer.
302 On successful conversion the original item is substituted for the
303 result of the item evaluation.
304 This is done when comparing DATE/TIME of different formats and
305 also when comparing bigint to strings (in which case strings
306 are converted to bigints).
307
308 @param thd thread handle
309 @param field item will be converted using the type of this field
310 @param[in,out] item reference to the item to convert
311
312 @note
313 This function is called only at prepare stage.
314 As all derived tables are filled only after all derived tables
315 are prepared we do not evaluate items with subselects here because
316 they can contain derived tables and thus we may attempt to use a
317 table that has not been populated yet.
318
319 @retval
320 0 Can't convert item
321 @retval
322 1 Item was replaced with an integer version of the item
323 */
324
convert_const_to_int(THD * thd,Item_field * field_item,Item ** item)325 static bool convert_const_to_int(THD *thd, Item_field *field_item,
326 Item **item)
327 {
328 Field *field= field_item->field;
329 int result= 0;
330
331 /*
332 We don't need to convert an integer to an integer,
333 pretend it's already converted.
334
335 But we still convert it if it is compared with a Field_year,
336 as YEAR(2) may change the value of an integer when converting it
337 to an integer (say, 0 to 70).
338 */
339 if ((*item)->cmp_type() == INT_RESULT &&
340 field_item->field_type() != MYSQL_TYPE_YEAR)
341 return 1;
342
343 if ((*item)->const_item() && !(*item)->is_expensive())
344 {
345 TABLE *table= field->table;
346 Sql_mode_save sql_mode(thd);
347 Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
348 MY_BITMAP *old_maps[2] = { NULL, NULL };
349 ulonglong UNINIT_VAR(orig_field_val); /* original field value if valid */
350
351 /* table->read_set may not be set if we come here from a CREATE TABLE */
352 if (table && table->read_set)
353 dbug_tmp_use_all_columns(table, old_maps,
354 &table->read_set, &table->write_set);
355 /* For comparison purposes allow invalid dates like 2000-01-32 */
356 thd->variables.sql_mode= (thd->variables.sql_mode & ~MODE_NO_ZERO_DATE) |
357 MODE_INVALID_DATES;
358
359 /*
360 Store the value of the field/constant because the call to save_in_field
361 below overrides that value. Don't save field value if no data has been
362 read yet.
363 */
364 bool save_field_value= (field_item->const_item() ||
365 !(field->table->status & STATUS_NO_RECORD));
366 if (save_field_value)
367 orig_field_val= field->val_int();
368 if (!(*item)->save_in_field(field, 1) && !field->is_null())
369 {
370 int field_cmp= 0;
371 // If item is a decimal value, we must reject it if it was truncated.
372 if (field->type() == MYSQL_TYPE_LONGLONG)
373 {
374 field_cmp= stored_field_cmp_to_item(thd, field, *item);
375 DBUG_PRINT("info", ("convert_const_to_int %d", field_cmp));
376 }
377
378 if (0 == field_cmp)
379 {
380 Item *tmp= new (thd->mem_root) Item_int_with_ref(thd, field->val_int(), *item,
381 MY_TEST(field->flags & UNSIGNED_FLAG));
382 if (tmp)
383 thd->change_item_tree(item, tmp);
384 result= 1; // Item was replaced
385 }
386 }
387 /* Restore the original field value. */
388 if (save_field_value)
389 {
390 result= field->store(orig_field_val, TRUE);
391 /* orig_field_val must be a valid value that can be restored back. */
392 DBUG_ASSERT(!result);
393 }
394 if (table && table->read_set)
395 dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_maps);
396 }
397 return result;
398 }
399
400
401 /*
402 Make a special case of compare with fields to get nicer comparisons
403 of bigint numbers with constant string.
404 This directly contradicts the manual (number and a string should
405 be compared as doubles), but seems to provide more
406 "intuitive" behavior in some cases (but less intuitive in others).
407 */
convert_const_compared_to_int_field(THD * thd)408 void Item_func::convert_const_compared_to_int_field(THD *thd)
409 {
410 DBUG_ASSERT(arg_count >= 2); // Item_func_nullif has arg_count == 3
411 if (!thd->lex->is_ps_or_view_context_analysis())
412 {
413 int field;
414 if (args[field= 0]->real_item()->type() == FIELD_ITEM ||
415 args[field= 1]->real_item()->type() == FIELD_ITEM)
416 {
417 Item_field *field_item= (Item_field*) (args[field]->real_item());
418 if (((field_item->field_type() == MYSQL_TYPE_LONGLONG &&
419 field_item->type_handler() != &type_handler_vers_trx_id) ||
420 field_item->field_type() == MYSQL_TYPE_YEAR))
421 convert_const_to_int(thd, field_item, &args[!field]);
422 }
423 }
424 }
425
426
setup_args_and_comparator(THD * thd,Arg_comparator * cmp)427 bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp)
428 {
429 DBUG_ASSERT(arg_count >= 2); // Item_func_nullif has arg_count == 3
430
431 if (args[0]->cmp_type() == STRING_RESULT &&
432 args[1]->cmp_type() == STRING_RESULT)
433 {
434 DTCollation tmp;
435 if (agg_arg_charsets_for_comparison(tmp, args, 2))
436 return true;
437 cmp->m_compare_collation= tmp.collation;
438 }
439 // Convert constants when compared to int/year field
440 DBUG_ASSERT(functype() != LIKE_FUNC);
441 convert_const_compared_to_int_field(thd);
442
443 return cmp->set_cmp_func(this, &args[0], &args[1], true);
444 }
445
446
447 /*
448 Comparison operators remove arguments' dependency on PAD_CHAR_TO_FULL_LENGTH
449 in case of PAD SPACE comparison collations: trailing spaces do not affect
450 the comparison result for such collations.
451 */
452 Sql_mode_dependency
value_depends_on_sql_mode() const453 Item_bool_rowready_func2::value_depends_on_sql_mode() const
454 {
455 if (compare_collation()->state & MY_CS_NOPAD)
456 return Item_func::value_depends_on_sql_mode();
457 return ((args[0]->value_depends_on_sql_mode() |
458 args[1]->value_depends_on_sql_mode()) &
459 Sql_mode_dependency(~0, ~MODE_PAD_CHAR_TO_FULL_LENGTH)).
460 soft_to_hard();
461 }
462
463
fix_length_and_dec()464 bool Item_bool_rowready_func2::fix_length_and_dec()
465 {
466 max_length= 1; // Function returns 0 or 1
467
468 /*
469 As some compare functions are generated after sql_yacc,
470 we have to check for out of memory conditions here
471 */
472 if (!args[0] || !args[1])
473 return FALSE;
474 return setup_args_and_comparator(current_thd, &cmp);
475 }
476
477
478 /**
479 Prepare the comparator (set the comparison function) for comparing
480 items *a1 and *a2 in the context of 'type'.
481
482 @param[in] owner_arg Item, peforming the comparison (e.g. Item_func_eq)
483 @param[in,out] a1 first argument to compare
484 @param[in,out] a2 second argument to compare
485 @param[in] type type context to compare in
486
487 Both *a1 and *a2 can be replaced by this method - typically by constant
488 items, holding the cached converted value of the original (constant) item.
489 */
490
set_cmp_func(Item_func_or_sum * owner_arg,Item ** a1,Item ** a2)491 int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
492 Item **a1, Item **a2)
493 {
494 owner= owner_arg;
495 set_null= set_null && owner_arg;
496 a= a1;
497 b= a2;
498 Item *tmp_args[2]= {*a1, *a2};
499 Type_handler_hybrid_field_type tmp;
500 if (tmp.aggregate_for_comparison(owner_arg->func_name(), tmp_args, 2, false))
501 {
502 DBUG_ASSERT(current_thd->is_error());
503 return 1;
504 }
505 m_compare_handler= tmp.type_handler();
506 return m_compare_handler->set_comparator_func(this);
507 }
508
509
set_cmp_func_for_row_arguments()510 bool Arg_comparator::set_cmp_func_for_row_arguments()
511 {
512 uint n= (*a)->cols();
513 if (n != (*b)->cols())
514 {
515 my_error(ER_OPERAND_COLUMNS, MYF(0), n);
516 comparators= 0;
517 return true;
518 }
519 if (!(comparators= new Arg_comparator[n]))
520 return true;
521 for (uint i=0; i < n; i++)
522 {
523 if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
524 {
525 my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
526 return true;
527 }
528 if (comparators[i].set_cmp_func(owner, (*a)->addr(i),
529 (*b)->addr(i), set_null))
530 return true;
531 }
532 return false;
533 }
534
535
set_cmp_func_row()536 bool Arg_comparator::set_cmp_func_row()
537 {
538 func= is_owner_equal_func() ? &Arg_comparator::compare_e_row :
539 &Arg_comparator::compare_row;
540 return set_cmp_func_for_row_arguments();
541 }
542
543
set_cmp_func_string()544 bool Arg_comparator::set_cmp_func_string()
545 {
546 THD *thd= current_thd;
547 func= is_owner_equal_func() ? &Arg_comparator::compare_e_string :
548 &Arg_comparator::compare_string;
549 if (compare_type() == STRING_RESULT &&
550 (*a)->result_type() == STRING_RESULT &&
551 (*b)->result_type() == STRING_RESULT)
552 {
553 /*
554 We must set cmp_collation here as we may be called from for an automatic
555 generated item, like in natural join
556 */
557 if (owner->agg_arg_charsets_for_comparison(&m_compare_collation, a, b))
558 return true;
559
560 if ((*a)->type() == Item::FUNC_ITEM &&
561 ((Item_func *) (*a))->functype() == Item_func::JSON_EXTRACT_FUNC)
562 {
563 func= is_owner_equal_func() ? &Arg_comparator::compare_e_json_str:
564 &Arg_comparator::compare_json_str;
565 return 0;
566 }
567 else if ((*b)->type() == Item::FUNC_ITEM &&
568 ((Item_func *) (*b))->functype() == Item_func::JSON_EXTRACT_FUNC)
569 {
570 func= is_owner_equal_func() ? &Arg_comparator::compare_e_json_str:
571 &Arg_comparator::compare_str_json;
572 return 0;
573 }
574 }
575
576 a= cache_converted_constant(thd, a, &a_cache, compare_type_handler());
577 b= cache_converted_constant(thd, b, &b_cache, compare_type_handler());
578 return false;
579 }
580
581
set_cmp_func_time()582 bool Arg_comparator::set_cmp_func_time()
583 {
584 THD *thd= current_thd;
585 m_compare_collation= &my_charset_numeric;
586 func= is_owner_equal_func() ? &Arg_comparator::compare_e_time :
587 &Arg_comparator::compare_time;
588 a= cache_converted_constant(thd, a, &a_cache, compare_type_handler());
589 b= cache_converted_constant(thd, b, &b_cache, compare_type_handler());
590 return false;
591 }
592
593
set_cmp_func_datetime()594 bool Arg_comparator::set_cmp_func_datetime()
595 {
596 THD *thd= current_thd;
597 m_compare_collation= &my_charset_numeric;
598 func= is_owner_equal_func() ? &Arg_comparator::compare_e_datetime :
599 &Arg_comparator::compare_datetime;
600 a= cache_converted_constant(thd, a, &a_cache, compare_type_handler());
601 b= cache_converted_constant(thd, b, &b_cache, compare_type_handler());
602 return false;
603 }
604
605
set_cmp_func_int()606 bool Arg_comparator::set_cmp_func_int()
607 {
608 THD *thd= current_thd;
609 func= is_owner_equal_func() ? &Arg_comparator::compare_e_int :
610 &Arg_comparator::compare_int_signed;
611 if ((*a)->field_type() == MYSQL_TYPE_YEAR &&
612 (*b)->field_type() == MYSQL_TYPE_YEAR)
613 {
614 func= is_owner_equal_func() ? &Arg_comparator::compare_e_datetime :
615 &Arg_comparator::compare_datetime;
616 }
617 else if (func == &Arg_comparator::compare_int_signed)
618 {
619 if ((*a)->unsigned_flag)
620 func= (((*b)->unsigned_flag)?
621 &Arg_comparator::compare_int_unsigned :
622 &Arg_comparator::compare_int_unsigned_signed);
623 else if ((*b)->unsigned_flag)
624 func= &Arg_comparator::compare_int_signed_unsigned;
625 }
626 else if (func== &Arg_comparator::compare_e_int)
627 {
628 if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
629 func= &Arg_comparator::compare_e_int_diff_signedness;
630 }
631 a= cache_converted_constant(thd, a, &a_cache, compare_type_handler());
632 b= cache_converted_constant(thd, b, &b_cache, compare_type_handler());
633 return false;
634 }
635
636
set_cmp_func_real()637 bool Arg_comparator::set_cmp_func_real()
638 {
639 if ((((*a)->result_type() == DECIMAL_RESULT && !(*a)->const_item() &&
640 (*b)->result_type() == STRING_RESULT && (*b)->const_item()) ||
641 ((*b)->result_type() == DECIMAL_RESULT && !(*b)->const_item() &&
642 (*a)->result_type() == STRING_RESULT && (*a)->const_item())))
643 {
644 /*
645 <non-const decimal expression> <cmp> <const string expression>
646 or
647 <const string expression> <cmp> <non-const decimal expression>
648
649 Do comparison as decimal rather than float, in order not to lose precision.
650 */
651 m_compare_handler= &type_handler_newdecimal;
652 return set_cmp_func_decimal();
653 }
654
655 THD *thd= current_thd;
656 func= is_owner_equal_func() ? &Arg_comparator::compare_e_real :
657 &Arg_comparator::compare_real;
658 if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
659 {
660 precision= 5 / log_10[MY_MAX((*a)->decimals, (*b)->decimals) + 1];
661 if (func == &Arg_comparator::compare_real)
662 func= &Arg_comparator::compare_real_fixed;
663 else if (func == &Arg_comparator::compare_e_real)
664 func= &Arg_comparator::compare_e_real_fixed;
665 }
666 a= cache_converted_constant(thd, a, &a_cache, compare_type_handler());
667 b= cache_converted_constant(thd, b, &b_cache, compare_type_handler());
668 return false;
669 }
670
set_cmp_func_decimal()671 bool Arg_comparator::set_cmp_func_decimal()
672 {
673 THD *thd= current_thd;
674 func= is_owner_equal_func() ? &Arg_comparator::compare_e_decimal :
675 &Arg_comparator::compare_decimal;
676 a= cache_converted_constant(thd, a, &a_cache, compare_type_handler());
677 b= cache_converted_constant(thd, b, &b_cache, compare_type_handler());
678 return false;
679 }
680
681
682 /**
683 Convert and cache a constant.
684
685 @param value [in] An item to cache
686 @param cache_item [out] Placeholder for the cache item
687 @param type [in] Comparison type
688
689 @details
690 When given item is a constant and its type differs from comparison type
691 then cache its value to avoid type conversion of this constant on each
692 evaluation. In this case the value is cached and the reference to the cache
693 is returned.
694 Original value is returned otherwise.
695
696 @return cache item or original value.
697 */
698
cache_converted_constant(THD * thd_arg,Item ** value,Item ** cache_item,const Type_handler * handler)699 Item** Arg_comparator::cache_converted_constant(THD *thd_arg, Item **value,
700 Item **cache_item,
701 const Type_handler *handler)
702 {
703 /*
704 Don't need cache if doing context analysis only.
705 */
706 if (!thd_arg->lex->is_ps_or_view_context_analysis() &&
707 (*value)->const_item() &&
708 handler->type_handler_for_comparison() !=
709 (*value)->type_handler_for_comparison())
710 {
711 Item_cache *cache= handler->Item_get_cache(thd_arg, *value);
712 cache->setup(thd_arg, *value);
713 *cache_item= cache;
714 return cache_item;
715 }
716 return value;
717 }
718
719
compare_time()720 int Arg_comparator::compare_time()
721 {
722 longlong val1= (*a)->val_time_packed();
723 if (!(*a)->null_value)
724 {
725 longlong val2= (*b)->val_time_packed();
726 if (!(*b)->null_value)
727 return compare_not_null_values(val1, val2);
728 }
729 if (set_null)
730 owner->null_value= true;
731 return -1;
732 }
733
734
compare_e_time()735 int Arg_comparator::compare_e_time()
736 {
737 longlong val1= (*a)->val_time_packed();
738 longlong val2= (*b)->val_time_packed();
739 if ((*a)->null_value || (*b)->null_value)
740 return MY_TEST((*a)->null_value && (*b)->null_value);
741 return MY_TEST(val1 == val2);
742 }
743
744
745
compare_datetime()746 int Arg_comparator::compare_datetime()
747 {
748 longlong val1= (*a)->val_datetime_packed();
749 if (!(*a)->null_value)
750 {
751 longlong val2= (*b)->val_datetime_packed();
752 if (!(*b)->null_value)
753 return compare_not_null_values(val1, val2);
754 }
755 if (set_null)
756 owner->null_value= true;
757 return -1;
758 }
759
760
compare_e_datetime()761 int Arg_comparator::compare_e_datetime()
762 {
763 longlong val1= (*a)->val_datetime_packed();
764 longlong val2= (*b)->val_datetime_packed();
765 if ((*a)->null_value || (*b)->null_value)
766 return MY_TEST((*a)->null_value && (*b)->null_value);
767 return MY_TEST(val1 == val2);
768 }
769
770
compare_string()771 int Arg_comparator::compare_string()
772 {
773 String *res1,*res2;
774 if ((res1= (*a)->val_str(&value1)))
775 {
776 if ((res2= (*b)->val_str(&value2)))
777 {
778 if (set_null)
779 owner->null_value= 0;
780 return sortcmp(res1, res2, compare_collation());
781 }
782 }
783 if (set_null)
784 owner->null_value= 1;
785 return -1;
786 }
787
788
789 /**
790 Compare strings, but take into account that NULL == NULL.
791 */
792
793
compare_e_string()794 int Arg_comparator::compare_e_string()
795 {
796 String *res1,*res2;
797 res1= (*a)->val_str(&value1);
798 res2= (*b)->val_str(&value2);
799 if (!res1 || !res2)
800 return MY_TEST(res1 == res2);
801 return MY_TEST(sortcmp(res1, res2, compare_collation()) == 0);
802 }
803
804
compare_real()805 int Arg_comparator::compare_real()
806 {
807 /*
808 Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
809 gcc to flush double values out of 80-bit Intel FPU registers before
810 performing the comparison.
811 */
812 volatile double val1, val2;
813 val1= (*a)->val_real();
814 if (!(*a)->null_value)
815 {
816 val2= (*b)->val_real();
817 if (!(*b)->null_value)
818 {
819 if (set_null)
820 owner->null_value= 0;
821 if (val1 < val2) return -1;
822 if (val1 == val2) return 0;
823 return 1;
824 }
825 }
826 if (set_null)
827 owner->null_value= 1;
828 return -1;
829 }
830
compare_decimal()831 int Arg_comparator::compare_decimal()
832 {
833 my_decimal decimal1;
834 my_decimal *val1= (*a)->val_decimal(&decimal1);
835 if (!(*a)->null_value)
836 {
837 my_decimal decimal2;
838 my_decimal *val2= (*b)->val_decimal(&decimal2);
839 if (!(*b)->null_value)
840 {
841 if (set_null)
842 owner->null_value= 0;
843 my_decimal_round_if_needed(E_DEC_FATAL_ERROR, val1, (*a)->decimals, 0);
844 my_decimal_round_if_needed(E_DEC_FATAL_ERROR, val2, (*b)->decimals, 0);
845 return my_decimal_cmp(val1, val2);
846 }
847 }
848 if (set_null)
849 owner->null_value= 1;
850 return -1;
851 }
852
compare_e_real()853 int Arg_comparator::compare_e_real()
854 {
855 double val1= (*a)->val_real();
856 double val2= (*b)->val_real();
857 if ((*a)->null_value || (*b)->null_value)
858 return MY_TEST((*a)->null_value && (*b)->null_value);
859 return MY_TEST(val1 == val2);
860 }
861
compare_e_decimal()862 int Arg_comparator::compare_e_decimal()
863 {
864 my_decimal decimal1, decimal2;
865 my_decimal *val1= (*a)->val_decimal(&decimal1);
866 my_decimal *val2= (*b)->val_decimal(&decimal2);
867 if ((*a)->null_value || (*b)->null_value)
868 return MY_TEST((*a)->null_value && (*b)->null_value);
869 my_decimal_round_if_needed(E_DEC_FATAL_ERROR, val1, (*a)->decimals, 0);
870 my_decimal_round_if_needed(E_DEC_FATAL_ERROR, val2, (*b)->decimals, 0);
871 return my_decimal_cmp(val1, val2) == 0;
872 }
873
874
compare_real_fixed()875 int Arg_comparator::compare_real_fixed()
876 {
877 /*
878 Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
879 gcc to flush double values out of 80-bit Intel FPU registers before
880 performing the comparison.
881 */
882 volatile double val1, val2;
883 val1= (*a)->val_real();
884 if (!(*a)->null_value)
885 {
886 val2= (*b)->val_real();
887 if (!(*b)->null_value)
888 {
889 if (set_null)
890 owner->null_value= 0;
891 if (val1 == val2 || fabs(val1 - val2) < precision)
892 return 0;
893 if (val1 < val2)
894 return -1;
895 return 1;
896 }
897 }
898 if (set_null)
899 owner->null_value= 1;
900 return -1;
901 }
902
903
compare_e_real_fixed()904 int Arg_comparator::compare_e_real_fixed()
905 {
906 double val1= (*a)->val_real();
907 double val2= (*b)->val_real();
908 if ((*a)->null_value || (*b)->null_value)
909 return MY_TEST((*a)->null_value && (*b)->null_value);
910 return MY_TEST(val1 == val2 || fabs(val1 - val2) < precision);
911 }
912
913
compare_int_signed()914 int Arg_comparator::compare_int_signed()
915 {
916 longlong val1= (*a)->val_int();
917 if (!(*a)->null_value)
918 {
919 longlong val2= (*b)->val_int();
920 if (!(*b)->null_value)
921 return compare_not_null_values(val1, val2);
922 }
923 if (set_null)
924 owner->null_value= 1;
925 return -1;
926 }
927
928
929 /**
930 Compare values as BIGINT UNSIGNED.
931 */
932
compare_int_unsigned()933 int Arg_comparator::compare_int_unsigned()
934 {
935 ulonglong val1= (*a)->val_int();
936 if (!(*a)->null_value)
937 {
938 ulonglong val2= (*b)->val_int();
939 if (!(*b)->null_value)
940 {
941 if (set_null)
942 owner->null_value= 0;
943 if (val1 < val2) return -1;
944 if (val1 == val2) return 0;
945 return 1;
946 }
947 }
948 if (set_null)
949 owner->null_value= 1;
950 return -1;
951 }
952
953
954 /**
955 Compare signed (*a) with unsigned (*B)
956 */
957
compare_int_signed_unsigned()958 int Arg_comparator::compare_int_signed_unsigned()
959 {
960 longlong sval1= (*a)->val_int();
961 if (!(*a)->null_value)
962 {
963 ulonglong uval2= (ulonglong)(*b)->val_int();
964 if (!(*b)->null_value)
965 {
966 if (set_null)
967 owner->null_value= 0;
968 if (sval1 < 0 || (ulonglong)sval1 < uval2)
969 return -1;
970 if ((ulonglong)sval1 == uval2)
971 return 0;
972 return 1;
973 }
974 }
975 if (set_null)
976 owner->null_value= 1;
977 return -1;
978 }
979
980
981 /**
982 Compare unsigned (*a) with signed (*B)
983 */
984
compare_int_unsigned_signed()985 int Arg_comparator::compare_int_unsigned_signed()
986 {
987 ulonglong uval1= (ulonglong)(*a)->val_int();
988 if (!(*a)->null_value)
989 {
990 longlong sval2= (*b)->val_int();
991 if (!(*b)->null_value)
992 {
993 if (set_null)
994 owner->null_value= 0;
995 if (sval2 < 0)
996 return 1;
997 if (uval1 < (ulonglong)sval2)
998 return -1;
999 if (uval1 == (ulonglong)sval2)
1000 return 0;
1001 return 1;
1002 }
1003 }
1004 if (set_null)
1005 owner->null_value= 1;
1006 return -1;
1007 }
1008
1009
compare_e_int()1010 int Arg_comparator::compare_e_int()
1011 {
1012 longlong val1= (*a)->val_int();
1013 longlong val2= (*b)->val_int();
1014 if ((*a)->null_value || (*b)->null_value)
1015 return MY_TEST((*a)->null_value && (*b)->null_value);
1016 return MY_TEST(val1 == val2);
1017 }
1018
1019 /**
1020 Compare unsigned *a with signed *b or signed *a with unsigned *b.
1021 */
compare_e_int_diff_signedness()1022 int Arg_comparator::compare_e_int_diff_signedness()
1023 {
1024 longlong val1= (*a)->val_int();
1025 longlong val2= (*b)->val_int();
1026 if ((*a)->null_value || (*b)->null_value)
1027 return MY_TEST((*a)->null_value && (*b)->null_value);
1028 return (val1 >= 0) && MY_TEST(val1 == val2);
1029 }
1030
compare_row()1031 int Arg_comparator::compare_row()
1032 {
1033 int res= 0;
1034 bool was_null= 0;
1035 (*a)->bring_value();
1036 (*b)->bring_value();
1037
1038 if ((*a)->null_value || (*b)->null_value)
1039 {
1040 owner->null_value= 1;
1041 return -1;
1042 }
1043
1044 uint n= (*a)->cols();
1045 for (uint i= 0; i<n; i++)
1046 {
1047 res= comparators[i].compare();
1048 /* Aggregate functions don't need special null handling. */
1049 if (owner->null_value && owner->type() == Item::FUNC_ITEM)
1050 {
1051 // NULL was compared
1052 switch (((Item_func*)owner)->functype()) {
1053 case Item_func::NE_FUNC:
1054 break; // NE never aborts on NULL even if abort_on_null is set
1055 case Item_func::LT_FUNC:
1056 case Item_func::LE_FUNC:
1057 case Item_func::GT_FUNC:
1058 case Item_func::GE_FUNC:
1059 return -1; // <, <=, > and >= always fail on NULL
1060 case Item_func::EQ_FUNC:
1061 if (((Item_func_eq*)owner)->abort_on_null)
1062 return -1; // We do not need correct NULL returning
1063 break;
1064 default:
1065 DBUG_ASSERT(0);
1066 break;
1067 }
1068 was_null= 1;
1069 owner->null_value= 0;
1070 res= 0; // continue comparison (maybe we will meet explicit difference)
1071 }
1072 else if (res)
1073 return res;
1074 }
1075 if (was_null)
1076 {
1077 /*
1078 There was NULL(s) in comparison in some parts, but there was no
1079 explicit difference in other parts, so we have to return NULL.
1080 */
1081 owner->null_value= 1;
1082 return -1;
1083 }
1084 return 0;
1085 }
1086
1087
compare_e_row()1088 int Arg_comparator::compare_e_row()
1089 {
1090 (*a)->bring_value();
1091 (*b)->bring_value();
1092 uint n= (*a)->cols();
1093 for (uint i= 0; i<n; i++)
1094 {
1095 if (!comparators[i].compare())
1096 return 0;
1097 }
1098 return 1;
1099 }
1100
1101
compare_json_str()1102 int Arg_comparator::compare_json_str()
1103 {
1104 return compare_json_str_basic(*a, *b);
1105 }
1106
1107
compare_str_json()1108 int Arg_comparator::compare_str_json()
1109 {
1110 return -compare_json_str_basic(*b, *a);
1111 }
1112
1113
compare_e_json_str()1114 int Arg_comparator::compare_e_json_str()
1115 {
1116 return compare_e_json_str_basic(*a, *b);
1117 }
1118
1119
compare_e_str_json()1120 int Arg_comparator::compare_e_str_json()
1121 {
1122 return compare_e_json_str_basic(*b, *a);
1123 }
1124
1125
fix_length_and_dec()1126 bool Item_func_truth::fix_length_and_dec()
1127 {
1128 maybe_null= 0;
1129 null_value= 0;
1130 decimals= 0;
1131 max_length= 1;
1132 return FALSE;
1133 }
1134
1135
print(String * str,enum_query_type query_type)1136 void Item_func_truth::print(String *str, enum_query_type query_type)
1137 {
1138 args[0]->print_parenthesised(str, query_type, precedence());
1139 str->append(STRING_WITH_LEN(" is "));
1140 if (! affirmative)
1141 str->append(STRING_WITH_LEN("not "));
1142 if (value)
1143 str->append(STRING_WITH_LEN("true"));
1144 else
1145 str->append(STRING_WITH_LEN("false"));
1146 }
1147
1148
val_bool()1149 bool Item_func_truth::val_bool()
1150 {
1151 bool val= args[0]->val_bool();
1152 if (args[0]->null_value)
1153 {
1154 /*
1155 NULL val IS {TRUE, FALSE} --> FALSE
1156 NULL val IS NOT {TRUE, FALSE} --> TRUE
1157 */
1158 return (! affirmative);
1159 }
1160
1161 if (affirmative)
1162 {
1163 /* {TRUE, FALSE} val IS {TRUE, FALSE} value */
1164 return (val == value);
1165 }
1166
1167 /* {TRUE, FALSE} val IS NOT {TRUE, FALSE} value */
1168 return (val != value);
1169 }
1170
1171
val_int()1172 longlong Item_func_truth::val_int()
1173 {
1174 return (val_bool() ? 1 : 0);
1175 }
1176
1177
is_top_level_item()1178 bool Item_in_optimizer::is_top_level_item()
1179 {
1180 if (!invisible_mode())
1181 return ((Item_in_subselect *)args[1])->is_top_level_item();
1182 return false;
1183 }
1184
1185
fix_after_pullout(st_select_lex * new_parent,Item ** ref,bool merge)1186 void Item_in_optimizer::fix_after_pullout(st_select_lex *new_parent,
1187 Item **ref, bool merge)
1188 {
1189 DBUG_ASSERT(fixed);
1190 /* This will re-calculate attributes of our Item_in_subselect: */
1191 Item_bool_func::fix_after_pullout(new_parent, ref, merge);
1192
1193 /* Then, re-calculate not_null_tables_cache: */
1194 eval_not_null_tables(NULL);
1195 }
1196
1197
eval_not_null_tables(void * opt_arg)1198 bool Item_in_optimizer::eval_not_null_tables(void *opt_arg)
1199 {
1200 not_null_tables_cache= 0;
1201 if (is_top_level_item())
1202 {
1203 /*
1204 It is possible to determine NULL-rejectedness of the left arguments
1205 of IN only if it is a top-level predicate.
1206 */
1207 not_null_tables_cache= args[0]->not_null_tables();
1208 }
1209 return FALSE;
1210 }
1211
1212
print(String * str,enum_query_type query_type)1213 void Item_in_optimizer::print(String *str, enum_query_type query_type)
1214 {
1215 restore_first_argument();
1216 Item_func::print(str, query_type);
1217 }
1218
1219
1220 /**
1221 "Restore" first argument before fix_fields() call (after it is harmless).
1222
1223 @Note: Main pointer to left part of IN/ALL/ANY subselect is subselect's
1224 lest_expr (see Item_in_optimizer::fix_left) so changes made during
1225 fix_fields will be rolled back there which can make
1226 Item_in_optimizer::args[0] unusable on second execution before fix_left()
1227 call. This call fix the pointer.
1228 */
1229
restore_first_argument()1230 void Item_in_optimizer::restore_first_argument()
1231 {
1232 if (args[1]->type() == Item::SUBSELECT_ITEM &&
1233 ((Item_subselect *)args[1])->is_in_predicate())
1234 {
1235 args[0]= ((Item_in_subselect *)args[1])->left_expr;
1236 }
1237 }
1238
1239
fix_left(THD * thd)1240 bool Item_in_optimizer::fix_left(THD *thd)
1241 {
1242 DBUG_ENTER("Item_in_optimizer::fix_left");
1243 /*
1244 Here we will store pointer on place of main storage of left expression.
1245 For usual IN (ALL/ANY) it is subquery left_expr.
1246 For other cases (MAX/MIN optimization, non-transformed EXISTS (10.0))
1247 it is args[0].
1248 */
1249 Item **ref0= args;
1250 if (args[1]->type() == Item::SUBSELECT_ITEM &&
1251 ((Item_subselect *)args[1])->is_in_predicate())
1252 {
1253 /*
1254 left_expr->fix_fields() may cause left_expr to be substituted for
1255 another item. (e.g. an Item_field may be changed into Item_ref). This
1256 transformation is undone at the end of statement execution (e.g. the
1257 Item_ref is deleted). However, Item_in_optimizer::args[0] may keep
1258 the pointer to the post-transformation item. Because of that, on the
1259 next execution we need to copy args[1]->left_expr again.
1260 */
1261 ref0= &(((Item_in_subselect *)args[1])->left_expr);
1262 args[0]= ((Item_in_subselect *)args[1])->left_expr;
1263 }
1264 if ((*ref0)->fix_fields_if_needed(thd, ref0) ||
1265 (!cache && !(cache= (*ref0)->get_cache(thd))))
1266 DBUG_RETURN(1);
1267 /*
1268 During fix_field() expression could be substituted.
1269 So we copy changes before use
1270 */
1271 if (args[0] != (*ref0))
1272 args[0]= (*ref0);
1273 DBUG_PRINT("info", ("actual fix fields"));
1274
1275 cache->setup(thd, args[0]);
1276 if (cache->cols() == 1)
1277 {
1278 DBUG_ASSERT(args[0]->type() != ROW_ITEM);
1279 /*
1280 Note: there can be cases when used_tables()==0 && !const_item(). See
1281 Item_sum::update_used_tables for details.
1282 */
1283 if ((used_tables_cache= args[0]->used_tables()) || !args[0]->const_item())
1284 cache->set_used_tables(OUTER_REF_TABLE_BIT);
1285 else
1286 cache->set_used_tables(0);
1287 }
1288 else
1289 {
1290 uint n= cache->cols();
1291 for (uint i= 0; i < n; i++)
1292 {
1293 /* Check that the expression (part of row) do not contain a subquery */
1294 if (args[0]->element_index(i)->walk(&Item::is_subquery_processor, 0, 0))
1295 {
1296 my_error(ER_NOT_SUPPORTED_YET, MYF(0),
1297 "SUBQUERY in ROW in left expression of IN/ALL/ANY");
1298 DBUG_RETURN(1);
1299 }
1300 Item *element=args[0]->element_index(i);
1301 if (element->used_tables() || !element->const_item())
1302 {
1303 ((Item_cache *)cache->element_index(i))->
1304 set_used_tables(OUTER_REF_TABLE_BIT);
1305 cache->set_used_tables(OUTER_REF_TABLE_BIT);
1306 }
1307 else
1308 ((Item_cache *)cache->element_index(i))->set_used_tables(0);
1309 }
1310 used_tables_cache= args[0]->used_tables();
1311 }
1312 eval_not_null_tables(NULL);
1313 with_sum_func= args[0]->with_sum_func;
1314 with_param= args[0]->with_param || args[1]->with_param;
1315 with_field= args[0]->with_field;
1316 if ((const_item_cache= args[0]->const_item()))
1317 {
1318 cache->store(args[0]);
1319 cache->cache_value();
1320 }
1321 if (args[1]->fixed)
1322 {
1323 /* to avoid overriding is called to update left expression */
1324 used_tables_and_const_cache_join(args[1]);
1325 with_sum_func= with_sum_func || args[1]->with_sum_func;
1326 }
1327 DBUG_RETURN(0);
1328 }
1329
1330
fix_fields(THD * thd,Item ** ref)1331 bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
1332 {
1333 DBUG_ASSERT(fixed == 0);
1334 Item_subselect *sub= 0;
1335 uint col;
1336
1337 /*
1338 MAX/MIN optimization can convert the subquery into
1339 expr + Item_singlerow_subselect
1340 */
1341 if (args[1]->type() == Item::SUBSELECT_ITEM)
1342 sub= (Item_subselect *)args[1];
1343
1344 if (fix_left(thd))
1345 return TRUE;
1346 if (args[0]->maybe_null)
1347 maybe_null=1;
1348
1349 if (args[1]->fix_fields_if_needed(thd, args + 1))
1350 return TRUE;
1351 if (!invisible_mode() &&
1352 ((sub && ((col= args[0]->cols()) != sub->engine->cols())) ||
1353 (!sub && (args[1]->cols() != (col= 1)))))
1354 {
1355 my_error(ER_OPERAND_COLUMNS, MYF(0), col);
1356 return TRUE;
1357 }
1358 if (args[1]->maybe_null)
1359 maybe_null=1;
1360 m_with_subquery= true;
1361 with_sum_func= with_sum_func || args[1]->with_sum_func;
1362 with_window_func= args[0]->with_window_func;
1363 // The subquery cannot have window functions aggregated in this select
1364 DBUG_ASSERT(!args[1]->with_window_func);
1365 with_field= with_field || args[1]->with_field;
1366 with_param= args[0]->with_param || args[1]->with_param;
1367 used_tables_and_const_cache_join(args[1]);
1368 fixed= 1;
1369 return FALSE;
1370 }
1371
1372 /**
1373 Check if Item_in_optimizer should work as a pass-through item for its
1374 arguments.
1375
1376 @note
1377 Item_in_optimizer should work as pass-through for
1378 - subqueries that were processed by ALL/ANY->MIN/MAX rewrite
1379 - subqueries that were originally EXISTS subqueries (and were coinverted by
1380 the EXISTS->IN rewrite)
1381
1382 When Item_in_optimizer is not not working as a pass-through, it
1383 - caches its "left argument", args[0].
1384 - makes adjustments to subquery item's return value for proper NULL
1385 value handling
1386 */
1387
invisible_mode()1388 bool Item_in_optimizer::invisible_mode()
1389 {
1390 /* MAX/MIN transformed or EXISTS->IN prepared => do nothing */
1391 return (args[1]->type() != Item::SUBSELECT_ITEM ||
1392 ((Item_subselect *)args[1])->substype() ==
1393 Item_subselect::EXISTS_SUBS);
1394 }
1395
1396
1397 /**
1398 Add an expression cache for this subquery if it is needed
1399
1400 @param thd_arg Thread handle
1401
1402 @details
1403 The function checks whether an expression cache is needed for this item
1404 and if if so wraps the item into an item of the class
1405 Item_cache_wrapper with an appropriate expression cache set up there.
1406
1407 @note
1408 used from Item::transform()
1409
1410 @return
1411 new wrapper item if an expression cache is needed,
1412 this item - otherwise
1413 */
1414
expr_cache_insert_transformer(THD * thd,uchar * unused)1415 Item *Item_in_optimizer::expr_cache_insert_transformer(THD *thd, uchar *unused)
1416 {
1417 DBUG_ENTER("Item_in_optimizer::expr_cache_insert_transformer");
1418 DBUG_ASSERT(fixed);
1419
1420 if (invisible_mode())
1421 DBUG_RETURN(this);
1422
1423 if (expr_cache)
1424 DBUG_RETURN(expr_cache);
1425
1426 if (args[1]->expr_cache_is_needed(thd) &&
1427 (expr_cache= set_expr_cache(thd)))
1428 DBUG_RETURN(expr_cache);
1429
1430 DBUG_RETURN(this);
1431 }
1432
1433
1434
1435 /**
1436 Collect and add to the list cache parameters for this Item.
1437
1438 @param parameters The list where to add parameters
1439 */
1440
get_cache_parameters(List<Item> & parameters)1441 void Item_in_optimizer::get_cache_parameters(List<Item> ¶meters)
1442 {
1443 DBUG_ASSERT(fixed);
1444 /* Add left expression to the list of the parameters of the subquery */
1445 if (!invisible_mode())
1446 {
1447 if (args[0]->cols() == 1)
1448 parameters.add_unique(args[0], &cmp_items);
1449 else
1450 {
1451 for (uint i= 0; i < args[0]->cols(); i++)
1452 {
1453 parameters.add_unique(args[0]->element_index(i), &cmp_items);
1454 }
1455 }
1456 }
1457 args[1]->get_cache_parameters(parameters);
1458 }
1459
1460 /**
1461 The implementation of optimized \<outer expression\> [NOT] IN \<subquery\>
1462 predicates. The implementation works as follows.
1463
1464 For the current value of the outer expression
1465
1466 - If it contains only NULL values, the original (before rewrite by the
1467 Item_in_subselect rewrite methods) inner subquery is non-correlated and
1468 was previously executed, there is no need to re-execute it, and the
1469 previous return value is returned.
1470
1471 - If it contains NULL values, check if there is a partial match for the
1472 inner query block by evaluating it. For clarity we repeat here the
1473 transformation previously performed on the sub-query. The expression
1474
1475 <tt>
1476 ( oc_1, ..., oc_n )
1477 \<in predicate\>
1478 ( SELECT ic_1, ..., ic_n
1479 FROM \<table\>
1480 WHERE \<inner where\>
1481 )
1482 </tt>
1483
1484 was transformed into
1485
1486 <tt>
1487 ( oc_1, ..., oc_n )
1488 \<in predicate\>
1489 ( SELECT ic_1, ..., ic_n
1490 FROM \<table\>
1491 WHERE \<inner where\> AND ... ( ic_k = oc_k OR ic_k IS NULL )
1492 HAVING ... NOT ic_k IS NULL
1493 )
1494 </tt>
1495
1496 The evaluation will now proceed according to special rules set up
1497 elsewhere. These rules include:
1498
1499 - The HAVING NOT \<inner column\> IS NULL conditions added by the
1500 aforementioned rewrite methods will detect whether they evaluated (and
1501 rejected) a NULL value and if so, will cause the subquery to evaluate
1502 to NULL.
1503
1504 - The added WHERE and HAVING conditions are present only for those inner
1505 columns that correspond to outer column that are not NULL at the moment.
1506
1507 - If there is an eligible index for executing the subquery, the special
1508 access method "Full scan on NULL key" is employed which ensures that
1509 the inner query will detect if there are NULL values resulting from the
1510 inner query. This access method will quietly resort to table scan if it
1511 needs to find NULL values as well.
1512
1513 - Under these conditions, the sub-query need only be evaluated in order to
1514 find out whether it produced any rows.
1515
1516 - If it did, we know that there was a partial match since there are
1517 NULL values in the outer row expression.
1518
1519 - If it did not, the result is FALSE or UNKNOWN. If at least one of the
1520 HAVING sub-predicates rejected a NULL value corresponding to an outer
1521 non-NULL, and hence the inner query block returns UNKNOWN upon
1522 evaluation, there was a partial match and the result is UNKNOWN.
1523
1524 - If it contains no NULL values, the call is forwarded to the inner query
1525 block.
1526
1527 @see Item_in_subselect::val_bool()
1528 @see Item_is_not_null_test::val_int()
1529 */
1530
val_int()1531 longlong Item_in_optimizer::val_int()
1532 {
1533 bool tmp;
1534 DBUG_ASSERT(fixed == 1);
1535 cache->store(args[0]);
1536 cache->cache_value();
1537 DBUG_ENTER(" Item_in_optimizer::val_int");
1538
1539 if (invisible_mode())
1540 {
1541 longlong res= args[1]->val_int();
1542 null_value= args[1]->null_value;
1543 DBUG_PRINT("info", ("pass trough"));
1544 DBUG_RETURN(res);
1545 }
1546
1547 if (cache->null_value_inside)
1548 {
1549 DBUG_PRINT("info", ("Left NULL..."));
1550 /*
1551 We're evaluating
1552 "<outer_value_list> [NOT] IN (SELECT <inner_value_list>...)"
1553 where one or more of the outer values is NULL.
1554 */
1555 if (((Item_in_subselect*)args[1])->is_top_level_item())
1556 {
1557 /*
1558 We're evaluating a top level item, e.g.
1559 "<outer_value_list> IN (SELECT <inner_value_list>...)",
1560 and in this case a NULL value in the outer_value_list means
1561 that the result shall be NULL/FALSE (makes no difference for
1562 top level items). The cached value is NULL, so just return
1563 NULL.
1564 */
1565 null_value= 1;
1566 }
1567 else
1568 {
1569 /*
1570 We're evaluating an item where a NULL value in either the
1571 outer or inner value list does not automatically mean that we
1572 can return NULL/FALSE. An example of such a query is
1573 "<outer_value_list> NOT IN (SELECT <inner_value_list>...)"
1574 The result when there is at least one NULL value is: NULL if the
1575 SELECT evaluated over the non-NULL values produces at least
1576 one row, FALSE otherwise
1577 */
1578 Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
1579 bool all_left_cols_null= true;
1580 const uint ncols= cache->cols();
1581
1582 /*
1583 Turn off the predicates that are based on column compares for
1584 which the left part is currently NULL
1585 */
1586 for (uint i= 0; i < ncols; i++)
1587 {
1588 if (cache->element_index(i)->null_value)
1589 item_subs->set_cond_guard_var(i, FALSE);
1590 else
1591 all_left_cols_null= false;
1592 }
1593
1594 if (!item_subs->is_correlated &&
1595 all_left_cols_null && result_for_null_param != UNKNOWN)
1596 {
1597 /*
1598 This is a non-correlated subquery, all values in the outer
1599 value list are NULL, and we have already evaluated the
1600 subquery for all NULL values: Return the same result we
1601 did last time without evaluating the subquery.
1602 */
1603 null_value= result_for_null_param;
1604 }
1605 else
1606 {
1607 /* The subquery has to be evaluated */
1608 (void) item_subs->val_bool_result();
1609 if (item_subs->engine->no_rows())
1610 null_value= item_subs->null_value;
1611 else
1612 null_value= TRUE;
1613 if (all_left_cols_null)
1614 result_for_null_param= null_value;
1615 }
1616
1617 /* Turn all predicates back on */
1618 for (uint i= 0; i < ncols; i++)
1619 item_subs->set_cond_guard_var(i, TRUE);
1620 }
1621 DBUG_RETURN(0);
1622 }
1623 tmp= args[1]->val_bool_result();
1624 null_value= args[1]->null_value;
1625 DBUG_RETURN(tmp);
1626 }
1627
1628
keep_top_level_cache()1629 void Item_in_optimizer::keep_top_level_cache()
1630 {
1631 cache->keep_array();
1632 save_cache= 1;
1633 }
1634
1635
cleanup()1636 void Item_in_optimizer::cleanup()
1637 {
1638 DBUG_ENTER("Item_in_optimizer::cleanup");
1639 Item_bool_func::cleanup();
1640 if (!save_cache)
1641 cache= 0;
1642 expr_cache= 0;
1643 DBUG_VOID_RETURN;
1644 }
1645
1646
is_null()1647 bool Item_in_optimizer::is_null()
1648 {
1649 val_int();
1650 return null_value;
1651 }
1652
1653
1654 /**
1655 Transform an Item_in_optimizer and its arguments with a callback function.
1656
1657 @param transformer the transformer callback function to be applied to the
1658 nodes of the tree of the object
1659 @param parameter to be passed to the transformer
1660
1661 @detail
1662 Recursively transform the left and the right operand of this Item. The
1663 Right operand is an Item_in_subselect or its subclass. To avoid the
1664 creation of new Items, we use the fact the the left operand of the
1665 Item_in_subselect is the same as the one of 'this', so instead of
1666 transforming its operand, we just assign the left operand of the
1667 Item_in_subselect to be equal to the left operand of 'this'.
1668 The transformation is not applied further to the subquery operand
1669 if the IN predicate.
1670
1671 @returns
1672 @retval pointer to the transformed item
1673 @retval NULL if an error occurred
1674 */
1675
transform(THD * thd,Item_transformer transformer,uchar * argument)1676 Item *Item_in_optimizer::transform(THD *thd, Item_transformer transformer,
1677 uchar *argument)
1678 {
1679 Item *new_item;
1680
1681 DBUG_ASSERT(fixed);
1682 DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
1683 DBUG_ASSERT(arg_count == 2);
1684
1685 /* Transform the left IN operand. */
1686 new_item= (*args)->transform(thd, transformer, argument);
1687 if (!new_item)
1688 return 0;
1689 /*
1690 THD::change_item_tree() should be called only if the tree was
1691 really transformed, i.e. when a new item has been created.
1692 Otherwise we'll be allocating a lot of unnecessary memory for
1693 change records at each execution.
1694 */
1695 if ((*args) != new_item)
1696 thd->change_item_tree(args, new_item);
1697
1698 if (invisible_mode())
1699 {
1700 /* MAX/MIN transformed => pass through */
1701 new_item= args[1]->transform(thd, transformer, argument);
1702 if (!new_item)
1703 return 0;
1704 if (args[1] != new_item)
1705 thd->change_item_tree(args + 1, new_item);
1706 }
1707 else
1708 {
1709 /*
1710 Transform the right IN operand which should be an Item_in_subselect or a
1711 subclass of it. The left operand of the IN must be the same as the left
1712 operand of this Item_in_optimizer, so in this case there is no further
1713 transformation, we only make both operands the same.
1714 TODO: is it the way it should be?
1715 */
1716 DBUG_ASSERT((args[1])->type() == Item::SUBSELECT_ITEM &&
1717 (((Item_subselect*)(args[1]))->substype() ==
1718 Item_subselect::IN_SUBS ||
1719 ((Item_subselect*)(args[1]))->substype() ==
1720 Item_subselect::ALL_SUBS ||
1721 ((Item_subselect*)(args[1]))->substype() ==
1722 Item_subselect::ANY_SUBS));
1723
1724 Item_in_subselect *in_arg= (Item_in_subselect*)args[1];
1725 thd->change_item_tree(&in_arg->left_expr, args[0]);
1726 }
1727 return (this->*transformer)(thd, argument);
1728 }
1729
1730
is_expensive_processor(void * arg)1731 bool Item_in_optimizer::is_expensive_processor(void *arg)
1732 {
1733 DBUG_ASSERT(fixed);
1734 return args[0]->is_expensive_processor(arg) ||
1735 args[1]->is_expensive_processor(arg);
1736 }
1737
1738
is_expensive()1739 bool Item_in_optimizer::is_expensive()
1740 {
1741 DBUG_ASSERT(fixed);
1742 return args[0]->is_expensive() || args[1]->is_expensive();
1743 }
1744
1745
val_int()1746 longlong Item_func_eq::val_int()
1747 {
1748 DBUG_ASSERT(fixed == 1);
1749 int value= cmp.compare();
1750 return value == 0 ? 1 : 0;
1751 }
1752
1753
1754 /** Same as Item_func_eq, but NULL = NULL. */
1755
fix_length_and_dec()1756 bool Item_func_equal::fix_length_and_dec()
1757 {
1758 bool rc= Item_bool_rowready_func2::fix_length_and_dec();
1759 maybe_null=null_value=0;
1760 return rc;
1761 }
1762
val_int()1763 longlong Item_func_equal::val_int()
1764 {
1765 DBUG_ASSERT(fixed == 1);
1766 return cmp.compare();
1767 }
1768
val_int()1769 longlong Item_func_ne::val_int()
1770 {
1771 DBUG_ASSERT(fixed == 1);
1772 int value= cmp.compare();
1773 return value != 0 && !null_value ? 1 : 0;
1774 }
1775
1776
val_int()1777 longlong Item_func_ge::val_int()
1778 {
1779 DBUG_ASSERT(fixed == 1);
1780 int value= cmp.compare();
1781 return value >= 0 ? 1 : 0;
1782 }
1783
1784
val_int()1785 longlong Item_func_gt::val_int()
1786 {
1787 DBUG_ASSERT(fixed == 1);
1788 int value= cmp.compare();
1789 return value > 0 ? 1 : 0;
1790 }
1791
val_int()1792 longlong Item_func_le::val_int()
1793 {
1794 DBUG_ASSERT(fixed == 1);
1795 int value= cmp.compare();
1796 return value <= 0 && !null_value ? 1 : 0;
1797 }
1798
1799
val_int()1800 longlong Item_func_lt::val_int()
1801 {
1802 DBUG_ASSERT(fixed == 1);
1803 int value= cmp.compare();
1804 return value < 0 && !null_value ? 1 : 0;
1805 }
1806
1807
val_int()1808 longlong Item_func_strcmp::val_int()
1809 {
1810 DBUG_ASSERT(fixed == 1);
1811 String *a= args[0]->val_str(&value1);
1812 String *b= args[1]->val_str(&value2);
1813 if (!a || !b)
1814 {
1815 null_value=1;
1816 return 0;
1817 }
1818 int value= cmp_collation.sortcmp(a, b);
1819 null_value=0;
1820 return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1);
1821 }
1822
1823
eq(const Item * item,bool binary_cmp) const1824 bool Item_func_opt_neg::eq(const Item *item, bool binary_cmp) const
1825 {
1826 /* Assume we don't have rtti */
1827 if (this == item)
1828 return 1;
1829 if (item->type() != FUNC_ITEM)
1830 return 0;
1831 Item_func *item_func=(Item_func*) item;
1832 if (arg_count != item_func->argument_count() ||
1833 functype() != item_func->functype())
1834 return 0;
1835 if (negated != ((Item_func_opt_neg *) item_func)->negated)
1836 return 0;
1837 return Item_args::eq(item_func, binary_cmp);
1838 }
1839
1840
fix_fields(THD * thd,Item ** ref)1841 bool Item_func_interval::fix_fields(THD *thd, Item **ref)
1842 {
1843 if (Item_long_func::fix_fields(thd, ref))
1844 return true;
1845 for (uint i= 0 ; i < row->cols(); i++)
1846 {
1847 if (row->element_index(i)->check_cols(1))
1848 return true;
1849 }
1850 return false;
1851 }
1852
1853
fix_length_and_dec()1854 bool Item_func_interval::fix_length_and_dec()
1855 {
1856 uint rows= row->cols();
1857
1858 use_decimal_comparison= ((row->element_index(0)->result_type() ==
1859 DECIMAL_RESULT) ||
1860 (row->element_index(0)->result_type() ==
1861 INT_RESULT));
1862 if (rows > 8)
1863 {
1864 bool not_null_consts= TRUE;
1865
1866 for (uint i= 1; not_null_consts && i < rows; i++)
1867 {
1868 Item *el= row->element_index(i);
1869 not_null_consts&= el->const_item() && !el->is_null();
1870 }
1871
1872 if (not_null_consts)
1873 {
1874 intervals= (interval_range*) current_thd->alloc(sizeof(interval_range) *
1875 (rows - 1));
1876 if (!intervals)
1877 return TRUE;
1878
1879 if (use_decimal_comparison)
1880 {
1881 for (uint i= 1; i < rows; i++)
1882 {
1883 Item *el= row->element_index(i);
1884 interval_range *range= intervals + (i-1);
1885 if ((el->result_type() == DECIMAL_RESULT) ||
1886 (el->result_type() == INT_RESULT))
1887 {
1888 range->type= DECIMAL_RESULT;
1889 range->dec.init();
1890 my_decimal *dec= el->val_decimal(&range->dec);
1891 if (dec != &range->dec)
1892 {
1893 range->dec= *dec;
1894 }
1895 }
1896 else
1897 {
1898 range->type= REAL_RESULT;
1899 range->dbl= el->val_real();
1900 }
1901 }
1902 }
1903 else
1904 {
1905 for (uint i= 1; i < rows; i++)
1906 {
1907 intervals[i-1].dbl= row->element_index(i)->val_real();
1908 }
1909 }
1910 }
1911 }
1912 maybe_null= 0;
1913 max_length= 2;
1914 used_tables_and_const_cache_join(row);
1915 not_null_tables_cache= row->not_null_tables();
1916 with_sum_func= with_sum_func || row->with_sum_func;
1917 with_param= with_param || row->with_param;
1918 with_field= with_field || row->with_field;
1919 return FALSE;
1920 }
1921
1922
1923 /**
1924 Execute Item_func_interval().
1925
1926 @note
1927 If we are doing a decimal comparison, we are evaluating the first
1928 item twice.
1929
1930 @return
1931 - -1 if null value,
1932 - 0 if lower than lowest
1933 - 1 - arg_count-1 if between args[n] and args[n+1]
1934 - arg_count if higher than biggest argument
1935 */
1936
val_int()1937 longlong Item_func_interval::val_int()
1938 {
1939 DBUG_ASSERT(fixed == 1);
1940 double value;
1941 my_decimal dec_buf, *dec= NULL;
1942 uint i;
1943
1944 if (use_decimal_comparison)
1945 {
1946 dec= row->element_index(0)->val_decimal(&dec_buf);
1947 if (row->element_index(0)->null_value)
1948 return -1;
1949 my_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
1950 }
1951 else
1952 {
1953 value= row->element_index(0)->val_real();
1954 if (row->element_index(0)->null_value)
1955 return -1;
1956 }
1957
1958 if (intervals)
1959 { // Use binary search to find interval
1960 uint start,end;
1961 start= 0;
1962 end= row->cols()-2;
1963 while (start != end)
1964 {
1965 uint mid= (start + end + 1) / 2;
1966 interval_range *range= intervals + mid;
1967 my_bool cmp_result;
1968 /*
1969 The values in the range interval may have different types,
1970 Only do a decimal comparison if the first argument is a decimal
1971 and we are comparing against a decimal
1972 */
1973 if (dec && range->type == DECIMAL_RESULT)
1974 cmp_result= my_decimal_cmp(&range->dec, dec) <= 0;
1975 else
1976 cmp_result= (range->dbl <= value);
1977 if (cmp_result)
1978 start= mid;
1979 else
1980 end= mid - 1;
1981 }
1982 interval_range *range= intervals+start;
1983 return ((dec && range->type == DECIMAL_RESULT) ?
1984 my_decimal_cmp(dec, &range->dec) < 0 :
1985 value < range->dbl) ? 0 : start + 1;
1986 }
1987
1988 for (i=1 ; i < row->cols() ; i++)
1989 {
1990 Item *el= row->element_index(i);
1991 if (use_decimal_comparison &&
1992 ((el->result_type() == DECIMAL_RESULT) ||
1993 (el->result_type() == INT_RESULT)))
1994 {
1995 my_decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf);
1996 /* Skip NULL ranges. */
1997 if (el->null_value)
1998 continue;
1999 if (my_decimal_cmp(e_dec, dec) > 0)
2000 return i - 1;
2001 }
2002 else
2003 {
2004 double val= el->val_real();
2005 /* Skip NULL ranges. */
2006 if (el->null_value)
2007 continue;
2008 if (val > value)
2009 return i - 1;
2010 }
2011 }
2012 return i-1;
2013 }
2014
2015
2016 /**
2017 Perform context analysis of a BETWEEN item tree.
2018
2019 This function performs context analysis (name resolution) and calculates
2020 various attributes of the item tree with Item_func_between as its root.
2021 The function saves in ref the pointer to the item or to a newly created
2022 item that is considered as a replacement for the original one.
2023
2024 @param thd reference to the global context of the query thread
2025 @param ref pointer to Item* variable where pointer to resulting "fixed"
2026 item is to be assigned
2027
2028 @note
2029 Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
2030 a predicate/function level. Then it's easy to show that:
2031 @verbatim
2032 T0(e BETWEEN e1 AND e2) = union(T1(e),T1(e1),T1(e2))
2033 T1(e BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
2034 T0(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
2035 T1(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
2036 @endverbatim
2037
2038 @retval
2039 0 ok
2040 @retval
2041 1 got error
2042 */
2043
2044
eval_not_null_tables(void * opt_arg)2045 bool Item_func_between::eval_not_null_tables(void *opt_arg)
2046 {
2047 if (Item_func_opt_neg::eval_not_null_tables(NULL))
2048 return 1;
2049
2050 /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
2051 if (pred_level && !negated)
2052 return 0;
2053
2054 /* not_null_tables_cache == union(T1(e), intersection(T1(e1),T1(e2))) */
2055 not_null_tables_cache= (args[0]->not_null_tables() |
2056 (args[1]->not_null_tables() &
2057 args[2]->not_null_tables()));
2058 return 0;
2059 }
2060
2061
count_sargable_conds(void * arg)2062 bool Item_func_between::count_sargable_conds(void *arg)
2063 {
2064 SELECT_LEX *sel= (SELECT_LEX *) arg;
2065 sel->cond_count++;
2066 sel->between_count++;
2067 return 0;
2068 }
2069
2070
fix_after_pullout(st_select_lex * new_parent,Item ** ref,bool merge)2071 void Item_func_between::fix_after_pullout(st_select_lex *new_parent,
2072 Item **ref, bool merge)
2073 {
2074 /* This will re-calculate attributes of the arguments */
2075 Item_func_opt_neg::fix_after_pullout(new_parent, ref, merge);
2076 /* Then, re-calculate not_null_tables_cache according to our special rules */
2077 eval_not_null_tables(NULL);
2078 }
2079
fix_length_and_dec()2080 bool Item_func_between::fix_length_and_dec()
2081 {
2082 max_length= 1;
2083
2084 /*
2085 As some compare functions are generated after sql_yacc,
2086 we have to check for out of memory conditions here
2087 */
2088 if (!args[0] || !args[1] || !args[2])
2089 return TRUE;
2090 if (m_comparator.aggregate_for_comparison(Item_func_between::func_name(),
2091 args, 3, false))
2092 {
2093 DBUG_ASSERT(current_thd->is_error());
2094 return TRUE;
2095 }
2096
2097 return m_comparator.type_handler()->
2098 Item_func_between_fix_length_and_dec(this);
2099 }
2100
2101
fix_length_and_dec_numeric(THD * thd)2102 bool Item_func_between::fix_length_and_dec_numeric(THD *thd)
2103 {
2104 /* See the comment about the similar block in Item_bool_func2 */
2105 if (args[0]->real_item()->type() == FIELD_ITEM &&
2106 !thd->lex->is_ps_or_view_context_analysis())
2107 {
2108 Item_field *field_item= (Item_field*) (args[0]->real_item());
2109 if (field_item->field_type() == MYSQL_TYPE_LONGLONG ||
2110 field_item->field_type() == MYSQL_TYPE_YEAR)
2111 {
2112 const bool cvt_arg1= convert_const_to_int(thd, field_item, &args[1]);
2113 const bool cvt_arg2= convert_const_to_int(thd, field_item, &args[2]);
2114 if (cvt_arg1 && cvt_arg2)
2115 {
2116 // Works for all types
2117 m_comparator.set_handler(&type_handler_longlong);
2118 }
2119 }
2120 }
2121 return FALSE;
2122 }
2123
2124
fix_length_and_dec_temporal(THD * thd)2125 bool Item_func_between::fix_length_and_dec_temporal(THD *thd)
2126 {
2127 if (!thd->lex->is_ps_or_view_context_analysis())
2128 {
2129 for (uint i= 0; i < 3; i ++)
2130 {
2131 if (args[i]->const_item() &&
2132 args[i]->type_handler_for_comparison() != m_comparator.type_handler())
2133 {
2134 Item_cache *cache= m_comparator.type_handler()->Item_get_cache(thd, args[i]);
2135 if (!cache || cache->setup(thd, args[i]))
2136 return true;
2137 thd->change_item_tree(&args[i], cache);
2138 }
2139 }
2140 }
2141 return false;
2142 }
2143
2144
val_int_cmp_temporal()2145 longlong Item_func_between::val_int_cmp_temporal()
2146 {
2147 enum_field_types f_type= m_comparator.type_handler()->field_type();
2148 longlong value= args[0]->val_temporal_packed(f_type), a, b;
2149 if ((null_value= args[0]->null_value))
2150 return 0;
2151 a= args[1]->val_temporal_packed(f_type);
2152 b= args[2]->val_temporal_packed(f_type);
2153 if (!args[1]->null_value && !args[2]->null_value)
2154 return (longlong) ((value >= a && value <= b) != negated);
2155 if (args[1]->null_value && args[2]->null_value)
2156 null_value= true;
2157 else if (args[1]->null_value)
2158 null_value= value <= b; // not null if false range.
2159 else
2160 null_value= value >= a;
2161 return (longlong) (!null_value && negated);
2162 }
2163
2164
val_int_cmp_string()2165 longlong Item_func_between::val_int_cmp_string()
2166 {
2167 String *value,*a,*b;
2168 value=args[0]->val_str(&value0);
2169 if ((null_value=args[0]->null_value))
2170 return 0;
2171 a= args[1]->val_str(&value1);
2172 b= args[2]->val_str(&value2);
2173 if (!args[1]->null_value && !args[2]->null_value)
2174 return (longlong) ((sortcmp(value,a,cmp_collation.collation) >= 0 &&
2175 sortcmp(value,b,cmp_collation.collation) <= 0) !=
2176 negated);
2177 if (args[1]->null_value && args[2]->null_value)
2178 null_value= true;
2179 else if (args[1]->null_value)
2180 {
2181 // Set to not null if false range.
2182 null_value= sortcmp(value,b,cmp_collation.collation) <= 0;
2183 }
2184 else
2185 {
2186 // Set to not null if false range.
2187 null_value= sortcmp(value,a,cmp_collation.collation) >= 0;
2188 }
2189 return (longlong) (!null_value && negated);
2190 }
2191
2192
val_int_cmp_int()2193 longlong Item_func_between::val_int_cmp_int()
2194 {
2195 Longlong_hybrid value= args[0]->to_longlong_hybrid();
2196 if ((null_value= args[0]->null_value))
2197 return 0; /* purecov: inspected */
2198 Longlong_hybrid a= args[1]->to_longlong_hybrid();
2199 Longlong_hybrid b= args[2]->to_longlong_hybrid();
2200 if (!args[1]->null_value && !args[2]->null_value)
2201 return (longlong) ((value.cmp(a) >= 0 && value.cmp(b) <= 0) != negated);
2202 if (args[1]->null_value && args[2]->null_value)
2203 null_value= true;
2204 else if (args[1]->null_value)
2205 null_value= value.cmp(b) <= 0; // not null if false range.
2206 else
2207 null_value= value.cmp(a) >= 0;
2208 return (longlong) (!null_value && negated);
2209 }
2210
2211
val_int_cmp_decimal()2212 longlong Item_func_between::val_int_cmp_decimal()
2213 {
2214 my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
2215 a_buf, *a_dec, b_buf, *b_dec;
2216 if ((null_value=args[0]->null_value))
2217 return 0; /* purecov: inspected */
2218 a_dec= args[1]->val_decimal(&a_buf);
2219 b_dec= args[2]->val_decimal(&b_buf);
2220 if (!args[1]->null_value && !args[2]->null_value)
2221 return (longlong) ((my_decimal_cmp(dec, a_dec) >= 0 &&
2222 my_decimal_cmp(dec, b_dec) <= 0) != negated);
2223 if (args[1]->null_value && args[2]->null_value)
2224 null_value= true;
2225 else if (args[1]->null_value)
2226 null_value= (my_decimal_cmp(dec, b_dec) <= 0);
2227 else
2228 null_value= (my_decimal_cmp(dec, a_dec) >= 0);
2229 return (longlong) (!null_value && negated);
2230 }
2231
2232
val_int_cmp_real()2233 longlong Item_func_between::val_int_cmp_real()
2234 {
2235 double value= args[0]->val_real(),a,b;
2236 if ((null_value=args[0]->null_value))
2237 return 0; /* purecov: inspected */
2238 a= args[1]->val_real();
2239 b= args[2]->val_real();
2240 if (!args[1]->null_value && !args[2]->null_value)
2241 return (longlong) ((value >= a && value <= b) != negated);
2242 if (args[1]->null_value && args[2]->null_value)
2243 null_value= true;
2244 else if (args[1]->null_value)
2245 {
2246 null_value= value <= b; // not null if false range.
2247 }
2248 else
2249 {
2250 null_value= value >= a;
2251 }
2252 return (longlong) (!null_value && negated);
2253 }
2254
2255
print(String * str,enum_query_type query_type)2256 void Item_func_between::print(String *str, enum_query_type query_type)
2257 {
2258 args[0]->print_parenthesised(str, query_type, higher_precedence());
2259 if (negated)
2260 str->append(STRING_WITH_LEN(" not"));
2261 str->append(STRING_WITH_LEN(" between "));
2262 args[1]->print_parenthesised(str, query_type, precedence());
2263 str->append(STRING_WITH_LEN(" and "));
2264 args[2]->print_parenthesised(str, query_type, precedence());
2265 }
2266
2267
2268 double
real_op()2269 Item_func_ifnull::real_op()
2270 {
2271 DBUG_ASSERT(fixed == 1);
2272 double value= args[0]->val_real();
2273 if (!args[0]->null_value)
2274 {
2275 null_value=0;
2276 return value;
2277 }
2278 value= args[1]->val_real();
2279 if ((null_value=args[1]->null_value))
2280 return 0.0;
2281 return value;
2282 }
2283
2284 longlong
int_op()2285 Item_func_ifnull::int_op()
2286 {
2287 DBUG_ASSERT(fixed == 1);
2288 longlong value=args[0]->val_int();
2289 if (!args[0]->null_value)
2290 {
2291 null_value=0;
2292 return value;
2293 }
2294 value=args[1]->val_int();
2295 if ((null_value=args[1]->null_value))
2296 return 0;
2297 return value;
2298 }
2299
2300
decimal_op(my_decimal * decimal_value)2301 my_decimal *Item_func_ifnull::decimal_op(my_decimal *decimal_value)
2302 {
2303 DBUG_ASSERT(fixed == 1);
2304 my_decimal *value= args[0]->val_decimal(decimal_value);
2305 if (!args[0]->null_value)
2306 {
2307 null_value= 0;
2308 return value;
2309 }
2310 value= args[1]->val_decimal(decimal_value);
2311 if ((null_value= args[1]->null_value))
2312 return 0;
2313 return value;
2314 }
2315
2316
2317 String *
str_op(String * str)2318 Item_func_ifnull::str_op(String *str)
2319 {
2320 DBUG_ASSERT(fixed == 1);
2321 String *res =args[0]->val_str(str);
2322 if (!args[0]->null_value)
2323 {
2324 null_value=0;
2325 res->set_charset(collation.collation);
2326 return res;
2327 }
2328 res=args[1]->val_str(str);
2329 if ((null_value=args[1]->null_value))
2330 return 0;
2331 res->set_charset(collation.collation);
2332 return res;
2333 }
2334
2335
date_op(MYSQL_TIME * ltime,ulonglong fuzzydate)2336 bool Item_func_ifnull::date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
2337 {
2338 DBUG_ASSERT(fixed == 1);
2339 for (uint i= 0; i < 2; i++)
2340 {
2341 Datetime dt(current_thd, args[i], fuzzydate & ~TIME_FUZZY_DATES);
2342 if (!(dt.copy_to_mysql_time(ltime, mysql_timestamp_type())))
2343 return (null_value= false);
2344 }
2345 return (null_value= true);
2346 }
2347
2348
time_op(MYSQL_TIME * ltime)2349 bool Item_func_ifnull::time_op(MYSQL_TIME *ltime)
2350 {
2351 DBUG_ASSERT(fixed == 1);
2352 for (uint i= 0; i < 2; i++)
2353 {
2354 if (!Time(args[i]).copy_to_mysql_time(ltime))
2355 return (null_value= false);
2356 }
2357 return (null_value= true);
2358 }
2359
2360
2361 /**
2362 Perform context analysis of an IF item tree.
2363
2364 This function performs context analysis (name resolution) and calculates
2365 various attributes of the item tree with Item_func_if as its root.
2366 The function saves in ref the pointer to the item or to a newly created
2367 item that is considered as a replacement for the original one.
2368
2369 @param thd reference to the global context of the query thread
2370 @param ref pointer to Item* variable where pointer to resulting "fixed"
2371 item is to be assigned
2372
2373 @note
2374 Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
2375 a predicate/function level. Then it's easy to show that:
2376 @verbatim
2377 T0(IF(e,e1,e2) = T1(IF(e,e1,e2))
2378 T1(IF(e,e1,e2)) = intersection(T1(e1),T1(e2))
2379 @endverbatim
2380
2381 @retval
2382 0 ok
2383 @retval
2384 1 got error
2385 */
2386
2387 bool
fix_fields(THD * thd,Item ** ref)2388 Item_func_if::fix_fields(THD *thd, Item **ref)
2389 {
2390 DBUG_ASSERT(fixed == 0);
2391 args[0]->top_level_item();
2392
2393 if (Item_func::fix_fields(thd, ref))
2394 return 1;
2395
2396 return 0;
2397 }
2398
2399
2400 bool
eval_not_null_tables(void * opt_arg)2401 Item_func_if::eval_not_null_tables(void *opt_arg)
2402 {
2403 if (Item_func::eval_not_null_tables(NULL))
2404 return 1;
2405
2406 not_null_tables_cache= (args[1]->not_null_tables() &
2407 args[2]->not_null_tables());
2408
2409 return 0;
2410 }
2411
2412
fix_after_pullout(st_select_lex * new_parent,Item ** ref,bool merge)2413 void Item_func_if::fix_after_pullout(st_select_lex *new_parent,
2414 Item **ref, bool merge)
2415 {
2416 /* This will re-calculate attributes of the arguments */
2417 Item_func::fix_after_pullout(new_parent, ref, merge);
2418 /* Then, re-calculate not_null_tables_cache according to our special rules */
2419 eval_not_null_tables(NULL);
2420 }
2421
2422
split_sum_func(THD * thd,Ref_ptr_array ref_pointer_array,List<Item> & fields,uint flags)2423 void Item_func_nullif::split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
2424 List<Item> &fields, uint flags)
2425 {
2426 if (m_cache)
2427 {
2428 flags|= SPLIT_SUM_SKIP_REGISTERED; // See Item_func::split_sum_func
2429 m_cache->split_sum_func2_example(thd, ref_pointer_array, fields, flags);
2430 args[1]->split_sum_func2(thd, ref_pointer_array, fields, &args[1], flags);
2431 }
2432 else
2433 {
2434 Item_func::split_sum_func(thd, ref_pointer_array, fields, flags);
2435 }
2436 }
2437
2438
walk(Item_processor processor,bool walk_subquery,void * arg)2439 bool Item_func_nullif::walk(Item_processor processor,
2440 bool walk_subquery, void *arg)
2441 {
2442 /*
2443 No needs to iterate through args[2] when it's just a copy of args[0].
2444 See MDEV-9712 Performance degradation of nested NULLIF
2445 */
2446 uint tmp_count= arg_count == 2 || args[0] == args[2] ? 2 : 3;
2447 for (uint i= 0; i < tmp_count; i++)
2448 {
2449 if (args[i]->walk(processor, walk_subquery, arg))
2450 return true;
2451 }
2452 return (this->*processor)(arg);
2453 }
2454
2455
update_used_tables()2456 void Item_func_nullif::update_used_tables()
2457 {
2458 if (m_cache)
2459 {
2460 used_tables_and_const_cache_init();
2461 used_tables_and_const_cache_update_and_join(m_cache->get_example());
2462 used_tables_and_const_cache_update_and_join(arg_count, args);
2463 }
2464 else
2465 {
2466 /*
2467 MDEV-9712 Performance degradation of nested NULLIF
2468 No needs to iterate through args[2] when it's just a copy of args[0].
2469 */
2470 DBUG_ASSERT(arg_count == 3);
2471 used_tables_and_const_cache_init();
2472 used_tables_and_const_cache_update_and_join(args[0] == args[2] ? 2 : 3,
2473 args);
2474 }
2475 }
2476
2477
2478
2479 bool
fix_length_and_dec()2480 Item_func_nullif::fix_length_and_dec()
2481 {
2482 /*
2483 If this is the first invocation of fix_length_and_dec(), create the
2484 third argument as a copy of the first. This cannot be done before
2485 fix_fields(), because fix_fields() might replace items,
2486 for exampe NOT x --> x==0, or (SELECT 1) --> 1.
2487 See also class Item_func_nullif declaration.
2488 */
2489 if (arg_count == 2)
2490 args[arg_count++]= m_arg0 ? m_arg0 : args[0];
2491
2492 THD *thd= current_thd;
2493 /*
2494 At prepared statement EXECUTE time, args[0] can already
2495 point to a different Item, created during PREPARE time fix_length_and_dec().
2496 For example, if character set conversion was needed, arguments can look
2497 like this:
2498
2499 args[0]= > Item_func_conv_charset \
2500 l_expr
2501 args[2]= >------------------------/
2502
2503 Otherwise (during PREPARE or convensional execution),
2504 args[0] and args[2] should still point to the same original l_expr.
2505 */
2506 DBUG_ASSERT(args[0] == args[2] || thd->stmt_arena->is_stmt_execute());
2507 if (args[0]->type() == SUM_FUNC_ITEM &&
2508 !thd->lex->is_ps_or_view_context_analysis())
2509 {
2510 /*
2511 NULLIF(l_expr, r_expr)
2512
2513 is calculated in the way to return a result equal to:
2514
2515 CASE WHEN l_expr = r_expr THEN NULL ELSE r_expr END.
2516
2517 There's nothing special with r_expr, because it's referenced
2518 only by args[1] and nothing else.
2519
2520 l_expr needs a special treatment, as it's referenced by both
2521 args[0] and args[2] initially.
2522
2523 args[2] is used to return the value. Afrer all transformations
2524 (e.g. in fix_length_and_dec(), equal field propagation, etc)
2525 args[2] points to a an Item which preserves the exact data type and
2526 attributes (e.g. collation) of the original l_expr.
2527 It can point:
2528 - to the original l_expr
2529 - to an Item_cache pointing to l_expr
2530 - to a constant of the same data type with l_expr.
2531
2532 args[0] is used for comparison. It can be replaced:
2533
2534 - to Item_func_conv_charset by character set aggregation routines
2535 - to a constant Item by equal field propagation routines
2536 (in case of Item_field)
2537
2538 The data type and/or the attributes of args[0] can differ from
2539 the data type and the attributes of the original l_expr, to make
2540 it comparable to args[1] (which points to r_expr or its replacement).
2541
2542 For aggregate functions we have to wrap the original args[0]/args[2]
2543 into Item_cache (see MDEV-9181). In this case the Item_cache
2544 instance becomes the subject to character set conversion instead of
2545 the original args[0]/args[2], while the original args[0]/args[2] get
2546 hidden inside the cache.
2547
2548 Some examples of what NULLIF can end up with after argument
2549 substitution (we don't mention args[1] in some cases for simplicity):
2550
2551 1. l_expr is not an aggregate function:
2552
2553 a. No conversion happened.
2554 args[0] and args[2] were not replaced to something else
2555 (i.e. neither by character set conversion, nor by propagation):
2556
2557 args[1] > r_expr
2558 args[0] \
2559 l_expr
2560 args[2] /
2561
2562 b. Conversion of args[0] happened:
2563
2564 CREATE OR REPLACE TABLE t1 (
2565 a CHAR(10) CHARACTER SET latin1,
2566 b CHAR(10) CHARACTER SET utf8);
2567 SELECT * FROM t1 WHERE NULLIF(a,b);
2568
2569 args[1] > r_expr (Item_field for t1.b)
2570 args[0] > Item_func_conv_charset\
2571 l_expr (Item_field for t1.a)
2572 args[2] > ----------------------/
2573
2574 c. Conversion of args[1] happened:
2575
2576 CREATE OR REPLACE TABLE t1 (
2577 a CHAR(10) CHARACTER SET utf8,
2578 b CHAR(10) CHARACTER SET latin1);
2579 SELECT * FROM t1 WHERE NULLIF(a,b);
2580
2581 args[1] > Item_func_conv_charset -> r_expr (Item_field for t1.b)
2582 args[0] \
2583 l_expr (Item_field for t1.a)
2584 args[2] /
2585
2586 d. Conversion of only args[0] happened (by equal field proparation):
2587
2588 CREATE OR REPLACE TABLE t1 (
2589 a CHAR(10),
2590 b CHAR(10));
2591 SELECT * FROM t1 WHERE NULLIF(a,b) AND a='a';
2592
2593 args[1] > r_expr (Item_field for t1.b)
2594 args[0] > Item_string('a') (constant replacement for t1.a)
2595 args[2] > l_expr (Item_field for t1.a)
2596
2597 e. Conversion of both args[0] and args[2] happened
2598 (by equal field propagation):
2599
2600 CREATE OR REPLACE TABLE t1 (a INT,b INT);
2601 SELECT * FROM t1 WHERE NULLIF(a,b) AND a=5;
2602
2603 args[1] > r_expr (Item_field for "b")
2604 args[0] \
2605 Item_int (5) (constant replacement for "a")
2606 args[2] /
2607
2608 2. In case if l_expr is an aggregate function:
2609
2610 a. No conversion happened:
2611
2612 args[0] \
2613 Item_cache > l_expr
2614 args[2] /
2615
2616 b. Conversion of args[0] happened:
2617
2618 args[0] > Item_func_conv_charset \
2619 Item_cache > l_expr
2620 args[2] >------------------------/
2621
2622 c. Conversion of both args[0] and args[2] happened.
2623 (e.g. by equal expression propagation)
2624 TODO: check if it's possible (and add an example query if so).
2625 */
2626 m_cache= args[0]->cmp_type() == STRING_RESULT ?
2627 new (thd->mem_root) Item_cache_str_for_nullif(thd, args[0]) :
2628 args[0]->get_cache(thd);
2629 if (!m_cache)
2630 return TRUE;
2631 m_cache->setup(thd, args[0]);
2632 m_cache->store(args[0]);
2633 m_cache->set_used_tables(args[0]->used_tables());
2634 thd->change_item_tree(&args[0], m_cache);
2635 thd->change_item_tree(&args[2], m_cache);
2636 }
2637 set_handler(args[2]->type_handler());
2638 collation.set(args[2]->collation);
2639 decimals= args[2]->decimals;
2640 unsigned_flag= args[2]->unsigned_flag;
2641 fix_char_length(args[2]->max_char_length());
2642 maybe_null=1;
2643 m_arg0= args[0];
2644 if (setup_args_and_comparator(thd, &cmp))
2645 return TRUE;
2646 /*
2647 A special code for EXECUTE..PREPARE.
2648
2649 If args[0] did not change, then we don't remember it, as it can point
2650 to a temporary Item object which will be destroyed between PREPARE
2651 and EXECUTE. EXECUTE time fix_length_and_dec() will correctly set args[2]
2652 from args[0] again.
2653
2654 If args[0] changed, then it can be Item_func_conv_charset() for the
2655 original args[0], which was permanently installed during PREPARE time
2656 into the item tree as a wrapper for args[0], using change_item_tree(), i.e.
2657
2658 NULLIF(latin1_field, 'a' COLLATE utf8_bin)
2659
2660 was "rewritten" to:
2661
2662 CASE WHEN CONVERT(latin1_field USING utf8) = 'a' COLLATE utf8_bin
2663 THEN NULL
2664 ELSE latin1_field
2665
2666 - m_args0 points to Item_field corresponding to latin1_field
2667 - args[0] points to Item_func_conv_charset
2668 - args[0]->args[0] is equal to m_args0
2669 - args[1] points to Item_func_set_collation
2670 - args[2] points is eqial to m_args0
2671
2672 In this case we remember and reuse m_arg0 during EXECUTE time as args[2].
2673
2674 QQ: How to make sure that m_args0 does not point
2675 to something temporary which will be destroyed between PREPARE and EXECUTE.
2676 The condition below should probably be more strict and somehow check that:
2677 - change_item_tree() was called for the new args[0]
2678 - m_args0 is referenced from inside args[0], e.g. as a function argument,
2679 and therefore it is also something that won't be destroyed between
2680 PREPARE and EXECUTE.
2681 Any ideas?
2682 */
2683 if (args[0] == m_arg0)
2684 m_arg0= NULL;
2685 return FALSE;
2686 }
2687
2688
print(String * str,enum_query_type query_type)2689 void Item_func_nullif::print(String *str, enum_query_type query_type)
2690 {
2691 /*
2692 NULLIF(a,b) is implemented according to the SQL standard as a short for
2693 CASE WHEN a=b THEN NULL ELSE a END
2694
2695 The constructor of Item_func_nullif sets args[0] and args[2] to the
2696 same item "a", and sets args[1] to "b".
2697
2698 If "this" is a part of a WHERE or ON condition, then:
2699 - the left "a" is a subject to equal field propagation with ANY_SUBST.
2700 - the right "a" is a subject to equal field propagation with IDENTITY_SUBST.
2701 Therefore, after equal field propagation args[0] and args[2] can point
2702 to different items.
2703 */
2704 if ((query_type & QT_ITEM_ORIGINAL_FUNC_NULLIF) ||
2705 (arg_count == 2) ||
2706 (args[0] == args[2]))
2707 {
2708 /*
2709 If QT_ITEM_ORIGINAL_FUNC_NULLIF is requested,
2710 that means we want the original NULLIF() representation,
2711 e.g. when we are in:
2712 SHOW CREATE {VIEW|FUNCTION|PROCEDURE}
2713
2714 The original representation is possible only if
2715 args[0] and args[2] still point to the same Item.
2716
2717 The caller must never pass call print() with QT_ITEM_ORIGINAL_FUNC_NULLIF
2718 if an expression has undergone some optimization
2719 (e.g. equal field propagation done in optimize_cond()) already and
2720 NULLIF() potentially has two different representations of "a":
2721 - one "a" for comparison
2722 - another "a" for the returned value!
2723 */
2724 DBUG_ASSERT(arg_count == 2 ||
2725 args[0] == args[2] || current_thd->lex->context_analysis_only);
2726 str->append(func_name());
2727 str->append('(');
2728 if (arg_count == 2)
2729 args[0]->print(str, query_type);
2730 else
2731 args[2]->print(str, query_type);
2732 str->append(',');
2733 args[1]->print(str, query_type);
2734 str->append(')');
2735 }
2736 else
2737 {
2738 /*
2739 args[0] and args[2] are different items.
2740 This is possible after WHERE optimization (equal fields propagation etc),
2741 e.g. in EXPLAIN EXTENDED or EXPLAIN FORMAT=JSON.
2742 As it's not possible to print as a function with 2 arguments any more,
2743 do it in the CASE style.
2744 */
2745 str->append(STRING_WITH_LEN("(case when "));
2746 args[0]->print(str, query_type);
2747 str->append(STRING_WITH_LEN(" = "));
2748 args[1]->print(str, query_type);
2749 str->append(STRING_WITH_LEN(" then NULL else "));
2750 args[2]->print(str, query_type);
2751 str->append(STRING_WITH_LEN(" end)"));
2752 }
2753 }
2754
2755
compare()2756 int Item_func_nullif::compare()
2757 {
2758 if (m_cache)
2759 m_cache->cache_value();
2760 return cmp.compare();
2761 }
2762
2763 /**
2764 @note
2765 Note that we have to evaluate the first argument twice as the compare
2766 may have been done with a different type than return value
2767 @return
2768 NULL if arguments are equal
2769 @return
2770 the first argument if not equal
2771 */
2772
2773 double
real_op()2774 Item_func_nullif::real_op()
2775 {
2776 DBUG_ASSERT(fixed == 1);
2777 double value;
2778 if (!compare())
2779 {
2780 null_value=1;
2781 return 0.0;
2782 }
2783 value= args[2]->val_real();
2784 null_value= args[2]->null_value;
2785 return value;
2786 }
2787
2788 longlong
int_op()2789 Item_func_nullif::int_op()
2790 {
2791 DBUG_ASSERT(fixed == 1);
2792 longlong value;
2793 if (!compare())
2794 {
2795 null_value=1;
2796 return 0;
2797 }
2798 value= args[2]->val_int();
2799 null_value= args[2]->null_value;
2800 return value;
2801 }
2802
2803 String *
str_op(String * str)2804 Item_func_nullif::str_op(String *str)
2805 {
2806 DBUG_ASSERT(fixed == 1);
2807 String *res;
2808 if (!compare())
2809 {
2810 null_value=1;
2811 return 0;
2812 }
2813 res= args[2]->val_str(str);
2814 null_value= args[2]->null_value;
2815 return res;
2816 }
2817
2818
2819 my_decimal *
decimal_op(my_decimal * decimal_value)2820 Item_func_nullif::decimal_op(my_decimal * decimal_value)
2821 {
2822 DBUG_ASSERT(fixed == 1);
2823 my_decimal *res;
2824 if (!compare())
2825 {
2826 null_value=1;
2827 return 0;
2828 }
2829 res= args[2]->val_decimal(decimal_value);
2830 null_value= args[2]->null_value;
2831 return res;
2832 }
2833
2834
2835 bool
date_op(MYSQL_TIME * ltime,ulonglong fuzzydate)2836 Item_func_nullif::date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
2837 {
2838 DBUG_ASSERT(fixed == 1);
2839 if (!compare())
2840 return (null_value= true);
2841 Datetime dt(current_thd, args[2], fuzzydate);
2842 return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
2843 }
2844
2845
2846 bool
time_op(MYSQL_TIME * ltime)2847 Item_func_nullif::time_op(MYSQL_TIME *ltime)
2848 {
2849 DBUG_ASSERT(fixed == 1);
2850 if (!compare())
2851 return (null_value= true);
2852 return (null_value= Time(args[2]).copy_to_mysql_time(ltime));
2853
2854 }
2855
2856
2857 bool
is_null()2858 Item_func_nullif::is_null()
2859 {
2860 return (null_value= (!compare() ? 1 : args[2]->is_null()));
2861 }
2862
reorder_args(uint start)2863 void Item_func_case::reorder_args(uint start)
2864 {
2865 /*
2866 Reorder args, to have at first the optional CASE expression, then all WHEN
2867 expressions, then all THEN expressions. And the optional ELSE expression
2868 at the end.
2869
2870 We reorder an even number of arguments, starting from start.
2871 */
2872 uint count = (arg_count - start) / 2;
2873 const size_t size= sizeof(Item*) * count * 2;
2874 Item **arg_buffer= (Item **)my_safe_alloca(size);
2875 memcpy(arg_buffer, &args[start], size);
2876 for (uint i= 0; i < count; i++)
2877 {
2878 args[start + i]= arg_buffer[i*2];
2879 args[start + i + count]= arg_buffer[i*2 + 1];
2880 }
2881 my_safe_afree(arg_buffer, size);
2882 }
2883
2884
2885
2886 /**
2887 Find and return matching items for CASE or ELSE item if all compares
2888 are failed or NULL if ELSE item isn't defined.
2889
2890 IMPLEMENTATION
2891 In order to do correct comparisons of the CASE expression (the expression
2892 between CASE and the first WHEN) with each WHEN expression several
2893 comparators are used. One for each result type. CASE expression can be
2894 evaluated up to # of different result types are used. To check whether
2895 the CASE expression already was evaluated for a particular result type
2896 a bit mapped variable value_added_map is used. Result types are mapped
2897 to it according to their int values i.e. STRING_RESULT is mapped to bit
2898 0, REAL_RESULT to bit 1, so on.
2899
2900 @retval
2901 NULL Nothing found and there is no ELSE expression defined
2902 @retval
2903 item Found item or ELSE item if defined and all comparisons are
2904 failed
2905 */
2906
find_item()2907 Item *Item_func_case_searched::find_item()
2908 {
2909 uint count= when_count();
2910 for (uint i= 0 ; i < count ; i++)
2911 {
2912 if (args[i]->val_bool())
2913 return args[i + count];
2914 }
2915 Item **pos= Item_func_case_searched::else_expr_addr();
2916 return pos ? pos[0] : 0;
2917 }
2918
2919
find_item()2920 Item *Item_func_case_simple::find_item()
2921 {
2922 /* Compare every WHEN argument with it and return the first match */
2923 uint idx;
2924 if (!Predicant_to_list_comparator::cmp(this, &idx, NULL))
2925 return args[idx + when_count()];
2926 Item **pos= Item_func_case_simple::else_expr_addr();
2927 return pos ? pos[0] : 0;
2928 }
2929
2930
find_item()2931 Item *Item_func_decode_oracle::find_item()
2932 {
2933 uint idx;
2934 if (!Predicant_to_list_comparator::cmp_nulls_equal(this, &idx))
2935 return args[idx + when_count()];
2936 Item **pos= Item_func_decode_oracle::else_expr_addr();
2937 return pos ? pos[0] : 0;
2938 }
2939
2940
str_op(String * str)2941 String *Item_func_case::str_op(String *str)
2942 {
2943 DBUG_ASSERT(fixed == 1);
2944 String *res;
2945 Item *item= find_item();
2946
2947 if (!item)
2948 {
2949 null_value=1;
2950 return 0;
2951 }
2952 null_value= 0;
2953 if (!(res=item->val_str(str)))
2954 null_value= 1;
2955 return res;
2956 }
2957
2958
int_op()2959 longlong Item_func_case::int_op()
2960 {
2961 DBUG_ASSERT(fixed == 1);
2962 Item *item= find_item();
2963 longlong res;
2964
2965 if (!item)
2966 {
2967 null_value=1;
2968 return 0;
2969 }
2970 res=item->val_int();
2971 null_value=item->null_value;
2972 return res;
2973 }
2974
real_op()2975 double Item_func_case::real_op()
2976 {
2977 DBUG_ASSERT(fixed == 1);
2978 Item *item= find_item();
2979 double res;
2980
2981 if (!item)
2982 {
2983 null_value=1;
2984 return 0;
2985 }
2986 res= item->val_real();
2987 null_value=item->null_value;
2988 return res;
2989 }
2990
2991
decimal_op(my_decimal * decimal_value)2992 my_decimal *Item_func_case::decimal_op(my_decimal *decimal_value)
2993 {
2994 DBUG_ASSERT(fixed == 1);
2995 Item *item= find_item();
2996 my_decimal *res;
2997
2998 if (!item)
2999 {
3000 null_value=1;
3001 return 0;
3002 }
3003
3004 res= item->val_decimal(decimal_value);
3005 null_value= item->null_value;
3006 return res;
3007 }
3008
3009
date_op(MYSQL_TIME * ltime,ulonglong fuzzydate)3010 bool Item_func_case::date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
3011 {
3012 DBUG_ASSERT(fixed == 1);
3013 Item *item= find_item();
3014 if (!item)
3015 return (null_value= true);
3016 Datetime dt(current_thd, item, fuzzydate);
3017 return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
3018 }
3019
3020
time_op(MYSQL_TIME * ltime)3021 bool Item_func_case::time_op(MYSQL_TIME *ltime)
3022 {
3023 DBUG_ASSERT(fixed == 1);
3024 Item *item= find_item();
3025 if (!item)
3026 return (null_value= true);
3027 return (null_value= Time(item).copy_to_mysql_time(ltime));
3028 }
3029
3030
fix_fields(THD * thd,Item ** ref)3031 bool Item_func_case::fix_fields(THD *thd, Item **ref)
3032 {
3033 bool res= Item_func::fix_fields(thd, ref);
3034
3035 Item **pos= else_expr_addr();
3036 if (!pos || pos[0]->maybe_null)
3037 maybe_null= 1;
3038 return res;
3039 }
3040
3041
3042 /**
3043 Check if (*place) and new_value points to different Items and call
3044 THD::change_item_tree() if needed.
3045 */
3046
propagate_and_change_item_tree(THD * thd,Item ** place,COND_EQUAL * cond,const Item::Context & ctx)3047 static void propagate_and_change_item_tree(THD *thd, Item **place,
3048 COND_EQUAL *cond,
3049 const Item::Context &ctx)
3050 {
3051 Item *new_value= (*place)->propagate_equal_fields(thd, ctx, cond);
3052 if (new_value && *place != new_value)
3053 thd->change_item_tree(place, new_value);
3054 }
3055
3056
prepare_predicant_and_values(THD * thd,uint * found_types,bool nulls_equal)3057 bool Item_func_case_simple::prepare_predicant_and_values(THD *thd,
3058 uint *found_types,
3059 bool nulls_equal)
3060 {
3061 bool have_null= false;
3062 uint type_cnt;
3063 Type_handler_hybrid_field_type tmp;
3064 uint ncases= when_count();
3065 add_predicant(this, 0);
3066 for (uint i= 0 ; i < ncases; i++)
3067 {
3068 if (nulls_equal ?
3069 add_value("case..when", this, i + 1) :
3070 add_value_skip_null("case..when", this, i + 1, &have_null))
3071 return true;
3072 }
3073 all_values_added(&tmp, &type_cnt, &m_found_types);
3074 #ifndef DBUG_OFF
3075 Predicant_to_list_comparator::debug_print(thd);
3076 #endif
3077 return false;
3078 }
3079
3080
fix_length_and_dec()3081 bool Item_func_case_searched::fix_length_and_dec()
3082 {
3083 THD *thd= current_thd;
3084 return aggregate_then_and_else_arguments(thd, when_count());
3085 }
3086
3087
fix_length_and_dec()3088 bool Item_func_case_simple::fix_length_and_dec()
3089 {
3090 THD *thd= current_thd;
3091 return (aggregate_then_and_else_arguments(thd, when_count() + 1) ||
3092 aggregate_switch_and_when_arguments(thd, false));
3093 }
3094
3095
fix_length_and_dec()3096 bool Item_func_decode_oracle::fix_length_and_dec()
3097 {
3098 THD *thd= current_thd;
3099 return (aggregate_then_and_else_arguments(thd, when_count() + 1) ||
3100 aggregate_switch_and_when_arguments(thd, true));
3101 }
3102
3103
3104 /*
3105 Aggregate all THEN and ELSE expression types
3106 and collations when string result
3107
3108 @param THD - current thd
3109 @param start - an element in args to start aggregating from
3110 */
aggregate_then_and_else_arguments(THD * thd,uint start)3111 bool Item_func_case::aggregate_then_and_else_arguments(THD *thd, uint start)
3112 {
3113 if (aggregate_for_result(func_name(), args + start, arg_count - start, true))
3114 return true;
3115
3116 if (fix_attributes(args + start, arg_count - start))
3117 return true;
3118
3119 return false;
3120 }
3121
3122
3123 /*
3124 Aggregate the predicant expression and all WHEN expression types
3125 and collations when string comparison
3126 */
aggregate_switch_and_when_arguments(THD * thd,bool nulls_eq)3127 bool Item_func_case_simple::aggregate_switch_and_when_arguments(THD *thd,
3128 bool nulls_eq)
3129 {
3130 uint ncases= when_count();
3131 m_found_types= 0;
3132 if (prepare_predicant_and_values(thd, &m_found_types, nulls_eq))
3133 {
3134 /*
3135 If Predicant_to_list_comparator() fails to prepare components,
3136 it must put an error into the diagnostics area. This is needed
3137 to make fix_fields() catches such errors.
3138 */
3139 DBUG_ASSERT(thd->is_error());
3140 return true;
3141 }
3142
3143 if (!(m_found_types= collect_cmp_types(args, ncases + 1)))
3144 return true;
3145
3146 if (m_found_types & (1U << STRING_RESULT))
3147 {
3148 /*
3149 If we'll do string comparison, we also need to aggregate
3150 character set and collation for first/WHEN items and
3151 install converters for some of them to cmp_collation when necessary.
3152 This is done because cmp_item compatators cannot compare
3153 strings in two different character sets.
3154 Some examples when we install converters:
3155
3156 1. Converter installed for the first expression:
3157
3158 CASE latin1_item WHEN utf16_item THEN ... END
3159
3160 is replaced to:
3161
3162 CASE CONVERT(latin1_item USING utf16) WHEN utf16_item THEN ... END
3163
3164 2. Converter installed for the left WHEN item:
3165
3166 CASE utf16_item WHEN latin1_item THEN ... END
3167
3168 is replaced to:
3169
3170 CASE utf16_item WHEN CONVERT(latin1_item USING utf16) THEN ... END
3171 */
3172 if (agg_arg_charsets_for_comparison(cmp_collation, args, ncases + 1))
3173 return true;
3174 }
3175
3176 if (make_unique_cmp_items(thd, cmp_collation.collation))
3177 return true;
3178
3179 return false;
3180 }
3181
3182
propagate_equal_fields(THD * thd,const Context & ctx,COND_EQUAL * cond)3183 Item* Item_func_case_simple::propagate_equal_fields(THD *thd,
3184 const Context &ctx,
3185 COND_EQUAL *cond)
3186 {
3187 const Type_handler *first_expr_cmp_handler;
3188
3189 first_expr_cmp_handler= args[0]->type_handler_for_comparison();
3190 /*
3191 Cannot replace the CASE (the switch) argument if
3192 there are multiple comparison types were found, or found a single
3193 comparison type that is not equal to args[0]->cmp_type().
3194
3195 - Example: multiple comparison types, can't propagate:
3196 WHERE CASE str_column
3197 WHEN 'string' THEN TRUE
3198 WHEN 1 THEN TRUE
3199 ELSE FALSE END;
3200
3201 - Example: a single incompatible comparison type, can't propagate:
3202 WHERE CASE str_column
3203 WHEN DATE'2001-01-01' THEN TRUE
3204 ELSE FALSE END;
3205
3206 - Example: a single incompatible comparison type, can't propagate:
3207 WHERE CASE str_column
3208 WHEN 1 THEN TRUE
3209 ELSE FALSE END;
3210
3211 - Example: a single compatible comparison type, ok to propagate:
3212 WHERE CASE str_column
3213 WHEN 'str1' THEN TRUE
3214 WHEN 'str2' THEN TRUE
3215 ELSE FALSE END;
3216 */
3217 if (m_found_types == (1UL << first_expr_cmp_handler->cmp_type()))
3218 propagate_and_change_item_tree(thd, &args[0], cond,
3219 Context(ANY_SUBST, first_expr_cmp_handler, cmp_collation.collation));
3220
3221 /*
3222 These arguments are in comparison.
3223 Allow invariants of the same value during propagation.
3224 Note, as we pass ANY_SUBST, none of the WHEN arguments will be
3225 replaced to zero-filled constants (only IDENTITY_SUBST allows this).
3226 Such a change for WHEN arguments would require rebuilding cmp_items.
3227 */
3228 uint i, count= when_count();
3229 for (i= 1; i <= count; i++)
3230 {
3231 Type_handler_hybrid_field_type tmp(first_expr_cmp_handler);
3232 if (!tmp.aggregate_for_comparison(args[i]->type_handler_for_comparison()))
3233 propagate_and_change_item_tree(thd, &args[i], cond,
3234 Context(ANY_SUBST, tmp.type_handler(), cmp_collation.collation));
3235 }
3236
3237 // THEN and ELSE arguments (they are not in comparison)
3238 for (; i < arg_count; i++)
3239 propagate_and_change_item_tree(thd, &args[i], cond, Context_identity());
3240
3241 return this;
3242 }
3243
3244
print_when_then_arguments(String * str,enum_query_type query_type,Item ** items,uint count)3245 inline void Item_func_case::print_when_then_arguments(String *str,
3246 enum_query_type
3247 query_type,
3248 Item **items, uint count)
3249 {
3250 for (uint i= 0; i < count; i++)
3251 {
3252 str->append(STRING_WITH_LEN("when "));
3253 items[i]->print(str, query_type);
3254 str->append(STRING_WITH_LEN(" then "));
3255 items[i + count]->print(str, query_type);
3256 str->append(' ');
3257 }
3258 }
3259
3260
print_else_argument(String * str,enum_query_type query_type,Item * item)3261 inline void Item_func_case::print_else_argument(String *str,
3262 enum_query_type query_type,
3263 Item *item)
3264 {
3265 str->append(STRING_WITH_LEN("else "));
3266 item->print(str, query_type);
3267 str->append(' ');
3268 }
3269
3270
print(String * str,enum_query_type query_type)3271 void Item_func_case_searched::print(String *str, enum_query_type query_type)
3272 {
3273 Item **pos;
3274 str->append(STRING_WITH_LEN("case "));
3275 print_when_then_arguments(str, query_type, &args[0], when_count());
3276 if ((pos= Item_func_case_searched::else_expr_addr()))
3277 print_else_argument(str, query_type, pos[0]);
3278 str->append(STRING_WITH_LEN("end"));
3279 }
3280
3281
print(String * str,enum_query_type query_type)3282 void Item_func_case_simple::print(String *str, enum_query_type query_type)
3283 {
3284 Item **pos;
3285 str->append(STRING_WITH_LEN("case "));
3286 args[0]->print_parenthesised(str, query_type, precedence());
3287 str->append(' ');
3288 print_when_then_arguments(str, query_type, &args[1], when_count());
3289 if ((pos= Item_func_case_simple::else_expr_addr()))
3290 print_else_argument(str, query_type, pos[0]);
3291 str->append(STRING_WITH_LEN("end"));
3292 }
3293
3294
print(String * str,enum_query_type query_type)3295 void Item_func_decode_oracle::print(String *str, enum_query_type query_type)
3296 {
3297 str->append(func_name());
3298 str->append('(');
3299 args[0]->print(str, query_type);
3300 for (uint i= 1, count= when_count() ; i <= count; i++)
3301 {
3302 str->append(',');
3303 args[i]->print(str, query_type);
3304 str->append(',');
3305 args[i+count]->print(str, query_type);
3306 }
3307 Item **else_expr= Item_func_case_simple::else_expr_addr();
3308 if (else_expr)
3309 {
3310 str->append(',');
3311 (*else_expr)->print(str, query_type);
3312 }
3313 str->append(')');
3314 }
3315
3316
3317 /**
3318 Coalesce - return first not NULL argument.
3319 */
3320
str_op(String * str)3321 String *Item_func_coalesce::str_op(String *str)
3322 {
3323 DBUG_ASSERT(fixed == 1);
3324 null_value=0;
3325 for (uint i=0 ; i < arg_count ; i++)
3326 {
3327 String *res;
3328 if ((res=args[i]->val_str(str)))
3329 return res;
3330 }
3331 null_value=1;
3332 return 0;
3333 }
3334
int_op()3335 longlong Item_func_coalesce::int_op()
3336 {
3337 DBUG_ASSERT(fixed == 1);
3338 null_value=0;
3339 for (uint i=0 ; i < arg_count ; i++)
3340 {
3341 longlong res=args[i]->val_int();
3342 if (!args[i]->null_value)
3343 return res;
3344 }
3345 null_value=1;
3346 return 0;
3347 }
3348
real_op()3349 double Item_func_coalesce::real_op()
3350 {
3351 DBUG_ASSERT(fixed == 1);
3352 null_value=0;
3353 for (uint i=0 ; i < arg_count ; i++)
3354 {
3355 double res= args[i]->val_real();
3356 if (!args[i]->null_value)
3357 return res;
3358 }
3359 null_value=1;
3360 return 0;
3361 }
3362
3363
date_op(MYSQL_TIME * ltime,ulonglong fuzzydate)3364 bool Item_func_coalesce::date_op(MYSQL_TIME *ltime, ulonglong fuzzydate)
3365 {
3366 DBUG_ASSERT(fixed == 1);
3367 for (uint i= 0; i < arg_count; i++)
3368 {
3369 Datetime dt(current_thd, args[i], fuzzydate & ~TIME_FUZZY_DATES);
3370 if (!dt.copy_to_mysql_time(ltime, mysql_timestamp_type()))
3371 return (null_value= false);
3372 }
3373 return (null_value= true);
3374 }
3375
3376
time_op(MYSQL_TIME * ltime)3377 bool Item_func_coalesce::time_op(MYSQL_TIME *ltime)
3378 {
3379 DBUG_ASSERT(fixed == 1);
3380 for (uint i= 0; i < arg_count; i++)
3381 {
3382 if (!Time(args[i]).copy_to_mysql_time(ltime))
3383 return (null_value= false);
3384 }
3385 return (null_value= true);
3386 }
3387
3388
decimal_op(my_decimal * decimal_value)3389 my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
3390 {
3391 DBUG_ASSERT(fixed == 1);
3392 null_value= 0;
3393 for (uint i= 0; i < arg_count; i++)
3394 {
3395 my_decimal *res= args[i]->val_decimal(decimal_value);
3396 if (!args[i]->null_value)
3397 return res;
3398 }
3399 null_value=1;
3400 return 0;
3401 }
3402
3403
3404 /****************************************************************************
3405 Classes and function for the IN operator
3406 ****************************************************************************/
3407
3408 /*
3409 Determine which of the signed longlong arguments is bigger
3410
3411 SYNOPSIS
3412 cmp_longs()
3413 a_val left argument
3414 b_val right argument
3415
3416 DESCRIPTION
3417 This function will compare two signed longlong arguments
3418 and will return -1, 0, or 1 if left argument is smaller than,
3419 equal to or greater than the right argument.
3420
3421 RETURN VALUE
3422 -1 left argument is smaller than the right argument.
3423 0 left argument is equal to the right argument.
3424 1 left argument is greater than the right argument.
3425 */
cmp_longs(longlong a_val,longlong b_val)3426 static inline int cmp_longs (longlong a_val, longlong b_val)
3427 {
3428 return a_val < b_val ? -1 : a_val == b_val ? 0 : 1;
3429 }
3430
3431
3432 /*
3433 Determine which of the unsigned longlong arguments is bigger
3434
3435 SYNOPSIS
3436 cmp_ulongs()
3437 a_val left argument
3438 b_val right argument
3439
3440 DESCRIPTION
3441 This function will compare two unsigned longlong arguments
3442 and will return -1, 0, or 1 if left argument is smaller than,
3443 equal to or greater than the right argument.
3444
3445 RETURN VALUE
3446 -1 left argument is smaller than the right argument.
3447 0 left argument is equal to the right argument.
3448 1 left argument is greater than the right argument.
3449 */
cmp_ulongs(ulonglong a_val,ulonglong b_val)3450 static inline int cmp_ulongs (ulonglong a_val, ulonglong b_val)
3451 {
3452 return a_val < b_val ? -1 : a_val == b_val ? 0 : 1;
3453 }
3454
3455
3456 /*
3457 Compare two integers in IN value list format (packed_longlong)
3458
3459 SYNOPSIS
3460 cmp_longlong()
3461 cmp_arg an argument passed to the calling function (my_qsort2)
3462 a left argument
3463 b right argument
3464
3465 DESCRIPTION
3466 This function will compare two integer arguments in the IN value list
3467 format and will return -1, 0, or 1 if left argument is smaller than,
3468 equal to or greater than the right argument.
3469 It's used in sorting the IN values list and finding an element in it.
3470 Depending on the signedness of the arguments cmp_longlong() will
3471 compare them as either signed (using cmp_longs()) or unsigned (using
3472 cmp_ulongs()).
3473
3474 RETURN VALUE
3475 -1 left argument is smaller than the right argument.
3476 0 left argument is equal to the right argument.
3477 1 left argument is greater than the right argument.
3478 */
cmp_longlong(void * cmp_arg,in_longlong::packed_longlong * a,in_longlong::packed_longlong * b)3479 int cmp_longlong(void *cmp_arg,
3480 in_longlong::packed_longlong *a,
3481 in_longlong::packed_longlong *b)
3482 {
3483 if (a->unsigned_flag != b->unsigned_flag)
3484 {
3485 /*
3486 One of the args is unsigned and is too big to fit into the
3487 positive signed range. Report no match.
3488 */
3489 if ((a->unsigned_flag && ((ulonglong) a->val) > (ulonglong) LONGLONG_MAX)
3490 ||
3491 (b->unsigned_flag && ((ulonglong) b->val) > (ulonglong) LONGLONG_MAX))
3492 return a->unsigned_flag ? 1 : -1;
3493 /*
3494 Although the signedness differs both args can fit into the signed
3495 positive range. Make them signed and compare as usual.
3496 */
3497 return cmp_longs(a->val, b->val);
3498 }
3499 if (a->unsigned_flag)
3500 return cmp_ulongs((ulonglong) a->val, (ulonglong) b->val);
3501 return cmp_longs(a->val, b->val);
3502 }
3503
cmp_double(void * cmp_arg,double * a,double * b)3504 static int cmp_double(void *cmp_arg, double *a,double *b)
3505 {
3506 return *a < *b ? -1 : *a == *b ? 0 : 1;
3507 }
3508
cmp_row(void * cmp_arg,cmp_item_row * a,cmp_item_row * b)3509 static int cmp_row(void *cmp_arg, cmp_item_row *a, cmp_item_row *b)
3510 {
3511 return a->compare(b);
3512 }
3513
3514
cmp_decimal(void * cmp_arg,my_decimal * a,my_decimal * b)3515 static int cmp_decimal(void *cmp_arg, my_decimal *a, my_decimal *b)
3516 {
3517 /*
3518 We need call of fixing buffer pointer, because fast sort just copy
3519 decimal buffers in memory and pointers left pointing on old buffer place
3520 */
3521 a->fix_buffer_pointer();
3522 b->fix_buffer_pointer();
3523 return my_decimal_cmp(a, b);
3524 }
3525
3526
find(Item * item)3527 bool in_vector::find(Item *item)
3528 {
3529 uchar *result=get_value(item);
3530 if (!result || !used_count)
3531 return false; // Null value
3532
3533 uint start,end;
3534 start=0; end=used_count-1;
3535 while (start != end)
3536 {
3537 uint mid=(start+end+1)/2;
3538 int res;
3539 if ((res=(*compare)(collation, base+mid*size, result)) == 0)
3540 return true;
3541 if (res < 0)
3542 start=mid;
3543 else
3544 end=mid-1;
3545 }
3546 return ((*compare)(collation, base+start*size, result) == 0);
3547 }
3548
in_string(THD * thd,uint elements,qsort2_cmp cmp_func,CHARSET_INFO * cs)3549 in_string::in_string(THD *thd, uint elements, qsort2_cmp cmp_func,
3550 CHARSET_INFO *cs)
3551 :in_vector(thd, elements, sizeof(String), cmp_func, cs),
3552 tmp(buff, sizeof(buff), &my_charset_bin)
3553 {}
3554
~in_string()3555 in_string::~in_string()
3556 {
3557 if (base)
3558 {
3559 // base was allocated on THD::mem_root => following is OK
3560 for (uint i=0 ; i < count ; i++)
3561 ((String*) base)[i].free();
3562 }
3563 }
3564
set(uint pos,Item * item)3565 void in_string::set(uint pos,Item *item)
3566 {
3567 String *str=((String*) base)+pos;
3568 String *res=item->val_str(str);
3569 if (res && res != str)
3570 {
3571 if (res->uses_buffer_owned_by(str))
3572 res->copy();
3573 if (item->type() == Item::FUNC_ITEM)
3574 str->copy(*res);
3575 else
3576 *str= *res;
3577 }
3578 if (!str->charset())
3579 {
3580 CHARSET_INFO *cs;
3581 if (!(cs= item->collation.collation))
3582 cs= &my_charset_bin; // Should never happen for STR items
3583 str->set_charset(cs);
3584 }
3585 }
3586
3587
get_value(Item * item)3588 uchar *in_string::get_value(Item *item)
3589 {
3590 return (uchar*) item->val_str(&tmp);
3591 }
3592
create_item(THD * thd)3593 Item *in_string::create_item(THD *thd)
3594 {
3595 return new (thd->mem_root) Item_string_for_in_vector(thd, collation);
3596 }
3597
3598
in_row(THD * thd,uint elements,Item * item)3599 in_row::in_row(THD *thd, uint elements, Item * item)
3600 {
3601 base= (char*) new (thd->mem_root) cmp_item_row[count= elements];
3602 size= sizeof(cmp_item_row);
3603 compare= (qsort2_cmp) cmp_row;
3604 /*
3605 We need to reset these as otherwise we will call sort() with
3606 uninitialized (even if not used) elements
3607 */
3608 used_count= elements;
3609 collation= 0;
3610 }
3611
~in_row()3612 in_row::~in_row()
3613 {
3614 if (base)
3615 delete [] (cmp_item_row*) base;
3616 }
3617
get_value(Item * item)3618 uchar *in_row::get_value(Item *item)
3619 {
3620 tmp.store_value(item);
3621 if (item->is_null())
3622 return 0;
3623 return (uchar *)&tmp;
3624 }
3625
set(uint pos,Item * item)3626 void in_row::set(uint pos, Item *item)
3627 {
3628 DBUG_ENTER("in_row::set");
3629 DBUG_PRINT("enter", ("pos: %u item: %p", pos,item));
3630 ((cmp_item_row*) base)[pos].store_value_by_template(current_thd, &tmp, item);
3631 DBUG_VOID_RETURN;
3632 }
3633
in_longlong(THD * thd,uint elements)3634 in_longlong::in_longlong(THD *thd, uint elements)
3635 :in_vector(thd, elements, sizeof(packed_longlong),
3636 (qsort2_cmp) cmp_longlong, 0)
3637 {}
3638
set(uint pos,Item * item)3639 void in_longlong::set(uint pos,Item *item)
3640 {
3641 struct packed_longlong *buff= &((packed_longlong*) base)[pos];
3642
3643 buff->val= item->val_int();
3644 buff->unsigned_flag= item->unsigned_flag;
3645 }
3646
get_value(Item * item)3647 uchar *in_longlong::get_value(Item *item)
3648 {
3649 tmp.val= item->val_int();
3650 if (item->null_value)
3651 return 0;
3652 tmp.unsigned_flag= item->unsigned_flag;
3653 return (uchar*) &tmp;
3654 }
3655
create_item(THD * thd)3656 Item *in_longlong::create_item(THD *thd)
3657 {
3658 /*
3659 We're created a signed INT, this may not be correct in
3660 general case (see BUG#19342).
3661 */
3662 return new (thd->mem_root) Item_int(thd, (longlong)0);
3663 }
3664
3665
set(uint pos,Item * item)3666 void in_datetime::set(uint pos,Item *item)
3667 {
3668 struct packed_longlong *buff= &((packed_longlong*) base)[pos];
3669
3670 buff->val= item->val_datetime_packed();
3671 buff->unsigned_flag= 1L;
3672 }
3673
set(uint pos,Item * item)3674 void in_time::set(uint pos,Item *item)
3675 {
3676 struct packed_longlong *buff= &((packed_longlong*) base)[pos];
3677
3678 buff->val= item->val_time_packed();
3679 buff->unsigned_flag= 1L;
3680 }
3681
get_value_internal(Item * item,enum_field_types f_type)3682 uchar *in_temporal::get_value_internal(Item *item, enum_field_types f_type)
3683 {
3684 tmp.val= item->val_temporal_packed(f_type);
3685 if (item->null_value)
3686 return 0;
3687 tmp.unsigned_flag= 1L;
3688 return (uchar*) &tmp;
3689 }
3690
create_item(THD * thd)3691 Item *in_temporal::create_item(THD *thd)
3692 {
3693 return new (thd->mem_root) Item_datetime(thd);
3694 }
3695
3696
in_double(THD * thd,uint elements)3697 in_double::in_double(THD *thd, uint elements)
3698 :in_vector(thd, elements, sizeof(double), (qsort2_cmp) cmp_double, 0)
3699 {}
3700
set(uint pos,Item * item)3701 void in_double::set(uint pos,Item *item)
3702 {
3703 ((double*) base)[pos]= item->val_real();
3704 }
3705
get_value(Item * item)3706 uchar *in_double::get_value(Item *item)
3707 {
3708 tmp= item->val_real();
3709 if (item->null_value)
3710 return 0; /* purecov: inspected */
3711 return (uchar*) &tmp;
3712 }
3713
create_item(THD * thd)3714 Item *in_double::create_item(THD *thd)
3715 {
3716 return new (thd->mem_root) Item_float(thd, 0.0, 0);
3717 }
3718
3719
in_decimal(THD * thd,uint elements)3720 in_decimal::in_decimal(THD *thd, uint elements)
3721 :in_vector(thd, elements, sizeof(my_decimal), (qsort2_cmp) cmp_decimal, 0)
3722 {}
3723
3724
set(uint pos,Item * item)3725 void in_decimal::set(uint pos, Item *item)
3726 {
3727 /* as far as 'item' is constant, we can store reference on my_decimal */
3728 my_decimal *dec= ((my_decimal *)base) + pos;
3729 dec->len= DECIMAL_BUFF_LENGTH;
3730 dec->fix_buffer_pointer();
3731 my_decimal *res= item->val_decimal(dec);
3732 /* if item->val_decimal() is evaluated to NULL then res == 0 */
3733 if (!item->null_value && res != dec)
3734 my_decimal2decimal(res, dec);
3735 }
3736
3737
get_value(Item * item)3738 uchar *in_decimal::get_value(Item *item)
3739 {
3740 my_decimal *result= item->val_decimal(&val);
3741 if (item->null_value)
3742 return 0;
3743 return (uchar *)result;
3744 }
3745
create_item(THD * thd)3746 Item *in_decimal::create_item(THD *thd)
3747 {
3748 return new (thd->mem_root) Item_decimal(thd, 0, FALSE);
3749 }
3750
3751
alloc_comparators(THD * thd,uint nargs)3752 bool Predicant_to_list_comparator::alloc_comparators(THD *thd, uint nargs)
3753 {
3754 size_t nbytes= sizeof(Predicant_to_value_comparator) * nargs;
3755 if (!(m_comparators= (Predicant_to_value_comparator *) thd->alloc(nbytes)))
3756 return true;
3757 memset(m_comparators, 0, nbytes);
3758 return false;
3759 }
3760
3761
add_value(const char * funcname,Item_args * args,uint value_index)3762 bool Predicant_to_list_comparator::add_value(const char *funcname,
3763 Item_args *args,
3764 uint value_index)
3765 {
3766 DBUG_ASSERT(m_predicant_index < args->argument_count());
3767 DBUG_ASSERT(value_index < args->argument_count());
3768 Type_handler_hybrid_field_type tmp;
3769 Item *tmpargs[2];
3770 tmpargs[0]= args->arguments()[m_predicant_index];
3771 tmpargs[1]= args->arguments()[value_index];
3772 if (tmp.aggregate_for_comparison(funcname, tmpargs, 2, true))
3773 {
3774 DBUG_ASSERT(current_thd->is_error());
3775 return true;
3776 }
3777 m_comparators[m_comparator_count].m_handler= tmp.type_handler();
3778 m_comparators[m_comparator_count].m_arg_index= value_index;
3779 m_comparator_count++;
3780 return false;
3781 }
3782
3783
add_value_skip_null(const char * funcname,Item_args * args,uint value_index,bool * nulls_found)3784 bool Predicant_to_list_comparator::add_value_skip_null(const char *funcname,
3785 Item_args *args,
3786 uint value_index,
3787 bool *nulls_found)
3788 {
3789 /*
3790 Skip explicit NULL constant items.
3791 Using real_item() to correctly detect references to explicit NULLs
3792 in HAVING clause, e.g. in this example "b" is skipped:
3793 SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (b,'A');
3794 */
3795 if (args->arguments()[value_index]->real_item()->type() == Item::NULL_ITEM)
3796 {
3797 *nulls_found= true;
3798 return false;
3799 }
3800 return add_value(funcname, args, value_index);
3801 }
3802
3803
3804 void Predicant_to_list_comparator::
detect_unique_handlers(Type_handler_hybrid_field_type * compatible,uint * unique_count,uint * found_types)3805 detect_unique_handlers(Type_handler_hybrid_field_type *compatible,
3806 uint *unique_count,
3807 uint *found_types)
3808 {
3809 *unique_count= 0;
3810 *found_types= 0;
3811 for (uint i= 0; i < m_comparator_count; i++)
3812 {
3813 uint idx;
3814 if (find_handler(&idx, m_comparators[i].m_handler, i))
3815 {
3816 m_comparators[i].m_handler_index= i; // New unique handler
3817 (*unique_count)++;
3818 (*found_types)|= 1U << m_comparators[i].m_handler->cmp_type();
3819 compatible->set_handler(m_comparators[i].m_handler);
3820 }
3821 else
3822 {
3823 m_comparators[i].m_handler_index= idx; // Non-unique handler
3824 }
3825 }
3826 }
3827
3828
make_unique_cmp_items(THD * thd,CHARSET_INFO * cs)3829 bool Predicant_to_list_comparator::make_unique_cmp_items(THD *thd,
3830 CHARSET_INFO *cs)
3831 {
3832 for (uint i= 0; i < m_comparator_count; i++)
3833 {
3834 if (m_comparators[i].m_handler && // Skip implicit NULLs
3835 m_comparators[i].m_handler_index == i && // Skip non-unuque
3836 !(m_comparators[i].m_cmp_item=
3837 m_comparators[i].m_handler->make_cmp_item(thd, cs)))
3838 return true;
3839 }
3840 return false;
3841 }
3842
3843
make_same()3844 cmp_item* cmp_item_sort_string::make_same()
3845 {
3846 return new cmp_item_sort_string_in_static(cmp_charset);
3847 }
3848
make_same()3849 cmp_item* cmp_item_int::make_same()
3850 {
3851 return new cmp_item_int();
3852 }
3853
make_same()3854 cmp_item* cmp_item_real::make_same()
3855 {
3856 return new cmp_item_real();
3857 }
3858
make_same()3859 cmp_item* cmp_item_row::make_same()
3860 {
3861 return new cmp_item_row();
3862 }
3863
3864
~cmp_item_row()3865 cmp_item_row::~cmp_item_row()
3866 {
3867 DBUG_ENTER("~cmp_item_row");
3868 DBUG_PRINT("enter",("this: %p", this));
3869 if (comparators)
3870 {
3871 for (uint i= 0; i < n; i++)
3872 {
3873 if (comparators[i])
3874 delete comparators[i];
3875 }
3876 }
3877 DBUG_VOID_RETURN;
3878 }
3879
3880
alloc_comparators(THD * thd,uint cols)3881 bool cmp_item_row::alloc_comparators(THD *thd, uint cols)
3882 {
3883 if (comparators)
3884 {
3885 DBUG_ASSERT(cols == n);
3886 return false;
3887 }
3888 return
3889 !(comparators= (cmp_item **) thd->calloc(sizeof(cmp_item *) * (n= cols)));
3890 }
3891
3892
store_value(Item * item)3893 void cmp_item_row::store_value(Item *item)
3894 {
3895 DBUG_ENTER("cmp_item_row::store_value");
3896 THD *thd= current_thd;
3897 if (!alloc_comparators(thd, item->cols()))
3898 {
3899 item->bring_value();
3900 item->null_value= 0;
3901 for (uint i=0; i < n; i++)
3902 {
3903 if (!comparators[i])
3904 {
3905 /**
3906 Comparators for the row elements that have temporal data types
3907 are installed at initialization time by prepare_comparators().
3908 Here we install comparators for the other data types.
3909 There is a bug in the below code. See MDEV-11511.
3910 When performing:
3911 (predicant0,predicant1) IN ((value00,value01),(value10,value11))
3912 It uses only the data type and the collation of the predicant
3913 elements only. It should be fixed to aggregate the data type and
3914 the collation for all elements at the N-th positions of the
3915 predicate and all values:
3916 - predicate0, value00, value01
3917 - predicate1, value10, value11
3918 */
3919 Item *elem= item->element_index(i);
3920 const Type_handler *handler= elem->type_handler();
3921 DBUG_ASSERT(elem->cmp_type() != TIME_RESULT);
3922 if (!(comparators[i]=
3923 handler->make_cmp_item(thd, elem->collation.collation)))
3924 break; // new failed
3925 }
3926 comparators[i]->store_value(item->element_index(i));
3927 item->null_value|= item->element_index(i)->null_value;
3928 }
3929 }
3930 DBUG_VOID_RETURN;
3931 }
3932
3933
store_value_by_template(THD * thd,cmp_item * t,Item * item)3934 void cmp_item_row::store_value_by_template(THD *thd, cmp_item *t, Item *item)
3935 {
3936 cmp_item_row *tmpl= (cmp_item_row*) t;
3937 if (tmpl->n != item->cols())
3938 {
3939 my_error(ER_OPERAND_COLUMNS, MYF(0), tmpl->n);
3940 return;
3941 }
3942 n= tmpl->n;
3943 if ((comparators= (cmp_item **) thd->alloc(sizeof(cmp_item *)*n)))
3944 {
3945 item->bring_value();
3946 item->null_value= 0;
3947 for (uint i=0; i < n; i++)
3948 {
3949 if (!(comparators[i]= tmpl->comparators[i]->make_same()))
3950 break; // new failed
3951 comparators[i]->store_value_by_template(thd, tmpl->comparators[i],
3952 item->element_index(i));
3953 item->null_value|= item->element_index(i)->null_value;
3954 }
3955 }
3956 }
3957
3958
cmp(Item * arg)3959 int cmp_item_row::cmp(Item *arg)
3960 {
3961 arg->null_value= 0;
3962 if (arg->cols() != n)
3963 {
3964 my_error(ER_OPERAND_COLUMNS, MYF(0), n);
3965 return 1;
3966 }
3967 bool was_null= 0;
3968 arg->bring_value();
3969 for (uint i=0; i < n; i++)
3970 {
3971 const int rc= comparators[i]->cmp(arg->element_index(i));
3972 switch (rc)
3973 {
3974 case UNKNOWN:
3975 was_null= true;
3976 break;
3977 case TRUE:
3978 return TRUE;
3979 case FALSE:
3980 break; // elements #i are equal
3981 }
3982 arg->null_value|= arg->element_index(i)->null_value;
3983 }
3984 return was_null ? UNKNOWN : FALSE;
3985 }
3986
3987
compare(cmp_item * c)3988 int cmp_item_row::compare(cmp_item *c)
3989 {
3990 cmp_item_row *l_cmp= (cmp_item_row *) c;
3991 for (uint i=0; i < n; i++)
3992 {
3993 int res;
3994 if ((res= comparators[i]->compare(l_cmp->comparators[i])))
3995 return res;
3996 }
3997 return 0;
3998 }
3999
4000
store_value(Item * item)4001 void cmp_item_decimal::store_value(Item *item)
4002 {
4003 my_decimal *val= item->val_decimal(&value);
4004 /* val may be zero if item is nnull */
4005 if (val && val != &value)
4006 my_decimal2decimal(val, &value);
4007 m_null_value= item->null_value;
4008 }
4009
4010
cmp_not_null(const Value * val)4011 int cmp_item_decimal::cmp_not_null(const Value *val)
4012 {
4013 DBUG_ASSERT(!val->is_null());
4014 DBUG_ASSERT(val->is_decimal());
4015 return my_decimal_cmp(&value, &val->m_decimal);
4016 }
4017
4018
cmp(Item * arg)4019 int cmp_item_decimal::cmp(Item *arg)
4020 {
4021 my_decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
4022 return (m_null_value || arg->null_value) ?
4023 UNKNOWN : (my_decimal_cmp(&value, tmp) != 0);
4024 }
4025
4026
compare(cmp_item * arg)4027 int cmp_item_decimal::compare(cmp_item *arg)
4028 {
4029 cmp_item_decimal *l_cmp= (cmp_item_decimal*) arg;
4030 return my_decimal_cmp(&value, &l_cmp->value);
4031 }
4032
4033
make_same()4034 cmp_item* cmp_item_decimal::make_same()
4035 {
4036 return new cmp_item_decimal();
4037 }
4038
4039
store_value_internal(Item * item,enum_field_types f_type)4040 void cmp_item_temporal::store_value_internal(Item *item,
4041 enum_field_types f_type)
4042 {
4043 value= item->val_temporal_packed(f_type);
4044 m_null_value= item->null_value;
4045 }
4046
4047
cmp_not_null(const Value * val)4048 int cmp_item_datetime::cmp_not_null(const Value *val)
4049 {
4050 DBUG_ASSERT(!val->is_null());
4051 DBUG_ASSERT(val->is_temporal());
4052 return value != pack_time(&val->value.m_time);
4053 }
4054
4055
cmp(Item * arg)4056 int cmp_item_datetime::cmp(Item *arg)
4057 {
4058 const bool rc= value != arg->val_datetime_packed();
4059 return (m_null_value || arg->null_value) ? UNKNOWN : rc;
4060 }
4061
4062
cmp_not_null(const Value * val)4063 int cmp_item_time::cmp_not_null(const Value *val)
4064 {
4065 DBUG_ASSERT(!val->is_null());
4066 DBUG_ASSERT(val->is_temporal());
4067 return value != pack_time(&val->value.m_time);
4068 }
4069
4070
cmp(Item * arg)4071 int cmp_item_time::cmp(Item *arg)
4072 {
4073 const bool rc= value != arg->val_time_packed();
4074 return (m_null_value || arg->null_value) ? UNKNOWN : rc;
4075 }
4076
4077
compare(cmp_item * ci)4078 int cmp_item_temporal::compare(cmp_item *ci)
4079 {
4080 cmp_item_temporal *l_cmp= (cmp_item_temporal *)ci;
4081 return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
4082 }
4083
4084
make_same()4085 cmp_item *cmp_item_datetime::make_same()
4086 {
4087 return new cmp_item_datetime();
4088 }
4089
4090
make_same()4091 cmp_item *cmp_item_time::make_same()
4092 {
4093 return new cmp_item_time();
4094 }
4095
4096
count_sargable_conds(void * arg)4097 bool Item_func_in::count_sargable_conds(void *arg)
4098 {
4099 ((SELECT_LEX*) arg)->cond_count++;
4100 return 0;
4101 }
4102
4103
list_contains_null()4104 bool Item_func_in::list_contains_null()
4105 {
4106 Item **arg,**arg_end;
4107 for (arg= args + 1, arg_end= args+arg_count; arg != arg_end ; arg++)
4108 {
4109 if ((*arg)->null_inside())
4110 return 1;
4111 }
4112 return 0;
4113 }
4114
4115
4116 /**
4117 Perform context analysis of an IN item tree.
4118
4119 This function performs context analysis (name resolution) and calculates
4120 various attributes of the item tree with Item_func_in as its root.
4121 The function saves in ref the pointer to the item or to a newly created
4122 item that is considered as a replacement for the original one.
4123
4124 @param thd reference to the global context of the query thread
4125 @param ref pointer to Item* variable where pointer to resulting "fixed"
4126 item is to be assigned
4127
4128 @note
4129 Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
4130 a predicate/function level. Then it's easy to show that:
4131 @verbatim
4132 T0(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
4133 T1(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
4134 T0(e NOT IN(e1,...,en)) = union(T1(e),union(T1(ei)))
4135 T1(e NOT IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
4136 @endverbatim
4137
4138 @retval
4139 0 ok
4140 @retval
4141 1 got error
4142 */
4143
4144 bool
fix_fields(THD * thd,Item ** ref)4145 Item_func_in::fix_fields(THD *thd, Item **ref)
4146 {
4147
4148 if (Item_func_opt_neg::fix_fields(thd, ref))
4149 return 1;
4150
4151 return 0;
4152 }
4153
4154
4155 bool
eval_not_null_tables(void * opt_arg)4156 Item_func_in::eval_not_null_tables(void *opt_arg)
4157 {
4158 Item **arg, **arg_end;
4159
4160 if (Item_func_opt_neg::eval_not_null_tables(NULL))
4161 return 1;
4162
4163 /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
4164 if (pred_level && negated)
4165 return 0;
4166
4167 /* not_null_tables_cache = union(T1(e),intersection(T1(ei))) */
4168 not_null_tables_cache= ~(table_map) 0;
4169 for (arg= args + 1, arg_end= args + arg_count; arg != arg_end; arg++)
4170 not_null_tables_cache&= (*arg)->not_null_tables();
4171 not_null_tables_cache|= (*args)->not_null_tables();
4172 return 0;
4173 }
4174
4175
fix_after_pullout(st_select_lex * new_parent,Item ** ref,bool merge)4176 void Item_func_in::fix_after_pullout(st_select_lex *new_parent, Item **ref,
4177 bool merge)
4178 {
4179 /* This will re-calculate attributes of the arguments */
4180 Item_func_opt_neg::fix_after_pullout(new_parent, ref, merge);
4181 /* Then, re-calculate not_null_tables_cache according to our special rules */
4182 eval_not_null_tables(NULL);
4183 }
4184
4185
prepare_predicant_and_values(THD * thd,uint * found_types)4186 bool Item_func_in::prepare_predicant_and_values(THD *thd, uint *found_types)
4187 {
4188 uint type_cnt;
4189 have_null= false;
4190
4191 add_predicant(this, 0);
4192 for (uint i= 1 ; i < arg_count; i++)
4193 {
4194 if (add_value_skip_null(Item_func_in::func_name(), this, i, &have_null))
4195 return true;
4196 }
4197 all_values_added(&m_comparator, &type_cnt, found_types);
4198 arg_types_compatible= type_cnt < 2;
4199
4200 #ifndef DBUG_OFF
4201 Predicant_to_list_comparator::debug_print(thd);
4202 #endif
4203 return false;
4204 }
4205
4206
fix_length_and_dec()4207 bool Item_func_in::fix_length_and_dec()
4208 {
4209 THD *thd= current_thd;
4210 uint found_types;
4211 m_comparator.set_handler(type_handler_varchar.type_handler_for_comparison());
4212 max_length= 1;
4213
4214 if (prepare_predicant_and_values(thd, &found_types))
4215 {
4216 DBUG_ASSERT(thd->is_error()); // Must set error
4217 return TRUE;
4218 }
4219
4220 if (arg_types_compatible) // Bisection condition #1
4221 {
4222 if (m_comparator.type_handler()->
4223 Item_func_in_fix_comparator_compatible_types(thd, this))
4224 return TRUE;
4225 }
4226 else
4227 {
4228 DBUG_ASSERT(m_comparator.cmp_type() != ROW_RESULT);
4229 if ( fix_for_scalar_comparison_using_cmp_items(thd, found_types))
4230 return TRUE;
4231 }
4232
4233 DBUG_EXECUTE_IF("Item_func_in",
4234 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
4235 ER_UNKNOWN_ERROR, "DBUG: types_compatible=%s bisect=%s",
4236 arg_types_compatible ? "yes" : "no",
4237 array != NULL ? "yes" : "no"););
4238 return FALSE;
4239 }
4240
4241
4242 /**
4243 Populate Item_func_in::array with constant not-NULL arguments and sort them.
4244
4245 Sets "have_null" to true if some of the values appeared to be NULL.
4246 Note, explicit NULLs were found during prepare_predicant_and_values().
4247 So "have_null" can already be true before the fix_in_vector() call.
4248 Here we additionally catch implicit NULLs.
4249 */
fix_in_vector()4250 void Item_func_in::fix_in_vector()
4251 {
4252 DBUG_ASSERT(array);
4253 uint j=0;
4254 for (uint i=1 ; i < arg_count ; i++)
4255 {
4256 array->set(j,args[i]);
4257 if (!args[i]->null_value)
4258 j++; // include this cell in the array.
4259 else
4260 {
4261 /*
4262 We don't put NULL values in array, to avoid erronous matches in
4263 bisection.
4264 */
4265 have_null= 1;
4266 }
4267 }
4268 if ((array->used_count= j))
4269 array->sort();
4270 }
4271
4272
4273 /**
4274 Convert all items in <in value list> to INT.
4275
4276 IN must compare INT columns and constants as int values (the same
4277 way as equality does).
4278 So we must check here if the column on the left and all the constant
4279 values on the right can be compared as integers and adjust the
4280 comparison type accordingly.
4281
4282 See the comment about the similar block in Item_bool_func2
4283 */
value_list_convert_const_to_int(THD * thd)4284 bool Item_func_in::value_list_convert_const_to_int(THD *thd)
4285 {
4286 if (args[0]->real_item()->type() == FIELD_ITEM &&
4287 !thd->lex->is_view_context_analysis())
4288 {
4289 Item_field *field_item= (Item_field*) (args[0]->real_item());
4290 if (field_item->field_type() == MYSQL_TYPE_LONGLONG ||
4291 field_item->field_type() == MYSQL_TYPE_YEAR)
4292 {
4293 bool all_converted= true;
4294 Item **arg, **arg_end;
4295 for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
4296 {
4297 /*
4298 Explicit NULLs should not affect data cmp_type resolution:
4299 - we ignore NULLs when calling collect_cmp_type()
4300 - we ignore NULLs here
4301 So this expression:
4302 year_column IN (DATE'2001-01-01', NULL)
4303 switches from TIME_RESULT to INT_RESULT.
4304 */
4305 if (arg[0]->type() != Item::NULL_ITEM &&
4306 !convert_const_to_int(thd, field_item, &arg[0]))
4307 all_converted= false;
4308 }
4309 if (all_converted)
4310 m_comparator.set_handler(&type_handler_longlong);
4311 }
4312 }
4313 return thd->is_fatal_error; // Catch errrors in convert_const_to_int
4314 }
4315
4316
4317 /**
4318 Historically this code installs comparators at initialization time
4319 for temporal ROW elements only. All other comparators are installed later,
4320 during the first store_value(). This causes the bug MDEV-11511.
4321 See also comments in cmp_item_row::store_value().
4322 */
prepare_comparators(THD * thd,Item ** args,uint arg_count)4323 bool cmp_item_row::prepare_comparators(THD *thd, Item **args, uint arg_count)
4324 {
4325 for (uint col= 0; col < n; col++)
4326 {
4327 Item *date_arg= find_date_time_item(args, arg_count, col);
4328 if (date_arg)
4329 {
4330 // TODO: do like the scalar comparators do
4331 const Type_handler *h= date_arg->type_handler();
4332 comparators[col]= h->field_type() == MYSQL_TYPE_TIME ?
4333 (cmp_item *) new (thd->mem_root) cmp_item_time() :
4334 (cmp_item *) new (thd->mem_root) cmp_item_datetime();
4335 if (!comparators[col])
4336 return true;
4337 }
4338 }
4339 return false;
4340 }
4341
4342
fix_for_row_comparison_using_bisection(THD * thd)4343 bool Item_func_in::fix_for_row_comparison_using_bisection(THD *thd)
4344 {
4345 uint cols= args[0]->cols();
4346 if (unlikely(!(array= new (thd->mem_root) in_row(thd, arg_count-1, 0))))
4347 return true;
4348 cmp_item_row *cmp= &((in_row*)array)->tmp;
4349 if (cmp->alloc_comparators(thd, cols) ||
4350 cmp->prepare_comparators(thd, args, arg_count))
4351 return true;
4352 /*
4353 Only DATETIME items comparators were initialized.
4354 Call store_value() to setup others.
4355 */
4356 cmp->store_value(args[0]);
4357 if (unlikely(thd->is_fatal_error)) // OOM
4358 return true;
4359 fix_in_vector();
4360 return false;
4361 }
4362
4363
4364 /**
4365 This method is called for scalar data types when bisection is not possible,
4366 for example:
4367 - Some of args[1..arg_count] are not constants.
4368 - args[1..arg_count] are constants, but pairs {args[0],args[1..arg_count]}
4369 are compared by different data types, e.g.:
4370 WHERE decimal_expr IN (1, 1e0)
4371 The pair {args[0],args[1]} is compared by type_handler_decimal.
4372 The pair {args[0],args[2]} is compared by type_handler_double.
4373 */
fix_for_scalar_comparison_using_cmp_items(THD * thd,uint found_types)4374 bool Item_func_in::fix_for_scalar_comparison_using_cmp_items(THD *thd,
4375 uint found_types)
4376 {
4377 if (found_types & (1U << STRING_RESULT) &&
4378 agg_arg_charsets_for_comparison(cmp_collation, args, arg_count))
4379 return true;
4380 if (make_unique_cmp_items(thd, cmp_collation.collation))
4381 return true;
4382 return false;
4383 }
4384
4385
4386 /**
4387 This method is called for the ROW data type when bisection is not possible.
4388 */
fix_for_row_comparison_using_cmp_items(THD * thd)4389 bool Item_func_in::fix_for_row_comparison_using_cmp_items(THD *thd)
4390 {
4391 if (make_unique_cmp_items(thd, cmp_collation.collation))
4392 return true;
4393 DBUG_ASSERT(get_comparator_type_handler(0) == &type_handler_row);
4394 DBUG_ASSERT(get_comparator_cmp_item(0));
4395 cmp_item_row *cmp_row= (cmp_item_row*) get_comparator_cmp_item(0);
4396 return cmp_row->alloc_comparators(thd, args[0]->cols()) ||
4397 cmp_row->prepare_comparators(thd, args, arg_count);
4398 }
4399
4400
print(String * str,enum_query_type query_type)4401 void Item_func_in::print(String *str, enum_query_type query_type)
4402 {
4403 args[0]->print_parenthesised(str, query_type, precedence());
4404 if (negated)
4405 str->append(STRING_WITH_LEN(" not"));
4406 str->append(STRING_WITH_LEN(" in ("));
4407 print_args(str, 1, query_type);
4408 str->append(STRING_WITH_LEN(")"));
4409 }
4410
4411
4412 /*
4413 Evaluate the function and return its value.
4414
4415 SYNOPSIS
4416 val_int()
4417
4418 DESCRIPTION
4419 Evaluate the function and return its value.
4420
4421 IMPLEMENTATION
4422 If the array object is defined then the value of the function is
4423 calculated by means of this array.
4424 Otherwise several cmp_item objects are used in order to do correct
4425 comparison of left expression and an expression from the values list.
4426 One cmp_item object correspond to one used comparison type. Left
4427 expression can be evaluated up to number of different used comparison
4428 types. A bit mapped variable value_added_map is used to check whether
4429 the left expression already was evaluated for a particular result type.
4430 Result types are mapped to it according to their integer values i.e.
4431 STRING_RESULT is mapped to bit 0, REAL_RESULT to bit 1, so on.
4432
4433 RETURN
4434 Value of the function
4435 */
4436
val_int()4437 longlong Item_func_in::val_int()
4438 {
4439 DBUG_ASSERT(fixed == 1);
4440 if (array)
4441 {
4442 bool tmp=array->find(args[0]);
4443 /*
4444 NULL on left -> UNKNOWN.
4445 Found no match, and NULL on right -> UNKNOWN.
4446 NULL on right can never give a match, as it is not stored in
4447 array.
4448 See also the 'bisection_possible' variable in fix_length_and_dec().
4449 */
4450 null_value=args[0]->null_value || (!tmp && have_null);
4451 return (longlong) (!null_value && tmp != negated);
4452 }
4453
4454 if ((null_value= args[0]->real_item()->type() == NULL_ITEM))
4455 return 0;
4456
4457 null_value= have_null;
4458 uint idx;
4459 if (!Predicant_to_list_comparator::cmp(this, &idx, &null_value))
4460 {
4461 null_value= false;
4462 return (longlong) (!negated);
4463 }
4464 return (longlong) (!null_value && negated);
4465 }
4466
4467
mark_as_condition_AND_part(TABLE_LIST * embedding)4468 void Item_func_in::mark_as_condition_AND_part(TABLE_LIST *embedding)
4469 {
4470 THD *thd= current_thd;
4471
4472 Query_arena *arena, backup;
4473 arena= thd->activate_stmt_arena_if_needed(&backup);
4474
4475 if (to_be_transformed_into_in_subq(thd))
4476 {
4477 transform_into_subq= true;
4478 thd->lex->current_select->in_funcs.push_back(this, thd->mem_root);
4479 }
4480
4481 if (arena)
4482 thd->restore_active_arena(arena, &backup);
4483
4484 emb_on_expr_nest= embedding;
4485 }
4486
4487
val_int()4488 longlong Item_func_bit_or::val_int()
4489 {
4490 DBUG_ASSERT(fixed == 1);
4491 ulonglong arg1= (ulonglong) args[0]->val_int();
4492 if (args[0]->null_value)
4493 {
4494 null_value=1; /* purecov: inspected */
4495 return 0; /* purecov: inspected */
4496 }
4497 ulonglong arg2= (ulonglong) args[1]->val_int();
4498 if (args[1]->null_value)
4499 {
4500 null_value=1;
4501 return 0;
4502 }
4503 null_value=0;
4504 return (longlong) (arg1 | arg2);
4505 }
4506
4507
val_int()4508 longlong Item_func_bit_and::val_int()
4509 {
4510 DBUG_ASSERT(fixed == 1);
4511 ulonglong arg1= (ulonglong) args[0]->val_int();
4512 if (args[0]->null_value)
4513 {
4514 null_value=1; /* purecov: inspected */
4515 return 0; /* purecov: inspected */
4516 }
4517 ulonglong arg2= (ulonglong) args[1]->val_int();
4518 if (args[1]->null_value)
4519 {
4520 null_value=1; /* purecov: inspected */
4521 return 0; /* purecov: inspected */
4522 }
4523 null_value=0;
4524 return (longlong) (arg1 & arg2);
4525 }
4526
Item_cond(THD * thd,Item_cond * item)4527 Item_cond::Item_cond(THD *thd, Item_cond *item)
4528 :Item_bool_func(thd, item),
4529 abort_on_null(item->abort_on_null),
4530 and_tables_cache(item->and_tables_cache)
4531 {
4532 /*
4533 item->list will be copied by copy_andor_arguments() call
4534 */
4535 }
4536
4537
Item_cond(THD * thd,Item * i1,Item * i2)4538 Item_cond::Item_cond(THD *thd, Item *i1, Item *i2):
4539 Item_bool_func(thd), abort_on_null(0)
4540 {
4541 list.push_back(i1, thd->mem_root);
4542 list.push_back(i2, thd->mem_root);
4543 }
4544
4545
copy_andor_structure(THD * thd)4546 Item *Item_cond_and::copy_andor_structure(THD *thd)
4547 {
4548 Item_cond_and *item;
4549 if ((item= new (thd->mem_root) Item_cond_and(thd, this)))
4550 item->copy_andor_arguments(thd, this);
4551 return item;
4552 }
4553
4554
copy_andor_arguments(THD * thd,Item_cond * item)4555 void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
4556 {
4557 List_iterator_fast<Item> li(item->list);
4558 while (Item *it= li++)
4559 list.push_back(it->copy_andor_structure(thd), thd->mem_root);
4560 }
4561
4562
4563 bool
fix_fields(THD * thd,Item ** ref)4564 Item_cond::fix_fields(THD *thd, Item **ref)
4565 {
4566 DBUG_ASSERT(fixed == 0);
4567 List_iterator<Item> li(list);
4568 Item *item;
4569 uchar buff[sizeof(char*)]; // Max local vars in function
4570 bool is_and_cond= functype() == Item_func::COND_AND_FUNC;
4571 not_null_tables_cache= 0;
4572 used_tables_and_const_cache_init();
4573
4574 /*
4575 and_table_cache is the value that Item_cond_or() returns for
4576 not_null_tables()
4577 */
4578 and_tables_cache= ~(table_map) 0;
4579
4580 if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
4581 return TRUE; // Fatal error flag is set!
4582 /*
4583 The following optimization reduces the depth of an AND-OR tree.
4584 E.g. a WHERE clause like
4585 F1 AND (F2 AND (F2 AND F4))
4586 is parsed into a tree with the same nested structure as defined
4587 by braces. This optimization will transform such tree into
4588 AND (F1, F2, F3, F4).
4589 Trees of OR items are flattened as well:
4590 ((F1 OR F2) OR (F3 OR F4)) => OR (F1, F2, F3, F4)
4591 Items for removed AND/OR levels will dangle until the death of the
4592 entire statement.
4593 The optimization is currently prepared statements and stored procedures
4594 friendly as it doesn't allocate any memory and its effects are durable
4595 (i.e. do not depend on PS/SP arguments).
4596 */
4597 while ((item=li++))
4598 {
4599 while (item->type() == Item::COND_ITEM &&
4600 ((Item_cond*) item)->functype() == functype() &&
4601 !((Item_cond*) item)->list.is_empty())
4602 { // Identical function
4603 li.replace(((Item_cond*) item)->list);
4604 ((Item_cond*) item)->list.empty();
4605 item= *li.ref(); // new current item
4606 }
4607 if (abort_on_null)
4608 item->top_level_item();
4609
4610 /*
4611 replace degraded condition:
4612 was: <field>
4613 become: <field> = 1
4614 */
4615 Item::Type type= item->type();
4616 if (type == Item::FIELD_ITEM || type == Item::REF_ITEM)
4617 {
4618 Query_arena backup, *arena;
4619 Item *new_item;
4620 arena= thd->activate_stmt_arena_if_needed(&backup);
4621 if ((new_item= new (thd->mem_root) Item_func_ne(thd, item, new (thd->mem_root) Item_int(thd, 0, 1))))
4622 li.replace(item= new_item);
4623 if (arena)
4624 thd->restore_active_arena(arena, &backup);
4625 }
4626
4627 if (item->fix_fields_if_needed_for_bool(thd, li.ref()))
4628 return TRUE; /* purecov: inspected */
4629 item= *li.ref(); // item can be substituted in fix_fields
4630 used_tables_cache|= item->used_tables();
4631 if (item->const_item() && !item->with_param &&
4632 !item->is_expensive() && !cond_has_datetime_is_null(item))
4633 {
4634 if (item->eval_const_cond() == is_and_cond && top_level())
4635 {
4636 /*
4637 a. This is "... AND true_cond AND ..."
4638 In this case, true_cond has no effect on cond_and->not_null_tables()
4639 b. This is "... OR false_cond/null cond OR ..."
4640 In this case, false_cond has no effect on cond_or->not_null_tables()
4641 */
4642 }
4643 else
4644 {
4645 /*
4646 a. This is "... AND false_cond/null_cond AND ..."
4647 The whole condition is FALSE/UNKNOWN.
4648 b. This is "... OR const_cond OR ..."
4649 In this case, cond_or->not_null_tables()=0, because the condition
4650 const_cond might evaluate to true (regardless of whether some tables
4651 were NULL-complemented).
4652 */
4653 not_null_tables_cache= (table_map) 0;
4654 and_tables_cache= (table_map) 0;
4655 }
4656 if (thd->is_error())
4657 return TRUE;
4658 }
4659 else
4660 {
4661 table_map tmp_table_map= item->not_null_tables();
4662 not_null_tables_cache|= tmp_table_map;
4663 and_tables_cache&= tmp_table_map;
4664
4665 const_item_cache= FALSE;
4666 }
4667
4668 with_sum_func|= item->with_sum_func;
4669 with_param|= item->with_param;
4670 with_field|= item->with_field;
4671 m_with_subquery|= item->with_subquery();
4672 with_window_func|= item->with_window_func;
4673 maybe_null|= item->maybe_null;
4674 }
4675 if (fix_length_and_dec())
4676 return TRUE;
4677 fixed= 1;
4678 return FALSE;
4679 }
4680
4681
4682 bool
eval_not_null_tables(void * opt_arg)4683 Item_cond::eval_not_null_tables(void *opt_arg)
4684 {
4685 Item *item;
4686 bool is_and_cond= functype() == Item_func::COND_AND_FUNC;
4687 List_iterator<Item> li(list);
4688 not_null_tables_cache= (table_map) 0;
4689 and_tables_cache= ~(table_map) 0;
4690 while ((item=li++))
4691 {
4692 table_map tmp_table_map;
4693 if (item->const_item() && !item->with_param &&
4694 !item->is_expensive() && !cond_has_datetime_is_null(item))
4695 {
4696 if (item->eval_const_cond() == is_and_cond && top_level())
4697 {
4698 /*
4699 a. This is "... AND true_cond AND ..."
4700 In this case, true_cond has no effect on cond_and->not_null_tables()
4701 b. This is "... OR false_cond/null cond OR ..."
4702 In this case, false_cond has no effect on cond_or->not_null_tables()
4703 */
4704 }
4705 else
4706 {
4707 /*
4708 a. This is "... AND false_cond/null_cond AND ..."
4709 The whole condition is FALSE/UNKNOWN.
4710 b. This is "... OR const_cond OR ..."
4711 In this case, cond_or->not_null_tables()=0, because the condition
4712 const_cond might evaluate to true (regardless of whether some tables
4713 were NULL-complemented).
4714 */
4715 not_null_tables_cache= (table_map) 0;
4716 and_tables_cache= (table_map) 0;
4717 }
4718 }
4719 else
4720 {
4721 tmp_table_map= item->not_null_tables();
4722 not_null_tables_cache|= tmp_table_map;
4723 and_tables_cache&= tmp_table_map;
4724 }
4725 }
4726 return 0;
4727 }
4728
4729
fix_after_pullout(st_select_lex * new_parent,Item ** ref,bool merge)4730 void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref,
4731 bool merge)
4732 {
4733 List_iterator<Item> li(list);
4734 Item *item;
4735
4736 used_tables_and_const_cache_init();
4737
4738 and_tables_cache= ~(table_map) 0; // Here and below we do as fix_fields does
4739 not_null_tables_cache= 0;
4740
4741 while ((item=li++))
4742 {
4743 table_map tmp_table_map;
4744 item->fix_after_pullout(new_parent, li.ref(), merge);
4745 item= *li.ref();
4746 used_tables_and_const_cache_join(item);
4747
4748 if (item->const_item())
4749 and_tables_cache= (table_map) 0;
4750 else
4751 {
4752 tmp_table_map= item->not_null_tables();
4753 not_null_tables_cache|= tmp_table_map;
4754 and_tables_cache&= tmp_table_map;
4755 const_item_cache= FALSE;
4756 }
4757 }
4758 }
4759
4760
walk(Item_processor processor,bool walk_subquery,void * arg)4761 bool Item_cond::walk(Item_processor processor, bool walk_subquery, void *arg)
4762 {
4763 List_iterator_fast<Item> li(list);
4764 Item *item;
4765 while ((item= li++))
4766 if (item->walk(processor, walk_subquery, arg))
4767 return 1;
4768 return Item_func::walk(processor, walk_subquery, arg);
4769 }
4770
4771 /**
4772 Transform an Item_cond object with a transformer callback function.
4773
4774 The function recursively applies the transform method to each
4775 member item of the condition list.
4776 If the call of the method for a member item returns a new item
4777 the old item is substituted for a new one.
4778 After this the transformer is applied to the root node
4779 of the Item_cond object.
4780
4781 @param transformer the transformer callback function to be applied to
4782 the nodes of the tree of the object
4783 @param arg parameter to be passed to the transformer
4784
4785 @return
4786 Item returned as the result of transformation of the root node
4787 */
4788
transform(THD * thd,Item_transformer transformer,uchar * arg)4789 Item *Item_cond::transform(THD *thd, Item_transformer transformer, uchar *arg)
4790 {
4791 DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
4792
4793 List_iterator<Item> li(list);
4794 Item *item;
4795 while ((item= li++))
4796 {
4797 Item *new_item= item->transform(thd, transformer, arg);
4798 if (!new_item)
4799 return 0;
4800
4801 /*
4802 THD::change_item_tree() should be called only if the tree was
4803 really transformed, i.e. when a new item has been created.
4804 Otherwise we'll be allocating a lot of unnecessary memory for
4805 change records at each execution.
4806 */
4807 if (new_item != item)
4808 thd->change_item_tree(li.ref(), new_item);
4809 }
4810 return Item_func::transform(thd, transformer, arg);
4811 }
4812
4813
4814 /**
4815 Compile Item_cond object with a processor and a transformer
4816 callback functions.
4817
4818 First the function applies the analyzer to the root node of
4819 the Item_func object. Then if the analyzer succeeeds (returns TRUE)
4820 the function recursively applies the compile method to member
4821 item of the condition list.
4822 If the call of the method for a member item returns a new item
4823 the old item is substituted for a new one.
4824 After this the transformer is applied to the root node
4825 of the Item_cond object.
4826
4827 @param analyzer the analyzer callback function to be applied to the
4828 nodes of the tree of the object
4829 @param[in,out] arg_p parameter to be passed to the analyzer
4830 @param transformer the transformer callback function to be applied to the
4831 nodes of the tree of the object
4832 @param arg_t parameter to be passed to the transformer
4833
4834 @return
4835 Item returned as the result of transformation of the root node
4836 */
4837
compile(THD * thd,Item_analyzer analyzer,uchar ** arg_p,Item_transformer transformer,uchar * arg_t)4838 Item *Item_cond::compile(THD *thd, Item_analyzer analyzer, uchar **arg_p,
4839 Item_transformer transformer, uchar *arg_t)
4840 {
4841 if (!(this->*analyzer)(arg_p))
4842 return 0;
4843
4844 List_iterator<Item> li(list);
4845 Item *item;
4846 while ((item= li++))
4847 {
4848 /*
4849 The same parameter value of arg_p must be passed
4850 to analyze any argument of the condition formula.
4851 */
4852 uchar *arg_v= *arg_p;
4853 Item *new_item= item->compile(thd, analyzer, &arg_v, transformer, arg_t);
4854 if (new_item && new_item != item)
4855 thd->change_item_tree(li.ref(), new_item);
4856 }
4857 return Item_func::transform(thd, transformer, arg_t);
4858 }
4859
4860
propagate_equal_fields(THD * thd,const Context & ctx,COND_EQUAL * cond)4861 Item *Item_cond::propagate_equal_fields(THD *thd,
4862 const Context &ctx,
4863 COND_EQUAL *cond)
4864 {
4865 DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
4866 DBUG_ASSERT(arg_count == 0);
4867 List_iterator<Item> li(list);
4868 while (li++)
4869 {
4870 /*
4871 The exact value of the last parameter to propagate_and_change_item_tree()
4872 is not important at this point. Item_func derivants will create and
4873 pass their own context to the arguments.
4874 */
4875 propagate_and_change_item_tree(thd, li.ref(), cond, Context_boolean());
4876 }
4877 return this;
4878 }
4879
traverse_cond(Cond_traverser traverser,void * arg,traverse_order order)4880 void Item_cond::traverse_cond(Cond_traverser traverser,
4881 void *arg, traverse_order order)
4882 {
4883 List_iterator<Item> li(list);
4884 Item *item;
4885
4886 switch(order) {
4887 case(PREFIX):
4888 (*traverser)(this, arg);
4889 while ((item= li++))
4890 {
4891 item->traverse_cond(traverser, arg, order);
4892 }
4893 (*traverser)(NULL, arg);
4894 break;
4895 case(POSTFIX):
4896 while ((item= li++))
4897 {
4898 item->traverse_cond(traverser, arg, order);
4899 }
4900 (*traverser)(this, arg);
4901 }
4902 }
4903
4904 /**
4905 Move SUM items out from item tree and replace with reference.
4906
4907 The split is done to get an unique item for each SUM function
4908 so that we can easily find and calculate them.
4909 (Calculation done by update_sum_func() and copy_sum_funcs() in
4910 sql_select.cc)
4911
4912 @param thd Thread handler
4913 @param ref_pointer_array Pointer to array of reference fields
4914 @param fields All fields in select
4915
4916 @note
4917 This function is run on all expression (SELECT list, WHERE, HAVING etc)
4918 that have or refer (HAVING) to a SUM expression.
4919 */
4920
split_sum_func(THD * thd,Ref_ptr_array ref_pointer_array,List<Item> & fields,uint flags)4921 void Item_cond::split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
4922 List<Item> &fields, uint flags)
4923 {
4924 List_iterator<Item> li(list);
4925 Item *item;
4926 while ((item= li++))
4927 item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(),
4928 flags | SPLIT_SUM_SKIP_REGISTERED);
4929 }
4930
4931
4932 table_map
used_tables() const4933 Item_cond::used_tables() const
4934 { // This caches used_tables
4935 return used_tables_cache;
4936 }
4937
4938
print(String * str,enum_query_type query_type)4939 void Item_cond::print(String *str, enum_query_type query_type)
4940 {
4941 List_iterator_fast<Item> li(list);
4942 Item *item;
4943 if ((item=li++))
4944 item->print_parenthesised(str, query_type, precedence());
4945 while ((item=li++))
4946 {
4947 str->append(' ');
4948 str->append(func_name());
4949 str->append(' ');
4950 item->print_parenthesised(str, query_type, precedence());
4951 }
4952 }
4953
4954
neg_arguments(THD * thd)4955 void Item_cond::neg_arguments(THD *thd)
4956 {
4957 List_iterator<Item> li(list);
4958 Item *item;
4959 while ((item= li++)) /* Apply not transformation to the arguments */
4960 {
4961 Item *new_item= item->neg_transformer(thd);
4962 if (!new_item)
4963 {
4964 if (!(new_item= new (thd->mem_root) Item_func_not(thd, item)))
4965 return; // Fatal OEM error
4966 }
4967 (void) li.replace(new_item);
4968 }
4969 }
4970
4971
4972 /**
4973 @brief
4974 Building clone for Item_cond
4975
4976 @param thd thread handle
4977 @param mem_root part of the memory for the clone
4978
4979 @details
4980 This method gets copy of the current item and also
4981 build clones for its elements. For this elements
4982 build_copy is called again.
4983
4984 @retval
4985 clone of the item
4986 0 if an error occurred
4987 */
4988
build_clone(THD * thd)4989 Item *Item_cond::build_clone(THD *thd)
4990 {
4991 List_iterator_fast<Item> li(list);
4992 Item *item;
4993 Item_cond *copy= (Item_cond *) get_copy(thd);
4994 if (!copy)
4995 return 0;
4996 copy->list.empty();
4997 while ((item= li++))
4998 {
4999 Item *arg_clone= item->build_clone(thd);
5000 if (!arg_clone)
5001 return 0;
5002 if (copy->list.push_back(arg_clone, thd->mem_root))
5003 return 0;
5004 }
5005 return copy;
5006 }
5007
5008
excl_dep_on_table(table_map tab_map)5009 bool Item_cond::excl_dep_on_table(table_map tab_map)
5010 {
5011 if (used_tables() & OUTER_REF_TABLE_BIT)
5012 return false;
5013 if (!(used_tables() & ~tab_map))
5014 return true;
5015 List_iterator_fast<Item> li(list);
5016 Item *item;
5017 while ((item= li++))
5018 {
5019 if (!item->excl_dep_on_table(tab_map))
5020 return false;
5021 }
5022 return true;
5023 }
5024
5025
excl_dep_on_grouping_fields(st_select_lex * sel)5026 bool Item_cond::excl_dep_on_grouping_fields(st_select_lex *sel)
5027 {
5028 List_iterator_fast<Item> li(list);
5029 Item *item;
5030 while ((item= li++))
5031 {
5032 if (!item->excl_dep_on_grouping_fields(sel))
5033 return false;
5034 }
5035 return true;
5036 }
5037
5038
mark_as_condition_AND_part(TABLE_LIST * embedding)5039 void Item_cond_and::mark_as_condition_AND_part(TABLE_LIST *embedding)
5040 {
5041 List_iterator<Item> li(list);
5042 Item *item;
5043 while ((item=li++))
5044 {
5045 item->mark_as_condition_AND_part(embedding);
5046 }
5047 }
5048
5049 /**
5050 Evaluation of AND(expr, expr, expr ...).
5051
5052 @note
5053 abort_if_null is set for AND expressions for which we don't care if the
5054 result is NULL or 0. This is set for:
5055 - WHERE clause
5056 - HAVING clause
5057 - IF(expression)
5058
5059 @retval
5060 1 If all expressions are true
5061 @retval
5062 0 If all expressions are false or if we find a NULL expression and
5063 'abort_on_null' is set.
5064 @retval
5065 NULL if all expression are either 1 or NULL
5066 */
5067
5068
val_int()5069 longlong Item_cond_and::val_int()
5070 {
5071 DBUG_ASSERT(fixed == 1);
5072 List_iterator_fast<Item> li(list);
5073 Item *item;
5074 null_value= 0;
5075 while ((item=li++))
5076 {
5077 if (!item->val_bool())
5078 {
5079 if (abort_on_null || !(null_value= item->null_value))
5080 return 0; // return FALSE
5081 }
5082 }
5083 return null_value ? 0 : 1;
5084 }
5085
5086
val_int()5087 longlong Item_cond_or::val_int()
5088 {
5089 DBUG_ASSERT(fixed == 1);
5090 List_iterator_fast<Item> li(list);
5091 Item *item;
5092 null_value=0;
5093 while ((item=li++))
5094 {
5095 if (item->val_bool())
5096 {
5097 null_value=0;
5098 return 1;
5099 }
5100 if (item->null_value)
5101 null_value=1;
5102 }
5103 return 0;
5104 }
5105
copy_andor_structure(THD * thd)5106 Item *Item_cond_or::copy_andor_structure(THD *thd)
5107 {
5108 Item_cond_or *item;
5109 if ((item= new (thd->mem_root) Item_cond_or(thd, this)))
5110 item->copy_andor_arguments(thd, this);
5111 return item;
5112 }
5113
5114
5115 /**
5116 Create an AND expression from two expressions.
5117
5118 @param a expression or NULL
5119 @param b expression.
5120 @param org_item Don't modify a if a == *org_item.
5121 If a == NULL, org_item is set to point at b,
5122 to ensure that future calls will not modify b.
5123
5124 @note
5125 This will not modify item pointed to by org_item or b
5126 The idea is that one can call this in a loop and create and
5127 'and' over all items without modifying any of the original items.
5128
5129 @retval
5130 NULL Error
5131 @retval
5132 Item
5133 */
5134
and_expressions(THD * thd,Item * a,Item * b,Item ** org_item)5135 Item *and_expressions(THD *thd, Item *a, Item *b, Item **org_item)
5136 {
5137 if (!a)
5138 return (*org_item= (Item*) b);
5139 if (a == *org_item)
5140 {
5141 Item_cond *res;
5142 if ((res= new (thd->mem_root) Item_cond_and(thd, a, (Item*) b)))
5143 {
5144 res->used_tables_cache= a->used_tables() | b->used_tables();
5145 res->not_null_tables_cache= a->not_null_tables() | b->not_null_tables();
5146 }
5147 return res;
5148 }
5149 if (((Item_cond_and*) a)->add((Item*) b, thd->mem_root))
5150 return 0;
5151 ((Item_cond_and*) a)->used_tables_cache|= b->used_tables();
5152 ((Item_cond_and*) a)->not_null_tables_cache|= b->not_null_tables();
5153 return a;
5154 }
5155
5156
count_sargable_conds(void * arg)5157 bool Item_func_null_predicate::count_sargable_conds(void *arg)
5158 {
5159 ((SELECT_LEX*) arg)->cond_count++;
5160 return 0;
5161 }
5162
5163
val_int()5164 longlong Item_func_isnull::val_int()
5165 {
5166 DBUG_ASSERT(fixed == 1);
5167 if (const_item() && !args[0]->maybe_null)
5168 return 0;
5169 return args[0]->is_null() ? 1: 0;
5170 }
5171
5172
print(String * str,enum_query_type query_type)5173 void Item_func_isnull::print(String *str, enum_query_type query_type)
5174 {
5175 if (const_item() && !args[0]->maybe_null &&
5176 !(query_type & (QT_NO_DATA_EXPANSION | QT_VIEW_INTERNAL)))
5177 str->append("/*always not null*/ 1");
5178 else
5179 args[0]->print_parenthesised(str, query_type, precedence());
5180 str->append(STRING_WITH_LEN(" is null"));
5181 }
5182
5183
val_int()5184 longlong Item_is_not_null_test::val_int()
5185 {
5186 DBUG_ASSERT(fixed == 1);
5187 DBUG_ENTER("Item_is_not_null_test::val_int");
5188 if (const_item() && !args[0]->maybe_null)
5189 DBUG_RETURN(1);
5190 if (args[0]->is_null())
5191 {
5192 DBUG_PRINT("info", ("null"));
5193 owner->was_null|= 1;
5194 DBUG_RETURN(0);
5195 }
5196 else
5197 DBUG_RETURN(1);
5198 }
5199
5200 /**
5201 Optimize case of not_null_column IS NULL.
5202 */
update_used_tables()5203 void Item_is_not_null_test::update_used_tables()
5204 {
5205 if (!args[0]->maybe_null)
5206 used_tables_cache= 0; /* is always true */
5207 else
5208 args[0]->update_used_tables();
5209 }
5210
5211
val_int()5212 longlong Item_func_isnotnull::val_int()
5213 {
5214 DBUG_ASSERT(fixed == 1);
5215 return args[0]->is_null() ? 0 : 1;
5216 }
5217
5218
print(String * str,enum_query_type query_type)5219 void Item_func_isnotnull::print(String *str, enum_query_type query_type)
5220 {
5221 args[0]->print_parenthesised(str, query_type, precedence());
5222 str->append(STRING_WITH_LEN(" is not null"));
5223 }
5224
5225
count_sargable_conds(void * arg)5226 bool Item_bool_func2::count_sargable_conds(void *arg)
5227 {
5228 ((SELECT_LEX*) arg)->cond_count++;
5229 return 0;
5230 }
5231
print(String * str,enum_query_type query_type)5232 void Item_func_like::print(String *str, enum_query_type query_type)
5233 {
5234 args[0]->print_parenthesised(str, query_type, precedence());
5235 str->append(' ');
5236 if (negated)
5237 str->append(STRING_WITH_LEN(" not "));
5238 str->append(func_name());
5239 str->append(' ');
5240 if (escape_used_in_parsing)
5241 {
5242 args[1]->print_parenthesised(str, query_type, precedence());
5243 str->append(STRING_WITH_LEN(" escape "));
5244 escape_item->print_parenthesised(str, query_type, higher_precedence());
5245 }
5246 else
5247 args[1]->print_parenthesised(str, query_type, higher_precedence());
5248 }
5249
5250
val_int()5251 longlong Item_func_like::val_int()
5252 {
5253 DBUG_ASSERT(fixed == 1);
5254 DBUG_ASSERT(escape != ESCAPE_NOT_INITIALIZED);
5255 String* res= args[0]->val_str(&cmp_value1);
5256 if (args[0]->null_value)
5257 {
5258 null_value=1;
5259 return 0;
5260 }
5261 String* res2= args[1]->val_str(&cmp_value2);
5262 if (args[1]->null_value)
5263 {
5264 null_value=1;
5265 return 0;
5266 }
5267 null_value=0;
5268 if (canDoTurboBM)
5269 return turboBM_matches(res->ptr(), res->length()) ? !negated : negated;
5270 return my_wildcmp(cmp_collation.collation,
5271 res->ptr(),res->ptr()+res->length(),
5272 res2->ptr(),res2->ptr()+res2->length(),
5273 escape,wild_one,wild_many) ? negated : !negated;
5274 }
5275
5276
5277 /**
5278 We can optimize a where if first character isn't a wildcard
5279 */
5280
with_sargable_pattern() const5281 bool Item_func_like::with_sargable_pattern() const
5282 {
5283 if (negated)
5284 return false;
5285
5286 if (!args[1]->const_item() || args[1]->is_expensive())
5287 return false;
5288
5289 String* res2= args[1]->val_str((String *) &cmp_value2);
5290 if (!res2)
5291 return false;
5292
5293 if (!res2->length()) // Can optimize empty wildcard: column LIKE ''
5294 return true;
5295
5296 DBUG_ASSERT(res2->ptr());
5297 char first= res2->ptr()[0];
5298 return first != wild_many && first != wild_one;
5299 }
5300
5301
5302 /*
5303 subject LIKE pattern
5304 removes subject's dependency on PAD_CHAR_TO_FULL_LENGTH
5305 if pattern ends with the '%' wildcard.
5306 */
value_depends_on_sql_mode() const5307 Sql_mode_dependency Item_func_like::value_depends_on_sql_mode() const
5308 {
5309 if (!args[1]->value_depends_on_sql_mode_const_item())
5310 return Item_func::value_depends_on_sql_mode();
5311 StringBuffer<64> patternbuf;
5312 String *pattern= args[1]->val_str_ascii(&patternbuf);
5313 if (!pattern || !pattern->length())
5314 return Sql_mode_dependency(); // Will return NULL or 0
5315 DBUG_ASSERT(pattern->charset()->mbminlen == 1);
5316 if (pattern->ptr()[pattern->length() - 1] != '%')
5317 return Item_func::value_depends_on_sql_mode();
5318 return ((args[0]->value_depends_on_sql_mode() |
5319 args[1]->value_depends_on_sql_mode()) &
5320 Sql_mode_dependency(~0, ~MODE_PAD_CHAR_TO_FULL_LENGTH)).
5321 soft_to_hard();
5322 }
5323
5324
get_mm_tree(RANGE_OPT_PARAM * param,Item ** cond_ptr)5325 SEL_TREE *Item_func_like::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
5326 {
5327 MEM_ROOT *tmp_root= param->mem_root;
5328 param->thd->mem_root= param->old_root;
5329 bool sargable_pattern= with_sargable_pattern();
5330 param->thd->mem_root= tmp_root;
5331 return sargable_pattern ?
5332 Item_bool_func2::get_mm_tree(param, cond_ptr) :
5333 Item_func::get_mm_tree(param, cond_ptr);
5334 }
5335
5336
fix_escape_item(THD * thd,Item * escape_item,String * tmp_str,bool escape_used_in_parsing,CHARSET_INFO * cmp_cs,int * escape)5337 bool fix_escape_item(THD *thd, Item *escape_item, String *tmp_str,
5338 bool escape_used_in_parsing, CHARSET_INFO *cmp_cs,
5339 int *escape)
5340 {
5341 /*
5342 ESCAPE clause accepts only constant arguments and Item_param.
5343
5344 Subqueries during context_analysis_only might decide they're
5345 const_during_execution, but not quite const yet, not evaluate-able.
5346 This is fine, as most of context_analysis_only modes will never
5347 reach val_int(), so we won't need the value.
5348 CONTEXT_ANALYSIS_ONLY_DERIVED being a notable exception here.
5349 */
5350 if (!escape_item->const_during_execution() ||
5351 (!escape_item->const_item() &&
5352 !(thd->lex->context_analysis_only & ~CONTEXT_ANALYSIS_ONLY_DERIVED)))
5353 {
5354 my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
5355 return TRUE;
5356 }
5357
5358 IF_DBUG(*escape= ESCAPE_NOT_INITIALIZED,);
5359
5360 if (escape_item->const_item())
5361 {
5362 /* If we are on execution stage */
5363 /* XXX is it safe to evaluate is_expensive() items here? */
5364 String *escape_str= escape_item->val_str(tmp_str);
5365 if (escape_str)
5366 {
5367 const char *escape_str_ptr= escape_str->ptr();
5368 if (escape_used_in_parsing && (
5369 (((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
5370 escape_str->numchars() != 1) ||
5371 escape_str->numchars() > 1)))
5372 {
5373 my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
5374 return TRUE;
5375 }
5376
5377 if (use_mb(cmp_cs))
5378 {
5379 CHARSET_INFO *cs= escape_str->charset();
5380 my_wc_t wc;
5381 int rc= cs->cset->mb_wc(cs, &wc,
5382 (const uchar*) escape_str_ptr,
5383 (const uchar*) escape_str_ptr +
5384 escape_str->length());
5385 *escape= (int) (rc > 0 ? wc : '\\');
5386 }
5387 else
5388 {
5389 /*
5390 In the case of 8bit character set, we pass native
5391 code instead of Unicode code as "escape" argument.
5392 Convert to "cs" if charset of escape differs.
5393 */
5394 uint32 unused;
5395 if (escape_str->needs_conversion(escape_str->length(),
5396 escape_str->charset(),cmp_cs,&unused))
5397 {
5398 char ch;
5399 uint errors;
5400 uint32 cnvlen= copy_and_convert(&ch, 1, cmp_cs, escape_str_ptr,
5401 escape_str->length(),
5402 escape_str->charset(), &errors);
5403 *escape= cnvlen ? ch : '\\';
5404 }
5405 else
5406 *escape= escape_str_ptr ? *escape_str_ptr : '\\';
5407 }
5408 }
5409 else
5410 *escape= '\\';
5411 }
5412
5413 return FALSE;
5414 }
5415
fix_fields(THD * thd,Item ** ref)5416 bool Item_func_like::fix_fields(THD *thd, Item **ref)
5417 {
5418 DBUG_ASSERT(fixed == 0);
5419 if (Item_bool_func2::fix_fields(thd, ref) ||
5420 escape_item->fix_fields_if_needed_for_scalar(thd, &escape_item) ||
5421 fix_escape_item(thd, escape_item, &cmp_value1, escape_used_in_parsing,
5422 cmp_collation.collation, &escape))
5423 return TRUE;
5424
5425 if (escape_item->const_item())
5426 {
5427 /*
5428 We could also do boyer-more for non-const items, but as we would have to
5429 recompute the tables for each row it's not worth it.
5430 */
5431 if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
5432 !args[1]->is_expensive())
5433 {
5434 String* res2= args[1]->val_str(&cmp_value2);
5435 if (!res2)
5436 return FALSE; // Null argument
5437
5438 const size_t len = res2->length();
5439 const char* first = res2->ptr();
5440 const char* last = first + len - 1;
5441 /*
5442 len must be > 2 ('%pattern%')
5443 heuristic: only do TurboBM for pattern_len > 2
5444 */
5445
5446 if (len > MIN_TURBOBM_PATTERN_LEN + 2 &&
5447 *first == wild_many &&
5448 *last == wild_many)
5449 {
5450 const char* tmp = first + 1;
5451 for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
5452 canDoTurboBM = (tmp == last) && !use_mb(args[0]->collation.collation);
5453 }
5454 if (canDoTurboBM)
5455 {
5456 pattern_len = (int) len - 2;
5457 pattern = thd->strmake(first + 1, pattern_len);
5458 DBUG_PRINT("info", ("Initializing pattern: '%s'", first));
5459 int *suff = (int*) thd->alloc((int) (sizeof(int)*
5460 ((pattern_len + 1)*2+
5461 alphabet_size)));
5462 bmGs = suff + pattern_len + 1;
5463 bmBc = bmGs + pattern_len + 1;
5464 turboBM_compute_good_suffix_shifts(suff);
5465 turboBM_compute_bad_character_shifts();
5466 DBUG_PRINT("info",("done"));
5467 }
5468 use_sampling= (len > 2 && (*first == wild_many || *first == wild_one));
5469 }
5470 }
5471 return FALSE;
5472 }
5473
5474
cleanup()5475 void Item_func_like::cleanup()
5476 {
5477 canDoTurboBM= FALSE;
5478 Item_bool_func2::cleanup();
5479 }
5480
5481
find_selective_predicates_list_processor(void * arg)5482 bool Item_func_like::find_selective_predicates_list_processor(void *arg)
5483 {
5484 find_selective_predicates_list_processor_data *data=
5485 (find_selective_predicates_list_processor_data *) arg;
5486 if (use_sampling && used_tables() == data->table->map)
5487 {
5488 THD *thd= data->table->in_use;
5489 COND_STATISTIC *stat;
5490 Item *arg0;
5491 if (!(stat= (COND_STATISTIC *) thd->alloc(sizeof(COND_STATISTIC))))
5492 return TRUE;
5493 stat->cond= this;
5494 arg0= args[0]->real_item();
5495 if (args[1]->const_item() && arg0->type() == FIELD_ITEM)
5496 stat->field_arg= ((Item_field *)arg0)->field;
5497 else
5498 stat->field_arg= NULL;
5499 data->list.push_back(stat, thd->mem_root);
5500 }
5501 return FALSE;
5502 }
5503
5504
default_regex_flags()5505 int Regexp_processor_pcre::default_regex_flags()
5506 {
5507 return default_regex_flags_pcre(current_thd);
5508 }
5509
set_recursion_limit(THD * thd)5510 void Regexp_processor_pcre::set_recursion_limit(THD *thd)
5511 {
5512 long stack_used;
5513 DBUG_ASSERT(thd == current_thd);
5514 stack_used= available_stack_size(thd->thread_stack, &stack_used);
5515 m_pcre_extra.match_limit_recursion=
5516 (ulong)((my_thread_stack_size - STACK_MIN_SIZE - stack_used)/my_pcre_frame_size);
5517 }
5518
5519
5520 /**
5521 Convert string to lib_charset, if needed.
5522 */
convert_if_needed(String * str,String * converter)5523 String *Regexp_processor_pcre::convert_if_needed(String *str, String *converter)
5524 {
5525 if (m_conversion_is_needed)
5526 {
5527 uint dummy_errors;
5528 if (converter->copy(str->ptr(), str->length(), str->charset(),
5529 m_library_charset, &dummy_errors))
5530 return NULL;
5531 str= converter;
5532 }
5533 return str;
5534 }
5535
5536
5537 /**
5538 @brief Compile regular expression.
5539
5540 @param[in] pattern the pattern to compile from.
5541 @param[in] send_error send error message if any.
5542
5543 @details Make necessary character set conversion then
5544 compile regular expression passed in the args[1].
5545
5546 @retval false success.
5547 @retval true error occurred.
5548 */
5549
compile(String * pattern,bool send_error)5550 bool Regexp_processor_pcre::compile(String *pattern, bool send_error)
5551 {
5552 const char *pcreErrorStr;
5553 int pcreErrorOffset;
5554
5555 if (is_compiled())
5556 {
5557 if (!stringcmp(pattern, &m_prev_pattern))
5558 return false;
5559 cleanup();
5560 m_prev_pattern.copy(*pattern);
5561 }
5562
5563 if (!(pattern= convert_if_needed(pattern, &pattern_converter)))
5564 return true;
5565
5566 m_pcre= pcre_compile(pattern->c_ptr_safe(), m_library_flags,
5567 &pcreErrorStr, &pcreErrorOffset, NULL);
5568
5569 if (unlikely(m_pcre == NULL))
5570 {
5571 if (send_error)
5572 {
5573 char buff[MAX_FIELD_WIDTH];
5574 my_snprintf(buff, sizeof(buff), "%s at offset %d", pcreErrorStr, pcreErrorOffset);
5575 my_error(ER_REGEXP_ERROR, MYF(0), buff);
5576 }
5577 return true;
5578 }
5579 return false;
5580 }
5581
5582
compile(Item * item,bool send_error)5583 bool Regexp_processor_pcre::compile(Item *item, bool send_error)
5584 {
5585 char buff[MAX_FIELD_WIDTH];
5586 String tmp(buff, sizeof(buff), &my_charset_bin);
5587 String *pattern= item->val_str(&tmp);
5588 if (unlikely(item->null_value) || (unlikely(compile(pattern, send_error))))
5589 return true;
5590 return false;
5591 }
5592
5593
5594 /**
5595 Send a warning explaining an error code returned by pcre_exec().
5596 */
pcre_exec_warn(int rc) const5597 void Regexp_processor_pcre::pcre_exec_warn(int rc) const
5598 {
5599 char buf[64];
5600 const char *errmsg= NULL;
5601 THD *thd= current_thd;
5602
5603 /*
5604 Make a descriptive message only for those pcre_exec() error codes
5605 that can actually happen in MariaDB.
5606 */
5607 switch (rc)
5608 {
5609 case PCRE_ERROR_NULL:
5610 errmsg= "pcre_exec: null argument passed";
5611 break;
5612 case PCRE_ERROR_BADOPTION:
5613 errmsg= "pcre_exec: bad option";
5614 break;
5615 case PCRE_ERROR_BADMAGIC:
5616 errmsg= "pcre_exec: bad magic - not a compiled regex";
5617 break;
5618 case PCRE_ERROR_UNKNOWN_OPCODE:
5619 errmsg= "pcre_exec: error in compiled regex";
5620 break;
5621 case PCRE_ERROR_NOMEMORY:
5622 errmsg= "pcre_exec: Out of memory";
5623 break;
5624 case PCRE_ERROR_NOSUBSTRING:
5625 errmsg= "pcre_exec: no substring";
5626 break;
5627 case PCRE_ERROR_MATCHLIMIT:
5628 errmsg= "pcre_exec: match limit exceeded";
5629 break;
5630 case PCRE_ERROR_CALLOUT:
5631 errmsg= "pcre_exec: callout error";
5632 break;
5633 case PCRE_ERROR_BADUTF8:
5634 errmsg= "pcre_exec: Invalid utf8 byte sequence in the subject string";
5635 break;
5636 case PCRE_ERROR_BADUTF8_OFFSET:
5637 errmsg= "pcre_exec: Started at invalid location within utf8 byte sequence";
5638 break;
5639 case PCRE_ERROR_PARTIAL:
5640 errmsg= "pcre_exec: partial match";
5641 break;
5642 case PCRE_ERROR_INTERNAL:
5643 errmsg= "pcre_exec: internal error";
5644 break;
5645 case PCRE_ERROR_BADCOUNT:
5646 errmsg= "pcre_exec: ovesize is negative";
5647 break;
5648 case PCRE_ERROR_RECURSIONLIMIT:
5649 my_snprintf(buf, sizeof(buf), "pcre_exec: recursion limit of %ld exceeded",
5650 m_pcre_extra.match_limit_recursion);
5651 errmsg= buf;
5652 break;
5653 case PCRE_ERROR_BADNEWLINE:
5654 errmsg= "pcre_exec: bad newline options";
5655 break;
5656 case PCRE_ERROR_BADOFFSET:
5657 errmsg= "pcre_exec: start offset negative or greater than string length";
5658 break;
5659 case PCRE_ERROR_SHORTUTF8:
5660 errmsg= "pcre_exec: ended in middle of utf8 sequence";
5661 break;
5662 case PCRE_ERROR_JIT_STACKLIMIT:
5663 errmsg= "pcre_exec: insufficient stack memory for JIT compile";
5664 break;
5665 case PCRE_ERROR_RECURSELOOP:
5666 errmsg= "pcre_exec: Recursion loop detected";
5667 break;
5668 case PCRE_ERROR_BADMODE:
5669 errmsg= "pcre_exec: compiled pattern passed to wrong bit library function";
5670 break;
5671 case PCRE_ERROR_BADENDIANNESS:
5672 errmsg= "pcre_exec: compiled pattern passed to wrong endianness processor";
5673 break;
5674 case PCRE_ERROR_JIT_BADOPTION:
5675 errmsg= "pcre_exec: bad jit option";
5676 break;
5677 case PCRE_ERROR_BADLENGTH:
5678 errmsg= "pcre_exec: negative length";
5679 break;
5680 default:
5681 /*
5682 As other error codes should normally not happen,
5683 we just report the error code without textual description
5684 of the code.
5685 */
5686 my_snprintf(buf, sizeof(buf), "pcre_exec: Internal error (%d)", rc);
5687 errmsg= buf;
5688 }
5689 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
5690 ER_REGEXP_ERROR, ER_THD(thd, ER_REGEXP_ERROR), errmsg);
5691 }
5692
5693
5694 /**
5695 Call pcre_exec() and send a warning if pcre_exec() returned with an error.
5696 */
pcre_exec_with_warn(const pcre * code,const pcre_extra * extra,const char * subject,int length,int startoffset,int options,int * ovector,int ovecsize)5697 int Regexp_processor_pcre::pcre_exec_with_warn(const pcre *code,
5698 const pcre_extra *extra,
5699 const char *subject,
5700 int length, int startoffset,
5701 int options, int *ovector,
5702 int ovecsize)
5703 {
5704 int rc= pcre_exec(code, extra, subject, length,
5705 startoffset, options, ovector, ovecsize);
5706 DBUG_EXECUTE_IF("pcre_exec_error_123", rc= -123;);
5707 if (unlikely(rc < PCRE_ERROR_NOMATCH))
5708 pcre_exec_warn(rc);
5709 return rc;
5710 }
5711
5712
exec(const char * str,size_t length,size_t offset)5713 bool Regexp_processor_pcre::exec(const char *str, size_t length, size_t offset)
5714 {
5715 m_pcre_exec_rc= pcre_exec_with_warn(m_pcre, &m_pcre_extra, str, (int)length, (int)offset, 0,
5716 m_SubStrVec, array_elements(m_SubStrVec));
5717 return false;
5718 }
5719
5720
exec(String * str,int offset,uint n_result_offsets_to_convert)5721 bool Regexp_processor_pcre::exec(String *str, int offset,
5722 uint n_result_offsets_to_convert)
5723 {
5724 if (!(str= convert_if_needed(str, &subject_converter)))
5725 return true;
5726 m_pcre_exec_rc= pcre_exec_with_warn(m_pcre, &m_pcre_extra,
5727 str->c_ptr_safe(), str->length(),
5728 offset, 0,
5729 m_SubStrVec, array_elements(m_SubStrVec));
5730 if (m_pcre_exec_rc > 0)
5731 {
5732 uint i;
5733 for (i= 0; i < n_result_offsets_to_convert; i++)
5734 {
5735 /*
5736 Convert byte offset into character offset.
5737 */
5738 m_SubStrVec[i]= (int) str->charset()->cset->numchars(str->charset(),
5739 str->ptr(),
5740 str->ptr() +
5741 m_SubStrVec[i]);
5742 }
5743 }
5744 return false;
5745 }
5746
5747
exec(Item * item,int offset,uint n_result_offsets_to_convert)5748 bool Regexp_processor_pcre::exec(Item *item, int offset,
5749 uint n_result_offsets_to_convert)
5750 {
5751 char buff[MAX_FIELD_WIDTH];
5752 String tmp(buff,sizeof(buff),&my_charset_bin);
5753 String *res= item->val_str(&tmp);
5754 if (item->null_value)
5755 return true;
5756 return exec(res, offset, n_result_offsets_to_convert);
5757 }
5758
5759
fix_owner(Item_func * owner,Item * subject_arg,Item * pattern_arg)5760 void Regexp_processor_pcre::fix_owner(Item_func *owner,
5761 Item *subject_arg,
5762 Item *pattern_arg)
5763 {
5764 if (!is_compiled() && pattern_arg->const_item())
5765 {
5766 if (compile(pattern_arg, true))
5767 {
5768 owner->maybe_null= 1; // Will always return NULL
5769 return;
5770 }
5771 set_const(true);
5772 owner->maybe_null= subject_arg->maybe_null;
5773 }
5774 else
5775 owner->maybe_null= 1;
5776 }
5777
5778
fix_fields(THD * thd,Item ** ref)5779 bool Item_func_regex::fix_fields(THD *thd, Item **ref)
5780 {
5781 re.set_recursion_limit(thd);
5782 return Item_bool_func::fix_fields(thd, ref);
5783 }
5784
5785 bool
fix_length_and_dec()5786 Item_func_regex::fix_length_and_dec()
5787 {
5788 if (Item_bool_func::fix_length_and_dec() ||
5789 agg_arg_charsets_for_comparison(cmp_collation, args, 2))
5790 return TRUE;
5791
5792 re.init(cmp_collation.collation, 0);
5793 re.fix_owner(this, args[0], args[1]);
5794 return FALSE;
5795 }
5796
5797
val_int()5798 longlong Item_func_regex::val_int()
5799 {
5800 DBUG_ASSERT(fixed == 1);
5801 if ((null_value= re.recompile(args[1])))
5802 return 0;
5803
5804 if ((null_value= re.exec(args[0], 0, 0)))
5805 return 0;
5806
5807 return re.match();
5808 }
5809
5810
fix_fields(THD * thd,Item ** ref)5811 bool Item_func_regexp_instr::fix_fields(THD *thd, Item **ref)
5812 {
5813 re.set_recursion_limit(thd);
5814 return Item_int_func::fix_fields(thd, ref);
5815 }
5816
5817
5818 bool
fix_length_and_dec()5819 Item_func_regexp_instr::fix_length_and_dec()
5820 {
5821 if (agg_arg_charsets_for_comparison(cmp_collation, args, 2))
5822 return TRUE;
5823
5824 re.init(cmp_collation.collation, 0);
5825 re.fix_owner(this, args[0], args[1]);
5826 max_length= MY_INT32_NUM_DECIMAL_DIGITS; // See also Item_func_locate
5827 return FALSE;
5828 }
5829
5830
val_int()5831 longlong Item_func_regexp_instr::val_int()
5832 {
5833 DBUG_ASSERT(fixed == 1);
5834 if ((null_value= re.recompile(args[1])))
5835 return 0;
5836
5837 if ((null_value= re.exec(args[0], 0, 1)))
5838 return 0;
5839
5840 return re.match() ? re.subpattern_start(0) + 1 : 0;
5841 }
5842
5843
5844 #ifdef LIKE_CMP_TOUPPER
5845 #define likeconv(cs,A) (uchar) (cs)->toupper(A)
5846 #else
5847 #define likeconv(cs,A) (uchar) (cs)->sort_order[(uchar) (A)]
5848 #endif
5849
5850
5851 /**
5852 Precomputation dependent only on pattern_len.
5853 */
5854
turboBM_compute_suffixes(int * suff)5855 void Item_func_like::turboBM_compute_suffixes(int *suff)
5856 {
5857 const int plm1 = pattern_len - 1;
5858 int f = 0;
5859 int g = plm1;
5860 int *const splm1 = suff + plm1;
5861 CHARSET_INFO *cs= cmp_collation.collation;
5862
5863 *splm1 = pattern_len;
5864
5865 if (!cs->sort_order)
5866 {
5867 int i;
5868 for (i = pattern_len - 2; i >= 0; i--)
5869 {
5870 int tmp = *(splm1 + i - f);
5871 if (g < i && tmp < i - g)
5872 suff[i] = tmp;
5873 else
5874 {
5875 if (i < g)
5876 g = i; // g = MY_MIN(i, g)
5877 f = i;
5878 while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
5879 g--;
5880 suff[i] = f - g;
5881 }
5882 }
5883 }
5884 else
5885 {
5886 int i;
5887 for (i = pattern_len - 2; 0 <= i; --i)
5888 {
5889 int tmp = *(splm1 + i - f);
5890 if (g < i && tmp < i - g)
5891 suff[i] = tmp;
5892 else
5893 {
5894 if (i < g)
5895 g = i; // g = MY_MIN(i, g)
5896 f = i;
5897 while (g >= 0 &&
5898 likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
5899 g--;
5900 suff[i] = f - g;
5901 }
5902 }
5903 }
5904 }
5905
5906
5907 /**
5908 Precomputation dependent only on pattern_len.
5909 */
5910
turboBM_compute_good_suffix_shifts(int * suff)5911 void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
5912 {
5913 turboBM_compute_suffixes(suff);
5914
5915 int *end = bmGs + pattern_len;
5916 int *k;
5917 for (k = bmGs; k < end; k++)
5918 *k = pattern_len;
5919
5920 int tmp;
5921 int i;
5922 int j = 0;
5923 const int plm1 = pattern_len - 1;
5924 for (i = plm1; i > -1; i--)
5925 {
5926 if (suff[i] == i + 1)
5927 {
5928 for (tmp = plm1 - i; j < tmp; j++)
5929 {
5930 int *tmp2 = bmGs + j;
5931 if (*tmp2 == pattern_len)
5932 *tmp2 = tmp;
5933 }
5934 }
5935 }
5936
5937 int *tmp2;
5938 for (tmp = plm1 - i; j < tmp; j++)
5939 {
5940 tmp2 = bmGs + j;
5941 if (*tmp2 == pattern_len)
5942 *tmp2 = tmp;
5943 }
5944
5945 tmp2 = bmGs + plm1;
5946 for (i = 0; i <= pattern_len - 2; i++)
5947 *(tmp2 - suff[i]) = plm1 - i;
5948 }
5949
5950
5951 /**
5952 Precomputation dependent on pattern_len.
5953 */
5954
turboBM_compute_bad_character_shifts()5955 void Item_func_like::turboBM_compute_bad_character_shifts()
5956 {
5957 int *i;
5958 int *end = bmBc + alphabet_size;
5959 int j;
5960 const int plm1 = pattern_len - 1;
5961 CHARSET_INFO *cs= cmp_collation.collation;
5962
5963 for (i = bmBc; i < end; i++)
5964 *i = pattern_len;
5965
5966 if (!cs->sort_order)
5967 {
5968 for (j = 0; j < plm1; j++)
5969 bmBc[(uint) (uchar) pattern[j]] = plm1 - j;
5970 }
5971 else
5972 {
5973 for (j = 0; j < plm1; j++)
5974 bmBc[(uint) likeconv(cs,pattern[j])] = plm1 - j;
5975 }
5976 }
5977
5978
5979 /**
5980 Search for pattern in text.
5981
5982 @return
5983 returns true/false for match/no match
5984 */
5985
turboBM_matches(const char * text,int text_len) const5986 bool Item_func_like::turboBM_matches(const char* text, int text_len) const
5987 {
5988 int bcShift;
5989 int turboShift;
5990 int shift = pattern_len;
5991 int j = 0;
5992 int u = 0;
5993 CHARSET_INFO *cs= cmp_collation.collation;
5994
5995 const int plm1= pattern_len - 1;
5996 const int tlmpl= text_len - pattern_len;
5997
5998 /* Searching */
5999 if (!cs->sort_order)
6000 {
6001 while (j <= tlmpl)
6002 {
6003 int i= plm1;
6004 while (i >= 0 && pattern[i] == text[i + j])
6005 {
6006 i--;
6007 if (i == plm1 - shift)
6008 i-= u;
6009 }
6010 if (i < 0)
6011 return 1;
6012
6013 const int v= plm1 - i;
6014 turboShift = u - v;
6015 bcShift = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
6016 shift = MY_MAX(turboShift, bcShift);
6017 shift = MY_MAX(shift, bmGs[i]);
6018 if (shift == bmGs[i])
6019 u = MY_MIN(pattern_len - shift, v);
6020 else
6021 {
6022 if (turboShift < bcShift)
6023 shift = MY_MAX(shift, u + 1);
6024 u = 0;
6025 }
6026 j+= shift;
6027 }
6028 return 0;
6029 }
6030 else
6031 {
6032 while (j <= tlmpl)
6033 {
6034 int i= plm1;
6035 while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
6036 {
6037 i--;
6038 if (i == plm1 - shift)
6039 i-= u;
6040 }
6041 if (i < 0)
6042 return 1;
6043
6044 const int v= plm1 - i;
6045 turboShift = u - v;
6046 bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
6047 shift = MY_MAX(turboShift, bcShift);
6048 shift = MY_MAX(shift, bmGs[i]);
6049 if (shift == bmGs[i])
6050 u = MY_MIN(pattern_len - shift, v);
6051 else
6052 {
6053 if (turboShift < bcShift)
6054 shift = MY_MAX(shift, u + 1);
6055 u = 0;
6056 }
6057 j+= shift;
6058 }
6059 return 0;
6060 }
6061 }
6062
6063
6064 /**
6065 Make a logical XOR of the arguments.
6066
6067 If either operator is NULL, return NULL.
6068
6069 @todo
6070 (low priority) Change this to be optimized as: @n
6071 A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1) @n
6072 To be able to do this, we would however first have to extend the MySQL
6073 range optimizer to handle OR better.
6074
6075 @note
6076 As we don't do any index optimization on XOR this is not going to be
6077 very fast to use.
6078 */
6079
val_int()6080 longlong Item_func_xor::val_int()
6081 {
6082 DBUG_ASSERT(fixed == 1);
6083 int result= 0;
6084 null_value= false;
6085 for (uint i= 0; i < arg_count; i++)
6086 {
6087 result^= (args[i]->val_int() != 0);
6088 if (args[i]->null_value)
6089 {
6090 null_value= true;
6091 return 0;
6092 }
6093 }
6094 return result;
6095 }
6096
6097 /**
6098 Apply NOT transformation to the item and return a new one.
6099
6100
6101 Transform the item using next rules:
6102 @verbatim
6103 a AND b AND ... -> NOT(a) OR NOT(b) OR ...
6104 a OR b OR ... -> NOT(a) AND NOT(b) AND ...
6105 NOT(a) -> a
6106 a = b -> a != b
6107 a != b -> a = b
6108 a < b -> a >= b
6109 a >= b -> a < b
6110 a > b -> a <= b
6111 a <= b -> a > b
6112 IS NULL(a) -> IS NOT NULL(a)
6113 IS NOT NULL(a) -> IS NULL(a)
6114 @endverbatim
6115
6116 @param thd thread handler
6117
6118 @return
6119 New item or
6120 NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
6121 */
6122
neg_transformer(THD * thd)6123 Item *Item_func_not::neg_transformer(THD *thd) /* NOT(x) -> x */
6124 {
6125 return args[0];
6126 }
6127
6128
fix_fields(THD * thd,Item ** ref)6129 bool Item_func_not::fix_fields(THD *thd, Item **ref)
6130 {
6131 args[0]->under_not(this);
6132 if (args[0]->type() == FIELD_ITEM)
6133 {
6134 /* replace "NOT <field>" with "<field> == 0" */
6135 Query_arena backup, *arena;
6136 Item *new_item;
6137 bool rc= TRUE;
6138 arena= thd->activate_stmt_arena_if_needed(&backup);
6139 if ((new_item= new (thd->mem_root) Item_func_eq(thd, args[0], new (thd->mem_root) Item_int(thd, 0, 1))))
6140 {
6141 new_item->name= name;
6142 rc= (*ref= new_item)->fix_fields(thd, ref);
6143 }
6144 if (arena)
6145 thd->restore_active_arena(arena, &backup);
6146 return rc;
6147 }
6148 return Item_func::fix_fields(thd, ref);
6149 }
6150
6151
neg_transformer(THD * thd)6152 Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
6153 {
6154 Item *item= negated_item(thd);
6155 return item;
6156 }
6157
6158 /**
6159 XOR can be negated by negating one of the operands:
6160
6161 NOT (a XOR b) => (NOT a) XOR b
6162 => a XOR (NOT b)
6163
6164 @param thd Thread handle
6165 @return New negated item
6166 */
neg_transformer(THD * thd)6167 Item *Item_func_xor::neg_transformer(THD *thd)
6168 {
6169 Item *neg_operand;
6170 Item_func_xor *new_item;
6171 if ((neg_operand= args[0]->neg_transformer(thd)))
6172 // args[0] has neg_tranformer
6173 new_item= new(thd->mem_root) Item_func_xor(thd, neg_operand, args[1]);
6174 else if ((neg_operand= args[1]->neg_transformer(thd)))
6175 // args[1] has neg_tranformer
6176 new_item= new(thd->mem_root) Item_func_xor(thd, args[0], neg_operand);
6177 else
6178 {
6179 neg_operand= new(thd->mem_root) Item_func_not(thd, args[0]);
6180 new_item= new(thd->mem_root) Item_func_xor(thd, neg_operand, args[1]);
6181 }
6182 return new_item;
6183 }
6184
6185
6186 /**
6187 a IS NULL -> a IS NOT NULL.
6188 */
neg_transformer(THD * thd)6189 Item *Item_func_isnull::neg_transformer(THD *thd)
6190 {
6191 Item *item= new (thd->mem_root) Item_func_isnotnull(thd, args[0]);
6192 return item;
6193 }
6194
6195
6196 /**
6197 a IS NOT NULL -> a IS NULL.
6198 */
neg_transformer(THD * thd)6199 Item *Item_func_isnotnull::neg_transformer(THD *thd)
6200 {
6201 Item *item= new (thd->mem_root) Item_func_isnull(thd, args[0]);
6202 return item;
6203 }
6204
6205
neg_transformer(THD * thd)6206 Item *Item_cond_and::neg_transformer(THD *thd) /* NOT(a AND b AND ...) -> */
6207 /* NOT a OR NOT b OR ... */
6208 {
6209 neg_arguments(thd);
6210 Item *item= new (thd->mem_root) Item_cond_or(thd, list);
6211 return item;
6212 }
6213
6214
neg_transformer(THD * thd)6215 Item *Item_cond_or::neg_transformer(THD *thd) /* NOT(a OR b OR ...) -> */
6216 /* NOT a AND NOT b AND ... */
6217 {
6218 neg_arguments(thd);
6219 Item *item= new (thd->mem_root) Item_cond_and(thd, list);
6220 return item;
6221 }
6222
6223
neg_transformer(THD * thd)6224 Item *Item_func_nop_all::neg_transformer(THD *thd)
6225 {
6226 /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
6227 Item_func_not_all *new_item= new (thd->mem_root) Item_func_not_all(thd, args[0]);
6228 Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
6229 allany->create_comp_func(FALSE);
6230 allany->all= !allany->all;
6231 allany->upper_item= new_item;
6232 return new_item;
6233 }
6234
neg_transformer(THD * thd)6235 Item *Item_func_not_all::neg_transformer(THD *thd)
6236 {
6237 /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
6238 Item_func_nop_all *new_item= new (thd->mem_root) Item_func_nop_all(thd, args[0]);
6239 Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
6240 allany->all= !allany->all;
6241 allany->create_comp_func(TRUE);
6242 allany->upper_item= new_item;
6243 return new_item;
6244 }
6245
negated_item(THD * thd)6246 Item *Item_func_eq::negated_item(THD *thd) /* a = b -> a != b */
6247 {
6248 return new (thd->mem_root) Item_func_ne(thd, args[0], args[1]);
6249 }
6250
6251
negated_item(THD * thd)6252 Item *Item_func_ne::negated_item(THD *thd) /* a != b -> a = b */
6253 {
6254 return new (thd->mem_root) Item_func_eq(thd, args[0], args[1]);
6255 }
6256
6257
negated_item(THD * thd)6258 Item *Item_func_lt::negated_item(THD *thd) /* a < b -> a >= b */
6259 {
6260 return new (thd->mem_root) Item_func_ge(thd, args[0], args[1]);
6261 }
6262
6263
negated_item(THD * thd)6264 Item *Item_func_ge::negated_item(THD *thd) /* a >= b -> a < b */
6265 {
6266 return new (thd->mem_root) Item_func_lt(thd, args[0], args[1]);
6267 }
6268
6269
negated_item(THD * thd)6270 Item *Item_func_gt::negated_item(THD *thd) /* a > b -> a <= b */
6271 {
6272 return new (thd->mem_root) Item_func_le(thd, args[0], args[1]);
6273 }
6274
6275
negated_item(THD * thd)6276 Item *Item_func_le::negated_item(THD *thd) /* a <= b -> a > b */
6277 {
6278 return new (thd->mem_root) Item_func_gt(thd, args[0], args[1]);
6279 }
6280
6281 /**
6282 just fake method, should never be called.
6283 */
negated_item(THD * thd)6284 Item *Item_bool_rowready_func2::negated_item(THD *thd)
6285 {
6286 DBUG_ASSERT(0);
6287 return 0;
6288 }
6289
6290
6291 /**
6292 Construct a minimal multiple equality item
6293
6294 @param f1 the first equal item
6295 @param f2 the second equal item
6296 @param with_const_item TRUE if the first item is constant
6297
6298 @details
6299 The constructor builds a new item equal object for the equality f1=f2.
6300 One of the equal items can be constant. If this is the case it is passed
6301 always as the first parameter and the parameter with_const_item serves
6302 as an indicator of this case.
6303 Currently any non-constant parameter items must point to an item of the
6304 of the type Item_field or Item_direct_view_ref(Item_field).
6305 */
6306
Item_equal(THD * thd,const Type_handler * handler,Item * f1,Item * f2,bool with_const_item)6307 Item_equal::Item_equal(THD *thd, const Type_handler *handler,
6308 Item *f1, Item *f2, bool with_const_item):
6309 Item_bool_func(thd), eval_item(0), cond_false(0), cond_true(0),
6310 context_field(NULL), link_equal_fields(FALSE),
6311 m_compare_handler(handler),
6312 m_compare_collation(f2->collation.collation)
6313 {
6314 const_item_cache= 0;
6315 with_const= with_const_item;
6316 equal_items.push_back(f1, thd->mem_root);
6317 equal_items.push_back(f2, thd->mem_root);
6318 upper_levels= NULL;
6319 }
6320
6321
6322 /**
6323 Copy constructor for a multiple equality
6324
6325 @param item_equal source item for the constructor
6326
6327 @details
6328 The function creates a copy of an Item_equal object.
6329 This constructor is used when an item belongs to a multiple equality
6330 of an upper level (an upper AND/OR level or an upper level of a nested
6331 outer join).
6332 */
6333
Item_equal(THD * thd,Item_equal * item_equal)6334 Item_equal::Item_equal(THD *thd, Item_equal *item_equal):
6335 Item_bool_func(thd), eval_item(0), cond_false(0), cond_true(0),
6336 context_field(NULL), link_equal_fields(FALSE),
6337 m_compare_handler(item_equal->m_compare_handler),
6338 m_compare_collation(item_equal->m_compare_collation)
6339 {
6340 const_item_cache= 0;
6341 List_iterator_fast<Item> li(item_equal->equal_items);
6342 Item *item;
6343 while ((item= li++))
6344 {
6345 equal_items.push_back(item, thd->mem_root);
6346 }
6347 with_const= item_equal->with_const;
6348 cond_false= item_equal->cond_false;
6349 upper_levels= item_equal->upper_levels;
6350 }
6351
6352
6353 /**
6354 @brief
6355 Add a constant item to the Item_equal object
6356
6357 @param[in] c the constant to add
6358 @param[in] f item from the list equal_items the item c is equal to
6359 (this parameter is optional)
6360
6361 @details
6362 The method adds the constant item c to the equal_items list. If the list
6363 doesn't have any constant item yet the item c is just put in the front
6364 the list. Otherwise the value of c is compared with the value of the
6365 constant item from equal_items. If they are not equal cond_false is set
6366 to TRUE. This serves as an indicator that this Item_equal is always FALSE.
6367 */
6368
add_const(THD * thd,Item * c)6369 void Item_equal::add_const(THD *thd, Item *c)
6370 {
6371 if (cond_false)
6372 return;
6373 if (!with_const)
6374 {
6375 with_const= TRUE;
6376 equal_items.push_front(c, thd->mem_root);
6377 return;
6378 }
6379 Item *const_item= get_const();
6380 switch (Item_equal::compare_type_handler()->cmp_type()) {
6381 case TIME_RESULT:
6382 {
6383 enum_field_types f_type= context_field->field_type();
6384 longlong value0= c->val_temporal_packed(f_type);
6385 longlong value1= const_item->val_temporal_packed(f_type);
6386 cond_false= c->null_value || const_item->null_value || value0 != value1;
6387 break;
6388 }
6389 case STRING_RESULT:
6390 {
6391 String *str1, *str2;
6392 /*
6393 Suppose we have an expression (with a string type field) like this:
6394 WHERE field=const1 AND field=const2 ...
6395
6396 For all pairs field=constXXX we know that:
6397
6398 - Item_func_eq::fix_length_and_dec() performed collation and character
6399 set aggregation and added character set converters when needed.
6400 Note, the case like:
6401 WHERE field=const1 COLLATE latin1_bin AND field=const2
6402 is not handled here, because the field would be replaced to
6403 Item_func_set_collation, which cannot get into Item_equal.
6404 So all constXXX that are handled by Item_equal
6405 already have compatible character sets with "field".
6406
6407 - Also, Field_str::test_if_equality_guarantees_uniqueness() guarantees
6408 that the comparison collation of all equalities handled by Item_equal
6409 match the the collation of the field.
6410
6411 Therefore, at Item_equal::add_const() time all constants constXXX
6412 should be directly comparable to each other without an additional
6413 character set conversion.
6414 It's safe to do val_str() for "const_item" and "c" and compare
6415 them according to the collation of the *field*.
6416
6417 So in a script like this:
6418 CREATE TABLE t1 (a VARCHAR(10) COLLATE xxx);
6419 INSERT INTO t1 VALUES ('a'),('A');
6420 SELECT * FROM t1 WHERE a='a' AND a='A';
6421 Item_equal::add_const() effectively rewrites the condition to:
6422 SELECT * FROM t1 WHERE a='a' AND 'a' COLLATE xxx='A';
6423 and then to:
6424 SELECT * FROM t1 WHERE a='a'; // if the two constants were equal
6425 // e.g. in case of latin1_swedish_ci
6426 or to:
6427 SELECT * FROM t1 WHERE FALSE; // if the two constants were not equal
6428 // e.g. in case of latin1_bin
6429
6430 Note, both "const_item" and "c" can return NULL, e.g.:
6431 SELECT * FROM t1 WHERE a=NULL AND a='const';
6432 SELECT * FROM t1 WHERE a='const' AND a=NULL;
6433 SELECT * FROM t1 WHERE a='const' AND a=(SELECT MAX(a) FROM t2)
6434 */
6435 cond_false= !(str1= const_item->val_str(&cmp_value1)) ||
6436 !(str2= c->val_str(&cmp_value2)) ||
6437 !str1->eq(str2, compare_collation());
6438 break;
6439 }
6440 default:
6441 {
6442 Item_func_eq *func= new (thd->mem_root) Item_func_eq(thd, c, const_item);
6443 if (func->set_cmp_func())
6444 return;
6445 func->quick_fix_field();
6446 cond_false= !func->val_int();
6447 }
6448 }
6449 if (with_const && equal_items.elements == 1)
6450 cond_true= TRUE;
6451 if (cond_false || cond_true)
6452 const_item_cache= 1;
6453 }
6454
6455
6456 /**
6457 @brief
6458 Check whether a field is referred to in the multiple equality
6459
6460 @param field field whose occurrence is to be checked
6461
6462 @details
6463 The function checks whether field is referred to by one of the
6464 items from the equal_items list.
6465
6466 @retval
6467 1 if multiple equality contains a reference to field
6468 @retval
6469 0 otherwise
6470 */
6471
contains(Field * field)6472 bool Item_equal::contains(Field *field)
6473 {
6474 Item_equal_fields_iterator it(*this);
6475 while (it++)
6476 {
6477 if (field->eq(it.get_curr_field()))
6478 return 1;
6479 }
6480 return 0;
6481 }
6482
6483
6484 /**
6485 @brief
6486 Join members of another Item_equal object
6487
6488 @param item multiple equality whose members are to be joined
6489
6490 @details
6491 The function actually merges two multiple equalities. After this operation
6492 the Item_equal object additionally contains the field items of another item of
6493 the type Item_equal.
6494 If the optional constant items are not equal the cond_false flag is set to TRUE.
6495
6496 @notes
6497 The function is called for any equality f1=f2 such that f1 and f2 are items
6498 of the type Item_field or Item_direct_view_ref(Item_field), and, f1->field is
6499 referred to in the list this->equal_items, while the list item->equal_items
6500 contains a reference to f2->field.
6501 */
6502
merge(THD * thd,Item_equal * item)6503 void Item_equal::merge(THD *thd, Item_equal *item)
6504 {
6505 Item *c= item->get_const();
6506 if (c)
6507 item->equal_items.pop();
6508 equal_items.append(&item->equal_items);
6509 if (c)
6510 {
6511 /*
6512 The flag cond_false will be set to TRUE after this if
6513 the multiple equality already contains a constant and its
6514 value is not equal to the value of c.
6515 */
6516 add_const(thd, c);
6517 }
6518 cond_false|= item->cond_false;
6519 }
6520
6521
6522 /**
6523 @brief
6524 Merge members of another Item_equal object into this one
6525
6526 @param item multiple equality whose members are to be merged
6527 @param save_merged keep the list of equalities in 'item' intact
6528 (e.g. for other merges)
6529
6530 @details
6531 If the Item_equal 'item' happens to have some elements of the list
6532 of equal items belonging to 'this' object then the function merges
6533 the equal items from 'item' into this list.
6534 If both lists contains constants and they are different then
6535 the value of the cond_false flag is set to TRUE.
6536
6537 @retval
6538 1 the lists of equal items in 'item' and 'this' contain common elements
6539 @retval
6540 0 otherwise
6541
6542 @notes
6543 The method 'merge' just joins the list of equal items belonging to 'item'
6544 to the list of equal items belonging to this object assuming that the lists
6545 are disjoint. It would be more correct to call the method 'join'.
6546 The method 'merge_into_with_check' really merges two lists of equal items if
6547 they have common members.
6548 */
6549
merge_with_check(THD * thd,Item_equal * item,bool save_merged)6550 bool Item_equal::merge_with_check(THD *thd, Item_equal *item, bool save_merged)
6551 {
6552 bool intersected= FALSE;
6553 Item_equal_fields_iterator_slow fi(*item);
6554
6555 while (fi++)
6556 {
6557 if (contains(fi.get_curr_field()))
6558 {
6559 intersected= TRUE;
6560 if (!save_merged)
6561 fi.remove();
6562 }
6563 }
6564 if (intersected)
6565 {
6566 if (!save_merged)
6567 merge(thd, item);
6568 else
6569 {
6570 Item *c= item->get_const();
6571 if (c)
6572 add_const(thd, c);
6573 if (!cond_false)
6574 {
6575 Item *item;
6576 fi.rewind();
6577 while ((item= fi++))
6578 {
6579 if (!contains(fi.get_curr_field()))
6580 add(item, thd->mem_root);
6581 }
6582 }
6583 }
6584 }
6585 return intersected;
6586 }
6587
6588
6589 /**
6590 @brief
6591 Merge this object into a list of Item_equal objects
6592
6593 @param list the list of Item_equal objects to merge into
6594 @param save_merged keep the list of equalities in 'this' intact
6595 (e.g. for other merges)
6596 @param only_intersected do not merge if there are no common members
6597 in any of Item_equal objects from the list
6598 and this Item_equal
6599
6600 @details
6601 If the list of equal items from 'this' object contains common members
6602 with the lists of equal items belonging to Item_equal objects from 'list'
6603 then all involved Item_equal objects e1,...,ek are merged into one
6604 Item equal that replaces e1,...,ek in the 'list'. Otherwise, in the case
6605 when the value of the parameter only_if_intersected is false, this
6606 Item_equal is joined to the 'list'.
6607 */
6608
merge_into_list(THD * thd,List<Item_equal> * list,bool save_merged,bool only_intersected)6609 void Item_equal::merge_into_list(THD *thd, List<Item_equal> *list,
6610 bool save_merged,
6611 bool only_intersected)
6612 {
6613 Item_equal *item;
6614 List_iterator<Item_equal> it(*list);
6615 Item_equal *merge_into= NULL;
6616 while((item= it++))
6617 {
6618 if (!merge_into)
6619 {
6620 if (item->merge_with_check(thd, this, save_merged))
6621 merge_into= item;
6622 }
6623 else
6624 {
6625 if (merge_into->merge_with_check(thd, item, false))
6626 it.remove();
6627 }
6628 }
6629 if (!only_intersected && !merge_into)
6630 list->push_back(this, thd->mem_root);
6631 }
6632
6633
6634 /**
6635 @brief
6636 Order equal items of the multiple equality according to a sorting criteria
6637
6638 @param compare function to compare items from the equal_items list
6639 @param arg context extra parameter for the cmp function
6640
6641 @details
6642 The function performs ordering of the items from the equal_items list
6643 according to the criteria determined by the cmp callback parameter.
6644 If cmp(item1,item2,arg)<0 than item1 must be placed after item2.
6645
6646 @notes
6647 The function sorts equal items by the bubble sort algorithm.
6648 The list of field items is looked through and whenever two neighboring
6649 members follow in a wrong order they are swapped. This is performed
6650 again and again until we get all members in a right order.
6651 */
6652
sort(Item_field_cmpfunc compare,void * arg)6653 void Item_equal::sort(Item_field_cmpfunc compare, void *arg)
6654 {
6655 bubble_sort<Item>(&equal_items, compare, arg);
6656 }
6657
6658
6659 /**
6660 @brief
6661 Check appearance of new constant items in the multiple equality object
6662
6663 @details
6664 The function checks appearance of new constant items among the members
6665 of the equal_items list. Each new constant item is compared with
6666 the constant item from the list if there is any. If there is none the first
6667 new constant item is placed at the very beginning of the list and
6668 with_const is set to TRUE. If it happens that the compared constant items
6669 are unequal then the flag cond_false is set to TRUE.
6670
6671 @notes
6672 Currently this function is called only after substitution of constant tables.
6673 */
6674
update_const(THD * thd)6675 void Item_equal::update_const(THD *thd)
6676 {
6677 List_iterator<Item> it(equal_items);
6678 if (with_const)
6679 it++;
6680 Item *item;
6681 while ((item= it++))
6682 {
6683 if (item->const_item() && !item->is_expensive() &&
6684 /*
6685 Don't propagate constant status of outer-joined column.
6686 Such a constant status here is a result of:
6687 a) empty outer-joined table: in this case such a column has a
6688 value of NULL; but at the same time other arguments of
6689 Item_equal don't have to be NULLs and the value of the whole
6690 multiple equivalence expression doesn't have to be NULL or FALSE
6691 because of the outer join nature;
6692 or
6693 b) outer-joined table contains only 1 row: the result of
6694 this column is equal to a row field value *or* NULL.
6695 Both values are inacceptable as Item_equal constants.
6696 */
6697 !item->is_outer_field())
6698 {
6699 if (item == equal_items.head())
6700 with_const= TRUE;
6701 else
6702 {
6703 it.remove();
6704 add_const(thd, item);
6705 }
6706 }
6707 }
6708 }
6709
6710
6711 /**
6712 @brief
6713 Fix fields in a completely built multiple equality
6714
6715 @param thd currently not used thread handle
6716 @param ref not used
6717
6718 @details
6719 This function is called once the multiple equality has been built out of
6720 the WHERE/ON condition and no new members are expected to be added to the
6721 equal_items list anymore.
6722 As any implementation of the virtual fix_fields method the function
6723 calculates the cached values of not_null_tables_cache, used_tables_cache,
6724 const_item_cache and calls fix_length_and_dec().
6725 Additionally the function sets a reference to the Item_equal object in
6726 the non-constant items of the equal_items list unless such a reference has
6727 been already set.
6728
6729 @notes
6730 Currently this function is called only in the function
6731 build_equal_items_for_cond.
6732
6733 @retval
6734 FALSE always
6735 */
6736
fix_fields(THD * thd,Item ** ref)6737 bool Item_equal::fix_fields(THD *thd, Item **ref)
6738 {
6739 DBUG_ASSERT(fixed == 0);
6740 Item_equal_fields_iterator it(*this);
6741 Item *item;
6742 Field *first_equal_field= NULL;
6743 Field *last_equal_field= NULL;
6744 Field *prev_equal_field= NULL;
6745 not_null_tables_cache= used_tables_cache= 0;
6746 const_item_cache= 0;
6747 while ((item= it++))
6748 {
6749 table_map tmp_table_map;
6750 used_tables_cache|= item->used_tables();
6751 tmp_table_map= item->not_null_tables();
6752 not_null_tables_cache|= tmp_table_map;
6753 DBUG_ASSERT(!item->with_sum_func && !item->with_subquery());
6754 if (item->maybe_null)
6755 maybe_null= 1;
6756 if (!item->get_item_equal())
6757 item->set_item_equal(this);
6758 if (link_equal_fields && item->real_item()->type() == FIELD_ITEM)
6759 {
6760 last_equal_field= ((Item_field *) (item->real_item()))->field;
6761 if (!prev_equal_field)
6762 first_equal_field= last_equal_field;
6763 else
6764 prev_equal_field->next_equal_field= last_equal_field;
6765 prev_equal_field= last_equal_field;
6766 }
6767 }
6768 if (prev_equal_field && last_equal_field != first_equal_field)
6769 last_equal_field->next_equal_field= first_equal_field;
6770 if (fix_length_and_dec())
6771 return TRUE;
6772 fixed= 1;
6773 return FALSE;
6774 }
6775
6776
6777 /**
6778 Update the value of the used table attribute and other attributes
6779 */
6780
update_used_tables()6781 void Item_equal::update_used_tables()
6782 {
6783 not_null_tables_cache= used_tables_cache= 0;
6784 if ((const_item_cache= cond_false || cond_true))
6785 return;
6786 Item_equal_fields_iterator it(*this);
6787 Item *item;
6788 const_item_cache= 1;
6789 while ((item= it++))
6790 {
6791 item->update_used_tables();
6792 used_tables_cache|= item->used_tables();
6793 /* see commentary at Item_equal::update_const() */
6794 const_item_cache&= item->const_item() && !item->is_outer_field();
6795 }
6796 }
6797
6798
count_sargable_conds(void * arg)6799 bool Item_equal::count_sargable_conds(void *arg)
6800 {
6801 SELECT_LEX *sel= (SELECT_LEX *) arg;
6802 uint m= equal_items.elements;
6803 sel->cond_count+= m*(m-1);
6804 return 0;
6805 }
6806
6807
6808 /**
6809 @brief
6810 Evaluate multiple equality
6811
6812 @details
6813 The function evaluate multiple equality to a boolean value.
6814 The function ignores non-constant items from the equal_items list.
6815 The function returns 1 if all constant items from the list are equal.
6816 It returns 0 if there are unequal constant items in the list or
6817 one of the constant items is evaluated to NULL.
6818
6819 @notes
6820 Currently this function can be called only at the optimization
6821 stage after the constant table substitution, since all Item_equals
6822 are eliminated before the execution stage.
6823
6824 @retval
6825 0 multiple equality is always FALSE or NULL
6826 1 otherwise
6827 */
6828
val_int()6829 longlong Item_equal::val_int()
6830 {
6831 if (cond_false)
6832 return 0;
6833 if (cond_true)
6834 return 1;
6835 Item *item= get_const();
6836 Item_equal_fields_iterator it(*this);
6837 if (!item)
6838 item= it++;
6839 eval_item->store_value(item);
6840 if ((null_value= item->null_value))
6841 return 0;
6842 while ((item= it++))
6843 {
6844 Field *field= it.get_curr_field();
6845 /* Skip fields of tables that has not been read yet */
6846 if (!field->table->status || (field->table->status & STATUS_NULL_ROW))
6847 {
6848 const int rc= eval_item->cmp(item);
6849 if ((rc == TRUE) || (null_value= (rc == UNKNOWN)))
6850 return 0;
6851 }
6852 }
6853 return 1;
6854 }
6855
6856
fix_length_and_dec()6857 bool Item_equal::fix_length_and_dec()
6858 {
6859 Item *item= get_first(NO_PARTICULAR_TAB, NULL);
6860 const Type_handler *handler= item->type_handler();
6861 eval_item= handler->make_cmp_item(current_thd, item->collation.collation);
6862 return eval_item == NULL;
6863 }
6864
6865
walk(Item_processor processor,bool walk_subquery,void * arg)6866 bool Item_equal::walk(Item_processor processor, bool walk_subquery, void *arg)
6867 {
6868 Item *item;
6869 Item_equal_fields_iterator it(*this);
6870 while ((item= it++))
6871 {
6872 if (item->walk(processor, walk_subquery, arg))
6873 return 1;
6874 }
6875 return Item_func::walk(processor, walk_subquery, arg);
6876 }
6877
6878
transform(THD * thd,Item_transformer transformer,uchar * arg)6879 Item *Item_equal::transform(THD *thd, Item_transformer transformer, uchar *arg)
6880 {
6881 DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
6882
6883 Item *item;
6884 Item_equal_fields_iterator it(*this);
6885 while ((item= it++))
6886 {
6887 Item *new_item= item->transform(thd, transformer, arg);
6888 if (!new_item)
6889 return 0;
6890
6891 /*
6892 THD::change_item_tree() should be called only if the tree was
6893 really transformed, i.e. when a new item has been created.
6894 Otherwise we'll be allocating a lot of unnecessary memory for
6895 change records at each execution.
6896 */
6897 if (new_item != item)
6898 thd->change_item_tree((Item **) it.ref(), new_item);
6899 }
6900 return Item_func::transform(thd, transformer, arg);
6901 }
6902
6903
print(String * str,enum_query_type query_type)6904 void Item_equal::print(String *str, enum_query_type query_type)
6905 {
6906 if (cond_false)
6907 {
6908 str->append('0');
6909 return;
6910 }
6911 str->append(func_name());
6912 str->append('(');
6913 List_iterator_fast<Item> it(equal_items);
6914 Item *item;
6915 item= it++;
6916 item->print(str, query_type);
6917 while ((item= it++))
6918 {
6919 str->append(',');
6920 str->append(' ');
6921 item->print(str, query_type);
6922 }
6923 str->append(')');
6924 }
6925
6926
6927 /*
6928 @brief Get the first equal field of multiple equality.
6929 @param[in] field the field to get equal field to
6930
6931 @details Get the first field of multiple equality that is equal to the
6932 given field. In order to make semi-join materialization strategy work
6933 correctly we can't propagate equal fields from upper select to a
6934 materialized semi-join.
6935 Thus the fields is returned according to following rules:
6936
6937 1) If the given field belongs to a semi-join then the first field in
6938 multiple equality which belong to the same semi-join is returned.
6939 Otherwise NULL is returned.
6940 2) If the given field doesn't belong to a semi-join then
6941 the first field in the multiple equality that doesn't belong to any
6942 semi-join is returned.
6943 If all fields in the equality are belong to semi-join(s) then NULL
6944 is returned.
6945 3) If no field is given then the first field in the multiple equality
6946 is returned without regarding whether it belongs to a semi-join or not.
6947
6948 @retval Found first field in the multiple equality.
6949 @retval 0 if no field found.
6950 */
6951
get_first(JOIN_TAB * context,Item * field_item)6952 Item* Item_equal::get_first(JOIN_TAB *context, Item *field_item)
6953 {
6954 Item_equal_fields_iterator it(*this);
6955 Item *item;
6956 if (!field_item)
6957 return (it++);
6958 Field *field= ((Item_field *) (field_item->real_item()))->field;
6959
6960 /*
6961 Of all equal fields, return the first one we can use. Normally, this is the
6962 field which belongs to the table that is the first in the join order.
6963
6964 There is one exception to this: When semi-join materialization strategy is
6965 used, and the given field belongs to a table within the semi-join nest, we
6966 must pick the first field in the semi-join nest.
6967
6968 Example: suppose we have a join order:
6969
6970 ot1 ot2 SJ-Mat(it1 it2 it3) ot3
6971
6972 and equality ot2.col = it1.col = it2.col
6973 If we're looking for best substitute for 'it2.col', we should pick it1.col
6974 and not ot2.col.
6975
6976 eliminate_item_equal() also has code that deals with equality substitution
6977 in presence of SJM nests.
6978 */
6979
6980 TABLE_LIST *emb_nest;
6981 if (context != NO_PARTICULAR_TAB)
6982 emb_nest= context->emb_sj_nest;
6983 else
6984 emb_nest= field->table->pos_in_table_list->embedding;
6985
6986 if (emb_nest && emb_nest->sj_mat_info && emb_nest->sj_mat_info->is_used)
6987 {
6988 /*
6989 It's a field from an materialized semi-join. We can substitute it for
6990 - a constant item
6991 - a field from the same semi-join
6992 Find the first of such items:
6993 */
6994 while ((item= it++))
6995 {
6996 if (item->const_item() ||
6997 it.get_curr_field()->table->pos_in_table_list->embedding == emb_nest)
6998 {
6999 /*
7000 If we found given field then return NULL to avoid unnecessary
7001 substitution.
7002 */
7003 return (item != field_item) ? item : NULL;
7004 }
7005 }
7006 }
7007 else
7008 {
7009 /*
7010 The field is not in SJ-Materialization nest. We must return the first
7011 field in the join order. The field may be inside a semi-join nest, i.e
7012 a join order may look like this:
7013
7014 SJ-Mat(it1 it2) ot1 ot2
7015
7016 where we're looking what to substitute ot2.col for. In this case we must
7017 still return it1.col, here's a proof why:
7018
7019 First let's note that either it1.col or it2.col participates in
7020 subquery's IN-equality. It can't be otherwise, because materialization is
7021 only applicable to uncorrelated subqueries, so the only way we could
7022 infer "it1.col=ot1.col" is from the IN-equality. Ok, so IN-eqality has
7023 it1.col or it2.col on its inner side. it1.col is first such item in the
7024 join order, so it's not possible for SJ-Mat to be
7025 SJ-Materialization-lookup, it is SJ-Materialization-Scan. The scan part
7026 of this strategy will unpack value of it1.col=it2.col into it1.col
7027 (that's the first equal item inside the subquery), and we'll be able to
7028 get it from there. qed.
7029 */
7030
7031 return equal_items.head();
7032 }
7033 // Shouldn't get here.
7034 DBUG_ASSERT(0);
7035 return NULL;
7036 }
7037
7038
val_int()7039 longlong Item_func_dyncol_check::val_int()
7040 {
7041 char buff[STRING_BUFFER_USUAL_SIZE];
7042 String tmp(buff, sizeof(buff), &my_charset_bin);
7043 DYNAMIC_COLUMN col;
7044 String *str;
7045 enum enum_dyncol_func_result rc;
7046
7047 str= args[0]->val_str(&tmp);
7048 if (args[0]->null_value)
7049 goto null;
7050 col.length= str->length();
7051 /* We do not change the string, so could do this trick */
7052 col.str= (char *)str->ptr();
7053 rc= mariadb_dyncol_check(&col);
7054 if (rc < 0 && rc != ER_DYNCOL_FORMAT)
7055 {
7056 dynamic_column_error_message(rc);
7057 goto null;
7058 }
7059 null_value= FALSE;
7060 return rc == ER_DYNCOL_OK;
7061
7062 null:
7063 null_value= TRUE;
7064 return 0;
7065 }
7066
val_int()7067 longlong Item_func_dyncol_exists::val_int()
7068 {
7069 char buff[STRING_BUFFER_USUAL_SIZE], nmstrbuf[11];
7070 String tmp(buff, sizeof(buff), &my_charset_bin),
7071 nmbuf(nmstrbuf, sizeof(nmstrbuf), system_charset_info);
7072 DYNAMIC_COLUMN col;
7073 String *str;
7074 LEX_STRING buf, *name= NULL;
7075 ulonglong num= 0;
7076 enum enum_dyncol_func_result rc;
7077
7078 if (args[1]->result_type() == INT_RESULT)
7079 num= args[1]->val_int();
7080 else
7081 {
7082 String *nm= args[1]->val_str(&nmbuf);
7083 if (!nm || args[1]->null_value)
7084 {
7085 null_value= 1;
7086 return 1;
7087 }
7088 if (my_charset_same(nm->charset(), DYNCOL_UTF))
7089 {
7090 buf.str= (char *) nm->ptr();
7091 buf.length= nm->length();
7092 }
7093 else
7094 {
7095 uint strlen= nm->length() * DYNCOL_UTF->mbmaxlen + 1;
7096 uint dummy_errors;
7097 buf.str= (char *) current_thd->alloc(strlen);
7098 if (buf.str)
7099 {
7100 buf.length=
7101 copy_and_convert(buf.str, strlen, DYNCOL_UTF,
7102 nm->ptr(), nm->length(), nm->charset(),
7103 &dummy_errors);
7104 }
7105 else
7106 buf.length= 0;
7107 }
7108 name= &buf;
7109 }
7110 str= args[0]->val_str(&tmp);
7111 if (args[0]->null_value || args[1]->null_value || num > UINT_MAX16)
7112 goto null;
7113 col.length= str->length();
7114 /* We do not change the string, so could do this trick */
7115 col.str= (char *)str->ptr();
7116 rc= ((name == NULL) ?
7117 mariadb_dyncol_exists_num(&col, (uint) num) :
7118 mariadb_dyncol_exists_named(&col, name));
7119 if (rc < 0)
7120 {
7121 dynamic_column_error_message(rc);
7122 goto null;
7123 }
7124 null_value= FALSE;
7125 return rc == ER_DYNCOL_YES;
7126
7127 null:
7128 null_value= TRUE;
7129 return 0;
7130 }
7131
7132
create(THD * thd,Item * a,Item * b) const7133 Item_bool_rowready_func2 *Eq_creator::create(THD *thd, Item *a, Item *b) const
7134 {
7135 return new(thd->mem_root) Item_func_eq(thd, a, b);
7136 }
7137
7138
create_swap(THD * thd,Item * a,Item * b) const7139 Item_bool_rowready_func2* Eq_creator::create_swap(THD *thd, Item *a, Item *b) const
7140 {
7141 return new(thd->mem_root) Item_func_eq(thd, b, a);
7142 }
7143
7144
create(THD * thd,Item * a,Item * b) const7145 Item_bool_rowready_func2* Ne_creator::create(THD *thd, Item *a, Item *b) const
7146 {
7147 return new(thd->mem_root) Item_func_ne(thd, a, b);
7148 }
7149
7150
create_swap(THD * thd,Item * a,Item * b) const7151 Item_bool_rowready_func2* Ne_creator::create_swap(THD *thd, Item *a, Item *b) const
7152 {
7153 return new(thd->mem_root) Item_func_ne(thd, b, a);
7154 }
7155
7156
create(THD * thd,Item * a,Item * b) const7157 Item_bool_rowready_func2* Gt_creator::create(THD *thd, Item *a, Item *b) const
7158 {
7159 return new(thd->mem_root) Item_func_gt(thd, a, b);
7160 }
7161
7162
create_swap(THD * thd,Item * a,Item * b) const7163 Item_bool_rowready_func2* Gt_creator::create_swap(THD *thd, Item *a, Item *b) const
7164 {
7165 return new(thd->mem_root) Item_func_lt(thd, b, a);
7166 }
7167
7168
create(THD * thd,Item * a,Item * b) const7169 Item_bool_rowready_func2* Lt_creator::create(THD *thd, Item *a, Item *b) const
7170 {
7171 return new(thd->mem_root) Item_func_lt(thd, a, b);
7172 }
7173
7174
create_swap(THD * thd,Item * a,Item * b) const7175 Item_bool_rowready_func2* Lt_creator::create_swap(THD *thd, Item *a, Item *b) const
7176 {
7177 return new(thd->mem_root) Item_func_gt(thd, b, a);
7178 }
7179
7180
create(THD * thd,Item * a,Item * b) const7181 Item_bool_rowready_func2* Ge_creator::create(THD *thd, Item *a, Item *b) const
7182 {
7183 return new(thd->mem_root) Item_func_ge(thd, a, b);
7184 }
7185
7186
create_swap(THD * thd,Item * a,Item * b) const7187 Item_bool_rowready_func2* Ge_creator::create_swap(THD *thd, Item *a, Item *b) const
7188 {
7189 return new(thd->mem_root) Item_func_le(thd, b, a);
7190 }
7191
7192
create(THD * thd,Item * a,Item * b) const7193 Item_bool_rowready_func2* Le_creator::create(THD *thd, Item *a, Item *b) const
7194 {
7195 return new(thd->mem_root) Item_func_le(thd, a, b);
7196 }
7197
7198
create_swap(THD * thd,Item * a,Item * b) const7199 Item_bool_rowready_func2* Le_creator::create_swap(THD *thd, Item *a, Item *b) const
7200 {
7201 return new(thd->mem_root) Item_func_ge(thd, b, a);
7202 }
7203