MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
item_cmpfunc.h
1 #ifndef ITEM_CMPFUNC_INCLUDED
2 #define ITEM_CMPFUNC_INCLUDED
3 
4 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
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 as published by
8  the Free Software Foundation; version 2 of the License.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
18 
19 
20 /* compare and test functions */
21 
22 #include "thr_malloc.h" /* sql_calloc */
23 #include "item_func.h" /* Item_int_func, Item_bool_func */
24 #include "my_regex.h"
25 
26 extern Item_result item_cmp_type(Item_result a,Item_result b);
27 class Item_bool_func2;
28 class Arg_comparator;
29 
30 typedef int (Arg_comparator::*arg_cmp_func)();
31 
32 typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
33 
35 {
36  Item **a, **b;
37  arg_cmp_func func;
38  Item_result_field *owner;
39  Arg_comparator *comparators; // used only for compare_row()
40  double precision;
41  /* Fields used in DATE/DATETIME comparison. */
42  THD *thd;
43  enum_field_types a_type, b_type; // Types of a and b items
44  Item *a_cache, *b_cache; // Cached values of a and b items
45  bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
46  bool set_null; // TRUE <=> set owner->null_value
47  // when one of arguments is NULL.
48  longlong (*get_value_a_func)(THD *thd, Item ***item_arg, Item **cache_arg,
49  Item *warn_item, bool *is_null);
50  longlong (*get_value_b_func)(THD *thd, Item ***item_arg, Item **cache_arg,
51  Item *warn_item, bool *is_null);
52  bool try_year_cmp_func(Item_result type);
53  static bool get_date_from_const(Item *date_arg, Item *str_arg,
54  ulonglong *value);
55 public:
56  DTCollation cmp_collation;
57  /* Allow owner function to use string buffers. */
58  String value1, value2;
59 
60  Arg_comparator(): comparators(0), thd(0), a_cache(0), b_cache(0), set_null(TRUE),
61  get_value_a_func(0), get_value_b_func(0) {};
62  Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), comparators(0), thd(0),
63  a_cache(0), b_cache(0), set_null(TRUE),
64  get_value_a_func(0), get_value_b_func(0) {};
65 
66  int set_compare_func(Item_result_field *owner, Item_result type);
67  inline int set_compare_func(Item_result_field *owner_arg)
68  {
69  return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
70  (*b)->result_type()));
71  }
72  int set_cmp_func(Item_result_field *owner_arg,
73  Item **a1, Item **a2,
74  Item_result type);
75 
76  inline int set_cmp_func(Item_result_field *owner_arg,
77  Item **a1, Item **a2, bool set_null_arg)
78  {
79  set_null= set_null_arg;
80  return set_cmp_func(owner_arg, a1, a2,
81  item_cmp_type((*a1)->result_type(),
82  (*a2)->result_type()));
83  }
84  inline int compare() { return (this->*func)(); }
85 
86  int compare_string(); // compare args[0] & args[1]
87  int compare_binary_string(); // compare args[0] & args[1]
88  int compare_real(); // compare args[0] & args[1]
89  int compare_decimal(); // compare args[0] & args[1]
90  int compare_int_signed(); // compare args[0] & args[1]
94  int compare_time_packed();
96  int compare_row(); // compare args[0] & args[1]
97  int compare_e_string(); // compare args[0] & args[1]
98  int compare_e_binary_string(); // compare args[0] & args[1]
99  int compare_e_real(); // compare args[0] & args[1]
100  int compare_e_decimal(); // compare args[0] & args[1]
101  int compare_e_int(); // compare args[0] & args[1]
103  int compare_e_row(); // compare args[0] & args[1]
104  int compare_real_fixed();
105  int compare_e_real_fixed();
106  int compare_datetime(); // compare args[0] & args[1] as DATETIMEs
107 
108  static bool can_compare_as_dates(Item *a, Item *b, ulonglong *const_val_arg);
109 
110  Item** cache_converted_constant(THD *thd, Item **value, Item **cache,
111  Item_result type);
112  void set_datetime_cmp_func(Item_result_field *owner_arg, Item **a1, Item **b1);
113  static arg_cmp_func comparator_matrix [5][2];
114  inline bool is_owner_equal_func()
115  {
116  return (owner->type() == Item::FUNC_ITEM &&
117  ((Item_func*)owner)->functype() == Item_func::EQUAL_FUNC);
118  }
119  void cleanup()
120  {
121  delete [] comparators;
122  comparators= 0;
123  }
124  /*
125  Set correct cmp_context if items would be compared as INTs.
126  */
127  inline void set_cmp_context_for_datetime()
128  {
129  DBUG_ASSERT(func == &Arg_comparator::compare_datetime);
130  if ((*a)->is_temporal())
131  (*a)->cmp_context= INT_RESULT;
132  if ((*b)->is_temporal())
133  (*b)->cmp_context= INT_RESULT;
134  }
135  friend class Item_func;
136 };
137 
139 {
140 public:
141  Item_bool_func() : Item_int_func(), m_created_by_in2exists(false) {}
143  m_created_by_in2exists(false) {}
144  Item_bool_func(Item *a,Item *b) : Item_int_func(a,b),
145  m_created_by_in2exists(false) {}
146  Item_bool_func(THD *thd, Item_bool_func *item) : Item_int_func(thd, item),
147  m_created_by_in2exists(item->m_created_by_in2exists) {}
148  bool is_bool_func() { return 1; }
149  void fix_length_and_dec() { decimals=0; max_length=1; }
150  uint decimal_precision() const { return 1; }
151  virtual bool created_by_in2exists() const { return m_created_by_in2exists; }
152  void set_created_by_in2exists() { m_created_by_in2exists= true; }
153 private:
158  bool m_created_by_in2exists;
159 };
160 
161 
168 {
169 public:
170  virtual bool val_bool();
171  virtual longlong val_int();
172  virtual void fix_length_and_dec();
173  virtual void print(String *str, enum_query_type query_type);
174 
175 protected:
176  Item_func_truth(Item *a, bool a_value, bool a_affirmative)
177  : Item_bool_func(a), value(a_value), affirmative(a_affirmative)
178  {}
179 
180  ~Item_func_truth()
181  {}
182 private:
187  const bool value;
191  const bool affirmative;
192 };
193 
194 
200 {
201 public:
202  Item_func_istrue(Item *a) : Item_func_truth(a, true, true) {}
203  ~Item_func_istrue() {}
204  virtual const char* func_name() const { return "istrue"; }
205 };
206 
207 
213 {
214 public:
215  Item_func_isnottrue(Item *a) : Item_func_truth(a, true, false) {}
216  ~Item_func_isnottrue() {}
217  virtual const char* func_name() const { return "isnottrue"; }
218 };
219 
220 
226 {
227 public:
228  Item_func_isfalse(Item *a) : Item_func_truth(a, false, true) {}
229  ~Item_func_isfalse() {}
230  virtual const char* func_name() const { return "isfalse"; }
231 };
232 
233 
239 {
240 public:
241  Item_func_isnotfalse(Item *a) : Item_func_truth(a, false, false) {}
243  virtual const char* func_name() const { return "isnotfalse"; }
244 };
245 
246 
247 class Item_cache;
248 #define UNKNOWN ((my_bool)-1)
249 
250 
251 /*
252  Item_in_optimizer(left_expr, Item_in_subselect(...))
253 
254  Item_in_optimizer is used to wrap an instance of Item_in_subselect. This
255  class does the following:
256  - Evaluate the left expression and store it in Item_cache_* object (to
257  avoid re-evaluating it many times during subquery execution)
258  - Shortcut the evaluation of "NULL IN (...)" to NULL in the cases where we
259  don't care if the result is NULL or FALSE.
260 
261  args[1] keeps a reference to the Item_in_subselect object.
262 
263  args[0] is a copy of Item_in_subselect's left expression and should be
264  kept equal also after resolving.
265 
266  NOTE
267  It is not quite clear why the above listed functionality should be
268  placed into a separate class called 'Item_in_optimizer'.
269 */
270 
272 {
273 private:
274  Item_cache *cache;
275  bool save_cache;
276  /*
277  Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
278  UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
279  FALSE - result is FALSE
280  TRUE - result is NULL
281  */
282  my_bool result_for_null_param;
283 public:
285  Item_bool_func(a, reinterpret_cast<Item *>(b)), cache(0),
286  save_cache(0), result_for_null_param(UNKNOWN)
287  { with_subselect= TRUE; }
288  bool fix_fields(THD *, Item **);
289  bool fix_left(THD *thd, Item **ref);
290  void fix_after_pullout(st_select_lex *parent_select,
291  st_select_lex *removed_select);
292  bool is_null();
293  longlong val_int();
294  void cleanup();
295  const char *func_name() const { return "<in_optimizer>"; }
296  Item_cache **get_cache() { return &cache; }
297  void keep_top_level_cache();
298  Item *transform(Item_transformer transformer, uchar *arg);
299 };
300 
302 {
303 public:
304  Comp_creator() {} /* Remove gcc warning */
305  virtual ~Comp_creator() {} /* Remove gcc warning */
306  virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
307  virtual const char* symbol(bool invert) const = 0;
308  virtual bool eqne_op() const = 0;
309  virtual bool l_op() const = 0;
310 };
311 
313 {
314 public:
315  Eq_creator() {} /* Remove gcc warning */
316  virtual ~Eq_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 1; }
320  virtual bool l_op() const { return 0; }
321 };
322 
324 {
325 public:
326  Ne_creator() {} /* Remove gcc warning */
327  virtual ~Ne_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 1; }
331  virtual bool l_op() const { return 0; }
332 };
333 
335 {
336 public:
337  Gt_creator() {} /* Remove gcc warning */
338  virtual ~Gt_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 0; }
343 };
344 
346 {
347 public:
348  Lt_creator() {} /* Remove gcc warning */
349  virtual ~Lt_creator() {} /* Remove gcc warning */
350  virtual Item_bool_func2* create(Item *a, Item *b) const;
351  virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
352  virtual bool eqne_op() const { return 0; }
353  virtual bool l_op() const { return 1; }
354 };
355 
357 {
358 public:
359  Ge_creator() {} /* Remove gcc warning */
360  virtual ~Ge_creator() {} /* Remove gcc warning */
361  virtual Item_bool_func2* create(Item *a, Item *b) const;
362  virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
363  virtual bool eqne_op() const { return 0; }
364  virtual bool l_op() const { return 0; }
365 };
366 
368 {
369 public:
370  Le_creator() {} /* Remove gcc warning */
371  virtual ~Le_creator() {} /* Remove gcc warning */
372  virtual Item_bool_func2* create(Item *a, Item *b) const;
373  virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
374  virtual bool eqne_op() const { return 0; }
375  virtual bool l_op() const { return 1; }
376 };
377 
379 { /* Bool with 2 string args */
380 private:
381  bool convert_constant_arg(THD *thd, Item *field, Item **item);
382 protected:
383  Arg_comparator cmp;
384  bool abort_on_null;
385 
386 public:
387  Item_bool_func2(Item *a,Item *b)
388  :Item_bool_func(a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(FALSE) {}
389  void fix_length_and_dec();
390  int set_cmp_func()
391  {
392  return cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, TRUE);
393  }
394  optimize_type select_optimize() const { return OPTIMIZE_OP; }
395  virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
396  bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
397 
398  virtual inline void print(String *str, enum_query_type query_type)
399  {
400  Item_func::print_op(str, query_type);
401  }
402 
403  bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
404  const CHARSET_INFO *compare_collation()
405  { return cmp.cmp_collation.collation; }
406  void top_level_item() { abort_on_null= TRUE; }
407  void cleanup()
408  {
409  Item_bool_func::cleanup();
410  cmp.cleanup();
411  }
412 
413  friend class Arg_comparator;
414 };
415 
417 {
418 public:
420  {
421  allowed_arg_cols= 0; // Fetch this value from first argument
422  }
423  Item *neg_transformer(THD *thd);
424  virtual Item *negated_item();
425  bool subst_argument_checker(uchar **arg) { return TRUE; }
426 };
427 
434 {
435 public:
436  Item_func_xor(Item *i1, Item *i2) :Item_bool_func2(i1, i2) {}
437  enum Functype functype() const { return XOR_FUNC; }
438  const char *func_name() const { return "xor"; }
439  longlong val_int();
440  void top_level_item() {}
441  Item *neg_transformer(THD *thd);
442 };
443 
445 {
446 public:
448  longlong val_int();
449  enum Functype functype() const { return NOT_FUNC; }
450  const char *func_name() const { return "not"; }
451  Item *neg_transformer(THD *thd);
452  virtual void print(String *str, enum_query_type query_type);
453 };
454 
456 struct st_join_table;
457 /*
458  trigcond<param>(arg) ::= param? arg : TRUE
459 
460  The class Item_func_trig_cond is used for guarded predicates
461  which are employed only for internal purposes.
462  A guarded predicate is an object consisting of an a regular or
463  a guarded predicate P and a pointer to a boolean guard variable g.
464  A guarded predicate P/g is evaluated to true if the value of the
465  guard g is false, otherwise it is evaluated to the same value that
466  the predicate P: val(P/g)= g ? val(P):true.
467  Guarded predicates allow us to include predicates into a conjunction
468  conditionally. Currently they are utilized for pushed down predicates
469  in queries with outer join operations.
470 
471  In the future, probably, it makes sense to extend this class to
472  the objects consisting of three elements: a predicate P, a pointer
473  to a variable g and a firing value s with following evaluation
474  rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
475  one item for the objects of the form P/g1/g2...
476 
477  Objects of this class are built only for query execution after
478  the execution plan has been already selected. That's why this
479  class needs only val_int out of generic methods.
480 
481  Current uses of Item_func_trig_cond objects:
482  - To wrap selection conditions when executing outer joins
483  - To wrap condition that is pushed down into subquery
484 */
485 
487 {
488 public:
490  {
509  };
510 private:
512  bool *trig_var;
514  const struct st_join_table *trig_tab;
516  enum_trig_type trig_type;
517 public:
525  Item_func_trig_cond(Item *a, bool *f, struct st_join_table *tab,
526  enum_trig_type trig_type_arg)
527  : Item_bool_func(a), trig_var(f), trig_tab(tab), trig_type(trig_type_arg)
528  {}
529  longlong val_int() { return *trig_var ? args[0]->val_int() : 1; }
530  enum Functype functype() const { return TRIG_COND_FUNC; };
532  const char *func_name() const { return "<if>"; };
533  bool const_item() const { return FALSE; }
534  bool *get_trig_var() { return trig_var; }
535  /* The following is needed for ICP: */
536  table_map used_tables() const { return args[0]->used_tables(); }
537  void print(String *str, enum_query_type query_type);
538 };
539 
540 
542 {
543  /* allow to check presence of values in max/min optimization */
544  Item_sum_hybrid *test_sum_item;
545  Item_maxmin_subselect *test_sub_item;
546  Item_subselect *subselect;
547 
548  bool abort_on_null;
549 public:
550  bool show;
551 
553  :Item_func_not(a), test_sum_item(0), test_sub_item(0), subselect(0),
554  abort_on_null(0), show(0)
555  {}
556  virtual void top_level_item() { abort_on_null= 1; }
557  bool top_level() { return abort_on_null; }
558  longlong val_int();
559  enum Functype functype() const { return NOT_ALL_FUNC; }
560  const char *func_name() const { return "<not>"; }
561  virtual void print(String *str, enum_query_type query_type);
562  void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
563  void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
564  void set_subselect(Item_subselect *item) { subselect= item; }
565  table_map not_null_tables() const
566  {
567  /*
568  See handling of not_null_tables_cache in
569  Item_in_optimizer::fix_fields().
570 
571  This item is the result of a transformation from an ALL clause
572  such as
573  left-expr < ALL(subquery)
574  into
575  <not>(left-expr >= (subquery)
576 
577  An inequality usually rejects NULLs from both operands, so the
578  not_null_tables() of the inequality is the union of the
579  null-rejecting tables of both operands. However, since this is a
580  transformed ALL clause that should return true if the subquery
581  is empty (even if left-expr is NULL), it is not null rejecting
582  for left-expr. The not null tables mask for left-expr should be
583  removed, leaving only the null-rejecting tables of the
584  subquery. Item_subselect::not_null_tables() always returns 0 (no
585  null-rejecting tables). Therefore, always return 0.
586  */
587  return 0;
588  }
589  bool empty_underlying_subquery();
590  Item *neg_transformer(THD *thd);
591 };
592 
593 
595 {
596 public:
597 
599  longlong val_int();
600  const char *func_name() const { return "<nop>"; }
601  table_map not_null_tables() const { return not_null_tables_cache; }
602  Item *neg_transformer(THD *thd);
603 };
604 
605 
607 {
608 public:
609  Item_func_eq(Item *a,Item *b) :
611  {}
612  longlong val_int();
613  enum Functype functype() const { return EQ_FUNC; }
614  enum Functype rev_functype() const { return EQ_FUNC; }
615  cond_result eq_cmp_result() const { return COND_TRUE; }
616  const char *func_name() const { return "="; }
617  Item *negated_item();
618  virtual bool equality_substitution_analyzer(uchar **arg) { return true; }
619  virtual Item* equality_substitution_transformer(uchar *arg);
620 };
621 
623 {
624 public:
626  longlong val_int();
627  void fix_length_and_dec();
628  table_map not_null_tables() const { return 0; }
629  enum Functype functype() const { return EQUAL_FUNC; }
630  enum Functype rev_functype() const { return EQUAL_FUNC; }
631  cond_result eq_cmp_result() const { return COND_TRUE; }
632  const char *func_name() const { return "<=>"; }
633  Item *neg_transformer(THD *thd) { return 0; }
634 };
635 
636 
638 {
639 public:
641  longlong val_int();
642  enum Functype functype() const { return GE_FUNC; }
643  enum Functype rev_functype() const { return LE_FUNC; }
644  cond_result eq_cmp_result() const { return COND_TRUE; }
645  const char *func_name() const { return ">="; }
646  Item *negated_item();
647 };
648 
649 
651 {
652 public:
654  longlong val_int();
655  enum Functype functype() const { return GT_FUNC; }
656  enum Functype rev_functype() const { return LT_FUNC; }
657  cond_result eq_cmp_result() const { return COND_FALSE; }
658  const char *func_name() const { return ">"; }
659  Item *negated_item();
660 };
661 
662 
664 {
665 public:
667  longlong val_int();
668  enum Functype functype() const { return LE_FUNC; }
669  enum Functype rev_functype() const { return GE_FUNC; }
670  cond_result eq_cmp_result() const { return COND_TRUE; }
671  const char *func_name() const { return "<="; }
672  Item *negated_item();
673 };
674 
675 
677 {
678 public:
680  longlong val_int();
681  enum Functype functype() const { return LT_FUNC; }
682  enum Functype rev_functype() const { return GT_FUNC; }
683  cond_result eq_cmp_result() const { return COND_FALSE; }
684  const char *func_name() const { return "<"; }
685  Item *negated_item();
686 };
687 
688 
690 {
691 public:
693  longlong val_int();
694  enum Functype functype() const { return NE_FUNC; }
695  cond_result eq_cmp_result() const { return COND_FALSE; }
696  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
697  const char *func_name() const { return "<>"; }
698  Item *negated_item();
699 };
700 
701 
702 /*
703  The class Item_func_opt_neg is defined to factor out the functionality
704  common for the classes Item_func_between and Item_func_in. The objects
705  of these classes can express predicates or there negations.
706  The alternative approach would be to create pairs Item_func_between,
707  Item_func_notbetween and Item_func_in, Item_func_notin.
708 
709 */
710 
712 {
713 public:
714  bool negated; /* <=> the item represents NOT <func> */
715  bool pred_level; /* <=> [NOT] <func> is used on a predicate level */
716 public:
717  Item_func_opt_neg(Item *a, Item *b, Item *c)
718  :Item_int_func(a, b, c), negated(0), pred_level(0) {}
720  :Item_int_func(list), negated(0), pred_level(0) {}
721 public:
722  inline void negate() { negated= !negated; }
723  inline void top_level_item() { pred_level= 1; }
724  Item *neg_transformer(THD *thd)
725  {
726  negated= !negated;
727  return this;
728  }
729  bool eq(const Item *item, bool binary_cmp) const;
730  bool subst_argument_checker(uchar **arg) { return TRUE; }
731 };
732 
733 
735 {
736  DTCollation cmp_collation;
737 public:
738  Item_result cmp_type;
739  String value0,value1,value2;
740  /* TRUE <=> arguments will be compared as dates. */
741  bool compare_as_dates_with_strings;
742  bool compare_as_temporal_dates;
743  bool compare_as_temporal_times;
744 
745  /* Comparators used for DATE/DATETIME comparison. */
746  Arg_comparator ge_cmp, le_cmp;
747  Item_func_between(Item *a, Item *b, Item *c)
748  :Item_func_opt_neg(a, b, c), compare_as_dates_with_strings(FALSE),
749  compare_as_temporal_dates(FALSE),
750  compare_as_temporal_times(FALSE) {}
751  longlong val_int();
752  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
753  enum Functype functype() const { return BETWEEN; }
754  const char *func_name() const { return "between"; }
755  bool fix_fields(THD *, Item **);
756  void fix_length_and_dec();
757  virtual void print(String *str, enum_query_type query_type);
758  bool is_bool_func() { return 1; }
759  const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
760  uint decimal_precision() const { return 1; }
761 };
762 
763 
765 {
766 public:
767  Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
768  longlong val_int();
769  optimize_type select_optimize() const { return OPTIMIZE_NONE; }
770  const char *func_name() const { return "strcmp"; }
771 
772  virtual inline void print(String *str, enum_query_type query_type)
773  {
774  Item_func::print(str, query_type);
775  }
776  void fix_length_and_dec()
777  {
778  Item_bool_func2::fix_length_and_dec();
779  fix_char_length(2); // returns "1" or "0" or "-1"
780  }
781 };
782 
783 
785 {
786  Item_result type;
787  double dbl;
788  my_decimal dec;
789 };
790 
792 {
793  Item_row *row;
794  my_bool use_decimal_comparison;
795  interval_range *intervals;
796 public:
798  :Item_int_func(a),row(a),intervals(0)
799  {
800  allowed_arg_cols= 0; // Fetch this value from first argument
801  }
802  longlong val_int();
803  void fix_length_and_dec();
804  const char *func_name() const { return "interval"; }
805  uint decimal_precision() const { return 2; }
806 };
807 
808 
810 {
811 protected:
812  enum_field_types cached_field_type;
814 public:
816  double real_op();
817  longlong int_op();
818  String *str_op(String *);
819  bool date_op(MYSQL_TIME *ltime, uint fuzzydate);
820  bool time_op(MYSQL_TIME *ltime);
822  void fix_length_and_dec();
823  void find_num_type() {}
824  enum Item_result result_type () const { return hybrid_type; }
825  const char *func_name() const { return "coalesce"; }
826  table_map not_null_tables() const { return 0; }
827  enum_field_types field_type() const { return cached_field_type; }
828 };
829 
830 
832 {
833 protected:
834  bool field_type_defined;
835 public:
837  double real_op();
838  longlong int_op();
839  String *str_op(String *str);
840  bool date_op(MYSQL_TIME *ltime, uint fuzzydate);
841  bool time_op(MYSQL_TIME *ltime);
843  void fix_length_and_dec();
844  const char *func_name() const { return "ifnull"; }
845  Field *tmp_table_field(TABLE *table);
846  uint decimal_precision() const;
847 };
848 
849 
850 class Item_func_if :public Item_func
851 {
852  enum Item_result cached_result_type;
853  enum_field_types cached_field_type;
854 public:
855  Item_func_if(Item *a,Item *b,Item *c)
856  :Item_func(a,b,c), cached_result_type(INT_RESULT)
857  {}
858  double val_real();
859  longlong val_int();
860  String *val_str(String *str);
861  my_decimal *val_decimal(my_decimal *);
862  bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
863  bool get_time(MYSQL_TIME *ltime);
864  enum Item_result result_type () const { return cached_result_type; }
865  enum_field_types field_type() const { return cached_field_type; }
866  bool fix_fields(THD *, Item **);
867  void fix_length_and_dec();
868  uint decimal_precision() const;
869  const char *func_name() const { return "if"; }
870 private:
871  void cache_type_info(Item *source);
872 };
873 
874 
876 {
877  enum Item_result cached_result_type;
878 public:
879  Item_func_nullif(Item *a,Item *b)
880  :Item_bool_func2(a,b), cached_result_type(INT_RESULT)
881  {}
882  double val_real();
883  longlong val_int();
884  String *val_str(String *str);
885  my_decimal *val_decimal(my_decimal *);
886  enum Item_result result_type () const { return cached_result_type; }
887  void fix_length_and_dec();
888  uint decimal_precision() const { return args[0]->decimal_precision(); }
889  const char *func_name() const { return "nullif"; }
890 
891  virtual inline void print(String *str, enum_query_type query_type)
892  {
893  Item_func::print(str, query_type);
894  }
895 
896  table_map not_null_tables() const { return 0; }
897  bool is_null();
898 };
899 
900 
901 /* Functions to handle the optimized IN */
902 
903 
904 /* A vector of values of some type */
905 
906 class in_vector :public Sql_alloc
907 {
908 public:
909  char *base;
910  uint size;
911  qsort2_cmp compare;
912  const CHARSET_INFO *collation;
913  uint count;
914  uint used_count;
915  in_vector() {}
916  in_vector(uint elements,uint element_length,qsort2_cmp cmp_func,
917  const CHARSET_INFO *cmp_coll)
918  :base((char*) sql_calloc(elements*element_length)),
919  size(element_length), compare(cmp_func), collation(cmp_coll),
920  count(elements), used_count(elements) {}
921  virtual ~in_vector() {}
922  virtual void set(uint pos,Item *item)=0;
923  virtual uchar *get_value(Item *item)=0;
924  void sort()
925  {
926  my_qsort2(base,used_count,size,compare,collation);
927  }
928  int find(Item *item);
929 
930  /*
931  Create an instance of Item_{type} (e.g. Item_decimal) constant object
932  which type allows it to hold an element of this vector without any
933  conversions.
934  The purpose of this function is to be able to get elements of this
935  vector in form of Item_xxx constants without creating Item_xxx object
936  for every array element you get (i.e. this implements "FlyWeight" pattern)
937  */
938  virtual Item* create_item() { return NULL; }
939 
940  /*
941  Store the value at position #pos into provided item object
942  SYNOPSIS
943  value_to_item()
944  pos Index of value to store
945  item Constant item to store value into. The item must be of the same
946  type that create_item() returns.
947  */
948  virtual void value_to_item(uint pos, Item *item) { }
949 
950  /* Compare values number pos1 and pos2 for equality */
951  bool compare_elems(uint pos1, uint pos2)
952  {
953  return test(compare(collation, base + pos1*size, base + pos2*size));
954  }
955  virtual Item_result result_type()= 0;
956 };
957 
958 class in_string :public in_vector
959 {
960  char buff[STRING_BUFFER_USUAL_SIZE];
961  String tmp;
962 public:
963  in_string(uint elements,qsort2_cmp cmp_func, const CHARSET_INFO *cs);
964  ~in_string();
965  void set(uint pos,Item *item);
966  uchar *get_value(Item *item);
967  Item* create_item()
968  {
969  return new Item_string(collation);
970  }
971  void value_to_item(uint pos, Item *item)
972  {
973  String *str=((String*) base)+pos;
974  Item_string *to= (Item_string*)item;
975  to->str_value= *str;
976  }
977  Item_result result_type() { return STRING_RESULT; }
978 };
979 
980 class in_longlong :public in_vector
981 {
982 protected:
983  /*
984  Here we declare a temporary variable (tmp) of the same type as the
985  elements of this vector. tmp is used in finding if a given value is in
986  the list.
987  */
989  {
990  longlong val;
991  longlong unsigned_flag; // Use longlong, not bool, to preserve alignment
992  } tmp;
993 public:
994  in_longlong(uint elements);
995  void set(uint pos,Item *item);
996  uchar *get_value(Item *item);
997 
998  Item* create_item()
999  {
1000  /*
1001  We're created a signed INT, this may not be correct in
1002  general case (see BUG#19342).
1003  */
1004  return new Item_int((longlong)0);
1005  }
1006  void value_to_item(uint pos, Item *item)
1007  {
1008  ((Item_int*) item)->value= ((packed_longlong*) base)[pos].val;
1009  ((Item_int*) item)->unsigned_flag= (my_bool)
1010  ((packed_longlong*) base)[pos].unsigned_flag;
1011  }
1012  Item_result result_type() { return INT_RESULT; }
1013 
1014  friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
1015 };
1016 
1017 
1019 {
1020 public:
1021  in_datetime_as_longlong(uint elements)
1022  :in_longlong(elements) {};
1023  Item *create_item()
1024  {
1025  return new Item_temporal(MYSQL_TYPE_DATETIME, 0LL);
1026  }
1027  void set(uint pos, Item *item);
1028  uchar *get_value(Item *item);
1029 };
1030 
1031 
1033 {
1034 public:
1035  in_time_as_longlong(uint elements)
1036  :in_longlong(elements) {};
1037  Item *create_item()
1038  {
1039  return new Item_temporal(MYSQL_TYPE_TIME, 0LL);
1040  }
1041  void set(uint pos, Item *item);
1042  uchar *get_value(Item *item);
1043 };
1044 
1045 
1046 /*
1047  Class to represent a vector of constant DATE/DATETIME values.
1048  Values are obtained with help of the get_datetime_value() function.
1049  If the left item is a constant one then its value is cached in the
1050  lval_cache variable.
1051 */
1053 {
1054 public:
1055  THD *thd;
1056  /* An item used to issue warnings. */
1057  Item *warn_item;
1058  /* Cache for the left item. */
1059  Item *lval_cache;
1060 
1061  in_datetime(Item *warn_item_arg, uint elements)
1062  :in_longlong(elements), thd(current_thd), warn_item(warn_item_arg),
1063  lval_cache(0) {};
1064  void set(uint pos,Item *item);
1065  uchar *get_value(Item *item);
1066  friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
1067  Item* create_item()
1068  {
1069  return new Item_temporal(MYSQL_TYPE_DATETIME, (longlong) 0);
1070  }
1071 };
1072 
1073 
1074 class in_double :public in_vector
1075 {
1076  double tmp;
1077 public:
1078  in_double(uint elements);
1079  void set(uint pos,Item *item);
1080  uchar *get_value(Item *item);
1081  Item *create_item()
1082  {
1083  return new Item_float(0.0, 0);
1084  }
1085  void value_to_item(uint pos, Item *item)
1086  {
1087  ((Item_float*)item)->value= ((double*) base)[pos];
1088  }
1089  Item_result result_type() { return REAL_RESULT; }
1090 };
1091 
1092 
1093 class in_decimal :public in_vector
1094 {
1095  my_decimal val;
1096 public:
1097  in_decimal(uint elements);
1098  void set(uint pos, Item *item);
1099  uchar *get_value(Item *item);
1100  Item *create_item()
1101  {
1102  return new Item_decimal(0, FALSE);
1103  }
1104  void value_to_item(uint pos, Item *item)
1105  {
1106  my_decimal *dec= ((my_decimal *)base) + pos;
1107  Item_decimal *item_dec= (Item_decimal*)item;
1108  item_dec->set_decimal_value(dec);
1109  }
1110  Item_result result_type() { return DECIMAL_RESULT; }
1111 
1112 };
1113 
1114 
1115 /*
1116 ** Classes for easy comparing of non const items
1117 */
1118 
1119 class cmp_item :public Sql_alloc
1120 {
1121 public:
1122  const CHARSET_INFO *cmp_charset;
1123  cmp_item() { cmp_charset= &my_charset_bin; }
1124  virtual ~cmp_item() {}
1125  virtual void store_value(Item *item)= 0;
1126  virtual int cmp(Item *item)= 0;
1127  // for optimized IN with row
1128  virtual int compare(cmp_item *item)= 0;
1129  static cmp_item* get_comparator(Item_result type, const CHARSET_INFO *cs);
1130  virtual cmp_item *make_same()= 0;
1131  virtual void store_value_by_template(cmp_item *tmpl, Item *item)
1132  {
1133  store_value(item);
1134  }
1135 };
1136 
1138 {
1139 protected:
1140  String *value_res;
1141 public:
1142  cmp_item_string () {}
1143  cmp_item_string (const CHARSET_INFO *cs) { cmp_charset= cs; }
1144  void set_charset(const CHARSET_INFO *cs) { cmp_charset= cs; }
1145  friend class cmp_item_sort_string;
1146  friend class cmp_item_sort_string_in_static;
1147 };
1148 
1150 {
1151 protected:
1152  char value_buff[STRING_BUFFER_USUAL_SIZE];
1153  String value;
1154 public:
1156  cmp_item_string() {}
1158  cmp_item_string(cs),
1159  value(value_buff, sizeof(value_buff), cs) {}
1160  void store_value(Item *item)
1161  {
1162  String *res= item->val_str(&value);
1163  if(res && (res != &value))
1164  {
1165  // 'res' may point in item's temporary internal data, so make a copy
1166  value.copy(*res);
1167  }
1168  value_res= &value;
1169  }
1170  int cmp(Item *arg)
1171  {
1172  char buff[STRING_BUFFER_USUAL_SIZE];
1173  String tmp(buff, sizeof(buff), cmp_charset), *res;
1174  res= arg->val_str(&tmp);
1175  return (value_res ? (res ? sortcmp(value_res, res, cmp_charset) : 1) :
1176  (res ? -1 : 0));
1177  }
1178  int compare(cmp_item *ci)
1179  {
1180  cmp_item_string *l_cmp= (cmp_item_string *) ci;
1181  return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1182  }
1183  cmp_item *make_same();
1184  void set_charset(const CHARSET_INFO *cs)
1185  {
1186  cmp_charset= cs;
1187  value.set_quick(value_buff, sizeof(value_buff), cs);
1188  }
1189 };
1190 
1191 class cmp_item_int :public cmp_item
1192 {
1193  longlong value;
1194 public:
1195  cmp_item_int() {} /* Remove gcc warning */
1196  void store_value(Item *item)
1197  {
1198  value= item->val_int();
1199  }
1200  int cmp(Item *arg)
1201  {
1202  return value != arg->val_int();
1203  }
1204  int compare(cmp_item *ci)
1205  {
1206  cmp_item_int *l_cmp= (cmp_item_int *)ci;
1207  return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
1208  }
1209  cmp_item *make_same();
1210 };
1211 
1212 /*
1213  Compare items in the DATETIME context.
1214  Values are obtained with help of the get_datetime_value() function.
1215  If the left item is a constant one then its value is cached in the
1216  lval_cache variable.
1217 */
1219 {
1220  longlong value;
1221 public:
1222  THD *thd;
1223  /* Item used for issuing warnings. */
1224  Item *warn_item;
1225  /* Cache for the left item. */
1226  Item *lval_cache;
1227 
1228  cmp_item_datetime(Item *warn_item_arg)
1229  :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
1230  void store_value(Item *item);
1231  int cmp(Item *arg);
1232  int compare(cmp_item *ci);
1233  cmp_item *make_same();
1234 };
1235 
1237 {
1238  double value;
1239 public:
1240  cmp_item_real() {} /* Remove gcc warning */
1241  void store_value(Item *item)
1242  {
1243  value= item->val_real();
1244  }
1245  int cmp(Item *arg)
1246  {
1247  return value != arg->val_real();
1248  }
1249  int compare(cmp_item *ci)
1250  {
1251  cmp_item_real *l_cmp= (cmp_item_real *) ci;
1252  return (value < l_cmp->value)? -1 : ((value == l_cmp->value) ? 0 : 1);
1253  }
1254  cmp_item *make_same();
1255 };
1256 
1257 
1259 {
1260  my_decimal value;
1261 public:
1262  cmp_item_decimal() {} /* Remove gcc warning */
1263  void store_value(Item *item);
1264  int cmp(Item *arg);
1265  int compare(cmp_item *c);
1266  cmp_item *make_same();
1267 };
1268 
1269 
1270 /*
1271  cmp_item for optimized IN with row (right part string, which never
1272  be changed)
1273 */
1274 
1276 {
1277  protected:
1278  String value;
1279 public:
1281  cmp_item_string(cs) {}
1282  void store_value(Item *item)
1283  {
1284  value_res= item->val_str(&value);
1285  }
1286  int cmp(Item *item)
1287  {
1288  // Should never be called
1289  DBUG_ASSERT(0);
1290  return 1;
1291  }
1292  int compare(cmp_item *ci)
1293  {
1294  cmp_item_string *l_cmp= (cmp_item_string *) ci;
1295  return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1296  }
1297  cmp_item *make_same()
1298  {
1299  return new cmp_item_sort_string_in_static(cmp_charset);
1300  }
1301 };
1302 
1303 
1304 /*
1305  The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1306  implementation.
1307 
1308  When there is no expression between CASE and the first WHEN
1309  (the CASE expression) then this function simple checks all WHEN expressions
1310  one after another. When some WHEN expression evaluated to TRUE then the
1311  value of the corresponding THEN expression is returned.
1312 
1313  When the CASE expression is specified then it is compared to each WHEN
1314  expression individually. When an equal WHEN expression is found
1315  corresponding THEN expression is returned.
1316  In order to do correct comparisons several comparators are used. One for
1317  each result type. Different result types that are used in particular
1318  CASE ... END expression are collected in the fix_length_and_dec() member
1319  function and only comparators for there result types are used.
1320 */
1321 
1323 {
1324  int first_expr_num, else_expr_num;
1325  enum Item_result cached_result_type, left_result_type;
1326  String tmp_value;
1327  uint ncases;
1328  Item_result cmp_type;
1329  DTCollation cmp_collation;
1330  enum_field_types cached_field_type;
1331  cmp_item *cmp_items[5]; /* For all result types */
1332  cmp_item *case_item;
1333 public:
1334  Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
1335  :Item_func(), first_expr_num(-1), else_expr_num(-1),
1336  cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
1337  {
1338  ncases= list.elements;
1339  if (first_expr_arg)
1340  {
1341  first_expr_num= list.elements;
1342  list.push_back(first_expr_arg);
1343  }
1344  if (else_expr_arg)
1345  {
1346  else_expr_num= list.elements;
1347  list.push_back(else_expr_arg);
1348  }
1349  set_arguments(list);
1350  memset(&cmp_items, 0, sizeof(cmp_items));
1351  }
1352  double val_real();
1353  longlong val_int();
1354  String *val_str(String *);
1355  my_decimal *val_decimal(my_decimal *);
1356  bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
1357  bool get_time(MYSQL_TIME *ltime);
1358  bool fix_fields(THD *thd, Item **ref);
1359  void fix_length_and_dec();
1360  uint decimal_precision() const;
1361  table_map not_null_tables() const { return 0; }
1362  enum Item_result result_type () const { return cached_result_type; }
1363  enum_field_types field_type() const { return cached_field_type; }
1364  const char *func_name() const { return "case"; }
1365  virtual void print(String *str, enum_query_type query_type);
1366  Item *find_item(String *str);
1367  const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1368  void cleanup();
1369  void agg_num_lengths(Item *arg);
1370 };
1371 
1372 /*
1373  The Item_func_in class implements the in_expr IN(values_list) function.
1374 
1375  The current implementation distinguishes 2 cases:
1376  1) all items in the value_list are constants and have the same
1377  result type. This case is handled by in_vector class.
1378  2) items in the value_list have different result types or there is some
1379  non-constant items.
1380  In this case Item_func_in employs several cmp_item objects to performs
1381  comparisons of in_expr and an item from the values_list. One cmp_item
1382  object for each result type. Different result types are collected in the
1383  fix_length_and_dec() member function by means of collect_cmp_types()
1384  function.
1385 */
1387 {
1388 public:
1389  /*
1390  an array of values when the right hand arguments of IN
1391  are all SQL constant and there are no nulls
1392  */
1393  in_vector *array;
1394  bool have_null;
1395  /*
1396  true when all arguments of the IN clause are of compatible types
1397  and can be used safely as comparisons for key conditions
1398  */
1399  bool arg_types_compatible;
1400  Item_result left_result_type;
1401  cmp_item *cmp_items[6]; /* One cmp_item for each result type */
1402  DTCollation cmp_collation;
1403 
1404  Item_func_in(List<Item> &list)
1405  :Item_func_opt_neg(list), array(0), have_null(0),
1406  arg_types_compatible(FALSE)
1407  {
1408  memset(&cmp_items, 0, sizeof(cmp_items));
1409  allowed_arg_cols= 0; // Fetch this value from first argument
1410  }
1411  longlong val_int();
1412  bool fix_fields(THD *, Item **);
1413  void fix_length_and_dec();
1414  uint decimal_precision() const { return 1; }
1415  void cleanup()
1416  {
1417  uint i;
1418  DBUG_ENTER("Item_func_in::cleanup");
1419  Item_int_func::cleanup();
1420  delete array;
1421  array= 0;
1422  for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1423  {
1424  delete cmp_items[i];
1425  cmp_items[i]= 0;
1426  }
1427  DBUG_VOID_RETURN;
1428  }
1429  optimize_type select_optimize() const
1430  { return OPTIMIZE_KEY; }
1431  virtual void print(String *str, enum_query_type query_type);
1432  enum Functype functype() const { return IN_FUNC; }
1433  const char *func_name() const { return " IN "; }
1434  bool nulls_in_row();
1435  bool is_bool_func() { return 1; }
1436  const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1437 };
1438 
1439 class cmp_item_row :public cmp_item
1440 {
1441  cmp_item **comparators;
1442  uint n;
1443 public:
1444  cmp_item_row(): comparators(0), n(0) {}
1445  ~cmp_item_row();
1446  void store_value(Item *item);
1447  inline void alloc_comparators();
1448  int cmp(Item *arg);
1449  int compare(cmp_item *arg);
1450  cmp_item *make_same();
1451  void store_value_by_template(cmp_item *tmpl, Item *);
1452  friend void Item_func_in::fix_length_and_dec();
1453 };
1454 
1455 
1456 class in_row :public in_vector
1457 {
1458  cmp_item_row tmp;
1459 public:
1460  in_row(uint elements, Item *);
1461  ~in_row();
1462  void set(uint pos,Item *item);
1463  uchar *get_value(Item *item);
1464  friend void Item_func_in::fix_length_and_dec();
1465  Item_result result_type() { return ROW_RESULT; }
1466 };
1467 
1468 /* Functions used by where clause */
1469 
1471 {
1472 protected:
1473  longlong cached_value;
1474 public:
1476  longlong val_int();
1477  enum Functype functype() const { return ISNULL_FUNC; }
1478  void fix_length_and_dec()
1479  {
1480  decimals=0; max_length=1; maybe_null=0;
1481  update_used_tables();
1482  }
1483  const char *func_name() const { return "isnull"; }
1484  /* Optimize case of not_null_column IS NULL */
1485  virtual void update_used_tables()
1486  {
1487  if (!args[0]->maybe_null)
1488  {
1489  used_tables_cache= 0; /* is always false */
1490  const_item_cache= 1;
1491  cached_value= (longlong) 0;
1492  }
1493  else
1494  {
1495  args[0]->update_used_tables();
1496  with_subselect= args[0]->has_subquery();
1497  with_stored_program= args[0]->has_stored_program();
1498 
1499  if ((const_item_cache= !(used_tables_cache= args[0]->used_tables()) &&
1500  !with_subselect && !with_stored_program))
1501  {
1502  /* Remember if the value is always NULL or never NULL */
1503  cached_value= (longlong) args[0]->is_null();
1504  }
1505  }
1506  }
1507  table_map not_null_tables() const { return 0; }
1508  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1509  Item *neg_transformer(THD *thd);
1510  const CHARSET_INFO *compare_collation()
1511  { return args[0]->collation.collation; }
1512 };
1513 
1514 /* Functions used by HAVING for rewriting IN subquery */
1515 
1516 class Item_in_subselect;
1517 
1518 /*
1519  This is like IS NOT NULL but it also remembers if it ever has
1520  encountered a NULL; it remembers this in the "was_null" property of the
1521  "owner" item.
1522 */
1524 {
1525  Item_in_subselect* owner;
1526 public:
1528  :Item_func_isnull(a), owner(ow)
1529  {}
1530  enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
1531  longlong val_int();
1532  const char *func_name() const { return "<is_not_null_test>"; }
1533  void update_used_tables();
1539  table_map get_initial_pseudo_tables() const { return RAND_TABLE_BIT; }
1540 };
1541 
1542 
1544 {
1545  bool abort_on_null;
1546 public:
1547  Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
1548  longlong val_int();
1549  enum Functype functype() const { return ISNOTNULL_FUNC; }
1550  void fix_length_and_dec()
1551  {
1552  decimals=0; max_length=1; maybe_null=0;
1553  }
1554  const char *func_name() const { return "isnotnull"; }
1555  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1556  table_map not_null_tables() const
1557  { return abort_on_null ? not_null_tables_cache : 0; }
1558  Item *neg_transformer(THD *thd);
1559  virtual void print(String *str, enum_query_type query_type);
1560  const CHARSET_INFO *compare_collation()
1561  { return args[0]->collation.collation; }
1562  void top_level_item() { abort_on_null=1; }
1563 };
1564 
1565 
1567 {
1568  // Turbo Boyer-Moore data
1569  bool canDoTurboBM; // pattern is '%abcd%' case
1570  const char* pattern;
1571  int pattern_len;
1572 
1573  // TurboBM buffers, *this is owner
1574  int* bmGs; // good suffix shift table, size is pattern_len + 1
1575  int* bmBc; // bad character shift table, size is alphabet_size
1576 
1577  void turboBM_compute_suffixes(int* suff);
1578  void turboBM_compute_good_suffix_shifts(int* suff);
1579  void turboBM_compute_bad_character_shifts();
1580  bool turboBM_matches(const char* text, int text_len) const;
1581  enum { alphabet_size = 256 };
1582 
1583  Item *escape_item;
1584 
1585  bool escape_used_in_parsing;
1586 
1587 public:
1588  int escape;
1589 
1590  Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1591  :Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0),
1592  bmGs(0), bmBc(0), escape_item(escape_arg),
1593  escape_used_in_parsing(escape_used) {}
1594  longlong val_int();
1595  enum Functype functype() const { return LIKE_FUNC; }
1596  optimize_type select_optimize() const;
1597  cond_result eq_cmp_result() const { return COND_TRUE; }
1598  const char *func_name() const { return "like"; }
1599  bool fix_fields(THD *thd, Item **ref);
1600  void cleanup();
1605  bool escape_was_used_in_parsing() const { return escape_used_in_parsing; }
1606 };
1607 
1608 
1610 {
1611  my_regex_t preg;
1612  bool regex_compiled;
1613  bool regex_is_const;
1614  String prev_regexp;
1615  DTCollation cmp_collation;
1616  const CHARSET_INFO *regex_lib_charset;
1617  int regex_lib_flags;
1618  String conv;
1619  int regcomp(bool send_error);
1620 public:
1621  Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b),
1622  regex_compiled(0),regex_is_const(0) {}
1623  void cleanup();
1624  longlong val_int();
1625  bool fix_fields(THD *thd, Item **ref);
1626  const char *func_name() const { return "regexp"; }
1627 
1628  virtual inline void print(String *str, enum_query_type query_type)
1629  {
1630  print_op(str, query_type);
1631  }
1632 
1633  const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1634 };
1635 
1636 
1638 {
1639 protected:
1640  List<Item> list;
1641  bool abort_on_null;
1642 
1643 public:
1644  /* Item_cond() is only used to create top level items */
1645  Item_cond(): Item_bool_func(), abort_on_null(1)
1646  { const_item_cache=0; }
1647  Item_cond(Item *i1,Item *i2)
1648  :Item_bool_func(), abort_on_null(0)
1649  {
1650  list.push_back(i1);
1651  list.push_back(i2);
1652  }
1653  Item_cond(THD *thd, Item_cond *item);
1654  Item_cond(List<Item> &nlist)
1655  :Item_bool_func(), list(nlist), abort_on_null(0) {}
1656  bool add(Item *item)
1657  {
1658  DBUG_ASSERT(item);
1659  return list.push_back(item);
1660  }
1661  bool add_at_head(Item *item)
1662  {
1663  DBUG_ASSERT(item);
1664  return list.push_front(item);
1665  }
1666  void add_at_head(List<Item> *nlist)
1667  {
1668  DBUG_ASSERT(nlist->elements);
1669  list.prepand(nlist);
1670  }
1671  bool fix_fields(THD *, Item **ref);
1672  void fix_after_pullout(st_select_lex *parent_select,
1673  st_select_lex *removed_select);
1674 
1675  enum Type type() const { return COND_ITEM; }
1676  List<Item>* argument_list() { return &list; }
1677  table_map used_tables() const { return used_tables_cache; }
1678  void update_used_tables();
1679  virtual void print(String *str, enum_query_type query_type);
1680  void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
1681  List<Item> &fields);
1682  friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
1683  Item **conds);
1684  void top_level_item() { abort_on_null=1; }
1685  void copy_andor_arguments(THD *thd, Item_cond *item, bool real_items= false);
1686  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1687  Item *transform(Item_transformer transformer, uchar *arg);
1688  void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1689  void neg_arguments(THD *thd);
1690  enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
1691  bool subst_argument_checker(uchar **arg) { return TRUE; }
1692  Item *compile(Item_analyzer analyzer, uchar **arg_p,
1693  Item_transformer transformer, uchar *arg_t);
1694 
1695  virtual bool equality_substitution_analyzer(uchar **arg) { return true; }
1696 };
1697 
1698 
1699 /*
1700  The class Item_equal is used to represent conjunctions of equality
1701  predicates of the form field1 = field2, and field=const in where
1702  conditions and on expressions.
1703 
1704  All equality predicates of the form field1=field2 contained in a
1705  conjunction are substituted for a sequence of items of this class.
1706  An item of this class Item_equal(f1,f2,...fk) represents a
1707  multiple equality f1=f2=...=fk.
1708 
1709  If a conjunction contains predicates f1=f2 and f2=f3, a new item of
1710  this class is created Item_equal(f1,f2,f3) representing the multiple
1711  equality f1=f2=f3 that substitutes the above equality predicates in
1712  the conjunction.
1713  A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1714  substituted for the item representing the same multiple equality
1715  f1=f2=f3.
1716  An item Item_equal(f1,f2) can appear instead of a conjunction of
1717  f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1718 
1719  An item of the class Item_equal inherits equalities from outer
1720  conjunctive levels.
1721 
1722  Suppose we have a where condition of the following form:
1723  WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
1724  In this case:
1725  f1=f2 will be substituted for Item_equal(f1,f2);
1726  f3=f4 and f3=f5 will be substituted for Item_equal(f3,f4,f5);
1727  f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1728 
1729  An object of the class Item_equal can contain an optional constant
1730  item c. Then it represents a multiple equality of the form
1731  c=f1=...=fk.
1732 
1733  Objects of the class Item_equal are used for the following:
1734 
1735  1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
1736  pair of tables ti and tj as joined by an equi-condition.
1737  Thus it provide us with additional access paths from table to table.
1738 
1739  2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
1740  SARGable predicates:
1741  f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
1742  It also can give us additional index scans and can allow us to
1743  improve selectivity estimates.
1744 
1745  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
1746  selected execution plan for the query: if table ti is accessed
1747  before the table tj then in any predicate P in the where condition
1748  the occurrence of tj.fj is substituted for ti.fi. This can allow
1749  an evaluation of the predicate at an earlier step.
1750 
1751  When feature 1 is supported they say that join transitive closure
1752  is employed.
1753  When feature 2 is supported they say that search argument transitive
1754  closure is employed.
1755  Both features are usually supported by preprocessing original query and
1756  adding additional predicates.
1757  We do not just add predicates, we rather dynamically replace some
1758  predicates that can not be used to access tables in the investigated
1759  plan for those, obtained by substitution of some fields for equal fields,
1760  that can be used.
1761 
1762  Prepared Statements/Stored Procedures note: instances of class
1763  Item_equal are created only at the time a PS/SP is executed and
1764  are deleted in the end of execution. All changes made to these
1765  objects need not be registered in the list of changes of the parse
1766  tree and do not harm PS/SP re-execution.
1767 
1768  Item equal objects are employed only at the optimize phase. Usually they are
1769  not supposed to be evaluated. Yet in some cases we call the method val_int()
1770  for them. We have to take care of restricting the predicate such an
1771  object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
1772 */
1773 struct st_join_table;
1774 
1776 {
1777  List<Item_field> fields; /* list of equal field items */
1778  Item *const_item; /* optional constant item equal to fields items */
1779  cmp_item *eval_item;
1780  Arg_comparator cmp;
1781  bool cond_false;
1782  bool compare_as_dates;
1783 public:
1784  inline Item_equal()
1785  : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
1786  { const_item_cache=0 ;}
1787  Item_equal(Item_field *f1, Item_field *f2);
1788  Item_equal(Item *c, Item_field *f);
1789  Item_equal(Item_equal *item_equal);
1790  virtual ~Item_equal()
1791  {
1792  delete eval_item;
1793  }
1794 
1795  inline Item* get_const() { return const_item; }
1796  void compare_const(Item *c);
1797  void add(Item *c, Item_field *f);
1798  void add(Item *c);
1799  void add(Item_field *f);
1800  uint members();
1801  bool contains(Field *field);
1807  Item_field* get_first() { return fields.head(); }
1808  Item_field* get_subst_item(const Item_field *field);
1809  void merge(Item_equal *item);
1810  void update_const();
1811  enum Functype functype() const { return MULT_EQUAL_FUNC; }
1812  longlong val_int();
1813  const char *func_name() const { return "multiple equal"; }
1814  optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1815  void sort(Item_field_cmpfunc compare, void *arg);
1816  friend class Item_equal_iterator;
1817  void fix_length_and_dec();
1818  bool fix_fields(THD *thd, Item **ref);
1819  void update_used_tables();
1820  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1821  Item *transform(Item_transformer transformer, uchar *arg);
1822  virtual void print(String *str, enum_query_type query_type);
1823  const CHARSET_INFO *compare_collation()
1824  { return fields.head()->collation.collation; }
1825 
1826  virtual bool equality_substitution_analyzer(uchar **arg) { return true; }
1827 
1828  virtual Item* equality_substitution_transformer(uchar *arg);
1829 };
1830 
1831 class COND_EQUAL: public Sql_alloc
1832 {
1833 public:
1834  uint max_members; /* max number of members the current level
1835  list and all lower level lists */
1836  COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
1837  List<Item_equal> current_level; /* list of multiple equalities of
1838  the current and level */
1839  COND_EQUAL()
1840  {
1841  upper_levels= 0;
1842  }
1843 };
1844 
1845 
1846 class Item_equal_iterator : public List_iterator_fast<Item_field>
1847 {
1848 public:
1849  inline Item_equal_iterator(Item_equal &item_equal)
1850  :List_iterator_fast<Item_field> (item_equal.fields)
1851  {}
1852  inline Item_field* operator++(int)
1853  {
1854  Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1855  return item;
1856  }
1857  inline void rewind(void)
1858  {
1860  }
1861 };
1862 
1864 {
1865 public:
1866  COND_EQUAL cond_equal; /* contains list of Item_equal objects for
1867  the current and level and reference
1868  to multiple equalities of upper and levels */
1869  Item_cond_and() :Item_cond() {}
1870  Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1871  Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
1872  Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1873  enum Functype functype() const { return COND_AND_FUNC; }
1874  longlong val_int();
1875  const char *func_name() const { return "and"; }
1876  Item* copy_andor_structure(THD *thd, bool real_items)
1877  {
1878  Item_cond_and *item;
1879  if ((item= new Item_cond_and(thd, this)))
1880  item->copy_andor_arguments(thd, this, real_items);
1881  return item;
1882  }
1883  Item *neg_transformer(THD *thd);
1884 };
1885 
1886 inline bool is_cond_and(Item *item)
1887 {
1888  if (item->type() != Item::COND_ITEM)
1889  return FALSE;
1890 
1891  Item_cond *cond_item= (Item_cond*) item;
1892  return (cond_item->functype() == Item_func::COND_AND_FUNC);
1893 }
1894 
1896 {
1897 public:
1898  Item_cond_or() :Item_cond() {}
1899  Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1900  Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
1901  Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1902  enum Functype functype() const { return COND_OR_FUNC; }
1903  longlong val_int();
1904  const char *func_name() const { return "or"; }
1905  Item* copy_andor_structure(THD *thd, bool real_items)
1906  {
1907  Item_cond_or *item;
1908  if ((item= new Item_cond_or(thd, this)))
1909  item->copy_andor_arguments(thd, this, real_items);
1910  return item;
1911  }
1912  Item *neg_transformer(THD *thd);
1913 };
1914 
1915 inline bool is_cond_or(Item *item)
1916 {
1917  if (item->type() != Item::COND_ITEM)
1918  return FALSE;
1919 
1920  Item_cond *cond_item= (Item_cond*) item;
1921  return (cond_item->functype() == Item_func::COND_OR_FUNC);
1922 }
1923 
1924 /* Some useful inline functions */
1925 
1926 inline Item *and_conds(Item *a, Item *b)
1927 {
1928  if (!b) return a;
1929  if (!a) return b;
1930  return new Item_cond_and(a, b);
1931 }
1932 
1933 
1934 Item *and_expressions(Item *a, Item *b, Item **org_item);
1935 
1936 longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
1937  Item *warn_item, bool *is_null);
1938 
1939 
1940 bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
1941  const char *warn_name, MYSQL_TIME *l_time);
1942 
1943 /*
1944  These need definitions from this file but the variables are defined
1945  in mysqld.h. The variables really belong in this component, but for
1946  the time being we leave them in mysqld.cc to avoid merge problems.
1947 */
1948 extern Eq_creator eq_creator;
1949 extern Ne_creator ne_creator;
1950 extern Gt_creator gt_creator;
1951 extern Lt_creator lt_creator;
1952 extern Ge_creator ge_creator;
1953 extern Le_creator le_creator;
1954 
1955 #endif /* ITEM_CMPFUNC_INCLUDED */