1 /* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23
24 /**
25 @file
26
27 @brief
28 This file defines all compare functions
29 */
30
31 #include <m_ctype.h>
32 #include "sql_select.h"
33 #include "sql_optimizer.h" // JOIN_TAB
34 #include "sql_parse.h" // check_stack_overrun
35 #include "sql_time.h" // make_truncated_value_warning
36 #include "opt_trace.h"
37 #include "parse_tree_helpers.h"
38 #include "template_utils.h"
39 #include "item_json_func.h" // json_value, get_json_atom_wrapper
40
41 #include <algorithm>
42 using std::min;
43 using std::max;
44 #include "aggregate_check.h"
45
46 static bool convert_constant_item(THD *, Item_field *, Item **);
47 static longlong
48 get_year_value(THD *thd, Item ***item_arg, Item **cache_arg,
49 const Item *warn_item, bool *is_null);
50
item_store_type(Item_result a,Item * item,my_bool unsigned_flag)51 static Item_result item_store_type(Item_result a, Item *item,
52 my_bool unsigned_flag)
53 {
54 Item_result b= item->result_type();
55
56 if (a == STRING_RESULT || b == STRING_RESULT)
57 return STRING_RESULT;
58 else if (a == REAL_RESULT || b == REAL_RESULT)
59 return REAL_RESULT;
60 else if (a == DECIMAL_RESULT || b == DECIMAL_RESULT ||
61 unsigned_flag != item->unsigned_flag)
62 return DECIMAL_RESULT;
63 else
64 return INT_RESULT;
65 }
66
agg_result_type(Item_result * type,my_bool * unsigned_flag,Item ** items,uint nitems)67 static void agg_result_type(Item_result *type, my_bool *unsigned_flag,
68 Item **items, uint nitems)
69 {
70 Item **item, **item_end;
71
72 *type= STRING_RESULT;
73 *unsigned_flag= FALSE;
74 /* Skip beginning NULL items */
75 for (item= items, item_end= item + nitems; item < item_end; item++)
76 {
77 if ((*item)->type() != Item::NULL_ITEM)
78 {
79 *type= (*item)->result_type();
80 *unsigned_flag= (*item)->unsigned_flag;
81 item++;
82 break;
83 }
84 }
85 /* Combine result types. Note: NULL items don't affect the result */
86 for (; item < item_end; item++)
87 {
88 if ((*item)->type() != Item::NULL_ITEM)
89 {
90 *type= item_store_type(*type, *item, *unsigned_flag);
91 *unsigned_flag= *unsigned_flag && (*item)->unsigned_flag;
92 }
93 }
94 }
95
96
97 /*
98 Compare row signature of two expressions
99
100 SYNOPSIS:
101 cmp_row_type()
102 item1 the first expression
103 item2 the second expression
104
105 DESCRIPTION
106 The function checks that two expressions have compatible row signatures
107 i.e. that the number of columns they return are the same and that if they
108 are both row expressions then each component from the first expression has
109 a row signature compatible with the signature of the corresponding component
110 of the second expression.
111
112 RETURN VALUES
113 1 type incompatibility has been detected
114 0 otherwise
115 */
116
cmp_row_type(Item * item1,Item * item2)117 static int cmp_row_type(Item* item1, Item* item2)
118 {
119 uint n= item1->cols();
120 if (item2->check_cols(n))
121 return 1;
122 for (uint i=0; i<n; i++)
123 {
124 if (item2->element_index(i)->check_cols(item1->element_index(i)->cols()) ||
125 (item1->element_index(i)->result_type() == ROW_RESULT &&
126 cmp_row_type(item1->element_index(i), item2->element_index(i))))
127 return 1;
128 }
129 return 0;
130 }
131
132
133 /**
134 Aggregates result types from the array of items.
135
136 SYNOPSIS:
137 agg_cmp_type()
138 type [out] the aggregated type
139 items array of items to aggregate the type from
140 nitems number of items in the array
141
142 DESCRIPTION
143 This function aggregates result types from the array of items. Found type
144 supposed to be used later for comparison of values of these items.
145 Aggregation itself is performed by the item_cmp_type() function.
146 @param[out] type the aggregated type
147 @param items array of items to aggregate the type from
148 @param nitems number of items in the array
149
150 @retval
151 1 type incompatibility has been detected
152 @retval
153 0 otherwise
154 */
155
agg_cmp_type(Item_result * type,Item ** items,uint nitems)156 static int agg_cmp_type(Item_result *type, Item **items, uint nitems)
157 {
158 uint i;
159 type[0]= items[0]->result_type();
160 for (i= 1 ; i < nitems ; i++)
161 {
162 type[0]= item_cmp_type(type[0], items[i]->result_type());
163 /*
164 When aggregating types of two row expressions we have to check
165 that they have the same cardinality and that each component
166 of the first row expression has a compatible row signature with
167 the signature of the corresponding component of the second row
168 expression.
169 */
170 if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
171 return 1; // error found: invalid usage of rows
172 }
173 return 0;
174 }
175
176
177 /**
178 @brief Aggregates field types from the array of items.
179
180 @param[in] items array of items to aggregate the type from
181 @paran[in] nitems number of items in the array
182
183 @details This function aggregates field types from the array of items.
184 Found type is supposed to be used later as the result field type
185 of a multi-argument function.
186 Aggregation itself is performed by the Field::field_type_merge()
187 function.
188
189 @note The term "aggregation" is used here in the sense of inferring the
190 result type of a function from its argument types.
191
192 @return aggregated field type.
193 */
194
agg_field_type(Item ** items,uint nitems)195 enum_field_types agg_field_type(Item **items, uint nitems)
196 {
197 uint i;
198 if (!nitems || items[0]->result_type() == ROW_RESULT )
199 return (enum_field_types)-1;
200 enum_field_types res= items[0]->field_type();
201 for (i= 1 ; i < nitems ; i++)
202 res= Field::field_type_merge(res, items[i]->field_type());
203 return real_type_to_type(res);
204 }
205
206 /*
207 Collects different types for comparison of first item with each other items
208
209 SYNOPSIS
210 collect_cmp_types()
211 items Array of items to collect types from
212 nitems Number of items in the array
213 skip_nulls Don't collect types of NULL items if TRUE
214
215 DESCRIPTION
216 This function collects different result types for comparison of the first
217 item in the list with each of the remaining items in the 'items' array.
218
219 RETURN
220 0 - if row type incompatibility has been detected (see cmp_row_type)
221 Bitmap of collected types - otherwise
222 */
223
collect_cmp_types(Item ** items,uint nitems,bool skip_nulls=FALSE)224 static uint collect_cmp_types(Item **items, uint nitems, bool skip_nulls= FALSE)
225 {
226 uint i;
227 uint found_types;
228 Item_result left_result= items[0]->result_type();
229 DBUG_ASSERT(nitems > 1);
230 found_types= 0;
231 for (i= 1; i < nitems ; i++)
232 {
233 if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
234 continue; // Skip NULL constant items
235 if ((left_result == ROW_RESULT ||
236 items[i]->result_type() == ROW_RESULT) &&
237 cmp_row_type(items[0], items[i]))
238 return 0;
239 found_types|= 1U << (uint)item_cmp_type(left_result,
240 items[i]->result_type());
241 }
242 /*
243 Even if all right-hand items are NULLs and we are skipping them all, we need
244 at least one type bit in the found_type bitmask.
245 */
246 if (skip_nulls && !found_types)
247 found_types= 1U << (uint)left_result;
248 return found_types;
249 }
250
my_coll_agg_error(DTCollation & c1,DTCollation & c2,const char * fname)251 static void my_coll_agg_error(DTCollation &c1, DTCollation &c2,
252 const char *fname)
253 {
254 my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
255 c1.collation->name,c1.derivation_name(),
256 c2.collation->name,c2.derivation_name(),
257 fname);
258 }
259
260
261 /**
262 This implementation of the factory method also implements flattening of
263 row constructors. Examples of flattening are:
264
265 - ROW(a, b) op ROW(x, y) => a op x P b op y.
266 - ROW(a, ROW(b, c) op ROW(x, ROW(y, z))) => a op x P b op y P c op z.
267
268 P is either AND or OR, depending on the comparison operation, and this
269 detail is left for combine().
270
271 The actual operator @i op is created by the concrete subclass in
272 create_scalar_predicate().
273 */
create(Item * a,Item * b) const274 Item_bool_func *Linear_comp_creator::create(Item *a, Item *b) const
275 {
276 /*
277 Test if the arguments are row constructors and thus can be flattened into
278 a list of ANDs or ORs.
279 */
280 if (a->type() == Item::ROW_ITEM && b->type() == Item::ROW_ITEM)
281 {
282 if (a->cols() != b->cols())
283 {
284 my_error(ER_OPERAND_COLUMNS, MYF(0), a->cols());
285 return NULL;
286 }
287 DBUG_ASSERT(a->cols() > 1);
288 List<Item> list;
289 for (uint i= 0; i < a->cols(); ++i)
290 list.push_back(create(a->element_index(i), b->element_index(i)));
291 return combine(list);
292 }
293 return create_scalar_predicate(a, b);
294 }
295
296
create_scalar_predicate(Item * a,Item * b) const297 Item_bool_func *Eq_creator::create_scalar_predicate(Item *a, Item *b) const
298 {
299 DBUG_ASSERT(a->type() != Item::ROW_ITEM || b->type() != Item::ROW_ITEM);
300 return new Item_func_eq(a, b);
301 }
302
303
combine(List<Item> list) const304 Item_bool_func *Eq_creator::combine(List<Item> list) const
305 {
306 return new Item_cond_and(list);
307 }
308
309
create_scalar_predicate(Item * a,Item * b) const310 Item_bool_func *Equal_creator::create_scalar_predicate(Item *a, Item *b)
311 const
312 {
313 DBUG_ASSERT(a->type() != Item::ROW_ITEM || b->type() != Item::ROW_ITEM);
314 return new Item_func_equal(a, b);
315 }
316
317
combine(List<Item> list) const318 Item_bool_func *Equal_creator::combine(List<Item> list) const
319 {
320 return new Item_cond_and(list);
321 }
322
323
create_scalar_predicate(Item * a,Item * b) const324 Item_bool_func* Ne_creator::create_scalar_predicate(Item *a, Item *b) const
325 {
326 DBUG_ASSERT(a->type() != Item::ROW_ITEM || b->type() != Item::ROW_ITEM);
327 return new Item_func_ne(a, b);
328 }
329
330
combine(List<Item> list) const331 Item_bool_func *Ne_creator::combine(List<Item> list) const
332 {
333 return new Item_cond_or(list);
334 }
335
336
create(Item * a,Item * b) const337 Item_bool_func* Gt_creator::create(Item *a, Item *b) const
338 {
339 return new Item_func_gt(a, b);
340 }
341
342
create(Item * a,Item * b) const343 Item_bool_func* Lt_creator::create(Item *a, Item *b) const
344 {
345 return new Item_func_lt(a, b);
346 }
347
348
create(Item * a,Item * b) const349 Item_bool_func* Ge_creator::create(Item *a, Item *b) const
350 {
351 return new Item_func_ge(a, b);
352 }
353
354
create(Item * a,Item * b) const355 Item_bool_func* Le_creator::create(Item *a, Item *b) const
356 {
357 return new Item_func_le(a, b);
358 }
359
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)360 float Item_func_not::get_filtering_effect(table_map filter_for_table,
361 table_map read_tables,
362 const MY_BITMAP *fields_to_ignore,
363 double rows_in_table)
364 {
365 const float filter= args[0]->get_filtering_effect(filter_for_table,
366 read_tables,
367 fields_to_ignore,
368 rows_in_table);
369
370 /*
371 If the predicate that will be negated has COND_FILTER_ALLPASS
372 filtering it means that some dependent tables have not been
373 read, that the predicate is of a type that filtering effect is
374 not calculated for or something similar. In any case, the
375 filtering effect of the inverted predicate should also be
376 COND_FILTER_ALLPASS.
377 */
378 if (filter == COND_FILTER_ALLPASS)
379 return COND_FILTER_ALLPASS;
380
381 return 1.0f - filter;
382 }
383
384 /*
385 Test functions
386 Most of these returns 0LL if false and 1LL if true and
387 NULL if some arg is NULL.
388 */
389
val_int()390 longlong Item_func_not::val_int()
391 {
392 DBUG_ASSERT(fixed == 1);
393 bool value= args[0]->val_bool();
394 null_value=args[0]->null_value;
395 return ((!null_value && value == 0) ? 1 : 0);
396 }
397
398 /*
399 We put any NOT expression into parenthesis to avoid
400 possible problems with internal view representations where
401 any '!' is converted to NOT. It may cause a problem if
402 '!' is used in an expression together with other operators
403 whose precedence is lower than the precedence of '!' yet
404 higher than the precedence of NOT.
405 */
406
print(String * str,enum_query_type query_type)407 void Item_func_not::print(String *str, enum_query_type query_type)
408 {
409 str->append('(');
410 Item_func::print(str, query_type);
411 str->append(')');
412 }
413
414 /**
415 special NOT for ALL subquery.
416 */
417
418
val_int()419 longlong Item_func_not_all::val_int()
420 {
421 DBUG_ASSERT(fixed == 1);
422 bool value= args[0]->val_bool();
423
424 /*
425 return TRUE if there was records in underlying select in max/min
426 optimization (ALL subquery)
427 */
428 if (empty_underlying_subquery())
429 return 1;
430
431 null_value= args[0]->null_value;
432 return ((!null_value && value == 0) ? 1 : 0);
433 }
434
435
empty_underlying_subquery()436 bool Item_func_not_all::empty_underlying_subquery()
437 {
438 DBUG_ASSERT(subselect || !(test_sum_item || test_sub_item));
439 /*
440 When outer argument is NULL the subquery has not yet been evaluated, we
441 need to evaluate it to get to know whether it returns any rows to return
442 the correct result. 'ANY' subqueries are an exception because the
443 result would be false or null which for a top level item always mean false.
444 The subselect->unit->item->... chain should be used instead of
445 subselect->... to workaround subquery transformation which could make
446 subselect->engine unusable.
447 */
448 if (subselect &&
449 subselect->substype() != Item_subselect::ANY_SUBS &&
450 !subselect->unit->item->is_evaluated())
451 subselect->unit->item->exec();
452 return ((test_sum_item && !test_sum_item->any_value()) ||
453 (test_sub_item && !test_sub_item->any_value()));
454 }
455
print(String * str,enum_query_type query_type)456 void Item_func_not_all::print(String *str, enum_query_type query_type)
457 {
458 if (show)
459 Item_func::print(str, query_type);
460 else
461 args[0]->print(str, query_type);
462 }
463
464
465 /**
466 Special NOP (No OPeration) for ALL subquery. It is like
467 Item_func_not_all.
468
469 @return
470 (return TRUE if underlying subquery do not return rows) but if subquery
471 returns some rows it return same value as argument (TRUE/FALSE).
472 */
473
val_int()474 longlong Item_func_nop_all::val_int()
475 {
476 DBUG_ASSERT(fixed == 1);
477 longlong value= args[0]->val_int();
478
479 /*
480 return FALSE if there was records in underlying select in max/min
481 optimization (SAME/ANY subquery)
482 */
483 if (empty_underlying_subquery())
484 return 0;
485
486 null_value= args[0]->null_value;
487 return (null_value || value == 0) ? 0 : 1;
488 }
489
490
491 /**
492 Convert a constant item to an int and replace the original item.
493
494 The function converts a constant expression or string to an integer.
495 On successful conversion the original item is substituted for the
496 result of the item evaluation.
497 This is done when comparing DATE/TIME of different formats and
498 also when comparing bigint to strings (in which case strings
499 are converted to bigints).
500
501 @param thd thread handle
502 @param field item will be converted using the type of this field
503 @param[in,out] item reference to the item to convert
504
505 @note
506 This function is called only at prepare stage.
507 As all derived tables are filled only after all derived tables
508 are prepared we do not evaluate items with subselects here because
509 they can contain derived tables and thus we may attempt to use a
510 table that has not been populated yet.
511
512 @retval
513 0 Can't convert item
514 @retval
515 1 Item was replaced with an integer version of the item
516 */
517
convert_constant_item(THD * thd,Item_field * field_item,Item ** item)518 static bool convert_constant_item(THD *thd, Item_field *field_item,
519 Item **item)
520 {
521 Field *field= field_item->field;
522 int result= 0;
523
524 if ((*item)->const_item() &&
525 /*
526 In case of GC it's possible that this func will be called on an
527 already converted constant. Don't convert it again.
528 */
529 !((*item)->field_type() == field_item->field_type() &&
530 (*item)->basic_const_item()))
531 {
532 TABLE *table= field->table;
533 sql_mode_t orig_sql_mode= thd->variables.sql_mode;
534 enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
535 my_bitmap_map *old_maps[2];
536 ulonglong orig_field_val= 0; /* original field value if valid */
537
538 old_maps[0]= NULL;
539 old_maps[1]= NULL;
540
541 if (table)
542 dbug_tmp_use_all_columns(table, old_maps,
543 table->read_set, table->write_set);
544 /* For comparison purposes allow invalid dates like 2000-01-32 */
545 thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
546 MODE_INVALID_DATES;
547 thd->count_cuted_fields= CHECK_FIELD_IGNORE;
548
549 /*
550 Store the value of the field/constant if it references an outer field
551 because the call to save_in_field below overrides that value.
552 Don't save field value if no data has been read yet.
553 Outer constant values are always saved.
554 */
555 bool save_field_value= (field_item->depended_from &&
556 (field_item->const_item() ||
557 !(field->table->status &
558 (STATUS_GARBAGE | STATUS_NOT_FOUND))));
559 if (save_field_value)
560 orig_field_val= field->val_int();
561 int rc;
562 if (!(*item)->is_null() &&
563 (((rc= (*item)->save_in_field(field, true)) == TYPE_OK) ||
564 rc == TYPE_NOTE_TIME_TRUNCATED)) // TS-TODO
565 {
566 int field_cmp= 0;
567 /*
568 If item is a decimal value, we must reject it if it was truncated.
569 TODO: consider doing the same for MYSQL_TYPE_YEAR,.
570 However: we have tests which assume that things '1999' and
571 '1991-01-01 01:01:01' can be converted to year.
572 Testing for MYSQL_TYPE_YEAR here, would treat such literals
573 as 'incorrect DOUBLE value'.
574 See Bug#13580652 YEAR COLUMN CAN BE EQUAL TO 1999.1
575 */
576 if (field->type() == MYSQL_TYPE_LONGLONG)
577 {
578 field_cmp= stored_field_cmp_to_item(thd, field, *item);
579 DBUG_PRINT("info", ("convert_constant_item %d", field_cmp));
580 }
581
582 if (0 == field_cmp)
583 {
584 Item *tmp= field->type() == MYSQL_TYPE_TIME ?
585 #define OLD_CMP
586 #ifdef OLD_CMP
587 new Item_time_with_ref(field->decimals(),
588 field->val_time_temporal(), *item) :
589 #else
590 new Item_time_with_ref(max((*item)->time_precision(),
591 field->decimals()),
592 (*item)->val_time_temporal(),
593 *item) :
594 #endif
595 field->is_temporal_with_date() ?
596 #ifdef OLD_CMP
597 new Item_datetime_with_ref(field->type(),
598 field->decimals(),
599 field->val_date_temporal(),
600 *item) :
601 #else
602 new Item_datetime_with_ref(field->type(),
603 max((*item)->datetime_precision(),
604 field->decimals()),
605 (*item)->val_date_temporal(),
606 *item) :
607 #endif
608 new Item_int_with_ref(field->type(), field->val_int(), *item,
609 MY_TEST(field->flags & UNSIGNED_FLAG));
610 if (tmp)
611 thd->change_item_tree(item, tmp);
612 result= 1; // Item was replaced
613 }
614 }
615 /* Restore the original field value. */
616 if (save_field_value)
617 {
618 result= field->store(orig_field_val, TRUE);
619 /* orig_field_val must be a valid value that can be restored back. */
620 DBUG_ASSERT(!result);
621 }
622 thd->variables.sql_mode= orig_sql_mode;
623 thd->count_cuted_fields= orig_count_cuted_fields;
624 if (table)
625 dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_maps);
626 }
627 return result;
628 }
629
630
convert_constant_arg(THD * thd,Item * field,Item ** item)631 bool Item_bool_func2::convert_constant_arg(THD *thd, Item *field, Item **item)
632 {
633 if (field->real_item()->type() != FIELD_ITEM)
634 return false;
635
636 Item_field *field_item= (Item_field*) (field->real_item());
637 if (field_item->field->can_be_compared_as_longlong() &&
638 !(field_item->is_temporal_with_date() &&
639 (*item)->result_type() == STRING_RESULT))
640 {
641 if (convert_constant_item(thd, field_item, item))
642 {
643 cmp.set_cmp_func(this, tmp_arg, tmp_arg + 1, INT_RESULT);
644 field->cmp_context= (*item)->cmp_context= INT_RESULT;
645 return true;
646 }
647 }
648 return false;
649 }
650
651
fix_length_and_dec()652 void Item_bool_func2::fix_length_and_dec()
653 {
654 max_length= 1; // Function returns 0 or 1
655 THD *thd;
656
657 /*
658 As some compare functions are generated after sql_yacc,
659 we have to check for out of memory conditions here
660 */
661 if (!args[0] || !args[1])
662 return;
663
664 DBUG_ENTER("Item_bool_func2::fix_length_and_dec");
665
666 /*
667 See agg_item_charsets() in item.cc for comments
668 on character set and collation aggregation.
669 */
670 if (args[0]->result_type() == STRING_RESULT &&
671 args[1]->result_type() == STRING_RESULT &&
672 agg_arg_charsets_for_comparison(cmp.cmp_collation, args, 2))
673 DBUG_VOID_RETURN;
674
675 args[0]->cmp_context= args[1]->cmp_context=
676 item_cmp_type(args[0]->result_type(), args[1]->result_type());
677 // Make a special case of compare with fields to get nicer DATE comparisons
678
679 if (functype() == LIKE_FUNC) // Disable conversion in case of LIKE function.
680 {
681 set_cmp_func();
682 DBUG_VOID_RETURN;
683 }
684
685 /*
686 Geometry item cannot participate in an arithmetic or string comparison or
687 a full text search, except in equal/not equal comparison.
688 We allow geometry arguments in equal/not equal, since such
689 comparisons are used now and are meaningful, although it simply compares
690 the GEOMETRY byte string rather than doing a geometric equality comparison.
691 */
692 const Functype func_type= functype();
693 if (func_type == LT_FUNC || func_type == LE_FUNC || func_type == GE_FUNC ||
694 func_type == GT_FUNC || func_type == FT_FUNC)
695 reject_geometry_args(arg_count, args, this);
696
697 thd= current_thd;
698 if (!thd->lex->is_ps_or_view_context_analysis())
699 {
700 if (convert_constant_arg(thd, args[0], &args[1]) ||
701 convert_constant_arg(thd, args[1], &args[0]))
702 DBUG_VOID_RETURN;
703 }
704 set_cmp_func();
705 DBUG_VOID_RETURN;
706 }
707
708
cleanup()709 void Arg_comparator::cleanup()
710 {
711 if (comparators != NULL)
712 {
713 /*
714 We cannot rely on (*a)->cols(), since *a may be deallocated
715 at this point, so use comparator_count to loop.
716 */
717 for (size_t i= 0; i < comparator_count; i++)
718 {
719 comparators[i].cleanup();
720 }
721 }
722 delete[] comparators;
723 comparators= 0;
724 delete_json_scalar_holder(json_scalar);
725 json_scalar= 0;
726 }
727
728
set_compare_func(Item_result_field * item,Item_result type)729 int Arg_comparator::set_compare_func(Item_result_field *item, Item_result type)
730 {
731 owner= item;
732 func= comparator_matrix[type]
733 [is_owner_equal_func()];
734
735 switch (type) {
736 case ROW_RESULT:
737 {
738 uint n= (*a)->cols();
739 if (n != (*b)->cols())
740 {
741 my_error(ER_OPERAND_COLUMNS, MYF(0), n);
742 comparators= 0;
743 return 1;
744 }
745 if (!(comparators= new Arg_comparator[n]))
746 return 1;
747 comparator_count= n;
748
749 for (uint i=0; i < n; i++)
750 {
751 if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
752 {
753 my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
754 return 1;
755 }
756 if (comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i),
757 set_null))
758 return 1;
759 }
760 break;
761 }
762 case STRING_RESULT:
763 {
764 /*
765 We must set cmp_charset here as we may be called from for an automatic
766 generated item, like in natural join
767 */
768 if (cmp_collation.set((*a)->collation, (*b)->collation, MY_COLL_CMP_CONV) ||
769 cmp_collation.derivation == DERIVATION_NONE)
770 {
771 my_coll_agg_error((*a)->collation, (*b)->collation,
772 owner->func_name());
773 return 1;
774 }
775 if (cmp_collation.collation == &my_charset_bin)
776 {
777 /*
778 We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
779 without removing end space
780 */
781 if (func == &Arg_comparator::compare_string)
782 func= &Arg_comparator::compare_binary_string;
783 else if (func == &Arg_comparator::compare_e_string)
784 func= &Arg_comparator::compare_e_binary_string;
785
786 /*
787 As this is binary compassion, mark all fields that they can't be
788 transformed. Otherwise we would get into trouble with comparisons
789 like:
790 WHERE col= 'j' AND col LIKE BINARY 'j'
791 which would be transformed to:
792 WHERE col= 'j'
793 */
794 (*a)->walk(&Item::set_no_const_sub, Item::WALK_POSTFIX, NULL);
795 (*b)->walk(&Item::set_no_const_sub, Item::WALK_POSTFIX, NULL);
796 }
797 break;
798 }
799 case INT_RESULT:
800 {
801 if ((*a)->is_temporal() && (*b)->is_temporal())
802 {
803 func= is_owner_equal_func() ?
804 &Arg_comparator::compare_e_time_packed :
805 &Arg_comparator::compare_time_packed;
806 }
807 else if (func == &Arg_comparator::compare_int_signed)
808 {
809 if ((*a)->unsigned_flag)
810 func= (((*b)->unsigned_flag)?
811 &Arg_comparator::compare_int_unsigned :
812 &Arg_comparator::compare_int_unsigned_signed);
813 else if ((*b)->unsigned_flag)
814 func= &Arg_comparator::compare_int_signed_unsigned;
815 }
816 else if (func== &Arg_comparator::compare_e_int)
817 {
818 if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
819 func= &Arg_comparator::compare_e_int_diff_signedness;
820 }
821 break;
822 }
823 case DECIMAL_RESULT:
824 break;
825 case REAL_RESULT:
826 {
827 if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
828 {
829 precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
830 if (func == &Arg_comparator::compare_real)
831 func= &Arg_comparator::compare_real_fixed;
832 else if (func == &Arg_comparator::compare_e_real)
833 func= &Arg_comparator::compare_e_real_fixed;
834 }
835 break;
836 }
837 default:
838 DBUG_ASSERT(0);
839 }
840 return 0;
841 }
842
843 /**
844 Parse date provided in a string to a MYSQL_TIME.
845
846 @param[in] thd Thread handle
847 @param[in] str A string to convert
848 @param[in] warn_type Type of the timestamp for issuing the warning
849 @param[in] warn_name Field name for issuing the warning
850 @param[out] l_time The MYSQL_TIME objects is initialized.
851
852 Parses a date provided in the string str into a MYSQL_TIME object. If the
853 string contains an incorrect date or doesn't correspond to a date at all
854 then a warning is issued. The warn_type and the warn_name arguments are used
855 as the name and the type of the field when issuing the warning. If any input
856 was discarded (trailing or non-timestamp-y characters), return value will be
857 TRUE.
858
859 @return Status flag
860 @retval FALSE Success.
861 @retval True Indicates failure.
862 */
863
get_mysql_time_from_str(THD * thd,String * str,timestamp_type warn_type,const char * warn_name,MYSQL_TIME * l_time)864 bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
865 const char *warn_name, MYSQL_TIME *l_time)
866 {
867 bool value;
868 MYSQL_TIME_STATUS status;
869 my_time_flags_t flags= TIME_FUZZY_DATE | TIME_INVALID_DATES;
870
871 if (thd->variables.sql_mode & MODE_NO_ZERO_IN_DATE)
872 flags|= TIME_NO_ZERO_IN_DATE;
873 if (thd->variables.sql_mode & MODE_NO_ZERO_DATE)
874 flags|= TIME_NO_ZERO_DATE;
875
876 if (!str_to_datetime(str, l_time, flags, &status) &&
877 (l_time->time_type == MYSQL_TIMESTAMP_DATETIME ||
878 l_time->time_type == MYSQL_TIMESTAMP_DATE))
879 /*
880 Do not return yet, we may still want to throw a "trailing garbage"
881 warning.
882 */
883 value= FALSE;
884 else
885 {
886 value= TRUE;
887 status.warnings= MYSQL_TIME_WARN_TRUNCATED; /* force warning */
888 }
889
890 if (status.warnings > 0)
891 make_truncated_value_warning(thd, Sql_condition::SL_WARNING,
892 ErrConvString(str), warn_type, warn_name);
893
894 return value;
895 }
896
897
898 /**
899 @brief Convert date provided in a string
900 to its packed temporal int representation.
901
902 @param[in] thd thread handle
903 @param[in] str a string to convert
904 @param[in] warn_type type of the timestamp for issuing the warning
905 @param[in] warn_name field name for issuing the warning
906 @param[out] error_arg could not extract a DATE or DATETIME
907
908 @details Convert date provided in the string str to the int
909 representation. If the string contains wrong date or doesn't
910 contain it at all then a warning is issued. The warn_type and
911 the warn_name arguments are used as the name and the type of the
912 field when issuing the warning.
913
914 @return
915 converted value. 0 on error and on zero-dates -- check 'failure'
916 */
get_date_from_str(THD * thd,String * str,timestamp_type warn_type,const char * warn_name,bool * error_arg)917 static ulonglong get_date_from_str(THD *thd, String *str,
918 timestamp_type warn_type,
919 const char *warn_name, bool *error_arg)
920 {
921 MYSQL_TIME l_time;
922 *error_arg= get_mysql_time_from_str(thd, str, warn_type, warn_name, &l_time);
923
924 if (*error_arg)
925 return 0;
926 return TIME_to_longlong_datetime_packed(&l_time);
927 }
928
929
930 /**
931 Check if str_arg is a constant and convert it to datetime packed value.
932 Note, const_value may stay untouched, so the caller is responsible to
933 initialize it.
934
935 @param date_arg date argument, it's name is used for error reporting.
936 @param str_arg string argument to get datetime value from.
937 @param[out] const_value the converted value is stored here, if not NULL.
938
939 @return true on error, false on success, false if str_arg is not a const.
940 */
get_date_from_const(Item * date_arg,Item * str_arg,ulonglong * const_value)941 bool Arg_comparator::get_date_from_const(Item *date_arg,
942 Item *str_arg,
943 ulonglong *const_value)
944 {
945 THD *thd= current_thd;
946 /*
947 Do not cache GET_USER_VAR() function as its const_item() may return TRUE
948 for the current thread but it still may change during the execution.
949 Don't use cache while in the context analysis mode only (i.e. for
950 EXPLAIN/CREATE VIEW and similar queries). Cache is useless in such
951 cases and can cause problems. For example evaluating subqueries can
952 confuse storage engines since in context analysis mode tables
953 aren't locked.
954 */
955 if (!thd->lex->is_ps_or_view_context_analysis() &&
956 str_arg->const_item() &&
957 (str_arg->type() != Item::FUNC_ITEM ||
958 ((Item_func*) str_arg)->functype() != Item_func::GUSERVAR_FUNC))
959 {
960 ulonglong value;
961 if (str_arg->field_type() == MYSQL_TYPE_TIME)
962 {
963 // Convert from TIME to DATETIME
964 value= str_arg->val_date_temporal();
965 if (str_arg->null_value)
966 return true;
967 }
968 else
969 {
970 // Convert from string to DATETIME
971 DBUG_ASSERT(str_arg->result_type() == STRING_RESULT);
972 bool error;
973 String tmp, *str_val= 0;
974 timestamp_type t_type= (date_arg->field_type() == MYSQL_TYPE_DATE ?
975 MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME);
976 str_val= str_arg->val_str(&tmp);
977 if (str_arg->null_value)
978 return true;
979 value= get_date_from_str(thd, str_val, t_type,
980 date_arg->item_name.ptr(), &error);
981 if (error)
982 return true;
983 }
984 if (const_value)
985 *const_value= value;
986 }
987 return false;
988 }
989
990
991 /*
992 Check whether compare_datetime() can be used to compare items.
993
994 SYNOPSIS
995 Arg_comparator::can_compare_as_dates()
996 a, b [in] items to be compared
997 const_value [out] converted value of the string constant, if any
998
999 DESCRIPTION
1000 Check several cases when the DATE/DATETIME comparator should be used.
1001 The following cases are checked:
1002 1. Both a and b is a DATE/DATETIME field/function returning string or
1003 int result.
1004 2. Only a or b is a DATE/DATETIME field/function returning string or
1005 int result and the other item (b or a) is an item with string result.
1006 If the second item is a constant one then it's checked to be
1007 convertible to the DATE/DATETIME type. If the constant can't be
1008 converted to a DATE/DATETIME then the compare_datetime() comparator
1009 isn't used and the warning about wrong DATE/DATETIME value is issued.
1010 In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
1011 the comparison is handled by other comparators.
1012 If the datetime comparator can be used and one the operands of the
1013 comparison is a string constant that was successfully converted to a
1014 DATE/DATETIME type then the result of the conversion is returned in the
1015 const_value if it is provided. If there is no constant or
1016 compare_datetime() isn't applicable then the *const_value remains
1017 unchanged.
1018
1019 @return true if can compare as dates, false otherwise.
1020 */
1021
1022 bool
can_compare_as_dates(Item * a,Item * b,ulonglong * const_value)1023 Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value)
1024 {
1025 if (a->type() == Item::ROW_ITEM || b->type() == Item::ROW_ITEM)
1026 return false;
1027
1028 if (a->is_temporal_with_date())
1029 {
1030 if (b->is_temporal_with_date()) // date[time] + date
1031 {
1032 return true;
1033 }
1034 else if (b->result_type() == STRING_RESULT) // date[time] + string
1035 {
1036 return !get_date_from_const(a, b, const_value);
1037 }
1038 else
1039 return false; // date[time] + number
1040 }
1041 else if (b->is_temporal_with_date() &&
1042 a->result_type() == STRING_RESULT) // string + date[time]
1043 {
1044 return !get_date_from_const(b, a, const_value);
1045 }
1046 else
1047 return false; // No date[time] items found
1048 }
1049
1050
1051 /*
1052 Retrieves correct TIME value from the given item.
1053
1054 SYNOPSIS
1055 get_time_value()
1056 thd thread handle
1057 item_arg [in/out] item to retrieve TIME value from
1058 cache_arg [in/out] pointer to place to store the cache item to
1059 warn_item [in] unused
1060 is_null [out] TRUE <=> the item_arg is null
1061
1062 DESCRIPTION
1063 Retrieves the correct TIME value from given item for comparison by the
1064 compare_datetime() function.
1065 If item's result can be compared as longlong then its int value is used
1066 and a value returned by get_time function is used otherwise.
1067 If an item is a constant one then its value is cached and it isn't
1068 get parsed again. An Item_cache_int object is used for for cached values.
1069 It seamlessly substitutes the original item. The cache item is marked as
1070 non-constant to prevent re-caching it again.
1071
1072 RETURN
1073 obtained value
1074 */
1075
1076 longlong
get_time_value(THD * thd,Item *** item_arg,Item ** cache_arg,const Item * warn_item,bool * is_null)1077 get_time_value(THD *thd, Item ***item_arg, Item **cache_arg,
1078 const Item *warn_item, bool *is_null)
1079 {
1080 longlong value;
1081 Item *item= **item_arg;
1082
1083 /*
1084 Note, it's wrong to assume that we always get
1085 a TIME expression or NULL here:
1086
1087 DBUG_ASSERT(item->field_type() == MYSQL_TYPE_TIME ||
1088 item->field_type() == MYSQL_TYPE_NULL);
1089
1090 because when this condition is optimized:
1091
1092 WHERE time_column=DATE(NULL) AND time_column=TIME(NULL);
1093
1094 rhe first AND part is eliminated and DATE(NULL) is substituted
1095 to the second AND part like this:
1096
1097 WHERE DATE(NULL) = TIME(NULL) // as TIME
1098
1099 whose Arg_comparator has already get_time_value set for both arguments.
1100 Therefore, get_time_value is executed for DATE(NULL).
1101 This condition is further evaluated as impossible condition.
1102
1103 TS-TODO: perhaps such cases should be evaluated without
1104 calling get_time_value at all.
1105
1106 See a similar comment in Arg_comparator::compare_time_packed.
1107 */
1108 value= item->val_time_temporal();
1109 *is_null= item->null_value;
1110
1111 /*
1112 Do not cache GET_USER_VAR() function as its const_item() may return TRUE
1113 for the current thread but it still may change during the execution.
1114 */
1115 if (item->const_item() && cache_arg &&
1116 item->type() != Item::CACHE_ITEM &&
1117 (item->type() != Item::FUNC_ITEM ||
1118 ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
1119 {
1120 Item_cache_datetime *cache= new Item_cache_datetime(item->field_type());
1121 /* Mark the cache as non-const to prevent re-caching. */
1122 cache->set_used_tables(1);
1123 cache->store(item, value);
1124 *cache_arg= cache;
1125 *item_arg= cache_arg;
1126 }
1127 return value;
1128 }
1129
1130
1131 /**
1132 Sets compare functions for various datatypes.
1133
1134 NOTE
1135 The result type of a comparison is chosen by item_cmp_type().
1136 Here we override the chosen result type for certain expression
1137 containing date or time or decimal expressions.
1138 */
set_cmp_func(Item_result_field * owner_arg,Item ** a1,Item ** a2,Item_result type)1139 int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
1140 Item **a1, Item **a2,
1141 Item_result type)
1142 {
1143 ulonglong const_value= (ulonglong)-1;
1144 owner= owner_arg;
1145 set_null= set_null && owner_arg;
1146 a= a1;
1147 b= a2;
1148
1149 if (type != ROW_RESULT &&
1150 (((*a)->result_type() == STRING_RESULT &&
1151 (*a)->field_type() == MYSQL_TYPE_JSON) ||
1152 ((*b)->result_type() == STRING_RESULT &&
1153 (*b)->field_type() == MYSQL_TYPE_JSON)))
1154 {
1155 // Use the JSON comparator if at least one of the arguments is JSON.
1156 is_nulls_eq= is_owner_equal_func();
1157 func= &Arg_comparator::compare_json;
1158 return 0;
1159 }
1160
1161 if (can_compare_as_dates(*a, *b, &const_value))
1162 {
1163 a_cache= 0;
1164 b_cache= 0;
1165
1166 if (const_value != (ulonglong)-1)
1167 {
1168 /*
1169 cache_converted_constant can't be used here because it can't
1170 correctly convert a DATETIME value from string to int representation.
1171 */
1172 Item_cache_datetime *cache= new Item_cache_datetime(MYSQL_TYPE_DATETIME);
1173 /* Mark the cache as non-const to prevent re-caching. */
1174 cache->set_used_tables(1);
1175 if (!(*a)->is_temporal_with_date())
1176 {
1177 cache->store((*a), const_value);
1178 a_cache= cache;
1179 a= &a_cache;
1180 }
1181 else
1182 {
1183 cache->store((*b), const_value);
1184 b_cache= cache;
1185 b= &b_cache;
1186 }
1187 }
1188 is_nulls_eq= is_owner_equal_func();
1189 func= &Arg_comparator::compare_datetime;
1190 get_value_a_func= &get_datetime_value;
1191 get_value_b_func= &get_datetime_value;
1192 cmp_collation.set(&my_charset_numeric);
1193 set_cmp_context_for_datetime();
1194 return 0;
1195 }
1196 else if ((type == STRING_RESULT ||
1197 // When comparing time field and cached/converted time constant
1198 type == REAL_RESULT) &&
1199 (*a)->field_type() == MYSQL_TYPE_TIME &&
1200 (*b)->field_type() == MYSQL_TYPE_TIME)
1201 {
1202 /* Compare TIME values as integers. */
1203 a_cache= 0;
1204 b_cache= 0;
1205 is_nulls_eq= is_owner_equal_func();
1206 func= &Arg_comparator::compare_datetime;
1207 get_value_a_func= &get_time_value;
1208 get_value_b_func= &get_time_value;
1209 set_cmp_context_for_datetime();
1210 return 0;
1211 }
1212 else if (type == STRING_RESULT &&
1213 (*a)->result_type() == STRING_RESULT &&
1214 (*b)->result_type() == STRING_RESULT)
1215 {
1216 DTCollation coll;
1217 coll.set((*a)->collation, (*b)->collation, MY_COLL_CMP_CONV);
1218 if (agg_item_set_converter(coll, owner->func_name(), a, 1,
1219 MY_COLL_CMP_CONV, 1) ||
1220 agg_item_set_converter(coll, owner->func_name(), b, 1,
1221 MY_COLL_CMP_CONV, 1))
1222 return true;
1223 }
1224 else if (try_year_cmp_func(type))
1225 {
1226 return 0;
1227 }
1228 else if (type == REAL_RESULT &&
1229 (((*a)->result_type() == DECIMAL_RESULT && !(*a)->const_item() &&
1230 (*b)->result_type() == STRING_RESULT && (*b)->const_item()) ||
1231 ((*b)->result_type() == DECIMAL_RESULT && !(*b)->const_item() &&
1232 (*a)->result_type() == STRING_RESULT && (*a)->const_item())))
1233 {
1234 /*
1235 <non-const decimal expression> <cmp> <const string expression>
1236 or
1237 <const string expression> <cmp> <non-const decimal expression>
1238
1239 Do comparison as decimal rather than float, in order not to lose precision.
1240 */
1241 type= DECIMAL_RESULT;
1242 }
1243
1244 THD *thd= current_thd;
1245 a= cache_converted_constant(thd, a, &a_cache, type);
1246 b= cache_converted_constant(thd, b, &b_cache, type);
1247 return set_compare_func(owner_arg, type);
1248 }
1249
1250
set_cmp_func(Item_result_field * owner_arg,Item ** a1,Item ** a2,bool set_null_arg)1251 int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
1252 Item **a1, Item **a2, bool set_null_arg)
1253 {
1254 set_null= set_null_arg;
1255 const Item_result item_result=
1256 item_cmp_type((*a1)->result_type(),
1257 (*a2)->result_type());
1258 return set_cmp_func(owner_arg, a1, a2, item_result);
1259 }
1260
1261 /*
1262 Helper function to call from Arg_comparator::set_cmp_func()
1263 */
1264
try_year_cmp_func(Item_result type)1265 bool Arg_comparator::try_year_cmp_func(Item_result type)
1266 {
1267 if (type == ROW_RESULT)
1268 return FALSE;
1269
1270 bool a_is_year= (*a)->field_type() == MYSQL_TYPE_YEAR;
1271 bool b_is_year= (*b)->field_type() == MYSQL_TYPE_YEAR;
1272
1273 if (!a_is_year && !b_is_year)
1274 return FALSE;
1275
1276 if (a_is_year && b_is_year)
1277 {
1278 get_value_a_func= &get_year_value;
1279 get_value_b_func= &get_year_value;
1280 }
1281 else if (a_is_year && (*b)->is_temporal_with_date())
1282 {
1283 get_value_a_func= &get_year_value;
1284 get_value_b_func= &get_datetime_value;
1285 }
1286 else if (b_is_year && (*a)->is_temporal_with_date())
1287 {
1288 get_value_b_func= &get_year_value;
1289 get_value_a_func= &get_datetime_value;
1290 }
1291 else
1292 return FALSE;
1293
1294 is_nulls_eq= is_owner_equal_func();
1295 func= &Arg_comparator::compare_datetime;
1296 set_cmp_context_for_datetime();
1297
1298 return TRUE;
1299 }
1300
1301 /**
1302 Convert and cache a constant.
1303
1304 @param value [in] An item to cache
1305 @param cache_item [out] Placeholder for the cache item
1306 @param type [in] Comparison type
1307
1308 @details
1309 When given item is a constant and its type differs from comparison type
1310 then cache its value to avoid type conversion of this constant on each
1311 evaluation. In this case the value is cached and the reference to the cache
1312 is returned.
1313 Original value is returned otherwise.
1314
1315 @return cache item or original value.
1316 */
1317
cache_converted_constant(THD * thd_arg,Item ** value,Item ** cache_item,Item_result type)1318 Item** Arg_comparator::cache_converted_constant(THD *thd_arg, Item **value,
1319 Item **cache_item,
1320 Item_result type)
1321 {
1322 /* Don't need cache if doing context analysis only. */
1323 if (!thd_arg->lex->is_ps_or_view_context_analysis() &&
1324 (*value)->const_item() && type != (*value)->result_type())
1325 {
1326 Item_cache *cache= Item_cache::get_cache(*value, type);
1327 cache->setup(*value);
1328 *cache_item= cache;
1329 return cache_item;
1330 }
1331 return value;
1332 }
1333
1334
set_datetime_cmp_func(Item_result_field * owner_arg,Item ** a1,Item ** b1)1335 void Arg_comparator::set_datetime_cmp_func(Item_result_field *owner_arg,
1336 Item **a1, Item **b1)
1337 {
1338 owner= owner_arg;
1339 a= a1;
1340 b= b1;
1341 a_cache= 0;
1342 b_cache= 0;
1343 is_nulls_eq= FALSE;
1344 func= &Arg_comparator::compare_datetime;
1345 get_value_a_func= &get_datetime_value;
1346 get_value_b_func= &get_datetime_value;
1347 set_cmp_context_for_datetime();
1348 }
1349
1350
1351 /*
1352 Retrieves correct DATETIME value from given item.
1353
1354 SYNOPSIS
1355 get_datetime_value()
1356 thd thread handle
1357 item_arg [in/out] item to retrieve DATETIME value from
1358 cache_arg [in/out] pointer to place to store the caching item to
1359 warn_item [in] item for issuing the conversion warning
1360 is_null [out] TRUE <=> the item_arg is null
1361
1362 DESCRIPTION
1363 Retrieves the correct DATETIME value from given item for comparison by the
1364 compare_datetime() function.
1365 If item's result can be compared as longlong then its int value is used
1366 and its string value is used otherwise. Strings are always parsed and
1367 converted to int values by the get_date_from_str() function.
1368 This allows us to compare correctly string dates with missed insignificant
1369 zeros. If an item is a constant one then its value is cached and it isn't
1370 get parsed again. An Item_cache_int object is used for caching values. It
1371 seamlessly substitutes the original item. The cache item is marked as
1372 non-constant to prevent re-caching it again. In order to compare
1373 correctly DATE and DATETIME items the result of the former are treated as
1374 a DATETIME with zero time (00:00:00).
1375
1376 RETURN
1377 obtained value
1378 */
1379
1380
1381 longlong
get_datetime_value(THD * thd,Item *** item_arg,Item ** cache_arg,const Item * warn_item,bool * is_null)1382 get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
1383 const Item *warn_item, bool *is_null)
1384 {
1385 longlong value= 0;
1386 String buf, *str= 0;
1387 Item *item= **item_arg;
1388
1389 if (item->is_temporal())
1390 {
1391 value= item->val_date_temporal();
1392 *is_null= item->null_value;
1393 }
1394 else
1395 {
1396 str= item->val_str(&buf);
1397 *is_null= item->null_value;
1398 }
1399 if (*is_null)
1400 return ~(ulonglong) 0;
1401 /*
1402 Convert strings to the integer DATE/DATETIME representation.
1403 Even if both dates provided in strings we can't compare them directly as
1404 strings as there is no warranty that they are correct and do not miss
1405 some insignificant zeros.
1406 */
1407 if (str)
1408 {
1409 bool error;
1410 enum_field_types f_type= warn_item->field_type();
1411 timestamp_type t_type= f_type ==
1412 MYSQL_TYPE_DATE ? MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME;
1413 value= (longlong) get_date_from_str(thd, str, t_type, warn_item->item_name.ptr(), &error);
1414 /*
1415 If str did not contain a valid date according to the current
1416 SQL_MODE, get_date_from_str() has already thrown a warning,
1417 and we don't want to throw NULL on invalid date (see 5.2.6
1418 "SQL modes" in the manual), so we're done here.
1419 */
1420 }
1421 /*
1422 Do not cache GET_USER_VAR() function as its const_item() may return TRUE
1423 for the current thread but it still may change during the execution.
1424 */
1425 if (item->const_item() && cache_arg &&
1426 item->type() != Item::CACHE_ITEM &&
1427 (item->type() != Item::FUNC_ITEM ||
1428 ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
1429 {
1430 Item_cache_datetime *cache= new Item_cache_datetime(MYSQL_TYPE_DATETIME);
1431 /* Mark the cache as non-const to prevent re-caching. */
1432 cache->set_used_tables(1);
1433 cache->store(item, value);
1434 *cache_arg= cache;
1435 *item_arg= cache_arg;
1436 }
1437 return value;
1438 }
1439
1440
1441 /*
1442 Retrieves YEAR value of 19XX-00-00 00:00:00 form from given item.
1443
1444 SYNOPSIS
1445 get_year_value()
1446 thd thread handle
1447 item_arg [in/out] item to retrieve YEAR value from
1448 cache_arg [in/out] pointer to place to store the caching item to
1449 warn_item [in] item for issuing the conversion warning
1450 is_null [out] TRUE <=> the item_arg is null
1451
1452 DESCRIPTION
1453 Retrieves the YEAR value of 19XX form from given item for comparison by the
1454 compare_datetime() function.
1455 Converts year to DATETIME of form YYYY-00-00 00:00:00 for the compatibility
1456 with the get_datetime_value function result.
1457
1458 RETURN
1459 obtained value
1460 */
1461
1462 static longlong
get_year_value(THD * thd,Item *** item_arg,Item ** cache_arg,const Item * warn_item,bool * is_null)1463 get_year_value(THD *thd, Item ***item_arg, Item **cache_arg,
1464 const Item *warn_item, bool *is_null)
1465 {
1466 longlong value= 0;
1467 Item *item= **item_arg;
1468
1469 value= item->val_int();
1470 *is_null= item->null_value;
1471 if (*is_null)
1472 return ~(ulonglong) 0;
1473
1474 /* Convert year to DATETIME packed format */
1475 return year_to_longlong_datetime_packed(static_cast<long>(value));
1476 }
1477
1478
1479 /*
1480 Compare items values as dates.
1481
1482 SYNOPSIS
1483 Arg_comparator::compare_datetime()
1484
1485 DESCRIPTION
1486 Compare items values as DATE/DATETIME for both EQUAL_FUNC and from other
1487 comparison functions. The correct DATETIME values are obtained
1488 with help of the get_datetime_value() function.
1489
1490 RETURN
1491 If is_nulls_eq is TRUE:
1492 1 if items are equal or both are null
1493 0 otherwise
1494 If is_nulls_eq is FALSE:
1495 -1 a < b or at least one item is null
1496 0 a == b
1497 1 a > b
1498 See the table:
1499 is_nulls_eq | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
1500 a_is_null | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
1501 b_is_null | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
1502 result | 1 | 0 | 0 |0/1|-1 |-1 |-1 |-1/0/1|
1503 */
1504
compare_datetime()1505 int Arg_comparator::compare_datetime()
1506 {
1507 bool a_is_null, b_is_null;
1508 longlong a_value, b_value;
1509 THD *thd= current_thd;
1510
1511 /* Get DATE/DATETIME/TIME value of the 'a' item. */
1512 a_value= (*get_value_a_func)(thd, &a, &a_cache, *b, &a_is_null);
1513 if (!is_nulls_eq && a_is_null)
1514 {
1515 if (set_null)
1516 owner->null_value= 1;
1517 return -1;
1518 }
1519
1520 /* Get DATE/DATETIME/TIME value of the 'b' item. */
1521 b_value= (*get_value_b_func)(thd, &b, &b_cache, *a, &b_is_null);
1522 if (a_is_null || b_is_null)
1523 {
1524 if (set_null)
1525 owner->null_value= is_nulls_eq ? 0 : 1;
1526 return is_nulls_eq ? (a_is_null == b_is_null) : -1;
1527 }
1528
1529 /* Here we have two not-NULL values. */
1530 if (set_null)
1531 owner->null_value= 0;
1532
1533 /* Compare values. */
1534 if (is_nulls_eq)
1535 return (a_value == b_value);
1536 return a_value < b_value ? -1 : (a_value > b_value ? 1 : 0);
1537 }
1538
1539
1540 /**
1541 Get one of the arguments to the comparator as a JSON value.
1542
1543 @param[in] arg pointer to the argument
1544 @param[in,out] value buffer used for reading the JSON value
1545 @param[in,out] tmp buffer used for converting string values to the
1546 correct charset, if necessary
1547 @param[out] result where to store the result
1548 @param[in,out] scalar pointer to a location with pre-allocated memory
1549 used for JSON scalars that are converted from
1550 SQL scalars
1551
1552 @retval false on success
1553 @retval true on failure
1554 */
get_json_arg(Item * arg,String * value,String * tmp,Json_wrapper * result,Json_scalar_holder ** scalar)1555 static bool get_json_arg(Item* arg, String *value, String *tmp,
1556 Json_wrapper *result, Json_scalar_holder **scalar)
1557 {
1558 Json_scalar_holder *holder= NULL;
1559
1560 /*
1561 If the argument is a non-JSON type, it gets converted to a JSON
1562 scalar. Use the pre-allocated memory passed in via the "scalar"
1563 argument. Note, however, that geometry types are not converted
1564 to scalars. They are converted to JSON objects by get_json_atom_wrapper().
1565 */
1566 if ((arg->field_type() != MYSQL_TYPE_JSON) &&
1567 (arg->field_type() != MYSQL_TYPE_GEOMETRY))
1568 {
1569 /*
1570 If it's a constant item, and we've already read it, just return
1571 the value that's cached in the pre-allocated memory.
1572 */
1573 if (*scalar && arg->const_item())
1574 {
1575 Json_wrapper tmp(get_json_scalar_from_holder(*scalar));
1576 tmp.set_alias();
1577 result->steal(&tmp);
1578 return false;
1579 }
1580
1581 /*
1582 Allocate memory to hold the scalar, if we haven't already done
1583 so. Otherwise, we reuse the previously allocated memory.
1584 */
1585 if (!*scalar)
1586 *scalar= create_json_scalar_holder();
1587
1588 holder= *scalar;
1589 }
1590
1591 return get_json_atom_wrapper(&arg, 0, "<=", value, tmp, result, holder, true);
1592 }
1593
1594
1595 /**
1596 Compare two Item objects as JSON.
1597
1598 If one of the arguments is NULL, and the owner is not EQUAL_FUNC,
1599 the null_value flag of the owner will be set to true.
1600
1601 @return
1602
1603 If is_nulls_eq is true, return 1 if both items are not NULL and
1604 they are equal, or if both items are NULL; otherwise, return 0.
1605
1606 If is_nulls_eq is false, return -1 if at least one of the items is
1607 NULL or if the first item is less than the second item, return 0
1608 if the two items are equal, return 1 if the first item is greater
1609 than the second item.
1610 */
compare_json()1611 int Arg_comparator::compare_json()
1612 {
1613 char buf[STRING_BUFFER_USUAL_SIZE];
1614 String tmp(buf, sizeof(buf), &my_charset_bin);
1615
1616 // Get the JSON value in the a Item.
1617 Json_wrapper aw;
1618 if (get_json_arg(*a, &value1, &tmp, &aw, &json_scalar))
1619 return 1;
1620
1621 bool a_is_null= (*a)->null_value;
1622 if (a_is_null)
1623 {
1624 if (!is_nulls_eq)
1625 {
1626 if (set_null)
1627 owner->null_value= true;
1628 return -1;
1629 }
1630 }
1631
1632 // Get the JSON value in the b Item.
1633 Json_wrapper bw;
1634 if (get_json_arg(*b, &value1, &tmp, &bw, &json_scalar))
1635 return 1;
1636
1637 bool b_is_null= (*b)->null_value;
1638 if (b_is_null)
1639 {
1640 if (!is_nulls_eq)
1641 {
1642 if (set_null)
1643 owner->null_value= true;
1644 return -1;
1645 }
1646 }
1647
1648 if (set_null)
1649 owner->null_value= false;
1650
1651 /*
1652 If we were called by the <=> operator, we should return 0/1
1653 instead of -1/0/1. 0 means not equal, 1 means equal. The <=>
1654 operator considers two NULLs equal.
1655 */
1656 if (is_nulls_eq)
1657 {
1658 if (a_is_null || b_is_null)
1659 return a_is_null == b_is_null;
1660 else
1661 return aw.compare(bw) == 0;
1662 }
1663
1664 // Otherwise, return -1/0/1.
1665 return aw.compare(bw);
1666 }
1667
1668
compare_string()1669 int Arg_comparator::compare_string()
1670 {
1671 String *res1,*res2;
1672 if ((res1= (*a)->val_str(&value1)))
1673 {
1674 if ((res2= (*b)->val_str(&value2)))
1675 {
1676 if (set_null)
1677 owner->null_value= 0;
1678 return sortcmp(res1,res2,cmp_collation.collation);
1679 }
1680 }
1681 if (set_null)
1682 owner->null_value= 1;
1683 return -1;
1684 }
1685
1686
1687 /**
1688 Compare strings byte by byte. End spaces are also compared.
1689
1690 @retval
1691 <0 *a < *b
1692 @retval
1693 0 *b == *b
1694 @retval
1695 >0 *a > *b
1696 */
1697
compare_binary_string()1698 int Arg_comparator::compare_binary_string()
1699 {
1700 String *res1,*res2;
1701 if ((res1= (*a)->val_str(&value1)))
1702 {
1703 if ((res2= (*b)->val_str(&value2)))
1704 {
1705 if (set_null)
1706 owner->null_value= 0;
1707 size_t res1_length= res1->length();
1708 size_t res2_length= res2->length();
1709 int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
1710 return cmp ? cmp : (int) (res1_length - res2_length);
1711 }
1712 }
1713 if (set_null)
1714 owner->null_value= 1;
1715 return -1;
1716 }
1717
1718
1719 /**
1720 Compare strings, but take into account that NULL == NULL.
1721 */
1722
1723
compare_e_string()1724 int Arg_comparator::compare_e_string()
1725 {
1726 String *res1,*res2;
1727 res1= (*a)->val_str(&value1);
1728 res2= (*b)->val_str(&value2);
1729 if (!res1 || !res2)
1730 return MY_TEST(res1 == res2);
1731 return MY_TEST(sortcmp(res1, res2, cmp_collation.collation) == 0);
1732 }
1733
1734
compare_e_binary_string()1735 int Arg_comparator::compare_e_binary_string()
1736 {
1737 String *res1,*res2;
1738 res1= (*a)->val_str(&value1);
1739 res2= (*b)->val_str(&value2);
1740 if (!res1 || !res2)
1741 return MY_TEST(res1 == res2);
1742 return MY_TEST(stringcmp(res1, res2) == 0);
1743 }
1744
1745
compare_real()1746 int Arg_comparator::compare_real()
1747 {
1748 /*
1749 Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
1750 gcc to flush double values out of 80-bit Intel FPU registers before
1751 performing the comparison.
1752 */
1753 volatile double val1, val2;
1754 val1= (*a)->val_real();
1755 if (!(*a)->null_value)
1756 {
1757 val2= (*b)->val_real();
1758 if (!(*b)->null_value)
1759 {
1760 if (set_null)
1761 owner->null_value= 0;
1762 if (val1 < val2) return -1;
1763 if (val1 == val2) return 0;
1764 return 1;
1765 }
1766 }
1767 if (set_null)
1768 owner->null_value= 1;
1769 return -1;
1770 }
1771
compare_decimal()1772 int Arg_comparator::compare_decimal()
1773 {
1774 my_decimal decimal1;
1775 my_decimal *val1= (*a)->val_decimal(&decimal1);
1776 if (!(*a)->null_value)
1777 {
1778 my_decimal decimal2;
1779 my_decimal *val2= (*b)->val_decimal(&decimal2);
1780 if (!(*b)->null_value)
1781 {
1782 if (set_null)
1783 owner->null_value= 0;
1784 return my_decimal_cmp(val1, val2);
1785 }
1786 }
1787 if (set_null)
1788 owner->null_value= 1;
1789 return -1;
1790 }
1791
compare_e_real()1792 int Arg_comparator::compare_e_real()
1793 {
1794 double val1= (*a)->val_real();
1795 double val2= (*b)->val_real();
1796 if ((*a)->null_value || (*b)->null_value)
1797 return MY_TEST((*a)->null_value && (*b)->null_value);
1798 return MY_TEST(val1 == val2);
1799 }
1800
compare_e_decimal()1801 int Arg_comparator::compare_e_decimal()
1802 {
1803 my_decimal decimal1, decimal2;
1804 my_decimal *val1= (*a)->val_decimal(&decimal1);
1805 my_decimal *val2= (*b)->val_decimal(&decimal2);
1806 if ((*a)->null_value || (*b)->null_value)
1807 return MY_TEST((*a)->null_value && (*b)->null_value);
1808 return MY_TEST(my_decimal_cmp(val1, val2) == 0);
1809 }
1810
1811
compare_real_fixed()1812 int Arg_comparator::compare_real_fixed()
1813 {
1814 /*
1815 Fix yet another manifestation of Bug#2338. 'Volatile' will instruct
1816 gcc to flush double values out of 80-bit Intel FPU registers before
1817 performing the comparison.
1818 */
1819 volatile double val1, val2;
1820 val1= (*a)->val_real();
1821 if (!(*a)->null_value)
1822 {
1823 val2= (*b)->val_real();
1824 if (!(*b)->null_value)
1825 {
1826 if (set_null)
1827 owner->null_value= 0;
1828 if (val1 == val2 || fabs(val1 - val2) < precision)
1829 return 0;
1830 if (val1 < val2)
1831 return -1;
1832 return 1;
1833 }
1834 }
1835 if (set_null)
1836 owner->null_value= 1;
1837 return -1;
1838 }
1839
1840
compare_e_real_fixed()1841 int Arg_comparator::compare_e_real_fixed()
1842 {
1843 double val1= (*a)->val_real();
1844 double val2= (*b)->val_real();
1845 if ((*a)->null_value || (*b)->null_value)
1846 return MY_TEST((*a)->null_value && (*b)->null_value);
1847 return MY_TEST(val1 == val2 || fabs(val1 - val2) < precision);
1848 }
1849
1850
compare_int_signed()1851 int Arg_comparator::compare_int_signed()
1852 {
1853 longlong val1= (*a)->val_int();
1854 if (!(*a)->null_value)
1855 {
1856 longlong val2= (*b)->val_int();
1857 if (!(*b)->null_value)
1858 {
1859 if (set_null)
1860 owner->null_value= 0;
1861 if (val1 < val2) return -1;
1862 if (val1 == val2) return 0;
1863 return 1;
1864 }
1865 }
1866 if (set_null)
1867 owner->null_value= 1;
1868 return -1;
1869 }
1870
1871
1872 /**
1873 Compare arguments using numeric packed temporal representation.
1874 */
compare_time_packed()1875 int Arg_comparator::compare_time_packed()
1876 {
1877 /*
1878 Note, we cannot do this:
1879 DBUG_ASSERT((*a)->field_type() == MYSQL_TYPE_TIME);
1880 DBUG_ASSERT((*b)->field_type() == MYSQL_TYPE_TIME);
1881
1882 SELECT col_time_key FROM t1
1883 WHERE
1884 col_time_key != UTC_DATE()
1885 AND
1886 col_time_key = MAKEDATE(43, -2852);
1887
1888 is rewritten to:
1889
1890 SELECT col_time_key FROM t1
1891 WHERE
1892 MAKEDATE(43, -2852) != UTC_DATE()
1893 AND
1894 col_time_key = MAKEDATE(43, -2852);
1895 */
1896 longlong val1= (*a)->val_time_temporal();
1897 if (!(*a)->null_value)
1898 {
1899 longlong val2= (*b)->val_time_temporal();
1900 if (!(*b)->null_value)
1901 {
1902 if (set_null)
1903 owner->null_value= 0;
1904 return val1 < val2 ? -1 : val1 > val2 ? 1 : 0;
1905 }
1906 }
1907 if (set_null)
1908 owner->null_value= 1;
1909 return -1;
1910 }
1911
1912
1913 /**
1914 Compare arguments using numeric packed representation for '<=>'.
1915 */
compare_e_time_packed()1916 int Arg_comparator::compare_e_time_packed()
1917 {
1918 longlong val1= (*a)->val_time_temporal();
1919 longlong val2= (*b)->val_time_temporal();
1920 if ((*a)->null_value || (*b)->null_value)
1921 return MY_TEST((*a)->null_value && (*b)->null_value);
1922 return MY_TEST(val1 == val2);
1923 }
1924
1925
1926
1927 /**
1928 Compare values as BIGINT UNSIGNED.
1929 */
1930
compare_int_unsigned()1931 int Arg_comparator::compare_int_unsigned()
1932 {
1933 ulonglong val1= (*a)->val_int();
1934 if (!(*a)->null_value)
1935 {
1936 ulonglong val2= (*b)->val_int();
1937 if (!(*b)->null_value)
1938 {
1939 if (set_null)
1940 owner->null_value= 0;
1941 if (val1 < val2) return -1;
1942 if (val1 == val2) return 0;
1943 return 1;
1944 }
1945 }
1946 if (set_null)
1947 owner->null_value= 1;
1948 return -1;
1949 }
1950
1951
1952 /**
1953 Compare signed (*a) with unsigned (*B)
1954 */
1955
compare_int_signed_unsigned()1956 int Arg_comparator::compare_int_signed_unsigned()
1957 {
1958 longlong sval1= (*a)->val_int();
1959 if (!(*a)->null_value)
1960 {
1961 ulonglong uval2= (ulonglong)(*b)->val_int();
1962 if (!(*b)->null_value)
1963 {
1964 if (set_null)
1965 owner->null_value= 0;
1966 if (sval1 < 0 || (ulonglong)sval1 < uval2)
1967 return -1;
1968 if ((ulonglong)sval1 == uval2)
1969 return 0;
1970 return 1;
1971 }
1972 }
1973 if (set_null)
1974 owner->null_value= 1;
1975 return -1;
1976 }
1977
1978
1979 /**
1980 Compare unsigned (*a) with signed (*B)
1981 */
1982
compare_int_unsigned_signed()1983 int Arg_comparator::compare_int_unsigned_signed()
1984 {
1985 ulonglong uval1= (ulonglong)(*a)->val_int();
1986 if (!(*a)->null_value)
1987 {
1988 longlong sval2= (*b)->val_int();
1989 if (!(*b)->null_value)
1990 {
1991 if (set_null)
1992 owner->null_value= 0;
1993 if (sval2 < 0)
1994 return 1;
1995 if (uval1 < (ulonglong)sval2)
1996 return -1;
1997 if (uval1 == (ulonglong)sval2)
1998 return 0;
1999 return 1;
2000 }
2001 }
2002 if (set_null)
2003 owner->null_value= 1;
2004 return -1;
2005 }
2006
2007
compare_e_int()2008 int Arg_comparator::compare_e_int()
2009 {
2010 longlong val1= (*a)->val_int();
2011 longlong val2= (*b)->val_int();
2012 if ((*a)->null_value || (*b)->null_value)
2013 return MY_TEST((*a)->null_value && (*b)->null_value);
2014 return MY_TEST(val1 == val2);
2015 }
2016
2017 /**
2018 Compare unsigned *a with signed *b or signed *a with unsigned *b.
2019 */
compare_e_int_diff_signedness()2020 int Arg_comparator::compare_e_int_diff_signedness()
2021 {
2022 longlong val1= (*a)->val_int();
2023 longlong val2= (*b)->val_int();
2024 if ((*a)->null_value || (*b)->null_value)
2025 return MY_TEST((*a)->null_value && (*b)->null_value);
2026 return (val1 >= 0) && MY_TEST(val1 == val2);
2027 }
2028
compare_row()2029 int Arg_comparator::compare_row()
2030 {
2031 int res= 0;
2032 bool was_null= 0;
2033 (*a)->bring_value();
2034 (*b)->bring_value();
2035
2036 if ((*a)->null_value || (*b)->null_value)
2037 {
2038 owner->null_value= 1;
2039 return -1;
2040 }
2041
2042 uint n= (*a)->cols();
2043 for (uint i= 0; i<n; i++)
2044 {
2045 res= comparators[i].compare();
2046 /* Aggregate functions don't need special null handling. */
2047 if (owner->null_value && owner->type() == Item::FUNC_ITEM)
2048 {
2049 // NULL was compared
2050 switch (((Item_func*)owner)->functype()) {
2051 case Item_func::NE_FUNC:
2052 break; // NE never aborts on NULL even if abort_on_null is set
2053 case Item_func::LT_FUNC:
2054 case Item_func::LE_FUNC:
2055 case Item_func::GT_FUNC:
2056 case Item_func::GE_FUNC:
2057 return -1; // <, <=, > and >= always fail on NULL
2058 default: // EQ_FUNC
2059 if (((Item_bool_func2*)owner)->abort_on_null)
2060 return -1; // We do not need correct NULL returning
2061 }
2062 was_null= 1;
2063 owner->null_value= 0;
2064 res= 0; // continue comparison (maybe we will meet explicit difference)
2065 }
2066 else if (res)
2067 return res;
2068 }
2069 if (was_null)
2070 {
2071 /*
2072 There was NULL(s) in comparison in some parts, but there was no
2073 explicit difference in other parts, so we have to return NULL.
2074 */
2075 owner->null_value= 1;
2076 return -1;
2077 }
2078 return 0;
2079 }
2080
2081
compare_e_row()2082 int Arg_comparator::compare_e_row()
2083 {
2084 (*a)->bring_value();
2085 (*b)->bring_value();
2086 uint n= (*a)->cols();
2087 for (uint i= 0; i<n; i++)
2088 {
2089 if (!comparators[i].compare())
2090 return 0;
2091 }
2092 return 1;
2093 }
2094
2095
fix_length_and_dec()2096 void Item_func_truth::fix_length_and_dec()
2097 {
2098 maybe_null= 0;
2099 null_value= 0;
2100 decimals= 0;
2101 max_length= 1;
2102 }
2103
2104
print(String * str,enum_query_type query_type)2105 void Item_func_truth::print(String *str, enum_query_type query_type)
2106 {
2107 str->append('(');
2108 args[0]->print(str, query_type);
2109 str->append(STRING_WITH_LEN(" is "));
2110 if (! affirmative)
2111 str->append(STRING_WITH_LEN("not "));
2112 if (value)
2113 str->append(STRING_WITH_LEN("true"));
2114 else
2115 str->append(STRING_WITH_LEN("false"));
2116 str->append(')');
2117 }
2118
2119
val_bool()2120 bool Item_func_truth::val_bool()
2121 {
2122 bool val= args[0]->val_bool();
2123 if (args[0]->null_value)
2124 {
2125 /*
2126 NULL val IS {TRUE, FALSE} --> FALSE
2127 NULL val IS NOT {TRUE, FALSE} --> TRUE
2128 */
2129 return (! affirmative);
2130 }
2131
2132 if (affirmative)
2133 {
2134 /* {TRUE, FALSE} val IS {TRUE, FALSE} value */
2135 return (val == value);
2136 }
2137
2138 /* {TRUE, FALSE} val IS NOT {TRUE, FALSE} value */
2139 return (val != value);
2140 }
2141
2142
val_int()2143 longlong Item_func_truth::val_int()
2144 {
2145 return (val_bool() ? 1 : 0);
2146 }
2147
2148
fix_left(THD * thd,Item ** ref)2149 bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
2150 {
2151 /*
2152 Refresh this pointer as left_expr may have been substituted
2153 during resolving.
2154 */
2155 args[0]= ((Item_in_subselect *)args[1])->left_expr;
2156
2157 if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
2158 (!cache && !(cache= Item_cache::get_cache(args[0]))))
2159 return 1;
2160
2161 cache->setup(args[0]);
2162 used_tables_cache= args[0]->used_tables();
2163 if (cache->cols() == 1)
2164 {
2165 cache->set_used_tables(used_tables_cache);
2166 }
2167 else
2168 {
2169 uint n= cache->cols();
2170 for (uint i= 0; i < n; i++)
2171 {
2172 ((Item_cache *)cache->element_index(i))->
2173 set_used_tables(args[0]->element_index(i)->used_tables());
2174 }
2175 }
2176 not_null_tables_cache= args[0]->not_null_tables();
2177 with_sum_func= args[0]->with_sum_func;
2178 if ((const_item_cache= args[0]->const_item()))
2179 cache->store(args[0]);
2180 return 0;
2181 }
2182
2183
fix_fields(THD * thd,Item ** ref)2184 bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
2185 {
2186 DBUG_ASSERT(fixed == 0);
2187 if (fix_left(thd, ref))
2188 return TRUE;
2189 if (args[0]->maybe_null)
2190 maybe_null=1;
2191
2192 if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
2193 return TRUE;
2194 Item_in_subselect * sub= (Item_in_subselect *)args[1];
2195 if (args[0]->cols() != sub->engine->cols())
2196 {
2197 my_error(ER_OPERAND_COLUMNS, MYF(0), args[0]->cols());
2198 return TRUE;
2199 }
2200 if (args[1]->maybe_null)
2201 maybe_null=1;
2202 with_sum_func= with_sum_func || args[1]->with_sum_func;
2203 used_tables_cache|= args[1]->used_tables();
2204 not_null_tables_cache|= args[1]->not_null_tables();
2205
2206 if (!sub->is_top_level_item())
2207 {
2208 /*
2209 This is a NOT IN subquery predicate (or equivalent). Null values passed
2210 from outer tables and used in the left-hand expression of the predicate
2211 must be considered in the evaluation, hence filter out these tables
2212 from the set of null-rejecting tables.
2213 */
2214 not_null_tables_cache&= ~args[0]->not_null_tables();
2215 }
2216 const_item_cache&= args[1]->const_item();
2217 fixed= 1;
2218 return FALSE;
2219 }
2220
2221
fix_after_pullout(st_select_lex * parent_select,st_select_lex * removed_select)2222 void Item_in_optimizer::fix_after_pullout(st_select_lex *parent_select,
2223 st_select_lex *removed_select)
2224 {
2225 used_tables_cache= get_initial_pseudo_tables();
2226 not_null_tables_cache= 0;
2227 const_item_cache= 1;
2228
2229 /*
2230 No need to call fix_after_pullout() on args[0] (ie left expression),
2231 as Item_in_subselect::fix_after_pullout() will do this.
2232 So, just forward the call to the Item_in_subselect object.
2233 */
2234
2235 args[1]->fix_after_pullout(parent_select, removed_select);
2236
2237 used_tables_cache|= args[1]->used_tables();
2238 not_null_tables_cache|= args[1]->not_null_tables();
2239 const_item_cache&= args[1]->const_item();
2240 }
2241
2242
2243 /**
2244 The implementation of optimized \<outer expression\> [NOT] IN \<subquery\>
2245 predicates. It applies to predicates which have gone through the IN->EXISTS
2246 transformation in in_to_exists_transformer functions; not to subquery
2247 materialization (which has no triggered conditions).
2248
2249 The implementation works as follows.
2250 For the current value of the outer expression
2251
2252 - If it contains only NULL values, the original (before rewrite by the
2253 Item_in_subselect rewrite methods) inner subquery is non-correlated and
2254 was previously executed, there is no need to re-execute it, and the
2255 previous return value is returned.
2256
2257 - If it contains NULL values, check if there is a partial match for the
2258 inner query block by evaluating it. For clarity we repeat here the
2259 transformation previously performed on the sub-query. The expression
2260
2261 <tt>
2262 ( oc_1, ..., oc_n )
2263 \<in predicate\>
2264 ( SELECT ic_1, ..., ic_n
2265 FROM \<table\>
2266 WHERE \<inner where\>
2267 )
2268 </tt>
2269
2270 was transformed into
2271
2272 <tt>
2273 ( oc_1, ..., oc_n )
2274 \<in predicate\>
2275 ( SELECT ic_1, ..., ic_n
2276 FROM \<table\>
2277 WHERE \<inner where\> AND ... ( ic_k = oc_k OR ic_k IS NULL )
2278 HAVING ... NOT ic_k IS NULL
2279 )
2280 </tt>
2281
2282 The evaluation will now proceed according to special rules set up
2283 elsewhere. These rules include:
2284
2285 - The HAVING NOT \<inner column\> IS NULL conditions added by the
2286 aforementioned rewrite methods will detect whether they evaluated (and
2287 rejected) a NULL value and if so, will cause the subquery to evaluate
2288 to NULL.
2289
2290 - The added WHERE and HAVING conditions are present only for those inner
2291 columns that correspond to outer column that are not NULL at the moment.
2292
2293 - If there is an eligible index for executing the subquery, the special
2294 access method "Full scan on NULL key" is employed which ensures that
2295 the inner query will detect if there are NULL values resulting from the
2296 inner query. This access method will quietly resort to table scan if it
2297 needs to find NULL values as well.
2298
2299 - Under these conditions, the sub-query need only be evaluated in order to
2300 find out whether it produced any rows.
2301
2302 - If it did, we know that there was a partial match since there are
2303 NULL values in the outer row expression.
2304
2305 - If it did not, the result is FALSE or UNKNOWN. If at least one of the
2306 HAVING sub-predicates rejected a NULL value corresponding to an outer
2307 non-NULL, and hence the inner query block returns UNKNOWN upon
2308 evaluation, there was a partial match and the result is UNKNOWN.
2309
2310 - If it contains no NULL values, the call is forwarded to the inner query
2311 block.
2312
2313 @see Item_in_subselect::val_bool()
2314 @see Item_is_not_null_test::val_int()
2315 */
2316
val_int()2317 longlong Item_in_optimizer::val_int()
2318 {
2319 bool tmp;
2320 DBUG_ASSERT(fixed == 1);
2321 cache->store(args[0]);
2322 cache->cache_value();
2323
2324 if (cache->null_value)
2325 {
2326 Item_in_subselect * const item_subs=
2327 static_cast<Item_in_subselect *>(args[1]);
2328 /*
2329 We're evaluating
2330 "<outer_value_list> [NOT] IN (SELECT <inner_value_list>...)"
2331 where one or more of the outer values is NULL.
2332 */
2333 if (item_subs->is_top_level_item())
2334 {
2335 /*
2336 We're evaluating a top level item, e.g.
2337 "<outer_value_list> IN (SELECT <inner_value_list>...)",
2338 and in this case a NULL value in the outer_value_list means
2339 that the result shall be NULL/FALSE (makes no difference for
2340 top level items). The cached value is NULL, so just return
2341 NULL.
2342 */
2343 null_value= 1;
2344 }
2345 else
2346 {
2347 /*
2348 We're evaluating an item where a NULL value in either the
2349 outer or inner value list does not automatically mean that we
2350 can return NULL/FALSE. An example of such a query is
2351 "<outer_value_list> NOT IN (SELECT <inner_value_list>...)"
2352 The result when there is at least one NULL value is: NULL if the
2353 SELECT evaluated over the non-NULL values produces at least
2354 one row, FALSE otherwise
2355 */
2356 bool all_left_cols_null= true;
2357 const uint ncols= cache->cols();
2358
2359 /*
2360 Turn off the predicates that are based on column compares for
2361 which the left part is currently NULL
2362 */
2363 for (uint i= 0; i < ncols; i++)
2364 {
2365 if (cache->element_index(i)->null_value)
2366 item_subs->set_cond_guard_var(i, FALSE);
2367 else
2368 all_left_cols_null= false;
2369 }
2370
2371 if (all_left_cols_null && result_for_null_param != UNKNOWN &&
2372 !item_subs->dependent_before_in2exists())
2373 {
2374 /*
2375 This subquery was originally not correlated. The IN->EXISTS
2376 transformation may have made it correlated, but only to the left
2377 expression. All values in the left expression are NULL, and we have
2378 already evaluated the subquery for all NULL values: return the same
2379 result we did last time without evaluating the subquery.
2380 */
2381 null_value= result_for_null_param;
2382 }
2383 else
2384 {
2385 /* The subquery has to be evaluated */
2386 (void) item_subs->val_bool_result();
2387 if (!item_subs->value)
2388 null_value= item_subs->null_value;
2389 else
2390 null_value= TRUE;
2391 if (all_left_cols_null)
2392 result_for_null_param= null_value;
2393 }
2394
2395 /* Turn all predicates back on */
2396 for (uint i= 0; i < ncols; i++)
2397 item_subs->set_cond_guard_var(i, TRUE);
2398 }
2399 return 0;
2400 }
2401 tmp= args[1]->val_bool_result();
2402 null_value= args[1]->null_value;
2403 return tmp;
2404 }
2405
2406
keep_top_level_cache()2407 void Item_in_optimizer::keep_top_level_cache()
2408 {
2409 cache->keep_array();
2410 save_cache= 1;
2411 }
2412
2413
cleanup()2414 void Item_in_optimizer::cleanup()
2415 {
2416 DBUG_ENTER("Item_in_optimizer::cleanup");
2417 Item_bool_func::cleanup();
2418 if (!save_cache)
2419 cache= 0;
2420 DBUG_VOID_RETURN;
2421 }
2422
2423
is_null()2424 bool Item_in_optimizer::is_null()
2425 {
2426 val_int();
2427 return null_value;
2428 }
2429
2430
2431 /**
2432 Transform an Item_in_optimizer and its arguments with a callback function.
2433
2434 @param transformer the transformer callback function to be applied to the
2435 nodes of the tree of the object
2436 @param parameter to be passed to the transformer
2437
2438 @detail
2439 Recursively transform the left and the right operand of this Item. The
2440 Right operand is an Item_in_subselect or its subclass. To avoid the
2441 creation of new Items, we use the fact the the left operand of the
2442 Item_in_subselect is the same as the one of 'this', so instead of
2443 transforming its operand, we just assign the left operand of the
2444 Item_in_subselect to be equal to the left operand of 'this'.
2445 The transformation is not applied further to the subquery operand
2446 if the IN predicate.
2447
2448 @returns
2449 @retval pointer to the transformed item
2450 @retval NULL if an error occurred
2451 */
2452
transform(Item_transformer transformer,uchar * argument)2453 Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument)
2454 {
2455 Item *new_item;
2456
2457 DBUG_ASSERT(!current_thd->stmt_arena->is_stmt_prepare());
2458 DBUG_ASSERT(arg_count == 2);
2459
2460 /* Transform the left IN operand. */
2461 new_item= args[0]->transform(transformer, argument);
2462 if (!new_item)
2463 return 0;
2464 /*
2465 THD::change_item_tree() should be called only if the tree was
2466 really transformed, i.e. when a new item has been created.
2467 Otherwise we'll be allocating a lot of unnecessary memory for
2468 change records at each execution.
2469 */
2470 if (args[0] != new_item)
2471 current_thd->change_item_tree(args, new_item);
2472
2473 /*
2474 Transform the right IN operand which should be an Item_in_subselect or a
2475 subclass of it. The left operand of the IN must be the same as the left
2476 operand of this Item_in_optimizer, so in this case there is no further
2477 transformation, we only make both operands the same.
2478 TODO: is it the way it should be?
2479 */
2480 DBUG_ASSERT((args[1])->type() == Item::SUBSELECT_ITEM &&
2481 (((Item_subselect*)(args[1]))->substype() ==
2482 Item_subselect::IN_SUBS ||
2483 ((Item_subselect*)(args[1]))->substype() ==
2484 Item_subselect::ALL_SUBS ||
2485 ((Item_subselect*)(args[1]))->substype() ==
2486 Item_subselect::ANY_SUBS));
2487
2488 Item_in_subselect *in_arg= (Item_in_subselect*)args[1];
2489
2490 if (in_arg->left_expr != args[0])
2491 current_thd->change_item_tree(&in_arg->left_expr, args[0]);
2492
2493 return (this->*transformer)(argument);
2494 }
2495
2496
replace_argument(THD * thd,Item ** oldpp,Item * newp)2497 void Item_in_optimizer::replace_argument(THD *thd, Item **oldpp, Item *newp)
2498 {
2499 // Maintain the invariant described in this class's comment
2500 Item_in_subselect *ss= down_cast<Item_in_subselect *>(args[1]);
2501 thd->change_item_tree(&ss->left_expr, newp);
2502 /*
2503 fix_left() does cache setup. This setup() does (mainly)
2504 cache->example=arg[0]; we could wonder why change_item_tree isn't used
2505 instead of this simple assignment. The reason is that cache->setup() is
2506 called at every fix_fields(), so every execution, so it's not important if
2507 the previous execution left a non-rolled-back now-pointing-to-garbage
2508 cache->example - it will be overwritten.
2509 */
2510 fix_left(thd, NULL);
2511 }
2512
val_int()2513 longlong Item_func_eq::val_int()
2514 {
2515 DBUG_ASSERT(fixed == 1);
2516 int value= cmp.compare();
2517 return value == 0 ? 1 : 0;
2518 }
2519
2520
2521 /** Same as Item_func_eq, but NULL = NULL. */
2522
fix_length_and_dec()2523 void Item_func_equal::fix_length_and_dec()
2524 {
2525 Item_bool_func2::fix_length_and_dec();
2526 maybe_null=null_value=0;
2527 }
2528
val_int()2529 longlong Item_func_equal::val_int()
2530 {
2531 DBUG_ASSERT(fixed == 1);
2532 return cmp.compare();
2533 }
2534
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)2535 float Item_func_ne::get_filtering_effect(table_map filter_for_table,
2536 table_map read_tables,
2537 const MY_BITMAP *fields_to_ignore,
2538 double rows_in_table)
2539 {
2540 const Item_field* fld=
2541 contributes_to_filter(read_tables, filter_for_table, fields_to_ignore);
2542 if (!fld)
2543 return COND_FILTER_ALLPASS;
2544
2545 return 1.0f - fld->get_cond_filter_default_probability(rows_in_table,
2546 COND_FILTER_EQUALITY);
2547 }
2548
val_int()2549 longlong Item_func_ne::val_int()
2550 {
2551 DBUG_ASSERT(fixed == 1);
2552 int value= cmp.compare();
2553 return value != 0 && !null_value ? 1 : 0;
2554 }
2555
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)2556 float Item_func_equal::get_filtering_effect(table_map filter_for_table,
2557 table_map read_tables,
2558 const MY_BITMAP *fields_to_ignore,
2559 double rows_in_table)
2560 {
2561 const Item_field* fld=
2562 contributes_to_filter(read_tables, filter_for_table, fields_to_ignore);
2563 if (!fld)
2564 return COND_FILTER_ALLPASS;
2565
2566 return fld->get_cond_filter_default_probability(rows_in_table,
2567 COND_FILTER_EQUALITY);
2568 }
2569
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)2570 float Item_func_ge::get_filtering_effect(table_map filter_for_table,
2571 table_map read_tables,
2572 const MY_BITMAP *fields_to_ignore,
2573 double rows_in_table)
2574 {
2575 const Item_field* fld=
2576 contributes_to_filter(read_tables, filter_for_table, fields_to_ignore);
2577 if (!fld)
2578 return COND_FILTER_ALLPASS;
2579
2580 return fld->get_cond_filter_default_probability(rows_in_table,
2581 COND_FILTER_INEQUALITY);
2582 }
2583
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)2584 float Item_func_lt::get_filtering_effect(table_map filter_for_table,
2585 table_map read_tables,
2586 const MY_BITMAP *fields_to_ignore,
2587 double rows_in_table)
2588 {
2589 const Item_field* fld=
2590 contributes_to_filter(read_tables, filter_for_table, fields_to_ignore);
2591 if (!fld)
2592 return COND_FILTER_ALLPASS;
2593
2594 return fld->get_cond_filter_default_probability(rows_in_table,
2595 COND_FILTER_INEQUALITY);
2596 }
2597
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)2598 float Item_func_le::get_filtering_effect(table_map filter_for_table,
2599 table_map read_tables,
2600 const MY_BITMAP *fields_to_ignore,
2601 double rows_in_table)
2602 {
2603 const Item_field* fld=
2604 contributes_to_filter(read_tables, filter_for_table, fields_to_ignore);
2605 if (!fld)
2606 return COND_FILTER_ALLPASS;
2607
2608 return fld->get_cond_filter_default_probability(rows_in_table,
2609 COND_FILTER_INEQUALITY);
2610 }
2611
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)2612 float Item_func_gt::get_filtering_effect(table_map filter_for_table,
2613 table_map read_tables,
2614 const MY_BITMAP *fields_to_ignore,
2615 double rows_in_table)
2616 {
2617 const Item_field* fld=
2618 contributes_to_filter(read_tables, filter_for_table, fields_to_ignore);
2619 if (!fld)
2620 return COND_FILTER_ALLPASS;
2621
2622 return fld->get_cond_filter_default_probability(rows_in_table,
2623 COND_FILTER_INEQUALITY);
2624 }
2625
val_int()2626 longlong Item_func_ge::val_int()
2627 {
2628 DBUG_ASSERT(fixed == 1);
2629 int value= cmp.compare();
2630 return value >= 0 ? 1 : 0;
2631 }
2632
val_int()2633 longlong Item_func_gt::val_int()
2634 {
2635 DBUG_ASSERT(fixed == 1);
2636 int value= cmp.compare();
2637 return value > 0 ? 1 : 0;
2638 }
2639
val_int()2640 longlong Item_func_le::val_int()
2641 {
2642 DBUG_ASSERT(fixed == 1);
2643 int value= cmp.compare();
2644 return value <= 0 && !null_value ? 1 : 0;
2645 }
2646
2647
val_int()2648 longlong Item_func_lt::val_int()
2649 {
2650 DBUG_ASSERT(fixed == 1);
2651 int value= cmp.compare();
2652 return value < 0 && !null_value ? 1 : 0;
2653 }
2654
2655
val_int()2656 longlong Item_func_strcmp::val_int()
2657 {
2658 DBUG_ASSERT(fixed == 1);
2659 String *a=args[0]->val_str(&cmp.value1);
2660 String *b=args[1]->val_str(&cmp.value2);
2661 if (!a || !b)
2662 {
2663 null_value=1;
2664 return 0;
2665 }
2666 int value= sortcmp(a,b,cmp.cmp_collation.collation);
2667 null_value=0;
2668 return !value ? 0 : (value < 0 ? (longlong) -1 : (longlong) 1);
2669 }
2670
2671
eq(const Item * item,bool binary_cmp) const2672 bool Item_func_opt_neg::eq(const Item *item, bool binary_cmp) const
2673 {
2674 /* Assume we don't have rtti */
2675 if (this == item)
2676 return 1;
2677 if (item->type() != FUNC_ITEM)
2678 return 0;
2679 Item_func *item_func=(Item_func*) item;
2680 if (arg_count != item_func->arg_count ||
2681 functype() != item_func->functype())
2682 return 0;
2683 if (negated != ((Item_func_opt_neg *) item_func)->negated)
2684 return 0;
2685 for (uint i=0; i < arg_count ; i++)
2686 if (!args[i]->eq(item_func->arguments()[i], binary_cmp))
2687 return 0;
2688 return 1;
2689 }
2690
2691
itemize(Parse_context * pc,Item ** res)2692 bool Item_func_interval::itemize(Parse_context *pc, Item **res)
2693 {
2694 if (skip_itemize(res))
2695 return false;
2696 if (row == NULL || // OOM in constructor
2697 super::itemize(pc, res))
2698 return true;
2699 DBUG_ASSERT(row == args[0]); // row->itemize() is not needed
2700 return false;
2701 }
2702
2703
alloc_row(const POS & pos,MEM_ROOT * mem_root,Item * expr1,Item * expr2,PT_item_list * opt_expr_list)2704 Item_row *Item_func_interval::alloc_row(const POS &pos, MEM_ROOT *mem_root,
2705 Item *expr1, Item *expr2,
2706 PT_item_list *opt_expr_list)
2707 {
2708 List<Item> *list= opt_expr_list ? &opt_expr_list->value
2709 : new (mem_root) List<Item>;
2710 if (list == NULL)
2711 return NULL;
2712 list->push_front(expr2);
2713 row= new (mem_root) Item_row(pos, expr1, *list);
2714 return row;
2715 }
2716
2717
fix_length_and_dec()2718 void Item_func_interval::fix_length_and_dec()
2719 {
2720 uint rows= row->cols();
2721
2722 //The number of columns in one argument is limited to one
2723 for (uint i= 0; i < rows; i++)
2724 {
2725 if (row->element_index(i)->check_cols(1))
2726 return;
2727 }
2728
2729 use_decimal_comparison= ((row->element_index(0)->result_type() ==
2730 DECIMAL_RESULT) ||
2731 (row->element_index(0)->result_type() ==
2732 INT_RESULT));
2733 if (rows > 8)
2734 {
2735 bool not_null_consts= TRUE;
2736
2737 for (uint i= 1; not_null_consts && i < rows; i++)
2738 {
2739 Item *el= row->element_index(i);
2740 not_null_consts= el->const_item() && !el->is_null();
2741 }
2742
2743 if (not_null_consts &&
2744 (intervals=
2745 (interval_range*) sql_alloc(sizeof(interval_range) * (rows - 1))))
2746 {
2747 if (use_decimal_comparison)
2748 {
2749 for (uint i= 1; i < rows; i++)
2750 {
2751 Item *el= row->element_index(i);
2752 interval_range *range= intervals + (i-1);
2753 if ((el->result_type() == DECIMAL_RESULT) ||
2754 (el->result_type() == INT_RESULT))
2755 {
2756 range->type= DECIMAL_RESULT;
2757 range->dec.init();
2758 my_decimal *dec= el->val_decimal(&range->dec);
2759 if (dec != &range->dec)
2760 {
2761 range->dec= *dec;
2762 }
2763 }
2764 else
2765 {
2766 range->type= REAL_RESULT;
2767 range->dbl= el->val_real();
2768 }
2769 }
2770 }
2771 else
2772 {
2773 for (uint i= 1; i < rows; i++)
2774 {
2775 intervals[i-1].dbl= row->element_index(i)->val_real();
2776 }
2777 }
2778 }
2779 }
2780 maybe_null= 0;
2781 max_length= 2;
2782 used_tables_cache|= row->used_tables();
2783 not_null_tables_cache= row->not_null_tables();
2784 with_sum_func= with_sum_func || row->with_sum_func;
2785 const_item_cache&= row->const_item();
2786 }
2787
2788
2789 /**
2790 Appends function name and arguments list to the String str.
2791
2792 @note
2793 Arguments of INTERVAL function are stored in "Item_row" object. Function
2794 print_args calls print function of "Item_row" class. Item_row::print
2795 function append "(", "argument_list" and ")" to String str.
2796
2797 @param str [in/out] String to which the func_name and argument list
2798 should be appeneded.
2799 @param query_type [in] Query type
2800 */
2801
print(String * str,enum_query_type query_type)2802 void Item_func_interval::print(String *str, enum_query_type query_type)
2803 {
2804 str->append(func_name());
2805 print_args(str, 0, query_type);
2806 }
2807
2808
2809 /**
2810 Execute Item_func_interval().
2811
2812 @note
2813 If we are doing a decimal comparison, we are evaluating the first
2814 item twice.
2815
2816 @return
2817 - -1 if null value,
2818 - 0 if lower than lowest
2819 - 1 - arg_count-1 if between args[n] and args[n+1]
2820 - arg_count if higher than biggest argument
2821 */
2822
val_int()2823 longlong Item_func_interval::val_int()
2824 {
2825 DBUG_ASSERT(fixed == 1);
2826 double value;
2827 my_decimal dec_buf, *dec= NULL;
2828 uint i;
2829
2830 if (use_decimal_comparison)
2831 {
2832 dec= row->element_index(0)->val_decimal(&dec_buf);
2833 if (row->element_index(0)->null_value)
2834 return -1;
2835 my_decimal2double(E_DEC_FATAL_ERROR, dec, &value);
2836 }
2837 else
2838 {
2839 value= row->element_index(0)->val_real();
2840 if (row->element_index(0)->null_value)
2841 return -1;
2842 }
2843
2844 if (intervals)
2845 { // Use binary search to find interval
2846 uint start,end;
2847 start= 0;
2848 end= row->cols()-2;
2849 while (start != end)
2850 {
2851 uint mid= (start + end + 1) / 2;
2852 interval_range *range= intervals + mid;
2853 my_bool cmp_result;
2854 /*
2855 The values in the range intervall may have different types,
2856 Only do a decimal comparision of the first argument is a decimal
2857 and we are comparing against a decimal
2858 */
2859 if (dec && range->type == DECIMAL_RESULT)
2860 cmp_result= my_decimal_cmp(&range->dec, dec) <= 0;
2861 else
2862 cmp_result= (range->dbl <= value);
2863 if (cmp_result)
2864 start= mid;
2865 else
2866 end= mid - 1;
2867 }
2868 interval_range *range= intervals+start;
2869 return ((dec && range->type == DECIMAL_RESULT) ?
2870 my_decimal_cmp(dec, &range->dec) < 0 :
2871 value < range->dbl) ? 0 : start + 1;
2872 }
2873
2874 for (i=1 ; i < row->cols() ; i++)
2875 {
2876 Item *el= row->element_index(i);
2877 if (use_decimal_comparison &&
2878 ((el->result_type() == DECIMAL_RESULT) ||
2879 (el->result_type() == INT_RESULT)))
2880 {
2881 my_decimal e_dec_buf, *e_dec= el->val_decimal(&e_dec_buf);
2882 /* Skip NULL ranges. */
2883 if (el->null_value)
2884 continue;
2885 if (my_decimal_cmp(e_dec, dec) > 0)
2886 return i - 1;
2887 }
2888 else
2889 {
2890 double val= el->val_real();
2891 /* Skip NULL ranges. */
2892 if (el->null_value)
2893 continue;
2894 if (val > value)
2895 return i - 1;
2896 }
2897 }
2898 return i-1;
2899 }
2900
2901
2902 /**
2903 Perform context analysis of a BETWEEN item tree.
2904
2905 This function performs context analysis (name resolution) and calculates
2906 various attributes of the item tree with Item_func_between as its root.
2907 The function saves in ref the pointer to the item or to a newly created
2908 item that is considered as a replacement for the original one.
2909
2910 @param thd reference to the global context of the query thread
2911 @param ref pointer to Item* variable where pointer to resulting "fixed"
2912 item is to be assigned
2913
2914 @note
2915 Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
2916 a predicate/function level. Then it's easy to show that:
2917 @verbatim
2918 T0(e BETWEEN e1 AND e2) = union(T1(e),T1(e1),T1(e2))
2919 T1(e BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
2920 T0(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
2921 T1(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
2922 @endverbatim
2923
2924 @retval
2925 0 ok
2926 @retval
2927 1 got error
2928 */
2929
fix_fields(THD * thd,Item ** ref)2930 bool Item_func_between::fix_fields(THD *thd, Item **ref)
2931 {
2932 if (Item_func_opt_neg::fix_fields(thd, ref))
2933 return 1;
2934
2935 thd->lex->current_select()->between_count++;
2936
2937 // not_null_tables_cache == union(T1(e),T1(e1),T1(e2))
2938 if (pred_level && !negated)
2939 return 0;
2940
2941 // not_null_tables_cache == union(T1(e), intersection(T1(e1),T1(e2)))
2942 not_null_tables_cache= (args[0]->not_null_tables() |
2943 (args[1]->not_null_tables() &
2944 args[2]->not_null_tables()));
2945
2946 return 0;
2947 }
2948
2949
fix_after_pullout(st_select_lex * parent_select,st_select_lex * removed_select)2950 void Item_func_between::fix_after_pullout(st_select_lex *parent_select,
2951 st_select_lex *removed_select)
2952 {
2953 Item_func_opt_neg::fix_after_pullout(parent_select, removed_select);
2954
2955 // not_null_tables_cache == union(T1(e),T1(e1),T1(e2))
2956 if (pred_level && !negated)
2957 return;
2958
2959 // not_null_tables_cache == union(T1(e), intersection(T1(e1),T1(e2)))
2960 not_null_tables_cache= args[0]->not_null_tables() |
2961 (args[1]->not_null_tables() &
2962 args[2]->not_null_tables());
2963 }
2964
2965
fix_length_and_dec()2966 void Item_func_between::fix_length_and_dec()
2967 {
2968 max_length= 1;
2969 int i;
2970 int datetime_items_found= 0;
2971 int time_items_found= 0;
2972 compare_as_dates_with_strings= false;
2973 compare_as_temporal_times= compare_as_temporal_dates= false;
2974 THD *thd= current_thd;
2975
2976 /*
2977 As some compare functions are generated after sql_yacc,
2978 we have to check for out of memory conditions here
2979 */
2980 if (!args[0] || !args[1] || !args[2])
2981 return;
2982 if ( agg_cmp_type(&cmp_type, args, 3))
2983 return;
2984 if (cmp_type == STRING_RESULT &&
2985 agg_arg_charsets_for_comparison(cmp_collation, args, 3))
2986 return;
2987
2988 /*
2989 See comments for the code block doing similar checks in
2990 Item_bool_func2::fix_length_and_dec().
2991 */
2992 reject_geometry_args(arg_count, args, this);
2993
2994 /*
2995 JSON values will be compared as strings, and not with the JSON
2996 comparator as one might expect. Raise a warning if one of the
2997 arguments is JSON.
2998 */
2999 unsupported_json_comparison(arg_count, args,
3000 "comparison of JSON in the BETWEEN operator");
3001
3002 /*
3003 Detect the comparison of DATE/DATETIME items.
3004 At least one of items should be a DATE/DATETIME item and other items
3005 should return the STRING result.
3006 */
3007 if (cmp_type == STRING_RESULT)
3008 {
3009 for (i= 0; i < 3; i++)
3010 {
3011 if (args[i]->is_temporal_with_date())
3012 datetime_items_found++;
3013 else
3014 if (args[i]->field_type() == MYSQL_TYPE_TIME)
3015 time_items_found++;
3016 }
3017 }
3018
3019 if (datetime_items_found + time_items_found == 3)
3020 {
3021 if (time_items_found == 3)
3022 {
3023 // All items are TIME
3024 cmp_type= INT_RESULT;
3025 compare_as_temporal_times= true;
3026 }
3027 else
3028 {
3029 /*
3030 There is at least one DATE or DATETIME item,
3031 all other items are DATE, DATETIME or TIME.
3032 */
3033 cmp_type= INT_RESULT;
3034 compare_as_temporal_dates= true;
3035 }
3036 }
3037 else if (datetime_items_found > 0)
3038 {
3039 /*
3040 There is at least one DATE or DATETIME item.
3041 All other items are DATE, DATETIME or strings.
3042 */
3043 compare_as_dates_with_strings= true;
3044 ge_cmp.set_datetime_cmp_func(this, args, args + 1);
3045 le_cmp.set_datetime_cmp_func(this, args, args + 2);
3046 }
3047 else if (args[0]->real_item()->type() == FIELD_ITEM &&
3048 thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
3049 thd->lex->sql_command != SQLCOM_SHOW_CREATE)
3050 {
3051 Item_field *field_item= (Item_field*) (args[0]->real_item());
3052 if (field_item->field->can_be_compared_as_longlong())
3053 {
3054 /*
3055 The following can't be recoded with || as convert_constant_item
3056 changes the argument
3057 */
3058 const bool cvt_arg1= convert_constant_item(thd, field_item, &args[1]);
3059 const bool cvt_arg2= convert_constant_item(thd, field_item, &args[2]);
3060 if (args[0]->is_temporal())
3061 { // special handling of date/time etc.
3062 if (cvt_arg1 || cvt_arg2)
3063 cmp_type=INT_RESULT;
3064 }
3065 else
3066 {
3067 if (cvt_arg1 && cvt_arg2)
3068 cmp_type=INT_RESULT;
3069 }
3070
3071 if (args[0]->is_temporal() &&
3072 args[1]->is_temporal() &&
3073 args[2]->is_temporal())
3074 {
3075 /*
3076 An expression:
3077 time_or_datetime_field
3078 BETWEEN const_number_or_time_or_datetime_expr1
3079 AND const_number_or_time_or_datetime_expr2
3080 was rewritten to:
3081 time_field
3082 BETWEEN Item_time_with_ref1
3083 AND Item_time_with_ref2
3084 or
3085 datetime_field
3086 BETWEEN Item_datetime_with_ref1
3087 AND Item_datetime_with_ref2
3088 */
3089 if (field_item->field_type() == MYSQL_TYPE_TIME)
3090 compare_as_temporal_times= true;
3091 else if (field_item->is_temporal_with_date())
3092 compare_as_temporal_dates= true;
3093 }
3094 }
3095 }
3096 }
3097
3098 float
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)3099 Item_func_between::get_filtering_effect(table_map filter_for_table,
3100 table_map read_tables,
3101 const MY_BITMAP *fields_to_ignore,
3102 double rows_in_table)
3103 {
3104 const Item_field* fld=
3105 contributes_to_filter(read_tables, filter_for_table, fields_to_ignore);
3106 if (!fld)
3107 return COND_FILTER_ALLPASS;
3108
3109 const float filter=
3110 fld->get_cond_filter_default_probability(rows_in_table,
3111 COND_FILTER_BETWEEN);
3112
3113 return negated ? 1.0f - filter : filter;
3114 }
3115
3116 /**
3117 A helper function for Item_func_between::val_int() to avoid
3118 over/underflow when comparing large values.
3119
3120 @tparam LLorULL ulonglong or longlong
3121
3122 @param compare_as_temporal_dates copy of Item_func_between member variable
3123 @param compare_as_temporal_times copy of Item_func_between member variable
3124 @param negated copy of Item_func_between member variable
3125 @param args copy of Item_func_between member variable
3126 @param null_value [out] set to true if result is not true/false
3127
3128 @retval true if: args[1] <= args[0] <= args[2]
3129 */
3130 template<typename LLorULL>
compare_between_int_result(bool compare_as_temporal_dates,bool compare_as_temporal_times,bool negated,Item ** args,my_bool * null_value)3131 longlong compare_between_int_result(bool compare_as_temporal_dates,
3132 bool compare_as_temporal_times,
3133 bool negated,
3134 Item **args,
3135 my_bool *null_value)
3136 {
3137 {
3138 LLorULL a, b, value;
3139 value= compare_as_temporal_times ? args[0]->val_time_temporal() :
3140 compare_as_temporal_dates ? args[0]->val_date_temporal() :
3141 args[0]->val_int();
3142 if ((*null_value= args[0]->null_value))
3143 return 0; /* purecov: inspected */
3144 if (compare_as_temporal_times)
3145 {
3146 a= args[1]->val_time_temporal();
3147 b= args[2]->val_time_temporal();
3148 }
3149 else if (compare_as_temporal_dates)
3150 {
3151 a= args[1]->val_date_temporal();
3152 b= args[2]->val_date_temporal();
3153 }
3154 else
3155 {
3156 a= args[1]->val_int();
3157 b= args[2]->val_int();
3158 }
3159
3160 if (args[0]->unsigned_flag)
3161 {
3162 /*
3163 Comparing as unsigned.
3164 value BETWEEN <some negative number> AND <some number>
3165 rewritten to
3166 value BETWEEN 0 AND <some number>
3167 */
3168 if (!args[1]->unsigned_flag && static_cast<longlong>(a) < 0)
3169 a = 0;
3170 /*
3171 Comparing as unsigned.
3172 value BETWEEN <some number> AND <some negative number>
3173 rewritten to
3174 1 BETWEEN <some number> AND 0
3175 */
3176 if (!args[2]->unsigned_flag && static_cast<longlong>(b) < 0)
3177 {
3178 b= 0;
3179 value= 1;
3180 }
3181 }
3182 else
3183 {
3184 // Comparing as signed, but b is unsigned, and really large
3185 if (args[2]->unsigned_flag && (longlong) b < 0)
3186 b= LLONG_MAX;
3187 }
3188
3189 if (!args[1]->null_value && !args[2]->null_value)
3190 return (longlong) ((value >= a && value <= b) != negated);
3191 if (args[1]->null_value && args[2]->null_value)
3192 *null_value= 1;
3193 else if (args[1]->null_value)
3194 {
3195 *null_value= value <= b; // not null if false range.
3196 }
3197 else
3198 {
3199 *null_value= value >= a;
3200 }
3201 return value;
3202 }
3203 }
3204
3205
val_int()3206 longlong Item_func_between::val_int()
3207 { // ANSI BETWEEN
3208 DBUG_ASSERT(fixed == 1);
3209 if (compare_as_dates_with_strings)
3210 {
3211 int ge_res, le_res;
3212
3213 ge_res= ge_cmp.compare();
3214 if ((null_value= args[0]->null_value))
3215 return 0;
3216 le_res= le_cmp.compare();
3217
3218 if (!args[1]->null_value && !args[2]->null_value)
3219 return (longlong) ((ge_res >= 0 && le_res <=0) != negated);
3220 else if (args[1]->null_value)
3221 {
3222 null_value= le_res > 0; // not null if false range.
3223 }
3224 else
3225 {
3226 null_value= ge_res < 0;
3227 }
3228 }
3229 else if (cmp_type == STRING_RESULT)
3230 {
3231 String *value,*a,*b;
3232 value=args[0]->val_str(&value0);
3233 if ((null_value=args[0]->null_value))
3234 return 0;
3235 a=args[1]->val_str(&value1);
3236 b=args[2]->val_str(&value2);
3237 if (!args[1]->null_value && !args[2]->null_value)
3238 return (longlong) ((sortcmp(value,a,cmp_collation.collation) >= 0 &&
3239 sortcmp(value,b,cmp_collation.collation) <= 0) !=
3240 negated);
3241 if (args[1]->null_value && args[2]->null_value)
3242 null_value=1;
3243 else if (args[1]->null_value)
3244 {
3245 // Set to not null if false range.
3246 null_value= sortcmp(value,b,cmp_collation.collation) <= 0;
3247 }
3248 else
3249 {
3250 // Set to not null if false range.
3251 null_value= sortcmp(value,a,cmp_collation.collation) >= 0;
3252 }
3253 }
3254 else if (cmp_type == INT_RESULT)
3255 {
3256 longlong value;
3257 if (args[0]->unsigned_flag)
3258 value= compare_between_int_result<ulonglong>(compare_as_temporal_dates,
3259 compare_as_temporal_times,
3260 negated,
3261 args,
3262 &null_value);
3263 else
3264 value= compare_between_int_result<longlong>(compare_as_temporal_dates,
3265 compare_as_temporal_times,
3266 negated,
3267 args,
3268 &null_value);
3269 if (args[0]->null_value)
3270 return 0; /* purecov: inspected */
3271 if (!args[1]->null_value && !args[2]->null_value)
3272 return value;
3273 }
3274 else if (cmp_type == DECIMAL_RESULT)
3275 {
3276 my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
3277 a_buf, *a_dec, b_buf, *b_dec;
3278 if ((null_value=args[0]->null_value))
3279 return 0; /* purecov: inspected */
3280 a_dec= args[1]->val_decimal(&a_buf);
3281 b_dec= args[2]->val_decimal(&b_buf);
3282 if (!args[1]->null_value && !args[2]->null_value)
3283 return (longlong) ((my_decimal_cmp(dec, a_dec) >= 0 &&
3284 my_decimal_cmp(dec, b_dec) <= 0) != negated);
3285 if (args[1]->null_value && args[2]->null_value)
3286 null_value=1;
3287 else if (args[1]->null_value)
3288 null_value= (my_decimal_cmp(dec, b_dec) <= 0);
3289 else
3290 null_value= (my_decimal_cmp(dec, a_dec) >= 0);
3291 }
3292 else
3293 {
3294 double value= args[0]->val_real(),a,b;
3295 if ((null_value=args[0]->null_value))
3296 return 0; /* purecov: inspected */
3297 a= args[1]->val_real();
3298 b= args[2]->val_real();
3299 if (!args[1]->null_value && !args[2]->null_value)
3300 return (longlong) ((value >= a && value <= b) != negated);
3301 if (args[1]->null_value && args[2]->null_value)
3302 null_value=1;
3303 else if (args[1]->null_value)
3304 {
3305 null_value= value <= b; // not null if false range.
3306 }
3307 else
3308 {
3309 null_value= value >= a;
3310 }
3311 }
3312 return (longlong) (!null_value && negated);
3313 }
3314
3315
print(String * str,enum_query_type query_type)3316 void Item_func_between::print(String *str, enum_query_type query_type)
3317 {
3318 str->append('(');
3319 args[0]->print(str, query_type);
3320 if (negated)
3321 str->append(STRING_WITH_LEN(" not"));
3322 str->append(STRING_WITH_LEN(" between "));
3323 args[1]->print(str, query_type);
3324 str->append(STRING_WITH_LEN(" and "));
3325 args[2]->print(str, query_type);
3326 str->append(')');
3327 }
3328
3329 void
fix_length_and_dec()3330 Item_func_ifnull::fix_length_and_dec()
3331 {
3332 uint32 char_length;
3333 agg_result_type(&hybrid_type, &unsigned_flag, args, 2);
3334 cached_field_type= agg_field_type(args, 2);
3335 maybe_null=args[1]->maybe_null;
3336 decimals= max(args[0]->decimals, args[1]->decimals);
3337
3338 if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
3339 {
3340 int len0= args[0]->max_char_length() - args[0]->decimals
3341 - (args[0]->unsigned_flag ? 0 : 1);
3342
3343 int len1= args[1]->max_char_length() - args[1]->decimals
3344 - (args[1]->unsigned_flag ? 0 : 1);
3345
3346 char_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
3347 }
3348 else
3349 char_length= max(args[0]->max_char_length(), args[1]->max_char_length());
3350
3351 switch (hybrid_type) {
3352 case STRING_RESULT:
3353 if (count_string_result_length(cached_field_type, args, arg_count))
3354 return;
3355 break;
3356 case DECIMAL_RESULT:
3357 case REAL_RESULT:
3358 break;
3359 case INT_RESULT:
3360 decimals= 0;
3361 break;
3362 case ROW_RESULT:
3363 default:
3364 DBUG_ASSERT(0);
3365 }
3366 fix_char_length(char_length);
3367 }
3368
3369
decimal_precision() const3370 uint Item_func_ifnull::decimal_precision() const
3371 {
3372 int arg0_int_part= args[0]->decimal_int_part();
3373 int arg1_int_part= args[1]->decimal_int_part();
3374 int max_int_part= max(arg0_int_part, arg1_int_part);
3375 int precision= max_int_part + decimals;
3376 return min<uint>(precision, DECIMAL_MAX_PRECISION);
3377 }
3378
3379
tmp_table_field(TABLE * table)3380 Field *Item_func_ifnull::tmp_table_field(TABLE *table)
3381 {
3382 return tmp_table_field_from_field_type(table, 0);
3383 }
3384
3385 double
real_op()3386 Item_func_ifnull::real_op()
3387 {
3388 DBUG_ASSERT(fixed == 1);
3389 double value= args[0]->val_real();
3390 if (!args[0]->null_value)
3391 {
3392 null_value=0;
3393 return value;
3394 }
3395 value= args[1]->val_real();
3396 if ((null_value=args[1]->null_value))
3397 return 0.0;
3398 return value;
3399 }
3400
3401 longlong
int_op()3402 Item_func_ifnull::int_op()
3403 {
3404 DBUG_ASSERT(fixed == 1);
3405 longlong value=args[0]->val_int();
3406 if (!args[0]->null_value)
3407 {
3408 null_value=0;
3409 return value;
3410 }
3411 value=args[1]->val_int();
3412 if ((null_value=args[1]->null_value))
3413 return 0;
3414 return value;
3415 }
3416
3417
decimal_op(my_decimal * decimal_value)3418 my_decimal *Item_func_ifnull::decimal_op(my_decimal *decimal_value)
3419 {
3420 DBUG_ASSERT(fixed == 1);
3421 my_decimal *value= args[0]->val_decimal(decimal_value);
3422 if (!args[0]->null_value)
3423 {
3424 null_value= 0;
3425 return value;
3426 }
3427 value= args[1]->val_decimal(decimal_value);
3428 if ((null_value= args[1]->null_value))
3429 return 0;
3430 return value;
3431 }
3432
3433
val_json(Json_wrapper * result)3434 bool Item_func_ifnull::val_json(Json_wrapper *result)
3435 {
3436 null_value= 0;
3437 if (json_value(args, 0, result))
3438 return error_json();
3439
3440 if (!args[0]->null_value)
3441 return false;
3442
3443 if (json_value(args, 1, result))
3444 return error_json();
3445
3446 null_value= args[1]->null_value;
3447 return false;
3448 }
3449
3450
date_op(MYSQL_TIME * ltime,my_time_flags_t fuzzydate)3451 bool Item_func_ifnull::date_op(MYSQL_TIME *ltime, my_time_flags_t fuzzydate)
3452 {
3453 DBUG_ASSERT(fixed == 1);
3454 if (!args[0]->get_date(ltime, fuzzydate))
3455 return (null_value= false);
3456 return (null_value= args[1]->get_date(ltime, fuzzydate));
3457 }
3458
3459
time_op(MYSQL_TIME * ltime)3460 bool Item_func_ifnull::time_op(MYSQL_TIME *ltime)
3461 {
3462 DBUG_ASSERT(fixed == 1);
3463 if (!args[0]->get_time(ltime))
3464 return (null_value= false);
3465 return (null_value= args[1]->get_time(ltime));
3466 }
3467
3468
3469 String *
str_op(String * str)3470 Item_func_ifnull::str_op(String *str)
3471 {
3472 DBUG_ASSERT(fixed == 1);
3473 String *res =args[0]->val_str(str);
3474 if (!args[0]->null_value)
3475 {
3476 null_value=0;
3477 res->set_charset(collation.collation);
3478 return res;
3479 }
3480 res=args[1]->val_str(str);
3481 if ((null_value=args[1]->null_value))
3482 return 0;
3483 res->set_charset(collation.collation);
3484 return res;
3485 }
3486
3487
3488 /**
3489 Perform context analysis of an IF item tree.
3490
3491 This function performs context analysis (name resolution) and calculates
3492 various attributes of the item tree with Item_func_if as its root.
3493 The function saves in ref the pointer to the item or to a newly created
3494 item that is considered as a replacement for the original one.
3495
3496 @param thd reference to the global context of the query thread
3497 @param ref pointer to Item* variable where pointer to resulting "fixed"
3498 item is to be assigned
3499
3500 @note
3501 Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
3502 a predicate/function level. Then it's easy to show that:
3503 @verbatim
3504 T0(IF(e,e1,e2) = T1(IF(e,e1,e2))
3505 T1(IF(e,e1,e2)) = intersection(T1(e1),T1(e2))
3506 @endverbatim
3507
3508 @retval
3509 0 ok
3510 @retval
3511 1 got error
3512 */
3513
3514 bool
fix_fields(THD * thd,Item ** ref)3515 Item_func_if::fix_fields(THD *thd, Item **ref)
3516 {
3517 DBUG_ASSERT(fixed == 0);
3518 args[0]->top_level_item();
3519
3520 if (Item_func::fix_fields(thd, ref))
3521 return 1;
3522
3523 not_null_tables_cache= (args[1]->not_null_tables() &
3524 args[2]->not_null_tables());
3525
3526 return 0;
3527 }
3528
3529
fix_after_pullout(st_select_lex * parent_select,st_select_lex * removed_select)3530 void Item_func_if::fix_after_pullout(st_select_lex *parent_select,
3531 st_select_lex *removed_select)
3532 {
3533 Item_func::fix_after_pullout(parent_select, removed_select);
3534
3535 not_null_tables_cache= (args[1]->not_null_tables() &
3536 args[2]->not_null_tables());
3537 }
3538
3539
cache_type_info(Item * source)3540 void Item_func_if::cache_type_info(Item *source)
3541 {
3542 collation.set(source->collation);
3543 cached_field_type= source->field_type();
3544 cached_result_type= source->result_type();
3545 decimals= source->decimals;
3546 max_length= source->max_length;
3547 maybe_null= source->maybe_null;
3548 unsigned_flag= source->unsigned_flag;
3549 }
3550
3551
3552 void
fix_length_and_dec()3553 Item_func_if::fix_length_and_dec()
3554 {
3555 // Let IF(cond, expr, NULL) and IF(cond, NULL, expr) inherit type from expr.
3556 if (args[1]->type() == NULL_ITEM)
3557 {
3558 cache_type_info(args[2]);
3559 maybe_null= true;
3560 // If both arguments are NULL, make resulting type BINARY(0).
3561 if (args[2]->type() == NULL_ITEM)
3562 cached_field_type= MYSQL_TYPE_STRING;
3563 return;
3564 }
3565 if (args[2]->type() == NULL_ITEM)
3566 {
3567 cache_type_info(args[1]);
3568 maybe_null= true;
3569 return;
3570 }
3571
3572 agg_result_type(&cached_result_type, &unsigned_flag, args + 1, 2);
3573 cached_field_type= agg_field_type(args + 1, 2);
3574 maybe_null= args[1]->maybe_null || args[2]->maybe_null;
3575 decimals= max(args[1]->decimals, args[2]->decimals);
3576
3577 if (cached_result_type == STRING_RESULT)
3578 {
3579 if (count_string_result_length(cached_field_type, args + 1, 2))
3580 return;
3581 }
3582 else
3583 {
3584 collation.set_numeric(); // Number
3585 }
3586
3587 uint32 char_length;
3588 if ((cached_result_type == DECIMAL_RESULT )
3589 || (cached_result_type == INT_RESULT))
3590 {
3591 int len1= args[1]->max_length - args[1]->decimals
3592 - (args[1]->unsigned_flag ? 0 : 1);
3593
3594 int len2= args[2]->max_length - args[2]->decimals
3595 - (args[2]->unsigned_flag ? 0 : 1);
3596
3597 char_length= max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
3598 }
3599 else
3600 char_length= max(args[1]->max_char_length(), args[2]->max_char_length());
3601 fix_char_length(char_length);
3602 }
3603
3604
decimal_precision() const3605 uint Item_func_if::decimal_precision() const
3606 {
3607 int arg1_prec= args[1]->decimal_int_part();
3608 int arg2_prec= args[2]->decimal_int_part();
3609 int precision=max(arg1_prec,arg2_prec) + decimals;
3610 return min<uint>(precision, DECIMAL_MAX_PRECISION);
3611 }
3612
3613
3614 double
val_real()3615 Item_func_if::val_real()
3616 {
3617 DBUG_ASSERT(fixed == 1);
3618 Item *arg= args[0]->val_bool() ? args[1] : args[2];
3619 double value= arg->val_real();
3620 null_value=arg->null_value;
3621 return value;
3622 }
3623
3624 longlong
val_int()3625 Item_func_if::val_int()
3626 {
3627 DBUG_ASSERT(fixed == 1);
3628 Item *arg= args[0]->val_bool() ? args[1] : args[2];
3629 longlong value=arg->val_int();
3630 null_value=arg->null_value;
3631 return value;
3632 }
3633
3634 String *
val_str(String * str)3635 Item_func_if::val_str(String *str)
3636 {
3637 DBUG_ASSERT(fixed == 1);
3638
3639 switch (field_type())
3640 {
3641 case MYSQL_TYPE_DATETIME:
3642 case MYSQL_TYPE_TIMESTAMP:
3643 return val_string_from_datetime(str);
3644 case MYSQL_TYPE_DATE:
3645 return val_string_from_date(str);
3646 case MYSQL_TYPE_TIME:
3647 return val_string_from_time(str);
3648 default:
3649 {
3650 Item *item= args[0]->val_bool() ? args[1] : args[2];
3651 String *res;
3652 if ((res= item->val_str(str)))
3653 {
3654 res->set_charset(collation.collation);
3655 null_value= 0;
3656 return res;
3657 }
3658 }
3659 }
3660 null_value= true;
3661 return (String *) 0;
3662 }
3663
3664
3665 my_decimal *
val_decimal(my_decimal * decimal_value)3666 Item_func_if::val_decimal(my_decimal *decimal_value)
3667 {
3668 DBUG_ASSERT(fixed == 1);
3669 Item *arg= args[0]->val_bool() ? args[1] : args[2];
3670 my_decimal *value= arg->val_decimal(decimal_value);
3671 null_value= arg->null_value;
3672 return value;
3673 }
3674
3675
val_json(Json_wrapper * wr)3676 bool Item_func_if::val_json(Json_wrapper *wr)
3677 {
3678 DBUG_ASSERT(fixed == 1);
3679 Item *arg= args[0]->val_bool() ? args[1] : args[2];
3680 Item *args[]= {arg};
3681 bool ok= json_value(args, 0, wr);
3682 null_value= arg->null_value;
3683 return ok;
3684 }
3685
3686
get_date(MYSQL_TIME * ltime,my_time_flags_t fuzzydate)3687 bool Item_func_if::get_date(MYSQL_TIME *ltime, my_time_flags_t fuzzydate)
3688 {
3689 DBUG_ASSERT(fixed == 1);
3690 Item *arg= args[0]->val_bool() ? args[1] : args[2];
3691 return (null_value= arg->get_date(ltime, fuzzydate));
3692 }
3693
3694
get_time(MYSQL_TIME * ltime)3695 bool Item_func_if::get_time(MYSQL_TIME *ltime)
3696 {
3697 DBUG_ASSERT(fixed == 1);
3698 Item *arg= args[0]->val_bool() ? args[1] : args[2];
3699 return (null_value= arg->get_time(ltime));
3700 }
3701
3702
3703 void
fix_length_and_dec()3704 Item_func_nullif::fix_length_and_dec()
3705 {
3706 Item_bool_func2::fix_length_and_dec();
3707 maybe_null=1;
3708 if (args[0]) // Only false if EOM
3709 {
3710 max_length=args[0]->max_length;
3711 decimals=args[0]->decimals;
3712 unsigned_flag= args[0]->unsigned_flag;
3713 cached_result_type= args[0]->result_type();
3714 if (cached_result_type == STRING_RESULT &&
3715 agg_arg_charsets_for_comparison(collation, args, arg_count))
3716 return;
3717 }
3718 }
3719
3720
3721 /**
3722 @note
3723 Note that we have to evaluate the first argument twice as the compare
3724 may have been done with a different type than return value
3725 @return
3726 NULL if arguments are equal
3727 @return
3728 the first argument if not equal
3729 */
3730
3731 double
val_real()3732 Item_func_nullif::val_real()
3733 {
3734 DBUG_ASSERT(fixed == 1);
3735 double value;
3736 if (!cmp.compare())
3737 {
3738 null_value=1;
3739 return 0.0;
3740 }
3741 value= args[0]->val_real();
3742 null_value=args[0]->null_value;
3743 return value;
3744 }
3745
3746 longlong
val_int()3747 Item_func_nullif::val_int()
3748 {
3749 DBUG_ASSERT(fixed == 1);
3750 longlong value;
3751 if (!cmp.compare())
3752 {
3753 null_value=1;
3754 return 0;
3755 }
3756 value=args[0]->val_int();
3757 null_value=args[0]->null_value;
3758 return value;
3759 }
3760
3761 String *
val_str(String * str)3762 Item_func_nullif::val_str(String *str)
3763 {
3764 DBUG_ASSERT(fixed == 1);
3765 String *res;
3766 if (!cmp.compare())
3767 {
3768 null_value=1;
3769 return 0;
3770 }
3771 res=args[0]->val_str(str);
3772 null_value=args[0]->null_value;
3773 return res;
3774 }
3775
3776
3777 my_decimal *
val_decimal(my_decimal * decimal_value)3778 Item_func_nullif::val_decimal(my_decimal * decimal_value)
3779 {
3780 DBUG_ASSERT(fixed == 1);
3781 my_decimal *res;
3782 if (!cmp.compare())
3783 {
3784 null_value=1;
3785 return 0;
3786 }
3787 res= args[0]->val_decimal(decimal_value);
3788 null_value= args[0]->null_value;
3789 return res;
3790 }
3791
3792
3793 bool
is_null()3794 Item_func_nullif::is_null()
3795 {
3796 return (null_value= (!cmp.compare() ? 1 : args[0]->null_value));
3797 }
3798
3799
3800 /**
3801 Find and return matching items for CASE or ELSE item if all compares
3802 are failed or NULL if ELSE item isn't defined.
3803
3804 IMPLEMENTATION
3805 In order to do correct comparisons of the CASE expression (the expression
3806 between CASE and the first WHEN) with each WHEN expression several
3807 comparators are used. One for each result type. CASE expression can be
3808 evaluated up to # of different result types are used. To check whether
3809 the CASE expression already was evaluated for a particular result type
3810 a bit mapped variable value_added_map is used. Result types are mapped
3811 to it according to their int values i.e. STRING_RESULT is mapped to bit
3812 0, REAL_RESULT to bit 1, so on.
3813
3814 @retval
3815 NULL Nothing found and there is no ELSE expression defined
3816 @retval
3817 item Found item or ELSE item if defined and all comparisons are
3818 failed
3819 */
3820
find_item(String * str)3821 Item *Item_func_case::find_item(String *str)
3822 {
3823 uint value_added_map= 0;
3824
3825 if (first_expr_num == -1)
3826 {
3827 for (uint i=0 ; i < ncases ; i+=2)
3828 {
3829 // No expression between CASE and the first WHEN
3830 if (args[i]->val_bool())
3831 return args[i+1];
3832 continue;
3833 }
3834 }
3835 else
3836 {
3837 /* Compare every WHEN argument with it and return the first match */
3838 for (uint i=0 ; i < ncases ; i+=2)
3839 {
3840 if (args[i]->real_item()->type() == NULL_ITEM)
3841 continue;
3842 cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
3843 DBUG_ASSERT(cmp_type != ROW_RESULT);
3844 DBUG_ASSERT(cmp_items[(uint)cmp_type]);
3845 if (!(value_added_map & (1U << (uint)cmp_type)))
3846 {
3847 cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
3848 if ((null_value=args[first_expr_num]->null_value))
3849 return else_expr_num != -1 ? args[else_expr_num] : 0;
3850 value_added_map|= 1U << (uint)cmp_type;
3851 }
3852 if (cmp_items[(uint)cmp_type]->cmp(args[i]) == FALSE)
3853 return args[i + 1];
3854 }
3855 }
3856 // No, WHEN clauses all missed, return ELSE expression
3857 return else_expr_num != -1 ? args[else_expr_num] : 0;
3858 }
3859
3860
val_str(String * str)3861 String *Item_func_case::val_str(String *str)
3862 {
3863 DBUG_ASSERT(fixed == 1);
3864 switch (field_type()) {
3865 case MYSQL_TYPE_DATETIME:
3866 case MYSQL_TYPE_TIMESTAMP:
3867 return val_string_from_datetime(str);
3868 case MYSQL_TYPE_DATE:
3869 return val_string_from_date(str);
3870 case MYSQL_TYPE_TIME:
3871 return val_string_from_time(str);
3872 default:
3873 {
3874 Item *item= find_item(str);
3875 if (item)
3876 {
3877 String *res;
3878 if ((res= item->val_str(str)))
3879 {
3880 res->set_charset(collation.collation);
3881 null_value= 0;
3882 return res;
3883 }
3884 }
3885 }
3886 }
3887 null_value= true;
3888 return (String *) 0;
3889 }
3890
3891
val_int()3892 longlong Item_func_case::val_int()
3893 {
3894 DBUG_ASSERT(fixed == 1);
3895 char buff[MAX_FIELD_WIDTH];
3896 String dummy_str(buff,sizeof(buff),default_charset());
3897 Item *item=find_item(&dummy_str);
3898 longlong res;
3899
3900 if (!item)
3901 {
3902 null_value=1;
3903 return 0;
3904 }
3905 res=item->val_int();
3906 null_value=item->null_value;
3907 return res;
3908 }
3909
val_real()3910 double Item_func_case::val_real()
3911 {
3912 DBUG_ASSERT(fixed == 1);
3913 char buff[MAX_FIELD_WIDTH];
3914 String dummy_str(buff,sizeof(buff),default_charset());
3915 Item *item=find_item(&dummy_str);
3916 double res;
3917
3918 if (!item)
3919 {
3920 null_value=1;
3921 return 0;
3922 }
3923 res= item->val_real();
3924 null_value=item->null_value;
3925 return res;
3926 }
3927
3928
val_decimal(my_decimal * decimal_value)3929 my_decimal *Item_func_case::val_decimal(my_decimal *decimal_value)
3930 {
3931 DBUG_ASSERT(fixed == 1);
3932 char buff[MAX_FIELD_WIDTH];
3933 String dummy_str(buff, sizeof(buff), default_charset());
3934 Item *item= find_item(&dummy_str);
3935 my_decimal *res;
3936
3937 if (!item)
3938 {
3939 null_value=1;
3940 return 0;
3941 }
3942
3943 res= item->val_decimal(decimal_value);
3944 null_value= item->null_value;
3945 return res;
3946 }
3947
3948
val_json(Json_wrapper * wr)3949 bool Item_func_case::val_json(Json_wrapper *wr)
3950 {
3951 DBUG_ASSERT(fixed == 1);
3952 char buff[MAX_FIELD_WIDTH];
3953 String dummy_str(buff, sizeof(buff), default_charset());
3954 Item *item= find_item(&dummy_str);
3955
3956 if (!item)
3957 {
3958 null_value= true;
3959 return false;
3960 }
3961
3962 Item *args[]= {item};
3963 return json_value(args, 0, wr);
3964 }
3965
3966
get_date(MYSQL_TIME * ltime,my_time_flags_t fuzzydate)3967 bool Item_func_case::get_date(MYSQL_TIME *ltime, my_time_flags_t fuzzydate)
3968 {
3969 DBUG_ASSERT(fixed == 1);
3970 char buff[MAX_FIELD_WIDTH];
3971 String dummy_str(buff, sizeof(buff), default_charset());
3972 Item *item= find_item(&dummy_str);
3973 if (!item)
3974 return (null_value= true);
3975 return (null_value= item->get_date(ltime, fuzzydate));
3976 }
3977
3978
get_time(MYSQL_TIME * ltime)3979 bool Item_func_case::get_time(MYSQL_TIME *ltime)
3980 {
3981 DBUG_ASSERT(fixed == 1);
3982 char buff[MAX_FIELD_WIDTH];
3983 String dummy_str(buff, sizeof(buff), default_charset());
3984 Item *item= find_item(&dummy_str);
3985 if (!item)
3986 return (null_value= true);
3987 return (null_value= item->get_time(ltime));
3988 }
3989
3990
fix_fields(THD * thd,Item ** ref)3991 bool Item_func_case::fix_fields(THD *thd, Item **ref)
3992 {
3993 /*
3994 buff should match stack usage from
3995 Item_func_case::val_int() -> Item_func_case::find_item()
3996 */
3997 uchar buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(longlong)*2];
3998 bool res= Item_func::fix_fields(thd, ref);
3999 /*
4000 Call check_stack_overrun after fix_fields to be sure that stack variable
4001 is not optimized away
4002 */
4003 if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
4004 return TRUE; // Fatal error flag is set!
4005 return res;
4006 }
4007
4008 /**
4009 Check if (*place) and new_value points to different Items and call
4010 THD::change_item_tree() if needed.
4011
4012 This function is a workaround for implementation deficiency in
4013 Item_func_case. The problem there is that the 'args' attribute contains
4014 Items from different expressions.
4015
4016 The function must not be used elsewhere and will be remove eventually.
4017 */
4018
change_item_tree_if_needed(THD * thd,Item ** place,Item * new_value)4019 static void change_item_tree_if_needed(THD *thd,
4020 Item **place,
4021 Item *new_value)
4022 {
4023 if (*place == new_value)
4024 return;
4025
4026 thd->change_item_tree(place, new_value);
4027 }
4028
4029 /**
4030 This function is a shared part to fix_length_and_dec() for numeric result
4031 type of CASE and COALESCE.
4032 COALESCE is a CASE abbreviation according to the standard.
4033 */
fix_num_length_and_dec_shared_for_case(Item_func * item_func,Item_result result_type,Item ** item,uint nitems)4034 static void fix_num_length_and_dec_shared_for_case(Item_func *item_func,
4035 Item_result result_type,
4036 Item **item,
4037 uint nitems)
4038 {
4039 switch (result_type)
4040 {
4041 case DECIMAL_RESULT:
4042 item_func->count_decimal_length(item, nitems);
4043 break;
4044 case REAL_RESULT:
4045 item_func->count_real_length(item, nitems);
4046 break;
4047 case INT_RESULT:
4048 item_func->count_only_length(item, nitems);
4049 item_func->decimals= 0;
4050 break;
4051 case ROW_RESULT:
4052 default:
4053 DBUG_ASSERT(0);
4054 }
4055 }
4056
fix_length_and_dec()4057 void Item_func_case::fix_length_and_dec()
4058 {
4059 Item **agg;
4060 uint nagg;
4061 uint found_types= 0;
4062 THD *thd= current_thd;
4063
4064 if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
4065 return;
4066
4067 // Determine nullability based on THEN and ELSE expressions:
4068
4069 maybe_null= else_expr_num == -1 || args[else_expr_num]->maybe_null;
4070
4071 for (Item **arg= args + 1; arg < args + arg_count; arg+= 2)
4072 maybe_null|= (*arg)->maybe_null;
4073
4074 /*
4075 Aggregate all THEN and ELSE expression types
4076 and collations when string result
4077 */
4078
4079 for (nagg= 0; nagg < ncases / 2; nagg++)
4080 agg[nagg]= args[nagg * 2 + 1];
4081
4082 if (else_expr_num != -1)
4083 agg[nagg++]= args[else_expr_num];
4084
4085 cached_field_type= agg_field_type(agg, nagg);
4086 agg_result_type(&cached_result_type, &unsigned_flag, agg, nagg);
4087 if (cached_result_type == STRING_RESULT)
4088 {
4089 /* Note: String result type is the same for CASE and COALESCE. */
4090 if (count_string_result_length(cached_field_type, agg, nagg))
4091 return;
4092 /*
4093 Copy all THEN and ELSE items back to args[] array.
4094 Some of the items might have been changed to Item_func_conv_charset.
4095 */
4096 for (nagg= 0 ; nagg < ncases / 2 ; nagg++)
4097 change_item_tree_if_needed(thd, &args[nagg * 2 + 1], agg[nagg]);
4098
4099 if (else_expr_num != -1)
4100 change_item_tree_if_needed(thd, &args[else_expr_num], agg[nagg++]);
4101 }
4102 else
4103 {
4104 collation.set_numeric();
4105 fix_num_length_and_dec_shared_for_case(this, cached_result_type, agg,
4106 nagg);
4107 }
4108
4109
4110 /*
4111 Aggregate first expression and all WHEN expression types
4112 and collations when string comparison
4113 */
4114 if (first_expr_num != -1)
4115 {
4116 uint i;
4117 agg[0]= args[first_expr_num];
4118 left_result_type= agg[0]->result_type();
4119
4120 /*
4121 As the first expression and WHEN expressions
4122 are intermixed in args[] array THEN and ELSE items,
4123 extract the first expression and all WHEN expressions into
4124 a temporary array, to process them easier.
4125 */
4126 for (nagg= 0; nagg < ncases/2 ; nagg++)
4127 agg[nagg+1]= args[nagg*2];
4128 nagg++;
4129 if (!(found_types= collect_cmp_types(agg, nagg)))
4130 return;
4131 if (found_types & (1U << STRING_RESULT))
4132 {
4133 /*
4134 If we'll do string comparison, we also need to aggregate
4135 character set and collation for first/WHEN items and
4136 install converters for some of them to cmp_collation when necessary.
4137 This is done because cmp_item compatators cannot compare
4138 strings in two different character sets.
4139 Some examples when we install converters:
4140
4141 1. Converter installed for the first expression:
4142
4143 CASE latin1_item WHEN utf16_item THEN ... END
4144
4145 is replaced to:
4146
4147 CASE CONVERT(latin1_item USING utf16) WHEN utf16_item THEN ... END
4148
4149 2. Converter installed for the left WHEN item:
4150
4151 CASE utf16_item WHEN latin1_item THEN ... END
4152
4153 is replaced to:
4154
4155 CASE utf16_item WHEN CONVERT(latin1_item USING utf16) THEN ... END
4156 */
4157 if (agg_arg_charsets_for_comparison(cmp_collation, agg, nagg))
4158 return;
4159 /*
4160 Now copy first expression and all WHEN expressions back to args[]
4161 arrray, because some of the items might have been changed to converters
4162 (e.g. Item_func_conv_charset, or Item_string for constants).
4163 */
4164 change_item_tree_if_needed(thd, &args[first_expr_num], agg[0]);
4165
4166 for (nagg= 0; nagg < ncases / 2; nagg++)
4167 change_item_tree_if_needed(thd, &args[nagg * 2], agg[nagg + 1]);
4168 }
4169 for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
4170 {
4171 if (found_types & (1U << i) && !cmp_items[i])
4172 {
4173 DBUG_ASSERT((Item_result)i != ROW_RESULT);
4174 if (!(cmp_items[i]=
4175 cmp_item::get_comparator((Item_result)i, args[first_expr_num],
4176 cmp_collation.collation)))
4177 return;
4178 }
4179 }
4180 /*
4181 Set cmp_context of all WHEN arguments. This prevents
4182 Item_field::equal_fields_propagator() from transforming a
4183 zerofill argument into a string constant. Such a change would
4184 require rebuilding cmp_items.
4185 */
4186 for (i= 0; i < ncases; i+= 2)
4187 args[i]->cmp_context= item_cmp_type(left_result_type,
4188 args[i]->result_type());
4189 }
4190
4191 }
4192
4193
decimal_precision() const4194 uint Item_func_case::decimal_precision() const
4195 {
4196 int max_int_part=0;
4197 for (uint i=0 ; i < ncases ; i+=2)
4198 set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
4199
4200 if (else_expr_num != -1)
4201 set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
4202 return min<uint>(max_int_part + decimals, DECIMAL_MAX_PRECISION);
4203 }
4204
4205
4206 /**
4207 @todo
4208 Fix this so that it prints the whole CASE expression
4209 */
4210
print(String * str,enum_query_type query_type)4211 void Item_func_case::print(String *str, enum_query_type query_type)
4212 {
4213 str->append(STRING_WITH_LEN("(case "));
4214 if (first_expr_num != -1)
4215 {
4216 args[first_expr_num]->print(str, query_type);
4217 str->append(' ');
4218 }
4219 for (uint i=0 ; i < ncases ; i+=2)
4220 {
4221 str->append(STRING_WITH_LEN("when "));
4222 args[i]->print(str, query_type);
4223 str->append(STRING_WITH_LEN(" then "));
4224 args[i+1]->print(str, query_type);
4225 str->append(' ');
4226 }
4227 if (else_expr_num != -1)
4228 {
4229 str->append(STRING_WITH_LEN("else "));
4230 args[else_expr_num]->print(str, query_type);
4231 str->append(' ');
4232 }
4233 str->append(STRING_WITH_LEN("end)"));
4234 }
4235
4236
cleanup()4237 void Item_func_case::cleanup()
4238 {
4239 uint i;
4240 DBUG_ENTER("Item_func_case::cleanup");
4241 Item_func::cleanup();
4242 for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
4243 {
4244 delete cmp_items[i];
4245 cmp_items[i]= 0;
4246 }
4247 DBUG_VOID_RETURN;
4248 }
4249
4250
4251 /**
4252 Coalesce - return first not NULL argument.
4253 */
4254
Item_func_coalesce(const POS & pos,PT_item_list * list)4255 Item_func_coalesce::Item_func_coalesce(const POS &pos, PT_item_list *list)
4256 : Item_func_numhybrid(pos, list)
4257 {}
4258
str_op(String * str)4259 String *Item_func_coalesce::str_op(String *str)
4260 {
4261 DBUG_ASSERT(fixed == 1);
4262 null_value=0;
4263 for (uint i=0 ; i < arg_count ; i++)
4264 {
4265 String *res;
4266 if ((res=args[i]->val_str(str)))
4267 return res;
4268 }
4269 null_value=1;
4270 return 0;
4271 }
4272
4273
val_json(Json_wrapper * wr)4274 bool Item_func_coalesce::val_json(Json_wrapper *wr)
4275 {
4276 DBUG_ASSERT(fixed == 1);
4277 null_value= false;
4278 for (uint i= 0; i < arg_count; i++)
4279 {
4280 if (json_value(args, i, wr))
4281 return error_json();
4282
4283 if (!args[i]->null_value)
4284 return false;
4285 }
4286
4287 null_value= true;
4288 return false;
4289 }
4290
4291
int_op()4292 longlong Item_func_coalesce::int_op()
4293 {
4294 DBUG_ASSERT(fixed == 1);
4295 null_value=0;
4296 for (uint i=0 ; i < arg_count ; i++)
4297 {
4298 longlong res=args[i]->val_int();
4299 if (!args[i]->null_value)
4300 return res;
4301 }
4302 null_value=1;
4303 return 0;
4304 }
4305
real_op()4306 double Item_func_coalesce::real_op()
4307 {
4308 DBUG_ASSERT(fixed == 1);
4309 null_value=0;
4310 for (uint i=0 ; i < arg_count ; i++)
4311 {
4312 double res= args[i]->val_real();
4313 if (!args[i]->null_value)
4314 return res;
4315 }
4316 null_value=1;
4317 return 0;
4318 }
4319
4320
decimal_op(my_decimal * decimal_value)4321 my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
4322 {
4323 DBUG_ASSERT(fixed == 1);
4324 null_value= 0;
4325 for (uint i= 0; i < arg_count; i++)
4326 {
4327 my_decimal *res= args[i]->val_decimal(decimal_value);
4328 if (!args[i]->null_value)
4329 return res;
4330 }
4331 null_value=1;
4332 return 0;
4333 }
4334
4335
4336
date_op(MYSQL_TIME * ltime,my_time_flags_t fuzzydate)4337 bool Item_func_coalesce::date_op(MYSQL_TIME *ltime, my_time_flags_t fuzzydate)
4338 {
4339 DBUG_ASSERT(fixed == 1);
4340 for (uint i= 0; i < arg_count; i++)
4341 {
4342 if (!args[i]->get_date(ltime, fuzzydate))
4343 return (null_value= false);
4344 }
4345 return (null_value= true);
4346 }
4347
4348
time_op(MYSQL_TIME * ltime)4349 bool Item_func_coalesce::time_op(MYSQL_TIME *ltime)
4350 {
4351 DBUG_ASSERT(fixed == 1);
4352 for (uint i= 0; i < arg_count; i++)
4353 {
4354 if (!args[i]->get_time(ltime))
4355 return (null_value= false);
4356 }
4357 return (null_value= true);
4358 }
4359
4360
fix_length_and_dec()4361 void Item_func_coalesce::fix_length_and_dec()
4362 {
4363 cached_field_type= agg_field_type(args, arg_count);
4364 agg_result_type(&hybrid_type, &unsigned_flag, args, arg_count);
4365 if (hybrid_type == STRING_RESULT)
4366 count_string_result_length(cached_field_type, args, arg_count);
4367 else
4368 fix_num_length_and_dec_shared_for_case(this, hybrid_type, args,
4369 arg_count);
4370 }
4371
4372 /****************************************************************************
4373 Classes and function for the IN operator
4374 ****************************************************************************/
4375
4376 /*
4377 Determine which of the signed longlong arguments is bigger
4378
4379 SYNOPSIS
4380 cmp_longs()
4381 a_val left argument
4382 b_val right argument
4383
4384 DESCRIPTION
4385 This function will compare two signed longlong arguments
4386 and will return -1, 0, or 1 if left argument is smaller than,
4387 equal to or greater than the right argument.
4388
4389 RETURN VALUE
4390 -1 left argument is smaller than the right argument.
4391 0 left argument is equal to the right argument.
4392 1 left argument is greater than the right argument.
4393 */
cmp_longs(longlong a_val,longlong b_val)4394 static inline int cmp_longs (longlong a_val, longlong b_val)
4395 {
4396 return a_val < b_val ? -1 : a_val == b_val ? 0 : 1;
4397 }
4398
4399
4400 /*
4401 Determine which of the unsigned longlong arguments is bigger
4402
4403 SYNOPSIS
4404 cmp_ulongs()
4405 a_val left argument
4406 b_val right argument
4407
4408 DESCRIPTION
4409 This function will compare two unsigned longlong arguments
4410 and will return -1, 0, or 1 if left argument is smaller than,
4411 equal to or greater than the right argument.
4412
4413 RETURN VALUE
4414 -1 left argument is smaller than the right argument.
4415 0 left argument is equal to the right argument.
4416 1 left argument is greater than the right argument.
4417 */
cmp_ulongs(ulonglong a_val,ulonglong b_val)4418 static inline int cmp_ulongs (ulonglong a_val, ulonglong b_val)
4419 {
4420 return a_val < b_val ? -1 : a_val == b_val ? 0 : 1;
4421 }
4422
4423
4424 /*
4425 Compare two integers in IN value list format (packed_longlong)
4426
4427 SYNOPSIS
4428 cmp_longlong()
4429 a left argument
4430 b right argument
4431
4432 DESCRIPTION
4433 This function will compare two integer arguments in the IN value list
4434 format and will return -1, 0, or 1 if left argument is smaller than,
4435 equal to or greater than the right argument.
4436 It's used in sorting the IN values list and finding an element in it.
4437 Depending on the signedness of the arguments cmp_longlong() will
4438 compare them as either signed (using cmp_longs()) or unsigned (using
4439 cmp_ulongs()).
4440
4441 RETURN VALUE
4442 -1 left argument is smaller than the right argument.
4443 0 left argument is equal to the right argument.
4444 1 left argument is greater than the right argument.
4445 */
cmp_longlong(const in_longlong::packed_longlong * a,const in_longlong::packed_longlong * b)4446 int cmp_longlong(const in_longlong::packed_longlong *a,
4447 const in_longlong::packed_longlong *b)
4448 {
4449 if (a->unsigned_flag != b->unsigned_flag)
4450 {
4451 /*
4452 One of the args is unsigned and is too big to fit into the
4453 positive signed range. Report no match.
4454 */
4455 if ((a->unsigned_flag && ((ulonglong) a->val) > (ulonglong) LLONG_MAX) ||
4456 (b->unsigned_flag && ((ulonglong) b->val) > (ulonglong) LLONG_MAX))
4457 return a->unsigned_flag ? 1 : -1;
4458 /*
4459 Although the signedness differs both args can fit into the signed
4460 positive range. Make them signed and compare as usual.
4461 */
4462 return cmp_longs (a->val, b->val);
4463 }
4464 if (a->unsigned_flag)
4465 return cmp_ulongs ((ulonglong) a->val, (ulonglong) b->val);
4466 else
4467 return cmp_longs (a->val, b->val);
4468 }
4469
4470
4471 class Cmp_longlong :
4472 public std::binary_function<const in_longlong::packed_longlong &,
4473 const in_longlong::packed_longlong &, bool>
4474 {
4475 public:
operator ()(const in_longlong::packed_longlong & a,const in_longlong::packed_longlong & b)4476 bool operator()(const in_longlong::packed_longlong &a,
4477 const in_longlong::packed_longlong &b)
4478 {
4479 return cmp_longlong(&a, &b) < 0;
4480 }
4481 };
4482
4483
sort()4484 void in_longlong::sort()
4485 {
4486 std::sort(base.begin(), base.end(), Cmp_longlong());
4487 }
4488
4489
find_value(const void * value) const4490 bool in_longlong::find_value(const void *value) const
4491 {
4492 const in_longlong::packed_longlong *val=
4493 static_cast<const in_longlong::packed_longlong*>(value);
4494
4495 return std::binary_search(base.begin(), base.end(), *val, Cmp_longlong());
4496 }
4497
4498
compare_elems(uint pos1,uint pos2) const4499 bool in_longlong::compare_elems(uint pos1, uint pos2) const
4500 {
4501 return cmp_longlong(&base[pos1], &base[pos2]) != 0;
4502 }
4503
4504
4505 class Cmp_row :
4506 public std::binary_function<const cmp_item_row *, const cmp_item_row *, bool>
4507 {
4508 public:
operator ()(const cmp_item_row * a,const cmp_item_row * b)4509 bool operator()(const cmp_item_row *a, const cmp_item_row *b)
4510 {
4511 return a->compare(b) < 0;
4512 }
4513 };
4514
4515
sort()4516 void in_row::sort()
4517 {
4518 std::sort(base_pointers.begin(), base_pointers.end(), Cmp_row());
4519 }
4520
4521
find_value(const void * value) const4522 bool in_row::find_value(const void *value) const
4523 {
4524 const cmp_item_row *row= static_cast<const cmp_item_row*>(value);
4525 return std::binary_search(base_pointers.begin(), base_pointers.end(),
4526 row, Cmp_row());
4527 }
4528
4529
compare_elems(uint pos1,uint pos2) const4530 bool in_row::compare_elems(uint pos1, uint pos2) const
4531 {
4532 return base_pointers[pos1]->compare(base_pointers[pos2]) != 0;
4533 }
4534
4535
find_item(Item * item)4536 bool in_vector::find_item(Item *item)
4537 {
4538 uchar *result=get_value(item);
4539 if (!result || !used_count)
4540 return false; // Null value
4541 return find_value(result);
4542 }
4543
4544
in_string(THD * thd,uint elements,qsort2_cmp cmp_func,const CHARSET_INFO * cs)4545 in_string::in_string(THD *thd, uint elements, qsort2_cmp cmp_func,
4546 const CHARSET_INFO *cs)
4547 : in_vector(elements),
4548 tmp(buff, sizeof(buff), &my_charset_bin),
4549 base_objects(thd->mem_root, elements),
4550 base_pointers(thd->mem_root, elements),
4551 compare(cmp_func),
4552 collation(cs)
4553 {
4554 for (uint ix= 0; ix < elements; ++ix)
4555 {
4556 base_pointers[ix]= &base_objects[ix];
4557 }
4558 }
4559
~in_string()4560 in_string::~in_string()
4561 {
4562 for (uint i= 0; i < base_objects.size(); i++)
4563 {
4564 base_objects[i].mem_free();
4565 }
4566 }
4567
set(uint pos,Item * item)4568 void in_string::set(uint pos, Item *item)
4569 {
4570 String *str= base_pointers[pos];
4571 String *res= item->val_str(str);
4572 if (res && res != str)
4573 {
4574 if (res->uses_buffer_owned_by(str))
4575 res->copy();
4576 if (item->type() == Item::FUNC_ITEM)
4577 str->copy(*res);
4578 else
4579 *str= *res;
4580 }
4581 if (!str->charset())
4582 {
4583 const CHARSET_INFO *cs;
4584 if (!(cs= item->collation.collation))
4585 cs= &my_charset_bin; // Should never happen for STR items
4586 str->set_charset(cs);
4587 }
4588 }
4589
4590
get_value(Item * item)4591 uchar *in_string::get_value(Item *item)
4592 {
4593 return (uchar*) item->val_str(&tmp);
4594 }
4595
4596
4597 class Cmp_string :
4598 public std::binary_function<const String *, const String *, bool>
4599 {
4600 public:
Cmp_string(qsort2_cmp cmp_func,const CHARSET_INFO * cs)4601 Cmp_string(qsort2_cmp cmp_func, const CHARSET_INFO *cs)
4602 : compare(cmp_func), collation(cs)
4603 {}
operator ()(const String * a,const String * b)4604 bool operator()(const String *a, const String *b)
4605 {
4606 return compare(collation, a, b) < 0;
4607 }
4608 private:
4609 qsort2_cmp compare;
4610 const CHARSET_INFO *collation;
4611 };
4612
4613
4614 // Our String objects have strange copy semantics, sort pointers instead.
sort()4615 void in_string::sort()
4616 {
4617 std::sort(base_pointers.begin(), base_pointers.end(),
4618 Cmp_string(compare, collation));
4619 }
4620
4621
find_value(const void * value) const4622 bool in_string::find_value(const void *value) const
4623 {
4624 const String *str= static_cast<const String*>(value);
4625 return std::binary_search(base_pointers.begin(), base_pointers.end(),
4626 str, Cmp_string(compare, collation));
4627 }
4628
4629
compare_elems(uint pos1,uint pos2) const4630 bool in_string::compare_elems(uint pos1, uint pos2) const
4631 {
4632 return compare(collation, base_pointers[pos1], base_pointers[pos2]) != 0;
4633 }
4634
4635
in_row(THD * thd,uint elements,Item * item)4636 in_row::in_row(THD *thd, uint elements, Item * item)
4637 : in_vector(elements),
4638 base_objects(thd->mem_root, elements),
4639 base_pointers(thd->mem_root, elements)
4640 {
4641 for (uint ix= 0; ix < elements; ++ix)
4642 {
4643 base_pointers[ix]= &base_objects[ix];
4644 }
4645 }
4646
~in_row()4647 in_row::~in_row()
4648 {
4649 delete_container_pointers(base_pointers);
4650 }
4651
get_value(Item * item)4652 uchar *in_row::get_value(Item *item)
4653 {
4654 tmp.store_value(item);
4655 if (item->is_null())
4656 return 0;
4657 return (uchar *)&tmp;
4658 }
4659
set(uint pos,Item * item)4660 void in_row::set(uint pos, Item *item)
4661 {
4662 DBUG_ENTER("in_row::set");
4663 DBUG_PRINT("enter", ("pos: %u item: 0x%lx", pos, (ulong) item));
4664 base_pointers[pos]->store_value_by_template(&tmp, item);
4665 DBUG_VOID_RETURN;
4666 }
4667
in_longlong(THD * thd,uint elements)4668 in_longlong::in_longlong(THD *thd, uint elements)
4669 : in_vector(elements),
4670 base(thd->mem_root, elements)
4671 {
4672 }
4673
set(uint pos,Item * item)4674 void in_longlong::set(uint pos,Item *item)
4675 {
4676 struct packed_longlong *buff= &base[pos];
4677
4678 buff->val= item->val_int();
4679 buff->unsigned_flag= item->unsigned_flag;
4680 }
4681
get_value(Item * item)4682 uchar *in_longlong::get_value(Item *item)
4683 {
4684 tmp.val= item->val_int();
4685 if (item->null_value)
4686 return 0;
4687 tmp.unsigned_flag= item->unsigned_flag;
4688 return (uchar*) &tmp;
4689 }
4690
4691
set(uint pos,Item * item)4692 void in_time_as_longlong::set(uint pos,Item *item)
4693 {
4694 struct packed_longlong *buff= &base[pos];
4695 buff->val= item->val_time_temporal();
4696 buff->unsigned_flag= item->unsigned_flag;
4697 }
4698
4699
get_value(Item * item)4700 uchar *in_time_as_longlong::get_value(Item *item)
4701 {
4702 tmp.val= item->val_time_temporal();
4703 if (item->null_value)
4704 return 0;
4705 tmp.unsigned_flag= item->unsigned_flag;
4706 return (uchar*) &tmp;
4707 }
4708
4709
set(uint pos,Item * item)4710 void in_datetime_as_longlong::set(uint pos,Item *item)
4711 {
4712 struct packed_longlong *buff= &base[pos];
4713 buff->val= item->val_date_temporal();
4714 buff->unsigned_flag= item->unsigned_flag;
4715 }
4716
4717
get_value(Item * item)4718 uchar *in_datetime_as_longlong::get_value(Item *item)
4719 {
4720 tmp.val= item->val_date_temporal();
4721 if (item->null_value)
4722 return 0;
4723 tmp.unsigned_flag= item->unsigned_flag;
4724 return (uchar*) &tmp;
4725 }
4726
4727
set(uint pos,Item * item)4728 void in_datetime::set(uint pos,Item *item)
4729 {
4730 Item **tmp_item= &item;
4731 bool is_null;
4732 struct packed_longlong *buff= &base[pos];
4733
4734 buff->val= get_datetime_value(current_thd, &tmp_item, 0, warn_item, &is_null);
4735 buff->unsigned_flag= 1L;
4736 }
4737
4738
get_value(Item * item)4739 uchar *in_datetime::get_value(Item *item)
4740 {
4741 bool is_null;
4742 Item **tmp_item= lval_cache ? &lval_cache : &item;
4743 tmp.val= get_datetime_value(current_thd, &tmp_item, &lval_cache, warn_item, &is_null);
4744 if (item->null_value)
4745 return 0;
4746 tmp.unsigned_flag= 1L;
4747 return (uchar*) &tmp;
4748 }
4749
4750
in_double(THD * thd,uint elements)4751 in_double::in_double(THD *thd, uint elements)
4752 : in_vector(elements),
4753 base(thd->mem_root, elements)
4754 {
4755 }
4756
set(uint pos,Item * item)4757 void in_double::set(uint pos,Item *item)
4758 {
4759 base[pos]= item->val_real();
4760 }
4761
get_value(Item * item)4762 uchar *in_double::get_value(Item *item)
4763 {
4764 tmp= item->val_real();
4765 if (item->null_value)
4766 return 0; /* purecov: inspected */
4767 return (uchar*) &tmp;
4768 }
4769
4770
sort()4771 void in_double::sort()
4772 {
4773 std::sort(base.begin(), base.end());
4774 }
4775
4776
find_value(const void * value) const4777 bool in_double::find_value(const void *value) const
4778 {
4779 const double *dbl= static_cast<const double*>(value);
4780 return std::binary_search(base.begin(), base.end(), *dbl);
4781 }
4782
4783
compare_elems(uint pos1,uint pos2) const4784 bool in_double::compare_elems(uint pos1, uint pos2) const
4785 {
4786 return base[pos1] != base[pos2];
4787 }
4788
4789
in_decimal(THD * thd,uint elements)4790 in_decimal::in_decimal(THD *thd, uint elements)
4791 : in_vector(elements),
4792 base(thd->mem_root, elements)
4793 {
4794 }
4795
4796
set(uint pos,Item * item)4797 void in_decimal::set(uint pos, Item *item)
4798 {
4799 /* as far as 'item' is constant, we can store reference on my_decimal */
4800 my_decimal *dec= &base[pos];
4801 my_decimal *res= item->val_decimal(dec);
4802 /* if item->val_decimal() is evaluated to NULL then res == 0 */
4803 if (!item->null_value && res != dec)
4804 my_decimal2decimal(res, dec);
4805 }
4806
4807
get_value(Item * item)4808 uchar *in_decimal::get_value(Item *item)
4809 {
4810 my_decimal *result= item->val_decimal(&val);
4811 if (item->null_value)
4812 return 0;
4813 return (uchar *)result;
4814 }
4815
4816
sort()4817 void in_decimal::sort()
4818 {
4819 std::sort(base.begin(), base.end());
4820 }
4821
4822
find_value(const void * value) const4823 bool in_decimal::find_value(const void *value) const
4824 {
4825 const my_decimal *dec= static_cast<const my_decimal*>(value);
4826 return std::binary_search(base.begin(), base.end(), *dec);
4827 }
4828
4829
compare_elems(uint pos1,uint pos2) const4830 bool in_decimal::compare_elems(uint pos1, uint pos2) const
4831 {
4832 return base[pos1] != base[pos2];
4833 }
4834
4835
get_comparator(Item_result result_type,const Item * item,const CHARSET_INFO * cs)4836 cmp_item* cmp_item::get_comparator(Item_result result_type, const Item *item,
4837 const CHARSET_INFO *cs)
4838 {
4839 switch (result_type) {
4840 case STRING_RESULT:
4841 /*
4842 Temporal types shouldn't be compared as strings. Since date/time formats
4843 may be different, e.g. '20000102' == '2000-01-02'."
4844 */
4845 if (item->is_temporal())
4846 return new cmp_item_datetime(item);
4847 else
4848 return new cmp_item_string(cs);
4849 case INT_RESULT:
4850 return new cmp_item_int;
4851 case REAL_RESULT:
4852 return new cmp_item_real;
4853 case ROW_RESULT:
4854 return new cmp_item_row;
4855 case DECIMAL_RESULT:
4856 return new cmp_item_decimal;
4857 default:
4858 DBUG_ASSERT(0);
4859 break;
4860 }
4861 return 0; // to satisfy compiler :)
4862 }
4863
4864
make_same()4865 cmp_item* cmp_item_string::make_same()
4866 {
4867 return new cmp_item_string(cmp_charset);
4868 }
4869
make_same()4870 cmp_item* cmp_item_int::make_same()
4871 {
4872 return new cmp_item_int();
4873 }
4874
make_same()4875 cmp_item* cmp_item_real::make_same()
4876 {
4877 return new cmp_item_real();
4878 }
4879
make_same()4880 cmp_item* cmp_item_row::make_same()
4881 {
4882 return new cmp_item_row();
4883 }
4884
4885
~cmp_item_row()4886 cmp_item_row::~cmp_item_row()
4887 {
4888 DBUG_ENTER("~cmp_item_row");
4889 DBUG_PRINT("enter",("this: 0x%lx", (long) this));
4890 if (comparators)
4891 {
4892 for (uint i= 0; i < n; i++)
4893 {
4894 if (comparators[i])
4895 delete comparators[i];
4896 }
4897 }
4898 DBUG_VOID_RETURN;
4899 }
4900
4901
alloc_comparators(Item * item)4902 void cmp_item_row::alloc_comparators(Item *item)
4903 {
4904 n= item->cols();
4905 DBUG_ASSERT(comparators == NULL);
4906 if (!comparators)
4907 comparators= (cmp_item **) current_thd->mem_calloc(sizeof(cmp_item *)*n);
4908 if (comparators)
4909 {
4910 for (uint i= 0; i < n; i++)
4911 {
4912 DBUG_ASSERT(comparators[i] == NULL);
4913 Item *item_i= item->element_index(i);
4914 if (!(comparators[i]=
4915 cmp_item::get_comparator(item_i->result_type(), item_i,
4916 item_i->collation.collation)))
4917 break; // new failed
4918 if (item_i->result_type() == ROW_RESULT)
4919 static_cast<cmp_item_row*>(comparators[i])->alloc_comparators(item_i);
4920 }
4921 }
4922 }
4923
4924
store_value(Item * item)4925 void cmp_item_row::store_value(Item *item)
4926 {
4927 DBUG_ENTER("cmp_item_row::store_value");
4928 DBUG_ASSERT(comparators);
4929 if (comparators)
4930 {
4931 item->bring_value();
4932 item->null_value= 0;
4933 for (uint i= 0; i < n; i++)
4934 {
4935 comparators[i]->store_value(item->element_index(i));
4936 item->null_value|= item->element_index(i)->null_value;
4937 }
4938 }
4939 DBUG_VOID_RETURN;
4940 }
4941
4942
store_value_by_template(cmp_item * t,Item * item)4943 void cmp_item_row::store_value_by_template(cmp_item *t, Item *item)
4944 {
4945 cmp_item_row *tmpl= (cmp_item_row*) t;
4946 if (tmpl->n != item->cols())
4947 {
4948 my_error(ER_OPERAND_COLUMNS, MYF(0), tmpl->n);
4949 return;
4950 }
4951 n= tmpl->n;
4952 if ((comparators= (cmp_item **) sql_alloc(sizeof(cmp_item *)*n)))
4953 {
4954 item->bring_value();
4955 item->null_value= 0;
4956 for (uint i=0; i < n; i++)
4957 {
4958 if (!(comparators[i]= tmpl->comparators[i]->make_same()))
4959 break; // new failed
4960 comparators[i]->store_value_by_template(tmpl->comparators[i],
4961 item->element_index(i));
4962 item->null_value|= item->element_index(i)->null_value;
4963 }
4964 }
4965 }
4966
4967
cmp(Item * arg)4968 int cmp_item_row::cmp(Item *arg)
4969 {
4970 arg->null_value= 0;
4971 if (arg->cols() != n)
4972 {
4973 my_error(ER_OPERAND_COLUMNS, MYF(0), n);
4974 return 1;
4975 }
4976 bool was_null= 0;
4977 arg->bring_value();
4978 for (uint i=0; i < n; i++)
4979 {
4980 const int rc= comparators[i]->cmp(arg->element_index(i));
4981 switch (rc)
4982 {
4983 case UNKNOWN:
4984 was_null= true;
4985 break;
4986 case TRUE:
4987 return TRUE;
4988 case FALSE:
4989 break; // elements #i are equal
4990 }
4991 arg->null_value|= arg->element_index(i)->null_value;
4992 }
4993 return was_null ? UNKNOWN : FALSE;
4994 }
4995
4996
compare(const cmp_item * c) const4997 int cmp_item_row::compare(const cmp_item *c) const
4998 {
4999 const cmp_item_row *l_cmp= down_cast<const cmp_item_row*>(c);
5000 for (uint i=0; i < n; i++)
5001 {
5002 int res;
5003 if ((res= comparators[i]->compare(l_cmp->comparators[i])))
5004 return res;
5005 }
5006 return 0;
5007 }
5008
5009
store_value(Item * item)5010 void cmp_item_decimal::store_value(Item *item)
5011 {
5012 my_decimal *val= item->val_decimal(&value);
5013 /* val may be zero if item is nnull */
5014 if (val && val != &value)
5015 my_decimal2decimal(val, &value);
5016 set_null_value(item->null_value);
5017 }
5018
5019
cmp(Item * arg)5020 int cmp_item_decimal::cmp(Item *arg)
5021 {
5022 my_decimal tmp_buf, *tmp= arg->val_decimal(&tmp_buf);
5023 return (m_null_value || arg->null_value) ?
5024 UNKNOWN : (my_decimal_cmp(&value, tmp) != 0);
5025 }
5026
5027
compare(const cmp_item * arg) const5028 int cmp_item_decimal::compare(const cmp_item *arg) const
5029 {
5030 const cmp_item_decimal *l_cmp= down_cast<const cmp_item_decimal*>(arg);
5031 return my_decimal_cmp(&value, &l_cmp->value);
5032 }
5033
5034
make_same()5035 cmp_item* cmp_item_decimal::make_same()
5036 {
5037 return new cmp_item_decimal();
5038 }
5039
5040
cmp_item_datetime(const Item * warn_item_arg)5041 cmp_item_datetime::cmp_item_datetime(const Item *warn_item_arg)
5042 :warn_item(warn_item_arg), lval_cache(0),
5043 has_date(warn_item_arg->is_temporal_with_date())
5044 {}
5045
store_value(Item * item)5046 void cmp_item_datetime::store_value(Item *item)
5047 {
5048 bool is_null;
5049 Item **tmp_item= lval_cache ? &lval_cache : &item;
5050 if (has_date)
5051 value= get_datetime_value(current_thd, &tmp_item, &lval_cache, warn_item,
5052 &is_null);
5053 else
5054 value= get_time_value(current_thd, &tmp_item, &lval_cache, warn_item,
5055 &is_null);
5056 set_null_value(item->null_value);
5057 }
5058
5059
cmp(Item * arg)5060 int cmp_item_datetime::cmp(Item *arg)
5061 {
5062 bool is_null;
5063 Item **tmp_item= &arg;
5064 longlong value2= 0;
5065 if (has_date)
5066 value2= get_datetime_value(current_thd, &tmp_item, 0, warn_item, &is_null);
5067 else
5068 value2= get_time_value(current_thd, &tmp_item, 0, warn_item, &is_null);
5069
5070 const bool rc= (value != value2);
5071 return (m_null_value || arg->null_value) ? UNKNOWN : rc;
5072 }
5073
5074
compare(const cmp_item * ci) const5075 int cmp_item_datetime::compare(const cmp_item *ci) const
5076 {
5077 const cmp_item_datetime *l_cmp= down_cast<const cmp_item_datetime*>(ci);
5078 return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
5079 }
5080
5081
make_same()5082 cmp_item *cmp_item_datetime::make_same()
5083 {
5084 return new cmp_item_datetime(warn_item);
5085 }
5086
5087
5088 float
get_single_col_filtering_effect(Item_ident * fieldref,table_map filter_for_table,const MY_BITMAP * fields_to_ignore,double rows_in_table)5089 Item_func_in::get_single_col_filtering_effect(Item_ident *fieldref,
5090 table_map filter_for_table,
5091 const MY_BITMAP *fields_to_ignore,
5092 double rows_in_table)
5093 {
5094 /*
5095 Does not contribute to filtering effect if
5096 1) This field belongs to another table.
5097 2) Filter effect for this field has already been taken into
5098 account. 'fieldref' may be a field or a reference to a field
5099 (through a view, to an outer table etc)
5100 */
5101 if ((fieldref->used_tables() != filter_for_table) || // 1)
5102 bitmap_is_set(fields_to_ignore,
5103 static_cast<Item_field*>
5104 (fieldref->real_item())->field->field_index)) // 2)
5105 return COND_FILTER_ALLPASS;
5106
5107 const Item_field *fld= (Item_field*)fieldref->real_item();
5108 return fld->get_cond_filter_default_probability(rows_in_table,
5109 COND_FILTER_EQUALITY);
5110
5111 }
5112
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)5113 float Item_func_in::get_filtering_effect(table_map filter_for_table,
5114 table_map read_tables,
5115 const MY_BITMAP *fields_to_ignore,
5116 double rows_in_table)
5117 {
5118
5119 DBUG_ASSERT((read_tables & filter_for_table) == 0);
5120 /*
5121 To contribute to filtering effect, the condition must refer to
5122 exactly one unread table: the table filtering is currently
5123 calculated for.
5124
5125 Dependent subqueries are not considered available values and no
5126 filtering should be calculated for this item if the IN list
5127 contains one. dep_subq_in_list is 'true' if the IN list contains a
5128 dependent subquery.
5129 */
5130 if ((used_tables() & ~read_tables) != filter_for_table ||
5131 dep_subq_in_list)
5132 return COND_FILTER_ALLPASS;
5133
5134 /*
5135 No matter how many row values are input the filtering effect
5136 shall not be higher than in_max_filter (currently 0.5).
5137 */
5138 const float in_max_filter= 0.5f;
5139
5140 float filter= COND_FILTER_ALLPASS;
5141 if (args[0]->type() == Item::ROW_ITEM)
5142 {
5143 /*
5144 This is a row value IN predicate:
5145 "WHERE (col1, col2, ...) IN ((1,2,..), ...)"
5146 which can be rewritten to:
5147 "WHERE (col1=1 AND col2=2...) OR (col1=.. AND col2=...) OR ..."
5148
5149 The filtering effect is:
5150 filter= #row_values * filter(<single_row_value>)
5151
5152 where filter(<single_row_value>) = filter(col1) * filter(col2) * ...
5153
5154 In other words, we ignore the fact that there could be identical
5155 row values since writing "WHERE (a,b) IN ((1,1), (1,1), ...)" is
5156 not expected input from a user.
5157 */
5158 Item_row* lhs_row= static_cast<Item_row*>(args[0]);
5159 // For all items in the left row
5160 float single_rowval_filter= COND_FILTER_ALLPASS;
5161 for (uint i= 0; i < lhs_row->cols(); i++)
5162 {
5163 /*
5164 May contribute to condition filtering only if
5165 lhs_row->element_index(i) is a field or a reference to a field
5166 (through a view, to an outer table etc)
5167 */
5168 if (lhs_row->element_index(i)->real_item()->type() == Item::FIELD_ITEM)
5169 {
5170 Item_ident *fieldref=
5171 static_cast<Item_ident*>(lhs_row->element_index(i));
5172
5173 const float tmp_filt= get_single_col_filtering_effect(fieldref,
5174 filter_for_table,
5175 fields_to_ignore,
5176 rows_in_table);
5177 single_rowval_filter*= tmp_filt;
5178 }
5179 }
5180
5181 /*
5182 If single_rowval_filter == COND_FILTER_ALLPASS, the filtering
5183 effect of this field should be ignored. If not, selectivity
5184 should not be higher than 'in_max_filter' even if there are a
5185 lot of values on the right hand side
5186
5187 arg_count includes the left hand side item
5188 */
5189 if (single_rowval_filter != COND_FILTER_ALLPASS)
5190 filter= min((arg_count - 1) * single_rowval_filter, in_max_filter);
5191 }
5192 else if (args[0]->real_item()->type() == Item::FIELD_ITEM)
5193 {
5194 /*
5195 This is a single-column IN predicate:
5196 "WHERE col IN (1, 2, ...)"
5197 which can be rewritten to:
5198 "WHERE col=1 OR col1=2 OR ..."
5199
5200 The filtering effect is: #values_right_hand_side * selectivity(=)
5201
5202 As for row values, it is assumed that no values on the right
5203 hand side are identical.
5204 */
5205 DBUG_ASSERT(args[0]->type() == FIELD_ITEM || args[0]->type() == REF_ITEM);
5206 Item_ident *fieldref= static_cast<Item_ident*>(args[0]);
5207
5208 const float tmp_filt= get_single_col_filtering_effect(fieldref,
5209 filter_for_table,
5210 fields_to_ignore,
5211 rows_in_table);
5212 /*
5213 If tmp_filt == COND_FILTER_ALLPASS, the filtering effect of this
5214 field should be ignored. If not, selectivity should not be
5215 higher than 'in_max_filter' even if there are a lot of values on
5216 the right hand side
5217
5218 arg_count includes the left hand side item
5219 */
5220 if (tmp_filt != COND_FILTER_ALLPASS)
5221 filter= min((arg_count - 1) * tmp_filt, in_max_filter);
5222 }
5223
5224 if (negated && filter != COND_FILTER_ALLPASS)
5225 filter= 1.0f - filter;
5226
5227 DBUG_ASSERT(filter >= 0.0f && filter <= 1.0f);
5228 return filter;
5229 }
5230
list_contains_null()5231 bool Item_func_in::list_contains_null()
5232 {
5233 Item **arg,**arg_end;
5234 for (arg= args + 1, arg_end= args+arg_count; arg != arg_end ; arg++)
5235 {
5236 if ((*arg)->null_inside())
5237 return 1;
5238 }
5239 return 0;
5240 }
5241
5242
5243 /**
5244 Perform context analysis of an IN item tree.
5245
5246 This function performs context analysis (name resolution) and calculates
5247 various attributes of the item tree with Item_func_in as its root.
5248 The function saves in ref the pointer to the item or to a newly created
5249 item that is considered as a replacement for the original one.
5250
5251 @param thd reference to the global context of the query thread
5252 @param ref pointer to Item* variable where pointer to resulting "fixed"
5253 item is to be assigned
5254
5255 @note
5256 Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
5257 a predicate/function level. Then it's easy to show that:
5258 @verbatim
5259 T0(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
5260 T1(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
5261 T0(e NOT IN(e1,...,en)) = union(T1(e),union(T1(ei)))
5262 T1(e NOT IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
5263 @endverbatim
5264
5265 @retval
5266 0 ok
5267 @retval
5268 1 got error
5269 */
5270
fix_fields(THD * thd,Item ** ref)5271 bool Item_func_in::fix_fields(THD *thd, Item **ref)
5272 {
5273 if (Item_func_opt_neg::fix_fields(thd, ref))
5274 return true;
5275
5276 // not_null_tables_cache == union(T1(e),union(T1(ei)))
5277 if (pred_level && negated)
5278 return false;
5279
5280 // not_null_tables_cache = union(T1(e),intersection(T1(ei)))
5281 not_null_tables_cache= ~(table_map) 0;
5282 Item **arg_end= args + arg_count;
5283 for (Item **arg= args + 1; arg != arg_end; arg++)
5284 not_null_tables_cache&= (*arg)->not_null_tables();
5285 not_null_tables_cache|= (*args)->not_null_tables();
5286
5287 return false;
5288 }
5289
5290
fix_after_pullout(st_select_lex * parent_select,st_select_lex * removed_select)5291 void Item_func_in::fix_after_pullout(st_select_lex *parent_select,
5292 st_select_lex *removed_select)
5293 {
5294 Item_func_opt_neg::fix_after_pullout(parent_select, removed_select);
5295
5296 // not_null_tables_cache == union(T1(e),union(T1(ei)))
5297 if (pred_level && negated)
5298 return;
5299
5300 // not_null_tables_cache = union(T1(e),intersection(T1(ei)))
5301 not_null_tables_cache= ~(table_map) 0;
5302 Item **arg_end= args + arg_count;
5303 for (Item **arg= args + 1; arg != arg_end; arg++)
5304 not_null_tables_cache&= (*arg)->not_null_tables();
5305 not_null_tables_cache|= (*args)->not_null_tables();
5306 }
5307
5308
srtcmp_in(CHARSET_INFO * cs,const String * x,const String * y)5309 static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
5310 {
5311 return cs->coll->strnncollsp(cs,
5312 (uchar *) x->ptr(),x->length(),
5313 (uchar *) y->ptr(),y->length(), 0);
5314 }
5315
5316
fix_length_and_dec()5317 void Item_func_in::fix_length_and_dec()
5318 {
5319 Item **arg, **arg_end;
5320 bool const_itm= 1;
5321 THD *thd= current_thd;
5322 bool datetime_found= FALSE;
5323 /* TRUE <=> arguments values will be compared as DATETIMEs. */
5324 bool compare_as_datetime= FALSE;
5325 Item *date_arg= 0;
5326 uint found_types= 0;
5327 uint type_cnt= 0, i;
5328 Item_result cmp_type= STRING_RESULT;
5329 left_result_type= args[0]->result_type();
5330 if (!(found_types= collect_cmp_types(args, arg_count, true)))
5331 return;
5332
5333 for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
5334 {
5335 if (!arg[0]->const_item())
5336 {
5337 const_itm= 0;
5338 if (arg[0]->real_item()->type() == Item::SUBSELECT_ITEM)
5339 dep_subq_in_list= true;
5340 break;
5341 }
5342 }
5343 for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
5344 {
5345 if (found_types & (1U << i))
5346 {
5347 (type_cnt)++;
5348 cmp_type= (Item_result) i;
5349 }
5350 }
5351
5352 /*
5353 First conditions for bisection to be possible:
5354 1. All types are similar, and
5355 2. All expressions in <in value list> are const
5356 */
5357 bool bisection_possible=
5358 type_cnt == 1 && // 1
5359 const_itm; // 2
5360 if (bisection_possible)
5361 {
5362 /*
5363 In the presence of NULLs, the correct result of evaluating this item
5364 must be UNKNOWN or FALSE. To achieve that:
5365 - If type is scalar, we can use bisection and the "have_null" boolean.
5366 - If type is ROW, we will need to scan all of <in value list> when
5367 searching, so bisection is impossible. Unless:
5368 3. UNKNOWN and FALSE are equivalent results
5369 4. Neither left expression nor <in value list> contain any NULL value
5370 */
5371
5372 if (cmp_type == ROW_RESULT &&
5373 !((is_top_level_item() && !negated) || // 3
5374 (!list_contains_null() && !args[0]->maybe_null))) // 4
5375 bisection_possible= false;
5376 }
5377
5378 /*
5379 JSON values will be compared as strings, and not with the JSON
5380 comparator as one might expect. Raise a warning if one of the
5381 arguments is JSON. (The degenerate case x IN (y) may get rewritten
5382 to x = y, though, and then the JSON comparator will be used if one
5383 of the arguments is JSON.)
5384 */
5385 unsupported_json_comparison(arg_count, args,
5386 "comparison of JSON in the IN operator");
5387
5388 if (type_cnt == 1)
5389 {
5390 if (cmp_type == STRING_RESULT &&
5391 agg_arg_charsets_for_comparison(cmp_collation, args, arg_count))
5392 return;
5393 /*
5394 When comparing rows create the row comparator object beforehand to ease
5395 the DATETIME comparison detection procedure.
5396 */
5397 if (cmp_type == ROW_RESULT)
5398 {
5399 cmp_item_row *cmp= 0;
5400 if (bisection_possible)
5401 {
5402 array= new in_row(thd, arg_count-1, 0);
5403 cmp= &((in_row*)array)->tmp;
5404 }
5405 else
5406 {
5407 if (!(cmp= new cmp_item_row))
5408 return;
5409 cmp_items[ROW_RESULT]= cmp;
5410 }
5411 cmp->n= args[0]->cols();
5412 cmp->alloc_comparators(args[0]);
5413 }
5414 /* All DATE/DATETIME fields/functions has the STRING result type. */
5415 if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
5416 {
5417 uint col, cols= args[0]->cols();
5418
5419 for (col= 0; col < cols; col++)
5420 {
5421 bool skip_column= FALSE;
5422 /*
5423 Check that all items to be compared has the STRING result type and at
5424 least one of them is a DATE/DATETIME item.
5425 */
5426 for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++)
5427 {
5428 Item *itm= ((cmp_type == STRING_RESULT) ? arg[0] :
5429 arg[0]->element_index(col));
5430 if (itm->result_type() != STRING_RESULT)
5431 {
5432 skip_column= TRUE;
5433 break;
5434 }
5435 else if (itm->is_temporal_with_date())
5436 {
5437 datetime_found= TRUE;
5438 /*
5439 Internally all DATE/DATETIME values are converted to the DATETIME
5440 type. So try to find a DATETIME item to issue correct warnings.
5441 */
5442 if (!date_arg)
5443 date_arg= itm;
5444 else if (itm->field_type() == MYSQL_TYPE_DATETIME)
5445 {
5446 date_arg= itm;
5447 /* All arguments are already checked to have the STRING result. */
5448 if (cmp_type == STRING_RESULT)
5449 break;
5450 }
5451 }
5452 }
5453 if (skip_column)
5454 continue;
5455 if (datetime_found)
5456 {
5457 if (cmp_type == ROW_RESULT)
5458 {
5459 cmp_item **cmp= 0;
5460 if (array)
5461 cmp= ((in_row*)array)->tmp.comparators + col;
5462 else
5463 cmp= ((cmp_item_row*)cmp_items[ROW_RESULT])->comparators + col;
5464 *cmp= new cmp_item_datetime(date_arg);
5465 /* Reset variables for the next column. */
5466 date_arg= 0;
5467 datetime_found= FALSE;
5468 }
5469 else
5470 compare_as_datetime= TRUE;
5471 }
5472 }
5473 }
5474 }
5475
5476 if (bisection_possible)
5477 {
5478 if (compare_as_datetime)
5479 array= new in_datetime(thd, date_arg, arg_count - 1);
5480 else
5481 {
5482 /*
5483 IN must compare INT columns and constants as int values (the same
5484 way as equality does).
5485 So we must check here if the column on the left and all the constant
5486 values on the right can be compared as integers and adjust the
5487 comparison type accordingly.
5488 */
5489 bool datetime_as_longlong= false;
5490 if (args[0]->real_item()->type() == FIELD_ITEM &&
5491 thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
5492 thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
5493 cmp_type != INT_RESULT)
5494 {
5495 Item_field *field_item= (Item_field*) (args[0]->real_item());
5496 if (field_item->field->can_be_compared_as_longlong())
5497 {
5498 bool all_converted= true;
5499 for (arg=args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
5500 {
5501 if (!convert_constant_item (thd, field_item, &arg[0]))
5502 all_converted= false;
5503 }
5504 if (all_converted)
5505 {
5506 cmp_type= INT_RESULT;
5507 datetime_as_longlong= field_item->is_temporal();
5508 }
5509 }
5510 }
5511 switch (cmp_type) {
5512 case STRING_RESULT:
5513 array=new in_string(thd, arg_count-1, (qsort2_cmp) srtcmp_in,
5514 cmp_collation.collation);
5515 break;
5516 case INT_RESULT:
5517 array= datetime_as_longlong ?
5518 args[0]->field_type() == MYSQL_TYPE_TIME ?
5519 (in_vector*) new in_time_as_longlong(thd, arg_count - 1) :
5520 (in_vector*) new in_datetime_as_longlong(thd, arg_count - 1) :
5521 (in_vector*) new in_longlong(thd, arg_count - 1);
5522 break;
5523 case REAL_RESULT:
5524 array= new in_double(thd, arg_count-1);
5525 break;
5526 case ROW_RESULT:
5527 /*
5528 The row comparator was created at the beginning.
5529 */
5530 break;
5531 case DECIMAL_RESULT:
5532 array= new in_decimal(thd, arg_count - 1);
5533 break;
5534 default:
5535 DBUG_ASSERT(0);
5536 return;
5537 }
5538 }
5539 if (!array || thd->is_fatal_error) // OOM
5540 return;
5541 uint j=0;
5542 for (uint i=1 ; i < arg_count ; i++)
5543 {
5544 array->set(j,args[i]);
5545 if (!args[i]->null_value)
5546 j++; // include this cell in the array.
5547 else
5548 {
5549 /*
5550 We don't put NULL values in array, to avoid erronous matches in
5551 bisection.
5552 */
5553 have_null= 1;
5554 }
5555 }
5556 array->used_count= j;
5557 DBUG_ASSERT(array->used_count <= array->count);
5558 if (array->used_count < array->count)
5559 array->shrink_array(j);
5560
5561 if (array->used_count)
5562 array->sort();
5563 }
5564 else
5565 {
5566 if (compare_as_datetime)
5567 cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
5568 else
5569 {
5570 for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
5571 {
5572 if (found_types & (1U << i) && !cmp_items[i])
5573 {
5574 if ((Item_result)i == STRING_RESULT &&
5575 agg_arg_charsets_for_comparison(cmp_collation, args, arg_count))
5576 return;
5577 if (!cmp_items[i] && !(cmp_items[i]=
5578 cmp_item::get_comparator((Item_result)i, args[0],
5579 cmp_collation.collation)))
5580 return;
5581 }
5582 }
5583 }
5584 }
5585 Opt_trace_object(&thd->opt_trace).add("IN_uses_bisection",
5586 bisection_possible);
5587 /*
5588 Set cmp_context of all arguments. This prevents
5589 Item_field::equal_fields_propagator() from transforming a zerofill integer
5590 argument into a string constant. Such a change would require rebuilding
5591 cmp_itmes.
5592 */
5593 for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
5594 {
5595 arg[0]->cmp_context= item_cmp_type(left_result_type, arg[0]->result_type());
5596 }
5597 max_length= 1;
5598 }
5599
5600
print(String * str,enum_query_type query_type)5601 void Item_func_in::print(String *str, enum_query_type query_type)
5602 {
5603 str->append('(');
5604 args[0]->print(str, query_type);
5605 if (negated)
5606 str->append(STRING_WITH_LEN(" not"));
5607 str->append(STRING_WITH_LEN(" in ("));
5608 print_args(str, 1, query_type);
5609 str->append(STRING_WITH_LEN("))"));
5610 }
5611
5612
5613 /*
5614 Evaluate the function and return its value.
5615
5616 SYNOPSIS
5617 val_int()
5618
5619 DESCRIPTION
5620 Evaluate the function and return its value.
5621
5622 IMPLEMENTATION
5623 If the array object is defined then the value of the function is
5624 calculated by means of this array.
5625 Otherwise several cmp_item objects are used in order to do correct
5626 comparison of left expression and an expression from the values list.
5627 One cmp_item object correspond to one used comparison type. Left
5628 expression can be evaluated up to number of different used comparison
5629 types. A bit mapped variable value_added_map is used to check whether
5630 the left expression already was evaluated for a particular result type.
5631 Result types are mapped to it according to their integer values i.e.
5632 STRING_RESULT is mapped to bit 0, REAL_RESULT to bit 1, so on.
5633
5634 RETURN
5635 Value of the function
5636 */
5637
val_int()5638 longlong Item_func_in::val_int()
5639 {
5640 cmp_item *in_item;
5641 DBUG_ASSERT(fixed == 1);
5642 uint value_added_map= 0;
5643 if (array)
5644 {
5645 bool tmp=array->find_item(args[0]);
5646 /*
5647 NULL on left -> UNKNOWN.
5648 Found no match, and NULL on right -> UNKNOWN.
5649 NULL on right can never give a match, as it is not stored in
5650 array.
5651 See also the 'bisection_possible' variable in fix_length_and_dec().
5652 */
5653 null_value=args[0]->null_value || (!tmp && have_null);
5654 return (longlong) (!null_value && tmp != negated);
5655 }
5656
5657 if ((null_value= args[0]->real_item()->type() == NULL_ITEM))
5658 return 0;
5659
5660 have_null= 0;
5661 for (uint i= 1 ; i < arg_count ; i++)
5662 {
5663 if (args[i]->real_item()->type() == NULL_ITEM)
5664 {
5665 have_null= TRUE;
5666 continue;
5667 }
5668 Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
5669 in_item= cmp_items[(uint)cmp_type];
5670 DBUG_ASSERT(in_item);
5671 if (!(value_added_map & (1U << (uint)cmp_type)))
5672 {
5673 in_item->store_value(args[0]);
5674 value_added_map|= 1U << (uint)cmp_type;
5675 }
5676 const int rc= in_item->cmp(args[i]);
5677 if (rc == FALSE)
5678 return (longlong) (!negated);
5679 have_null|= (rc == UNKNOWN);
5680 }
5681
5682 null_value= have_null;
5683 return (longlong) (!null_value && negated);
5684 }
5685
5686
check_deprecated_bin_op(const Item * a,const Item * b)5687 void Item::check_deprecated_bin_op(const Item *a, const Item *b)
5688 {
5689 /*
5690 We want to warn about cases which will likely change behaviour in future
5691 versions. The conditions to emit a warning are:
5692
5693 1. If there's only one argument, the item should be a [VAR]BINARY
5694 argument (1) and it should be different from the hex/bit/NULL literal (2).
5695
5696 2. If there are two arguments, both should be [VAR]BINARY (3) and at least
5697 one of them should be different from the hex/bit/NULL literal (4)
5698 */
5699 if (a->result_type() == STRING_RESULT &&
5700 a->collation.collation == &my_charset_bin && // (1), (3)
5701 (!b ||
5702 (b->result_type() == STRING_RESULT &&
5703 b->collation.collation == &my_charset_bin)) && // (3)
5704 ((a->type() != Item::VARBIN_ITEM &&
5705 a->type() != Item::NULL_ITEM) || // (2), (4)
5706 (b && b->type() != Item::VARBIN_ITEM &&
5707 b->type() != Item::NULL_ITEM))) // (4)
5708 {
5709 push_warning_printf(current_thd, Sql_condition::SL_WARNING,
5710 ER_WARN_DEPRECATED_SYNTAX,
5711 "Bitwise operations on BINARY will change behavior"
5712 " in a future version, check the 'Bit functions'"
5713 " section in the manual.");
5714 }
5715 }
5716
val_int()5717 longlong Item_func_bit_or::val_int()
5718 {
5719 DBUG_ASSERT(fixed == 1);
5720 ulonglong arg1= (ulonglong) args[0]->val_int();
5721 if (args[0]->null_value)
5722 {
5723 null_value=1; /* purecov: inspected */
5724 return 0; /* purecov: inspected */
5725 }
5726 ulonglong arg2= (ulonglong) args[1]->val_int();
5727 if (args[1]->null_value)
5728 {
5729 null_value=1;
5730 return 0;
5731 }
5732 null_value=0;
5733 return (longlong) (arg1 | arg2);
5734 }
5735
5736
val_int()5737 longlong Item_func_bit_and::val_int()
5738 {
5739 DBUG_ASSERT(fixed == 1);
5740 ulonglong arg1= (ulonglong) args[0]->val_int();
5741 if (args[0]->null_value)
5742 {
5743 null_value=1; /* purecov: inspected */
5744 return 0; /* purecov: inspected */
5745 }
5746 ulonglong arg2= (ulonglong) args[1]->val_int();
5747 if (args[1]->null_value)
5748 {
5749 null_value=1; /* purecov: inspected */
5750 return 0; /* purecov: inspected */
5751 }
5752 null_value=0;
5753 return (longlong) (arg1 & arg2);
5754 }
5755
Item_cond(THD * thd,Item_cond * item)5756 Item_cond::Item_cond(THD *thd, Item_cond *item)
5757 :Item_bool_func(thd, item),
5758 abort_on_null(item->abort_on_null)
5759 {
5760 /*
5761 item->list will be copied by copy_andor_arguments() call
5762 */
5763 }
5764
5765 /**
5766 Contextualization for Item_cond functional items
5767
5768 Item_cond successors use Item_cond::list instead of Item_func::args
5769 and Item_func::arg_count, so we can't itemize parse-time Item_cond
5770 objects by forwarding a contextualization process to the parent Item_func
5771 class: we need to overload this function to run a contextualization
5772 the Item_cond::list items.
5773 */
itemize(Parse_context * pc,Item ** res)5774 bool Item_cond::itemize(Parse_context *pc, Item **res)
5775 {
5776 if (skip_itemize(res))
5777 return false;
5778 if (super::itemize(pc, res))
5779 return true;
5780
5781 List_iterator<Item> li(list);
5782 Item *item;
5783 while ((item= li++))
5784 {
5785 if (item->itemize(pc, &item))
5786 return true;
5787 li.replace(item);
5788 }
5789 return false;
5790 }
5791
5792
copy_andor_arguments(THD * thd,Item_cond * item)5793 void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
5794 {
5795 List_iterator_fast<Item> li(item->list);
5796 while (Item *it= li++)
5797 {
5798 DBUG_ASSERT(it->real_item()); // Sanity check (no dangling 'ref')
5799 list.push_back(it->copy_andor_structure(thd));
5800 }
5801 }
5802
5803
5804 bool
fix_fields(THD * thd,Item ** ref)5805 Item_cond::fix_fields(THD *thd, Item **ref)
5806 {
5807 DBUG_ASSERT(fixed == 0);
5808 List_iterator<Item> li(list);
5809 Item *item;
5810
5811 /*
5812 Semi-join flattening should only be performed for predicates on
5813 the AND-top-level. Disable it if this condition is not an AND.
5814 */
5815 Disable_semijoin_flattening DSF(thd->lex->current_select(),
5816 functype() != COND_AND_FUNC);
5817
5818 uchar buff[sizeof(char*)]; // Max local vars in function
5819 used_tables_cache= 0;
5820 const_item_cache= true;
5821
5822 if (functype() == COND_AND_FUNC && abort_on_null)
5823 not_null_tables_cache= 0;
5824 else
5825 not_null_tables_cache= ~(table_map) 0;
5826
5827 if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
5828 return TRUE; // Fatal error flag is set!
5829 /*
5830 The following optimization reduces the depth of an AND-OR tree.
5831 E.g. a WHERE clause like
5832 F1 AND (F2 AND (F2 AND F4))
5833 is parsed into a tree with the same nested structure as defined
5834 by braces. This optimization will transform such tree into
5835 AND (F1, F2, F3, F4).
5836 Trees of OR items are flattened as well:
5837 ((F1 OR F2) OR (F3 OR F4)) => OR (F1, F2, F3, F4)
5838 Items for removed AND/OR levels will dangle until the death of the
5839 entire statement.
5840 The optimization is currently prepared statements and stored procedures
5841 friendly as it doesn't allocate any memory and its effects are durable
5842 (i.e. do not depend on PS/SP arguments).
5843 */
5844 while ((item=li++))
5845 {
5846 while (item->type() == Item::COND_ITEM &&
5847 ((Item_cond*) item)->functype() == functype() &&
5848 !((Item_cond*) item)->list.is_empty())
5849 { // Identical function
5850 li.replace(((Item_cond*) item)->list);
5851 ((Item_cond*) item)->list.empty();
5852 item= *li.ref(); // new current item
5853 }
5854 if (abort_on_null)
5855 item->top_level_item();
5856
5857 // item can be substituted in fix_fields
5858 if ((!item->fixed &&
5859 item->fix_fields(thd, li.ref())) ||
5860 (item= *li.ref())->check_cols(1))
5861 return TRUE; /* purecov: inspected */
5862 used_tables_cache|= item->used_tables();
5863 const_item_cache&= item->const_item();
5864
5865 if (functype() == COND_AND_FUNC && abort_on_null)
5866 not_null_tables_cache|= item->not_null_tables();
5867 else
5868 not_null_tables_cache&= item->not_null_tables();
5869 with_sum_func|= item->with_sum_func;
5870 with_subselect|= item->has_subquery();
5871 with_stored_program|= item->has_stored_program();
5872 maybe_null|= item->maybe_null;
5873 }
5874 thd->lex->current_select()->cond_count+= list.elements;
5875 fix_length_and_dec();
5876 fixed= true;
5877 return false;
5878 }
5879
5880
fix_after_pullout(st_select_lex * parent_select,st_select_lex * removed_select)5881 void Item_cond::fix_after_pullout(st_select_lex *parent_select,
5882 st_select_lex *removed_select)
5883 {
5884 List_iterator<Item> li(list);
5885 Item *item;
5886
5887 used_tables_cache= get_initial_pseudo_tables();
5888 const_item_cache= true;
5889
5890 if (functype() == COND_AND_FUNC && abort_on_null)
5891 not_null_tables_cache= 0;
5892 else
5893 not_null_tables_cache= ~(table_map) 0;
5894
5895 while ((item=li++))
5896 {
5897 item->fix_after_pullout(parent_select, removed_select);
5898 used_tables_cache|= item->used_tables();
5899 const_item_cache&= item->const_item();
5900 if (functype() == COND_AND_FUNC && abort_on_null)
5901 not_null_tables_cache|= item->not_null_tables();
5902 else
5903 not_null_tables_cache&= item->not_null_tables();
5904 }
5905 }
5906
5907
eq(const Item * item,bool binary_cmp) const5908 bool Item_cond::eq(const Item *item, bool binary_cmp) const
5909 {
5910 if (this == item)
5911 return true;
5912 if (item->type() != COND_ITEM)
5913 return false;
5914 const Item_cond *item_cond= down_cast<const Item_cond *>(item);
5915 if (functype() != item_cond->functype() ||
5916 list.elements != item_cond->list.elements ||
5917 func_name() != item_cond->func_name())
5918 return false;
5919 // Item_cond never uses "args". Inspect "list" instead.
5920 DBUG_ASSERT(arg_count == 0 && item_cond->arg_count == 0);
5921 List_iterator_fast<Item> it1(const_cast<Item_cond *>(this)->list);
5922 List_iterator_fast<Item> it2(const_cast<Item_cond *>(item_cond)->list);
5923 Item *i;
5924 while ((i= it1++))
5925 if (!i->eq(it2++, binary_cmp))
5926 return false;
5927 return true;
5928 }
5929
5930
walk(Item_processor processor,enum_walk walk,uchar * arg)5931 bool Item_cond::walk(Item_processor processor, enum_walk walk, uchar *arg)
5932 {
5933 if ((walk & WALK_PREFIX) && (this->*processor)(arg))
5934 return true;
5935
5936 List_iterator_fast<Item> li(list);
5937 Item *item;
5938 while ((item= li++))
5939 {
5940 if (item->walk(processor, walk, arg))
5941 return true;
5942 }
5943 return (walk & WALK_POSTFIX) && (this->*processor)(arg);
5944 }
5945
5946
5947 /**
5948 Transform an Item_cond object with a transformer callback function.
5949
5950 The function recursively applies the transform method to each
5951 member item of the condition list.
5952 If the call of the method for a member item returns a new item
5953 the old item is substituted for a new one.
5954 After this the transformer is applied to the root node
5955 of the Item_cond object.
5956
5957 @param transformer the transformer callback function to be applied to
5958 the nodes of the tree of the object
5959 @param arg parameter to be passed to the transformer
5960
5961 @return
5962 Item returned as the result of transformation of the root node
5963 */
5964
transform(Item_transformer transformer,uchar * arg)5965 Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
5966 {
5967 DBUG_ASSERT(!current_thd->stmt_arena->is_stmt_prepare());
5968
5969 List_iterator<Item> li(list);
5970 Item *item;
5971 while ((item= li++))
5972 {
5973 Item *new_item= item->transform(transformer, arg);
5974 if (!new_item)
5975 return 0;
5976
5977 /*
5978 THD::change_item_tree() should be called only if the tree was
5979 really transformed, i.e. when a new item has been created.
5980 Otherwise we'll be allocating a lot of unnecessary memory for
5981 change records at each execution.
5982 */
5983 if (new_item != item)
5984 current_thd->change_item_tree(li.ref(), new_item);
5985 }
5986 return Item_func::transform(transformer, arg);
5987 }
5988
5989
5990 /**
5991 Compile Item_cond object with a processor and a transformer
5992 callback functions.
5993
5994 First the function applies the analyzer to the root node of
5995 the Item_func object. Then if the analyzer succeeeds (returns TRUE)
5996 the function recursively applies the compile method to member
5997 item of the condition list.
5998 If the call of the method for a member item returns a new item
5999 the old item is substituted for a new one.
6000 After this the transformer is applied to the root node
6001 of the Item_cond object.
6002
6003 @param analyzer the analyzer callback function to be applied to the
6004 nodes of the tree of the object
6005 @param[in,out] arg_p parameter to be passed to the analyzer
6006 @param transformer the transformer callback function to be applied to the
6007 nodes of the tree of the object
6008 @param arg_t parameter to be passed to the transformer
6009
6010 @return Item returned as result of transformation of the node,
6011 the same item if no transformation applied, or NULL if
6012 transformation caused an error.
6013 */
6014
compile(Item_analyzer analyzer,uchar ** arg_p,Item_transformer transformer,uchar * arg_t)6015 Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
6016 Item_transformer transformer, uchar *arg_t)
6017 {
6018 if (!(this->*analyzer)(arg_p))
6019 return this;
6020
6021 List_iterator<Item> li(list);
6022 Item *item;
6023 while ((item= li++))
6024 {
6025 /*
6026 The same parameter value of arg_p must be passed
6027 to analyze any argument of the condition formula.
6028 */
6029 uchar *arg_v= *arg_p;
6030 Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
6031 if (new_item == NULL)
6032 return NULL;
6033 if (new_item != item)
6034 current_thd->change_item_tree(li.ref(), new_item);
6035 }
6036 // strange to call transform(): each argument will thus have the transformer
6037 // called twice on it (in compile() above and Item_func::transform below)??
6038 return Item_func::transform(transformer, arg_t);
6039 }
6040
traverse_cond(Cond_traverser traverser,void * arg,traverse_order order)6041 void Item_cond::traverse_cond(Cond_traverser traverser,
6042 void *arg, traverse_order order)
6043 {
6044 List_iterator<Item> li(list);
6045 Item *item;
6046
6047 switch(order) {
6048 case(PREFIX):
6049 (*traverser)(this, arg);
6050 while ((item= li++))
6051 {
6052 item->traverse_cond(traverser, arg, order);
6053 }
6054 (*traverser)(NULL, arg);
6055 break;
6056 case(POSTFIX):
6057 while ((item= li++))
6058 {
6059 item->traverse_cond(traverser, arg, order);
6060 }
6061 (*traverser)(this, arg);
6062 }
6063 }
6064
6065 /**
6066 Move SUM items out from item tree and replace with reference.
6067
6068 The split is done to get an unique item for each SUM function
6069 so that we can easily find and calculate them.
6070 (Calculation done by update_sum_func() and copy_sum_funcs() in
6071 sql_select.cc)
6072
6073 @param thd Thread handler
6074 @param ref_pointer_array Pointer to array of reference fields
6075 @param fields All fields in select
6076
6077 @note
6078 This function is run on all expression (SELECT list, WHERE, HAVING etc)
6079 that have or refer (HAVING) to a SUM expression.
6080 */
6081
split_sum_func(THD * thd,Ref_ptr_array ref_pointer_array,List<Item> & fields)6082 void Item_cond::split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
6083 List<Item> &fields)
6084 {
6085 List_iterator<Item> li(list);
6086 Item *item;
6087 while ((item= li++))
6088 item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), TRUE);
6089 }
6090
6091
update_used_tables()6092 void Item_cond::update_used_tables()
6093 {
6094 List_iterator_fast<Item> li(list);
6095 Item *item;
6096
6097 used_tables_cache=0;
6098 const_item_cache=1;
6099 with_subselect= false;
6100 with_stored_program= false;
6101 while ((item=li++))
6102 {
6103 item->update_used_tables();
6104 used_tables_cache|= item->used_tables();
6105 const_item_cache&= item->const_item();
6106 with_subselect|= item->has_subquery();
6107 with_stored_program|= item->has_stored_program();
6108 }
6109 }
6110
6111
print(String * str,enum_query_type query_type)6112 void Item_cond::print(String *str, enum_query_type query_type)
6113 {
6114 str->append('(');
6115 List_iterator_fast<Item> li(list);
6116 Item *item;
6117 if ((item=li++))
6118 item->print(str, query_type);
6119 while ((item=li++))
6120 {
6121 str->append(' ');
6122 str->append(func_name());
6123 str->append(' ');
6124 item->print(str, query_type);
6125 }
6126 str->append(')');
6127 }
6128
6129
neg_arguments(THD * thd)6130 void Item_cond::neg_arguments(THD *thd)
6131 {
6132 List_iterator<Item> li(list);
6133 Item *item;
6134 while ((item= li++)) /* Apply not transformation to the arguments */
6135 {
6136 Item *new_item= item->neg_transformer(thd);
6137 if (!new_item)
6138 {
6139 if (!(new_item= new Item_func_not(item)))
6140 return; // Fatal OEM error
6141 }
6142 (void) li.replace(new_item);
6143 }
6144 }
6145
6146
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)6147 float Item_cond_and::get_filtering_effect(table_map filter_for_table,
6148 table_map read_tables,
6149 const MY_BITMAP *fields_to_ignore,
6150 double rows_in_table)
6151 {
6152 if (!(used_tables() & filter_for_table))
6153 return COND_FILTER_ALLPASS; // No conditions below this apply to the table
6154
6155 float filter= COND_FILTER_ALLPASS;
6156 List_iterator<Item> it(list);
6157 Item *item;
6158
6159 /*
6160 Calculated as "Conjunction of independent events":
6161 P(A and B ...) = P(A) * P(B) * ...
6162 */
6163 while ((item= it++))
6164 filter*= item->get_filtering_effect(filter_for_table,
6165 read_tables,
6166 fields_to_ignore,
6167 rows_in_table);
6168 return filter;
6169 }
6170
6171 /**
6172 Evaluation of AND(expr, expr, expr ...).
6173
6174 @note
6175 abort_if_null is set for AND expressions for which we don't care if the
6176 result is NULL or 0. This is set for:
6177 - WHERE clause
6178 - HAVING clause
6179 - IF(expression)
6180
6181 @retval
6182 1 If all expressions are true
6183 @retval
6184 0 If all expressions are false or if we find a NULL expression and
6185 'abort_on_null' is set.
6186 @retval
6187 NULL if all expression are either 1 or NULL
6188 */
6189
6190
val_int()6191 longlong Item_cond_and::val_int()
6192 {
6193 DBUG_ASSERT(fixed == 1);
6194 List_iterator_fast<Item> li(list);
6195 Item *item;
6196 null_value= 0;
6197 while ((item=li++))
6198 {
6199 if (!item->val_bool())
6200 {
6201 if (abort_on_null || !(null_value= item->null_value))
6202 return 0; // return FALSE
6203 }
6204 }
6205 return null_value ? 0 : 1;
6206 }
6207
6208
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)6209 float Item_cond_or::get_filtering_effect(table_map filter_for_table,
6210 table_map read_tables,
6211 const MY_BITMAP *fields_to_ignore,
6212 double rows_in_table)
6213 {
6214 if (!(used_tables() & filter_for_table))
6215 return COND_FILTER_ALLPASS; // No conditions below this apply to the table
6216
6217 float filter= 0.0f;
6218 List_iterator<Item> it(list);
6219 Item *item;
6220 while ((item= it++))
6221 {
6222 const float cur_filter=
6223 item->get_filtering_effect(filter_for_table, read_tables,
6224 fields_to_ignore, rows_in_table);
6225 /*
6226 Calculated as "Disjunction of independent events":
6227 P(A or B) = P(A) + P(B) - P(A) * P(B)
6228
6229 If any of the ORed predicates has a filtering effect of
6230 COND_FILTER_ALLPASS, the end result is COND_FILTER_ALLPASS. This is as
6231 expected since COND_FILTER_ALLPASS means that a) the predicate has
6232 no filtering effect at all, or b) the predicate's filtering
6233 effect is unknown. In both cases, the only meaningful result is
6234 for OR to produce COND_FILTER_ALLPASS.
6235 */
6236 filter= filter + cur_filter - (filter * cur_filter);
6237 }
6238 return filter;
6239 }
6240
val_int()6241 longlong Item_cond_or::val_int()
6242 {
6243 DBUG_ASSERT(fixed == 1);
6244 List_iterator_fast<Item> li(list);
6245 Item *item;
6246 null_value=0;
6247 while ((item=li++))
6248 {
6249 if (item->val_bool())
6250 {
6251 null_value=0;
6252 return 1;
6253 }
6254 if (item->null_value)
6255 null_value=1;
6256 }
6257 return 0;
6258 }
6259
6260 /**
6261 Create an AND expression from two expressions.
6262
6263 @param a expression or NULL
6264 @param b expression.
6265 @param org_item Don't modify a if a == *org_item.
6266 If a == NULL, org_item is set to point at b,
6267 to ensure that future calls will not modify b.
6268
6269 @note
6270 This will not modify item pointed to by org_item or b
6271 The idea is that one can call this in a loop and create and
6272 'and' over all items without modifying any of the original items.
6273
6274 @retval
6275 NULL Error
6276 @retval
6277 Item
6278 */
6279
and_expressions(Item * a,Item * b,Item ** org_item)6280 Item *and_expressions(Item *a, Item *b, Item **org_item)
6281 {
6282 if (!a)
6283 return (*org_item= b);
6284 if (a == *org_item)
6285 {
6286 Item_cond *res;
6287 if ((res= new Item_cond_and(a, b)))
6288 {
6289 res->set_used_tables(a->used_tables() | b->used_tables());
6290 res->set_not_null_tables(a->not_null_tables() | b->not_null_tables());
6291 }
6292 return res;
6293 }
6294 if (((Item_cond_and*) a)->add(b))
6295 return 0;
6296 ((Item_cond_and*) a)->set_used_tables(a->used_tables() | b->used_tables());
6297 ((Item_cond_and*) a)->set_not_null_tables(a->not_null_tables() |
6298 b->not_null_tables());
6299 return a;
6300 }
6301
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)6302 float Item_func_isnull::get_filtering_effect(table_map filter_for_table,
6303 table_map read_tables,
6304 const MY_BITMAP *fields_to_ignore,
6305 double rows_in_table)
6306 {
6307 const Item_field* fld=
6308 contributes_to_filter(read_tables, filter_for_table, fields_to_ignore);
6309 if (!fld)
6310 return COND_FILTER_ALLPASS;
6311
6312 return fld->get_cond_filter_default_probability(rows_in_table,
6313 COND_FILTER_EQUALITY);
6314 }
6315
val_int()6316 longlong Item_func_isnull::val_int()
6317 {
6318 DBUG_ASSERT(fixed == 1);
6319 /*
6320 Handle optimization if the argument can't be null
6321 This has to be here because of the test in update_used_tables().
6322 */
6323 if (const_item_cache)
6324 return cached_value;
6325 return args[0]->is_null() ? 1: 0;
6326 }
6327
val_int()6328 longlong Item_is_not_null_test::val_int()
6329 {
6330 DBUG_ASSERT(fixed == 1);
6331 DBUG_ENTER("Item_is_not_null_test::val_int");
6332 if (!used_tables_cache && !with_subselect && !with_stored_program)
6333 {
6334 /*
6335 TODO: Currently this branch never executes, since used_tables_cache
6336 is never equal to 0 -- it always contains RAND_TABLE_BIT,
6337 see get_initial_pseudo_tables().
6338 */
6339 owner->was_null|= (!cached_value);
6340 DBUG_PRINT("info", ("cached: %ld", (long) cached_value));
6341 DBUG_RETURN(cached_value);
6342 }
6343 if (args[0]->is_null())
6344 {
6345 DBUG_PRINT("info", ("null"));
6346 owner->was_null|= 1;
6347 DBUG_RETURN(0);
6348 }
6349 else
6350 DBUG_RETURN(1);
6351 }
6352
6353 /**
6354 Optimize case of not_null_column IS NULL.
6355 */
update_used_tables()6356 void Item_is_not_null_test::update_used_tables()
6357 {
6358 const table_map initial_pseudo_tables= get_initial_pseudo_tables();
6359 used_tables_cache= initial_pseudo_tables;
6360 if (!args[0]->maybe_null)
6361 {
6362 cached_value= 1;
6363 return;
6364 }
6365 args[0]->update_used_tables();
6366 with_subselect= args[0]->has_subquery();
6367 with_stored_program= args[0]->has_stored_program();
6368 used_tables_cache|= args[0]->used_tables();
6369 if (used_tables_cache == initial_pseudo_tables && !with_subselect &&
6370 !with_stored_program)
6371 /* Remember if the value is always NULL or never NULL */
6372 cached_value= !args[0]->is_null();
6373 }
6374
6375 float
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)6376 Item_func_isnotnull::get_filtering_effect(table_map filter_for_table,
6377 table_map read_tables,
6378 const MY_BITMAP *fields_to_ignore,
6379 double rows_in_table)
6380 {
6381 const Item_field* fld=
6382 contributes_to_filter(read_tables, filter_for_table, fields_to_ignore);
6383 if (!fld)
6384 return COND_FILTER_ALLPASS;
6385
6386 return 1.0f - fld->get_cond_filter_default_probability(rows_in_table,
6387 COND_FILTER_EQUALITY);
6388 }
6389
val_int()6390 longlong Item_func_isnotnull::val_int()
6391 {
6392 DBUG_ASSERT(fixed == 1);
6393 return args[0]->is_null() ? 0 : 1;
6394 }
6395
6396
print(String * str,enum_query_type query_type)6397 void Item_func_isnotnull::print(String *str, enum_query_type query_type)
6398 {
6399 str->append('(');
6400 args[0]->print(str, query_type);
6401 str->append(STRING_WITH_LEN(" is not null)"));
6402 }
6403
6404
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)6405 float Item_func_like::get_filtering_effect(table_map filter_for_table,
6406 table_map read_tables,
6407 const MY_BITMAP *fields_to_ignore,
6408 double rows_in_table)
6409 {
6410 const Item_field* fld=
6411 contributes_to_filter(read_tables, filter_for_table, fields_to_ignore);
6412 if (!fld)
6413 return COND_FILTER_ALLPASS;
6414
6415 /*
6416 Filtering effect is similar to that of BETWEEN because
6417
6418 * "col like abc%" is similar to
6419 "col between abc and abd"
6420 The same applies for 'abc_'
6421 * "col like %abc" can be seen as
6422 "reverse(col) like cba%"" (see above)
6423 * "col like "abc%def%..." is also similar
6424
6425 Now we're left with "col like <string_no_wildcards>" which should
6426 have filtering effect like equality, but it would be costly to
6427 look through the whole string searching for wildcards and since
6428 LIKE is mostly used for wildcards this isn't checked.
6429 */
6430 return fld->get_cond_filter_default_probability(rows_in_table,
6431 COND_FILTER_BETWEEN);
6432 }
6433
6434
itemize(Parse_context * pc,Item ** res)6435 bool Item_func_like::itemize(Parse_context *pc, Item **res)
6436 {
6437 if (skip_itemize(res))
6438 return false;
6439 if (super::itemize(pc, res) ||
6440 (escape_item != NULL && escape_item->itemize(pc, &escape_item)))
6441 return true;
6442
6443 if (escape_item == NULL)
6444 {
6445 THD *thd= pc->thd;
6446 escape_item=
6447 ((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) ?
6448 new (pc->mem_root) Item_string("", 0, &my_charset_latin1) :
6449 new (pc->mem_root) Item_string("\\", 1, &my_charset_latin1));
6450 }
6451 return escape_item == NULL;
6452 }
6453
6454
val_int()6455 longlong Item_func_like::val_int()
6456 {
6457 DBUG_ASSERT(fixed == 1);
6458
6459 if (!escape_evaluated && eval_escape_clause(current_thd))
6460 return error_int();
6461
6462 String* res = args[0]->val_str(&cmp.value1);
6463 if (args[0]->null_value)
6464 {
6465 null_value=1;
6466 return 0;
6467 }
6468 String* res2 = args[1]->val_str(&cmp.value2);
6469 if (args[1]->null_value)
6470 {
6471 null_value=1;
6472 return 0;
6473 }
6474 null_value=0;
6475 if (can_do_bm)
6476 return bm_matches(res->ptr(), res->length()) ? 1 : 0;
6477 return my_wildcmp(cmp.cmp_collation.collation,
6478 res->ptr(),res->ptr()+res->length(),
6479 res2->ptr(),res2->ptr()+res2->length(),
6480 escape,wild_one,wild_many) ? 0 : 1;
6481 }
6482
6483
6484 /**
6485 We can optimize a where if first character isn't a wildcard
6486 */
6487
select_optimize() const6488 Item_func::optimize_type Item_func_like::select_optimize() const
6489 {
6490 if (!args[1]->const_item())
6491 return OPTIMIZE_NONE;
6492
6493 String* res2= args[1]->val_str((String *)&cmp.value2);
6494 if (!res2)
6495 return OPTIMIZE_NONE;
6496
6497 if (!res2->length()) // Can optimize empty wildcard: column LIKE ''
6498 return OPTIMIZE_OP;
6499
6500 DBUG_ASSERT(res2->ptr());
6501 char first= res2->ptr()[0];
6502 return (first == wild_many || first == wild_one) ?
6503 OPTIMIZE_NONE : OPTIMIZE_OP;
6504 }
6505
6506
fix_fields(THD * thd,Item ** ref)6507 bool Item_func_like::fix_fields(THD *thd, Item **ref)
6508 {
6509 DBUG_ASSERT(fixed == 0);
6510
6511 Disable_semijoin_flattening DSF(thd->lex->current_select(), true);
6512
6513 if (Item_bool_func2::fix_fields(thd, ref) ||
6514 escape_item->fix_fields(thd, &escape_item) ||
6515 escape_item->check_cols(1))
6516 return true;
6517
6518 if (!escape_item->const_during_execution())
6519 {
6520 my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
6521 return true;
6522 }
6523
6524 if (escape_item->const_item())
6525 {
6526 /*
6527 We need to know the escape character in order to apply Boyer-Moore. Since
6528 it is const, it is safe to evaluate it now at the resolution stage.
6529 */
6530 if (eval_escape_clause(thd))
6531 return true;
6532
6533 /*
6534 We could also do boyer-more for non-const items, but as we would have to
6535 recompute the tables for each row it's not worth it.
6536 */
6537 if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
6538 !(specialflag & SPECIAL_NO_NEW_FUNC))
6539 {
6540 String* res2 = args[1]->val_str(&cmp.value2);
6541 if (thd->is_error())
6542 return true;
6543 if (!res2)
6544 return false; // Null argument
6545
6546 const size_t len = res2->length();
6547 const char* first = res2->ptr();
6548 const char* last = first + len - 1;
6549
6550 /*
6551 Minimum length pattern before Boyer-Moore is used
6552 for SELECT "text" LIKE "%pattern%" including the two
6553 wildcards in class Item_func_like.
6554 */
6555
6556 const size_t min_bm_pattern_len= 5;
6557
6558 if (len > min_bm_pattern_len &&
6559 *first == wild_many &&
6560 *last == wild_many)
6561 {
6562 const char* tmp = first + 1;
6563 for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
6564 can_do_bm= (tmp == last) && !use_mb(args[0]->collation.collation);
6565 }
6566 if (can_do_bm)
6567 {
6568 pattern_len = (int) len - 2;
6569 pattern = thd->strmake(first + 1, pattern_len);
6570 DBUG_PRINT("info", ("Initializing pattern: '%s'", first));
6571 int *suff = (int*) thd->alloc((int) (sizeof(int)*
6572 ((pattern_len + 1)*2+
6573 alphabet_size)));
6574 bmGs = suff + pattern_len + 1;
6575 bmBc = bmGs + pattern_len + 1;
6576 bm_compute_good_suffix_shifts(suff);
6577 bm_compute_bad_character_shifts();
6578 DBUG_PRINT("info",("done"));
6579 }
6580 }
6581 }
6582 return false;
6583 }
6584
cleanup()6585 void Item_func_like::cleanup()
6586 {
6587 can_do_bm= false;
6588 escape_evaluated= false;
6589 Item_bool_func2::cleanup();
6590 }
6591
6592 /**
6593 Evaluate the expression in the escape clause.
6594
6595 @param thd thread handler
6596 @return false on success, true on failure
6597 */
eval_escape_clause(THD * thd)6598 bool Item_func_like::eval_escape_clause(THD *thd)
6599 {
6600 DBUG_ASSERT(!escape_evaluated);
6601
6602 String buf;
6603 String *escape_str= escape_item->val_str(&buf);
6604 if (escape_str)
6605 {
6606 const char *escape_str_ptr= escape_str->ptr();
6607 if (escape_used_in_parsing && (
6608 (((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
6609 escape_str->numchars() != 1) ||
6610 escape_str->numchars() > 1)))
6611 {
6612 my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
6613 return true;
6614 }
6615
6616 if (use_mb(cmp.cmp_collation.collation))
6617 {
6618 const CHARSET_INFO *cs= escape_str->charset();
6619 my_wc_t wc;
6620 int rc= cs->cset->mb_wc(cs, &wc,
6621 (const uchar*) escape_str_ptr,
6622 (const uchar*) escape_str_ptr +
6623 escape_str->length());
6624 escape= (int) (rc > 0 ? wc : '\\');
6625 }
6626 else
6627 {
6628 /*
6629 In the case of 8bit character set, we pass native
6630 code instead of Unicode code as "escape" argument.
6631 Convert to "cs" if charset of escape differs.
6632 */
6633 const CHARSET_INFO *cs= cmp.cmp_collation.collation;
6634 size_t unused;
6635 if (escape_str->needs_conversion(escape_str->length(),
6636 escape_str->charset(), cs, &unused))
6637 {
6638 char ch;
6639 uint errors;
6640 size_t cnvlen= copy_and_convert(&ch, 1, cs, escape_str_ptr,
6641 escape_str->length(),
6642 escape_str->charset(), &errors);
6643 escape= cnvlen ? ch : '\\';
6644 }
6645 else
6646 escape= escape_str_ptr ? *escape_str_ptr : '\\';
6647 }
6648 }
6649 else
6650 escape= '\\';
6651
6652 escape_evaluated= true;
6653
6654 return false;
6655 }
6656
6657 /**
6658 @brief Compile regular expression.
6659
6660 @param[in] send_error send error message if any.
6661
6662 @details Make necessary character set conversion then
6663 compile regular expression passed in the args[1].
6664
6665 @retval 0 success.
6666 @retval 1 error occurred.
6667 @retval -1 given null regular expression.
6668 */
6669
regcomp(bool send_error)6670 int Item_func_regex::regcomp(bool send_error)
6671 {
6672 char buff[MAX_FIELD_WIDTH];
6673 String tmp(buff,sizeof(buff),&my_charset_bin);
6674 String *res= args[1]->val_str(&tmp);
6675 int error;
6676
6677 if (args[1]->null_value)
6678 return -1;
6679
6680 if (regex_compiled)
6681 {
6682 if (!stringcmp(res, &prev_regexp))
6683 return 0;
6684 prev_regexp.copy(*res);
6685 my_regfree(&preg);
6686 regex_compiled= 0;
6687 }
6688
6689 if (cmp_collation.collation != regex_lib_charset)
6690 {
6691 /* Convert UCS2 strings to UTF8 */
6692 uint dummy_errors;
6693 if (conv.copy(res->ptr(), res->length(), res->charset(),
6694 regex_lib_charset, &dummy_errors))
6695 return 1;
6696 res= &conv;
6697 }
6698
6699 if ((error= my_regcomp(&preg, res->c_ptr_safe(),
6700 regex_lib_flags, regex_lib_charset)))
6701 {
6702 if (send_error)
6703 {
6704 (void) my_regerror(error, &preg, buff, sizeof(buff));
6705 my_error(ER_REGEXP_ERROR, MYF(0), buff);
6706 }
6707 return 1;
6708 }
6709 regex_compiled= 1;
6710 return 0;
6711 }
6712
6713
6714 bool
fix_fields(THD * thd,Item ** ref)6715 Item_func_regex::fix_fields(THD *thd, Item **ref)
6716 {
6717 DBUG_ASSERT(fixed == 0);
6718
6719 Disable_semijoin_flattening DSF(thd->lex->current_select(), true);
6720
6721 if ((!args[0]->fixed &&
6722 args[0]->fix_fields(thd, args)) || args[0]->check_cols(1) ||
6723 (!args[1]->fixed &&
6724 args[1]->fix_fields(thd, args + 1)) || args[1]->check_cols(1))
6725 return TRUE; /* purecov: inspected */
6726 with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func;
6727 with_subselect= args[0]->has_subquery() || args[1]->has_subquery();
6728 with_stored_program= args[0]->has_stored_program() ||
6729 args[1]->has_stored_program();
6730 max_length= 1;
6731 decimals= 0;
6732
6733 if (agg_arg_charsets_for_comparison(cmp_collation, args, 2))
6734 return TRUE;
6735
6736 regex_lib_flags= (cmp_collation.collation->state &
6737 (MY_CS_BINSORT | MY_CS_CSSORT)) ?
6738 MY_REG_EXTENDED | MY_REG_NOSUB :
6739 MY_REG_EXTENDED | MY_REG_NOSUB | MY_REG_ICASE;
6740 /*
6741 If the case of UCS2 and other non-ASCII character sets,
6742 we will convert patterns and strings to UTF8.
6743 */
6744 regex_lib_charset= (cmp_collation.collation->mbminlen > 1) ?
6745 &my_charset_utf8_general_ci :
6746 cmp_collation.collation;
6747
6748 used_tables_cache=args[0]->used_tables() | args[1]->used_tables();
6749 not_null_tables_cache= (args[0]->not_null_tables() |
6750 args[1]->not_null_tables());
6751 const_item_cache=args[0]->const_item() && args[1]->const_item();
6752 if (!regex_compiled && args[1]->const_item())
6753 {
6754 int comp_res= regcomp(TRUE);
6755 if (comp_res == -1)
6756 { // Will always return NULL
6757 maybe_null=1;
6758 fixed= 1;
6759 return FALSE;
6760 }
6761 else if (comp_res)
6762 return TRUE;
6763 regex_is_const= 1;
6764 maybe_null= args[0]->maybe_null;
6765 }
6766 else
6767 maybe_null=1;
6768 fixed= 1;
6769 return FALSE;
6770 }
6771
6772
val_int()6773 longlong Item_func_regex::val_int()
6774 {
6775 DBUG_ASSERT(fixed == 1);
6776 char buff[MAX_FIELD_WIDTH];
6777 String tmp(buff,sizeof(buff),&my_charset_bin);
6778 String *res= args[0]->val_str(&tmp);
6779
6780 if ((null_value= (args[0]->null_value ||
6781 (!regex_is_const && regcomp(FALSE)))))
6782 return 0;
6783
6784 if (cmp_collation.collation != regex_lib_charset)
6785 {
6786 /* Convert UCS2 strings to UTF8 */
6787 uint dummy_errors;
6788 if (conv.copy(res->ptr(), res->length(), res->charset(),
6789 regex_lib_charset, &dummy_errors))
6790 {
6791 null_value= 1;
6792 return 0;
6793 }
6794 res= &conv;
6795 }
6796 return my_regexec(&preg,res->c_ptr_safe(),0,(my_regmatch_t*) 0,0) ? 0 : 1;
6797 }
6798
6799
cleanup()6800 void Item_func_regex::cleanup()
6801 {
6802 DBUG_ENTER("Item_func_regex::cleanup");
6803 Item_bool_func::cleanup();
6804 if (regex_compiled)
6805 {
6806 my_regfree(&preg);
6807 regex_compiled=0;
6808 prev_regexp.length(0);
6809 }
6810 DBUG_VOID_RETURN;
6811 }
6812
6813
6814 #define likeconv(cs,A) (uchar) (cs)->sort_order[(uchar) (A)]
6815
6816
6817 /**
6818 Precomputation dependent only on pattern_len.
6819 */
6820
bm_compute_suffixes(int * suff)6821 void Item_func_like::bm_compute_suffixes(int *suff)
6822 {
6823 const int plm1 = pattern_len - 1;
6824 int f = 0;
6825 int g = plm1;
6826 int *const splm1 = suff + plm1;
6827 const CHARSET_INFO *cs= cmp.cmp_collation.collation;
6828
6829 *splm1 = pattern_len;
6830
6831 if (!cs->sort_order)
6832 {
6833 int i;
6834 for (i = pattern_len - 2; i >= 0; i--)
6835 {
6836 int tmp = *(splm1 + i - f);
6837 if (g < i && tmp < i - g)
6838 suff[i] = tmp;
6839 else
6840 {
6841 if (i < g)
6842 g = i; // g = min(i, g)
6843 f = i;
6844 while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
6845 g--;
6846 suff[i] = f - g;
6847 }
6848 }
6849 }
6850 else
6851 {
6852 int i;
6853 for (i = pattern_len - 2; 0 <= i; --i)
6854 {
6855 int tmp = *(splm1 + i - f);
6856 if (g < i && tmp < i - g)
6857 suff[i] = tmp;
6858 else
6859 {
6860 if (i < g)
6861 g = i; // g = min(i, g)
6862 f = i;
6863 while (g >= 0 &&
6864 likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
6865 g--;
6866 suff[i] = f - g;
6867 }
6868 }
6869 }
6870 }
6871
6872
6873 /**
6874 Precomputation dependent only on pattern_len.
6875 */
6876
bm_compute_good_suffix_shifts(int * suff)6877 void Item_func_like::bm_compute_good_suffix_shifts(int *suff)
6878 {
6879 bm_compute_suffixes(suff);
6880
6881 int *end = bmGs + pattern_len;
6882 int *k;
6883 for (k = bmGs; k < end; k++)
6884 *k = pattern_len;
6885
6886 int tmp;
6887 int i;
6888 int j = 0;
6889 const int plm1 = pattern_len - 1;
6890 for (i = plm1; i > -1; i--)
6891 {
6892 if (suff[i] == i + 1)
6893 {
6894 for (tmp = plm1 - i; j < tmp; j++)
6895 {
6896 int *tmp2 = bmGs + j;
6897 if (*tmp2 == pattern_len)
6898 *tmp2 = tmp;
6899 }
6900 }
6901 }
6902
6903 int *tmp2;
6904 for (tmp = plm1 - i; j < tmp; j++)
6905 {
6906 tmp2 = bmGs + j;
6907 if (*tmp2 == pattern_len)
6908 *tmp2 = tmp;
6909 }
6910
6911 tmp2 = bmGs + plm1;
6912 for (i = 0; i <= pattern_len - 2; i++)
6913 *(tmp2 - suff[i]) = plm1 - i;
6914 }
6915
6916
6917 /**
6918 Precomputation dependent on pattern_len.
6919 */
6920
bm_compute_bad_character_shifts()6921 void Item_func_like::bm_compute_bad_character_shifts()
6922 {
6923 int *i;
6924 int *end = bmBc + alphabet_size;
6925 int j;
6926 const int plm1 = pattern_len - 1;
6927 const CHARSET_INFO *cs= cmp.cmp_collation.collation;
6928
6929 for (i = bmBc; i < end; i++)
6930 *i = pattern_len;
6931
6932 if (!cs->sort_order)
6933 {
6934 for (j = 0; j < plm1; j++)
6935 bmBc[(uchar) pattern[j]] = plm1 - j;
6936 }
6937 else
6938 {
6939 for (j = 0; j < plm1; j++)
6940 bmBc[likeconv(cs,pattern[j])] = plm1 - j;
6941 }
6942 }
6943
6944
6945 /**
6946 Search for pattern in text.
6947
6948 @return
6949 returns true/false for match/no match
6950 */
6951
bm_matches(const char * text,size_t text_len) const6952 bool Item_func_like::bm_matches(const char* text, size_t text_len) const
6953 {
6954 int bcShift;
6955 int shift = pattern_len;
6956 int j = 0;
6957 const CHARSET_INFO *cs= cmp.cmp_collation.collation;
6958
6959 const int plm1= pattern_len - 1;
6960 const int tlmpl= text_len - pattern_len;
6961
6962 /* Searching */
6963 if (!cs->sort_order)
6964 {
6965 while (j <= tlmpl)
6966 {
6967 int i;
6968
6969 for (i= plm1; (i >= 0) && (pattern[i] == text[i + j]) ;--i) {}
6970
6971 if (i < 0)
6972 return true;
6973 else
6974 {
6975 bcShift= bmBc[(uchar) text[i + j]] - plm1 + i;
6976 shift= max(bcShift, bmGs[i]);
6977 }
6978 j+= shift;
6979 }
6980 return false;
6981 }
6982 else
6983 {
6984 while (j <= tlmpl)
6985 {
6986 int i;
6987
6988 for (i= plm1;
6989 (i >= 0) && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]);
6990 --i) {}
6991
6992 if (i < 0)
6993 return true;
6994 else
6995 {
6996 bcShift= bmBc[likeconv(cs, text[i + j])] - plm1 + i;
6997 shift= max(bcShift, bmGs[i]);
6998 }
6999 j+= shift;
7000 }
7001 return false;
7002 }
7003 }
7004
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)7005 float Item_func_xor::get_filtering_effect(table_map filter_for_table,
7006 table_map read_tables,
7007 const MY_BITMAP *fields_to_ignore,
7008 double rows_in_table)
7009 {
7010 DBUG_ASSERT(arg_count == 2);
7011
7012 const float filter0=
7013 args[0]->get_filtering_effect(filter_for_table, read_tables,
7014 fields_to_ignore, rows_in_table);
7015 if (filter0 == COND_FILTER_ALLPASS)
7016 return COND_FILTER_ALLPASS;
7017
7018 const float filter1=
7019 args[1]->get_filtering_effect(filter_for_table, read_tables,
7020 fields_to_ignore, rows_in_table);
7021
7022 if (filter1 == COND_FILTER_ALLPASS)
7023 return COND_FILTER_ALLPASS;
7024
7025 /*
7026 Calculated as "exactly one of independent events":
7027 P(A and not B) + P(B and not A) = P(A) + P(B) - 2 * P(A) * P(B)
7028 */
7029 return filter0 + filter1 - (2 * filter0 * filter1);
7030 }
7031
7032 /**
7033 Make a logical XOR of the arguments.
7034
7035 If either operator is NULL, return NULL.
7036
7037 @todo
7038 (low priority) Change this to be optimized as: @n
7039 A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1) @n
7040 To be able to do this, we would however first have to extend the MySQL
7041 range optimizer to handle OR better.
7042
7043 @note
7044 As we don't do any index optimization on XOR this is not going to be
7045 very fast to use.
7046 */
7047
val_int()7048 longlong Item_func_xor::val_int()
7049 {
7050 DBUG_ASSERT(fixed == 1);
7051 int result= 0;
7052 null_value= false;
7053 for (uint i= 0; i < arg_count; i++)
7054 {
7055 result^= (args[i]->val_int() != 0);
7056 if (args[i]->null_value)
7057 {
7058 null_value= true;
7059 return 0;
7060 }
7061 }
7062 return result;
7063 }
7064
7065 /**
7066 Apply NOT transformation to the item and return a new one.
7067
7068
7069 Transform the item using next rules:
7070 @verbatim
7071 a AND b AND ... -> NOT(a) OR NOT(b) OR ...
7072 a OR b OR ... -> NOT(a) AND NOT(b) AND ...
7073 NOT(a) -> a
7074 a = b -> a != b
7075 a != b -> a = b
7076 a < b -> a >= b
7077 a >= b -> a < b
7078 a > b -> a <= b
7079 a <= b -> a > b
7080 IS NULL(a) -> IS NOT NULL(a)
7081 IS NOT NULL(a) -> IS NULL(a)
7082 @endverbatim
7083
7084 @param thd thread handler
7085
7086 @return
7087 New item or
7088 NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
7089 */
7090
neg_transformer(THD * thd)7091 Item *Item_func_not::neg_transformer(THD *thd) /* NOT(x) -> x */
7092 {
7093 return args[0];
7094 }
7095
7096
neg_transformer(THD * thd)7097 Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
7098 {
7099 Item *item= negated_item();
7100 return item;
7101 }
7102
7103 /**
7104 XOR can be negated by negating one of the operands:
7105
7106 NOT (a XOR b) => (NOT a) XOR b
7107 => a XOR (NOT b)
7108
7109 @param thd Thread handle
7110 @return New negated item
7111 */
neg_transformer(THD * thd)7112 Item *Item_func_xor::neg_transformer(THD *thd)
7113 {
7114 Item *neg_operand;
7115 Item_func_xor *new_item;
7116 if ((neg_operand= args[0]->neg_transformer(thd)))
7117 // args[0] has neg_tranformer
7118 new_item= new(thd->mem_root) Item_func_xor(neg_operand, args[1]);
7119 else if ((neg_operand= args[1]->neg_transformer(thd)))
7120 // args[1] has neg_tranformer
7121 new_item= new(thd->mem_root) Item_func_xor(args[0], neg_operand);
7122 else
7123 {
7124 neg_operand= new(thd->mem_root) Item_func_not(args[0]);
7125 new_item= new(thd->mem_root) Item_func_xor(neg_operand, args[1]);
7126 }
7127 return new_item;
7128 }
7129
7130
7131 /**
7132 a IS NULL -> a IS NOT NULL.
7133 */
neg_transformer(THD * thd)7134 Item *Item_func_isnull::neg_transformer(THD *thd)
7135 {
7136 Item *item= new Item_func_isnotnull(args[0]);
7137 return item;
7138 }
7139
7140
7141 /**
7142 a IS NOT NULL -> a IS NULL.
7143 */
neg_transformer(THD * thd)7144 Item *Item_func_isnotnull::neg_transformer(THD *thd)
7145 {
7146 Item *item= new Item_func_isnull(args[0]);
7147 return item;
7148 }
7149
7150
neg_transformer(THD * thd)7151 Item *Item_cond_and::neg_transformer(THD *thd) /* NOT(a AND b AND ...) -> */
7152 /* NOT a OR NOT b OR ... */
7153 {
7154 neg_arguments(thd);
7155 Item *item= new Item_cond_or(list);
7156 return item;
7157 }
7158
7159
neg_transformer(THD * thd)7160 Item *Item_cond_or::neg_transformer(THD *thd) /* NOT(a OR b OR ...) -> */
7161 /* NOT a AND NOT b AND ... */
7162 {
7163 neg_arguments(thd);
7164 Item *item= new Item_cond_and(list);
7165 return item;
7166 }
7167
7168
neg_transformer(THD * thd)7169 Item *Item_func_nop_all::neg_transformer(THD *thd)
7170 {
7171 /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
7172 Item_func_not_all *new_item= new Item_func_not_all(args[0]);
7173 Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
7174 allany->func= allany->func_creator(FALSE);
7175 allany->all= !allany->all;
7176 allany->upper_item= new_item;
7177 return new_item;
7178 }
7179
neg_transformer(THD * thd)7180 Item *Item_func_not_all::neg_transformer(THD *thd)
7181 {
7182 /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
7183 Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
7184 Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
7185 allany->all= !allany->all;
7186 allany->func= allany->func_creator(TRUE);
7187 allany->upper_item= new_item;
7188 return new_item;
7189 }
7190
negated_item()7191 Item *Item_func_eq::negated_item() /* a = b -> a != b */
7192 {
7193 return new Item_func_ne(args[0], args[1]);
7194 }
7195
7196
negated_item()7197 Item *Item_func_ne::negated_item() /* a != b -> a = b */
7198 {
7199 return new Item_func_eq(args[0], args[1]);
7200 }
7201
7202
negated_item()7203 Item *Item_func_lt::negated_item() /* a < b -> a >= b */
7204 {
7205 return new Item_func_ge(args[0], args[1]);
7206 }
7207
7208
negated_item()7209 Item *Item_func_ge::negated_item() /* a >= b -> a < b */
7210 {
7211 return new Item_func_lt(args[0], args[1]);
7212 }
7213
7214
negated_item()7215 Item *Item_func_gt::negated_item() /* a > b -> a <= b */
7216 {
7217 return new Item_func_le(args[0], args[1]);
7218 }
7219
7220
negated_item()7221 Item *Item_func_le::negated_item() /* a <= b -> a > b */
7222 {
7223 return new Item_func_gt(args[0], args[1]);
7224 }
7225
7226 /**
7227 just fake method, should never be called.
7228 */
negated_item()7229 Item *Item_bool_rowready_func2::negated_item()
7230 {
7231 DBUG_ASSERT(0);
7232 return 0;
7233 }
7234
Item_equal(Item_field * f1,Item_field * f2)7235 Item_equal::Item_equal(Item_field *f1, Item_field *f2)
7236 : Item_bool_func(), const_item(0), eval_item(0), cond_false(0),
7237 compare_as_dates(FALSE)
7238 {
7239 const_item_cache= 0;
7240 fields.push_back(f1);
7241 fields.push_back(f2);
7242 }
7243
Item_equal(Item * c,Item_field * f)7244 Item_equal::Item_equal(Item *c, Item_field *f)
7245 : Item_bool_func(), eval_item(0), cond_false(0)
7246 {
7247 const_item_cache= 0;
7248 fields.push_back(f);
7249 const_item= c;
7250 compare_as_dates= f->is_temporal_with_date();
7251 }
7252
7253
Item_equal(Item_equal * item_equal)7254 Item_equal::Item_equal(Item_equal *item_equal)
7255 : Item_bool_func(), eval_item(0), cond_false(0)
7256 {
7257 const_item_cache= 0;
7258 List_iterator_fast<Item_field> li(item_equal->fields);
7259 Item_field *item;
7260 while ((item= li++))
7261 {
7262 fields.push_back(item);
7263 }
7264 const_item= item_equal->const_item;
7265 compare_as_dates= item_equal->compare_as_dates;
7266 cond_false= item_equal->cond_false;
7267 }
7268
7269
compare_const(THD * thd,Item * c)7270 bool Item_equal::compare_const(THD *thd, Item *c)
7271 {
7272 if (compare_as_dates)
7273 {
7274 cmp.set_datetime_cmp_func(this, &c, &const_item);
7275 cond_false= cmp.compare();
7276 }
7277 else
7278 {
7279 Item_func_eq *func= new Item_func_eq(c, const_item);
7280 if (func == NULL)
7281 return true;
7282 if (func->set_cmp_func())
7283 return true;
7284 func->quick_fix_field();
7285 cond_false= !func->val_int();
7286 }
7287 if (thd->is_error())
7288 return true;
7289 if (cond_false)
7290 const_item_cache= 1;
7291 return false;
7292 }
7293
7294
add(THD * thd,Item * c,Item_field * f)7295 bool Item_equal::add(THD *thd, Item *c, Item_field *f)
7296 {
7297 if (cond_false)
7298 return false;
7299 if (!const_item)
7300 {
7301 DBUG_ASSERT(f);
7302 const_item= c;
7303 compare_as_dates= f->is_temporal_with_date();
7304 return false;
7305 }
7306 return compare_const(thd, c);
7307 }
7308
7309
add(THD * thd,Item * c)7310 bool Item_equal::add(THD *thd, Item *c)
7311 {
7312 if (cond_false)
7313 return false;
7314 if (!const_item)
7315 {
7316 const_item= c;
7317 return false;
7318 }
7319 return compare_const(thd, c);
7320 }
7321
add(Item_field * f)7322 void Item_equal::add(Item_field *f)
7323 {
7324 fields.push_back(f);
7325 }
7326
members()7327 uint Item_equal::members()
7328 {
7329 return fields.elements;
7330 }
7331
7332
7333 /**
7334 Check whether a field is referred in the multiple equality.
7335
7336 The function checks whether field is occurred in the Item_equal object .
7337
7338 @param field field whose occurrence is to be checked
7339
7340 @retval
7341 1 if nultiple equality contains a reference to field
7342 @retval
7343 0 otherwise
7344 */
7345
contains(Field * field)7346 bool Item_equal::contains(Field *field)
7347 {
7348 List_iterator_fast<Item_field> it(fields);
7349 Item_field *item;
7350 while ((item= it++))
7351 {
7352 if (field->eq(item->field))
7353 return 1;
7354 }
7355 return 0;
7356 }
7357
7358
7359 /**
7360 Join members of another Item_equal object.
7361
7362 The function actually merges two multiple equalities.
7363 After this operation the Item_equal object additionally contains
7364 the field items of another item of the type Item_equal.
7365 If the optional constant items are not equal the cond_false flag is
7366 set to 1.
7367
7368 @param thd thread handler
7369 @param item multiple equality whose members are to be joined
7370
7371 @returns false if success, true if error
7372 */
7373
merge(THD * thd,Item_equal * item)7374 bool Item_equal::merge(THD *thd, Item_equal *item)
7375 {
7376 fields.concat(&item->fields);
7377 Item *c= item->const_item;
7378 if (c)
7379 {
7380 /*
7381 The flag cond_false will be set to 1 after this, if
7382 the multiple equality already contains a constant and its
7383 value is not equal to the value of c.
7384 */
7385 if (add(thd, c))
7386 return true;
7387 }
7388 cond_false|= item->cond_false;
7389 return false;
7390 }
7391
7392
7393 /**
7394 Order field items in multiple equality according to a sorting criteria.
7395
7396 The function perform ordering of the field items in the Item_equal
7397 object according to the criteria determined by the cmp callback parameter.
7398 If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
7399 placed after item_fiel2.
7400
7401 The function sorts field items by the exchange sort algorithm.
7402 The list of field items is looked through and whenever two neighboring
7403 members follow in a wrong order they are swapped. This is performed
7404 again and again until we get all members in a right order.
7405
7406 @param compare function to compare field item
7407 @param arg context extra parameter for the cmp function
7408 */
7409
sort(Item_field_cmpfunc compare,void * arg)7410 void Item_equal::sort(Item_field_cmpfunc compare, void *arg)
7411 {
7412 fields.sort((Node_cmp_func)compare, arg);
7413 }
7414
7415
7416 /**
7417 Check appearance of new constant items in the multiple equality object.
7418
7419 The function checks appearance of new constant items among
7420 the members of multiple equalities. Each new constant item is
7421 compared with the designated constant item if there is any in the
7422 multiple equality. If there is none the first new constant item
7423 becomes designated.
7424
7425 @param thd thread handler
7426
7427 @returns false if success, true if error
7428 */
7429
update_const(THD * thd)7430 bool Item_equal::update_const(THD *thd)
7431 {
7432 List_iterator<Item_field> it(fields);
7433 Item *item;
7434 while ((item= it++))
7435 {
7436 if (item->const_item() &&
7437 /*
7438 Don't propagate constant status of outer-joined column.
7439 Such a constant status here is a result of:
7440 a) empty outer-joined table: in this case such a column has a
7441 value of NULL; but at the same time other arguments of
7442 Item_equal don't have to be NULLs and the value of the whole
7443 multiple equivalence expression doesn't have to be NULL or FALSE
7444 because of the outer join nature;
7445 or
7446 b) outer-joined table contains only 1 row: the result of
7447 this column is equal to a row field value *or* NULL.
7448 Both values are inacceptable as Item_equal constants.
7449 */
7450 !item->is_outer_field())
7451 {
7452 it.remove();
7453 if (add(thd, item))
7454 return true;
7455 }
7456 }
7457 return false;
7458 }
7459
fix_fields(THD * thd,Item ** ref)7460 bool Item_equal::fix_fields(THD *thd, Item **ref)
7461 {
7462 List_iterator_fast<Item_field> li(fields);
7463 Item *item;
7464 not_null_tables_cache= used_tables_cache= 0;
7465 const_item_cache= 0;
7466 while ((item= li++))
7467 {
7468 used_tables_cache|= item->used_tables();
7469 not_null_tables_cache|= item->not_null_tables();
7470 maybe_null|= item->maybe_null;
7471 }
7472 fix_length_and_dec();
7473 fixed= 1;
7474 return 0;
7475 }
7476
7477 /**
7478 Get filtering effect for multiple equalities, i.e.
7479 "tx.col = value_1 = ... = value_n" where value_i may be a
7480 constant, a column etc.
7481
7482 The multiple equality only contributes to the filtering effect for
7483 'filter_for_table' if
7484 a) A column in 'filter_for_table' is referred to
7485 b) at least one value_i is a constant or a column in a table
7486 already read
7487
7488 If this multiple equality refers to more than one column in
7489 'filter_for_table', the predicates on all these fields will
7490 contribute to the filtering effect.
7491 */
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)7492 float Item_equal::get_filtering_effect(table_map filter_for_table,
7493 table_map read_tables,
7494 const MY_BITMAP *fields_to_ignore,
7495 double rows_in_table)
7496 {
7497 // This predicate does not refer to a column in 'filter_for_table'
7498 if (!(used_tables() & filter_for_table))
7499 return COND_FILTER_ALLPASS;
7500
7501 float filter= COND_FILTER_ALLPASS;
7502 /*
7503 Keep track of whether or not a usable value that is either a
7504 constant or a column in an already read table has been found.
7505 */
7506 bool found_comparable= false;
7507
7508 // Is there a constant that this multiple equality is equal to?
7509 if (const_item)
7510 found_comparable= true;
7511
7512 List_iterator<Item_field> it(fields);
7513
7514 Item_field *cur_field;
7515 /*
7516 Calculate filtering effect for all applicable fields. If this
7517 item has multiple fields from 'filter_for_table', each of these
7518 fields will contribute to the filtering effect.
7519 */
7520 while ((cur_field= it++))
7521 {
7522 if (cur_field->used_tables() & read_tables)
7523 {
7524 // cur_field is a field in a table earlier in the join sequence.
7525 found_comparable= true;
7526 }
7527 else if (cur_field->used_tables() == filter_for_table)
7528 {
7529 if (bitmap_is_set(fields_to_ignore, cur_field->field->field_index))
7530 {
7531 /*
7532 cur_field is a field in 'filter_for_table', but it is a
7533 field which already contributes to the filtering effect.
7534 Its value can still be used as a constant if another column
7535 in the same table is referred to in this multiple equality.
7536 */
7537 found_comparable= true;
7538 }
7539 else
7540 {
7541 /*
7542 cur_field is a field in 'filter_for_table', and it's not one
7543 of the fields that must be ignored
7544 */
7545 float cur_filter=
7546 cur_field->get_cond_filter_default_probability(rows_in_table,
7547 COND_FILTER_EQUALITY);
7548
7549 // Use index statistics if available for this field
7550 if (!cur_field->field->key_start.is_clear_all())
7551 {
7552 // cur_field is indexed - there may be statistics for it.
7553 const TABLE *tab= cur_field->field->table;
7554
7555 for (uint j= 0; j < tab->s->keys; j++)
7556 {
7557 if (cur_field->field->key_start.is_set(j) &&
7558 tab->key_info[j].has_records_per_key(0))
7559 {
7560 cur_filter= static_cast<float>(tab->key_info[j].records_per_key(0) / rows_in_table);
7561 break;
7562 }
7563 }
7564 /*
7565 Since rec_per_key and rows_per_table are calculated at
7566 different times, their values may not be in synch and thus
7567 it is possible that cur_filter is greater than 1.0 if
7568 rec_per_key is outdated. Force the filter to 1.0 in such
7569 cases.
7570 */
7571 if (cur_filter >= 1.0)
7572 cur_filter= 1.0f;
7573 }
7574
7575 filter*= cur_filter;
7576 }
7577 }
7578 }
7579 return found_comparable ? filter : COND_FILTER_ALLPASS;
7580 }
7581
update_used_tables()7582 void Item_equal::update_used_tables()
7583 {
7584 List_iterator_fast<Item_field> li(fields);
7585 Item *item;
7586 not_null_tables_cache= used_tables_cache= 0;
7587 if ((const_item_cache= cond_false))
7588 return;
7589 with_subselect= false;
7590 with_stored_program= false;
7591 while ((item=li++))
7592 {
7593 item->update_used_tables();
7594 used_tables_cache|= item->used_tables();
7595 not_null_tables_cache|= item->not_null_tables();
7596 /* see commentary at Item_equal::update_const() */
7597 const_item_cache&= item->const_item() && !item->is_outer_field();
7598 with_subselect|= item->has_subquery();
7599 with_stored_program|= item->has_stored_program();
7600 }
7601 }
7602
val_int()7603 longlong Item_equal::val_int()
7604 {
7605 Item_field *item_field;
7606 if (cond_false)
7607 return 0;
7608 List_iterator_fast<Item_field> it(fields);
7609 Item *item= const_item ? const_item : it++;
7610 eval_item->store_value(item);
7611 if ((null_value= item->null_value))
7612 return 0;
7613 while ((item_field= it++))
7614 {
7615 /* Skip fields of non-const tables. They haven't been read yet */
7616 if (item_field->field->table->const_table)
7617 {
7618 const int rc= eval_item->cmp(item_field);
7619 if ((rc == TRUE) || (null_value= (rc == UNKNOWN)))
7620 return 0;
7621 }
7622 }
7623 return 1;
7624 }
7625
fix_length_and_dec()7626 void Item_equal::fix_length_and_dec()
7627 {
7628 Item *item= get_first();
7629 eval_item= cmp_item::get_comparator(item->result_type(), item,
7630 item->collation.collation);
7631 }
7632
walk(Item_processor processor,enum_walk walk,uchar * arg)7633 bool Item_equal::walk(Item_processor processor, enum_walk walk, uchar *arg)
7634 {
7635 if ((walk & WALK_PREFIX) && (this->*processor)(arg))
7636 return true;
7637
7638 List_iterator_fast<Item_field> it(fields);
7639 Item *item;
7640 while ((item= it++))
7641 {
7642 if (item->walk(processor, walk, arg))
7643 return true;
7644 }
7645
7646 return (walk & WALK_POSTFIX) && (this->*processor)(arg);
7647 }
7648
transform(Item_transformer transformer,uchar * arg)7649 Item *Item_equal::transform(Item_transformer transformer, uchar *arg)
7650 {
7651 DBUG_ASSERT(!current_thd->stmt_arena->is_stmt_prepare());
7652
7653 List_iterator<Item_field> it(fields);
7654 Item *item;
7655 while ((item= it++))
7656 {
7657 Item *new_item= item->transform(transformer, arg);
7658 if (!new_item)
7659 return 0;
7660
7661 /*
7662 THD::change_item_tree() should be called only if the tree was
7663 really transformed, i.e. when a new item has been created.
7664 Otherwise we'll be allocating a lot of unnecessary memory for
7665 change records at each execution.
7666 */
7667 if (new_item != item)
7668 current_thd->change_item_tree((Item **) it.ref(), new_item);
7669 }
7670 return Item_func::transform(transformer, arg);
7671 }
7672
print(String * str,enum_query_type query_type)7673 void Item_equal::print(String *str, enum_query_type query_type)
7674 {
7675 str->append(func_name());
7676 str->append('(');
7677 List_iterator_fast<Item_field> it(fields);
7678 Item *item;
7679 if (const_item)
7680 const_item->print(str, query_type);
7681 else
7682 {
7683 item= it++;
7684 item->print(str, query_type);
7685 }
7686 while ((item= it++))
7687 {
7688 str->append(',');
7689 str->append(' ');
7690 item->print(str, query_type);
7691 }
7692 str->append(')');
7693 }
7694
7695
val_int()7696 longlong Item_func_trig_cond::val_int()
7697 {
7698 if (trig_var == NULL)
7699 {
7700 DBUG_ASSERT(m_join != NULL && m_idx >= 0);
7701 switch(trig_type)
7702 {
7703 case IS_NOT_NULL_COMPL:
7704 trig_var= &m_join->qep_tab[m_idx].not_null_compl;
7705 break;
7706 case FOUND_MATCH:
7707 trig_var= &m_join->qep_tab[m_idx].found;
7708 break;
7709 default:
7710 DBUG_ASSERT(false); /* purecov: inspected */
7711 return 0;
7712 }
7713 }
7714 return *trig_var ? args[0]->val_int() : 1;
7715 }
7716
print(String * str,enum_query_type query_type)7717 void Item_func_trig_cond::print(String *str, enum_query_type query_type)
7718 {
7719 /*
7720 Print:
7721 <if>(<property><(optional list of source tables)>, condition, TRUE)
7722 which means: if a certain property (<property>) is true, then return
7723 the value of <condition>, else return TRUE. If source tables are
7724 present, they are the owner of the property.
7725 */
7726 str->append(func_name());
7727 str->append("(");
7728 switch(trig_type)
7729 {
7730 case IS_NOT_NULL_COMPL:
7731 str->append("is_not_null_compl");
7732 break;
7733 case FOUND_MATCH:
7734 str->append("found_match");
7735 break;
7736 case OUTER_FIELD_IS_NOT_NULL:
7737 str->append("outer_field_is_not_null");
7738 break;
7739 default:
7740 DBUG_ASSERT(0);
7741 }
7742 if (m_join != NULL)
7743 {
7744 /*
7745 Item printing is done at various stages of optimization, so there can
7746 be a JOIN_TAB or a QEP_TAB.
7747 */
7748 TABLE *table, *last_inner_table;
7749 plan_idx last_inner;
7750 if (m_join->qep_tab)
7751 {
7752 QEP_TAB *qep_tab= &m_join->qep_tab[m_idx];
7753 table= qep_tab->table();
7754 last_inner= qep_tab->last_inner();
7755 last_inner_table= m_join->qep_tab[last_inner].table();
7756 }
7757 else
7758 {
7759 JOIN_TAB *join_tab= m_join->best_ref[m_idx];
7760 table= join_tab->table();
7761 last_inner= join_tab->last_inner();
7762 last_inner_table= m_join->best_ref[last_inner]->table();
7763 }
7764 str->append("(");
7765 str->append(table->alias);
7766 if (last_inner != m_idx)
7767 {
7768 /* case of t1 LEFT JOIN (t2,t3,...): print range of inner tables */
7769 str->append("..");
7770 str->append(last_inner_table->alias);
7771 }
7772 str->append(")");
7773 }
7774 str->append(", ");
7775 args[0]->print(str, query_type);
7776 str->append(", true)");
7777 }
7778
7779
7780 /**
7781 Get item that can be substituted for the supplied item.
7782
7783 @param field field item to get substitution field for, which must be
7784 present within the multiple equality itself.
7785
7786 @retval Found substitution item in the multiple equality.
7787
7788 @details Get the first item of multiple equality that can be substituted
7789 for the given field item. In order to make semijoin materialization strategy
7790 work correctly we can't propagate equal fields between a materialized
7791 semijoin and the outer query (or any other semijoin) unconditionally.
7792 Thus the field is returned according to the following rules:
7793
7794 1) If the given field belongs to a materialized semijoin then the
7795 first field in the multiple equality which belongs to the same semijoin
7796 is returned.
7797 2) If the given field doesn't belong to a materialized semijoin then
7798 the first field in the multiple equality is returned.
7799 */
7800
get_subst_item(const Item_field * field)7801 Item_field* Item_equal::get_subst_item(const Item_field *field)
7802 {
7803 DBUG_ASSERT(field != NULL);
7804
7805 const JOIN_TAB *field_tab= field->field->table->reginfo.join_tab;
7806
7807 /*
7808 field_tab is NULL if this function was not called from
7809 JOIN::optimize() but from e.g. mysql_delete() or mysql_update().
7810 In these cases there is only one table and no semijoin
7811 */
7812 if (field_tab &&
7813 sj_is_materialize_strategy(field_tab->get_sj_strategy()))
7814 {
7815 /*
7816 It's a field from a materialized semijoin. We can substitute it only
7817 with a field from the same semijoin.
7818
7819 Example: suppose we have a join_tab order:
7820
7821 ot1 ot2 <subquery> ot3 SJM(it1 it2 it3)
7822
7823 <subquery> is the temporary table that is materialized from the join
7824 of it1, it2 and it3.
7825
7826 and equality ot2.col = <subquery>.col = it1.col = it2.col
7827
7828 If we're looking for best substitute for 'it2.col', we must pick it1.col
7829 and not ot2.col. it2.col is evaluated while performing materialization,
7830 when the outer tables are not available in the execution.
7831
7832 Note that subquery materialization does not have the same problem:
7833 even though IN->EXISTS has injected equalities involving outer query's
7834 expressions, it has wrapped those expressions in variants of Item_ref,
7835 never Item_field, so they can be part of an Item_equal only if they are
7836 constant (in which case there is no problem with choosing them below);
7837 @see check_simple_equality().
7838 */
7839 List_iterator<Item_field> it(fields);
7840 Item_field *item;
7841 plan_idx first= field_tab->first_sj_inner(), last= field_tab->last_sj_inner();
7842
7843 while ((item= it++))
7844 {
7845 plan_idx idx= item->field->table->reginfo.join_tab->idx();
7846 if (idx >= first && idx <= last)
7847 return item;
7848 }
7849 }
7850 else
7851 {
7852 /*
7853 The field is not in a materialized semijoin nest. We can return
7854 the first field in the multiple equality.
7855
7856 Example: suppose we have a join_tab order with MaterializeLookup:
7857
7858 ot1 ot2 <subquery> SJM(it1 it2)
7859
7860 Here we should always pick the first field in the multiple equality,
7861 as this will be present before all other dependent fields.
7862
7863 Example: suppose we have a join_tab order with MaterializeScan:
7864
7865 <subquery> ot1 ot2 SJM(it1 it2)
7866
7867 and equality <subquery>.col = ot2.col = ot1.col = it2.col.
7868
7869 When looking for best substitute for ot2.col, we should pick
7870 <subquery>.col, because column values from the inner materialized tables
7871 are copied to the temporary table <subquery>, and when we run the scan,
7872 field values are read into this table's field buffers.
7873 */
7874 return fields.head();
7875 }
7876 DBUG_ASSERT(FALSE); // Should never get here.
7877 return NULL;
7878 }
7879
7880 /**
7881 Transform an Item_equal object after having added a table that
7882 represents a materialized semi-join.
7883
7884 @details
7885 If the multiple equality represented by the Item_equal object contains
7886 a field from the subquery that was used to create the materialized table,
7887 add the corresponding key field from the materialized table to the
7888 multiple equality.
7889 @see JOIN::update_equalities_for_sjm() for the reason.
7890 */
7891
equality_substitution_transformer(uchar * arg)7892 Item* Item_equal::equality_substitution_transformer(uchar *arg)
7893 {
7894 TABLE_LIST *sj_nest= reinterpret_cast<TABLE_LIST *>(arg);
7895 List_iterator<Item_field> it(fields);
7896 List<Item_field> added_fields;
7897 Item_field *item;
7898 // Iterate over the fields in the multiple equality
7899 while ((item= it++))
7900 {
7901 // Skip fields that do not come from materialized subqueries
7902 const JOIN_TAB *tab= item->field->table->reginfo.join_tab;
7903 if (!tab || !sj_is_materialize_strategy(tab->get_sj_strategy()))
7904 continue;
7905
7906 // Iterate over the fields selected from the subquery
7907 List_iterator<Item> mit(sj_nest->nested_join->sj_inner_exprs);
7908 Item *existing;
7909 uint fieldno= 0;
7910 while ((existing= mit++))
7911 {
7912 if (existing->real_item()->eq(item, false))
7913 added_fields.push_back(sj_nest->nested_join->sjm.mat_fields[fieldno]);
7914 fieldno++;
7915 }
7916 }
7917 fields.concat(&added_fields);
7918
7919 return this;
7920 }
7921
7922 /**
7923 Replace arg of Item_func_eq object after having added a table that
7924 represents a materialized semi-join.
7925
7926 @details
7927 The right argument of an injected semi-join equality (which comes from
7928 the select list of the subquery) is replaced with the corresponding
7929 column from the materialized temporary table, if the left and right
7930 arguments are not from the same semi-join nest.
7931 @see JOIN::update_equalities_for_sjm() for why this is needed.
7932 */
equality_substitution_transformer(uchar * arg)7933 Item* Item_func_eq::equality_substitution_transformer(uchar *arg)
7934 {
7935 TABLE_LIST *sj_nest= reinterpret_cast<TABLE_LIST *>(arg);
7936
7937 // Iterate over the fields selected from the subquery
7938 List_iterator<Item> mit(sj_nest->nested_join->sj_inner_exprs);
7939 Item *existing;
7940 uint fieldno= 0;
7941 while ((existing= mit++))
7942 {
7943 if (existing->real_item()->eq(args[1], false) &&
7944 (args[0]->used_tables() & ~sj_nest->sj_inner_tables))
7945 current_thd->change_item_tree(args+1,
7946 sj_nest->nested_join->sjm.mat_fields[fieldno]);
7947 fieldno++;
7948 }
7949 return this;
7950 }
7951
get_filtering_effect(table_map filter_for_table,table_map read_tables,const MY_BITMAP * fields_to_ignore,double rows_in_table)7952 float Item_func_eq::get_filtering_effect(table_map filter_for_table,
7953 table_map read_tables,
7954 const MY_BITMAP *fields_to_ignore,
7955 double rows_in_table)
7956 {
7957 const Item_field* fld=
7958 contributes_to_filter(read_tables, filter_for_table, fields_to_ignore);
7959 if (!fld)
7960 return COND_FILTER_ALLPASS;
7961
7962 return fld->get_cond_filter_default_probability(rows_in_table,
7963 COND_FILTER_EQUALITY);
7964 }
7965
7966
aggregate_check_group(uchar * arg)7967 bool Item_func_any_value::aggregate_check_group(uchar *arg)
7968 {
7969 Group_check *gc= reinterpret_cast<Group_check *>(arg);
7970 if (gc->is_stopped(this))
7971 return false;
7972 gc->stop_at(this);
7973 return false;
7974 }
7975
7976
aggregate_check_distinct(uchar * arg)7977 bool Item_func_any_value::aggregate_check_distinct(uchar *arg)
7978 {
7979 Distinct_check *dc= reinterpret_cast<Distinct_check *>(arg);
7980 if (dc->is_stopped(this))
7981 return false;
7982 dc->stop_at(this);
7983 return false;
7984 }
7985