Drizzled Public API Documentation

cmpfunc.h
1 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2008 Sun Microsystems, Inc.
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 #pragma once
21 
22 /* compare and test functions */
23 
24 #include <drizzled/common.h>
25 #include <drizzled/comp_creator.h>
26 #include <drizzled/function/math/int.h>
27 #include <drizzled/function/numhybrid.h>
28 #include <drizzled/item/decimal.h>
29 #include <drizzled/item/float.h>
30 #include <drizzled/item/function/boolean.h>
31 #include <drizzled/item/int.h>
32 #include <drizzled/item/row.h>
33 #include <drizzled/item/string.h>
34 #include <drizzled/item/sum.h>
35 #include <drizzled/qsort_cmp.h>
36 
37 namespace drizzled {
38 
39 extern Item_result item_cmp_type(Item_result a,Item_result b);
40 
41 typedef int (Arg_comparator::*arg_cmp_func)();
42 
43 typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
44 
45 int64_t get_datetime_value(Session *session,
46  Item ***item_arg,
47  Item **cache_arg,
48  Item *warn_item,
49  bool *is_null);
50 
52 {
53  Item **a, **b;
54  arg_cmp_func func;
55  Item_bool_func2 *owner;
56  Arg_comparator *comparators; // used only for compare_row()
57  double precision;
58  /* Fields used in DATE/DATETIME comparison. */
59  Session *session;
60  enum_field_types a_type, b_type; // Types of a and b items
61  Item *a_cache, *b_cache; // Cached values of a and b items
62  bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
63  enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
64  CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
65  int64_t (*get_value_func)(Session *session, Item ***item_arg, Item **cache_arg,
66  Item *warn_item, bool *is_null);
67 public:
68  DTCollation cmp_collation;
69 
71 
72  Arg_comparator(Item **a1, Item **a2);
73 
74  int set_compare_func(Item_bool_func2 *owner, Item_result type);
75  inline int set_compare_func(Item_bool_func2 *owner_arg)
76  {
77  return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
78  (*b)->result_type()));
79  }
80  int set_cmp_func(Item_bool_func2 *owner_arg,
81  Item **a1, Item **a2,
82  Item_result type);
83 
84  inline int set_cmp_func(Item_bool_func2 *owner_arg,
85  Item **a1, Item **a2)
86  {
87  return set_cmp_func(owner_arg, a1, a2,
88  item_cmp_type((*a1)->result_type(),
89  (*a2)->result_type()));
90  }
91  inline int compare() { return (this->*func)(); }
92 
93  int compare_string(); // compare args[0] & args[1]
94  int compare_binary_string(); // compare args[0] & args[1]
95  int compare_real(); // compare args[0] & args[1]
96  int compare_decimal(); // compare args[0] & args[1]
97  int compare_int_signed(); // compare args[0] & args[1]
100  int compare_int_unsigned();
101  int compare_row(); // compare args[0] & args[1]
102  int compare_e_string(); // compare args[0] & args[1]
103  int compare_e_binary_string(); // compare args[0] & args[1]
104  int compare_e_real(); // compare args[0] & args[1]
105  int compare_e_decimal(); // compare args[0] & args[1]
106  int compare_e_int(); // compare args[0] & args[1]
108  int compare_e_row(); // compare args[0] & args[1]
109  int compare_real_fixed();
110  int compare_e_real_fixed();
111  int compare_datetime(); // compare args[0] & args[1] as DATETIMEs
112 
113  static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b,
114  int64_t *const_val_arg);
115 
116  void set_datetime_cmp_func(Item **a1, Item **b1);
117  static arg_cmp_func comparator_matrix [5][2];
118 
119  friend class Item_func;
120 };
121 
122 
129 {
130 public:
131  virtual bool val_bool();
132  virtual int64_t val_int();
133  virtual void fix_length_and_dec();
134  virtual void print(String *str);
135 
136 protected:
137  Item_func_truth(Item *a, bool a_value, bool a_affirmative)
138  : item::function::Boolean(a), value(a_value), affirmative(a_affirmative)
139  {}
140 
141 private:
146  const bool value;
150  const bool affirmative;
151 };
152 
153 
159 {
160 public:
161  Item_func_istrue(Item *a) : Item_func_truth(a, true, true) {}
162  virtual const char* func_name() const { return "istrue"; }
163 };
164 
165 
171 {
172 public:
173  Item_func_isnottrue(Item *a) : Item_func_truth(a, true, false) {}
174  virtual const char* func_name() const { return "isnottrue"; }
175 };
176 
177 
183 {
184 public:
185  Item_func_isfalse(Item *a) : Item_func_truth(a, false, true) {}
186  virtual const char* func_name() const { return "isfalse"; }
187 };
188 
189 
195 {
196 public:
197  Item_func_isnotfalse(Item *a) : Item_func_truth(a, false, false) {}
198  virtual const char* func_name() const { return "isnotfalse"; }
199 };
200 
201 
202 #define UNKNOWN ((bool)-1)
203 
204 
205 /*
206  Item_in_optimizer(left_expr, Item_in_subselect(...))
207 
208  Item_in_optimizer is used to wrap an instance of Item_in_subselect. This
209  class does the following:
210  - Evaluate the left expression and store it in Item_cache_* object (to
211  avoid re-evaluating it many times during subquery execution)
212  - Shortcut the evaluation of "NULL IN (...)" to NULL in the cases where we
213  don't care if the result is NULL or FALSE.
214 
215  NOTE
216  It is not quite clear why the above listed functionality should be
217  placed into a separate class called 'Item_in_optimizer'.
218 */
219 
221 {
222 protected:
223  Item_cache *cache;
224  bool save_cache;
225  /*
226  Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
227  UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
228  FALSE - result is FALSE
229  TRUE - result is NULL
230  */
231  bool result_for_null_param;
232 public:
234  item::function::Boolean(a, reinterpret_cast<Item *>(b)), cache(0),
235  save_cache(0), result_for_null_param(UNKNOWN)
236  { with_subselect= true; }
237  bool fix_fields(Session *, Item **);
238  bool fix_left(Session *session, Item **ref);
239  bool is_null();
240  int64_t val_int();
241  void cleanup();
242  const char *func_name() const { return "<in_optimizer>"; }
243  Item_cache **get_cache() { return &cache; }
244  void keep_top_level_cache();
245  Item *transform(Item_transformer transformer, unsigned char *arg);
246 };
247 
249 {
250 public:
251  virtual Item_bool_func2* create(Item *a, Item *b) const;
252  virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
253  virtual bool eqne_op() const { return 1; }
254  virtual bool l_op() const { return 0; }
255  static const Eq_creator *instance();
256 };
257 
259 {
260 public:
261  virtual Item_bool_func2* create(Item *a, Item *b) const;
262  virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
263  virtual bool eqne_op() const { return 1; }
264  virtual bool l_op() const { return 0; }
265  static const Ne_creator *instance();
266 };
267 
269 {
270 public:
271  virtual Item_bool_func2* create(Item *a, Item *b) const;
272  virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
273  virtual bool eqne_op() const { return 0; }
274  virtual bool l_op() const { return 0; }
275  static const Gt_creator *instance();
276 };
277 
279 {
280 public:
281  virtual Item_bool_func2* create(Item *a, Item *b) const;
282  virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
283  virtual bool eqne_op() const { return 0; }
284  virtual bool l_op() const { return 1; }
285  static const Lt_creator *instance();
286 };
287 
289 {
290 public:
291  virtual Item_bool_func2* create(Item *a, Item *b) const;
292  virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
293  virtual bool eqne_op() const { return 0; }
294  virtual bool l_op() const { return 0; }
295  static const Ge_creator *instance();
296 };
297 
299 {
300 public:
301  virtual Item_bool_func2* create(Item *a, Item *b) const;
302  virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
303  virtual bool eqne_op() const { return 0; }
304  virtual bool l_op() const { return 1; }
305  static const Le_creator *instance();
306 };
307 
309 { /* Bool with 2 string args */
310 protected:
311  Arg_comparator cmp;
312  String tmp_value1,tmp_value2;
313  bool abort_on_null;
314 
315 public:
316  Item_bool_func2(Item *a,Item *b)
317  :Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(false) {}
318  void fix_length_and_dec();
319  void set_cmp_func()
320  {
321  cmp.set_cmp_func(this, tmp_arg, tmp_arg+1);
322  }
323  optimize_type select_optimize() const { return OPTIMIZE_OP; }
324  virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
325  bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
326 
327  virtual inline void print(String *str)
328  {
329  Item_func::print_op(str);
330  }
331 
332  bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
333  bool is_bool_func() { return 1; }
334  const charset_info_st *compare_collation() { return cmp.cmp_collation.collation; }
335  uint32_t decimal_precision() const { return 1; }
336  void top_level_item() { abort_on_null= true; }
337 
338  friend class Arg_comparator;
339 };
340 
342 {
343 public:
345  {
346  allowed_arg_cols= 0; // Fetch this value from first argument
347  }
348  Item *neg_transformer(Session *session);
349  virtual Item *negated_item();
350  bool subst_argument_checker(unsigned char **)
351  { return true; }
352 };
353 
355 {
356 public:
358  int64_t val_int();
359  enum Functype functype() const { return NOT_FUNC; }
360  const char *func_name() const { return "not"; }
361  Item *neg_transformer(Session *session);
362  virtual void print(String *str);
363 };
364 
365 /*
366  trigcond<param>(arg) ::= param? arg : TRUE
367 
368  The class Item_func_trig_cond is used for guarded predicates
369  which are employed only for internal purposes.
370  A guarded predicate is an object consisting of an a regular or
371  a guarded predicate P and a pointer to a boolean guard variable g.
372  A guarded predicate P/g is evaluated to true if the value of the
373  guard g is false, otherwise it is evaluated to the same value that
374  the predicate P: val(P/g)= g ? val(P):true.
375  Guarded predicates allow us to include predicates into a conjunction
376  conditionally. Currently they are utilized for pushed down predicates
377  in queries with outer join operations.
378 
379  In the future, probably, it makes sense to extend this class to
380  the objects consisting of three elements: a predicate P, a pointer
381  to a variable g and a firing value s with following evaluation
382  rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
383  one item for the objects of the form P/g1/g2...
384 
385  Objects of this class are built only for query execution after
386  the execution plan has been already selected. That's why this
387  class needs only val_int out of generic methods.
388 
389  Current uses of Item_func_trig_cond objects:
390  - To wrap selection conditions when executing outer joins
391  - To wrap condition that is pushed down into subquery
392 */
393 
395 {
396  bool *trig_var;
397 public:
398  Item_func_trig_cond(Item *a, bool *f) : item::function::Boolean(a) { trig_var= f; }
399  int64_t val_int() { return *trig_var ? args[0]->val_int() : 1; }
400  enum Functype functype() const { return TRIG_COND_FUNC; };
401  const char *func_name() const { return "trigcond"; };
402  bool const_item() const { return false; }
403  bool *get_trig_var() { return trig_var; }
404  /* The following is needed for ICP: */
405  table_map used_tables() const { return args[0]->used_tables(); }
406 };
407 
409 {
410  /* allow to check presence of values in max/min optimization */
411  Item_sum_hybrid *test_sum_item;
412  Item_maxmin_subselect *test_sub_item;
413 
414  bool abort_on_null;
415 public:
416  bool show;
417 
419  :Item_func_not(a), test_sum_item(0), test_sub_item(0), abort_on_null(0),
420  show(0)
421  {}
422  virtual void top_level_item() { abort_on_null= 1; }
423  bool top_level() { return abort_on_null; }
424  int64_t val_int();
425  enum Functype functype() const { return NOT_ALL_FUNC; }
426  const char *func_name() const { return "<not>"; }
427  virtual void print(String *str);
428  void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
429  void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
430  bool empty_underlying_subquery();
431  Item *neg_transformer(Session *session);
432 };
433 
434 
436 {
437 public:
438 
440  int64_t val_int();
441  const char *func_name() const { return "<nop>"; }
442  Item *neg_transformer(Session *session);
443 };
444 
445 
447 {
448 public:
450  int64_t val_int();
451  enum Functype functype() const { return EQ_FUNC; }
452  enum Functype rev_functype() const { return EQ_FUNC; }
453  cond_result eq_cmp_result() const { return COND_TRUE; }
454  const char *func_name() const { return "="; }
455  Item *negated_item();
456 };
457 
459 {
460 public:
462  int64_t val_int();
463  void fix_length_and_dec();
464  table_map not_null_tables() const { return 0; }
465  enum Functype functype() const { return EQUAL_FUNC; }
466  enum Functype rev_functype() const { return EQUAL_FUNC; }
467  cond_result eq_cmp_result() const { return COND_TRUE; }
468  const char *func_name() const { return "<=>"; }
469  Item *neg_transformer(Session *) { return 0; }
470 };
471 
472 
474 {
475 public:
477  int64_t val_int();
478  enum Functype functype() const { return GE_FUNC; }
479  enum Functype rev_functype() const { return LE_FUNC; }
480  cond_result eq_cmp_result() const { return COND_TRUE; }
481  const char *func_name() const { return ">="; }
482  Item *negated_item();
483 };
484 
485 
487 {
488 public:
490  int64_t val_int();
491  enum Functype functype() const { return GT_FUNC; }
492  enum Functype rev_functype() const { return LT_FUNC; }
493  cond_result eq_cmp_result() const { return COND_FALSE; }
494  const char *func_name() const { return ">"; }
495  Item *negated_item();
496 };
497 
498 
500 {
501 public:
503  int64_t val_int();
504  enum Functype functype() const { return LE_FUNC; }
505  enum Functype rev_functype() const { return GE_FUNC; }
506  cond_result eq_cmp_result() const { return COND_TRUE; }
507  const char *func_name() const { return "<="; }
508  Item *negated_item();
509 };
510 
511 
513 {
514 public:
516  int64_t val_int();
517  enum Functype functype() const { return LT_FUNC; }
518  enum Functype rev_functype() const { return GT_FUNC; }
519  cond_result eq_cmp_result() const { return COND_FALSE; }
520  const char *func_name() const { return "<"; }
521  Item *negated_item();
522 };
523 
524 
526 {
527 public:
529  int64_t val_int();
530  enum Functype functype() const { return NE_FUNC; }
531  cond_result eq_cmp_result() const { return COND_FALSE; }
532  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
533  const char *func_name() const { return "<>"; }
534  Item *negated_item();
535 };
536 
537 
538 /*
539  The class Item_func_opt_neg is defined to factor out the functionality
540  common for the classes Item_func_between and Item_func_in. The objects
541  of these classes can express predicates or there negations.
542  The alternative approach would be to create pairs Item_func_between,
543  Item_func_notbetween and Item_func_in, Item_func_notin.
544 
545 */
546 
548 {
549 public:
550  bool negated; /* <=> the item represents NOT <func> */
551  bool pred_level; /* <=> [NOT] <func> is used on a predicate level */
552 public:
553  Item_func_opt_neg(Item *a, Item *b, Item *c)
554  :Item_int_func(a, b, c), negated(0), pred_level(0) {}
556  :Item_int_func(list), negated(0), pred_level(0) {}
557 public:
558  inline void negate() { negated= !negated; }
559  inline void top_level_item() { pred_level= 1; }
560  Item *neg_transformer(Session *)
561  {
562  negated= !negated;
563  return this;
564  }
565  bool eq(const Item *item, bool binary_cmp) const;
566  bool subst_argument_checker(unsigned char **)
567  { return true; }
568 };
569 
570 
572 {
573  DTCollation cmp_collation;
574 public:
575  Item_result cmp_type;
576  String value0,value1,value2;
577  /* TRUE <=> arguments will be compared as dates. */
578  bool compare_as_dates;
579  /* Comparators used for DATE/DATETIME comparison. */
580  Arg_comparator ge_cmp, le_cmp;
581  Item_func_between(Item *a, Item *b, Item *c)
582  :Item_func_opt_neg(a, b, c), compare_as_dates(false) {}
583  int64_t val_int();
584  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
585  enum Functype functype() const { return BETWEEN; }
586  const char *func_name() const { return "between"; }
587  bool fix_fields(Session *, Item **);
588  void fix_length_and_dec();
589  virtual void print(String *str);
590  bool is_bool_func() { return 1; }
591  const charset_info_st *compare_collation() { return cmp_collation.collation; }
592  uint32_t decimal_precision() const { return 1; }
593 };
594 
595 
597 {
598 public:
599  Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
600  int64_t val_int();
601  optimize_type select_optimize() const { return OPTIMIZE_NONE; }
602  const char *func_name() const { return "strcmp"; }
603 
604  virtual inline void print(String *str)
605  {
606  Item_func::print(str);
607  }
608 };
609 
610 
612 {
613  Item_result type;
614  double dbl;
615  type::Decimal dec;
616 };
617 
619 {
620  Item_row *row;
621  bool use_decimal_comparison;
622  interval_range *intervals;
623 public:
625  :Item_int_func(a),row(a),intervals(0)
626  {
627  allowed_arg_cols= 0; // Fetch this value from first argument
628  }
629  int64_t val_int();
630  void fix_length_and_dec();
631  const char *func_name() const { return "interval"; }
632  uint32_t decimal_precision() const { return 2; }
633 };
634 
635 
637 {
638 protected:
639  enum_field_types cached_field_type;
641 public:
643  double real_op();
644  int64_t int_op();
645  String *str_op(String *);
647  void fix_length_and_dec();
648  void find_num_type() {}
649  enum Item_result result_type () const { return hybrid_type; }
650  const char *func_name() const { return "coalesce"; }
651  table_map not_null_tables() const { return 0; }
652  enum_field_types field_type() const { return cached_field_type; }
653 };
654 
655 
657 {
658 protected:
659  bool field_type_defined;
660 public:
662  double real_op();
663  int64_t int_op();
664  String *str_op(String *str);
666  enum_field_types field_type() const;
667  void fix_length_and_dec();
668  const char *func_name() const { return "ifnull"; }
669  Field *tmp_table_field()
670  {
671  return Item_func::tmp_table_field();
672  }
673  Field *tmp_table_field(Table *table);
674  uint32_t decimal_precision() const;
675 };
676 
677 
678 class Item_func_if :public Item_func
679 {
680  Item_result cached_result_type;
681  enum_field_types cached_field_type;
682 
683 public:
684  Item_func_if(Item *a, Item *b, Item *c) :
685  Item_func(a,b,c),
686  cached_result_type(INT_RESULT)
687  {}
688 
689  double val_real();
690  int64_t val_int();
691  String *val_str(String *str);
693  Item_result result_type () const { return cached_result_type; }
694  enum_field_types field_type() const { return cached_field_type; }
695  bool fix_fields(Session *, Item **);
696  void fix_length_and_dec();
697  uint32_t decimal_precision() const;
698  const char *func_name() const { return "if"; }
699 };
700 
701 
703 {
704  enum Item_result cached_result_type;
705 public:
706  Item_func_nullif(Item *a,Item *b)
707  :Item_bool_func2(a,b), cached_result_type(INT_RESULT)
708  {}
709  double val_real();
710  int64_t val_int();
711  String *val_str(String *str);
713  enum Item_result result_type () const { return cached_result_type; }
714  void fix_length_and_dec();
715  uint32_t decimal_precision() const { return args[0]->decimal_precision(); }
716  const char *func_name() const { return "nullif"; }
717 
718  virtual inline void print(String *str)
719  {
720  Item_func::print(str);
721  }
722 
723  table_map not_null_tables() const { return 0; }
724  bool is_null();
725 };
726 
727 
728 /* Functions to handle the optimized IN */
729 
730 
731 /* A vector of values of some type */
732 
734 {
735 public:
736  char *base;
737  uint32_t size;
738  qsort2_cmp compare;
739  const charset_info_st *collation;
740  uint32_t count;
741  uint32_t used_count;
742  in_vector() {}
743  in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func,
744  const charset_info_st * const cmp_coll)
745  :base((char*) memory::sql_calloc(elements*element_length)),
746  size(element_length), compare(cmp_func), collation(cmp_coll),
747  count(elements), used_count(elements) {}
748  virtual ~in_vector() {}
749  virtual void set(uint32_t pos,Item *item)=0;
750  virtual unsigned char *get_value(Item *item)=0;
751  void sort();
752  int find(Item *item);
753 
754  /*
755  Create an instance of Item_{type} (e.g. Item_decimal) constant object
756  which type allows it to hold an element of this vector without any
757  conversions.
758  The purpose of this function is to be able to get elements of this
759  vector in form of Item_xxx constants without creating Item_xxx object
760  for every array element you get (i.e. this implements "FlyWeight" pattern)
761  */
762  virtual Item* create_item() { return NULL; }
763 
764  /*
765  Store the value at position #pos into provided item object
766  SYNOPSIS
767  value_to_item()
768  pos Index of value to store
769  item Constant item to store value into. The item must be of the same
770  type that create_item() returns.
771  */
772  virtual void value_to_item(uint32_t, Item *) { }
773 
774  /* Compare values number pos1 and pos2 for equality */
775  bool compare_elems(uint32_t pos1, uint32_t pos2)
776  {
777  return test(compare(collation, base + pos1*size, base + pos2*size));
778  }
779  virtual Item_result result_type()= 0;
780 };
781 
782 class in_string :public in_vector
783 {
784  char buff[STRING_BUFFER_USUAL_SIZE];
785  String tmp;
786 public:
787  in_string(uint32_t elements,qsort2_cmp cmp_func, const charset_info_st * const cs);
788  ~in_string();
789  void set(uint32_t pos,Item *item);
790  unsigned char *get_value(Item *item);
791  Item* create_item()
792  {
793  return new Item_string(collation);
794  }
795  void value_to_item(uint32_t pos, Item *item)
796  {
797  String *str=((String*) base)+pos;
798  Item_string *to= (Item_string*)item;
799  to->str_value= *str;
800  }
801  Item_result result_type() { return STRING_RESULT; }
802 };
803 
804 class in_int64_t :public in_vector
805 {
806 protected:
807  /*
808  Here we declare a temporary variable (tmp) of the same type as the
809  elements of this vector. tmp is used in finding if a given value is in
810  the list.
811  */
813  {
814  int64_t val;
815  int64_t unsigned_flag; // Use int64_t, not bool, to preserve alignment
816  } tmp;
817 public:
818  in_int64_t(uint32_t elements);
819  void set(uint32_t pos,Item *item);
820  unsigned char *get_value(Item *item);
821 
822  Item* create_item()
823  {
824  /*
825  We're created a signed INT, this may not be correct in
826  general case (see BUG#19342).
827  */
828  return new Item_int((int64_t)0);
829  }
830  void value_to_item(uint32_t pos, Item *item)
831  {
832  ((Item_int*) item)->value= ((packed_int64_t*) base)[pos].val;
833  ((Item_int*) item)->unsigned_flag= (bool)
834  ((packed_int64_t*) base)[pos].unsigned_flag;
835  }
836  Item_result result_type() { return INT_RESULT; }
837 
838  friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
839 };
840 
841 
842 /*
843  Class to represent a vector of constant DATE/DATETIME values.
844  Values are obtained with help of the get_datetime_value() function.
845  If the left item is a constant one then its value is cached in the
846  lval_cache variable.
847 */
848 class in_datetime :public in_int64_t
849 {
850 public:
851  Session *session;
852  /* An item used to issue warnings. */
853  Item *warn_item;
854  /* Cache for the left item. */
855  Item *lval_cache;
856 
857  in_datetime(Item *warn_item_arg, uint32_t elements);
858 
859  void set(uint32_t pos,Item *item);
860  unsigned char *get_value(Item *item);
861  friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
862 };
863 
864 
865 class in_double :public in_vector
866 {
867  double tmp;
868 public:
869  in_double(uint32_t elements);
870  void set(uint32_t pos,Item *item);
871  unsigned char *get_value(Item *item);
872  Item *create_item()
873  {
874  return new Item_float(0.0, 0);
875  }
876  void value_to_item(uint32_t pos, Item *item)
877  {
878  ((Item_float*)item)->value= ((double*) base)[pos];
879  }
880  Item_result result_type() { return REAL_RESULT; }
881 };
882 
883 
884 class in_decimal :public in_vector
885 {
886  type::Decimal val;
887 public:
888  in_decimal(uint32_t elements);
889  void set(uint32_t pos, Item *item);
890  unsigned char *get_value(Item *item);
891  Item *create_item()
892  {
893  return new Item_decimal(0, false);
894  }
895  void value_to_item(uint32_t pos, Item *item)
896  {
897  type::Decimal *dec= ((type::Decimal *)base) + pos;
898  Item_decimal *item_dec= (Item_decimal*)item;
899  item_dec->set_decimal_value(dec);
900  }
901  Item_result result_type() { return DECIMAL_RESULT; }
902 
903 };
904 
905 
906 /*
907 ** Classes for easy comparing of non const items
908 */
909 
911 {
912 public:
913  const charset_info_st *cmp_charset;
914 
915  cmp_item()
916  {
917  cmp_charset= &my_charset_bin;
918  }
919 
920  virtual ~cmp_item() {}
921  virtual void store_value(Item *item)= 0;
922  virtual int cmp(Item *item)= 0;
923  // for optimized IN with row
924  virtual int compare(cmp_item *item)= 0;
925  static cmp_item* get_comparator(Item_result type, const charset_info_st * const cs);
926  virtual cmp_item *make_same()= 0;
927  virtual void store_value_by_template(cmp_item *, Item *item)
928  {
929  store_value(item);
930  }
931 };
932 
934 {
935 protected:
936  String *value_res;
937 public:
938  cmp_item_string () {}
939  cmp_item_string (const charset_info_st * const cs) { cmp_charset= cs; }
940  void set_charset(const charset_info_st * const cs) { cmp_charset= cs; }
941  friend class cmp_item_sort_string;
942  friend class cmp_item_sort_string_in_static;
943 };
944 
946 {
947 protected:
948  char value_buff[STRING_BUFFER_USUAL_SIZE];
949  String value;
950 public:
952  cmp_item_string() {}
953  cmp_item_sort_string(const charset_info_st * const cs):
954  cmp_item_string(cs),
955  value(value_buff, sizeof(value_buff), cs) {}
956  void store_value(Item *item)
957  {
958  value_res= item->val_str(&value);
959  }
960  int cmp(Item *arg)
961  {
962  char buff[STRING_BUFFER_USUAL_SIZE];
963  String tmp(buff, sizeof(buff), cmp_charset), *res;
964  res= arg->val_str(&tmp);
965  return (value_res ? (res ? sortcmp(value_res, res, cmp_charset) : 1) :
966  (res ? -1 : 0));
967  }
968  int compare(cmp_item *ci)
969  {
970  cmp_item_string *l_cmp= (cmp_item_string *) ci;
971  return sortcmp(value_res, l_cmp->value_res, cmp_charset);
972  }
973  cmp_item *make_same();
974  void set_charset(const charset_info_st * const cs)
975  {
976  cmp_charset= cs;
977  value.set_quick(value_buff, sizeof(value_buff), cs);
978  }
979 };
980 
981 class cmp_item_int :public cmp_item
982 {
983  int64_t value;
984 public:
985  void store_value(Item *item)
986  {
987  value= item->val_int();
988  }
989  int cmp(Item *arg)
990  {
991  return value != arg->val_int();
992  }
993  int compare(cmp_item *ci)
994  {
995  cmp_item_int *l_cmp= (cmp_item_int *)ci;
996  return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
997  }
998  cmp_item *make_same();
999 };
1000 
1001 /*
1002  Compare items in the DATETIME context.
1003  Values are obtained with help of the get_datetime_value() function.
1004  If the left item is a constant one then its value is cached in the
1005  lval_cache variable.
1006 */
1008 {
1009  int64_t value;
1010 
1011 public:
1012  Session *session;
1013  /* Item used for issuing warnings. */
1014  Item *warn_item;
1015  /* Cache for the left item. */
1016  Item *lval_cache;
1017 
1018  cmp_item_datetime(Item *warn_item_arg);
1019 
1020  void store_value(Item *item);
1021  int cmp(Item *arg);
1022  int compare(cmp_item *ci);
1023  cmp_item *make_same();
1024 };
1025 
1027 {
1028  double value;
1029 public:
1030  void store_value(Item *item)
1031  {
1032  value= item->val_real();
1033  }
1034  int cmp(Item *arg)
1035  {
1036  return value != arg->val_real();
1037  }
1038  int compare(cmp_item *ci)
1039  {
1040  cmp_item_real *l_cmp= (cmp_item_real *) ci;
1041  return (value < l_cmp->value)? -1 : ((value == l_cmp->value) ? 0 : 1);
1042  }
1043  cmp_item *make_same();
1044 };
1045 
1046 
1048 {
1049  type::Decimal value;
1050 public:
1051  void store_value(Item *item);
1052  int cmp(Item *arg);
1053  int compare(cmp_item *c);
1054  cmp_item *make_same();
1055 };
1056 
1057 
1058 /*
1059  cmp_item for optimized IN with row (right part string, which never
1060  be changed)
1061 */
1062 
1064 {
1065  protected:
1066  String value;
1067 public:
1069  cmp_item_string(cs) {}
1070  void store_value(Item *item)
1071  {
1072  value_res= item->val_str(&value);
1073  }
1074  int cmp(Item *)
1075  {
1076  // Should never be called
1077  assert(0);
1078  return 1;
1079  }
1080  int compare(cmp_item *ci)
1081  {
1082  cmp_item_string *l_cmp= (cmp_item_string *) ci;
1083  return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1084  }
1085  cmp_item *make_same()
1086  {
1087  return new cmp_item_sort_string_in_static(cmp_charset);
1088  }
1089 };
1090 
1091 
1092 /*
1093  The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1094  implementation.
1095 
1096  When there is no expression between CASE and the first WHEN
1097  (the CASE expression) then this function simple checks all WHEN expressions
1098  one after another. When some WHEN expression evaluated to TRUE then the
1099  value of the corresponding THEN expression is returned.
1100 
1101  When the CASE expression is specified then it is compared to each WHEN
1102  expression individually. When an equal WHEN expression is found
1103  corresponding THEN expression is returned.
1104  In order to do correct comparisons several comparators are used. One for
1105  each result type. Different result types that are used in particular
1106  CASE ... END expression are collected in the fix_length_and_dec() member
1107  function and only comparators for there result types are used.
1108 */
1109 
1111 {
1112  int first_expr_num, else_expr_num;
1113  enum Item_result cached_result_type, left_result_type;
1114  String tmp_value;
1115  uint32_t ncases;
1116  Item_result cmp_type;
1117  DTCollation cmp_collation;
1118  enum_field_types cached_field_type;
1119  cmp_item *cmp_items[DECIMAL_RESULT+1]; /* For all result types */
1120  cmp_item *case_item;
1121 public:
1122  Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
1123  :Item_func(), first_expr_num(-1), else_expr_num(-1),
1124  cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
1125  {
1126  ncases= list.size();
1127  if (first_expr_arg)
1128  {
1129  first_expr_num= list.size();
1130  list.push_back(first_expr_arg);
1131  }
1132  if (else_expr_arg)
1133  {
1134  else_expr_num= list.size();
1135  list.push_back(else_expr_arg);
1136  }
1137  set_arguments(list);
1138  memset(&cmp_items, 0, sizeof(cmp_items));
1139  }
1140  double val_real();
1141  int64_t val_int();
1142  String *val_str(String *);
1144  bool fix_fields(Session *session, Item **ref);
1145  void fix_length_and_dec();
1146  uint32_t decimal_precision() const;
1147  table_map not_null_tables() const { return 0; }
1148  enum Item_result result_type () const { return cached_result_type; }
1149  enum_field_types field_type() const { return cached_field_type; }
1150  const char *func_name() const { return "case"; }
1151  virtual void print(String *str);
1152  Item *find_item(String *str);
1153  const charset_info_st *compare_collation() { return cmp_collation.collation; }
1154  void cleanup();
1155  void agg_str_lengths(Item *arg);
1156  void agg_num_lengths(Item *arg);
1157 };
1158 
1159 /*
1160  The Item_func_in class implements the in_expr IN(values_list) function.
1161 
1162  The current implementation distinguishes 2 cases:
1163  1) all items in the value_list are constants and have the same
1164  result type. This case is handled by in_vector class.
1165  2) items in the value_list have different result types or there is some
1166  non-constant items.
1167  In this case Item_func_in employs several cmp_item objects to performs
1168  comparisons of in_expr and an item from the values_list. One cmp_item
1169  object for each result type. Different result types are collected in the
1170  fix_length_and_dec() member function by means of collect_cmp_types()
1171  function.
1172 */
1174 {
1175 public:
1176  /*
1177  an array of values when the right hand arguments of IN
1178  are all SQL constant and there are no nulls
1179  */
1180  in_vector *array;
1181  bool have_null;
1182  /*
1183  true when all arguments of the IN clause are of compatible types
1184  and can be used safely as comparisons for key conditions
1185  */
1186  bool arg_types_compatible;
1187  Item_result left_result_type;
1188  cmp_item *cmp_items[6]; /* One cmp_item for each result type */
1189  DTCollation cmp_collation;
1190 
1191  Item_func_in(List<Item> &list)
1192  :Item_func_opt_neg(list), array(0), have_null(0),
1193  arg_types_compatible(false)
1194  {
1195  memset(&cmp_items, 0, sizeof(cmp_items));
1196  allowed_arg_cols= 0; // Fetch this value from first argument
1197  }
1198  int64_t val_int();
1199  bool fix_fields(Session *, Item **);
1200  void fix_length_and_dec();
1201  uint32_t decimal_precision() const { return 1; }
1202  void cleanup()
1203  {
1204  Item_int_func::cleanup();
1205  delete array;
1206  array= 0;
1207  for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
1208  {
1209  delete cmp_items[i];
1210  cmp_items[i]= 0;
1211  }
1212  return;
1213  }
1214  optimize_type select_optimize() const
1215  { return OPTIMIZE_KEY; }
1216  virtual void print(String *str);
1217  enum Functype functype() const { return IN_FUNC; }
1218  const char *func_name() const { return " IN "; }
1219  bool nulls_in_row();
1220  bool is_bool_func() { return 1; }
1221  const charset_info_st *compare_collation() { return cmp_collation.collation; }
1222 };
1223 
1224 class cmp_item_row :public cmp_item
1225 {
1226  cmp_item **comparators;
1227  uint32_t n;
1228 public:
1229  cmp_item_row(): comparators(0), n(0) {}
1230  ~cmp_item_row();
1231  void store_value(Item *item);
1232  inline void alloc_comparators();
1233  int cmp(Item *arg);
1234  int compare(cmp_item *arg);
1235  cmp_item *make_same();
1236  void store_value_by_template(cmp_item *tmpl, Item *);
1237  friend void Item_func_in::fix_length_and_dec();
1238 };
1239 
1240 
1241 class in_row :public in_vector
1242 {
1243  cmp_item_row tmp;
1244 public:
1245  in_row(uint32_t elements, Item *);
1246  ~in_row();
1247  void set(uint32_t pos,Item *item);
1248  unsigned char *get_value(Item *item);
1249  friend void Item_func_in::fix_length_and_dec();
1250  Item_result result_type() { return ROW_RESULT; }
1251 };
1252 
1253 /* Functions used by where clause */
1254 
1256 {
1257 protected:
1258  int64_t cached_value;
1259 public:
1261  int64_t val_int();
1262  enum Functype functype() const { return ISNULL_FUNC; }
1263  void fix_length_and_dec()
1264  {
1265  decimals=0; max_length=1; maybe_null=0;
1266  update_used_tables();
1267  }
1268  const char *func_name() const { return "isnull"; }
1269  /* Optimize case of not_null_column IS NULL */
1270  virtual void update_used_tables()
1271  {
1272  if (!args[0]->maybe_null)
1273  {
1274  used_tables_cache= 0; /* is always false */
1275  const_item_cache= 1;
1276  cached_value= (int64_t) 0;
1277  }
1278  else
1279  {
1280  args[0]->update_used_tables();
1281  if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) &&
1282  !with_subselect)
1283  {
1284  /* Remember if the value is always NULL or never NULL */
1285  cached_value= (int64_t) args[0]->is_null();
1286  }
1287  }
1288  }
1289  table_map not_null_tables() const { return 0; }
1290  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1291  Item *neg_transformer(Session *session);
1292  const charset_info_st *compare_collation() { return args[0]->collation.collation; }
1293 };
1294 
1295 /* Functions used by HAVING for rewriting IN subquery */
1296 
1297 /*
1298  This is like IS NOT NULL but it also remembers if it ever has
1299  encountered a NULL.
1300 */
1302 {
1303  Item_in_subselect* owner;
1304 public:
1306  :Item_func_isnull(a), owner(ow)
1307  {}
1308  enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
1309  int64_t val_int();
1310  const char *func_name() const { return "<is_not_null_test>"; }
1311  void update_used_tables();
1312  /*
1313  we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
1314  */
1315  table_map used_tables() const
1316  { return used_tables_cache | RAND_TABLE_BIT; }
1317 };
1318 
1319 
1321 {
1322  bool abort_on_null;
1323 public:
1324  Item_func_isnotnull(Item *a) :item::function::Boolean(a), abort_on_null(0) {}
1325  int64_t val_int();
1326  enum Functype functype() const { return ISNOTNULL_FUNC; }
1327  void fix_length_and_dec()
1328  {
1329  decimals=0; max_length=1; maybe_null=0;
1330  }
1331  const char *func_name() const { return "isnotnull"; }
1332  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1333  table_map not_null_tables() const
1334  { return abort_on_null ? not_null_tables_cache : 0; }
1335  Item *neg_transformer(Session *session);
1336  virtual void print(String *str);
1337  const charset_info_st *compare_collation() { return args[0]->collation.collation; }
1338  void top_level_item() { abort_on_null=1; }
1339 };
1340 
1341 
1343 {
1344  // Turbo Boyer-Moore data
1345  bool canDoTurboBM; // pattern is '%abcd%' case
1346  const char* pattern;
1347  int pattern_len;
1348 
1349  // TurboBM buffers, *this is owner
1350  int* bmGs; // good suffix shift table, size is pattern_len + 1
1351  int* bmBc; // bad character shift table, size is alphabet_size
1352 
1353  void turboBM_compute_suffixes(int* suff);
1354  void turboBM_compute_good_suffix_shifts(int* suff);
1356  bool turboBM_matches(const char* text, int text_len) const;
1357  enum { alphabet_size = 256 };
1358 
1359  Item *escape_item;
1360 
1361  bool escape_used_in_parsing;
1362 
1363 
1364 public:
1365 
1366  char *escape;
1367 
1368  Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1369  :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0),
1370  bmGs(0), bmBc(0), escape_item(escape_arg),
1371  escape_used_in_parsing(escape_used), escape(NULL) {}
1372  int64_t val_int();
1373  enum Functype functype() const { return LIKE_FUNC; }
1374  optimize_type select_optimize() const;
1375  cond_result eq_cmp_result() const { return COND_TRUE; }
1376  const char *func_name() const { return "like"; }
1377  bool fix_fields(Session *session, Item **ref);
1378  void cleanup();
1379 };
1380 
1381 
1383 {
1384 protected:
1385  List<Item> list;
1386  bool abort_on_null;
1387  table_map and_tables_cache;
1388 
1389 public:
1390 
1391  using Item::split_sum_func;
1392 
1393  /* Item_cond() is only used to create top level items */
1394  Item_cond(): item::function::Boolean(), abort_on_null(1)
1395  { const_item_cache=0; }
1396  Item_cond(Item *i1,Item *i2)
1397  :item::function::Boolean(), abort_on_null(0)
1398  {
1399  list.push_back(i1);
1400  list.push_back(i2);
1401  }
1402  Item_cond(Session *session, Item_cond *item);
1403  Item_cond(List<Item> &nlist)
1404  :item::function::Boolean(), list(nlist), abort_on_null(0) {}
1405  void add(Item *item) { list.push_back(item); }
1406  void add_at_head(Item *item) { list.push_front(item); }
1407  void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1408  bool fix_fields(Session *, Item **ref);
1409  void fix_after_pullout(Select_Lex *new_parent, Item **ref);
1410 
1411  enum Type type() const { return COND_ITEM; }
1412  List<Item>* argument_list() { return &list; }
1413  table_map used_tables() const;
1414  void update_used_tables();
1415  virtual void print(String *str);
1416  void split_sum_func(Session *session, Item **ref_pointer_array, List<Item> &fields);
1417  friend int setup_conds(Session *session, TableList *tables, TableList *leaves,
1418  COND **conds);
1419  void top_level_item() { abort_on_null=1; }
1420  void copy_andor_arguments(Session *session, Item_cond *item);
1421  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1422  Item *transform(Item_transformer transformer, unsigned char *arg);
1423  void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1424  void neg_arguments(Session *session);
1425  enum_field_types field_type() const { return DRIZZLE_TYPE_LONGLONG; }
1426  bool subst_argument_checker(unsigned char **)
1427  { return true; }
1428  Item *compile(Item_analyzer analyzer, unsigned char **arg_p,
1429  Item_transformer transformer, unsigned char *arg_t);
1430 };
1431 
1432 
1433 /*
1434  The class Item_equal is used to represent conjunctions of equality
1435  predicates of the form field1 = field2, and field=const in where
1436  conditions and on expressions.
1437 
1438  All equality predicates of the form field1=field2 contained in a
1439  conjunction are substituted for a sequence of items of this class.
1440  An item of this class Item_equal(f1,f2,...fk) represents a
1441  multiple equality f1=f2=...=fk.
1442 
1443  If a conjunction contains predicates f1=f2 and f2=f3, a new item of
1444  this class is created Item_equal(f1,f2,f3) representing the multiple
1445  equality f1=f2=f3 that substitutes the above equality predicates in
1446  the conjunction.
1447  A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1448  substituted for the item representing the same multiple equality
1449  f1=f2=f3.
1450  An item Item_equal(f1,f2) can appear instead of a conjunction of
1451  f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1452 
1453  An item of the class Item_equal inherits equalities from outer
1454  conjunctive levels.
1455 
1456  Suppose we have a where condition of the following form:
1457  WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
1458  In this case:
1459  f1=f2 will be substituted for Item_equal(f1,f2);
1460  f3=f4 and f3=f5 will be substituted for Item_equal(f3,f4,f5);
1461  f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1462 
1463  An object of the class Item_equal can contain an optional constant
1464  item c. Then it represents a multiple equality of the form
1465  c=f1=...=fk.
1466 
1467  Objects of the class Item_equal are used for the following:
1468 
1469  1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
1470  pair of tables ti and tj as joined by an equi-condition.
1471  Thus it provide us with additional access paths from table to table.
1472 
1473  2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
1474  SARGable predicates:
1475  f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
1476  It also can give us additional index scans and can allow us to
1477  improve selectivity estimates.
1478 
1479  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
1480  selected execution plan for the query: if table ti is accessed
1481  before the table tj then in any predicate P in the where condition
1482  the occurrence of tj.fj is substituted for ti.fi. This can allow
1483  an evaluation of the predicate at an earlier step.
1484 
1485  When feature 1 is supported they say that join transitive closure
1486  is employed.
1487  When feature 2 is supported they say that search argument transitive
1488  closure is employed.
1489  Both features are usually supported by preprocessing original query and
1490  adding additional predicates.
1491  We do not just add predicates, we rather dynamically replace some
1492  predicates that can not be used to access tables in the investigated
1493  plan for those, obtained by substitution of some fields for equal fields,
1494  that can be used.
1495 
1496  Prepared Statements/Stored Procedures note: instances of class
1497  Item_equal are created only at the time a PS/SP is executed and
1498  are deleted in the end of execution. All changes made to these
1499  objects need not be registered in the list of changes of the parse
1500  tree and do not harm PS/SP re-execution.
1501 
1502  Item equal objects are employed only at the optimize phase. Usually they are
1503  not supposed to be evaluated. Yet in some cases we call the method val_int()
1504  for them. We have to take care of restricting the predicate such an
1505  object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
1506 */
1507 
1509 {
1510 public:
1511  typedef List<Item_field> fields_t;
1512 
1513  Item_equal() :
1514  const_item(0),
1515  eval_item(0),
1516  cond_false(0)
1517  {
1518  const_item_cache=0;
1519  }
1520 
1521  fields_t::iterator begin()
1522  {
1523  return fields.begin();
1524  }
1525 
1526  Item_equal(Item_field *f1, Item_field *f2);
1527  Item_equal(Item *c, Item_field *f);
1528  Item_equal(Item_equal *item_equal);
1529  inline Item* get_const() { return const_item; }
1530  void add(Item *c);
1531  void add(Item_field *f);
1532  uint32_t members();
1533  bool contains(Field *field);
1534  Item_field* get_first() { return &fields.front(); }
1535  void merge(Item_equal *item);
1536  void update_const();
1537  enum Functype functype() const { return MULT_EQUAL_FUNC; }
1538  int64_t val_int();
1539  const char *func_name() const { return "multiple equal"; }
1540  optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1541  void sort(Item_field_cmpfunc cmp, void *arg);
1542  void fix_length_and_dec();
1543  bool fix_fields(Session *session, Item **ref);
1544  void update_used_tables();
1545  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1546  Item *transform(Item_transformer transformer, unsigned char *arg);
1547  virtual void print(String *str);
1548  const charset_info_st *compare_collation()
1549  { return fields.front().collation.collation; }
1550 private:
1551  fields_t fields; /* list of equal field items */
1552  Item *const_item; /* optional constant item equal to fields items */
1553  cmp_item *eval_item;
1554  bool cond_false;
1555 
1556 };
1557 
1559 {
1560 public:
1561  uint32_t max_members; /* max number of members the current level
1562  list and all lower level lists */
1563  COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
1564  List<Item_equal> current_level; /* list of multiple equalities of
1565  the current and level */
1566  COND_EQUAL()
1567  {
1568  upper_levels= 0;
1569  }
1570 };
1571 
1572 typedef List<Item_field>::iterator Item_equal_iterator;
1573 
1575 {
1576 public:
1577  COND_EQUAL cond_equal; /* contains list of Item_equal objects for
1578  the current and level and reference
1579  to multiple equalities of upper and levels */
1580  Item_cond_and() :Item_cond() {}
1581  Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1582  Item_cond_and(Session *session, Item_cond_and *item) :Item_cond(session, item) {}
1583  Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1584  enum Functype functype() const { return COND_AND_FUNC; }
1585  int64_t val_int();
1586  const char *func_name() const { return "and"; }
1587  table_map not_null_tables() const
1588  { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1589  Item* copy_andor_structure(Session *session)
1590  {
1591  Item_cond_and *item;
1592  item= new Item_cond_and(session, this);
1593  item->copy_andor_arguments(session, this);
1594  return item;
1595  }
1596  Item *neg_transformer(Session *session);
1597 };
1598 
1599 inline bool is_cond_and(Item *item)
1600 {
1601  if (item->type() != Item::COND_ITEM)
1602  return false;
1603 
1604  Item_cond *cond_item= (Item_cond*) item;
1605  return (cond_item->functype() == Item_func::COND_AND_FUNC);
1606 }
1607 
1609 {
1610 public:
1611  Item_cond_or() :Item_cond() {}
1612  Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1613  Item_cond_or(Session *session, Item_cond_or *item) :Item_cond(session, item) {}
1614  Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1615  enum Functype functype() const { return COND_OR_FUNC; }
1616  int64_t val_int();
1617  const char *func_name() const { return "or"; }
1618  table_map not_null_tables() const { return and_tables_cache; }
1619  Item* copy_andor_structure(Session *session)
1620  {
1621  Item_cond_or *item;
1622  item= new Item_cond_or(session, this);
1623  item->copy_andor_arguments(session, this);
1624  return item;
1625  }
1626  Item *neg_transformer(Session *session);
1627 };
1628 
1629 inline bool is_cond_or(Item *item)
1630 {
1631  if (item->type() != Item::COND_ITEM)
1632  return false;
1633 
1634  Item_cond *cond_item= (Item_cond*) item;
1635  return (cond_item->functype() == Item_func::COND_OR_FUNC);
1636 }
1637 
1638 /*
1639  XOR is Item_cond, not an Item_int_func because we could like to
1640  optimize (a XOR b) later on. It's low prio, though
1641 */
1642 
1644 {
1645 public:
1646  Item_cond_xor() :Item_cond() {}
1647  Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1648  enum Functype functype() const { return COND_XOR_FUNC; }
1649  /* TODO: remove the next line when implementing XOR optimization */
1650  enum Type type() const { return FUNC_ITEM; }
1651  int64_t val_int();
1652  const char *func_name() const { return "xor"; }
1653  void top_level_item() {}
1654 };
1655 
1656 enum_field_types agg_field_type(Item **items, uint32_t nitems);
1657 
1658 
1659 /* Some useful inline functions */
1660 
1661 inline Item *and_conds(Item *a, Item *b)
1662 {
1663  if (!b) return a;
1664  if (!a) return b;
1665  return new Item_cond_and(a, b);
1666 }
1667 
1668 Item *and_expressions(Item *a, Item *b, Item **org_item);
1669 
1670 } /* namespace drizzled */
1671 
virtual void print(String *str)
Definition: cmpfunc.cc:388
virtual void print(String *str)
Definition: cmpfunc.h:604
Item * neg_transformer(Session *session)
Definition: cmpfunc.cc:4809
virtual void print(String *str)
Definition: cmpfunc.cc:3812
table_map not_null_tables() const
Definition: cmpfunc.h:651
int64_t int_op()
Performs the operation that this functions implements when the result type is INT.
Definition: cmpfunc.cc:2909
bool fix_fields(Session *, Item **)
Definition: cmpfunc.cc:3554
virtual void print(String *str)
Definition: cmpfunc.cc:5175
Item * find_item(String *str)
Definition: cmpfunc.cc:2606
bool fix_fields(Session *, Item **)
Definition: cmpfunc.cc:1998
type::Decimal * decimal_op(type::Decimal *)
Performs the operation that this functions implements when the result type is DECIMAL.
Definition: cmpfunc.cc:2297
void merge(Item_equal *item)
Definition: cmpfunc.cc:4995
virtual int64_t val_int()=0
int64_t int_op()
Performs the operation that this functions implements when the result type is INT.
Definition: cmpfunc.cc:2281
table_map not_null_tables() const
Definition: cmpfunc.h:1289
table_map not_null_tables() const
Definition: cmpfunc.h:1587
table_map used_tables() const
Definition: func.cc:430
bool contains(Field *field)
Definition: cmpfunc.cc:4971
TODO: Rename this file - func.h is stupid.
bool eq(const Item *item, bool binary_cmp) const
Definition: cmpfunc.cc:1792
bool turboBM_matches(const char *text, int text_len) const
Definition: cmpfunc.cc:4641
virtual bool val_bool()
Definition: cmpfunc.cc:1473
String * str_op(String *)
Definition: cmpfunc.cc:2895
virtual void print(String *str)
Definition: cmpfunc.cc:1458
table_map not_null_tables() const
Definition: cmpfunc.h:464
void top_level_item()
Definition: cmpfunc.h:1419
const bool affirmative
Definition: cmpfunc.h:150
void fix_after_pullout(Select_Lex *new_parent, Item **ref)
Definition: cmpfunc.cc:3981
String * val_str(String *str)
Definition: cmpfunc.cc:2547
Item * transform(Item_transformer transformer, unsigned char *arg)
Definition: cmpfunc.cc:4042
table_map used_tables() const
Definition: cmpfunc.h:405
virtual bool const_item() const
Definition: func.h:108
bool maybe_null
Definition: item.h:121
double real_op()
Performs the operation that this functions implements when the result type is REAL.
Definition: cmpfunc.cc:2265
enum_field_types agg_field_type(Item **items, uint32_t nitems)
Aggregates field types from the array of items.
Definition: cmpfunc.cc:202
String * str_op(String *str)
Definition: cmpfunc.cc:2314
Item * compile(Item_analyzer analyzer, unsigned char **arg_p, Item_transformer transformer, unsigned char *arg_t)
Definition: cmpfunc.cc:4081
Item * neg_transformer(Session *session)
Definition: cmpfunc.cc:4799
String * val_str(String *)
Definition: cmpfunc.cc:2644
void sort(Item_field_cmpfunc cmp, void *arg)
Definition: cmpfunc.cc:5029
bool is_null()
Definition: func.cc:512
virtual double val_real()=0
virtual void print(String *str)
Definition: func.cc:442
type::Decimal * val_decimal(type::Decimal *)
Definition: cmpfunc.cc:2699
virtual void print(String *str)
Definition: cmpfunc.h:327
void turboBM_compute_bad_character_shifts()
Definition: cmpfunc.cc:4610
table_map not_null_tables() const
Definition: cmpfunc.h:1333
String * val_str(String *str)
Definition: cmpfunc.cc:2463
virtual void print(String *str)
Definition: cmpfunc.cc:2189
Item * neg_transformer(Session *session)
Definition: cmpfunc.cc:4845
table_map used_tables() const
Definition: cmpfunc.cc:4154
table_map not_null_tables() const
Definition: cmpfunc.h:723
virtual void top_level_item()
Definition: cmpfunc.h:422
Item * neg_transformer(Session *session)
Definition: cmpfunc.cc:4783
virtual String * val_str(String *str)=0
table_map not_null_tables() const
Definition: cmpfunc.h:1618
bool with_subselect
Definition: item.h:142
int compare_e_int_diff_signedness()
Definition: cmpfunc.cc:1381
virtual void print(String *str)
Definition: cmpfunc.h:718
Item * transform(Item_transformer transformer, unsigned char *arg)
Definition: cmpfunc.cc:1680
virtual table_map used_tables() const
Definition: item.h:451
virtual void print(String *str)
Definition: cmpfunc.cc:4362
void split_sum_func(Session *session, Item **ref_pointer_array, List< Item > &fields)
Definition: cmpfunc.cc:4144
void turboBM_compute_good_suffix_shifts(int *suff)
Definition: cmpfunc.cc:4566
bool const_item() const
Definition: cmpfunc.h:402
bool fix_fields(Session *, Item **)
Definition: cmpfunc.cc:2359
virtual void print(String *str)
Definition: cmpfunc.cc:4176
table_map used_tables() const
Definition: cmpfunc.h:1315
type::Decimal * val_decimal(type::Decimal *)
Definition: cmpfunc.cc:2478
Item * and_expressions(Item *a, Item *b, Item **org_item)
Definition: cmpfunc.cc:4285
void turboBM_compute_suffixes(int *suff)
Definition: cmpfunc.cc:4512
String str_value
Definition: item.h:107
double real_op()
Performs the operation that this functions implements when the result type is REAL.
Definition: cmpfunc.cc:2923
Item * neg_transformer(Session *session)
Definition: cmpfunc.cc:4834
type::Decimal * decimal_op(type::Decimal *)
Performs the operation that this functions implements when the result type is DECIMAL.
Definition: cmpfunc.cc:2938
virtual void print(String *str)
Definition: cmpfunc.cc:2854
type::Decimal * val_decimal(type::Decimal *)
Definition: cmpfunc.cc:2563
optimize_type select_optimize() const
Definition: cmpfunc.cc:4399
virtual int64_t val_int()
Definition: cmpfunc.cc:1496
table_map not_null_tables() const
Definition: cmpfunc.h:1147
Item * transform(Item_transformer transformer, unsigned char *arg)
Definition: cmpfunc.cc:5161
virtual void print(String *str)
Definition: cmpfunc.cc:353