1 #ifndef ITEM_CMPFUNC_INCLUDED
2 #define ITEM_CMPFUNC_INCLUDED
3
4 /* Copyright (c) 2000, 2021, Oracle and/or its affiliates.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License, version 2.0,
8 as published by the Free Software Foundation.
9
10 This program is also distributed with certain software (including
11 but not limited to OpenSSL) that is licensed under separate terms,
12 as designated in a particular file or component or in included license
13 documentation. The authors of MySQL hereby grant you an additional
14 permission to link the program and your derivative works with the
15 separately licensed software that they have included with MySQL.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License, version 2.0, for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
25
26
27 /* compare and test functions */
28
29 #include "mem_root_array.h" // Mem_root_array
30 #include "my_regex.h" // my_regex_t
31 #include "item_func.h" // Item_int_func
32 #include "item_row.h" // Item_row
33 #include "template_utils.h" // down_cast
34
35 class Arg_comparator;
36 class Item_sum_hybrid;
37 class Item_row;
38 struct Json_scalar_holder;
39
40 typedef int (Arg_comparator::*arg_cmp_func)();
41
42 typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
43
44 class Arg_comparator: public Sql_alloc
45 {
46 Item **a, **b;
47 arg_cmp_func func;
48 Item_result_field *owner;
49 Arg_comparator *comparators; // used only for compare_row()
50 uint16 comparator_count;
51 double precision;
52 /* Fields used in DATE/DATETIME comparison. */
53 Item *a_cache, *b_cache; // Cached values of a and b items
54 bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
55 bool set_null; // TRUE <=> set owner->null_value
56 // when one of arguments is NULL.
57 longlong (*get_value_a_func)(THD *thd, Item ***item_arg, Item **cache_arg,
58 const Item *warn_item, bool *is_null);
59 longlong (*get_value_b_func)(THD *thd, Item ***item_arg, Item **cache_arg,
60 const Item *warn_item, bool *is_null);
61 bool try_year_cmp_func(Item_result type);
62 static bool get_date_from_const(Item *date_arg, Item *str_arg,
63 ulonglong *value);
64 /**
65 Only used by compare_json() in the case where a JSON value is
66 compared to an SQL value. This member points to pre-allocated
67 memory that can be used instead of the heap when converting the
68 SQL value to a JSON value.
69 */
70 Json_scalar_holder *json_scalar;
71 public:
72 DTCollation cmp_collation;
73 /* Allow owner function to use string buffers. */
74 String value1, value2;
75
Arg_comparator()76 Arg_comparator(): comparators(0), comparator_count(0),
77 a_cache(0), b_cache(0), set_null(TRUE),
78 get_value_a_func(0), get_value_b_func(0), json_scalar(0)
79 {}
Arg_comparator(Item ** a1,Item ** a2)80 Arg_comparator(Item **a1, Item **a2): a(a1), b(a2),
81 comparators(0), comparator_count(0),
82 a_cache(0), b_cache(0), set_null(TRUE),
83 get_value_a_func(0), get_value_b_func(0), json_scalar(0)
84 {}
85
86 int set_compare_func(Item_result_field *owner, Item_result type);
set_compare_func(Item_result_field * owner_arg)87 inline int set_compare_func(Item_result_field *owner_arg)
88 {
89 return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
90 (*b)->result_type()));
91 }
92 int set_cmp_func(Item_result_field *owner_arg,
93 Item **a1, Item **a2,
94 Item_result type);
95
96 int set_cmp_func(Item_result_field *owner_arg,
97 Item **a1, Item **a2, bool set_null_arg);
98
compare()99 inline int compare() { return (this->*func)(); }
100
101 int compare_string(); // compare args[0] & args[1]
102 int compare_binary_string(); // compare args[0] & args[1]
103 int compare_real(); // compare args[0] & args[1]
104 int compare_decimal(); // compare args[0] & args[1]
105 int compare_int_signed(); // compare args[0] & args[1]
106 int compare_int_signed_unsigned();
107 int compare_int_unsigned_signed();
108 int compare_int_unsigned();
109 int compare_time_packed();
110 int compare_e_time_packed();
111 int compare_row(); // compare args[0] & args[1]
112 int compare_e_string(); // compare args[0] & args[1]
113 int compare_e_binary_string(); // compare args[0] & args[1]
114 int compare_e_real(); // compare args[0] & args[1]
115 int compare_e_decimal(); // compare args[0] & args[1]
116 int compare_e_int(); // compare args[0] & args[1]
117 int compare_e_int_diff_signedness();
118 int compare_e_row(); // compare args[0] & args[1]
119 int compare_real_fixed();
120 int compare_e_real_fixed();
121 int compare_datetime(); // compare args[0] & args[1] as DATETIMEs
122 int compare_json();
123
124 static bool can_compare_as_dates(Item *a, Item *b, ulonglong *const_val_arg);
125
126 Item** cache_converted_constant(THD *thd, Item **value, Item **cache,
127 Item_result type);
128 void set_datetime_cmp_func(Item_result_field *owner_arg, Item **a1, Item **b1);
129 static arg_cmp_func comparator_matrix [5][2];
is_owner_equal_func()130 inline bool is_owner_equal_func()
131 {
132 return (owner->type() == Item::FUNC_ITEM &&
133 ((Item_func*)owner)->functype() == Item_func::EQUAL_FUNC);
134 }
135 void cleanup();
136 /*
137 Set correct cmp_context if items would be compared as INTs.
138 */
set_cmp_context_for_datetime()139 inline void set_cmp_context_for_datetime()
140 {
141 assert(func == &Arg_comparator::compare_datetime);
142 if ((*a)->is_temporal())
143 (*a)->cmp_context= INT_RESULT;
144 if ((*b)->is_temporal())
145 (*b)->cmp_context= INT_RESULT;
146 }
147 friend class Item_func;
148 };
149
150 class Item_bool_func :public Item_int_func
151 {
152 public:
Item_bool_func()153 Item_bool_func() : Item_int_func(), m_created_by_in2exists(false) {}
Item_bool_func(const POS & pos)154 explicit Item_bool_func(const POS &pos)
155 : Item_int_func(pos), m_created_by_in2exists(false)
156 {}
157
Item_bool_func(Item * a)158 Item_bool_func(Item *a) : Item_int_func(a),
159 m_created_by_in2exists(false) {}
Item_bool_func(const POS & pos,Item * a)160 Item_bool_func(const POS &pos, Item *a) : Item_int_func(pos, a),
161 m_created_by_in2exists(false) {}
162
Item_bool_func(Item * a,Item * b)163 Item_bool_func(Item *a,Item *b) : Item_int_func(a,b),
164 m_created_by_in2exists(false) {}
Item_bool_func(const POS & pos,Item * a,Item * b)165 Item_bool_func(const POS &pos, Item *a,Item *b) : Item_int_func(pos, a,b),
166 m_created_by_in2exists(false) {}
167
Item_bool_func(THD * thd,Item_bool_func * item)168 Item_bool_func(THD *thd, Item_bool_func *item) : Item_int_func(thd, item),
169 m_created_by_in2exists(item->m_created_by_in2exists) {}
is_bool_func()170 bool is_bool_func() { return 1; }
fix_length_and_dec()171 void fix_length_and_dec() { decimals=0; max_length=1; }
decimal_precision()172 uint decimal_precision() const { return 1; }
created_by_in2exists()173 virtual bool created_by_in2exists() const { return m_created_by_in2exists; }
set_created_by_in2exists()174 void set_created_by_in2exists() { m_created_by_in2exists= true; }
175 private:
176 /**
177 True <=> this item was added by IN->EXISTS subquery transformation, and
178 should thus be deleted if we switch to materialization.
179 */
180 bool m_created_by_in2exists;
181 };
182
183
184 /**
185 Abstract Item class, to represent <code>X IS [NOT] (TRUE | FALSE)</code>
186 boolean predicates.
187 */
188
189 class Item_func_truth : public Item_bool_func
190 {
191 public:
192 virtual bool val_bool();
193 virtual longlong val_int();
194 virtual void fix_length_and_dec();
195 virtual void print(String *str, enum_query_type query_type);
196
197 protected:
Item_func_truth(const POS & pos,Item * a,bool a_value,bool a_affirmative)198 Item_func_truth(const POS &pos, Item *a, bool a_value, bool a_affirmative)
199 : Item_bool_func(pos, a), value(a_value), affirmative(a_affirmative)
200 {}
201
~Item_func_truth()202 ~Item_func_truth()
203 {}
204 private:
205 /**
206 True for <code>X IS [NOT] TRUE</code>,
207 false for <code>X IS [NOT] FALSE</code> predicates.
208 */
209 const bool value;
210 /**
211 True for <code>X IS Y</code>, false for <code>X IS NOT Y</code> predicates.
212 */
213 const bool affirmative;
214 };
215
216
217 /**
218 This Item represents a <code>X IS TRUE</code> boolean predicate.
219 */
220
221 class Item_func_istrue : public Item_func_truth
222 {
223 public:
Item_func_istrue(const POS & pos,Item * a)224 Item_func_istrue(const POS &pos, Item *a)
225 : Item_func_truth(pos, a, true, true)
226 {}
~Item_func_istrue()227 ~Item_func_istrue() {}
func_name()228 virtual const char* func_name() const { return "istrue"; }
229 };
230
231
232 /**
233 This Item represents a <code>X IS NOT TRUE</code> boolean predicate.
234 */
235
236 class Item_func_isnottrue : public Item_func_truth
237 {
238 public:
Item_func_isnottrue(const POS & pos,Item * a)239 Item_func_isnottrue(const POS &pos, Item *a)
240 : Item_func_truth(pos, a, true, false)
241 {}
~Item_func_isnottrue()242 ~Item_func_isnottrue() {}
func_name()243 virtual const char* func_name() const { return "isnottrue"; }
244 };
245
246
247 /**
248 This Item represents a <code>X IS FALSE</code> boolean predicate.
249 */
250
251 class Item_func_isfalse : public Item_func_truth
252 {
253 public:
Item_func_isfalse(const POS & pos,Item * a)254 Item_func_isfalse(const POS &pos, Item *a)
255 : Item_func_truth(pos, a, false, true)
256 {}
~Item_func_isfalse()257 ~Item_func_isfalse() {}
func_name()258 virtual const char* func_name() const { return "isfalse"; }
259 };
260
261
262 /**
263 This Item represents a <code>X IS NOT FALSE</code> boolean predicate.
264 */
265
266 class Item_func_isnotfalse : public Item_func_truth
267 {
268 public:
Item_func_isnotfalse(const POS & pos,Item * a)269 Item_func_isnotfalse(const POS &pos, Item *a)
270 : Item_func_truth(pos, a, false, false)
271 {}
~Item_func_isnotfalse()272 ~Item_func_isnotfalse() {}
func_name()273 virtual const char* func_name() const { return "isnotfalse"; }
274 };
275
276
277 class Item_cache;
278 #define UNKNOWN ((my_bool)-1)
279
280
281 /*
282 Item_in_optimizer(left_expr, Item_in_subselect(...))
283
284 Item_in_optimizer is used to wrap an instance of Item_in_subselect. This
285 class does the following:
286 - Evaluate the left expression and store it in Item_cache_* object (to
287 avoid re-evaluating it many times during subquery execution)
288 - Shortcut the evaluation of "NULL IN (...)" to NULL in the cases where we
289 don't care if the result is NULL or FALSE.
290
291 args[1] keeps a reference to the Item_in_subselect object.
292
293 args[0] is a copy of Item_in_subselect's left expression and should be
294 kept equal also after resolving.
295
296 NOTE
297 It is not quite clear why the above listed functionality should be
298 placed into a separate class called 'Item_in_optimizer'.
299 */
300
301 class Item_in_optimizer: public Item_bool_func
302 {
303 private:
304 Item_cache *cache;
305 bool save_cache;
306 /*
307 Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
308 UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
309 FALSE - result is FALSE
310 TRUE - result is NULL
311 */
312 my_bool result_for_null_param;
313 public:
Item_in_optimizer(Item * a,Item_in_subselect * b)314 Item_in_optimizer(Item *a, Item_in_subselect *b):
315 Item_bool_func(a, reinterpret_cast<Item *>(b)), cache(0),
316 save_cache(0), result_for_null_param(UNKNOWN)
317 { with_subselect= TRUE; }
318 bool fix_fields(THD *, Item **);
319 bool fix_left(THD *thd, Item **ref);
320 void fix_after_pullout(st_select_lex *parent_select,
321 st_select_lex *removed_select);
322 bool is_null();
323 longlong val_int();
324 void cleanup();
func_name()325 const char *func_name() const { return "<in_optimizer>"; }
get_cache()326 Item_cache **get_cache() { return &cache; }
327 void keep_top_level_cache();
328 Item *transform(Item_transformer transformer, uchar *arg);
329 void replace_argument(THD *thd, Item **oldpp, Item *newp);
330 };
331
332 /// Abstract factory interface for creating comparison predicates.
333 class Comp_creator
334 {
335 public:
~Comp_creator()336 virtual ~Comp_creator() {}
337 virtual Item_bool_func* create(Item *a, Item *b) const = 0;
338
339 /// This interface is only used by Item_allany_subselect.
340 virtual const char* symbol(bool invert) const = 0;
341 virtual bool eqne_op() const = 0;
342 virtual bool l_op() const = 0;
343 };
344
345 /// Abstract base class for the comparison operators =, <> and <=>.
346 class Linear_comp_creator :public Comp_creator
347 {
348 public:
349 virtual Item_bool_func *create(Item *a, Item *b) const;
eqne_op()350 virtual bool eqne_op() const { return true; }
l_op()351 virtual bool l_op() const { return false; }
352
353 protected:
354 /**
355 Creates only an item tree node, without attempting to rewrite row
356 constructors.
357 @see create()
358 */
359 virtual Item_bool_func *create_scalar_predicate(Item *a, Item *b) const = 0;
360
361 /// Combines a list of conditions <code>exp op exp</code>.
362 virtual Item_bool_func *combine(List<Item> list) const = 0;
363 };
364
365 class Eq_creator :public Linear_comp_creator
366 {
367 public:
symbol(bool invert)368 virtual const char* symbol(bool invert) const { return invert ? "<>" : "="; }
369
370 protected:
371 virtual Item_bool_func *create_scalar_predicate(Item *a, Item *b) const;
372 virtual Item_bool_func *combine(List<Item> list) const;
373 };
374
375 class Equal_creator :public Linear_comp_creator
376 {
377 public:
symbol(bool invert)378 virtual const char* symbol(bool invert) const
379 {
380 // This will never be called with true.
381 assert(!invert);
382 return "<=>";
383 }
384
385 protected:
386 virtual Item_bool_func *create_scalar_predicate(Item *a, Item *b) const;
387 virtual Item_bool_func *combine(List<Item> list) const;
388 };
389
390 class Ne_creator :public Linear_comp_creator
391 {
392 public:
symbol(bool invert)393 virtual const char* symbol(bool invert) const { return invert ? "=" : "<>"; }
394
395 protected:
396 virtual Item_bool_func *create_scalar_predicate(Item *a, Item *b) const;
397 virtual Item_bool_func *combine(List<Item> list) const;
398 };
399
400 class Gt_creator :public Comp_creator
401 {
402 public:
Gt_creator()403 Gt_creator() {} /* Remove gcc warning */
~Gt_creator()404 virtual ~Gt_creator() {} /* Remove gcc warning */
405 virtual Item_bool_func* create(Item *a, Item *b) const;
symbol(bool invert)406 virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
eqne_op()407 virtual bool eqne_op() const { return 0; }
l_op()408 virtual bool l_op() const { return 0; }
409 };
410
411 class Lt_creator :public Comp_creator
412 {
413 public:
Lt_creator()414 Lt_creator() {} /* Remove gcc warning */
~Lt_creator()415 virtual ~Lt_creator() {} /* Remove gcc warning */
416 virtual Item_bool_func* create(Item *a, Item *b) const;
symbol(bool invert)417 virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
eqne_op()418 virtual bool eqne_op() const { return 0; }
l_op()419 virtual bool l_op() const { return 1; }
420 };
421
422 class Ge_creator :public Comp_creator
423 {
424 public:
Ge_creator()425 Ge_creator() {} /* Remove gcc warning */
~Ge_creator()426 virtual ~Ge_creator() {} /* Remove gcc warning */
427 virtual Item_bool_func* create(Item *a, Item *b) const;
symbol(bool invert)428 virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
eqne_op()429 virtual bool eqne_op() const { return 0; }
l_op()430 virtual bool l_op() const { return 0; }
431 };
432
433 class Le_creator :public Comp_creator
434 {
435 public:
Le_creator()436 Le_creator() {} /* Remove gcc warning */
~Le_creator()437 virtual ~Le_creator() {} /* Remove gcc warning */
438 virtual Item_bool_func* create(Item *a, Item *b) const;
symbol(bool invert)439 virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
eqne_op()440 virtual bool eqne_op() const { return 0; }
l_op()441 virtual bool l_op() const { return 1; }
442 };
443
444 class Item_bool_func2 :public Item_bool_func
445 { /* Bool with 2 string args */
446 private:
447 bool convert_constant_arg(THD *thd, Item *field, Item **item);
448 protected:
449 Arg_comparator cmp;
450 bool abort_on_null;
451
452 public:
Item_bool_func2(Item * a,Item * b)453 Item_bool_func2(Item *a,Item *b)
454 :Item_bool_func(a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(FALSE) {}
455
Item_bool_func2(const POS & pos,Item * a,Item * b)456 Item_bool_func2(const POS &pos, Item *a,Item *b)
457 :Item_bool_func(pos, a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(FALSE)
458 {}
459
460 void fix_length_and_dec();
set_cmp_func()461 int set_cmp_func()
462 {
463 return cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, TRUE);
464 }
select_optimize()465 optimize_type select_optimize() const { return OPTIMIZE_OP; }
rev_functype()466 virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
have_rev_func()467 bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
468
print(String * str,enum_query_type query_type)469 virtual inline void print(String *str, enum_query_type query_type)
470 {
471 Item_func::print_op(str, query_type);
472 }
473
is_null()474 bool is_null() { return MY_TEST(args[0]->is_null() || args[1]->is_null()); }
compare_collation()475 const CHARSET_INFO *compare_collation()
476 { return cmp.cmp_collation.collation; }
top_level_item()477 void top_level_item() { abort_on_null= TRUE; }
cleanup()478 void cleanup()
479 {
480 Item_bool_func::cleanup();
481 cmp.cleanup();
482 }
483
484 friend class Arg_comparator;
485 };
486
487 class Item_bool_rowready_func2 :public Item_bool_func2
488 {
489 public:
Item_bool_rowready_func2(Item * a,Item * b)490 Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b)
491 {
492 allowed_arg_cols= 0; // Fetch this value from first argument
493 }
Item_bool_rowready_func2(const POS & pos,Item * a,Item * b)494 Item_bool_rowready_func2(const POS &pos, Item *a, Item *b)
495 : Item_bool_func2(pos, a, b)
496 {
497 allowed_arg_cols= 0; // Fetch this value from first argument
498 }
499
500 Item *neg_transformer(THD *thd);
501 virtual Item *negated_item();
subst_argument_checker(uchar ** arg)502 bool subst_argument_checker(uchar **arg) { return TRUE; }
503 };
504
505 /**
506 XOR inherits from Item_bool_func2 because it is not optimized yet.
507 Later, when XOR is optimized, it needs to inherit from
508 Item_cond instead. See WL#5800.
509 */
510 class Item_func_xor :public Item_bool_func2
511 {
512 public:
Item_func_xor(Item * i1,Item * i2)513 Item_func_xor(Item *i1, Item *i2) :Item_bool_func2(i1, i2) {}
Item_func_xor(const POS & pos,Item * i1,Item * i2)514 Item_func_xor(const POS &pos, Item *i1, Item *i2)
515 : Item_bool_func2(pos, i1, i2)
516 {}
517
functype()518 enum Functype functype() const { return XOR_FUNC; }
func_name()519 const char *func_name() const { return "xor"; }
520 longlong val_int();
top_level_item()521 void top_level_item() {}
522 Item *neg_transformer(THD *thd);
523
524 float get_filtering_effect(table_map filter_for_table,
525 table_map read_tables,
526 const MY_BITMAP *fields_to_ignore,
527 double rows_in_table);
528 };
529
530 class Item_func_not :public Item_bool_func
531 {
532 public:
Item_func_not(Item * a)533 Item_func_not(Item *a) :Item_bool_func(a) {}
Item_func_not(const POS & pos,Item * a)534 Item_func_not(const POS &pos, Item *a) :Item_bool_func(pos, a) {}
535
536 longlong val_int();
functype()537 enum Functype functype() const { return NOT_FUNC; }
func_name()538 const char *func_name() const { return "not"; }
539 Item *neg_transformer(THD *thd);
540 virtual void print(String *str, enum_query_type query_type);
541
542 float get_filtering_effect(table_map filter_for_table,
543 table_map read_tables,
544 const MY_BITMAP *fields_to_ignore,
545 double rows_in_table);
546 };
547
548 class Item_maxmin_subselect;
549 class JOIN;
550
551 /*
552 trigcond<param>(arg) ::= param? arg : TRUE
553
554 The class Item_func_trig_cond is used for guarded predicates
555 which are employed only for internal purposes.
556 A guarded predicate is an object consisting of an a regular or
557 a guarded predicate P and a pointer to a boolean guard variable g.
558 A guarded predicate P/g is evaluated to true if the value of the
559 guard g is false, otherwise it is evaluated to the same value that
560 the predicate P: val(P/g)= g ? val(P):true.
561 Guarded predicates allow us to include predicates into a conjunction
562 conditionally. Currently they are utilized for pushed down predicates
563 in queries with outer join operations.
564
565 In the future, probably, it makes sense to extend this class to
566 the objects consisting of three elements: a predicate P, a pointer
567 to a variable g and a firing value s with following evaluation
568 rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
569 one item for the objects of the form P/g1/g2...
570
571 Objects of this class are built only for query execution after
572 the execution plan has been already selected. That's why this
573 class needs only val_int out of generic methods.
574
575 Current uses of Item_func_trig_cond objects:
576 - To wrap selection conditions when executing outer joins
577 - To wrap condition that is pushed down into subquery
578 */
579
580 class Item_func_trig_cond: public Item_bool_func
581 {
582 public:
583 enum enum_trig_type
584 {
585 /**
586 This trigger type deactivates join conditions when a row has been
587 NULL-complemented. For example, in t1 LEFT JOIN t2, the join condition
588 can be tested on t2's row only if that row is not NULL-complemented.
589 */
590 IS_NOT_NULL_COMPL,
591
592 /**
593 This trigger type deactivates predicated from WHERE condition when no
594 row satisfying the join condition has been found. For Example, in t1
595 LEFT JOIN t2, the where condition pushed to t2 can be tested only after
596 at least one t2 row has been produced, which may be a NULL-complemented
597 row.
598 */
599 FOUND_MATCH,
600
601 /**
602 In IN->EXISTS subquery transformation, new predicates are added:
603 WHERE inner_field=outer_field OR inner_field IS NULL,
604 as well as
605 HAVING inner_field IS NOT NULL,
606 are disabled if outer_field is a NULL value
607 */
608 OUTER_FIELD_IS_NOT_NULL
609 };
610 private:
611 /** Pointer to trigger variable */
612 bool *trig_var;
613 /// Optional: JOIN of table which is the source of trig_var
614 const JOIN *m_join;
615 /// Optional: if join!=NULL: index of table
616 plan_idx m_idx;
617 /** Type of trig_var; for printing */
618 enum_trig_type trig_type;
619 public:
620 /**
621 @param a the item for <condition>
622 @param f pointer to trigger variable
623 @param join if a table's property is the source of 'f', JOIN
624 which owns this table; NULL otherwise.
625 @param idx if join!=NULL: index of this table in the
626 JOIN_TAB/QEP_TAB array. NO_PLAN_IDX otherwise.
627 @param trig_type_arg type of 'f'
628 */
Item_func_trig_cond(Item * a,bool * f,JOIN * join,plan_idx idx,enum_trig_type trig_type_arg)629 Item_func_trig_cond(Item *a, bool *f, JOIN *join, plan_idx idx,
630 enum_trig_type trig_type_arg)
631 : Item_bool_func(a), trig_var(f), m_join(join), m_idx(idx),
632 trig_type(trig_type_arg)
633 {}
634 longlong val_int();
functype()635 enum Functype functype() const { return TRIG_COND_FUNC; };
636 /// '<if>', to distinguish from the if() SQL function
func_name()637 const char *func_name() const { return "<if>"; };
const_item()638 bool const_item() const { return FALSE; }
get_trig_var()639 bool *get_trig_var() { return trig_var; }
640 /* The following is needed for ICP: */
used_tables()641 table_map used_tables() const { return args[0]->used_tables(); }
642 void print(String *str, enum_query_type query_type);
643 };
644
645
646 class Item_func_not_all :public Item_func_not
647 {
648 /* allow to check presence of values in max/min optimization */
649 Item_sum_hybrid *test_sum_item;
650 Item_maxmin_subselect *test_sub_item;
651 Item_subselect *subselect;
652
653 bool abort_on_null;
654 public:
655 bool show;
656
Item_func_not_all(Item * a)657 Item_func_not_all(Item *a)
658 :Item_func_not(a), test_sum_item(0), test_sub_item(0), subselect(0),
659 abort_on_null(0), show(0)
660 {}
top_level_item()661 virtual void top_level_item() { abort_on_null= 1; }
is_top_level_item()662 bool is_top_level_item() const { return abort_on_null; }
663 longlong val_int();
functype()664 enum Functype functype() const { return NOT_ALL_FUNC; }
func_name()665 const char *func_name() const { return "<not>"; }
666 virtual void print(String *str, enum_query_type query_type);
set_sum_test(Item_sum_hybrid * item)667 void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
set_sub_test(Item_maxmin_subselect * item)668 void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
set_subselect(Item_subselect * item)669 void set_subselect(Item_subselect *item) { subselect= item; }
not_null_tables()670 table_map not_null_tables() const
671 {
672 /*
673 See handling of not_null_tables_cache in
674 Item_in_optimizer::fix_fields().
675
676 This item is the result of a transformation from an ALL clause
677 such as
678 left-expr < ALL(subquery)
679 into
680 <not>(left-expr >= (subquery)
681
682 An inequality usually rejects NULLs from both operands, so the
683 not_null_tables() of the inequality is the union of the
684 null-rejecting tables of both operands. However, since this is a
685 transformed ALL clause that should return true if the subquery
686 is empty (even if left-expr is NULL), it is not null rejecting
687 for left-expr. The not null tables mask for left-expr should be
688 removed, leaving only the null-rejecting tables of the
689 subquery. Item_subselect::not_null_tables() always returns 0 (no
690 null-rejecting tables). Therefore, always return 0.
691 */
692 return 0;
693 }
694 bool empty_underlying_subquery();
695 Item *neg_transformer(THD *thd);
696 };
697
698
699 class Item_func_nop_all :public Item_func_not_all
700 {
701 public:
702
Item_func_nop_all(Item * a)703 Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
704 longlong val_int();
func_name()705 const char *func_name() const { return "<nop>"; }
not_null_tables()706 table_map not_null_tables() const { return not_null_tables_cache; }
707 Item *neg_transformer(THD *thd);
708 };
709
710
711 class Item_func_eq :public Item_bool_rowready_func2
712 {
713 public:
Item_func_eq(Item * a,Item * b)714 Item_func_eq(Item *a,Item *b) :
715 Item_bool_rowready_func2( a, b)
716 {}
Item_func_eq(const POS & pos,Item * a,Item * b)717 Item_func_eq(const POS &pos, Item *a,Item *b) :
718 Item_bool_rowready_func2(pos, a, b)
719 {}
720 longlong val_int();
functype()721 enum Functype functype() const { return EQ_FUNC; }
rev_functype()722 enum Functype rev_functype() const { return EQ_FUNC; }
eq_cmp_result()723 cond_result eq_cmp_result() const { return COND_TRUE; }
func_name()724 const char *func_name() const { return "="; }
725 Item *negated_item();
equality_substitution_analyzer(uchar ** arg)726 virtual bool equality_substitution_analyzer(uchar **arg) { return true; }
727 virtual Item* equality_substitution_transformer(uchar *arg);
gc_subst_analyzer(uchar ** arg)728 bool gc_subst_analyzer(uchar **arg) { return true; }
729
730 float get_filtering_effect(table_map filter_for_table,
731 table_map read_tables,
732 const MY_BITMAP *fields_to_ignore,
733 double rows_in_table);
734 };
735
736 class Item_func_equal :public Item_bool_rowready_func2
737 {
738 public:
Item_func_equal(Item * a,Item * b)739 Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
Item_func_equal(const POS & pos,Item * a,Item * b)740 Item_func_equal(const POS &pos, Item *a,Item *b)
741 : Item_bool_rowready_func2(pos, a,b)
742 {};
743
744 longlong val_int();
745 void fix_length_and_dec();
not_null_tables()746 table_map not_null_tables() const { return 0; }
functype()747 enum Functype functype() const { return EQUAL_FUNC; }
rev_functype()748 enum Functype rev_functype() const { return EQUAL_FUNC; }
eq_cmp_result()749 cond_result eq_cmp_result() const { return COND_TRUE; }
func_name()750 const char *func_name() const { return "<=>"; }
neg_transformer(THD * thd)751 Item *neg_transformer(THD *thd) { return 0; }
752
753 float get_filtering_effect(table_map filter_for_table,
754 table_map read_tables,
755 const MY_BITMAP *fields_to_ignore,
756 double rows_in_table);
757 };
758
759
760 class Item_func_ge :public Item_bool_rowready_func2
761 {
762 public:
Item_func_ge(Item * a,Item * b)763 Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
764 longlong val_int();
functype()765 enum Functype functype() const { return GE_FUNC; }
rev_functype()766 enum Functype rev_functype() const { return LE_FUNC; }
eq_cmp_result()767 cond_result eq_cmp_result() const { return COND_TRUE; }
func_name()768 const char *func_name() const { return ">="; }
769 Item *negated_item();
gc_subst_analyzer(uchar ** arg)770 bool gc_subst_analyzer(uchar **arg) { return true; }
771
772 float get_filtering_effect(table_map filter_for_table,
773 table_map read_tables,
774 const MY_BITMAP *fields_to_ignore,
775 double rows_in_table);
776 };
777
778 class Item_func_gt :public Item_bool_rowready_func2
779 {
780 public:
Item_func_gt(Item * a,Item * b)781 Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
782 longlong val_int();
functype()783 enum Functype functype() const { return GT_FUNC; }
rev_functype()784 enum Functype rev_functype() const { return LT_FUNC; }
eq_cmp_result()785 cond_result eq_cmp_result() const { return COND_FALSE; }
func_name()786 const char *func_name() const { return ">"; }
787 Item *negated_item();
gc_subst_analyzer(uchar ** arg)788 bool gc_subst_analyzer(uchar **arg) { return true; }
789
790 float get_filtering_effect(table_map filter_for_table,
791 table_map read_tables,
792 const MY_BITMAP *fields_to_ignore,
793 double rows_in_table);
794 };
795
796
797 class Item_func_le :public Item_bool_rowready_func2
798 {
799 public:
Item_func_le(Item * a,Item * b)800 Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
801 longlong val_int();
functype()802 enum Functype functype() const { return LE_FUNC; }
rev_functype()803 enum Functype rev_functype() const { return GE_FUNC; }
eq_cmp_result()804 cond_result eq_cmp_result() const { return COND_TRUE; }
func_name()805 const char *func_name() const { return "<="; }
806 Item *negated_item();
gc_subst_analyzer(uchar ** arg)807 bool gc_subst_analyzer(uchar **arg) { return true; }
808
809 float get_filtering_effect(table_map filter_for_table,
810 table_map read_tables,
811 const MY_BITMAP *fields_to_ignore,
812 double rows_in_table);
813 };
814
815
816 class Item_func_lt :public Item_bool_rowready_func2
817 {
818 public:
Item_func_lt(Item * a,Item * b)819 Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
820 longlong val_int();
functype()821 enum Functype functype() const { return LT_FUNC; }
rev_functype()822 enum Functype rev_functype() const { return GT_FUNC; }
eq_cmp_result()823 cond_result eq_cmp_result() const { return COND_FALSE; }
func_name()824 const char *func_name() const { return "<"; }
825 Item *negated_item();
gc_subst_analyzer(uchar ** arg)826 bool gc_subst_analyzer(uchar **arg) { return true; }
827
828 float get_filtering_effect(table_map filter_for_table,
829 table_map read_tables,
830 const MY_BITMAP *fields_to_ignore,
831 double rows_in_table);
832 };
833
834
835 class Item_func_ne :public Item_bool_rowready_func2
836 {
837 public:
Item_func_ne(Item * a,Item * b)838 Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
839 longlong val_int();
functype()840 enum Functype functype() const { return NE_FUNC; }
eq_cmp_result()841 cond_result eq_cmp_result() const { return COND_FALSE; }
select_optimize()842 optimize_type select_optimize() const { return OPTIMIZE_KEY; }
func_name()843 const char *func_name() const { return "<>"; }
844 Item *negated_item();
845
846 float get_filtering_effect(table_map filter_for_table,
847 table_map read_tables,
848 const MY_BITMAP *fields_to_ignore,
849 double rows_in_table);
850 };
851
852
853 /*
854 The class Item_func_opt_neg is defined to factor out the functionality
855 common for the classes Item_func_between and Item_func_in. The objects
856 of these classes can express predicates or there negations.
857 The alternative approach would be to create pairs Item_func_between,
858 Item_func_notbetween and Item_func_in, Item_func_notin.
859
860 */
861
862 class Item_func_opt_neg :public Item_int_func
863 {
864 public:
865 bool negated; /* <=> the item represents NOT <func> */
866 bool pred_level; /* <=> [NOT] <func> is used on a predicate level */
867 public:
Item_func_opt_neg(const POS & pos,Item * a,Item * b,Item * c,bool is_negation)868 Item_func_opt_neg(const POS &pos, Item *a, Item *b, Item *c, bool is_negation)
869 :Item_int_func(pos, a, b, c), negated(0), pred_level(0)
870 {
871 if (is_negation)
872 negate();
873 }
Item_func_opt_neg(const POS & pos,PT_item_list * list,bool is_negation)874 Item_func_opt_neg(const POS &pos, PT_item_list *list, bool is_negation)
875 :Item_int_func(pos, list), negated(0), pred_level(0)
876 {
877 if (is_negation)
878 negate();
879 }
880 public:
negate()881 inline void negate() { negated= !negated; }
top_level_item()882 inline void top_level_item() { pred_level= 1; }
is_top_level_item()883 bool is_top_level_item() const { return pred_level; }
neg_transformer(THD * thd)884 Item *neg_transformer(THD *thd)
885 {
886 negated= !negated;
887 return this;
888 }
889 bool eq(const Item *item, bool binary_cmp) const;
subst_argument_checker(uchar ** arg)890 bool subst_argument_checker(uchar **arg) { return TRUE; }
891 };
892
893
894 class Item_func_between :public Item_func_opt_neg
895 {
896 DTCollation cmp_collation;
897 public:
898 Item_result cmp_type;
899 String value0,value1,value2;
900 /* TRUE <=> arguments will be compared as dates. */
901 bool compare_as_dates_with_strings;
902 bool compare_as_temporal_dates;
903 bool compare_as_temporal_times;
904
905 /* Comparators used for DATE/DATETIME comparison. */
906 Arg_comparator ge_cmp, le_cmp;
Item_func_between(const POS & pos,Item * a,Item * b,Item * c,bool is_negation)907 Item_func_between(const POS &pos, Item *a, Item *b, Item *c, bool is_negation)
908 :Item_func_opt_neg(pos, a, b, c, is_negation),
909 compare_as_dates_with_strings(FALSE),
910 compare_as_temporal_dates(FALSE),
911 compare_as_temporal_times(FALSE) {}
912 longlong val_int();
select_optimize()913 optimize_type select_optimize() const { return OPTIMIZE_KEY; }
functype()914 enum Functype functype() const { return BETWEEN; }
func_name()915 const char *func_name() const { return "between"; }
916 bool fix_fields(THD *, Item **);
917 void fix_after_pullout(st_select_lex *parent_select,
918 st_select_lex *removed_select);
919 void fix_length_and_dec();
920 virtual void print(String *str, enum_query_type query_type);
is_bool_func()921 bool is_bool_func() { return 1; }
compare_collation()922 const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
decimal_precision()923 uint decimal_precision() const { return 1; }
gc_subst_analyzer(uchar ** arg)924 bool gc_subst_analyzer(uchar **arg) { return true; }
925
926 float get_filtering_effect(table_map filter_for_table,
927 table_map read_tables,
928 const MY_BITMAP *fields_to_ignore,
929 double rows_in_table);
930 };
931
932
933 class Item_func_strcmp :public Item_bool_func2
934 {
935 public:
Item_func_strcmp(const POS & pos,Item * a,Item * b)936 Item_func_strcmp(const POS &pos, Item *a, Item *b) :Item_bool_func2(pos, a, b)
937 {}
938 longlong val_int();
select_optimize()939 optimize_type select_optimize() const { return OPTIMIZE_NONE; }
func_name()940 const char *func_name() const { return "strcmp"; }
941
print(String * str,enum_query_type query_type)942 virtual inline void print(String *str, enum_query_type query_type)
943 {
944 Item_func::print(str, query_type);
945 }
fix_length_and_dec()946 void fix_length_and_dec()
947 {
948 Item_bool_func2::fix_length_and_dec();
949 fix_char_length(2); // returns "1" or "0" or "-1"
950 }
951 };
952
953
954 struct interval_range
955 {
956 Item_result type;
957 double dbl;
958 my_decimal dec;
959 };
960
961 class Item_func_interval :public Item_int_func
962 {
963 typedef Item_int_func super;
964
965 Item_row *row;
966 my_bool use_decimal_comparison;
967 interval_range *intervals;
968 public:
969 Item_func_interval(const POS &pos, MEM_ROOT *mem_root, Item *expr1,
970 Item *expr2, class PT_item_list *opt_expr_list= NULL)
super(pos,alloc_row (pos,mem_root,expr1,expr2,opt_expr_list))971 :super(pos, alloc_row(pos, mem_root, expr1, expr2, opt_expr_list)),
972 intervals(0)
973 {
974 allowed_arg_cols= 0; // Fetch this value from first argument
975 }
976
977 virtual bool itemize(Parse_context *pc, Item **res);
978 longlong val_int();
979 void fix_length_and_dec();
func_name()980 const char *func_name() const { return "interval"; }
decimal_precision()981 uint decimal_precision() const { return 2; }
982 void print(String *str, enum_query_type query_type);
983
984 private:
985 Item_row *alloc_row(const POS &pos, MEM_ROOT *mem_root, Item *expr1,
986 Item *expr2, class PT_item_list *opt_expr_list);
987 };
988
989
990 class Item_func_coalesce :public Item_func_numhybrid
991 {
992 protected:
993 enum_field_types cached_field_type;
Item_func_coalesce(const POS & pos,Item * a,Item * b)994 Item_func_coalesce(const POS &pos, Item *a, Item *b)
995 : Item_func_numhybrid(pos, a, b)
996 {}
Item_func_coalesce(const POS & pos,Item * a)997 Item_func_coalesce(const POS &pos, Item *a)
998 : Item_func_numhybrid(pos, a)
999 {}
1000 public:
1001 Item_func_coalesce(const POS &pos, PT_item_list *list);
1002 double real_op();
1003 longlong int_op();
1004 String *str_op(String *);
1005 /**
1006 Get the result of COALESCE as a JSON value.
1007 @param[in,out] wr the result value holder
1008 */
1009 bool val_json(Json_wrapper *wr);
1010 bool date_op(MYSQL_TIME *ltime, my_time_flags_t fuzzydate);
1011 bool time_op(MYSQL_TIME *ltime);
1012 my_decimal *decimal_op(my_decimal *);
1013 void fix_length_and_dec();
find_num_type()1014 void find_num_type() {}
result_type()1015 enum Item_result result_type () const { return hybrid_type; }
func_name()1016 const char *func_name() const { return "coalesce"; }
not_null_tables()1017 table_map not_null_tables() const { return 0; }
field_type()1018 enum_field_types field_type() const { return cached_field_type; }
1019 };
1020
1021
1022 class Item_func_ifnull :public Item_func_coalesce
1023 {
1024 protected:
1025 bool field_type_defined;
1026 public:
Item_func_ifnull(const POS & pos,Item * a,Item * b)1027 Item_func_ifnull(const POS &pos, Item *a, Item *b)
1028 : Item_func_coalesce(pos, a, b)
1029 {}
1030 double real_op();
1031 longlong int_op();
1032 String *str_op(String *str);
1033 bool date_op(MYSQL_TIME *ltime, my_time_flags_t fuzzydate);
1034 bool time_op(MYSQL_TIME *ltime);
1035 my_decimal *decimal_op(my_decimal *);
1036 bool val_json(Json_wrapper *result);
1037 void fix_length_and_dec();
func_name()1038 const char *func_name() const { return "ifnull"; }
1039 Field *tmp_table_field(TABLE *table);
1040 uint decimal_precision() const;
1041 };
1042
1043
1044 /**
1045 ANY_VALUE(expr) is like expr except that it is not checked by
1046 aggregate_check logic. It serves as a solution for users who want to
1047 bypass this logic.
1048 */
1049 class Item_func_any_value :public Item_func_coalesce
1050 {
1051 public:
Item_func_any_value(const POS & pos,Item * a)1052 Item_func_any_value(const POS &pos, Item *a) :Item_func_coalesce(pos, a) {}
func_name()1053 const char *func_name() const { return "any_value"; }
1054 bool aggregate_check_group(uchar *arg);
1055 bool aggregate_check_distinct(uchar *arg);
1056 };
1057
1058
1059 class Item_func_if :public Item_func
1060 {
1061 enum Item_result cached_result_type;
1062 enum_field_types cached_field_type;
1063 public:
Item_func_if(Item * a,Item * b,Item * c)1064 Item_func_if(Item *a,Item *b,Item *c)
1065 :Item_func(a,b,c), cached_result_type(INT_RESULT)
1066 {}
Item_func_if(const POS & pos,Item * a,Item * b,Item * c)1067 Item_func_if(const POS &pos, Item *a,Item *b,Item *c)
1068 :Item_func(pos, a,b,c), cached_result_type(INT_RESULT)
1069 {}
1070
1071 double val_real();
1072 longlong val_int();
1073 String *val_str(String *str);
1074 my_decimal *val_decimal(my_decimal *);
1075 bool val_json(Json_wrapper *wr);
1076 bool get_date(MYSQL_TIME *ltime, my_time_flags_t fuzzydate);
1077 bool get_time(MYSQL_TIME *ltime);
result_type()1078 enum Item_result result_type () const { return cached_result_type; }
field_type()1079 enum_field_types field_type() const { return cached_field_type; }
1080 bool fix_fields(THD *, Item **);
1081 void fix_length_and_dec();
1082 void fix_after_pullout(st_select_lex *parent_select,
1083 st_select_lex *removed_select);
1084 uint decimal_precision() const;
func_name()1085 const char *func_name() const { return "if"; }
1086 private:
1087 void cache_type_info(Item *source);
1088 };
1089
1090
1091 class Item_func_nullif :public Item_bool_func2
1092 {
1093 enum Item_result cached_result_type;
1094 public:
Item_func_nullif(const POS & pos,Item * a,Item * b)1095 Item_func_nullif(const POS &pos, Item *a, Item *b)
1096 :Item_bool_func2(pos, a, b), cached_result_type(INT_RESULT)
1097 {}
1098 double val_real();
1099 longlong val_int();
1100 String *val_str(String *str);
1101 my_decimal *val_decimal(my_decimal *);
result_type()1102 enum Item_result result_type () const { return cached_result_type; }
1103 void fix_length_and_dec();
decimal_precision()1104 uint decimal_precision() const { return args[0]->decimal_precision(); }
func_name()1105 const char *func_name() const { return "nullif"; }
1106
print(String * str,enum_query_type query_type)1107 virtual inline void print(String *str, enum_query_type query_type)
1108 {
1109 Item_func::print(str, query_type);
1110 }
1111
not_null_tables()1112 table_map not_null_tables() const { return 0; }
1113 bool is_null();
1114 };
1115
1116
1117 /* Functions to handle the optimized IN */
1118
1119
1120 /* A vector of values of some type */
1121
1122 class in_vector :public Sql_alloc
1123 {
1124 public:
1125 const uint count; ///< Original size of the vector
1126 uint used_count; ///< The actual size of the vector (NULL may be ignored)
1127
1128 /**
1129 See Item_func_in::fix_length_and_dec for why we need both
1130 count and used_count.
1131 */
in_vector(uint elements)1132 explicit in_vector(uint elements)
1133 : count(elements), used_count(elements)
1134 {}
1135
~in_vector()1136 virtual ~in_vector() {}
1137 virtual void set(uint pos,Item *item)=0;
1138 virtual uchar *get_value(Item *item)=0;
1139
1140 /**
1141 Shrinks the IN-list array, to fit actual usage.
1142 */
1143 virtual void shrink_array(size_t n) = 0;
1144
1145 /**
1146 Sorts the IN-list array, so we can do efficient lookup with binary_search.
1147 */
1148 virtual void sort() = 0;
1149
1150 /**
1151 Calls (the virtual) get_value, i.e. item->val_int() or item->val_str() etc.
1152 and then calls find_value() if the value is non-null.
1153 @param item to evaluate, and lookup in the IN-list.
1154 @return true if item was found.
1155 */
1156 bool find_item(Item *item);
1157
1158 /**
1159 Does a binary_search in the 'base' array for the input 'value'
1160 @param value to lookup in the IN-list.
1161 @return true if value was found.
1162 */
1163 virtual bool find_value(const void *value) const = 0;
1164
1165 /*
1166 Create an instance of Item_{type} (e.g. Item_decimal) constant object
1167 which type allows it to hold an element of this vector without any
1168 conversions.
1169 The purpose of this function is to be able to get elements of this
1170 vector in form of Item_xxx constants without creating Item_xxx object
1171 for every array element you get (i.e. this implements "FlyWeight" pattern)
1172 */
create_item()1173 virtual Item* create_item() { return NULL; }
1174
1175 /*
1176 Store the value at position #pos into provided item object
1177 SYNOPSIS
1178 value_to_item()
1179 pos Index of value to store
1180 item Constant item to store value into. The item must be of the same
1181 type that create_item() returns.
1182 */
value_to_item(uint pos,Item * item)1183 virtual void value_to_item(uint pos, Item *item) { }
1184
1185 /* Compare values number pos1 and pos2 for equality */
1186 virtual bool compare_elems(uint pos1, uint pos2) const = 0;
1187
1188 virtual Item_result result_type()= 0;
1189 };
1190
1191 class in_string :public in_vector
1192 {
1193 char buff[STRING_BUFFER_USUAL_SIZE];
1194 String tmp;
1195 // DTOR is not trivial, but we manage memory ourselves.
1196 Mem_root_array<String, true> base_objects;
1197 // String objects are not sortable, sort pointers instead.
1198 Mem_root_array<String*, true> base_pointers;
1199
1200 qsort2_cmp compare;
1201 const CHARSET_INFO *collation;
1202 public:
1203 in_string(THD *thd,
1204 uint elements, qsort2_cmp cmp_func, const CHARSET_INFO *cs);
1205 ~in_string();
1206 void set(uint pos,Item *item);
1207 uchar *get_value(Item *item);
create_item()1208 Item* create_item()
1209 {
1210 return new Item_string(collation);
1211 }
value_to_item(uint pos,Item * item)1212 void value_to_item(uint pos, Item *item)
1213 {
1214 String *str= base_pointers[pos];
1215 Item_string *to= (Item_string*)item;
1216 to->str_value= *str;
1217 }
result_type()1218 Item_result result_type() { return STRING_RESULT; }
1219
shrink_array(size_t n)1220 virtual void shrink_array(size_t n) { base_pointers.resize(n); }
1221
1222 virtual void sort();
1223 virtual bool find_value(const void *value) const;
1224 virtual bool compare_elems(uint pos1, uint pos2) const;
1225 };
1226
1227 class in_longlong :public in_vector
1228 {
1229 public:
1230 struct packed_longlong
1231 {
1232 longlong val;
1233 longlong unsigned_flag;
1234 };
1235 protected:
1236 /*
1237 Here we declare a temporary variable (tmp) of the same type as the
1238 elements of this vector. tmp is used in finding if a given value is in
1239 the list.
1240 */
1241 packed_longlong tmp;
1242
1243 Mem_root_array<packed_longlong, true> base;
1244
1245 public:
1246 in_longlong(THD *thd, uint elements);
1247 void set(uint pos,Item *item);
1248 uchar *get_value(Item *item);
1249
create_item()1250 Item* create_item()
1251 {
1252 /*
1253 We're created a signed INT, this may not be correct in
1254 general case (see BUG#19342).
1255 */
1256 return new Item_int((longlong)0);
1257 }
value_to_item(uint pos,Item * item)1258 void value_to_item(uint pos, Item *item)
1259 {
1260 ((Item_int*) item)->value= base[pos].val;
1261 ((Item_int*) item)->unsigned_flag= (my_bool)
1262 base[pos].unsigned_flag;
1263 }
result_type()1264 Item_result result_type() { return INT_RESULT; }
1265
shrink_array(size_t n)1266 virtual void shrink_array(size_t n) { base.resize(n); }
1267
1268 virtual void sort();
1269 virtual bool find_value(const void *value) const;
1270 virtual bool compare_elems(uint pos1, uint pos2) const;
1271 };
1272
1273
1274 class in_datetime_as_longlong :public in_longlong
1275 {
1276 public:
in_datetime_as_longlong(THD * thd,uint elements)1277 in_datetime_as_longlong(THD *thd, uint elements)
1278 : in_longlong(thd, elements)
1279 {};
create_item()1280 Item *create_item()
1281 {
1282 return new Item_temporal(MYSQL_TYPE_DATETIME, 0LL);
1283 }
1284 void set(uint pos, Item *item);
1285 uchar *get_value(Item *item);
1286 };
1287
1288
1289 class in_time_as_longlong :public in_longlong
1290 {
1291 public:
in_time_as_longlong(THD * thd,uint elements)1292 in_time_as_longlong(THD *thd, uint elements)
1293 : in_longlong(thd, elements)
1294 {};
create_item()1295 Item *create_item()
1296 {
1297 return new Item_temporal(MYSQL_TYPE_TIME, 0LL);
1298 }
1299 void set(uint pos, Item *item);
1300 uchar *get_value(Item *item);
1301 };
1302
1303
1304 /*
1305 Class to represent a vector of constant DATE/DATETIME values.
1306 Values are obtained with help of the get_datetime_value() function.
1307 If the left item is a constant one then its value is cached in the
1308 lval_cache variable.
1309 */
1310 class in_datetime :public in_longlong
1311 {
1312 public:
1313 /* An item used to issue warnings. */
1314 Item *warn_item;
1315 /* Cache for the left item. */
1316 Item *lval_cache;
1317
in_datetime(THD * thd_arg,Item * warn_item_arg,uint elements)1318 in_datetime(THD *thd_arg, Item *warn_item_arg, uint elements)
1319 : in_longlong(thd_arg, elements), warn_item(warn_item_arg),
1320 lval_cache(0)
1321 {};
1322 void set(uint pos,Item *item);
1323 uchar *get_value(Item *item);
1324
create_item()1325 Item* create_item()
1326 {
1327 return new Item_temporal(MYSQL_TYPE_DATETIME, (longlong) 0);
1328 }
1329 };
1330
1331
1332 class in_double :public in_vector
1333 {
1334 double tmp;
1335 Mem_root_array<double, true> base;
1336 public:
1337 in_double(THD *thd, uint elements);
1338 void set(uint pos,Item *item);
1339 uchar *get_value(Item *item);
create_item()1340 Item *create_item()
1341 {
1342 return new Item_float(0.0, 0);
1343 }
value_to_item(uint pos,Item * item)1344 void value_to_item(uint pos, Item *item)
1345 {
1346 ((Item_float*)item)->value= base[pos];
1347 }
result_type()1348 Item_result result_type() { return REAL_RESULT; }
1349
shrink_array(size_t n)1350 virtual void shrink_array(size_t n) { base.resize(n); }
1351
1352 virtual void sort();
1353 virtual bool find_value(const void *value) const;
1354 virtual bool compare_elems(uint pos1, uint pos2) const;
1355 };
1356
1357
1358 class in_decimal :public in_vector
1359 {
1360 my_decimal val;
1361 Mem_root_array<my_decimal, true> base;
1362 public:
1363 in_decimal(THD *thd, uint elements);
1364 void set(uint pos, Item *item);
1365 uchar *get_value(Item *item);
create_item()1366 Item *create_item()
1367 {
1368 return new Item_decimal(0, FALSE);
1369 }
value_to_item(uint pos,Item * item)1370 void value_to_item(uint pos, Item *item)
1371 {
1372 my_decimal *dec= &base[pos];
1373 Item_decimal *item_dec= (Item_decimal*)item;
1374 item_dec->set_decimal_value(dec);
1375 }
result_type()1376 Item_result result_type() { return DECIMAL_RESULT; }
1377
shrink_array(size_t n)1378 virtual void shrink_array(size_t n) { base.resize(n); }
1379
1380 virtual void sort();
1381 virtual bool find_value(const void *value) const;
1382 virtual bool compare_elems(uint pos1, uint pos2) const;
1383 };
1384
1385
1386 /*
1387 ** Classes for easy comparing of non const items
1388 */
1389
1390 class cmp_item :public Sql_alloc
1391 {
1392 public:
cmp_item()1393 cmp_item() {}
~cmp_item()1394 virtual ~cmp_item() {}
1395 virtual void store_value(Item *item)= 0;
1396 /**
1397 @returns result (TRUE, FALSE or UNKNOWN) of
1398 "stored argument's value <> item's value"
1399 */
1400 virtual int cmp(Item *item)= 0;
1401 // for optimized IN with row
1402 virtual int compare(const cmp_item *item) const= 0;
1403
1404 /**
1405 Find the appropriate comparator for the given type.
1406
1407 @param result_type Used to find the appropriate comparator.
1408 @param item Item object used to distinguish temporal types.
1409 @param cs Charset
1410
1411 @return
1412 New cmp_item_xxx object.
1413 */
1414 static cmp_item* get_comparator(Item_result result_type, const Item *item,
1415 const CHARSET_INFO *cs);
1416 virtual cmp_item *make_same()= 0;
store_value_by_template(cmp_item * tmpl,Item * item)1417 virtual void store_value_by_template(cmp_item *tmpl, Item *item)
1418 {
1419 store_value(item);
1420 }
1421 };
1422
1423 /// cmp_item which stores a scalar (i.e. non-ROW).
1424 class cmp_item_scalar : public cmp_item
1425 {
1426 protected:
1427 bool m_null_value; ///< If stored value is NULL
set_null_value(bool nv)1428 void set_null_value(bool nv) { m_null_value= nv; }
1429 };
1430
1431 class cmp_item_string : public cmp_item_scalar
1432 {
1433 private:
1434 String *value_res;
1435 char value_buff[STRING_BUFFER_USUAL_SIZE];
1436 String value;
1437 const CHARSET_INFO *cmp_charset;
1438 public:
cmp_item_string(const CHARSET_INFO * cs)1439 cmp_item_string (const CHARSET_INFO *cs)
1440 : value(value_buff, sizeof(value_buff), cs), cmp_charset(cs)
1441 {}
1442
compare(const cmp_item * ci)1443 virtual int compare(const cmp_item *ci) const
1444 {
1445 const cmp_item_string *l_cmp= down_cast<const cmp_item_string*>(ci);
1446 return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1447 }
1448
store_value(Item * item)1449 virtual void store_value(Item *item)
1450 {
1451 String *res= item->val_str(&value);
1452 if (res && (res != &value || !res->is_alloced()))
1453 {
1454 // 'res' may point in item's transient internal data, so make a copy
1455 value.copy(*res);
1456 }
1457 value_res= &value;
1458 set_null_value(item->null_value);
1459 }
1460
cmp(Item * arg)1461 virtual int cmp(Item *arg)
1462 {
1463 char buff[STRING_BUFFER_USUAL_SIZE];
1464 String tmp(buff, sizeof(buff), cmp_charset);
1465 String *res= arg->val_str(&tmp);
1466 if (m_null_value || arg->null_value)
1467 return UNKNOWN;
1468 if (value_res && res)
1469 return sortcmp(value_res, res, cmp_charset) != 0;
1470 else if (!value_res && !res)
1471 return FALSE;
1472 else
1473 return TRUE;
1474 }
1475 virtual cmp_item *make_same();
1476 };
1477
1478
1479 class cmp_item_int : public cmp_item_scalar
1480 {
1481 longlong value;
1482 public:
cmp_item_int()1483 cmp_item_int() {} /* Remove gcc warning */
store_value(Item * item)1484 void store_value(Item *item)
1485 {
1486 value= item->val_int();
1487 set_null_value(item->null_value);
1488 }
cmp(Item * arg)1489 int cmp(Item *arg)
1490 {
1491 const bool rc= value != arg->val_int();
1492 return (m_null_value || arg->null_value) ? UNKNOWN : rc;
1493 }
compare(const cmp_item * ci)1494 int compare(const cmp_item *ci) const
1495 {
1496 const cmp_item_int *l_cmp= down_cast<const cmp_item_int*>(ci);
1497 return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
1498 }
1499 cmp_item *make_same();
1500 };
1501
1502 /*
1503 Compare items of temporal type.
1504 Values are obtained with: get_datetime_value() (DATE/DATETIME/TIMESTAMP) and
1505 get_time_value() (TIME).
1506 If the left item is a constant one then its value is cached in the
1507 lval_cache variable.
1508 */
1509 class cmp_item_datetime : public cmp_item_scalar
1510 {
1511 longlong value;
1512 public:
1513 /* Item used for issuing warnings. */
1514 const Item *warn_item;
1515 /* Cache for the left item. */
1516 Item *lval_cache;
1517 /// Distinguish between DATE/DATETIME/TIMESTAMP and TIME
1518 bool has_date;
1519
1520 cmp_item_datetime(const Item *warn_item_arg);
1521 void store_value(Item *item);
1522 int cmp(Item *arg);
1523 int compare(const cmp_item *ci) const;
1524 cmp_item *make_same();
1525 };
1526
1527 class cmp_item_real : public cmp_item_scalar
1528 {
1529 double value;
1530 public:
cmp_item_real()1531 cmp_item_real() {} /* Remove gcc warning */
store_value(Item * item)1532 void store_value(Item *item)
1533 {
1534 value= item->val_real();
1535 set_null_value(item->null_value);
1536 }
cmp(Item * arg)1537 int cmp(Item *arg)
1538 {
1539 const bool rc= value != arg->val_real();
1540 return (m_null_value || arg->null_value) ? UNKNOWN : rc;
1541 }
compare(const cmp_item * ci)1542 int compare(const cmp_item *ci) const
1543 {
1544 const cmp_item_real *l_cmp= down_cast<const cmp_item_real*>(ci);
1545 return (value < l_cmp->value)? -1 : ((value == l_cmp->value) ? 0 : 1);
1546 }
1547 cmp_item *make_same();
1548 };
1549
1550
1551 class cmp_item_decimal : public cmp_item_scalar
1552 {
1553 my_decimal value;
1554 public:
cmp_item_decimal()1555 cmp_item_decimal() {} /* Remove gcc warning */
1556 void store_value(Item *item);
1557 int cmp(Item *arg);
1558 int compare(const cmp_item *c) const;
1559 cmp_item *make_same();
1560 };
1561
1562
1563 /*
1564 The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1565 implementation.
1566
1567 When there is no expression between CASE and the first WHEN
1568 (the CASE expression) then this function simple checks all WHEN expressions
1569 one after another. When some WHEN expression evaluated to TRUE then the
1570 value of the corresponding THEN expression is returned.
1571
1572 When the CASE expression is specified then it is compared to each WHEN
1573 expression individually. When an equal WHEN expression is found
1574 corresponding THEN expression is returned.
1575 In order to do correct comparisons several comparators are used. One for
1576 each result type. Different result types that are used in particular
1577 CASE ... END expression are collected in the fix_length_and_dec() member
1578 function and only comparators for there result types are used.
1579 */
1580
1581 class Item_func_case :public Item_func
1582 {
1583 typedef Item_func super;
1584
1585 int first_expr_num, else_expr_num;
1586 enum Item_result cached_result_type, left_result_type;
1587 String tmp_value;
1588 uint ncases;
1589 Item_result cmp_type;
1590 DTCollation cmp_collation;
1591 enum_field_types cached_field_type;
1592 cmp_item *cmp_items[5]; /* For all result types */
1593 cmp_item *case_item;
1594 public:
Item_func_case(const POS & pos,List<Item> & list,Item * first_expr_arg,Item * else_expr_arg)1595 Item_func_case(const POS &pos, List<Item> &list, Item *first_expr_arg,
1596 Item *else_expr_arg)
1597 : super(pos), first_expr_num(-1), else_expr_num(-1),
1598 cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
1599 {
1600 ncases= list.elements;
1601 if (first_expr_arg)
1602 {
1603 first_expr_num= list.elements;
1604 list.push_back(first_expr_arg);
1605 }
1606 if (else_expr_arg)
1607 {
1608 else_expr_num= list.elements;
1609 list.push_back(else_expr_arg);
1610 }
1611 set_arguments(list, true);
1612 memset(&cmp_items, 0, sizeof(cmp_items));
1613 }
1614 double val_real();
1615 longlong val_int();
1616 String *val_str(String *);
1617 my_decimal *val_decimal(my_decimal *);
1618 bool val_json(Json_wrapper *wr);
1619 bool get_date(MYSQL_TIME *ltime, my_time_flags_t fuzzydate);
1620 bool get_time(MYSQL_TIME *ltime);
1621 bool fix_fields(THD *thd, Item **ref);
1622 void fix_length_and_dec();
1623 uint decimal_precision() const;
not_null_tables()1624 table_map not_null_tables() const { return 0; }
result_type()1625 enum Item_result result_type () const { return cached_result_type; }
field_type()1626 enum_field_types field_type() const { return cached_field_type; }
func_name()1627 const char *func_name() const { return "case"; }
1628 virtual void print(String *str, enum_query_type query_type);
1629 Item *find_item(String *str);
compare_collation()1630 const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1631 void cleanup();
1632 };
1633
1634 /*
1635 The Item_func_in class implements
1636 in_expr IN (<in value list>)
1637 and
1638 in_expr NOT IN (<in value list>)
1639
1640 The current implementation distinguishes 2 cases:
1641 1) all items in <in value list> are constants and have the same
1642 result type. This case is handled by in_vector class.
1643 2) otherwise Item_func_in employs several cmp_item objects to perform
1644 comparisons of in_expr and an item from <in value list>. One cmp_item
1645 object for each result type. Different result types are collected in the
1646 fix_length_and_dec() member function by means of collect_cmp_types()
1647 function.
1648 */
1649 class Item_func_in :public Item_func_opt_neg
1650 {
1651 public:
1652 /// An array of values, created when the bisection lookup method is used
1653 in_vector *array;
1654 /**
1655 If there is some NULL among <in value list>, during a val_int() call; for
1656 example
1657 IN ( (1,(3,'col')), ... ), where 'col' is a column which evaluates to
1658 NULL.
1659 */
1660 bool have_null;
1661 /**
1662 Set to true by fix_length_and_dec() if the IN list contains a
1663 dependent subquery, in which case condition filtering will not be
1664 calculated for this item.
1665 */
1666 bool dep_subq_in_list;
1667 Item_result left_result_type;
1668 cmp_item *cmp_items[6]; /* One cmp_item for each result type */
1669 DTCollation cmp_collation;
1670
Item_func_in(const POS & pos,PT_item_list * list,bool is_negation)1671 Item_func_in(const POS &pos, PT_item_list *list, bool is_negation)
1672 :Item_func_opt_neg(pos, list, is_negation), array(NULL),
1673 have_null(false), dep_subq_in_list(false)
1674 {
1675 memset(&cmp_items, 0, sizeof(cmp_items));
1676 allowed_arg_cols= 0; // Fetch this value from first argument
1677 }
1678 longlong val_int();
1679 bool fix_fields(THD *, Item **);
1680 void fix_after_pullout(st_select_lex *parent_select,
1681 st_select_lex *removed_select);
1682 void fix_length_and_dec();
decimal_precision()1683 uint decimal_precision() const { return 1; }
1684
1685 /**
1686 Cleanup data and comparator arrays.
1687
1688 @note Used during regular cleanup and to free arrays after GC substitution.
1689 @see substitute_gc().
1690 */
cleanup_arrays()1691 void cleanup_arrays()
1692 {
1693 uint i;
1694 delete array;
1695 array= 0;
1696 for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1697 {
1698 delete cmp_items[i];
1699 cmp_items[i]= 0;
1700 }
1701 }
1702
cleanup()1703 void cleanup()
1704 {
1705 DBUG_ENTER("Item_func_in::cleanup");
1706 Item_int_func::cleanup();
1707 cleanup_arrays();
1708 DBUG_VOID_RETURN;
1709 }
select_optimize()1710 optimize_type select_optimize() const
1711 { return OPTIMIZE_KEY; }
1712 virtual void print(String *str, enum_query_type query_type);
functype()1713 enum Functype functype() const { return IN_FUNC; }
func_name()1714 const char *func_name() const { return " IN "; }
is_bool_func()1715 bool is_bool_func() { return 1; }
compare_collation()1716 const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
gc_subst_analyzer(uchar ** arg)1717 bool gc_subst_analyzer(uchar **arg) { return true; }
1718
1719 float get_filtering_effect(table_map filter_for_table,
1720 table_map read_tables,
1721 const MY_BITMAP *fields_to_ignore,
1722 double rows_in_table);
1723 private:
1724 /**
1725 Usable if <in value list> is made only of constants. Returns true if one
1726 of these constants contains a NULL. Example:
1727 IN ( (-5, (12,NULL)), ... ).
1728 */
1729 bool list_contains_null();
1730 /**
1731 Utility function to help calculate the total filtering effect of
1732 IN predicates. This function calculates the filtering effect from
1733 a single field (or field reference) on the left hand side of the
1734 expression.
1735
1736 @param fieldref Field (or field reference) on left hand side of
1737 IN, i.e., this function should be called for
1738 each fi in "(f1,...,fn) IN (values)"
1739 @param filter_for_table The table we are calculating filter effect for
1740 @param fields_to_ignore Fields in 'filter_for_table' that should not
1741 be part of the filter calculation. The filtering
1742 effect of these fields are already part of the
1743 calculation somehow (e.g. because there is a
1744 predicate "col = <const>", and the optimizer
1745 has decided to do ref access on 'col').
1746 @param rows_in_table The number of rows in table 'filter_for_table'
1747
1748 @return the filtering effect (between 0 and 1) 'the_field'
1749 participates with in this IN predicate.
1750 */
1751 float get_single_col_filtering_effect(Item_ident *fieldref,
1752 table_map filter_for_table,
1753 const MY_BITMAP *fields_to_ignore,
1754 double rows_in_table);
1755 };
1756
1757 class cmp_item_row :public cmp_item
1758 {
1759 cmp_item **comparators;
1760 uint n;
1761 public:
cmp_item_row()1762 cmp_item_row(): comparators(0), n(0) {}
1763 ~cmp_item_row();
1764 void store_value(Item *item);
1765 void alloc_comparators(Item *item);
1766 int cmp(Item *arg);
1767 int compare(const cmp_item *arg) const;
1768 cmp_item *make_same();
1769 void store_value_by_template(cmp_item *tmpl, Item *);
1770 friend void Item_func_in::fix_length_and_dec();
1771 };
1772
1773
1774 class in_row :public in_vector
1775 {
1776 cmp_item_row tmp;
1777 // DTOR is not trivial, but we manage memory ourselves.
1778 Mem_root_array<cmp_item_row, true> base_objects;
1779 // Sort pointers, rather than objects.
1780 Mem_root_array<cmp_item_row*, true> base_pointers;
1781 public:
1782 in_row(THD *thd, uint elements, Item *);
1783 ~in_row();
1784 void set(uint pos,Item *item);
1785 uchar *get_value(Item *item);
1786 friend void Item_func_in::fix_length_and_dec();
result_type()1787 Item_result result_type() { return ROW_RESULT; }
1788
shrink_array(size_t n)1789 virtual void shrink_array(size_t n) { base_pointers.resize(n); }
1790
1791 virtual void sort();
1792 virtual bool find_value(const void *value) const;
1793 virtual bool compare_elems(uint pos1, uint pos2) const;
1794 };
1795
1796 /* Functions used by where clause */
1797
1798 class Item_func_isnull :public Item_bool_func
1799 {
1800 protected:
1801 longlong cached_value;
1802 public:
Item_func_isnull(Item * a)1803 Item_func_isnull(Item *a) :Item_bool_func(a) {}
Item_func_isnull(const POS & pos,Item * a)1804 Item_func_isnull(const POS &pos, Item *a) :Item_bool_func(pos, a) {}
1805
1806 longlong val_int();
functype()1807 enum Functype functype() const { return ISNULL_FUNC; }
fix_length_and_dec()1808 void fix_length_and_dec()
1809 {
1810 decimals=0; max_length=1; maybe_null=0;
1811 update_used_tables();
1812 }
func_name()1813 const char *func_name() const { return "isnull"; }
1814 /* Optimize case of not_null_column IS NULL */
update_used_tables()1815 virtual void update_used_tables()
1816 {
1817 if (!args[0]->maybe_null)
1818 {
1819 used_tables_cache= 0; /* is always false */
1820 const_item_cache= 1;
1821 cached_value= (longlong) 0;
1822 }
1823 else
1824 {
1825 args[0]->update_used_tables();
1826 with_subselect= args[0]->has_subquery();
1827 with_stored_program= args[0]->has_stored_program();
1828
1829 if ((const_item_cache= !(used_tables_cache= args[0]->used_tables()) &&
1830 !with_subselect && !with_stored_program))
1831 {
1832 /* Remember if the value is always NULL or never NULL */
1833 cached_value= (longlong) args[0]->is_null();
1834 }
1835 }
1836 }
1837
1838 float get_filtering_effect(table_map filter_for_table,
1839 table_map read_tables,
1840 const MY_BITMAP *fields_to_ignore,
1841 double rows_in_table);
not_null_tables()1842 table_map not_null_tables() const { return 0; }
select_optimize()1843 optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1844 Item *neg_transformer(THD *thd);
compare_collation()1845 const CHARSET_INFO *compare_collation()
1846 { return args[0]->collation.collation; }
1847 };
1848
1849 /* Functions used by HAVING for rewriting IN subquery */
1850
1851 class Item_in_subselect;
1852
1853 /*
1854 This is like IS NOT NULL but it also remembers if it ever has
1855 encountered a NULL; it remembers this in the "was_null" property of the
1856 "owner" item.
1857 */
1858 class Item_is_not_null_test :public Item_func_isnull
1859 {
1860 Item_in_subselect* owner;
1861 public:
Item_is_not_null_test(Item_in_subselect * ow,Item * a)1862 Item_is_not_null_test(Item_in_subselect* ow, Item *a)
1863 :Item_func_isnull(a), owner(ow)
1864 {}
functype()1865 enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
1866 longlong val_int();
func_name()1867 const char *func_name() const { return "<is_not_null_test>"; }
1868 void update_used_tables();
1869 /**
1870 We add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE.
1871
1872 @retval Always RAND_TABLE_BIT
1873 */
get_initial_pseudo_tables()1874 table_map get_initial_pseudo_tables() const { return RAND_TABLE_BIT; }
1875 };
1876
1877
1878 class Item_func_isnotnull :public Item_bool_func
1879 {
1880 bool abort_on_null;
1881 public:
Item_func_isnotnull(Item * a)1882 Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
Item_func_isnotnull(const POS & pos,Item * a)1883 Item_func_isnotnull(const POS &pos, Item *a)
1884 : Item_bool_func(pos, a), abort_on_null(0)
1885 {}
1886
1887 longlong val_int();
functype()1888 enum Functype functype() const { return ISNOTNULL_FUNC; }
fix_length_and_dec()1889 void fix_length_and_dec()
1890 {
1891 decimals=0; max_length=1; maybe_null=0;
1892 }
func_name()1893 const char *func_name() const { return "isnotnull"; }
select_optimize()1894 optimize_type select_optimize() const { return OPTIMIZE_NULL; }
not_null_tables()1895 table_map not_null_tables() const
1896 { return abort_on_null ? not_null_tables_cache : 0; }
1897 Item *neg_transformer(THD *thd);
1898 virtual void print(String *str, enum_query_type query_type);
compare_collation()1899 const CHARSET_INFO *compare_collation()
1900 { return args[0]->collation.collation; }
top_level_item()1901 void top_level_item() { abort_on_null=1; }
1902
1903 float get_filtering_effect(table_map filter_for_table,
1904 table_map read_tables,
1905 const MY_BITMAP *fields_to_ignore,
1906 double rows_in_table);
1907 };
1908
1909
1910 class Item_func_like :public Item_bool_func2
1911 {
1912 typedef Item_bool_func2 super;
1913
1914 // Boyer-Moore data
1915 bool can_do_bm; // pattern is '%abcd%' case
1916 const char* pattern;
1917 int pattern_len;
1918
1919 // Boyer-Moore buffers, *this is owner
1920 int* bmGs; // good suffix shift table, size is pattern_len + 1
1921 int* bmBc; // bad character shift table, size is alphabet_size
1922
1923 void bm_compute_suffixes(int* suff);
1924 void bm_compute_good_suffix_shifts(int* suff);
1925 void bm_compute_bad_character_shifts();
1926 bool bm_matches(const char* text, size_t text_len) const;
1927 enum { alphabet_size = 256 };
1928
1929 Item *escape_item;
1930
1931 bool escape_used_in_parsing;
1932
1933 bool escape_evaluated; ///< Tells if the escape clause has been evaluated.
1934 bool eval_escape_clause(THD *thd);
1935
1936 public:
1937 int escape;
1938
Item_func_like(Item * a,Item * b,Item * escape_arg,bool escape_used)1939 Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1940 :Item_bool_func2(a,b), can_do_bm(false), pattern(0), pattern_len(0),
1941 bmGs(0), bmBc(0), escape_item(escape_arg),
1942 escape_used_in_parsing(escape_used), escape_evaluated(false) {}
Item_func_like(const POS & pos,Item * a,Item * b,Item * opt_escape_arg)1943 Item_func_like(const POS &pos, Item *a, Item *b, Item *opt_escape_arg)
1944 :super(pos, a, b), can_do_bm(false), pattern(0), pattern_len(0),
1945 bmGs(0), bmBc(0), escape_item(opt_escape_arg),
1946 escape_used_in_parsing(opt_escape_arg != NULL), escape_evaluated(false)
1947 {}
1948
1949 virtual bool itemize(Parse_context *pc, Item **res);
1950
1951 longlong val_int();
functype()1952 enum Functype functype() const { return LIKE_FUNC; }
1953 optimize_type select_optimize() const;
eq_cmp_result()1954 cond_result eq_cmp_result() const { return COND_TRUE; }
func_name()1955 const char *func_name() const { return "like"; }
1956 bool fix_fields(THD *thd, Item **ref);
1957 void cleanup();
1958 /**
1959 @retval true non default escape char specified
1960 using "expr LIKE pat ESCAPE 'escape_char'" syntax
1961 */
escape_was_used_in_parsing()1962 bool escape_was_used_in_parsing() const { return escape_used_in_parsing; }
1963
1964 /**
1965 Has the escape clause been evaluated? It only needs to be evaluated
1966 once per execution, since we require it to be constant during execution.
1967 The escape member has a valid value if and only if this function returns
1968 true.
1969 */
escape_is_evaluated()1970 bool escape_is_evaluated() const { return escape_evaluated; }
1971
1972 float get_filtering_effect(table_map filter_for_table,
1973 table_map read_tables,
1974 const MY_BITMAP *fields_to_ignore,
1975 double rows_in_table);
1976 };
1977
1978
1979 class Item_func_regex :public Item_bool_func
1980 {
1981 my_regex_t preg;
1982 bool regex_compiled;
1983 bool regex_is_const;
1984 String prev_regexp;
1985 DTCollation cmp_collation;
1986 const CHARSET_INFO *regex_lib_charset;
1987 int regex_lib_flags;
1988 String conv;
1989 int regcomp(bool send_error);
1990 public:
Item_func_regex(const POS & pos,Item * a,Item * b)1991 Item_func_regex(const POS &pos, Item *a,Item *b) :Item_bool_func(pos, a,b),
1992 regex_compiled(0),regex_is_const(0) {}
1993 void cleanup();
1994 longlong val_int();
1995 bool fix_fields(THD *thd, Item **ref);
func_name()1996 const char *func_name() const { return "regexp"; }
1997
print(String * str,enum_query_type query_type)1998 virtual inline void print(String *str, enum_query_type query_type)
1999 {
2000 print_op(str, query_type);
2001 }
2002
compare_collation()2003 const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
2004 };
2005
2006
2007 class Item_cond :public Item_bool_func
2008 {
2009 typedef Item_bool_func super;
2010
2011 protected:
2012 List<Item> list;
2013 bool abort_on_null;
2014
2015 public:
2016 /* Item_cond() is only used to create top level items */
Item_cond()2017 Item_cond(): Item_bool_func(), abort_on_null(1)
2018 { const_item_cache=0; }
2019
Item_cond(Item * i1,Item * i2)2020 Item_cond(Item *i1,Item *i2)
2021 :Item_bool_func(), abort_on_null(0)
2022 {
2023 list.push_back(i1);
2024 list.push_back(i2);
2025 }
Item_cond(const POS & pos,Item * i1,Item * i2)2026 Item_cond(const POS &pos, Item *i1, Item *i2)
2027 :Item_bool_func(pos), abort_on_null(0)
2028 {
2029 list.push_back(i1);
2030 list.push_back(i2);
2031 }
2032
2033 Item_cond(THD *thd, Item_cond *item);
Item_cond(List<Item> & nlist)2034 Item_cond(List<Item> &nlist)
2035 :Item_bool_func(), list(nlist), abort_on_null(0) {}
add(Item * item)2036 bool add(Item *item)
2037 {
2038 assert(item);
2039 return list.push_back(item);
2040 }
add_at_head(Item * item)2041 bool add_at_head(Item *item)
2042 {
2043 assert(item);
2044 return list.push_front(item);
2045 }
add_at_head(List<Item> * nlist)2046 void add_at_head(List<Item> *nlist)
2047 {
2048 assert(nlist->elements);
2049 list.prepand(nlist);
2050 }
2051
2052 virtual bool itemize(Parse_context *pc, Item **res);
2053
2054 bool fix_fields(THD *, Item **ref);
2055 void fix_after_pullout(st_select_lex *parent_select,
2056 st_select_lex *removed_select);
2057
type()2058 enum Type type() const { return COND_ITEM; }
argument_list()2059 List<Item>* argument_list() { return &list; }
2060 bool eq(const Item *item, bool binary_cmp) const;
used_tables()2061 table_map used_tables() const { return used_tables_cache; }
2062 void update_used_tables();
2063 virtual void print(String *str, enum_query_type query_type);
2064 void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
2065 List<Item> &fields);
top_level_item()2066 void top_level_item() { abort_on_null=1; }
2067 void copy_andor_arguments(THD *thd, Item_cond *item);
2068 bool walk(Item_processor processor, enum_walk walk, uchar *arg);
2069 Item *transform(Item_transformer transformer, uchar *arg);
2070 void traverse_cond(Cond_traverser, void *arg, traverse_order order);
2071 void neg_arguments(THD *thd);
field_type()2072 enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
subst_argument_checker(uchar ** arg)2073 bool subst_argument_checker(uchar **arg) { return TRUE; }
2074 Item *compile(Item_analyzer analyzer, uchar **arg_p,
2075 Item_transformer transformer, uchar *arg_t);
2076
equality_substitution_analyzer(uchar ** arg)2077 virtual bool equality_substitution_analyzer(uchar **arg) { return true; }
2078 };
2079
2080
2081 /*
2082 The class Item_equal is used to represent conjunctions of equality
2083 predicates of the form field1 = field2, and field=const in where
2084 conditions and on expressions.
2085
2086 All equality predicates of the form field1=field2 contained in a
2087 conjunction are substituted for a sequence of items of this class.
2088 An item of this class Item_equal(f1,f2,...fk) represents a
2089 multiple equality f1=f2=...=fk.
2090
2091 If a conjunction contains predicates f1=f2 and f2=f3, a new item of
2092 this class is created Item_equal(f1,f2,f3) representing the multiple
2093 equality f1=f2=f3 that substitutes the above equality predicates in
2094 the conjunction.
2095 A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
2096 substituted for the item representing the same multiple equality
2097 f1=f2=f3.
2098 An item Item_equal(f1,f2) can appear instead of a conjunction of
2099 f2=f1 and f1=f2, or instead of just the predicate f1=f2.
2100
2101 An item of the class Item_equal inherits equalities from outer
2102 conjunctive levels.
2103
2104 Suppose we have a where condition of the following form:
2105 WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
2106 In this case:
2107 f1=f2 will be substituted for Item_equal(f1,f2);
2108 f3=f4 and f3=f5 will be substituted for Item_equal(f3,f4,f5);
2109 f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
2110
2111 An object of the class Item_equal can contain an optional constant
2112 item c. Then it represents a multiple equality of the form
2113 c=f1=...=fk.
2114
2115 Objects of the class Item_equal are used for the following:
2116
2117 1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
2118 pair of tables ti and tj as joined by an equi-condition.
2119 Thus it provide us with additional access paths from table to table.
2120
2121 2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
2122 SARGable predicates:
2123 f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
2124 It also can give us additional index scans and can allow us to
2125 improve selectivity estimates.
2126
2127 3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
2128 selected execution plan for the query: if table ti is accessed
2129 before the table tj then in any predicate P in the where condition
2130 the occurrence of tj.fj is substituted for ti.fi. This can allow
2131 an evaluation of the predicate at an earlier step.
2132
2133 When feature 1 is supported they say that join transitive closure
2134 is employed.
2135 When feature 2 is supported they say that search argument transitive
2136 closure is employed.
2137 Both features are usually supported by preprocessing original query and
2138 adding additional predicates.
2139 We do not just add predicates, we rather dynamically replace some
2140 predicates that can not be used to access tables in the investigated
2141 plan for those, obtained by substitution of some fields for equal fields,
2142 that can be used.
2143
2144 Prepared Statements/Stored Procedures note: instances of class
2145 Item_equal are created only at the time a PS/SP is executed and
2146 are deleted in the end of execution. All changes made to these
2147 objects need not be registered in the list of changes of the parse
2148 tree and do not harm PS/SP re-execution.
2149
2150 Item equal objects are employed only at the optimize phase. Usually they are
2151 not supposed to be evaluated. Yet in some cases we call the method val_int()
2152 for them. We have to take care of restricting the predicate such an
2153 object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
2154 */
2155 struct st_join_table;
2156
2157 class Item_equal: public Item_bool_func
2158 {
2159 List<Item_field> fields; /* list of equal field items */
2160 Item *const_item; /* optional constant item equal to fields items */
2161 cmp_item *eval_item;
2162 Arg_comparator cmp;
2163 bool cond_false;
2164 bool compare_as_dates;
2165 public:
Item_equal()2166 inline Item_equal()
2167 : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
2168 { const_item_cache=0 ;}
2169 Item_equal(Item_field *f1, Item_field *f2);
2170 Item_equal(Item *c, Item_field *f);
2171 Item_equal(Item_equal *item_equal);
~Item_equal()2172 virtual ~Item_equal()
2173 {
2174 delete eval_item;
2175 }
2176
get_const()2177 inline Item* get_const() { return const_item; }
2178 bool compare_const(THD *thd, Item *c);
2179 bool add(THD *thd, Item *c, Item_field *f);
2180 bool add(THD *thd, Item *c);
2181 void add(Item_field *f);
2182 uint members();
2183 bool contains(Field *field);
2184 /**
2185 Get the first field of multiple equality, use for semantic checking.
2186
2187 @retval First field in the multiple equality.
2188 */
get_first()2189 Item_field* get_first() { return fields.head(); }
2190 Item_field* get_subst_item(const Item_field *field);
2191 bool merge(THD *thd, Item_equal *item);
2192 bool update_const(THD *thd);
functype()2193 enum Functype functype() const { return MULT_EQUAL_FUNC; }
2194 longlong val_int();
func_name()2195 const char *func_name() const { return "multiple equal"; }
select_optimize()2196 optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
2197 void sort(Item_field_cmpfunc compare, void *arg);
2198 friend class Item_equal_iterator;
2199 void fix_length_and_dec();
2200 bool fix_fields(THD *thd, Item **ref);
2201 void update_used_tables();
2202 bool walk(Item_processor processor, enum_walk walk, uchar *arg);
2203 Item *transform(Item_transformer transformer, uchar *arg);
2204 virtual void print(String *str, enum_query_type query_type);
compare_collation()2205 const CHARSET_INFO *compare_collation()
2206 { return fields.head()->collation.collation; }
2207
equality_substitution_analyzer(uchar ** arg)2208 virtual bool equality_substitution_analyzer(uchar **arg) { return true; }
2209
2210 virtual Item* equality_substitution_transformer(uchar *arg);
2211
2212 float get_filtering_effect(table_map filter_for_table,
2213 table_map read_tables,
2214 const MY_BITMAP *fields_to_ignore,
2215 double rows_in_table);
2216 };
2217
2218 class COND_EQUAL: public Sql_alloc
2219 {
2220 public:
2221 uint max_members; /* max number of members the current level
2222 list and all lower level lists */
2223 COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
2224 List<Item_equal> current_level; /* list of multiple equalities of
2225 the current and level */
COND_EQUAL()2226 COND_EQUAL()
2227 {
2228 upper_levels= 0;
2229 }
2230 };
2231
2232
2233 class Item_equal_iterator : public List_iterator_fast<Item_field>
2234 {
2235 public:
Item_equal_iterator(Item_equal & item_equal)2236 inline Item_equal_iterator(Item_equal &item_equal)
2237 :List_iterator_fast<Item_field> (item_equal.fields)
2238 {}
2239 inline Item_field* operator++(int)
2240 {
2241 Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
2242 return item;
2243 }
rewind(void)2244 inline void rewind(void)
2245 {
2246 List_iterator_fast<Item_field>::rewind();
2247 }
2248 };
2249
2250 class Item_cond_and :public Item_cond
2251 {
2252 public:
2253 COND_EQUAL cond_equal; /* contains list of Item_equal objects for
2254 the current and level and reference
2255 to multiple equalities of upper and levels */
Item_cond_and()2256 Item_cond_and() :Item_cond() {}
2257
Item_cond_and(Item * i1,Item * i2)2258 Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
Item_cond_and(const POS & pos,Item * i1,Item * i2)2259 Item_cond_and(const POS &pos, Item *i1, Item *i2) :Item_cond(pos, i1, i2) {}
2260
Item_cond_and(THD * thd,Item_cond_and * item)2261 Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
Item_cond_and(List<Item> & list_arg)2262 Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
functype()2263 enum Functype functype() const { return COND_AND_FUNC; }
2264 longlong val_int();
func_name()2265 const char *func_name() const { return "and"; }
copy_andor_structure(THD * thd)2266 Item* copy_andor_structure(THD *thd)
2267 {
2268 Item_cond_and *item;
2269 if ((item= new Item_cond_and(thd, this)))
2270 item->copy_andor_arguments(thd, this);
2271 return item;
2272 }
2273 Item *neg_transformer(THD *thd);
gc_subst_analyzer(uchar ** arg)2274 bool gc_subst_analyzer(uchar **arg) { return true; }
2275
2276 float get_filtering_effect(table_map filter_for_table,
2277 table_map read_tables,
2278 const MY_BITMAP *fields_to_ignore,
2279 double rows_in_table);
2280 };
2281
2282
2283 class Item_cond_or :public Item_cond
2284 {
2285 public:
Item_cond_or()2286 Item_cond_or() :Item_cond() {}
2287
Item_cond_or(Item * i1,Item * i2)2288 Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
Item_cond_or(const POS & pos,Item * i1,Item * i2)2289 Item_cond_or(const POS &pos, Item *i1,Item *i2) :Item_cond(pos, i1, i2) {}
2290
Item_cond_or(THD * thd,Item_cond_or * item)2291 Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
Item_cond_or(List<Item> & list_arg)2292 Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
functype()2293 enum Functype functype() const { return COND_OR_FUNC; }
2294 longlong val_int();
func_name()2295 const char *func_name() const { return "or"; }
copy_andor_structure(THD * thd)2296 Item* copy_andor_structure(THD *thd)
2297 {
2298 Item_cond_or *item;
2299 if ((item= new Item_cond_or(thd, this)))
2300 item->copy_andor_arguments(thd, this);
2301 return item;
2302 }
2303 Item *neg_transformer(THD *thd);
gc_subst_analyzer(uchar ** arg)2304 bool gc_subst_analyzer(uchar **arg) { return true; }
2305
2306 float get_filtering_effect(table_map filter_for_table,
2307 table_map read_tables,
2308 const MY_BITMAP *fields_to_ignore,
2309 double rows_in_table);
2310 };
2311
2312 /* Some useful inline functions */
2313
and_conds(Item * a,Item * b)2314 inline Item *and_conds(Item *a, Item *b)
2315 {
2316 if (!b) return a;
2317 if (!a) return b;
2318 return new Item_cond_and(a, b);
2319 }
2320
2321
2322 Item *and_expressions(Item *a, Item *b, Item **org_item);
2323
2324 longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
2325 const Item *warn_item, bool *is_null);
2326
2327
2328 bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
2329 const char *warn_name, MYSQL_TIME *l_time);
2330 /*
2331 These need definitions from this file but the variables are defined
2332 in mysqld.h. The variables really belong in this component, but for
2333 the time being we leave them in mysqld.cc to avoid merge problems.
2334 */
2335 extern Eq_creator eq_creator;
2336 extern Equal_creator equal_creator;
2337 extern Ne_creator ne_creator;
2338 extern Gt_creator gt_creator;
2339 extern Lt_creator lt_creator;
2340 extern Ge_creator ge_creator;
2341 extern Le_creator le_creator;
2342
2343 #endif /* ITEM_CMPFUNC_INCLUDED */
2344