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 #ifdef MYSQL_SERVER
962
963 class Item_func_interval :public Item_int_func
964 {
965 typedef Item_int_func super;
966
967 Item_row *row;
968 my_bool use_decimal_comparison;
969 interval_range *intervals;
970 public:
971 Item_func_interval(const POS &pos, MEM_ROOT *mem_root, Item *expr1,
972 Item *expr2, class PT_item_list *opt_expr_list= NULL)
super(pos,alloc_row (pos,mem_root,expr1,expr2,opt_expr_list))973 :super(pos, alloc_row(pos, mem_root, expr1, expr2, opt_expr_list)),
974 intervals(0)
975 {
976 allowed_arg_cols= 0; // Fetch this value from first argument
977 }
978
979 virtual bool itemize(Parse_context *pc, Item **res);
980 longlong val_int();
981 void fix_length_and_dec();
func_name()982 const char *func_name() const { return "interval"; }
decimal_precision()983 uint decimal_precision() const { return 2; }
984 void print(String *str, enum_query_type query_type);
985
986 private:
987 Item_row *alloc_row(const POS &pos, MEM_ROOT *mem_root, Item *expr1,
988 Item *expr2, class PT_item_list *opt_expr_list);
989 };
990
991
992 class Item_func_coalesce :public Item_func_numhybrid
993 {
994 protected:
995 enum_field_types cached_field_type;
Item_func_coalesce(const POS & pos,Item * a,Item * b)996 Item_func_coalesce(const POS &pos, Item *a, Item *b)
997 : Item_func_numhybrid(pos, a, b)
998 {}
Item_func_coalesce(const POS & pos,Item * a)999 Item_func_coalesce(const POS &pos, Item *a)
1000 : Item_func_numhybrid(pos, a)
1001 {}
1002 public:
1003 Item_func_coalesce(const POS &pos, PT_item_list *list);
1004 double real_op();
1005 longlong int_op();
1006 String *str_op(String *);
1007 /**
1008 Get the result of COALESCE as a JSON value.
1009 @param[in,out] wr the result value holder
1010 */
1011 bool val_json(Json_wrapper *wr);
1012 bool date_op(MYSQL_TIME *ltime, my_time_flags_t fuzzydate);
1013 bool time_op(MYSQL_TIME *ltime);
1014 my_decimal *decimal_op(my_decimal *);
1015 void fix_length_and_dec();
find_num_type()1016 void find_num_type() {}
result_type()1017 enum Item_result result_type () const { return hybrid_type; }
func_name()1018 const char *func_name() const { return "coalesce"; }
not_null_tables()1019 table_map not_null_tables() const { return 0; }
field_type()1020 enum_field_types field_type() const { return cached_field_type; }
1021 };
1022
1023
1024 class Item_func_ifnull :public Item_func_coalesce
1025 {
1026 protected:
1027 bool field_type_defined;
1028 public:
Item_func_ifnull(const POS & pos,Item * a,Item * b)1029 Item_func_ifnull(const POS &pos, Item *a, Item *b)
1030 : Item_func_coalesce(pos, a, b)
1031 {}
1032 double real_op();
1033 longlong int_op();
1034 String *str_op(String *str);
1035 bool date_op(MYSQL_TIME *ltime, my_time_flags_t fuzzydate);
1036 bool time_op(MYSQL_TIME *ltime);
1037 my_decimal *decimal_op(my_decimal *);
1038 bool val_json(Json_wrapper *result);
1039 void fix_length_and_dec();
func_name()1040 const char *func_name() const { return "ifnull"; }
1041 Field *tmp_table_field(TABLE *table);
1042 uint decimal_precision() const;
1043 };
1044
1045
1046 /**
1047 ANY_VALUE(expr) is like expr except that it is not checked by
1048 aggregate_check logic. It serves as a solution for users who want to
1049 bypass this logic.
1050 */
1051 class Item_func_any_value :public Item_func_coalesce
1052 {
1053 public:
Item_func_any_value(const POS & pos,Item * a)1054 Item_func_any_value(const POS &pos, Item *a) :Item_func_coalesce(pos, a) {}
func_name()1055 const char *func_name() const { return "any_value"; }
1056 bool aggregate_check_group(uchar *arg);
1057 bool aggregate_check_distinct(uchar *arg);
1058 };
1059
1060
1061 class Item_func_if :public Item_func
1062 {
1063 enum Item_result cached_result_type;
1064 enum_field_types cached_field_type;
1065 public:
Item_func_if(Item * a,Item * b,Item * c)1066 Item_func_if(Item *a,Item *b,Item *c)
1067 :Item_func(a,b,c), cached_result_type(INT_RESULT)
1068 {}
Item_func_if(const POS & pos,Item * a,Item * b,Item * c)1069 Item_func_if(const POS &pos, Item *a,Item *b,Item *c)
1070 :Item_func(pos, a,b,c), cached_result_type(INT_RESULT)
1071 {}
1072
1073 double val_real();
1074 longlong val_int();
1075 String *val_str(String *str);
1076 my_decimal *val_decimal(my_decimal *);
1077 bool val_json(Json_wrapper *wr);
1078 bool get_date(MYSQL_TIME *ltime, my_time_flags_t fuzzydate);
1079 bool get_time(MYSQL_TIME *ltime);
result_type()1080 enum Item_result result_type () const { return cached_result_type; }
field_type()1081 enum_field_types field_type() const { return cached_field_type; }
1082 bool fix_fields(THD *, Item **);
1083 void fix_length_and_dec();
1084 void fix_after_pullout(st_select_lex *parent_select,
1085 st_select_lex *removed_select);
1086 uint decimal_precision() const;
func_name()1087 const char *func_name() const { return "if"; }
1088 private:
1089 void cache_type_info(Item *source);
1090 };
1091
1092
1093 class Item_func_nullif :public Item_bool_func2
1094 {
1095 enum Item_result cached_result_type;
1096 public:
Item_func_nullif(const POS & pos,Item * a,Item * b)1097 Item_func_nullif(const POS &pos, Item *a, Item *b)
1098 :Item_bool_func2(pos, a, b), cached_result_type(INT_RESULT)
1099 {}
1100 double val_real();
1101 longlong val_int();
1102 String *val_str(String *str);
1103 my_decimal *val_decimal(my_decimal *);
result_type()1104 enum Item_result result_type () const { return cached_result_type; }
1105 void fix_length_and_dec();
decimal_precision()1106 uint decimal_precision() const { return args[0]->decimal_precision(); }
func_name()1107 const char *func_name() const { return "nullif"; }
1108
print(String * str,enum_query_type query_type)1109 virtual inline void print(String *str, enum_query_type query_type)
1110 {
1111 Item_func::print(str, query_type);
1112 }
1113
not_null_tables()1114 table_map not_null_tables() const { return 0; }
1115 bool is_null();
1116 };
1117
1118
1119 /* Functions to handle the optimized IN */
1120
1121
1122 /* A vector of values of some type */
1123
1124 class in_vector :public Sql_alloc
1125 {
1126 public:
1127 const uint count; ///< Original size of the vector
1128 uint used_count; ///< The actual size of the vector (NULL may be ignored)
1129
1130 /**
1131 See Item_func_in::fix_length_and_dec for why we need both
1132 count and used_count.
1133 */
in_vector(uint elements)1134 explicit in_vector(uint elements)
1135 : count(elements), used_count(elements)
1136 {}
1137
~in_vector()1138 virtual ~in_vector() {}
1139 virtual void set(uint pos,Item *item)=0;
1140 virtual uchar *get_value(Item *item)=0;
1141
1142 /**
1143 Shrinks the IN-list array, to fit actual usage.
1144 */
1145 virtual void shrink_array(size_t n) = 0;
1146
1147 /**
1148 Sorts the IN-list array, so we can do efficient lookup with binary_search.
1149 */
1150 virtual void sort() = 0;
1151
1152 /**
1153 Calls (the virtual) get_value, i.e. item->val_int() or item->val_str() etc.
1154 and then calls find_value() if the value is non-null.
1155 @param item to evaluate, and lookup in the IN-list.
1156 @return true if item was found.
1157 */
1158 bool find_item(Item *item);
1159
1160 /**
1161 Does a binary_search in the 'base' array for the input 'value'
1162 @param value to lookup in the IN-list.
1163 @return true if value was found.
1164 */
1165 virtual bool find_value(const void *value) const = 0;
1166
1167 /*
1168 Create an instance of Item_{type} (e.g. Item_decimal) constant object
1169 which type allows it to hold an element of this vector without any
1170 conversions.
1171 The purpose of this function is to be able to get elements of this
1172 vector in form of Item_xxx constants without creating Item_xxx object
1173 for every array element you get (i.e. this implements "FlyWeight" pattern)
1174 */
create_item()1175 virtual Item* create_item() { return NULL; }
1176
1177 /*
1178 Store the value at position #pos into provided item object
1179 SYNOPSIS
1180 value_to_item()
1181 pos Index of value to store
1182 item Constant item to store value into. The item must be of the same
1183 type that create_item() returns.
1184 */
value_to_item(uint pos,Item * item)1185 virtual void value_to_item(uint pos, Item *item) { }
1186
1187 /* Compare values number pos1 and pos2 for equality */
1188 virtual bool compare_elems(uint pos1, uint pos2) const = 0;
1189
1190 virtual Item_result result_type()= 0;
1191 };
1192
1193 class in_string :public in_vector
1194 {
1195 char buff[STRING_BUFFER_USUAL_SIZE];
1196 String tmp;
1197 // DTOR is not trivial, but we manage memory ourselves.
1198 Mem_root_array<String, true> base_objects;
1199 // String objects are not sortable, sort pointers instead.
1200 Mem_root_array<String*, true> base_pointers;
1201
1202 qsort2_cmp compare;
1203 const CHARSET_INFO *collation;
1204 public:
1205 in_string(THD *thd,
1206 uint elements, qsort2_cmp cmp_func, const CHARSET_INFO *cs);
1207 ~in_string();
1208 void set(uint pos,Item *item);
1209 uchar *get_value(Item *item);
create_item()1210 Item* create_item()
1211 {
1212 return new Item_string(collation);
1213 }
value_to_item(uint pos,Item * item)1214 void value_to_item(uint pos, Item *item)
1215 {
1216 String *str= base_pointers[pos];
1217 Item_string *to= (Item_string*)item;
1218 to->str_value= *str;
1219 }
result_type()1220 Item_result result_type() { return STRING_RESULT; }
1221
shrink_array(size_t n)1222 virtual void shrink_array(size_t n) { base_pointers.resize(n); }
1223
1224 virtual void sort();
1225 virtual bool find_value(const void *value) const;
1226 virtual bool compare_elems(uint pos1, uint pos2) const;
1227 };
1228
1229 class in_longlong :public in_vector
1230 {
1231 public:
1232 struct packed_longlong
1233 {
1234 longlong val;
1235 longlong unsigned_flag;
1236 };
1237 protected:
1238 /*
1239 Here we declare a temporary variable (tmp) of the same type as the
1240 elements of this vector. tmp is used in finding if a given value is in
1241 the list.
1242 */
1243 packed_longlong tmp;
1244
1245 Mem_root_array<packed_longlong, true> base;
1246
1247 public:
1248 in_longlong(THD *thd, uint elements);
1249 void set(uint pos,Item *item);
1250 uchar *get_value(Item *item);
1251
create_item()1252 Item* create_item()
1253 {
1254 /*
1255 We're created a signed INT, this may not be correct in
1256 general case (see BUG#19342).
1257 */
1258 return new Item_int((longlong)0);
1259 }
value_to_item(uint pos,Item * item)1260 void value_to_item(uint pos, Item *item)
1261 {
1262 ((Item_int*) item)->value= base[pos].val;
1263 ((Item_int*) item)->unsigned_flag= (my_bool)
1264 base[pos].unsigned_flag;
1265 }
result_type()1266 Item_result result_type() { return INT_RESULT; }
1267
shrink_array(size_t n)1268 virtual void shrink_array(size_t n) { base.resize(n); }
1269
1270 virtual void sort();
1271 virtual bool find_value(const void *value) const;
1272 virtual bool compare_elems(uint pos1, uint pos2) const;
1273 };
1274
1275
1276 class in_datetime_as_longlong :public in_longlong
1277 {
1278 public:
in_datetime_as_longlong(THD * thd,uint elements)1279 in_datetime_as_longlong(THD *thd, uint elements)
1280 : in_longlong(thd, elements)
1281 {};
create_item()1282 Item *create_item()
1283 {
1284 return new Item_temporal(MYSQL_TYPE_DATETIME, 0LL);
1285 }
1286 void set(uint pos, Item *item);
1287 uchar *get_value(Item *item);
1288 };
1289
1290
1291 class in_time_as_longlong :public in_longlong
1292 {
1293 public:
in_time_as_longlong(THD * thd,uint elements)1294 in_time_as_longlong(THD *thd, uint elements)
1295 : in_longlong(thd, elements)
1296 {};
create_item()1297 Item *create_item()
1298 {
1299 return new Item_temporal(MYSQL_TYPE_TIME, 0LL);
1300 }
1301 void set(uint pos, Item *item);
1302 uchar *get_value(Item *item);
1303 };
1304
1305
1306 /*
1307 Class to represent a vector of constant DATE/DATETIME values.
1308 Values are obtained with help of the get_datetime_value() function.
1309 If the left item is a constant one then its value is cached in the
1310 lval_cache variable.
1311 */
1312 class in_datetime :public in_longlong
1313 {
1314 public:
1315 /* An item used to issue warnings. */
1316 Item *warn_item;
1317 /* Cache for the left item. */
1318 Item *lval_cache;
1319
in_datetime(THD * thd_arg,Item * warn_item_arg,uint elements)1320 in_datetime(THD *thd_arg, Item *warn_item_arg, uint elements)
1321 : in_longlong(thd_arg, elements), warn_item(warn_item_arg),
1322 lval_cache(0)
1323 {};
1324 void set(uint pos,Item *item);
1325 uchar *get_value(Item *item);
1326
create_item()1327 Item* create_item()
1328 {
1329 return new Item_temporal(MYSQL_TYPE_DATETIME, (longlong) 0);
1330 }
1331 };
1332
1333
1334 class in_double :public in_vector
1335 {
1336 double tmp;
1337 Mem_root_array<double, true> base;
1338 public:
1339 in_double(THD *thd, uint elements);
1340 void set(uint pos,Item *item);
1341 uchar *get_value(Item *item);
create_item()1342 Item *create_item()
1343 {
1344 return new Item_float(0.0, 0);
1345 }
value_to_item(uint pos,Item * item)1346 void value_to_item(uint pos, Item *item)
1347 {
1348 ((Item_float*)item)->value= base[pos];
1349 }
result_type()1350 Item_result result_type() { return REAL_RESULT; }
1351
shrink_array(size_t n)1352 virtual void shrink_array(size_t n) { base.resize(n); }
1353
1354 virtual void sort();
1355 virtual bool find_value(const void *value) const;
1356 virtual bool compare_elems(uint pos1, uint pos2) const;
1357 };
1358
1359
1360 class in_decimal :public in_vector
1361 {
1362 my_decimal val;
1363 Mem_root_array<my_decimal, true> base;
1364 public:
1365 in_decimal(THD *thd, uint elements);
1366 void set(uint pos, Item *item);
1367 uchar *get_value(Item *item);
create_item()1368 Item *create_item()
1369 {
1370 return new Item_decimal(0, FALSE);
1371 }
value_to_item(uint pos,Item * item)1372 void value_to_item(uint pos, Item *item)
1373 {
1374 my_decimal *dec= &base[pos];
1375 Item_decimal *item_dec= (Item_decimal*)item;
1376 item_dec->set_decimal_value(dec);
1377 }
result_type()1378 Item_result result_type() { return DECIMAL_RESULT; }
1379
shrink_array(size_t n)1380 virtual void shrink_array(size_t n) { base.resize(n); }
1381
1382 virtual void sort();
1383 virtual bool find_value(const void *value) const;
1384 virtual bool compare_elems(uint pos1, uint pos2) const;
1385 };
1386
1387
1388 /*
1389 ** Classes for easy comparing of non const items
1390 */
1391
1392 class cmp_item :public Sql_alloc
1393 {
1394 public:
cmp_item()1395 cmp_item() {}
~cmp_item()1396 virtual ~cmp_item() {}
1397 virtual void store_value(Item *item)= 0;
1398 /**
1399 @returns result (TRUE, FALSE or UNKNOWN) of
1400 "stored argument's value <> item's value"
1401 */
1402 virtual int cmp(Item *item)= 0;
1403 // for optimized IN with row
1404 virtual int compare(const cmp_item *item) const= 0;
1405
1406 /**
1407 Find the appropriate comparator for the given type.
1408
1409 @param result_type Used to find the appropriate comparator.
1410 @param item Item object used to distinguish temporal types.
1411 @param cs Charset
1412
1413 @return
1414 New cmp_item_xxx object.
1415 */
1416 static cmp_item* get_comparator(Item_result result_type, const Item *item,
1417 const CHARSET_INFO *cs);
1418 virtual cmp_item *make_same()= 0;
store_value_by_template(cmp_item * tmpl,Item * item)1419 virtual void store_value_by_template(cmp_item *tmpl, Item *item)
1420 {
1421 store_value(item);
1422 }
1423 };
1424
1425 /// cmp_item which stores a scalar (i.e. non-ROW).
1426 class cmp_item_scalar : public cmp_item
1427 {
1428 protected:
1429 bool m_null_value; ///< If stored value is NULL
set_null_value(bool nv)1430 void set_null_value(bool nv) { m_null_value= nv; }
1431 };
1432
1433 class cmp_item_string : public cmp_item_scalar
1434 {
1435 private:
1436 String *value_res;
1437 char value_buff[STRING_BUFFER_USUAL_SIZE];
1438 String value;
1439 const CHARSET_INFO *cmp_charset;
1440 public:
cmp_item_string(const CHARSET_INFO * cs)1441 cmp_item_string (const CHARSET_INFO *cs)
1442 : value(value_buff, sizeof(value_buff), cs), cmp_charset(cs)
1443 {}
1444
compare(const cmp_item * ci)1445 virtual int compare(const cmp_item *ci) const
1446 {
1447 const cmp_item_string *l_cmp= down_cast<const cmp_item_string*>(ci);
1448 return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1449 }
1450
store_value(Item * item)1451 virtual void store_value(Item *item)
1452 {
1453 String *res= item->val_str(&value);
1454 if (res && (res != &value || !res->is_alloced()))
1455 {
1456 // 'res' may point in item's transient internal data, so make a copy
1457 value.copy(*res);
1458 }
1459 value_res= &value;
1460 set_null_value(item->null_value);
1461 }
1462
cmp(Item * arg)1463 virtual int cmp(Item *arg)
1464 {
1465 char buff[STRING_BUFFER_USUAL_SIZE];
1466 String tmp(buff, sizeof(buff), cmp_charset);
1467 String *res= arg->val_str(&tmp);
1468 if (m_null_value || arg->null_value)
1469 return UNKNOWN;
1470 if (value_res && res)
1471 return sortcmp(value_res, res, cmp_charset) != 0;
1472 else if (!value_res && !res)
1473 return FALSE;
1474 else
1475 return TRUE;
1476 }
1477 virtual cmp_item *make_same();
1478 };
1479
1480
1481 class cmp_item_int : public cmp_item_scalar
1482 {
1483 longlong value;
1484 public:
cmp_item_int()1485 cmp_item_int() {} /* Remove gcc warning */
store_value(Item * item)1486 void store_value(Item *item)
1487 {
1488 value= item->val_int();
1489 set_null_value(item->null_value);
1490 }
cmp(Item * arg)1491 int cmp(Item *arg)
1492 {
1493 const bool rc= value != arg->val_int();
1494 return (m_null_value || arg->null_value) ? UNKNOWN : rc;
1495 }
compare(const cmp_item * ci)1496 int compare(const cmp_item *ci) const
1497 {
1498 const cmp_item_int *l_cmp= down_cast<const cmp_item_int*>(ci);
1499 return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
1500 }
1501 cmp_item *make_same();
1502 };
1503
1504 /*
1505 Compare items of temporal type.
1506 Values are obtained with: get_datetime_value() (DATE/DATETIME/TIMESTAMP) and
1507 get_time_value() (TIME).
1508 If the left item is a constant one then its value is cached in the
1509 lval_cache variable.
1510 */
1511 class cmp_item_datetime : public cmp_item_scalar
1512 {
1513 longlong value;
1514 public:
1515 /* Item used for issuing warnings. */
1516 const Item *warn_item;
1517 /* Cache for the left item. */
1518 Item *lval_cache;
1519 /// Distinguish between DATE/DATETIME/TIMESTAMP and TIME
1520 bool has_date;
1521
1522 cmp_item_datetime(const Item *warn_item_arg);
1523 void store_value(Item *item);
1524 int cmp(Item *arg);
1525 int compare(const cmp_item *ci) const;
1526 cmp_item *make_same();
1527 };
1528
1529 class cmp_item_real : public cmp_item_scalar
1530 {
1531 double value;
1532 public:
cmp_item_real()1533 cmp_item_real() {} /* Remove gcc warning */
store_value(Item * item)1534 void store_value(Item *item)
1535 {
1536 value= item->val_real();
1537 set_null_value(item->null_value);
1538 }
cmp(Item * arg)1539 int cmp(Item *arg)
1540 {
1541 const bool rc= value != arg->val_real();
1542 return (m_null_value || arg->null_value) ? UNKNOWN : rc;
1543 }
compare(const cmp_item * ci)1544 int compare(const cmp_item *ci) const
1545 {
1546 const cmp_item_real *l_cmp= down_cast<const cmp_item_real*>(ci);
1547 return (value < l_cmp->value)? -1 : ((value == l_cmp->value) ? 0 : 1);
1548 }
1549 cmp_item *make_same();
1550 };
1551
1552
1553 class cmp_item_decimal : public cmp_item_scalar
1554 {
1555 my_decimal value;
1556 public:
cmp_item_decimal()1557 cmp_item_decimal() {} /* Remove gcc warning */
1558 void store_value(Item *item);
1559 int cmp(Item *arg);
1560 int compare(const cmp_item *c) const;
1561 cmp_item *make_same();
1562 };
1563
1564
1565 /*
1566 The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1567 implementation.
1568
1569 When there is no expression between CASE and the first WHEN
1570 (the CASE expression) then this function simple checks all WHEN expressions
1571 one after another. When some WHEN expression evaluated to TRUE then the
1572 value of the corresponding THEN expression is returned.
1573
1574 When the CASE expression is specified then it is compared to each WHEN
1575 expression individually. When an equal WHEN expression is found
1576 corresponding THEN expression is returned.
1577 In order to do correct comparisons several comparators are used. One for
1578 each result type. Different result types that are used in particular
1579 CASE ... END expression are collected in the fix_length_and_dec() member
1580 function and only comparators for there result types are used.
1581 */
1582
1583 class Item_func_case :public Item_func
1584 {
1585 typedef Item_func super;
1586
1587 int first_expr_num, else_expr_num;
1588 enum Item_result cached_result_type, left_result_type;
1589 String tmp_value;
1590 uint ncases;
1591 Item_result cmp_type;
1592 DTCollation cmp_collation;
1593 enum_field_types cached_field_type;
1594 cmp_item *cmp_items[5]; /* For all result types */
1595 cmp_item *case_item;
1596 public:
Item_func_case(const POS & pos,List<Item> & list,Item * first_expr_arg,Item * else_expr_arg)1597 Item_func_case(const POS &pos, List<Item> &list, Item *first_expr_arg,
1598 Item *else_expr_arg)
1599 : super(pos), first_expr_num(-1), else_expr_num(-1),
1600 cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
1601 {
1602 ncases= list.elements;
1603 if (first_expr_arg)
1604 {
1605 first_expr_num= list.elements;
1606 list.push_back(first_expr_arg);
1607 }
1608 if (else_expr_arg)
1609 {
1610 else_expr_num= list.elements;
1611 list.push_back(else_expr_arg);
1612 }
1613 set_arguments(list, true);
1614 memset(&cmp_items, 0, sizeof(cmp_items));
1615 }
1616 double val_real();
1617 longlong val_int();
1618 String *val_str(String *);
1619 my_decimal *val_decimal(my_decimal *);
1620 bool val_json(Json_wrapper *wr);
1621 bool get_date(MYSQL_TIME *ltime, my_time_flags_t fuzzydate);
1622 bool get_time(MYSQL_TIME *ltime);
1623 bool fix_fields(THD *thd, Item **ref);
1624 void fix_length_and_dec();
1625 uint decimal_precision() const;
not_null_tables()1626 table_map not_null_tables() const { return 0; }
result_type()1627 enum Item_result result_type () const { return cached_result_type; }
field_type()1628 enum_field_types field_type() const { return cached_field_type; }
func_name()1629 const char *func_name() const { return "case"; }
1630 virtual void print(String *str, enum_query_type query_type);
1631 Item *find_item(String *str);
compare_collation()1632 const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1633 void cleanup();
1634 };
1635
1636 /*
1637 The Item_func_in class implements
1638 in_expr IN (<in value list>)
1639 and
1640 in_expr NOT IN (<in value list>)
1641
1642 The current implementation distinguishes 2 cases:
1643 1) all items in <in value list> are constants and have the same
1644 result type. This case is handled by in_vector class.
1645 2) otherwise Item_func_in employs several cmp_item objects to perform
1646 comparisons of in_expr and an item from <in value list>. One cmp_item
1647 object for each result type. Different result types are collected in the
1648 fix_length_and_dec() member function by means of collect_cmp_types()
1649 function.
1650 */
1651 class Item_func_in :public Item_func_opt_neg
1652 {
1653 public:
1654 /// An array of values, created when the bisection lookup method is used
1655 in_vector *array;
1656 /**
1657 If there is some NULL among <in value list>, during a val_int() call; for
1658 example
1659 IN ( (1,(3,'col')), ... ), where 'col' is a column which evaluates to
1660 NULL.
1661 */
1662 bool have_null;
1663 /**
1664 Set to true by fix_length_and_dec() if the IN list contains a
1665 dependent subquery, in which case condition filtering will not be
1666 calculated for this item.
1667 */
1668 bool dep_subq_in_list;
1669 Item_result left_result_type;
1670 cmp_item *cmp_items[6]; /* One cmp_item for each result type */
1671 DTCollation cmp_collation;
1672
Item_func_in(const POS & pos,PT_item_list * list,bool is_negation)1673 Item_func_in(const POS &pos, PT_item_list *list, bool is_negation)
1674 :Item_func_opt_neg(pos, list, is_negation), array(NULL),
1675 have_null(false), dep_subq_in_list(false)
1676 {
1677 memset(&cmp_items, 0, sizeof(cmp_items));
1678 allowed_arg_cols= 0; // Fetch this value from first argument
1679 }
1680 longlong val_int();
1681 bool fix_fields(THD *, Item **);
1682 void fix_after_pullout(st_select_lex *parent_select,
1683 st_select_lex *removed_select);
1684 void fix_length_and_dec();
decimal_precision()1685 uint decimal_precision() const { return 1; }
1686
1687 /**
1688 Cleanup data and comparator arrays.
1689
1690 @note Used during regular cleanup and to free arrays after GC substitution.
1691 @see substitute_gc().
1692 */
cleanup_arrays()1693 void cleanup_arrays()
1694 {
1695 uint i;
1696 delete array;
1697 array= 0;
1698 for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1699 {
1700 delete cmp_items[i];
1701 cmp_items[i]= 0;
1702 }
1703 }
1704
cleanup()1705 void cleanup()
1706 {
1707 DBUG_ENTER("Item_func_in::cleanup");
1708 Item_int_func::cleanup();
1709 cleanup_arrays();
1710 DBUG_VOID_RETURN;
1711 }
select_optimize()1712 optimize_type select_optimize() const
1713 { return OPTIMIZE_KEY; }
1714 virtual void print(String *str, enum_query_type query_type);
functype()1715 enum Functype functype() const { return IN_FUNC; }
func_name()1716 const char *func_name() const { return " IN "; }
is_bool_func()1717 bool is_bool_func() { return 1; }
compare_collation()1718 const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
gc_subst_analyzer(uchar ** arg)1719 bool gc_subst_analyzer(uchar **arg) { return true; }
1720
1721 float get_filtering_effect(table_map filter_for_table,
1722 table_map read_tables,
1723 const MY_BITMAP *fields_to_ignore,
1724 double rows_in_table);
1725 private:
1726 /**
1727 Usable if <in value list> is made only of constants. Returns true if one
1728 of these constants contains a NULL. Example:
1729 IN ( (-5, (12,NULL)), ... ).
1730 */
1731 bool list_contains_null();
1732 /**
1733 Utility function to help calculate the total filtering effect of
1734 IN predicates. This function calculates the filtering effect from
1735 a single field (or field reference) on the left hand side of the
1736 expression.
1737
1738 @param fieldref Field (or field reference) on left hand side of
1739 IN, i.e., this function should be called for
1740 each fi in "(f1,...,fn) IN (values)"
1741 @param filter_for_table The table we are calculating filter effect for
1742 @param fields_to_ignore Fields in 'filter_for_table' that should not
1743 be part of the filter calculation. The filtering
1744 effect of these fields are already part of the
1745 calculation somehow (e.g. because there is a
1746 predicate "col = <const>", and the optimizer
1747 has decided to do ref access on 'col').
1748 @param rows_in_table The number of rows in table 'filter_for_table'
1749
1750 @return the filtering effect (between 0 and 1) 'the_field'
1751 participates with in this IN predicate.
1752 */
1753 float get_single_col_filtering_effect(Item_ident *fieldref,
1754 table_map filter_for_table,
1755 const MY_BITMAP *fields_to_ignore,
1756 double rows_in_table);
1757 };
1758
1759 class cmp_item_row :public cmp_item
1760 {
1761 cmp_item **comparators;
1762 uint n;
1763 public:
cmp_item_row()1764 cmp_item_row(): comparators(0), n(0) {}
1765 ~cmp_item_row();
1766 void store_value(Item *item);
1767 void alloc_comparators(Item *item);
1768 int cmp(Item *arg);
1769 int compare(const cmp_item *arg) const;
1770 cmp_item *make_same();
1771 void store_value_by_template(cmp_item *tmpl, Item *);
1772 friend void Item_func_in::fix_length_and_dec();
1773 };
1774
1775
1776 class in_row :public in_vector
1777 {
1778 cmp_item_row tmp;
1779 // DTOR is not trivial, but we manage memory ourselves.
1780 Mem_root_array<cmp_item_row, true> base_objects;
1781 // Sort pointers, rather than objects.
1782 Mem_root_array<cmp_item_row*, true> base_pointers;
1783 public:
1784 in_row(THD *thd, uint elements, Item *);
1785 ~in_row();
1786 void set(uint pos,Item *item);
1787 uchar *get_value(Item *item);
1788 friend void Item_func_in::fix_length_and_dec();
result_type()1789 Item_result result_type() { return ROW_RESULT; }
1790
shrink_array(size_t n)1791 virtual void shrink_array(size_t n) { base_pointers.resize(n); }
1792
1793 virtual void sort();
1794 virtual bool find_value(const void *value) const;
1795 virtual bool compare_elems(uint pos1, uint pos2) const;
1796 };
1797
1798 /* Functions used by where clause */
1799
1800 class Item_func_isnull :public Item_bool_func
1801 {
1802 protected:
1803 longlong cached_value;
1804 public:
Item_func_isnull(Item * a)1805 Item_func_isnull(Item *a) :Item_bool_func(a) {}
Item_func_isnull(const POS & pos,Item * a)1806 Item_func_isnull(const POS &pos, Item *a) :Item_bool_func(pos, a) {}
1807
1808 longlong val_int();
functype()1809 enum Functype functype() const { return ISNULL_FUNC; }
fix_length_and_dec()1810 void fix_length_and_dec()
1811 {
1812 decimals=0; max_length=1; maybe_null=0;
1813 update_used_tables();
1814 }
func_name()1815 const char *func_name() const { return "isnull"; }
1816 /* Optimize case of not_null_column IS NULL */
update_used_tables()1817 virtual void update_used_tables()
1818 {
1819 if (!args[0]->maybe_null)
1820 {
1821 used_tables_cache= 0; /* is always false */
1822 const_item_cache= 1;
1823 cached_value= (longlong) 0;
1824 }
1825 else
1826 {
1827 args[0]->update_used_tables();
1828 with_subselect= args[0]->has_subquery();
1829 with_stored_program= args[0]->has_stored_program();
1830
1831 if ((const_item_cache= !(used_tables_cache= args[0]->used_tables()) &&
1832 !with_subselect && !with_stored_program))
1833 {
1834 /* Remember if the value is always NULL or never NULL */
1835 cached_value= (longlong) args[0]->is_null();
1836 }
1837 }
1838 }
1839
1840 float get_filtering_effect(table_map filter_for_table,
1841 table_map read_tables,
1842 const MY_BITMAP *fields_to_ignore,
1843 double rows_in_table);
not_null_tables()1844 table_map not_null_tables() const { return 0; }
select_optimize()1845 optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1846 Item *neg_transformer(THD *thd);
compare_collation()1847 const CHARSET_INFO *compare_collation()
1848 { return args[0]->collation.collation; }
1849 };
1850
1851 /* Functions used by HAVING for rewriting IN subquery */
1852
1853 class Item_in_subselect;
1854
1855 /*
1856 This is like IS NOT NULL but it also remembers if it ever has
1857 encountered a NULL; it remembers this in the "was_null" property of the
1858 "owner" item.
1859 */
1860 class Item_is_not_null_test :public Item_func_isnull
1861 {
1862 Item_in_subselect* owner;
1863 public:
Item_is_not_null_test(Item_in_subselect * ow,Item * a)1864 Item_is_not_null_test(Item_in_subselect* ow, Item *a)
1865 :Item_func_isnull(a), owner(ow)
1866 {}
functype()1867 enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
1868 longlong val_int();
func_name()1869 const char *func_name() const { return "<is_not_null_test>"; }
1870 void update_used_tables();
1871 /**
1872 We add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE.
1873
1874 @retval Always RAND_TABLE_BIT
1875 */
get_initial_pseudo_tables()1876 table_map get_initial_pseudo_tables() const { return RAND_TABLE_BIT; }
1877 };
1878
1879
1880 class Item_func_isnotnull :public Item_bool_func
1881 {
1882 bool abort_on_null;
1883 public:
Item_func_isnotnull(Item * a)1884 Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
Item_func_isnotnull(const POS & pos,Item * a)1885 Item_func_isnotnull(const POS &pos, Item *a)
1886 : Item_bool_func(pos, a), abort_on_null(0)
1887 {}
1888
1889 longlong val_int();
functype()1890 enum Functype functype() const { return ISNOTNULL_FUNC; }
fix_length_and_dec()1891 void fix_length_and_dec()
1892 {
1893 decimals=0; max_length=1; maybe_null=0;
1894 }
func_name()1895 const char *func_name() const { return "isnotnull"; }
select_optimize()1896 optimize_type select_optimize() const { return OPTIMIZE_NULL; }
not_null_tables()1897 table_map not_null_tables() const
1898 { return abort_on_null ? not_null_tables_cache : 0; }
1899 Item *neg_transformer(THD *thd);
1900 virtual void print(String *str, enum_query_type query_type);
compare_collation()1901 const CHARSET_INFO *compare_collation()
1902 { return args[0]->collation.collation; }
top_level_item()1903 void top_level_item() { abort_on_null=1; }
1904
1905 float get_filtering_effect(table_map filter_for_table,
1906 table_map read_tables,
1907 const MY_BITMAP *fields_to_ignore,
1908 double rows_in_table);
1909 };
1910
1911
1912 class Item_func_like :public Item_bool_func2
1913 {
1914 typedef Item_bool_func2 super;
1915
1916 // Boyer-Moore data
1917 bool can_do_bm; // pattern is '%abcd%' case
1918 const char* pattern;
1919 int pattern_len;
1920
1921 // Boyer-Moore buffers, *this is owner
1922 int* bmGs; // good suffix shift table, size is pattern_len + 1
1923 int* bmBc; // bad character shift table, size is alphabet_size
1924
1925 void bm_compute_suffixes(int* suff);
1926 void bm_compute_good_suffix_shifts(int* suff);
1927 void bm_compute_bad_character_shifts();
1928 bool bm_matches(const char* text, size_t text_len) const;
1929 enum { alphabet_size = 256 };
1930
1931 Item *escape_item;
1932
1933 bool escape_used_in_parsing;
1934
1935 bool escape_evaluated; ///< Tells if the escape clause has been evaluated.
1936 bool eval_escape_clause(THD *thd);
1937
1938 public:
1939 int escape;
1940
Item_func_like(Item * a,Item * b,Item * escape_arg,bool escape_used)1941 Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1942 :Item_bool_func2(a,b), can_do_bm(false), pattern(0), pattern_len(0),
1943 bmGs(0), bmBc(0), escape_item(escape_arg),
1944 escape_used_in_parsing(escape_used), escape_evaluated(false) {}
Item_func_like(const POS & pos,Item * a,Item * b,Item * opt_escape_arg)1945 Item_func_like(const POS &pos, Item *a, Item *b, Item *opt_escape_arg)
1946 :super(pos, a, b), can_do_bm(false), pattern(0), pattern_len(0),
1947 bmGs(0), bmBc(0), escape_item(opt_escape_arg),
1948 escape_used_in_parsing(opt_escape_arg != NULL), escape_evaluated(false)
1949 {}
1950
1951 virtual bool itemize(Parse_context *pc, Item **res);
1952
1953 longlong val_int();
functype()1954 enum Functype functype() const { return LIKE_FUNC; }
1955 optimize_type select_optimize() const;
eq_cmp_result()1956 cond_result eq_cmp_result() const { return COND_TRUE; }
func_name()1957 const char *func_name() const { return "like"; }
1958 bool fix_fields(THD *thd, Item **ref);
1959 void cleanup();
1960 /**
1961 @retval true non default escape char specified
1962 using "expr LIKE pat ESCAPE 'escape_char'" syntax
1963 */
escape_was_used_in_parsing()1964 bool escape_was_used_in_parsing() const { return escape_used_in_parsing; }
1965
1966 /**
1967 Has the escape clause been evaluated? It only needs to be evaluated
1968 once per execution, since we require it to be constant during execution.
1969 The escape member has a valid value if and only if this function returns
1970 true.
1971 */
escape_is_evaluated()1972 bool escape_is_evaluated() const { return escape_evaluated; }
1973
1974 float get_filtering_effect(table_map filter_for_table,
1975 table_map read_tables,
1976 const MY_BITMAP *fields_to_ignore,
1977 double rows_in_table);
1978 };
1979
1980
1981 class Item_func_regex :public Item_bool_func
1982 {
1983 my_regex_t preg;
1984 bool regex_compiled;
1985 bool regex_is_const;
1986 String prev_regexp;
1987 DTCollation cmp_collation;
1988 const CHARSET_INFO *regex_lib_charset;
1989 int regex_lib_flags;
1990 String conv;
1991 int regcomp(bool send_error);
1992 public:
Item_func_regex(const POS & pos,Item * a,Item * b)1993 Item_func_regex(const POS &pos, Item *a,Item *b) :Item_bool_func(pos, a,b),
1994 regex_compiled(0),regex_is_const(0) {}
1995 void cleanup();
1996 longlong val_int();
1997 bool fix_fields(THD *thd, Item **ref);
func_name()1998 const char *func_name() const { return "regexp"; }
1999
print(String * str,enum_query_type query_type)2000 virtual inline void print(String *str, enum_query_type query_type)
2001 {
2002 print_op(str, query_type);
2003 }
2004
compare_collation()2005 const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
2006 };
2007
2008 #endif /* MYSQL_SERVER */
2009
2010 class Item_cond :public Item_bool_func
2011 {
2012 typedef Item_bool_func super;
2013
2014 protected:
2015 List<Item> list;
2016 bool abort_on_null;
2017
2018 public:
2019 /* Item_cond() is only used to create top level items */
Item_cond()2020 Item_cond(): Item_bool_func(), abort_on_null(1)
2021 { const_item_cache=0; }
2022
Item_cond(Item * i1,Item * i2)2023 Item_cond(Item *i1,Item *i2)
2024 :Item_bool_func(), abort_on_null(0)
2025 {
2026 list.push_back(i1);
2027 list.push_back(i2);
2028 }
Item_cond(const POS & pos,Item * i1,Item * i2)2029 Item_cond(const POS &pos, Item *i1, Item *i2)
2030 :Item_bool_func(pos), abort_on_null(0)
2031 {
2032 list.push_back(i1);
2033 list.push_back(i2);
2034 }
2035
2036 Item_cond(THD *thd, Item_cond *item);
Item_cond(List<Item> & nlist)2037 Item_cond(List<Item> &nlist)
2038 :Item_bool_func(), list(nlist), abort_on_null(0) {}
add(Item * item)2039 bool add(Item *item)
2040 {
2041 assert(item);
2042 return list.push_back(item);
2043 }
add_at_head(Item * item)2044 bool add_at_head(Item *item)
2045 {
2046 assert(item);
2047 return list.push_front(item);
2048 }
add_at_head(List<Item> * nlist)2049 void add_at_head(List<Item> *nlist)
2050 {
2051 assert(nlist->elements);
2052 list.prepand(nlist);
2053 }
2054
2055 virtual bool itemize(Parse_context *pc, Item **res);
2056
2057 bool fix_fields(THD *, Item **ref);
2058 void fix_after_pullout(st_select_lex *parent_select,
2059 st_select_lex *removed_select);
2060
type()2061 enum Type type() const { return COND_ITEM; }
argument_list()2062 List<Item>* argument_list() { return &list; }
2063 bool eq(const Item *item, bool binary_cmp) const;
used_tables()2064 table_map used_tables() const { return used_tables_cache; }
2065 void update_used_tables();
2066 virtual void print(String *str, enum_query_type query_type);
2067 void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
2068 List<Item> &fields);
top_level_item()2069 void top_level_item() { abort_on_null=1; }
2070 void copy_andor_arguments(THD *thd, Item_cond *item);
2071 bool walk(Item_processor processor, enum_walk walk, uchar *arg);
2072 Item *transform(Item_transformer transformer, uchar *arg);
2073 void traverse_cond(Cond_traverser, void *arg, traverse_order order);
2074 void neg_arguments(THD *thd);
field_type()2075 enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
subst_argument_checker(uchar ** arg)2076 bool subst_argument_checker(uchar **arg) { return TRUE; }
2077 Item *compile(Item_analyzer analyzer, uchar **arg_p,
2078 Item_transformer transformer, uchar *arg_t);
2079
equality_substitution_analyzer(uchar ** arg)2080 virtual bool equality_substitution_analyzer(uchar **arg) { return true; }
2081 };
2082
2083 #ifdef MYSQL_SERVER
2084
2085 /*
2086 The class Item_equal is used to represent conjunctions of equality
2087 predicates of the form field1 = field2, and field=const in where
2088 conditions and on expressions.
2089
2090 All equality predicates of the form field1=field2 contained in a
2091 conjunction are substituted for a sequence of items of this class.
2092 An item of this class Item_equal(f1,f2,...fk) represents a
2093 multiple equality f1=f2=...=fk.
2094
2095 If a conjunction contains predicates f1=f2 and f2=f3, a new item of
2096 this class is created Item_equal(f1,f2,f3) representing the multiple
2097 equality f1=f2=f3 that substitutes the above equality predicates in
2098 the conjunction.
2099 A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
2100 substituted for the item representing the same multiple equality
2101 f1=f2=f3.
2102 An item Item_equal(f1,f2) can appear instead of a conjunction of
2103 f2=f1 and f1=f2, or instead of just the predicate f1=f2.
2104
2105 An item of the class Item_equal inherits equalities from outer
2106 conjunctive levels.
2107
2108 Suppose we have a where condition of the following form:
2109 WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
2110 In this case:
2111 f1=f2 will be substituted for Item_equal(f1,f2);
2112 f3=f4 and f3=f5 will be substituted for Item_equal(f3,f4,f5);
2113 f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
2114
2115 An object of the class Item_equal can contain an optional constant
2116 item c. Then it represents a multiple equality of the form
2117 c=f1=...=fk.
2118
2119 Objects of the class Item_equal are used for the following:
2120
2121 1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
2122 pair of tables ti and tj as joined by an equi-condition.
2123 Thus it provide us with additional access paths from table to table.
2124
2125 2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
2126 SARGable predicates:
2127 f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
2128 It also can give us additional index scans and can allow us to
2129 improve selectivity estimates.
2130
2131 3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
2132 selected execution plan for the query: if table ti is accessed
2133 before the table tj then in any predicate P in the where condition
2134 the occurrence of tj.fj is substituted for ti.fi. This can allow
2135 an evaluation of the predicate at an earlier step.
2136
2137 When feature 1 is supported they say that join transitive closure
2138 is employed.
2139 When feature 2 is supported they say that search argument transitive
2140 closure is employed.
2141 Both features are usually supported by preprocessing original query and
2142 adding additional predicates.
2143 We do not just add predicates, we rather dynamically replace some
2144 predicates that can not be used to access tables in the investigated
2145 plan for those, obtained by substitution of some fields for equal fields,
2146 that can be used.
2147
2148 Prepared Statements/Stored Procedures note: instances of class
2149 Item_equal are created only at the time a PS/SP is executed and
2150 are deleted in the end of execution. All changes made to these
2151 objects need not be registered in the list of changes of the parse
2152 tree and do not harm PS/SP re-execution.
2153
2154 Item equal objects are employed only at the optimize phase. Usually they are
2155 not supposed to be evaluated. Yet in some cases we call the method val_int()
2156 for them. We have to take care of restricting the predicate such an
2157 object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
2158 */
2159 struct st_join_table;
2160
2161 class Item_equal: public Item_bool_func
2162 {
2163 List<Item_field> fields; /* list of equal field items */
2164 Item *const_item; /* optional constant item equal to fields items */
2165 cmp_item *eval_item;
2166 Arg_comparator cmp;
2167 bool cond_false;
2168 bool compare_as_dates;
2169 public:
Item_equal()2170 inline Item_equal()
2171 : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
2172 { const_item_cache=0 ;}
2173 Item_equal(Item_field *f1, Item_field *f2);
2174 Item_equal(Item *c, Item_field *f);
2175 Item_equal(Item_equal *item_equal);
~Item_equal()2176 virtual ~Item_equal()
2177 {
2178 delete eval_item;
2179 }
2180
get_const()2181 inline Item* get_const() { return const_item; }
2182 bool compare_const(THD *thd, Item *c);
2183 bool add(THD *thd, Item *c, Item_field *f);
2184 bool add(THD *thd, Item *c);
2185 void add(Item_field *f);
2186 uint members();
2187 bool contains(Field *field);
2188 /**
2189 Get the first field of multiple equality, use for semantic checking.
2190
2191 @retval First field in the multiple equality.
2192 */
get_first()2193 Item_field* get_first() { return fields.head(); }
2194 Item_field* get_subst_item(const Item_field *field);
2195 bool merge(THD *thd, Item_equal *item);
2196 bool update_const(THD *thd);
functype()2197 enum Functype functype() const { return MULT_EQUAL_FUNC; }
2198 longlong val_int();
func_name()2199 const char *func_name() const { return "multiple equal"; }
select_optimize()2200 optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
2201 void sort(Item_field_cmpfunc compare, void *arg);
2202 friend class Item_equal_iterator;
2203 void fix_length_and_dec();
2204 bool fix_fields(THD *thd, Item **ref);
2205 void update_used_tables();
2206 bool walk(Item_processor processor, enum_walk walk, uchar *arg);
2207 Item *transform(Item_transformer transformer, uchar *arg);
2208 virtual void print(String *str, enum_query_type query_type);
compare_collation()2209 const CHARSET_INFO *compare_collation()
2210 { return fields.head()->collation.collation; }
2211
equality_substitution_analyzer(uchar ** arg)2212 virtual bool equality_substitution_analyzer(uchar **arg) { return true; }
2213
2214 virtual Item* equality_substitution_transformer(uchar *arg);
2215
2216 float get_filtering_effect(table_map filter_for_table,
2217 table_map read_tables,
2218 const MY_BITMAP *fields_to_ignore,
2219 double rows_in_table);
2220 };
2221
2222 class COND_EQUAL: public Sql_alloc
2223 {
2224 public:
2225 uint max_members; /* max number of members the current level
2226 list and all lower level lists */
2227 COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
2228 List<Item_equal> current_level; /* list of multiple equalities of
2229 the current and level */
COND_EQUAL()2230 COND_EQUAL()
2231 {
2232 upper_levels= 0;
2233 }
2234 };
2235
2236
2237 class Item_equal_iterator : public List_iterator_fast<Item_field>
2238 {
2239 public:
Item_equal_iterator(Item_equal & item_equal)2240 inline Item_equal_iterator(Item_equal &item_equal)
2241 :List_iterator_fast<Item_field> (item_equal.fields)
2242 {}
2243 inline Item_field* operator++(int)
2244 {
2245 Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
2246 return item;
2247 }
rewind(void)2248 inline void rewind(void)
2249 {
2250 List_iterator_fast<Item_field>::rewind();
2251 }
2252 };
2253
2254 class Item_cond_and :public Item_cond
2255 {
2256 public:
2257 COND_EQUAL cond_equal; /* contains list of Item_equal objects for
2258 the current and level and reference
2259 to multiple equalities of upper and levels */
Item_cond_and()2260 Item_cond_and() :Item_cond() {}
2261
Item_cond_and(Item * i1,Item * i2)2262 Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
Item_cond_and(const POS & pos,Item * i1,Item * i2)2263 Item_cond_and(const POS &pos, Item *i1, Item *i2) :Item_cond(pos, i1, i2) {}
2264
Item_cond_and(THD * thd,Item_cond_and * item)2265 Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
Item_cond_and(List<Item> & list_arg)2266 Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
functype()2267 enum Functype functype() const { return COND_AND_FUNC; }
2268 longlong val_int();
func_name()2269 const char *func_name() const { return "and"; }
copy_andor_structure(THD * thd)2270 Item* copy_andor_structure(THD *thd)
2271 {
2272 Item_cond_and *item;
2273 if ((item= new Item_cond_and(thd, this)))
2274 item->copy_andor_arguments(thd, this);
2275 return item;
2276 }
2277 Item *neg_transformer(THD *thd);
gc_subst_analyzer(uchar ** arg)2278 bool gc_subst_analyzer(uchar **arg) { return true; }
2279
2280 float get_filtering_effect(table_map filter_for_table,
2281 table_map read_tables,
2282 const MY_BITMAP *fields_to_ignore,
2283 double rows_in_table);
2284 };
2285
2286
2287 class Item_cond_or :public Item_cond
2288 {
2289 public:
Item_cond_or()2290 Item_cond_or() :Item_cond() {}
2291
Item_cond_or(Item * i1,Item * i2)2292 Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
Item_cond_or(const POS & pos,Item * i1,Item * i2)2293 Item_cond_or(const POS &pos, Item *i1,Item *i2) :Item_cond(pos, i1, i2) {}
2294
Item_cond_or(THD * thd,Item_cond_or * item)2295 Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
Item_cond_or(List<Item> & list_arg)2296 Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
functype()2297 enum Functype functype() const { return COND_OR_FUNC; }
2298 longlong val_int();
func_name()2299 const char *func_name() const { return "or"; }
copy_andor_structure(THD * thd)2300 Item* copy_andor_structure(THD *thd)
2301 {
2302 Item_cond_or *item;
2303 if ((item= new Item_cond_or(thd, this)))
2304 item->copy_andor_arguments(thd, this);
2305 return item;
2306 }
2307 Item *neg_transformer(THD *thd);
gc_subst_analyzer(uchar ** arg)2308 bool gc_subst_analyzer(uchar **arg) { return true; }
2309
2310 float get_filtering_effect(table_map filter_for_table,
2311 table_map read_tables,
2312 const MY_BITMAP *fields_to_ignore,
2313 double rows_in_table);
2314 };
2315
2316 /* Some useful inline functions */
2317
and_conds(Item * a,Item * b)2318 inline Item *and_conds(Item *a, Item *b)
2319 {
2320 if (!b) return a;
2321 if (!a) return b;
2322 return new Item_cond_and(a, b);
2323 }
2324
2325
2326 Item *and_expressions(Item *a, Item *b, Item **org_item);
2327
2328 longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
2329 const Item *warn_item, bool *is_null);
2330
2331
2332 bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
2333 const char *warn_name, MYSQL_TIME *l_time);
2334 /*
2335 These need definitions from this file but the variables are defined
2336 in mysqld.h. The variables really belong in this component, but for
2337 the time being we leave them in mysqld.cc to avoid merge problems.
2338 */
2339 extern Eq_creator eq_creator;
2340 extern Equal_creator equal_creator;
2341 extern Ne_creator ne_creator;
2342 extern Gt_creator gt_creator;
2343 extern Lt_creator lt_creator;
2344 extern Ge_creator ge_creator;
2345 extern Le_creator le_creator;
2346
2347 #endif /* MYSQL_SERVER */
2348
2349 #endif /* ITEM_CMPFUNC_INCLUDED */
2350