mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / sql / item_cmpfunc.h
blobb5547b476149d40f87e4a7148b3cb3fde4230e61
1 /* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
17 /* compare and test functions */
19 #ifdef USE_PRAGMA_INTERFACE
20 #pragma interface /* gcc class implementation */
21 #endif
23 extern Item_result item_cmp_type(Item_result a,Item_result b);
24 class Item_bool_func2;
25 class Arg_comparator;
27 typedef int (Arg_comparator::*arg_cmp_func)();
29 typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
31 class Arg_comparator: public Sql_alloc
33 Item **a, **b;
34 arg_cmp_func func;
35 Item_result_field *owner;
36 Arg_comparator *comparators; // used only for compare_row()
37 double precision;
38 /* Fields used in DATE/DATETIME comparison. */
39 THD *thd;
40 enum_field_types a_type, b_type; // Types of a and b items
41 Item *a_cache, *b_cache; // Cached values of a and b items
42 bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
43 bool set_null; // TRUE <=> set owner->null_value
44 // when one of arguments is NULL.
45 enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
46 CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
47 longlong (*get_value_a_func)(THD *thd, Item ***item_arg, Item **cache_arg,
48 Item *warn_item, bool *is_null);
49 longlong (*get_value_b_func)(THD *thd, Item ***item_arg, Item **cache_arg,
50 Item *warn_item, bool *is_null);
51 bool try_year_cmp_func(Item_result type);
52 public:
53 DTCollation cmp_collation;
54 /* Allow owner function to use string buffers. */
55 String value1, value2;
57 Arg_comparator(): comparators(0), thd(0), a_cache(0), b_cache(0), set_null(TRUE),
58 get_value_a_func(0), get_value_b_func(0) {};
59 Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), comparators(0), thd(0),
60 a_cache(0), b_cache(0), set_null(TRUE),
61 get_value_a_func(0), get_value_b_func(0) {};
63 int set_compare_func(Item_result_field *owner, Item_result type);
64 inline int set_compare_func(Item_result_field *owner_arg)
66 return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
67 (*b)->result_type()));
69 int set_cmp_func(Item_result_field *owner_arg,
70 Item **a1, Item **a2,
71 Item_result type);
73 inline int set_cmp_func(Item_result_field *owner_arg,
74 Item **a1, Item **a2, bool set_null_arg)
76 set_null= set_null_arg;
77 return set_cmp_func(owner_arg, a1, a2,
78 item_cmp_type((*a1)->result_type(),
79 (*a2)->result_type()));
81 inline int compare() { return (this->*func)(); }
83 int compare_string(); // compare args[0] & args[1]
84 int compare_binary_string(); // compare args[0] & args[1]
85 int compare_real(); // compare args[0] & args[1]
86 int compare_decimal(); // compare args[0] & args[1]
87 int compare_int_signed(); // compare args[0] & args[1]
88 int compare_int_signed_unsigned();
89 int compare_int_unsigned_signed();
90 int compare_int_unsigned();
91 int compare_row(); // compare args[0] & args[1]
92 int compare_e_string(); // compare args[0] & args[1]
93 int compare_e_binary_string(); // compare args[0] & args[1]
94 int compare_e_real(); // compare args[0] & args[1]
95 int compare_e_decimal(); // compare args[0] & args[1]
96 int compare_e_int(); // compare args[0] & args[1]
97 int compare_e_int_diff_signedness();
98 int compare_e_row(); // compare args[0] & args[1]
99 int compare_real_fixed();
100 int compare_e_real_fixed();
101 int compare_datetime(); // compare args[0] & args[1] as DATETIMEs
103 static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b,
104 ulonglong *const_val_arg);
106 Item** cache_converted_constant(THD *thd, Item **value, Item **cache,
107 Item_result type);
108 void set_datetime_cmp_func(Item_result_field *owner_arg, Item **a1, Item **b1);
109 static arg_cmp_func comparator_matrix [5][2];
110 inline bool is_owner_equal_func()
112 return (owner->type() == Item::FUNC_ITEM &&
113 ((Item_func*)owner)->functype() == Item_func::EQUAL_FUNC);
115 void cleanup()
117 delete [] comparators;
118 comparators= 0;
121 friend class Item_func;
124 class Item_bool_func :public Item_int_func
126 public:
127 Item_bool_func() :Item_int_func() {}
128 Item_bool_func(Item *a) :Item_int_func(a) {}
129 Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
130 Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
131 bool is_bool_func() { return 1; }
132 void fix_length_and_dec() { decimals=0; max_length=1; }
133 uint decimal_precision() const { return 1; }
138 Abstract Item class, to represent <code>X IS [NOT] (TRUE | FALSE)</code>
139 boolean predicates.
142 class Item_func_truth : public Item_bool_func
144 public:
145 virtual bool val_bool();
146 virtual longlong val_int();
147 virtual void fix_length_and_dec();
148 virtual void print(String *str, enum_query_type query_type);
150 protected:
151 Item_func_truth(Item *a, bool a_value, bool a_affirmative)
152 : Item_bool_func(a), value(a_value), affirmative(a_affirmative)
155 ~Item_func_truth()
157 private:
159 True for <code>X IS [NOT] TRUE</code>,
160 false for <code>X IS [NOT] FALSE</code> predicates.
162 const bool value;
164 True for <code>X IS Y</code>, false for <code>X IS NOT Y</code> predicates.
166 const bool affirmative;
171 This Item represents a <code>X IS TRUE</code> boolean predicate.
174 class Item_func_istrue : public Item_func_truth
176 public:
177 Item_func_istrue(Item *a) : Item_func_truth(a, true, true) {}
178 ~Item_func_istrue() {}
179 virtual const char* func_name() const { return "istrue"; }
184 This Item represents a <code>X IS NOT TRUE</code> boolean predicate.
187 class Item_func_isnottrue : public Item_func_truth
189 public:
190 Item_func_isnottrue(Item *a) : Item_func_truth(a, true, false) {}
191 ~Item_func_isnottrue() {}
192 virtual const char* func_name() const { return "isnottrue"; }
197 This Item represents a <code>X IS FALSE</code> boolean predicate.
200 class Item_func_isfalse : public Item_func_truth
202 public:
203 Item_func_isfalse(Item *a) : Item_func_truth(a, false, true) {}
204 ~Item_func_isfalse() {}
205 virtual const char* func_name() const { return "isfalse"; }
210 This Item represents a <code>X IS NOT FALSE</code> boolean predicate.
213 class Item_func_isnotfalse : public Item_func_truth
215 public:
216 Item_func_isnotfalse(Item *a) : Item_func_truth(a, false, false) {}
217 ~Item_func_isnotfalse() {}
218 virtual const char* func_name() const { return "isnotfalse"; }
222 class Item_cache;
223 #define UNKNOWN ((my_bool)-1)
227 Item_in_optimizer(left_expr, Item_in_subselect(...))
229 Item_in_optimizer is used to wrap an instance of Item_in_subselect. This
230 class does the following:
231 - Evaluate the left expression and store it in Item_cache_* object (to
232 avoid re-evaluating it many times during subquery execution)
233 - Shortcut the evaluation of "NULL IN (...)" to NULL in the cases where we
234 don't care if the result is NULL or FALSE.
236 NOTE
237 It is not quite clear why the above listed functionality should be
238 placed into a separate class called 'Item_in_optimizer'.
241 class Item_in_optimizer: public Item_bool_func
243 protected:
244 Item_cache *cache;
245 bool save_cache;
247 Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
248 UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
249 FALSE - result is FALSE
250 TRUE - result is NULL
252 my_bool result_for_null_param;
253 public:
254 Item_in_optimizer(Item *a, Item_in_subselect *b):
255 Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0),
256 save_cache(0), result_for_null_param(UNKNOWN)
257 { with_subselect= true; }
258 bool fix_fields(THD *, Item **);
259 bool fix_left(THD *thd, Item **ref);
260 bool is_null();
261 longlong val_int();
262 void cleanup();
263 const char *func_name() const { return "<in_optimizer>"; }
264 Item_cache **get_cache() { return &cache; }
265 void keep_top_level_cache();
268 class Comp_creator
270 public:
271 Comp_creator() {} /* Remove gcc warning */
272 virtual ~Comp_creator() {} /* Remove gcc warning */
273 virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
274 virtual const char* symbol(bool invert) const = 0;
275 virtual bool eqne_op() const = 0;
276 virtual bool l_op() const = 0;
279 class Eq_creator :public Comp_creator
281 public:
282 Eq_creator() {} /* Remove gcc warning */
283 virtual ~Eq_creator() {} /* Remove gcc warning */
284 virtual Item_bool_func2* create(Item *a, Item *b) const;
285 virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
286 virtual bool eqne_op() const { return 1; }
287 virtual bool l_op() const { return 0; }
290 class Ne_creator :public Comp_creator
292 public:
293 Ne_creator() {} /* Remove gcc warning */
294 virtual ~Ne_creator() {} /* Remove gcc warning */
295 virtual Item_bool_func2* create(Item *a, Item *b) const;
296 virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
297 virtual bool eqne_op() const { return 1; }
298 virtual bool l_op() const { return 0; }
301 class Gt_creator :public Comp_creator
303 public:
304 Gt_creator() {} /* Remove gcc warning */
305 virtual ~Gt_creator() {} /* Remove gcc warning */
306 virtual Item_bool_func2* create(Item *a, Item *b) const;
307 virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
308 virtual bool eqne_op() const { return 0; }
309 virtual bool l_op() const { return 0; }
312 class Lt_creator :public Comp_creator
314 public:
315 Lt_creator() {} /* Remove gcc warning */
316 virtual ~Lt_creator() {} /* Remove gcc warning */
317 virtual Item_bool_func2* create(Item *a, Item *b) const;
318 virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
319 virtual bool eqne_op() const { return 0; }
320 virtual bool l_op() const { return 1; }
323 class Ge_creator :public Comp_creator
325 public:
326 Ge_creator() {} /* Remove gcc warning */
327 virtual ~Ge_creator() {} /* Remove gcc warning */
328 virtual Item_bool_func2* create(Item *a, Item *b) const;
329 virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
330 virtual bool eqne_op() const { return 0; }
331 virtual bool l_op() const { return 0; }
334 class Le_creator :public Comp_creator
336 public:
337 Le_creator() {} /* Remove gcc warning */
338 virtual ~Le_creator() {} /* Remove gcc warning */
339 virtual Item_bool_func2* create(Item *a, Item *b) const;
340 virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
341 virtual bool eqne_op() const { return 0; }
342 virtual bool l_op() const { return 1; }
345 class Item_bool_func2 :public Item_int_func
346 { /* Bool with 2 string args */
347 protected:
348 Arg_comparator cmp;
349 bool abort_on_null;
351 public:
352 Item_bool_func2(Item *a,Item *b)
353 :Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(FALSE) {}
354 void fix_length_and_dec();
355 void set_cmp_func()
357 cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, TRUE);
359 optimize_type select_optimize() const { return OPTIMIZE_OP; }
360 virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
361 bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
363 virtual inline void print(String *str, enum_query_type query_type)
365 Item_func::print_op(str, query_type);
368 bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
369 bool is_bool_func() { return 1; }
370 CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
371 uint decimal_precision() const { return 1; }
372 void top_level_item() { abort_on_null= TRUE; }
373 void cleanup()
375 Item_int_func::cleanup();
376 cmp.cleanup();
379 friend class Arg_comparator;
382 class Item_bool_rowready_func2 :public Item_bool_func2
384 public:
385 Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b)
387 allowed_arg_cols= 0; // Fetch this value from first argument
389 Item *neg_transformer(THD *thd);
390 virtual Item *negated_item();
391 bool subst_argument_checker(uchar **arg) { return TRUE; }
394 class Item_func_not :public Item_bool_func
396 public:
397 Item_func_not(Item *a) :Item_bool_func(a) {}
398 longlong val_int();
399 enum Functype functype() const { return NOT_FUNC; }
400 const char *func_name() const { return "not"; }
401 Item *neg_transformer(THD *thd);
402 virtual void print(String *str, enum_query_type query_type);
405 class Item_maxmin_subselect;
408 trigcond<param>(arg) ::= param? arg : TRUE
410 The class Item_func_trig_cond is used for guarded predicates
411 which are employed only for internal purposes.
412 A guarded predicate is an object consisting of an a regular or
413 a guarded predicate P and a pointer to a boolean guard variable g.
414 A guarded predicate P/g is evaluated to true if the value of the
415 guard g is false, otherwise it is evaluated to the same value that
416 the predicate P: val(P/g)= g ? val(P):true.
417 Guarded predicates allow us to include predicates into a conjunction
418 conditionally. Currently they are utilized for pushed down predicates
419 in queries with outer join operations.
421 In the future, probably, it makes sense to extend this class to
422 the objects consisting of three elements: a predicate P, a pointer
423 to a variable g and a firing value s with following evaluation
424 rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
425 one item for the objects of the form P/g1/g2...
427 Objects of this class are built only for query execution after
428 the execution plan has been already selected. That's why this
429 class needs only val_int out of generic methods.
431 Current uses of Item_func_trig_cond objects:
432 - To wrap selection conditions when executing outer joins
433 - To wrap condition that is pushed down into subquery
436 class Item_func_trig_cond: public Item_bool_func
438 bool *trig_var;
439 public:
440 Item_func_trig_cond(Item *a, bool *f) : Item_bool_func(a) { trig_var= f; }
441 longlong val_int() { return *trig_var ? args[0]->val_int() : 1; }
442 enum Functype functype() const { return TRIG_COND_FUNC; };
443 const char *func_name() const { return "trigcond"; };
444 bool const_item() const { return FALSE; }
445 bool *get_trig_var() { return trig_var; }
448 class Item_func_not_all :public Item_func_not
450 /* allow to check presence of values in max/min optimization */
451 Item_sum_hybrid *test_sum_item;
452 Item_maxmin_subselect *test_sub_item;
454 bool abort_on_null;
455 public:
456 bool show;
458 Item_func_not_all(Item *a)
459 :Item_func_not(a), test_sum_item(0), test_sub_item(0), abort_on_null(0),
460 show(0)
462 virtual void top_level_item() { abort_on_null= 1; }
463 bool top_level() { return abort_on_null; }
464 longlong val_int();
465 enum Functype functype() const { return NOT_ALL_FUNC; }
466 const char *func_name() const { return "<not>"; }
467 virtual void print(String *str, enum_query_type query_type);
468 void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
469 void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
470 bool empty_underlying_subquery();
471 Item *neg_transformer(THD *thd);
475 class Item_func_nop_all :public Item_func_not_all
477 public:
479 Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
480 longlong val_int();
481 const char *func_name() const { return "<nop>"; }
482 Item *neg_transformer(THD *thd);
486 class Item_func_eq :public Item_bool_rowready_func2
488 public:
489 Item_func_eq(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
490 longlong val_int();
491 enum Functype functype() const { return EQ_FUNC; }
492 enum Functype rev_functype() const { return EQ_FUNC; }
493 cond_result eq_cmp_result() const { return COND_TRUE; }
494 const char *func_name() const { return "="; }
495 Item *negated_item();
498 class Item_func_equal :public Item_bool_rowready_func2
500 public:
501 Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
502 longlong val_int();
503 void fix_length_and_dec();
504 table_map not_null_tables() const { return 0; }
505 enum Functype functype() const { return EQUAL_FUNC; }
506 enum Functype rev_functype() const { return EQUAL_FUNC; }
507 cond_result eq_cmp_result() const { return COND_TRUE; }
508 const char *func_name() const { return "<=>"; }
509 Item *neg_transformer(THD *thd) { return 0; }
513 class Item_func_ge :public Item_bool_rowready_func2
515 public:
516 Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
517 longlong val_int();
518 enum Functype functype() const { return GE_FUNC; }
519 enum Functype rev_functype() const { return LE_FUNC; }
520 cond_result eq_cmp_result() const { return COND_TRUE; }
521 const char *func_name() const { return ">="; }
522 Item *negated_item();
526 class Item_func_gt :public Item_bool_rowready_func2
528 public:
529 Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
530 longlong val_int();
531 enum Functype functype() const { return GT_FUNC; }
532 enum Functype rev_functype() const { return LT_FUNC; }
533 cond_result eq_cmp_result() const { return COND_FALSE; }
534 const char *func_name() const { return ">"; }
535 Item *negated_item();
539 class Item_func_le :public Item_bool_rowready_func2
541 public:
542 Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
543 longlong val_int();
544 enum Functype functype() const { return LE_FUNC; }
545 enum Functype rev_functype() const { return GE_FUNC; }
546 cond_result eq_cmp_result() const { return COND_TRUE; }
547 const char *func_name() const { return "<="; }
548 Item *negated_item();
552 class Item_func_lt :public Item_bool_rowready_func2
554 public:
555 Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
556 longlong val_int();
557 enum Functype functype() const { return LT_FUNC; }
558 enum Functype rev_functype() const { return GT_FUNC; }
559 cond_result eq_cmp_result() const { return COND_FALSE; }
560 const char *func_name() const { return "<"; }
561 Item *negated_item();
565 class Item_func_ne :public Item_bool_rowready_func2
567 public:
568 Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
569 longlong val_int();
570 enum Functype functype() const { return NE_FUNC; }
571 cond_result eq_cmp_result() const { return COND_FALSE; }
572 optimize_type select_optimize() const { return OPTIMIZE_KEY; }
573 const char *func_name() const { return "<>"; }
574 Item *negated_item();
579 The class Item_func_opt_neg is defined to factor out the functionality
580 common for the classes Item_func_between and Item_func_in. The objects
581 of these classes can express predicates or there negations.
582 The alternative approach would be to create pairs Item_func_between,
583 Item_func_notbetween and Item_func_in, Item_func_notin.
587 class Item_func_opt_neg :public Item_int_func
589 public:
590 bool negated; /* <=> the item represents NOT <func> */
591 bool pred_level; /* <=> [NOT] <func> is used on a predicate level */
592 public:
593 Item_func_opt_neg(Item *a, Item *b, Item *c)
594 :Item_int_func(a, b, c), negated(0), pred_level(0) {}
595 Item_func_opt_neg(List<Item> &list)
596 :Item_int_func(list), negated(0), pred_level(0) {}
597 public:
598 inline void negate() { negated= !negated; }
599 inline void top_level_item() { pred_level= 1; }
600 Item *neg_transformer(THD *thd)
602 negated= !negated;
603 return this;
605 bool eq(const Item *item, bool binary_cmp) const;
606 bool subst_argument_checker(uchar **arg) { return TRUE; }
610 class Item_func_between :public Item_func_opt_neg
612 DTCollation cmp_collation;
613 public:
614 Item_result cmp_type;
615 String value0,value1,value2;
616 /* TRUE <=> arguments will be compared as dates. */
617 bool compare_as_dates;
618 /* Comparators used for DATE/DATETIME comparison. */
619 Arg_comparator ge_cmp, le_cmp;
620 Item_func_between(Item *a, Item *b, Item *c)
621 :Item_func_opt_neg(a, b, c), compare_as_dates(FALSE) {}
622 longlong val_int();
623 optimize_type select_optimize() const { return OPTIMIZE_KEY; }
624 enum Functype functype() const { return BETWEEN; }
625 const char *func_name() const { return "between"; }
626 bool fix_fields(THD *, Item **);
627 void fix_length_and_dec();
628 virtual void print(String *str, enum_query_type query_type);
629 bool is_bool_func() { return 1; }
630 CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
631 uint decimal_precision() const { return 1; }
635 class Item_func_strcmp :public Item_bool_func2
637 public:
638 Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
639 longlong val_int();
640 optimize_type select_optimize() const { return OPTIMIZE_NONE; }
641 const char *func_name() const { return "strcmp"; }
643 virtual inline void print(String *str, enum_query_type query_type)
645 Item_func::print(str, query_type);
650 struct interval_range
652 Item_result type;
653 double dbl;
654 my_decimal dec;
657 class Item_func_interval :public Item_int_func
659 Item_row *row;
660 my_bool use_decimal_comparison;
661 interval_range *intervals;
662 public:
663 Item_func_interval(Item_row *a)
664 :Item_int_func(a),row(a),intervals(0)
666 allowed_arg_cols= 0; // Fetch this value from first argument
668 longlong val_int();
669 void fix_length_and_dec();
670 const char *func_name() const { return "interval"; }
671 uint decimal_precision() const { return 2; }
675 class Item_func_coalesce :public Item_func_numhybrid
677 protected:
678 enum_field_types cached_field_type;
679 Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
680 public:
681 Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
682 double real_op();
683 longlong int_op();
684 String *str_op(String *);
685 my_decimal *decimal_op(my_decimal *);
686 void fix_length_and_dec();
687 void find_num_type() {}
688 enum Item_result result_type () const { return hybrid_type; }
689 const char *func_name() const { return "coalesce"; }
690 table_map not_null_tables() const { return 0; }
691 enum_field_types field_type() const { return cached_field_type; }
695 class Item_func_ifnull :public Item_func_coalesce
697 protected:
698 bool field_type_defined;
699 public:
700 Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
701 double real_op();
702 longlong int_op();
703 String *str_op(String *str);
704 my_decimal *decimal_op(my_decimal *);
705 enum_field_types field_type() const;
706 void fix_length_and_dec();
707 const char *func_name() const { return "ifnull"; }
708 Field *tmp_table_field(TABLE *table);
709 uint decimal_precision() const;
713 class Item_func_if :public Item_func
715 enum Item_result cached_result_type;
716 enum_field_types cached_field_type;
717 public:
718 Item_func_if(Item *a,Item *b,Item *c)
719 :Item_func(a,b,c), cached_result_type(INT_RESULT)
721 double val_real();
722 longlong val_int();
723 String *val_str(String *str);
724 my_decimal *val_decimal(my_decimal *);
725 enum Item_result result_type () const { return cached_result_type; }
726 enum_field_types field_type() const { return cached_field_type; }
727 bool fix_fields(THD *, Item **);
728 void fix_length_and_dec();
729 uint decimal_precision() const;
730 const char *func_name() const { return "if"; }
734 class Item_func_nullif :public Item_bool_func2
736 enum Item_result cached_result_type;
737 public:
738 Item_func_nullif(Item *a,Item *b)
739 :Item_bool_func2(a,b), cached_result_type(INT_RESULT)
741 double val_real();
742 longlong val_int();
743 String *val_str(String *str);
744 my_decimal *val_decimal(my_decimal *);
745 enum Item_result result_type () const { return cached_result_type; }
746 void fix_length_and_dec();
747 uint decimal_precision() const { return args[0]->decimal_precision(); }
748 const char *func_name() const { return "nullif"; }
750 virtual inline void print(String *str, enum_query_type query_type)
752 Item_func::print(str, query_type);
755 table_map not_null_tables() const { return 0; }
756 bool is_null();
760 /* Functions to handle the optimized IN */
763 /* A vector of values of some type */
765 class in_vector :public Sql_alloc
767 public:
768 char *base;
769 uint size;
770 qsort2_cmp compare;
771 CHARSET_INFO *collation;
772 uint count;
773 uint used_count;
774 in_vector() {}
775 in_vector(uint elements,uint element_length,qsort2_cmp cmp_func,
776 CHARSET_INFO *cmp_coll)
777 :base((char*) sql_calloc(elements*element_length)),
778 size(element_length), compare(cmp_func), collation(cmp_coll),
779 count(elements), used_count(elements) {}
780 virtual ~in_vector() {}
781 virtual void set(uint pos,Item *item)=0;
782 virtual uchar *get_value(Item *item)=0;
783 void sort()
785 my_qsort2(base,used_count,size,compare,collation);
787 int find(Item *item);
790 Create an instance of Item_{type} (e.g. Item_decimal) constant object
791 which type allows it to hold an element of this vector without any
792 conversions.
793 The purpose of this function is to be able to get elements of this
794 vector in form of Item_xxx constants without creating Item_xxx object
795 for every array element you get (i.e. this implements "FlyWeight" pattern)
797 virtual Item* create_item() { return NULL; }
800 Store the value at position #pos into provided item object
801 SYNOPSIS
802 value_to_item()
803 pos Index of value to store
804 item Constant item to store value into. The item must be of the same
805 type that create_item() returns.
807 virtual void value_to_item(uint pos, Item *item) { }
809 /* Compare values number pos1 and pos2 for equality */
810 bool compare_elems(uint pos1, uint pos2)
812 return test(compare(collation, base + pos1*size, base + pos2*size));
814 virtual Item_result result_type()= 0;
817 class in_string :public in_vector
819 char buff[STRING_BUFFER_USUAL_SIZE];
820 String tmp;
821 public:
822 in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs);
823 ~in_string();
824 void set(uint pos,Item *item);
825 uchar *get_value(Item *item);
826 Item* create_item()
828 return new Item_string(collation);
830 void value_to_item(uint pos, Item *item)
832 String *str=((String*) base)+pos;
833 Item_string *to= (Item_string*)item;
834 to->str_value= *str;
836 Item_result result_type() { return STRING_RESULT; }
839 class in_longlong :public in_vector
841 protected:
843 Here we declare a temporary variable (tmp) of the same type as the
844 elements of this vector. tmp is used in finding if a given value is in
845 the list.
847 struct packed_longlong
849 longlong val;
850 longlong unsigned_flag; // Use longlong, not bool, to preserve alignment
851 } tmp;
852 public:
853 in_longlong(uint elements);
854 void set(uint pos,Item *item);
855 uchar *get_value(Item *item);
857 Item* create_item()
860 We're created a signed INT, this may not be correct in
861 general case (see BUG#19342).
863 return new Item_int((longlong)0);
865 void value_to_item(uint pos, Item *item)
867 ((Item_int*) item)->value= ((packed_longlong*) base)[pos].val;
868 ((Item_int*) item)->unsigned_flag= (my_bool)
869 ((packed_longlong*) base)[pos].unsigned_flag;
871 Item_result result_type() { return INT_RESULT; }
873 friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
878 Class to represent a vector of constant DATE/DATETIME values.
879 Values are obtained with help of the get_datetime_value() function.
880 If the left item is a constant one then its value is cached in the
881 lval_cache variable.
883 class in_datetime :public in_longlong
885 public:
886 THD *thd;
887 /* An item used to issue warnings. */
888 Item *warn_item;
889 /* Cache for the left item. */
890 Item *lval_cache;
892 in_datetime(Item *warn_item_arg, uint elements)
893 :in_longlong(elements), thd(current_thd), warn_item(warn_item_arg),
894 lval_cache(0) {};
895 void set(uint pos,Item *item);
896 uchar *get_value(Item *item);
897 friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
901 class in_double :public in_vector
903 double tmp;
904 public:
905 in_double(uint elements);
906 void set(uint pos,Item *item);
907 uchar *get_value(Item *item);
908 Item *create_item()
910 return new Item_float(0.0, 0);
912 void value_to_item(uint pos, Item *item)
914 ((Item_float*)item)->value= ((double*) base)[pos];
916 Item_result result_type() { return REAL_RESULT; }
920 class in_decimal :public in_vector
922 my_decimal val;
923 public:
924 in_decimal(uint elements);
925 void set(uint pos, Item *item);
926 uchar *get_value(Item *item);
927 Item *create_item()
929 return new Item_decimal(0, FALSE);
931 void value_to_item(uint pos, Item *item)
933 my_decimal *dec= ((my_decimal *)base) + pos;
934 Item_decimal *item_dec= (Item_decimal*)item;
935 item_dec->set_decimal_value(dec);
937 Item_result result_type() { return DECIMAL_RESULT; }
943 ** Classes for easy comparing of non const items
946 class cmp_item :public Sql_alloc
948 public:
949 CHARSET_INFO *cmp_charset;
950 cmp_item() { cmp_charset= &my_charset_bin; }
951 virtual ~cmp_item() {}
952 virtual void store_value(Item *item)= 0;
953 virtual int cmp(Item *item)= 0;
954 // for optimized IN with row
955 virtual int compare(cmp_item *item)= 0;
956 static cmp_item* get_comparator(Item_result type, CHARSET_INFO *cs);
957 virtual cmp_item *make_same()= 0;
958 virtual void store_value_by_template(cmp_item *tmpl, Item *item)
960 store_value(item);
964 class cmp_item_string :public cmp_item
966 protected:
967 String *value_res;
968 public:
969 cmp_item_string () {}
970 cmp_item_string (CHARSET_INFO *cs) { cmp_charset= cs; }
971 void set_charset(CHARSET_INFO *cs) { cmp_charset= cs; }
972 friend class cmp_item_sort_string;
973 friend class cmp_item_sort_string_in_static;
976 class cmp_item_sort_string :public cmp_item_string
978 protected:
979 char value_buff[STRING_BUFFER_USUAL_SIZE];
980 String value;
981 public:
982 cmp_item_sort_string():
983 cmp_item_string() {}
984 cmp_item_sort_string(CHARSET_INFO *cs):
985 cmp_item_string(cs),
986 value(value_buff, sizeof(value_buff), cs) {}
987 void store_value(Item *item)
989 value_res= item->val_str(&value);
991 int cmp(Item *arg)
993 char buff[STRING_BUFFER_USUAL_SIZE];
994 String tmp(buff, sizeof(buff), cmp_charset), *res;
995 res= arg->val_str(&tmp);
996 return (value_res ? (res ? sortcmp(value_res, res, cmp_charset) : 1) :
997 (res ? -1 : 0));
999 int compare(cmp_item *ci)
1001 cmp_item_string *l_cmp= (cmp_item_string *) ci;
1002 return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1004 cmp_item *make_same();
1005 void set_charset(CHARSET_INFO *cs)
1007 cmp_charset= cs;
1008 value.set_quick(value_buff, sizeof(value_buff), cs);
1012 class cmp_item_int :public cmp_item
1014 longlong value;
1015 public:
1016 cmp_item_int() {} /* Remove gcc warning */
1017 void store_value(Item *item)
1019 value= item->val_int();
1021 int cmp(Item *arg)
1023 return value != arg->val_int();
1025 int compare(cmp_item *ci)
1027 cmp_item_int *l_cmp= (cmp_item_int *)ci;
1028 return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
1030 cmp_item *make_same();
1034 Compare items in the DATETIME context.
1035 Values are obtained with help of the get_datetime_value() function.
1036 If the left item is a constant one then its value is cached in the
1037 lval_cache variable.
1039 class cmp_item_datetime :public cmp_item
1041 longlong value;
1042 public:
1043 THD *thd;
1044 /* Item used for issuing warnings. */
1045 Item *warn_item;
1046 /* Cache for the left item. */
1047 Item *lval_cache;
1049 cmp_item_datetime(Item *warn_item_arg)
1050 :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
1051 void store_value(Item *item);
1052 int cmp(Item *arg);
1053 int compare(cmp_item *ci);
1054 cmp_item *make_same();
1057 class cmp_item_real :public cmp_item
1059 double value;
1060 public:
1061 cmp_item_real() {} /* Remove gcc warning */
1062 void store_value(Item *item)
1064 value= item->val_real();
1066 int cmp(Item *arg)
1068 return value != arg->val_real();
1070 int compare(cmp_item *ci)
1072 cmp_item_real *l_cmp= (cmp_item_real *) ci;
1073 return (value < l_cmp->value)? -1 : ((value == l_cmp->value) ? 0 : 1);
1075 cmp_item *make_same();
1079 class cmp_item_decimal :public cmp_item
1081 my_decimal value;
1082 public:
1083 cmp_item_decimal() {} /* Remove gcc warning */
1084 void store_value(Item *item);
1085 int cmp(Item *arg);
1086 int compare(cmp_item *c);
1087 cmp_item *make_same();
1092 cmp_item for optimized IN with row (right part string, which never
1093 be changed)
1096 class cmp_item_sort_string_in_static :public cmp_item_string
1098 protected:
1099 String value;
1100 public:
1101 cmp_item_sort_string_in_static(CHARSET_INFO *cs):
1102 cmp_item_string(cs) {}
1103 void store_value(Item *item)
1105 value_res= item->val_str(&value);
1107 int cmp(Item *item)
1109 // Should never be called
1110 DBUG_ASSERT(0);
1111 return 1;
1113 int compare(cmp_item *ci)
1115 cmp_item_string *l_cmp= (cmp_item_string *) ci;
1116 return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1118 cmp_item *make_same()
1120 return new cmp_item_sort_string_in_static(cmp_charset);
1126 The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1127 implementation.
1129 When there is no expression between CASE and the first WHEN
1130 (the CASE expression) then this function simple checks all WHEN expressions
1131 one after another. When some WHEN expression evaluated to TRUE then the
1132 value of the corresponding THEN expression is returned.
1134 When the CASE expression is specified then it is compared to each WHEN
1135 expression individually. When an equal WHEN expression is found
1136 corresponding THEN expression is returned.
1137 In order to do correct comparisons several comparators are used. One for
1138 each result type. Different result types that are used in particular
1139 CASE ... END expression are collected in the fix_length_and_dec() member
1140 function and only comparators for there result types are used.
1143 class Item_func_case :public Item_func
1145 int first_expr_num, else_expr_num;
1146 enum Item_result cached_result_type, left_result_type;
1147 String tmp_value;
1148 uint ncases;
1149 Item_result cmp_type;
1150 DTCollation cmp_collation;
1151 enum_field_types cached_field_type;
1152 cmp_item *cmp_items[5]; /* For all result types */
1153 cmp_item *case_item;
1154 public:
1155 Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
1156 :Item_func(), first_expr_num(-1), else_expr_num(-1),
1157 cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
1159 ncases= list.elements;
1160 if (first_expr_arg)
1162 first_expr_num= list.elements;
1163 list.push_back(first_expr_arg);
1165 if (else_expr_arg)
1167 else_expr_num= list.elements;
1168 list.push_back(else_expr_arg);
1170 set_arguments(list);
1171 bzero(&cmp_items, sizeof(cmp_items));
1173 double val_real();
1174 longlong val_int();
1175 String *val_str(String *);
1176 my_decimal *val_decimal(my_decimal *);
1177 bool fix_fields(THD *thd, Item **ref);
1178 void fix_length_and_dec();
1179 uint decimal_precision() const;
1180 table_map not_null_tables() const { return 0; }
1181 enum Item_result result_type () const { return cached_result_type; }
1182 enum_field_types field_type() const { return cached_field_type; }
1183 const char *func_name() const { return "case"; }
1184 virtual void print(String *str, enum_query_type query_type);
1185 Item *find_item(String *str);
1186 CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1187 void cleanup();
1188 void agg_str_lengths(Item *arg);
1189 void agg_num_lengths(Item *arg);
1193 The Item_func_in class implements the in_expr IN(values_list) function.
1195 The current implementation distinguishes 2 cases:
1196 1) all items in the value_list are constants and have the same
1197 result type. This case is handled by in_vector class.
1198 2) items in the value_list have different result types or there is some
1199 non-constant items.
1200 In this case Item_func_in employs several cmp_item objects to performs
1201 comparisons of in_expr and an item from the values_list. One cmp_item
1202 object for each result type. Different result types are collected in the
1203 fix_length_and_dec() member function by means of collect_cmp_types()
1204 function.
1206 class Item_func_in :public Item_func_opt_neg
1208 public:
1210 an array of values when the right hand arguments of IN
1211 are all SQL constant and there are no nulls
1213 in_vector *array;
1214 bool have_null;
1216 true when all arguments of the IN clause are of compatible types
1217 and can be used safely as comparisons for key conditions
1219 bool arg_types_compatible;
1220 Item_result left_result_type;
1221 cmp_item *cmp_items[6]; /* One cmp_item for each result type */
1222 DTCollation cmp_collation;
1224 Item_func_in(List<Item> &list)
1225 :Item_func_opt_neg(list), array(0), have_null(0),
1226 arg_types_compatible(FALSE)
1228 bzero(&cmp_items, sizeof(cmp_items));
1229 allowed_arg_cols= 0; // Fetch this value from first argument
1231 longlong val_int();
1232 bool fix_fields(THD *, Item **);
1233 void fix_length_and_dec();
1234 uint decimal_precision() const { return 1; }
1235 void cleanup()
1237 uint i;
1238 DBUG_ENTER("Item_func_in::cleanup");
1239 Item_int_func::cleanup();
1240 delete array;
1241 array= 0;
1242 for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1244 delete cmp_items[i];
1245 cmp_items[i]= 0;
1247 DBUG_VOID_RETURN;
1249 optimize_type select_optimize() const
1250 { return OPTIMIZE_KEY; }
1251 virtual void print(String *str, enum_query_type query_type);
1252 enum Functype functype() const { return IN_FUNC; }
1253 const char *func_name() const { return " IN "; }
1254 bool nulls_in_row();
1255 bool is_bool_func() { return 1; }
1256 CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1259 class cmp_item_row :public cmp_item
1261 cmp_item **comparators;
1262 uint n;
1263 public:
1264 cmp_item_row(): comparators(0), n(0) {}
1265 ~cmp_item_row();
1266 void store_value(Item *item);
1267 inline void alloc_comparators();
1268 int cmp(Item *arg);
1269 int compare(cmp_item *arg);
1270 cmp_item *make_same();
1271 void store_value_by_template(cmp_item *tmpl, Item *);
1272 friend void Item_func_in::fix_length_and_dec();
1276 class in_row :public in_vector
1278 cmp_item_row tmp;
1279 public:
1280 in_row(uint elements, Item *);
1281 ~in_row();
1282 void set(uint pos,Item *item);
1283 uchar *get_value(Item *item);
1284 friend void Item_func_in::fix_length_and_dec();
1285 Item_result result_type() { return ROW_RESULT; }
1288 /* Functions used by where clause */
1290 class Item_func_isnull :public Item_bool_func
1292 protected:
1293 longlong cached_value;
1294 public:
1295 Item_func_isnull(Item *a) :Item_bool_func(a) {}
1296 longlong val_int();
1297 enum Functype functype() const { return ISNULL_FUNC; }
1298 void fix_length_and_dec()
1300 decimals=0; max_length=1; maybe_null=0;
1301 update_used_tables();
1303 const char *func_name() const { return "isnull"; }
1304 /* Optimize case of not_null_column IS NULL */
1305 virtual void update_used_tables()
1307 if (!args[0]->maybe_null)
1309 used_tables_cache= 0; /* is always false */
1310 const_item_cache= 1;
1311 cached_value= (longlong) 0;
1313 else
1315 args[0]->update_used_tables();
1316 if ((const_item_cache= !(used_tables_cache= args[0]->used_tables()) &&
1317 !with_subselect))
1319 /* Remember if the value is always NULL or never NULL */
1320 cached_value= (longlong) args[0]->is_null();
1324 table_map not_null_tables() const { return 0; }
1325 optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1326 Item *neg_transformer(THD *thd);
1327 CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1330 /* Functions used by HAVING for rewriting IN subquery */
1332 class Item_in_subselect;
1335 This is like IS NOT NULL but it also remembers if it ever has
1336 encountered a NULL.
1338 class Item_is_not_null_test :public Item_func_isnull
1340 Item_in_subselect* owner;
1341 public:
1342 Item_is_not_null_test(Item_in_subselect* ow, Item *a)
1343 :Item_func_isnull(a), owner(ow)
1345 enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
1346 longlong val_int();
1347 const char *func_name() const { return "<is_not_null_test>"; }
1348 void update_used_tables();
1350 we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
1352 table_map used_tables() const
1353 { return used_tables_cache | RAND_TABLE_BIT; }
1357 class Item_func_isnotnull :public Item_bool_func
1359 bool abort_on_null;
1360 public:
1361 Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
1362 longlong val_int();
1363 enum Functype functype() const { return ISNOTNULL_FUNC; }
1364 void fix_length_and_dec()
1366 decimals=0; max_length=1; maybe_null=0;
1368 const char *func_name() const { return "isnotnull"; }
1369 optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1370 table_map not_null_tables() const
1371 { return abort_on_null ? not_null_tables_cache : 0; }
1372 Item *neg_transformer(THD *thd);
1373 virtual void print(String *str, enum_query_type query_type);
1374 CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1375 void top_level_item() { abort_on_null=1; }
1379 class Item_func_like :public Item_bool_func2
1381 // Turbo Boyer-Moore data
1382 bool canDoTurboBM; // pattern is '%abcd%' case
1383 const char* pattern;
1384 int pattern_len;
1386 // TurboBM buffers, *this is owner
1387 int* bmGs; // good suffix shift table, size is pattern_len + 1
1388 int* bmBc; // bad character shift table, size is alphabet_size
1390 void turboBM_compute_suffixes(int* suff);
1391 void turboBM_compute_good_suffix_shifts(int* suff);
1392 void turboBM_compute_bad_character_shifts();
1393 bool turboBM_matches(const char* text, int text_len) const;
1394 enum { alphabet_size = 256 };
1396 Item *escape_item;
1398 bool escape_used_in_parsing;
1400 public:
1401 int escape;
1403 Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1404 :Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0),
1405 bmGs(0), bmBc(0), escape_item(escape_arg),
1406 escape_used_in_parsing(escape_used) {}
1407 longlong val_int();
1408 enum Functype functype() const { return LIKE_FUNC; }
1409 optimize_type select_optimize() const;
1410 cond_result eq_cmp_result() const { return COND_TRUE; }
1411 const char *func_name() const { return "like"; }
1412 bool fix_fields(THD *thd, Item **ref);
1413 void cleanup();
1416 #ifdef USE_REGEX
1418 #include "my_regex.h"
1420 class Item_func_regex :public Item_bool_func
1422 my_regex_t preg;
1423 bool regex_compiled;
1424 bool regex_is_const;
1425 String prev_regexp;
1426 DTCollation cmp_collation;
1427 CHARSET_INFO *regex_lib_charset;
1428 int regex_lib_flags;
1429 String conv;
1430 int regcomp(bool send_error);
1431 public:
1432 Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b),
1433 regex_compiled(0),regex_is_const(0) {}
1434 void cleanup();
1435 longlong val_int();
1436 bool fix_fields(THD *thd, Item **ref);
1437 const char *func_name() const { return "regexp"; }
1439 virtual inline void print(String *str, enum_query_type query_type)
1441 print_op(str, query_type);
1444 CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1447 #else
1449 class Item_func_regex :public Item_bool_func
1451 public:
1452 Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b) {}
1453 longlong val_int() { return 0;}
1454 const char *func_name() const { return "regex"; }
1456 virtual inline void print(String *str, enum_query_type query_type)
1458 print_op(str, query_type);
1462 #endif /* USE_REGEX */
1465 typedef class Item COND;
1467 class Item_cond :public Item_bool_func
1469 protected:
1470 List<Item> list;
1471 bool abort_on_null;
1472 table_map and_tables_cache;
1474 public:
1475 /* Item_cond() is only used to create top level items */
1476 Item_cond(): Item_bool_func(), abort_on_null(1)
1477 { const_item_cache=0; }
1478 Item_cond(Item *i1,Item *i2)
1479 :Item_bool_func(), abort_on_null(0)
1481 list.push_back(i1);
1482 list.push_back(i2);
1484 Item_cond(THD *thd, Item_cond *item);
1485 Item_cond(List<Item> &nlist)
1486 :Item_bool_func(), list(nlist), abort_on_null(0) {}
1487 bool add(Item *item)
1489 DBUG_ASSERT(item);
1490 return list.push_back(item);
1492 bool add_at_head(Item *item)
1494 DBUG_ASSERT(item);
1495 return list.push_front(item);
1497 void add_at_head(List<Item> *nlist)
1499 DBUG_ASSERT(nlist->elements);
1500 list.prepand(nlist);
1502 bool fix_fields(THD *, Item **ref);
1504 enum Type type() const { return COND_ITEM; }
1505 List<Item>* argument_list() { return &list; }
1506 table_map used_tables() const;
1507 void update_used_tables();
1508 virtual void print(String *str, enum_query_type query_type);
1509 void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
1510 friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
1511 COND **conds);
1512 void top_level_item() { abort_on_null=1; }
1513 void copy_andor_arguments(THD *thd, Item_cond *item);
1514 bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1515 Item *transform(Item_transformer transformer, uchar *arg);
1516 void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1517 void neg_arguments(THD *thd);
1518 enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
1519 bool subst_argument_checker(uchar **arg) { return TRUE; }
1520 Item *compile(Item_analyzer analyzer, uchar **arg_p,
1521 Item_transformer transformer, uchar *arg_t);
1526 The class Item_equal is used to represent conjunctions of equality
1527 predicates of the form field1 = field2, and field=const in where
1528 conditions and on expressions.
1530 All equality predicates of the form field1=field2 contained in a
1531 conjunction are substituted for a sequence of items of this class.
1532 An item of this class Item_equal(f1,f2,...fk) represents a
1533 multiple equality f1=f2=...=fk.
1535 If a conjunction contains predicates f1=f2 and f2=f3, a new item of
1536 this class is created Item_equal(f1,f2,f3) representing the multiple
1537 equality f1=f2=f3 that substitutes the above equality predicates in
1538 the conjunction.
1539 A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1540 substituted for the item representing the same multiple equality
1541 f1=f2=f3.
1542 An item Item_equal(f1,f2) can appear instead of a conjunction of
1543 f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1545 An item of the class Item_equal inherits equalities from outer
1546 conjunctive levels.
1548 Suppose we have a where condition of the following form:
1549 WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
1550 In this case:
1551 f1=f2 will be substituted for Item_equal(f1,f2);
1552 f3=f4 and f3=f5 will be substituted for Item_equal(f3,f4,f5);
1553 f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1555 An object of the class Item_equal can contain an optional constant
1556 item c. Then it represents a multiple equality of the form
1557 c=f1=...=fk.
1559 Objects of the class Item_equal are used for the following:
1561 1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
1562 pair of tables ti and tj as joined by an equi-condition.
1563 Thus it provide us with additional access paths from table to table.
1565 2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
1566 SARGable predicates:
1567 f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
1568 It also can give us additional index scans and can allow us to
1569 improve selectivity estimates.
1571 3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
1572 selected execution plan for the query: if table ti is accessed
1573 before the table tj then in any predicate P in the where condition
1574 the occurrence of tj.fj is substituted for ti.fi. This can allow
1575 an evaluation of the predicate at an earlier step.
1577 When feature 1 is supported they say that join transitive closure
1578 is employed.
1579 When feature 2 is supported they say that search argument transitive
1580 closure is employed.
1581 Both features are usually supported by preprocessing original query and
1582 adding additional predicates.
1583 We do not just add predicates, we rather dynamically replace some
1584 predicates that can not be used to access tables in the investigated
1585 plan for those, obtained by substitution of some fields for equal fields,
1586 that can be used.
1588 Prepared Statements/Stored Procedures note: instances of class
1589 Item_equal are created only at the time a PS/SP is executed and
1590 are deleted in the end of execution. All changes made to these
1591 objects need not be registered in the list of changes of the parse
1592 tree and do not harm PS/SP re-execution.
1594 Item equal objects are employed only at the optimize phase. Usually they are
1595 not supposed to be evaluated. Yet in some cases we call the method val_int()
1596 for them. We have to take care of restricting the predicate such an
1597 object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
1600 class Item_equal: public Item_bool_func
1602 List<Item_field> fields; /* list of equal field items */
1603 Item *const_item; /* optional constant item equal to fields items */
1604 cmp_item *eval_item;
1605 Arg_comparator cmp;
1606 bool cond_false;
1607 bool compare_as_dates;
1608 public:
1609 inline Item_equal()
1610 : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
1611 { const_item_cache=0 ;}
1612 Item_equal(Item_field *f1, Item_field *f2);
1613 Item_equal(Item *c, Item_field *f);
1614 Item_equal(Item_equal *item_equal);
1615 inline Item* get_const() { return const_item; }
1616 void compare_const(Item *c);
1617 void add(Item *c, Item_field *f);
1618 void add(Item *c);
1619 void add(Item_field *f);
1620 uint members();
1621 bool contains(Field *field);
1622 Item_field* get_first() { return fields.head(); }
1623 void merge(Item_equal *item);
1624 void update_const();
1625 enum Functype functype() const { return MULT_EQUAL_FUNC; }
1626 longlong val_int();
1627 const char *func_name() const { return "multiple equal"; }
1628 optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1629 void sort(Item_field_cmpfunc compare, void *arg);
1630 friend class Item_equal_iterator;
1631 void fix_length_and_dec();
1632 bool fix_fields(THD *thd, Item **ref);
1633 void update_used_tables();
1634 bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1635 Item *transform(Item_transformer transformer, uchar *arg);
1636 virtual void print(String *str, enum_query_type query_type);
1637 CHARSET_INFO *compare_collation()
1638 { return fields.head()->collation.collation; }
1641 class COND_EQUAL: public Sql_alloc
1643 public:
1644 uint max_members; /* max number of members the current level
1645 list and all lower level lists */
1646 COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
1647 List<Item_equal> current_level; /* list of multiple equalities of
1648 the current and level */
1649 COND_EQUAL()
1651 upper_levels= 0;
1656 class Item_equal_iterator : public List_iterator_fast<Item_field>
1658 public:
1659 inline Item_equal_iterator(Item_equal &item_equal)
1660 :List_iterator_fast<Item_field> (item_equal.fields)
1662 inline Item_field* operator++(int)
1664 Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1665 return item;
1667 inline void rewind(void)
1669 List_iterator_fast<Item_field>::rewind();
1673 class Item_cond_and :public Item_cond
1675 public:
1676 COND_EQUAL cond_equal; /* contains list of Item_equal objects for
1677 the current and level and reference
1678 to multiple equalities of upper and levels */
1679 Item_cond_and() :Item_cond() {}
1680 Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1681 Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
1682 Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1683 enum Functype functype() const { return COND_AND_FUNC; }
1684 longlong val_int();
1685 const char *func_name() const { return "and"; }
1686 table_map not_null_tables() const
1687 { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1688 Item* copy_andor_structure(THD *thd)
1690 Item_cond_and *item;
1691 if ((item= new Item_cond_and(thd, this)))
1692 item->copy_andor_arguments(thd, this);
1693 return item;
1695 Item *neg_transformer(THD *thd);
1698 inline bool is_cond_and(Item *item)
1700 if (item->type() != Item::COND_ITEM)
1701 return FALSE;
1703 Item_cond *cond_item= (Item_cond*) item;
1704 return (cond_item->functype() == Item_func::COND_AND_FUNC);
1707 class Item_cond_or :public Item_cond
1709 public:
1710 Item_cond_or() :Item_cond() {}
1711 Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1712 Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
1713 Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1714 enum Functype functype() const { return COND_OR_FUNC; }
1715 longlong val_int();
1716 const char *func_name() const { return "or"; }
1717 table_map not_null_tables() const { return and_tables_cache; }
1718 Item* copy_andor_structure(THD *thd)
1720 Item_cond_or *item;
1721 if ((item= new Item_cond_or(thd, this)))
1722 item->copy_andor_arguments(thd, this);
1723 return item;
1725 Item *neg_transformer(THD *thd);
1728 inline bool is_cond_or(Item *item)
1730 if (item->type() != Item::COND_ITEM)
1731 return FALSE;
1733 Item_cond *cond_item= (Item_cond*) item;
1734 return (cond_item->functype() == Item_func::COND_OR_FUNC);
1738 XOR is Item_cond, not an Item_int_func because we could like to
1739 optimize (a XOR b) later on. It's low prio, though
1742 class Item_cond_xor :public Item_cond
1744 public:
1745 Item_cond_xor() :Item_cond() {}
1746 Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1747 enum Functype functype() const { return COND_XOR_FUNC; }
1748 /* TODO: remove the next line when implementing XOR optimization */
1749 enum Type type() const { return FUNC_ITEM; }
1750 longlong val_int();
1751 const char *func_name() const { return "xor"; }
1752 void top_level_item() {}
1756 /* Some useful inline functions */
1758 inline Item *and_conds(Item *a, Item *b)
1760 if (!b) return a;
1761 if (!a) return b;
1762 return new Item_cond_and(a, b);
1765 Item *and_expressions(Item *a, Item *b, Item **org_item);
1767 bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
1768 const char *warn_name, MYSQL_TIME *l_time);