1 #ifndef ITEM_CMPFUNC_INCLUDED
2 #define ITEM_CMPFUNC_INCLUDED
3 /* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
4    Copyright (c) 2009, 2020, MariaDB
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 Street, Fifth Floor, Boston, MA  02110-1335  USA */
18 
19 
20 /* compare and test functions */
21 
22 #ifdef USE_PRAGMA_INTERFACE
23 #pragma interface			/* gcc class implementation */
24 #endif
25 
26 #include "item_func.h"             /* Item_int_func, Item_bool_func */
27 #define PCRE_STATIC 1             /* Important on Windows */
28 #include "pcre.h"                 /* pcre header file */
29 #include "item.h"
30 
31 extern Item_result item_cmp_type(Item_result a,Item_result b);
item_cmp_type(const Item * a,const Item * b)32 inline Item_result item_cmp_type(const Item *a, const Item *b)
33 {
34   return item_cmp_type(a->cmp_type(), b->cmp_type());
35 }
item_cmp_type(Item_result a,const Item * b)36 inline Item_result item_cmp_type(Item_result a, const Item *b)
37 {
38   return item_cmp_type(a, b->cmp_type());
39 }
40 class Item_bool_func2;
41 class Arg_comparator;
42 
43 typedef int (Arg_comparator::*arg_cmp_func)();
44 
45 typedef int (*Item_field_cmpfunc)(Item *f1, Item *f2, void *arg);
46 
47 class Arg_comparator: public Sql_alloc
48 {
49   Item **a, **b;
50   const Type_handler *m_compare_handler;
51   CHARSET_INFO *m_compare_collation;
52   arg_cmp_func func;
53   Item_func_or_sum *owner;
54   bool set_null;                   // TRUE <=> set owner->null_value
55   Arg_comparator *comparators;   // used only for compare_row()
56   double precision;
57   /* Fields used in DATE/DATETIME comparison. */
58   Item *a_cache, *b_cache;         // Cached values of a and b items
59                                    //   when one of arguments is NULL.
60 
61   int set_cmp_func(Item_func_or_sum *owner_arg, Item **a1, Item **a2);
62 
compare_not_null_values(longlong val1,longlong val2)63   int compare_not_null_values(longlong val1, longlong val2)
64   {
65     if (set_null)
66       owner->null_value= false;
67     if (val1 < val2) return -1;
68     if (val1 == val2) return 0;
69     return 1;
70   }
71   NativeBuffer<STRING_BUFFER_USUAL_SIZE> m_native1, m_native2;
72 public:
73   /* Allow owner function to use string buffers. */
74   String value1, value2;
75 
Arg_comparator()76   Arg_comparator():
77     m_compare_handler(&type_handler_null),
78     m_compare_collation(&my_charset_bin),
79     set_null(TRUE), comparators(0),
80     a_cache(0), b_cache(0) {};
Arg_comparator(Item ** a1,Item ** a2)81   Arg_comparator(Item **a1, Item **a2): a(a1), b(a2),
82     m_compare_handler(&type_handler_null),
83     m_compare_collation(&my_charset_bin),
84     set_null(TRUE), comparators(0),
85     a_cache(0), b_cache(0) {};
86 
87 public:
88   bool set_cmp_func_for_row_arguments();
89   bool set_cmp_func_row();
90   bool set_cmp_func_string();
91   bool set_cmp_func_time();
92   bool set_cmp_func_datetime();
93   bool set_cmp_func_native();
94   bool set_cmp_func_int();
95   bool set_cmp_func_real();
96   bool set_cmp_func_decimal();
97 
set_cmp_func(Item_func_or_sum * owner_arg,Item ** a1,Item ** a2,bool set_null_arg)98   inline int set_cmp_func(Item_func_or_sum *owner_arg,
99 			  Item **a1, Item **a2, bool set_null_arg)
100   {
101     set_null= set_null_arg;
102     return set_cmp_func(owner_arg, a1, a2);
103   }
compare()104   inline int compare() { return (this->*func)(); }
105 
106   int compare_string();		 // compare args[0] & args[1]
107   int compare_real();            // compare args[0] & args[1]
108   int compare_decimal();         // compare args[0] & args[1]
109   int compare_int_signed();      // compare args[0] & args[1]
110   int compare_int_signed_unsigned();
111   int compare_int_unsigned_signed();
112   int compare_int_unsigned();
113   int compare_row();             // compare args[0] & args[1]
114   int compare_e_string();	 // compare args[0] & args[1]
115   int compare_e_real();          // compare args[0] & args[1]
116   int compare_e_decimal();       // compare args[0] & args[1]
117   int compare_e_int();           // compare args[0] & args[1]
118   int compare_e_int_diff_signedness();
119   int compare_e_row();           // compare args[0] & args[1]
120   int compare_real_fixed();
121   int compare_e_real_fixed();
122   int compare_datetime();
123   int compare_e_datetime();
124   int compare_time();
125   int compare_e_time();
126   int compare_native();
127   int compare_e_native();
128   int compare_json_str_basic(Item *j, Item *s);
129   int compare_json_str();
130   int compare_str_json();
131   int compare_e_json_str_basic(Item *j, Item *s);
132   int compare_e_json_str();
133   int compare_e_str_json();
134 
135   void min_max_update_field_native(THD *thd, Field *field, Item *item,
136                                    int cmp_sign);
137 
138   Item** cache_converted_constant(THD *thd, Item **value, Item **cache,
139                                   const Type_handler *type);
is_owner_equal_func()140   inline bool is_owner_equal_func()
141   {
142     return (owner->type() == Item::FUNC_ITEM &&
143            ((Item_func*)owner)->functype() == Item_func::EQUAL_FUNC);
144   }
compare_type_handler()145   const Type_handler *compare_type_handler() const { return m_compare_handler; }
compare_type()146   Item_result compare_type() const { return m_compare_handler->cmp_type(); }
compare_collation()147   CHARSET_INFO *compare_collation() const { return m_compare_collation; }
subcomparators()148   Arg_comparator *subcomparators() const { return comparators; }
cleanup()149   void cleanup()
150   {
151     delete [] comparators;
152     comparators= 0;
153   }
154   friend class Item_func;
155   friend class Item_bool_rowready_func2;
156 };
157 
158 
159 class SEL_ARG;
160 struct KEY_PART;
161 
162 class Item_bool_func :public Item_int_func,
163                       public Type_cmp_attributes
164 {
165 protected:
166   /*
167     Build a SEL_TREE for a simple predicate
168     @param  param       PARAM from SQL_SELECT::test_quick_select
169     @param  field       field in the predicate
170     @param  value       constant in the predicate
171     @return Pointer to the tree built tree
172   */
get_func_mm_tree(RANGE_OPT_PARAM * param,Field * field,Item * value)173   virtual SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
174                                      Field *field, Item *value)
175   {
176     DBUG_ENTER("Item_bool_func::get_func_mm_tree");
177     DBUG_ASSERT(0);
178     DBUG_RETURN(0);
179   }
180   /*
181     Return the full select tree for "field_item" and "value":
182     - a single SEL_TREE if the field is not in a multiple equality, or
183     - a conjunction of all SEL_TREEs for all fields from
184       the same multiple equality with "field_item".
185   */
186   SEL_TREE *get_full_func_mm_tree(RANGE_OPT_PARAM *param,
187                                   Item_field *field_item, Item *value);
188   /**
189     Test if "item" and "value" are suitable for the range optimization
190     and get their full select tree.
191 
192     "Suitable" means:
193     - "item" is a field or a field reference
194     - "value" is NULL                (e.g. WHERE field IS NULL), or
195       "value" is an unexpensive item (e.g. WHERE field OP value)
196 
197     @param item  - the argument that is checked to be a field
198     @param value - the other argument
199     @returns - NULL if the arguments are not suitable for the range optimizer.
200     @returns - the full select tree if the arguments are suitable.
201   */
get_full_func_mm_tree_for_args(RANGE_OPT_PARAM * param,Item * item,Item * value)202   SEL_TREE *get_full_func_mm_tree_for_args(RANGE_OPT_PARAM *param,
203                                            Item *item, Item *value)
204   {
205     DBUG_ENTER("Item_bool_func::get_full_func_mm_tree_for_args");
206     Item *field= item->real_item();
207     if (field->type() == Item::FIELD_ITEM && !field->const_item() &&
208         (!value || !value->is_expensive()))
209       DBUG_RETURN(get_full_func_mm_tree(param, (Item_field *) field, value));
210     DBUG_RETURN(NULL);
211   }
212   SEL_TREE *get_mm_parts(RANGE_OPT_PARAM *param, Field *field,
213                          Item_func::Functype type, Item *value);
214   SEL_TREE *get_ne_mm_tree(RANGE_OPT_PARAM *param,
215                            Field *field, Item *lt_value, Item *gt_value);
216   virtual SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param, Field *field,
217                                KEY_PART *key_part,
218                                Item_func::Functype type, Item *value);
219 public:
Item_bool_func(THD * thd)220   Item_bool_func(THD *thd): Item_int_func(thd) {}
Item_bool_func(THD * thd,Item * a)221   Item_bool_func(THD *thd, Item *a): Item_int_func(thd, a) {}
Item_bool_func(THD * thd,Item * a,Item * b)222   Item_bool_func(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {}
Item_bool_func(THD * thd,Item * a,Item * b,Item * c)223   Item_bool_func(THD *thd, Item *a, Item *b, Item *c): Item_int_func(thd, a, b, c) {}
Item_bool_func(THD * thd,List<Item> & list)224   Item_bool_func(THD *thd, List<Item> &list): Item_int_func(thd, list) { }
Item_bool_func(THD * thd,Item_bool_func * item)225   Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
type_handler()226   const Type_handler *type_handler() const { return &type_handler_bool; }
fixed_type_handler()227   const Type_handler *fixed_type_handler() const { return &type_handler_bool; }
compare_collation()228   CHARSET_INFO *compare_collation() const { return NULL; }
fix_length_and_dec()229   bool fix_length_and_dec() { decimals=0; max_length=1; return FALSE; }
decimal_precision()230   uint decimal_precision() const { return 1; }
need_parentheses_in_default()231   bool need_parentheses_in_default() { return true; }
232 };
233 
234 
235 /**
236   Abstract Item class, to represent <code>X IS [NOT] (TRUE | FALSE)</code>
237   boolean predicates.
238 */
239 
240 class Item_func_truth : public Item_bool_func
241 {
242 public:
243   virtual bool val_bool();
244   virtual longlong val_int();
245   virtual bool fix_length_and_dec();
246   virtual void print(String *str, enum_query_type query_type);
precedence()247   enum precedence precedence() const { return CMP_PRECEDENCE; }
248 
249 protected:
Item_func_truth(THD * thd,Item * a,bool a_value,bool a_affirmative)250   Item_func_truth(THD *thd, Item *a, bool a_value, bool a_affirmative):
251     Item_bool_func(thd, a), value(a_value), affirmative(a_affirmative)
252   {}
253 
~Item_func_truth()254   ~Item_func_truth()
255   {}
256 private:
257   /**
258     True for <code>X IS [NOT] TRUE</code>,
259     false for <code>X IS [NOT] FALSE</code> predicates.
260   */
261   const bool value;
262   /**
263     True for <code>X IS Y</code>, false for <code>X IS NOT Y</code> predicates.
264   */
265   const bool affirmative;
266 };
267 
268 
269 /**
270   This Item represents a <code>X IS TRUE</code> boolean predicate.
271 */
272 
273 class Item_func_istrue : public Item_func_truth
274 {
275 public:
Item_func_istrue(THD * thd,Item * a)276   Item_func_istrue(THD *thd, Item *a): Item_func_truth(thd, a, true, true) {}
~Item_func_istrue()277   ~Item_func_istrue() {}
func_name()278   virtual const char* func_name() const { return "istrue"; }
get_copy(THD * thd)279   Item *get_copy(THD *thd)
280   { return get_item_copy<Item_func_istrue>(thd, this); }
281 };
282 
283 
284 /**
285   This Item represents a <code>X IS NOT TRUE</code> boolean predicate.
286 */
287 
288 class Item_func_isnottrue : public Item_func_truth
289 {
290 public:
Item_func_isnottrue(THD * thd,Item * a)291   Item_func_isnottrue(THD *thd, Item *a):
292     Item_func_truth(thd, a, true, false) {}
~Item_func_isnottrue()293   ~Item_func_isnottrue() {}
func_name()294   virtual const char* func_name() const { return "isnottrue"; }
get_copy(THD * thd)295   Item *get_copy(THD *thd)
296   { return get_item_copy<Item_func_isnottrue>(thd, this); }
eval_not_null_tables(void *)297   bool eval_not_null_tables(void *) { not_null_tables_cache= 0; return false; }
298 };
299 
300 
301 /**
302   This Item represents a <code>X IS FALSE</code> boolean predicate.
303 */
304 
305 class Item_func_isfalse : public Item_func_truth
306 {
307 public:
Item_func_isfalse(THD * thd,Item * a)308   Item_func_isfalse(THD *thd, Item *a): Item_func_truth(thd, a, false, true) {}
~Item_func_isfalse()309   ~Item_func_isfalse() {}
func_name()310   virtual const char* func_name() const { return "isfalse"; }
get_copy(THD * thd)311   Item *get_copy(THD *thd)
312   { return get_item_copy<Item_func_isfalse>(thd, this); }
313 };
314 
315 
316 /**
317   This Item represents a <code>X IS NOT FALSE</code> boolean predicate.
318 */
319 
320 class Item_func_isnotfalse : public Item_func_truth
321 {
322 public:
Item_func_isnotfalse(THD * thd,Item * a)323   Item_func_isnotfalse(THD *thd, Item *a):
324     Item_func_truth(thd, a, false, false) {}
~Item_func_isnotfalse()325   ~Item_func_isnotfalse() {}
func_name()326   virtual const char* func_name() const { return "isnotfalse"; }
get_copy(THD * thd)327   Item *get_copy(THD *thd)
328   { return get_item_copy<Item_func_isnotfalse>(thd, this); }
eval_not_null_tables(void *)329   bool eval_not_null_tables(void *) { not_null_tables_cache= 0; return false; }
330 };
331 
332 
333 class Item_cache;
334 #define UNKNOWN (-1)
335 
336 
337 /*
338   Item_in_optimizer(left_expr, Item_in_subselect(...))
339 
340   Item_in_optimizer is used to wrap an instance of Item_in_subselect. This
341   class does the following:
342    - Evaluate the left expression and store it in Item_cache_* object (to
343      avoid re-evaluating it many times during subquery execution)
344    - Shortcut the evaluation of "NULL IN (...)" to NULL in the cases where we
345      don't care if the result is NULL or FALSE.
346 
347   NOTE
348     It is not quite clear why the above listed functionality should be
349     placed into a separate class called 'Item_in_optimizer'.
350 */
351 
352 class Item_in_optimizer: public Item_bool_func
353 {
354 protected:
355   Item_cache *cache;
356   Item *expr_cache;
357   bool save_cache;
358   /*
359     Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
360       UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
361       FALSE   - result is FALSE
362       TRUE    - result is NULL
363   */
364   int result_for_null_param;
365 public:
Item_in_optimizer(THD * thd,Item * a,Item * b)366   Item_in_optimizer(THD *thd, Item *a, Item *b):
367     Item_bool_func(thd, a, b), cache(0), expr_cache(0),
368     save_cache(0), result_for_null_param(UNKNOWN)
369   { m_with_subquery= true; }
370   bool fix_fields(THD *, Item **);
371   bool fix_left(THD *thd);
not_null_tables()372   table_map not_null_tables() const { return 0; }
373   bool is_null();
374   longlong val_int();
375   void cleanup();
functype()376   enum Functype functype() const   { return IN_OPTIMIZER_FUNC; }
func_name()377   const char *func_name() const { return "<in_optimizer>"; }
get_cache()378   Item_cache **get_cache() { return &cache; }
379   void keep_top_level_cache();
380   Item *transform(THD *thd, Item_transformer transformer, uchar *arg);
381   virtual Item *expr_cache_insert_transformer(THD *thd, uchar *unused);
382   bool is_expensive_processor(void *arg);
383   bool is_expensive();
set_join_tab_idx(uint join_tab_idx_arg)384   void set_join_tab_idx(uint join_tab_idx_arg)
385   { args[1]->set_join_tab_idx(join_tab_idx_arg); }
386   virtual void get_cache_parameters(List<Item> &parameters);
387   bool is_top_level_item();
388   bool eval_not_null_tables(void *opt_arg);
389   void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
390   bool invisible_mode();
reset_cache()391   void reset_cache() { cache= NULL; }
392   virtual void print(String *str, enum_query_type query_type);
393   void restore_first_argument();
get_wrapped_in_subselect_item()394   Item* get_wrapped_in_subselect_item()
395   { return args[1]; }
get_copy(THD * thd)396   Item *get_copy(THD *thd)
397   { return get_item_copy<Item_in_optimizer>(thd, this); }
398 };
399 
400 
401 /*
402   Functions and operators with two arguments that can use range optimizer.
403 */
404 class Item_bool_func2 :public Item_bool_func
405 {                                              /* Bool with 2 string args */
406 protected:
407   void add_key_fields_optimize_op(JOIN *join, KEY_FIELD **key_fields,
408                                   uint *and_level, table_map usable_tables,
409                                   SARGABLE_PARAM **sargables, bool equal_func);
410 public:
Item_bool_func2(THD * thd,Item * a,Item * b)411   Item_bool_func2(THD *thd, Item *a, Item *b):
412     Item_bool_func(thd, a, b) { }
413 
is_null()414   bool is_null() { return MY_TEST(args[0]->is_null() || args[1]->is_null()); }
415   COND *remove_eq_conds(THD *thd, Item::cond_result *cond_value,
416                         bool top_level);
417   bool count_sargable_conds(void *arg);
418   /*
419     Specifies which result type the function uses to compare its arguments.
420     This method is used in equal field propagation.
421   */
compare_type_handler()422   virtual const Type_handler *compare_type_handler() const
423   {
424     /*
425       Have STRING_RESULT by default, which means the function compares
426       val_str() results of the arguments. This is suitable for Item_func_like
427       and for Item_func_spatial_rel.
428       Note, Item_bool_rowready_func2 overrides this default behaviour.
429     */
430     return &type_handler_varchar;
431   }
get_mm_tree(RANGE_OPT_PARAM * param,Item ** cond_ptr)432   SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
433   {
434     DBUG_ENTER("Item_bool_func2::get_mm_tree");
435     DBUG_ASSERT(arg_count == 2);
436     SEL_TREE *ftree= get_full_func_mm_tree_for_args(param, args[0], args[1]);
437     if (!ftree)
438       ftree= Item_func::get_mm_tree(param, cond_ptr);
439     DBUG_RETURN(ftree);
440   }
441 };
442 
443 
444 /**
445   A class for functions and operators that can use the range optimizer and
446   have a reverse function/operator that can also use the range optimizer,
447   so this condition:
448     WHERE value OP field
449   can be optimized as equivalent to:
450     WHERE field REV_OP value
451 
452   This class covers:
453   - scalar comparison predicates:  <, <=, =, <=>, >=, >
454   - MBR and precise spatial relation predicates (e.g. SP_TOUCHES(x,y))
455 
456   For example:
457     WHERE 10 > field
458   can be optimized as:
459     WHERE field < 10
460 */
461 class Item_bool_func2_with_rev :public Item_bool_func2
462 {
463 protected:
get_func_mm_tree(RANGE_OPT_PARAM * param,Field * field,Item * value)464   SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
465                              Field *field, Item *value)
466   {
467     DBUG_ENTER("Item_bool_func2_with_rev::get_func_mm_tree");
468     Item_func::Functype func_type=
469       (value != arguments()[0]) ? functype() : rev_functype();
470     DBUG_RETURN(get_mm_parts(param, field, func_type, value));
471   }
472 public:
Item_bool_func2_with_rev(THD * thd,Item * a,Item * b)473   Item_bool_func2_with_rev(THD *thd, Item *a, Item *b):
474     Item_bool_func2(thd, a, b) { }
475   virtual enum Functype rev_functype() const= 0;
get_mm_tree(RANGE_OPT_PARAM * param,Item ** cond_ptr)476   SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
477   {
478     DBUG_ENTER("Item_bool_func2_with_rev::get_mm_tree");
479     DBUG_ASSERT(arg_count == 2);
480     SEL_TREE *ftree;
481     /*
482       Even if get_full_func_mm_tree_for_args(param, args[0], args[1]) will not
483       return a range predicate it may still be possible to create one
484       by reversing the order of the operands. Note that this only
485       applies to predicates where both operands are fields. Example: A
486       query of the form
487 
488          WHERE t1.a OP t2.b
489 
490       In this case, args[0] == t1.a and args[1] == t2.b.
491       When creating range predicates for t2,
492       get_full_func_mm_tree_for_args(param, args[0], args[1])
493       will return NULL because 'field' belongs to t1 and only
494       predicates that applies to t2 are of interest. In this case a
495       call to get_full_func_mm_tree_for_args() with reversed operands
496       may succeed.
497     */
498     if (!(ftree= get_full_func_mm_tree_for_args(param, args[0], args[1])) &&
499         !(ftree= get_full_func_mm_tree_for_args(param, args[1], args[0])))
500       ftree= Item_func::get_mm_tree(param, cond_ptr);
501     DBUG_RETURN(ftree);
502   }
503 };
504 
505 
506 class Item_bool_rowready_func2 :public Item_bool_func2_with_rev
507 {
508 protected:
509   Arg_comparator cmp;
check_arguments()510   bool check_arguments() const
511   {
512     return check_argument_types_like_args0();
513   }
514 public:
Item_bool_rowready_func2(THD * thd,Item * a,Item * b)515   Item_bool_rowready_func2(THD *thd, Item *a, Item *b):
516     Item_bool_func2_with_rev(thd, a, b), cmp(tmp_arg, tmp_arg + 1)
517   { }
518   Sql_mode_dependency value_depends_on_sql_mode() const;
print(String * str,enum_query_type query_type)519   void print(String *str, enum_query_type query_type)
520   {
521     Item_func::print_op(str, query_type);
522   }
precedence()523   enum precedence precedence() const { return CMP_PRECEDENCE; }
524   Item *neg_transformer(THD *thd);
525   virtual Item *negated_item(THD *thd);
propagate_equal_fields(THD * thd,const Context & ctx,COND_EQUAL * cond)526   Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
527   {
528     Item_args::propagate_equal_fields(thd,
529                                       Context(ANY_SUBST,
530                                               cmp.compare_type_handler(),
531                                               compare_collation()),
532                                       cond);
533     return this;
534   }
535   bool fix_length_and_dec();
set_cmp_func()536   int set_cmp_func()
537   {
538     return cmp.set_cmp_func(this, tmp_arg, tmp_arg + 1, true);
539   }
compare_collation()540   CHARSET_INFO *compare_collation() const { return cmp.compare_collation(); }
compare_type_handler()541   const Type_handler *compare_type_handler() const
542   {
543     return cmp.compare_type_handler();
544   }
get_comparator()545   Arg_comparator *get_comparator() { return &cmp; }
cleanup()546   void cleanup()
547   {
548     Item_bool_func2::cleanup();
549     cmp.cleanup();
550   }
add_key_fields(JOIN * join,KEY_FIELD ** key_fields,uint * and_level,table_map usable_tables,SARGABLE_PARAM ** sargables)551   void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
552                       uint *and_level, table_map usable_tables,
553                       SARGABLE_PARAM **sargables)
554   {
555     return add_key_fields_optimize_op(join, key_fields, and_level,
556                                       usable_tables, sargables, false);
557   }
build_clone(THD * thd)558   Item *build_clone(THD *thd)
559   {
560     Item_bool_rowready_func2 *clone=
561       (Item_bool_rowready_func2 *) Item_func::build_clone(thd);
562     if (clone)
563     {
564       clone->cmp.comparators= 0;
565     }
566     return clone;
567   }
568 };
569 
570 /**
571   XOR inherits from Item_bool_func because it is not optimized yet.
572   Later, when XOR is optimized, it needs to inherit from
573   Item_cond instead. See WL#5800.
574 */
575 class Item_func_xor :public Item_bool_func
576 {
577 public:
Item_func_xor(THD * thd,Item * i1,Item * i2)578   Item_func_xor(THD *thd, Item *i1, Item *i2): Item_bool_func(thd, i1, i2) {}
functype()579   enum Functype functype() const { return XOR_FUNC; }
func_name()580   const char *func_name() const { return "xor"; }
precedence()581   enum precedence precedence() const { return XOR_PRECEDENCE; }
print(String * str,enum_query_type query_type)582   void print(String *str, enum_query_type query_type)
583   { Item_func::print_op(str, query_type); }
584   longlong val_int();
585   Item *neg_transformer(THD *thd);
propagate_equal_fields(THD * thd,const Context & ctx,COND_EQUAL * cond)586   Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
587   {
588     Item_args::propagate_equal_fields(thd, Context_boolean(), cond);
589     return this;
590   }
get_copy(THD * thd)591   Item *get_copy(THD *thd)
592   { return get_item_copy<Item_func_xor>(thd, this); }
593 };
594 
595 class Item_func_not :public Item_bool_func
596 {
597   bool abort_on_null;
598 public:
Item_func_not(THD * thd,Item * a)599   Item_func_not(THD *thd, Item *a):
600     Item_bool_func(thd, a), abort_on_null(FALSE) {}
top_level_item()601   virtual void top_level_item() { abort_on_null= 1; }
is_top_level_item()602   bool is_top_level_item() { return abort_on_null; }
603   longlong val_int();
functype()604   enum Functype functype() const { return NOT_FUNC; }
func_name()605   const char *func_name() const { return "not"; }
precedence()606   enum precedence precedence() const { return NEG_PRECEDENCE; }
607   Item *neg_transformer(THD *thd);
608   bool fix_fields(THD *, Item **);
609   virtual void print(String *str, enum_query_type query_type);
get_copy(THD * thd)610   Item *get_copy(THD *thd)
611   { return get_item_copy<Item_func_not>(thd, this); }
612 };
613 
614 class Item_maxmin_subselect;
615 
616 /*
617   trigcond<param>(arg) ::= param? arg : TRUE
618 
619   The class Item_func_trig_cond is used for guarded predicates
620   which are employed only for internal purposes.
621   A guarded predicate is an object consisting of an a regular or
622   a guarded predicate P and a pointer to a boolean guard variable g.
623   A guarded predicate P/g is evaluated to true if the value of the
624   guard g is false, otherwise it is evaluated to the same value that
625   the predicate P: val(P/g)= g ? val(P):true.
626   Guarded predicates allow us to include predicates into a conjunction
627   conditionally. Currently they are utilized for pushed down predicates
628   in queries with outer join operations.
629 
630   In the future, probably, it makes sense to extend this class to
631   the objects consisting of three elements: a predicate P, a pointer
632   to a variable g and a firing value s with following evaluation
633   rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
634   one item for the objects of the form P/g1/g2...
635 
636   Objects of this class are built only for query execution after
637   the execution plan has been already selected. That's why this
638   class needs only val_int out of generic methods.
639 
640   Current uses of Item_func_trig_cond objects:
641    - To wrap selection conditions when executing outer joins
642    - To wrap condition that is pushed down into subquery
643 */
644 
645 class Item_func_trig_cond: public Item_bool_func
646 {
647   bool *trig_var;
648 public:
Item_func_trig_cond(THD * thd,Item * a,bool * f)649   Item_func_trig_cond(THD *thd, Item *a, bool *f): Item_bool_func(thd, a)
650   { trig_var= f; }
val_int()651   longlong val_int() { return *trig_var ? args[0]->val_int() : 1; }
functype()652   enum Functype functype() const { return TRIG_COND_FUNC; };
func_name()653   const char *func_name() const { return "trigcond"; };
const_item()654   bool const_item() const { return FALSE; }
get_trig_var()655   bool *get_trig_var() { return trig_var; }
656   void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
657                       uint *and_level, table_map usable_tables,
658                       SARGABLE_PARAM **sargables);
get_copy(THD * thd)659   Item *get_copy(THD *thd)
660   { return get_item_copy<Item_func_trig_cond>(thd, this); }
661 };
662 
663 class Item_func_not_all :public Item_func_not
664 {
665   /* allow to check presence of values in max/min optimization */
666   Item_sum_min_max *test_sum_item;
667   Item_maxmin_subselect *test_sub_item;
668 
669 public:
670   bool show;
671 
Item_func_not_all(THD * thd,Item * a)672   Item_func_not_all(THD *thd, Item *a):
673     Item_func_not(thd, a), test_sum_item(0), test_sub_item(0), show(0)
674     {}
not_null_tables()675   table_map not_null_tables() const { return 0; }
676   longlong val_int();
functype()677   enum Functype functype() const { return NOT_ALL_FUNC; }
func_name()678   const char *func_name() const { return "<not>"; }
fix_fields(THD * thd,Item ** ref)679   bool fix_fields(THD *thd, Item **ref)
680     {return Item_func::fix_fields(thd, ref);}
681   virtual void print(String *str, enum_query_type query_type);
set_sum_test(Item_sum_min_max * item)682   void set_sum_test(Item_sum_min_max *item) { test_sum_item= item; test_sub_item= 0; };
set_sub_test(Item_maxmin_subselect * item)683   void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; test_sum_item= 0;};
684   bool empty_underlying_subquery();
685   Item *neg_transformer(THD *thd);
686 };
687 
688 
689 class Item_func_nop_all :public Item_func_not_all
690 {
691 public:
692 
Item_func_nop_all(THD * thd,Item * a)693   Item_func_nop_all(THD *thd, Item *a): Item_func_not_all(thd, a) {}
694   longlong val_int();
func_name()695   const char *func_name() const { return "<nop>"; }
696   Item *neg_transformer(THD *thd);
get_copy(THD * thd)697   Item *get_copy(THD *thd)
698   { return get_item_copy<Item_func_nop_all>(thd, this); }
699 };
700 
701 
702 class Item_func_eq :public Item_bool_rowready_func2
703 {
704   bool abort_on_null;
705 public:
Item_func_eq(THD * thd,Item * a,Item * b)706   Item_func_eq(THD *thd, Item *a, Item *b):
707     Item_bool_rowready_func2(thd, a, b),
708     abort_on_null(false), in_equality_no(UINT_MAX)
709   {}
710   longlong val_int();
functype()711   enum Functype functype() const { return EQ_FUNC; }
rev_functype()712   enum Functype rev_functype() const { return EQ_FUNC; }
eq_cmp_result()713   cond_result eq_cmp_result() const { return COND_TRUE; }
func_name()714   const char *func_name() const { return "="; }
top_level_item()715   void top_level_item() { abort_on_null= true; }
716   Item *negated_item(THD *thd);
717   COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
718                           bool link_item_fields,
719                           COND_EQUAL **cond_equal_ref);
add_key_fields(JOIN * join,KEY_FIELD ** key_fields,uint * and_level,table_map usable_tables,SARGABLE_PARAM ** sargables)720   void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
721                       uint *and_level, table_map usable_tables,
722                       SARGABLE_PARAM **sargables)
723   {
724     return add_key_fields_optimize_op(join, key_fields, and_level,
725                                       usable_tables, sargables, true);
726   }
727   bool check_equality(THD *thd, COND_EQUAL *cond, List<Item> *eq_list);
728   /*
729     - If this equality is created from the subquery's IN-equality:
730       number of the item it was created from, e.g. for
731        (a,b) IN (SELECT c,d ...)  a=c will have in_equality_no=0,
732        and b=d will have in_equality_no=1.
733     - Otherwise, UINT_MAX
734   */
735   uint in_equality_no;
exists2in_reserved_items()736   virtual uint exists2in_reserved_items() { return 1; };
737   friend class  Arg_comparator;
get_copy(THD * thd)738   Item *get_copy(THD *thd)
739   { return get_item_copy<Item_func_eq>(thd, this); }
740 };
741 
742 class Item_func_equal :public Item_bool_rowready_func2
743 {
744 public:
Item_func_equal(THD * thd,Item * a,Item * b)745   Item_func_equal(THD *thd, Item *a, Item *b):
746     Item_bool_rowready_func2(thd, a, b) {}
747   longlong val_int();
748   bool fix_length_and_dec();
not_null_tables()749   table_map not_null_tables() const { return 0; }
functype()750   enum Functype functype() const { return EQUAL_FUNC; }
rev_functype()751   enum Functype rev_functype() const { return EQUAL_FUNC; }
eq_cmp_result()752   cond_result eq_cmp_result() const { return COND_TRUE; }
func_name()753   const char *func_name() const { return "<=>"; }
neg_transformer(THD * thd)754   Item *neg_transformer(THD *thd) { return 0; }
add_key_fields(JOIN * join,KEY_FIELD ** key_fields,uint * and_level,table_map usable_tables,SARGABLE_PARAM ** sargables)755   void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
756                       uint *and_level, table_map usable_tables,
757                       SARGABLE_PARAM **sargables)
758   {
759     return add_key_fields_optimize_op(join, key_fields, and_level,
760                                       usable_tables, sargables, true);
761   }
get_copy(THD * thd)762   Item *get_copy(THD *thd)
763   { return get_item_copy<Item_func_equal>(thd, this); }
764 };
765 
766 
767 class Item_func_ge :public Item_bool_rowready_func2
768 {
769 public:
Item_func_ge(THD * thd,Item * a,Item * b)770   Item_func_ge(THD *thd, Item *a, Item *b):
771     Item_bool_rowready_func2(thd, a, b) {};
772   longlong val_int();
functype()773   enum Functype functype() const { return GE_FUNC; }
rev_functype()774   enum Functype rev_functype() const { return LE_FUNC; }
eq_cmp_result()775   cond_result eq_cmp_result() const { return COND_TRUE; }
func_name()776   const char *func_name() const { return ">="; }
777   Item *negated_item(THD *thd);
get_copy(THD * thd)778   Item *get_copy(THD *thd)
779   { return get_item_copy<Item_func_ge>(thd, this); }
780 };
781 
782 
783 class Item_func_gt :public Item_bool_rowready_func2
784 {
785 public:
Item_func_gt(THD * thd,Item * a,Item * b)786   Item_func_gt(THD *thd, Item *a, Item *b):
787     Item_bool_rowready_func2(thd, a, b) {};
788   longlong val_int();
functype()789   enum Functype functype() const { return GT_FUNC; }
rev_functype()790   enum Functype rev_functype() const { return LT_FUNC; }
eq_cmp_result()791   cond_result eq_cmp_result() const { return COND_FALSE; }
func_name()792   const char *func_name() const { return ">"; }
793   Item *negated_item(THD *thd);
get_copy(THD * thd)794   Item *get_copy(THD *thd)
795   { return get_item_copy<Item_func_gt>(thd, this); }
796 };
797 
798 
799 class Item_func_le :public Item_bool_rowready_func2
800 {
801 public:
Item_func_le(THD * thd,Item * a,Item * b)802   Item_func_le(THD *thd, Item *a, Item *b):
803     Item_bool_rowready_func2(thd, a, b) {};
804   longlong val_int();
functype()805   enum Functype functype() const { return LE_FUNC; }
rev_functype()806   enum Functype rev_functype() const { return GE_FUNC; }
eq_cmp_result()807   cond_result eq_cmp_result() const { return COND_TRUE; }
func_name()808   const char *func_name() const { return "<="; }
809   Item *negated_item(THD *thd);
get_copy(THD * thd)810   Item *get_copy(THD *thd)
811   { return get_item_copy<Item_func_le>(thd, this); }
812 };
813 
814 
815 class Item_func_lt :public Item_bool_rowready_func2
816 {
817 public:
Item_func_lt(THD * thd,Item * a,Item * b)818   Item_func_lt(THD *thd, Item *a, Item *b):
819     Item_bool_rowready_func2(thd, a, b) {}
820   longlong val_int();
functype()821   enum Functype functype() const { return LT_FUNC; }
rev_functype()822   enum Functype rev_functype() const { return GT_FUNC; }
eq_cmp_result()823   cond_result eq_cmp_result() const { return COND_FALSE; }
func_name()824   const char *func_name() const { return "<"; }
825   Item *negated_item(THD *thd);
get_copy(THD * thd)826   Item *get_copy(THD *thd)
827   { return get_item_copy<Item_func_lt>(thd, this); }
828 };
829 
830 
831 class Item_func_ne :public Item_bool_rowready_func2
832 {
833 protected:
834   SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
835                              Field *field, Item *value);
836 public:
Item_func_ne(THD * thd,Item * a,Item * b)837   Item_func_ne(THD *thd, Item *a, Item *b):
838     Item_bool_rowready_func2(thd, a, b) {}
839   longlong val_int();
functype()840   enum Functype functype() const { return NE_FUNC; }
rev_functype()841   enum Functype rev_functype() const { return NE_FUNC; }
eq_cmp_result()842   cond_result eq_cmp_result() const { return COND_FALSE; }
func_name()843   const char *func_name() const { return "<>"; }
844   Item *negated_item(THD *thd);
845   void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
846                       table_map usable_tables, SARGABLE_PARAM **sargables);
get_copy(THD * thd)847   Item *get_copy(THD *thd)
848   { return get_item_copy<Item_func_ne>(thd, this); }
849 };
850 
851 
852 /*
853   The class Item_func_opt_neg is defined to factor out the functionality
854   common for the classes Item_func_between and Item_func_in. The objects
855   of these classes can express predicates or there negations.
856   The alternative approach would be to create pairs Item_func_between,
857   Item_func_notbetween and Item_func_in, Item_func_notin.
858 
859 */
860 
861 class Item_func_opt_neg :public Item_bool_func
862 {
863 protected:
864   /*
865     The data type handler that will be used for comparison.
866     Data type handlers of all arguments are mixed to here.
867   */
868   Type_handler_hybrid_field_type m_comparator;
869   /*
870     The collation that will be used for comparison in case
871     when m_compare_type is STRING_RESULT.
872   */
873   DTCollation cmp_collation;
874 public:
875   bool negated;     /* <=> the item represents NOT <func> */
876   bool pred_level;  /* <=> [NOT] <func> is used on a predicate level */
877 public:
Item_func_opt_neg(THD * thd,Item * a,Item * b,Item * c)878   Item_func_opt_neg(THD *thd, Item *a, Item *b, Item *c):
879     Item_bool_func(thd, a, b, c), negated(0), pred_level(0) {}
Item_func_opt_neg(THD * thd,List<Item> & list)880   Item_func_opt_neg(THD *thd, List<Item> &list):
881     Item_bool_func(thd, list), negated(0), pred_level(0) {}
882 public:
top_level_item()883   inline void top_level_item() { pred_level= 1; }
is_top_level_item()884   bool is_top_level_item() const { return pred_level; }
neg_transformer(THD * thd)885   Item *neg_transformer(THD *thd)
886   {
887     negated= !negated;
888     return this;
889   }
890   bool eq(const Item *item, bool binary_cmp) const;
compare_collation()891   CHARSET_INFO *compare_collation() const { return cmp_collation.collation; }
892   Item* propagate_equal_fields(THD *, const Context &, COND_EQUAL *) = 0;
893 };
894 
895 
896 class Item_func_between :public Item_func_opt_neg
897 {
898 protected:
899   SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
900                              Field *field, Item *value);
901   bool val_int_cmp_int_finalize(longlong value, longlong a, longlong b);
902 public:
903   String value0,value1,value2;
Item_func_between(THD * thd,Item * a,Item * b,Item * c)904   Item_func_between(THD *thd, Item *a, Item *b, Item *c):
905     Item_func_opt_neg(thd, a, b, c) { }
val_int()906   longlong val_int()
907   {
908     DBUG_ASSERT(fixed);
909     return m_comparator.type_handler()->Item_func_between_val_int(this);
910   }
functype()911   enum Functype functype() const   { return BETWEEN; }
func_name()912   const char *func_name() const { return "between"; }
precedence()913   enum precedence precedence() const { return BETWEEN_PRECEDENCE; }
914   bool fix_length_and_dec();
fix_length_and_dec_string(THD *)915   bool fix_length_and_dec_string(THD *)
916   {
917     return agg_arg_charsets_for_comparison(cmp_collation, args, 3);
918   }
919   bool fix_length_and_dec_temporal(THD *);
920   bool fix_length_and_dec_numeric(THD *);
921   virtual void print(String *str, enum_query_type query_type);
922   bool eval_not_null_tables(void *opt_arg);
923   void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
924   bool count_sargable_conds(void *arg);
925   void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
926                       uint *and_level, table_map usable_tables,
927                       SARGABLE_PARAM **sargables);
928   SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
propagate_equal_fields(THD * thd,const Context & ctx,COND_EQUAL * cond)929   Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
930   {
931     Item_args::propagate_equal_fields(thd,
932                                       Context(ANY_SUBST,
933                                               m_comparator.type_handler(),
934                                               compare_collation()),
935                                       cond);
936     return this;
937   }
get_copy(THD * thd)938   Item *get_copy(THD *thd)
939   { return get_item_copy<Item_func_between>(thd, this); }
940 
941   longlong val_int_cmp_string();
942   longlong val_int_cmp_datetime();
943   longlong val_int_cmp_time();
944   longlong val_int_cmp_native();
945   longlong val_int_cmp_int();
946   longlong val_int_cmp_real();
947   longlong val_int_cmp_decimal();
948 };
949 
950 
951 class Item_func_strcmp :public Item_long_func
952 {
check_arguments()953   bool check_arguments() const
954   { return check_argument_types_can_return_str(0, 2); }
955   String value1, value2;
956   DTCollation cmp_collation;
957 public:
Item_func_strcmp(THD * thd,Item * a,Item * b)958   Item_func_strcmp(THD *thd, Item *a, Item *b):
959     Item_long_func(thd, a, b) {}
960   longlong val_int();
decimal_precision()961   uint decimal_precision() const { return 1; }
func_name()962   const char *func_name() const { return "strcmp"; }
fix_length_and_dec()963   bool fix_length_and_dec()
964   {
965     if (agg_arg_charsets_for_comparison(cmp_collation, args, 2))
966       return TRUE;
967     fix_char_length(2); // returns "1" or "0" or "-1"
968     return FALSE;
969   }
get_copy(THD * thd)970   Item *get_copy(THD *thd)
971   { return get_item_copy<Item_func_strcmp>(thd, this); }
972 };
973 
974 
975 struct interval_range
976 {
977   Item_result type;
978   double dbl;
979   my_decimal dec;
980 };
981 
982 class Item_func_interval :public Item_long_func
983 {
984   Item_row *row;
985   bool use_decimal_comparison;
986   interval_range *intervals;
check_arguments()987   bool check_arguments() const
988   {
989     return check_argument_types_like_args0();
990   }
991 public:
Item_func_interval(THD * thd,Item_row * a)992   Item_func_interval(THD *thd, Item_row *a):
993     Item_long_func(thd, a), row(a), intervals(0)
994   { }
995   bool fix_fields(THD *, Item **);
996   longlong val_int();
997   bool fix_length_and_dec();
func_name()998   const char *func_name() const { return "interval"; }
decimal_precision()999   uint decimal_precision() const { return 2; }
print(String * str,enum_query_type query_type)1000   void print(String *str, enum_query_type query_type)
1001   {
1002     str->append(func_name());
1003     print_args(str, 0, query_type);
1004   }
get_copy(THD * thd)1005   Item *get_copy(THD *thd)
1006   { return get_item_copy<Item_func_interval>(thd, this); }
1007 };
1008 
1009 
1010 class Item_func_coalesce :public Item_func_case_expression
1011 {
1012 public:
Item_func_coalesce(THD * thd,Item * a,Item * b)1013   Item_func_coalesce(THD *thd, Item *a, Item *b):
1014     Item_func_case_expression(thd, a, b) {}
Item_func_coalesce(THD * thd,List<Item> & list)1015   Item_func_coalesce(THD *thd, List<Item> &list):
1016     Item_func_case_expression(thd, list) {}
1017   double real_op();
1018   longlong int_op();
1019   String *str_op(String *);
1020   my_decimal *decimal_op(my_decimal *);
1021   bool date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
1022   bool time_op(THD *thd, MYSQL_TIME *ltime);
1023   bool native_op(THD *thd, Native *to);
fix_length_and_dec()1024   bool fix_length_and_dec()
1025   {
1026     if (aggregate_for_result(func_name(), args, arg_count, true))
1027       return TRUE;
1028     fix_attributes(args, arg_count);
1029     return FALSE;
1030   }
func_name()1031   const char *func_name() const { return "coalesce"; }
not_null_tables()1032   table_map not_null_tables() const { return 0; }
get_copy(THD * thd)1033   Item *get_copy(THD *thd)
1034   { return get_item_copy<Item_func_coalesce>(thd, this); }
1035 };
1036 
1037 
1038 /*
1039   Case abbreviations that aggregate its result field type by two arguments:
1040     IFNULL(arg1, arg2)
1041     IF(switch, arg1, arg2)
1042     NVL2(switch, arg1, arg2)
1043 */
1044 class Item_func_case_abbreviation2 :public Item_func_case_expression
1045 {
1046 protected:
fix_length_and_dec2(Item ** items)1047   bool fix_length_and_dec2(Item **items)
1048   {
1049     if (aggregate_for_result(func_name(), items, 2, true))
1050       return TRUE;
1051     fix_attributes(items, 2);
1052     return FALSE;
1053   }
1054 
cache_type_info(const Item * source,bool maybe_null_arg)1055   void cache_type_info(const Item *source, bool maybe_null_arg)
1056   {
1057     Type_std_attributes::set(source);
1058     set_handler(source->type_handler());
1059     maybe_null= maybe_null_arg;
1060   }
1061 
fix_length_and_dec2_eliminate_null(Item ** items)1062   bool fix_length_and_dec2_eliminate_null(Item **items)
1063   {
1064     // Let IF(cond, expr, NULL) and IF(cond, NULL, expr) inherit type from expr.
1065     if (items[0]->type() == NULL_ITEM)
1066     {
1067       cache_type_info(items[1], true);
1068       // If both arguments are NULL, make resulting type BINARY(0).
1069       if (items[1]->type() == NULL_ITEM)
1070         set_handler(&type_handler_string);
1071     }
1072     else if (items[1]->type() == NULL_ITEM)
1073     {
1074       cache_type_info(items[0], true);
1075     }
1076     else
1077     {
1078       if (fix_length_and_dec2(items))
1079         return TRUE;
1080     }
1081     return FALSE;
1082   }
1083 
1084 public:
Item_func_case_abbreviation2(THD * thd,Item * a,Item * b)1085   Item_func_case_abbreviation2(THD *thd, Item *a, Item *b):
1086     Item_func_case_expression(thd, a, b) { }
Item_func_case_abbreviation2(THD * thd,Item * a,Item * b,Item * c)1087   Item_func_case_abbreviation2(THD *thd, Item *a, Item *b, Item *c):
1088     Item_func_case_expression(thd, a, b, c) { }
1089 };
1090 
1091 
1092 class Item_func_ifnull :public Item_func_case_abbreviation2
1093 {
1094 public:
Item_func_ifnull(THD * thd,Item * a,Item * b)1095   Item_func_ifnull(THD *thd, Item *a, Item *b):
1096     Item_func_case_abbreviation2(thd, a, b) {}
1097   double real_op();
1098   longlong int_op();
1099   String *str_op(String *str);
1100   my_decimal *decimal_op(my_decimal *);
1101   bool date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
1102   bool time_op(THD *thd, MYSQL_TIME *ltime);
1103   bool native_op(THD *thd, Native *to);
fix_length_and_dec()1104   bool fix_length_and_dec()
1105   {
1106     if (Item_func_case_abbreviation2::fix_length_and_dec2(args))
1107       return TRUE;
1108     maybe_null= args[1]->maybe_null;
1109     return FALSE;
1110   }
func_name()1111   const char *func_name() const { return "ifnull"; }
1112 
not_null_tables()1113   table_map not_null_tables() const { return 0; }
get_copy(THD * thd)1114   Item *get_copy(THD *thd)
1115   { return get_item_copy<Item_func_ifnull>(thd, this); }
1116 };
1117 
1118 
1119 /**
1120   Case abbreviations that have a switch argument and
1121   two return arguments to choose from. Returns the value
1122   of either of the two return arguments depending on the switch argument value.
1123 
1124   IF(switch, arg1, arg2)
1125   NVL(switch, arg1, arg2)
1126 */
1127 class Item_func_case_abbreviation2_switch: public Item_func_case_abbreviation2
1128 {
1129 protected:
1130   virtual Item *find_item() const= 0;
1131 
1132 public:
Item_func_case_abbreviation2_switch(THD * thd,Item * a,Item * b,Item * c)1133   Item_func_case_abbreviation2_switch(THD *thd, Item *a, Item *b, Item *c)
1134     :Item_func_case_abbreviation2(thd, a, b, c)
1135   { }
1136 
date_op(THD * thd,MYSQL_TIME * ltime,date_mode_t fuzzydate)1137   bool date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
1138   {
1139     Datetime_truncation_not_needed dt(thd, find_item(), fuzzydate);
1140     return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
1141   }
time_op(THD * thd,MYSQL_TIME * ltime)1142   bool time_op(THD *thd, MYSQL_TIME *ltime)
1143   {
1144     return (null_value= Time(find_item()).copy_to_mysql_time(ltime));
1145   }
int_op()1146   longlong int_op()
1147   {
1148     return val_int_from_item(find_item());
1149   }
real_op()1150   double real_op()
1151   {
1152     return val_real_from_item(find_item());
1153   }
decimal_op(my_decimal * decimal_value)1154   my_decimal *decimal_op(my_decimal *decimal_value)
1155   {
1156     return val_decimal_from_item(find_item(), decimal_value);
1157   }
str_op(String * str)1158   String *str_op(String *str)
1159   {
1160     return val_str_from_item(find_item(), str);
1161   }
native_op(THD * thd,Native * to)1162   bool native_op(THD *thd, Native *to)
1163   {
1164     return val_native_with_conversion_from_item(thd, find_item(), to,
1165                                                 type_handler());
1166   }
1167 };
1168 
1169 
1170 class Item_func_if :public Item_func_case_abbreviation2_switch
1171 {
1172 protected:
find_item()1173   Item *find_item() const { return args[0]->val_bool() ? args[1] : args[2]; }
1174 
1175 public:
Item_func_if(THD * thd,Item * a,Item * b,Item * c)1176   Item_func_if(THD *thd, Item *a, Item *b, Item *c):
1177     Item_func_case_abbreviation2_switch(thd, a, b, c)
1178   {}
1179   bool fix_fields(THD *, Item **);
fix_length_and_dec()1180   bool fix_length_and_dec()
1181   {
1182     return fix_length_and_dec2_eliminate_null(args + 1);
1183   }
func_name()1184   const char *func_name() const { return "if"; }
1185   bool eval_not_null_tables(void *opt_arg);
1186   void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
get_copy(THD * thd)1187   Item *get_copy(THD *thd)
1188   { return get_item_copy<Item_func_if>(thd, this); }
1189 private:
1190   void cache_type_info(Item *source);
1191 };
1192 
1193 
1194 class Item_func_nvl2 :public Item_func_case_abbreviation2_switch
1195 {
1196 protected:
find_item()1197   Item *find_item() const { return args[0]->is_null() ? args[2] : args[1]; }
1198 
1199 public:
Item_func_nvl2(THD * thd,Item * a,Item * b,Item * c)1200   Item_func_nvl2(THD *thd, Item *a, Item *b, Item *c):
1201     Item_func_case_abbreviation2_switch(thd, a, b, c)
1202   {}
func_name()1203   const char *func_name() const { return "nvl2"; }
fix_length_and_dec()1204   bool fix_length_and_dec()
1205   {
1206     return fix_length_and_dec2_eliminate_null(args + 1);
1207   }
get_copy(THD * thd)1208   Item *get_copy(THD *thd)
1209   { return get_item_copy<Item_func_nvl2>(thd, this); }
1210 };
1211 
1212 
1213 class Item_func_nullif :public Item_func_case_expression
1214 {
1215   Arg_comparator cmp;
1216   /*
1217     NULLIF(a,b) is a short for:
1218       CASE WHEN a=b THEN NULL ELSE a END
1219 
1220     The left "a" is for comparison purposes.
1221     The right "a" is for return value purposes.
1222     These are two different "a" and they can be replaced to different items.
1223 
1224     The left "a" is in a comparison and can be replaced by:
1225     - Item_func::convert_const_compared_to_int_field()
1226     - agg_item_set_converter() in set_cmp_func()
1227     - cache_converted_constant() in set_cmp_func()
1228 
1229     Both "a"s are subject to equal fields propagation and can be replaced by:
1230     - Item_field::propagate_equal_fields(ANY_SUBST) for the left "a"
1231     - Item_field::propagate_equal_fields(IDENTITY_SUBST) for the right "a"
1232   */
1233   Item_cache *m_cache;
1234   int compare();
reset_first_arg_if_needed()1235   void reset_first_arg_if_needed()
1236   {
1237     if (arg_count == 3 && args[0] != args[2])
1238       args[0]= args[2];
1239   }
1240   Item *m_arg0;
1241 public:
1242   /*
1243     Here we pass three arguments to the parent constructor, as NULLIF
1244     is a three-argument function, it needs two copies of the first argument
1245     (see above). But fix_fields() will be confused if we try to prepare the
1246     same Item twice (if args[0]==args[2]), so we hide the third argument
1247     (decrementing arg_count) and copy args[2]=args[0] again after fix_fields().
1248     See also Item_func_nullif::fix_length_and_dec().
1249   */
Item_func_nullif(THD * thd,Item * a,Item * b)1250   Item_func_nullif(THD *thd, Item *a, Item *b):
1251     Item_func_case_expression(thd, a, b, a),
1252     m_cache(NULL),
1253     m_arg0(NULL)
1254   { arg_count--; }
cleanup()1255   void cleanup()
1256   {
1257     Item_func_hybrid_field_type::cleanup();
1258     arg_count= 2; // See the comment to the constructor
1259   }
1260   bool date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
1261   bool time_op(THD *thd, MYSQL_TIME *ltime);
1262   double real_op();
1263   longlong int_op();
1264   String *str_op(String *str);
1265   my_decimal *decimal_op(my_decimal *);
1266   bool native_op(THD *thd, Native *to);
1267   bool fix_length_and_dec();
1268   bool walk(Item_processor processor, bool walk_subquery, void *arg);
func_name()1269   const char *func_name() const { return "nullif"; }
1270   void print(String *str, enum_query_type query_type);
1271   void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
1272                       List<Item> &fields, uint flags);
1273   void update_used_tables();
not_null_tables()1274   table_map not_null_tables() const { return 0; }
1275   bool is_null();
propagate_equal_fields(THD * thd,const Context & ctx,COND_EQUAL * cond)1276   Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
1277   {
1278     Context cmpctx(ANY_SUBST, cmp.compare_type_handler(),
1279                               cmp.compare_collation());
1280     const Item *old0= args[0];
1281     args[0]->propagate_equal_fields_and_change_item_tree(thd, cmpctx,
1282                                                          cond, &args[0]);
1283     args[1]->propagate_equal_fields_and_change_item_tree(thd, cmpctx,
1284                                                          cond, &args[1]);
1285     /*
1286       MDEV-9712 Performance degradation of nested NULLIF
1287       ANY_SUBST is more relaxed than IDENTITY_SUBST.
1288       If ANY_SUBST did not change args[0],
1289       then we can skip propagation for args[2].
1290     */
1291     if (old0 != args[0])
1292       args[2]->propagate_equal_fields_and_change_item_tree(thd,
1293                                                            Context_identity(),
1294                                                            cond, &args[2]);
1295     return this;
1296   }
get_copy(THD * thd)1297   Item *get_copy(THD *thd)
1298   { return get_item_copy<Item_func_nullif>(thd, this); }
derived_field_transformer_for_having(THD * thd,uchar * arg)1299   Item *derived_field_transformer_for_having(THD *thd, uchar *arg)
1300   { reset_first_arg_if_needed(); return this; }
derived_field_transformer_for_where(THD * thd,uchar * arg)1301   Item *derived_field_transformer_for_where(THD *thd, uchar *arg)
1302   { reset_first_arg_if_needed(); return this; }
grouping_field_transformer_for_where(THD * thd,uchar * arg)1303   Item *grouping_field_transformer_for_where(THD *thd, uchar *arg)
1304   { reset_first_arg_if_needed(); return this; }
in_subq_field_transformer_for_where(THD * thd,uchar * arg)1305   Item *in_subq_field_transformer_for_where(THD *thd, uchar *arg)
1306   { reset_first_arg_if_needed(); return this; }
in_subq_field_transformer_for_having(THD * thd,uchar * arg)1307   Item *in_subq_field_transformer_for_having(THD *thd, uchar *arg)
1308   { reset_first_arg_if_needed(); return this; }
1309 };
1310 
1311 
1312 /* Functions to handle the optimized IN */
1313 
1314 
1315 /* A vector of values of some type  */
1316 
1317 class in_vector :public Sql_alloc
1318 {
1319 public:
1320   char *base;
1321   uint size;
1322   qsort2_cmp compare;
1323   CHARSET_INFO *collation;
1324   uint count;
1325   uint used_count;
in_vector()1326   in_vector() {}
in_vector(THD * thd,uint elements,uint element_length,qsort2_cmp cmp_func,CHARSET_INFO * cmp_coll)1327   in_vector(THD *thd, uint elements, uint element_length, qsort2_cmp cmp_func,
1328   	    CHARSET_INFO *cmp_coll)
1329     :base((char*) thd_calloc(thd, elements * element_length)),
1330      size(element_length), compare(cmp_func), collation(cmp_coll),
1331      count(elements), used_count(elements) {}
~in_vector()1332   virtual ~in_vector() {}
1333   virtual void set(uint pos,Item *item)=0;
1334   virtual uchar *get_value(Item *item)=0;
sort()1335   void sort()
1336   {
1337     my_qsort2(base,used_count,size,compare,(void*)collation);
1338   }
1339   bool find(Item *item);
1340 
1341   /*
1342     Create an instance of Item_{type} (e.g. Item_decimal) constant object
1343     which type allows it to hold an element of this vector without any
1344     conversions.
1345     The purpose of this function is to be able to get elements of this
1346     vector in form of Item_xxx constants without creating Item_xxx object
1347     for every array element you get (i.e. this implements "FlyWeight" pattern)
1348   */
create_item(THD * thd)1349   virtual Item* create_item(THD *thd) { return NULL; }
1350 
1351   /*
1352     Store the value at position #pos into provided item object
1353     SYNOPSIS
1354       value_to_item()
1355         pos   Index of value to store
1356         item  Constant item to store value into. The item must be of the same
1357               type that create_item() returns.
1358   */
value_to_item(uint pos,Item * item)1359   virtual void value_to_item(uint pos, Item *item) { }
1360 
1361   /* Compare values number pos1 and pos2 for equality */
compare_elems(uint pos1,uint pos2)1362   bool compare_elems(uint pos1, uint pos2)
1363   {
1364     return MY_TEST(compare(collation, base + pos1 * size, base + pos2 * size));
1365   }
1366   virtual const Type_handler *type_handler() const= 0;
1367 };
1368 
1369 class in_string :public in_vector
1370 {
1371   char buff[STRING_BUFFER_USUAL_SIZE];
1372   String tmp;
1373   class Item_string_for_in_vector: public Item_string
1374   {
1375   public:
Item_string_for_in_vector(THD * thd,CHARSET_INFO * cs)1376     Item_string_for_in_vector(THD *thd, CHARSET_INFO *cs):
1377       Item_string(thd, cs)
1378     { }
set_value(const String * str)1379     void set_value(const String *str)
1380     {
1381       str_value= *str;
1382       collation.set(str->charset());
1383     }
1384   };
1385 public:
1386   in_string(THD *thd, uint elements, qsort2_cmp cmp_func, CHARSET_INFO *cs);
1387   ~in_string();
1388   void set(uint pos,Item *item);
1389   uchar *get_value(Item *item);
1390   Item* create_item(THD *thd);
value_to_item(uint pos,Item * item)1391   void value_to_item(uint pos, Item *item)
1392   {
1393     String *str=((String*) base)+pos;
1394     Item_string_for_in_vector *to= (Item_string_for_in_vector*) item;
1395     to->set_value(str);
1396   }
type_handler()1397   const Type_handler *type_handler() const { return &type_handler_varchar; }
1398 };
1399 
1400 class in_longlong :public in_vector
1401 {
1402 protected:
1403   /*
1404     Here we declare a temporary variable (tmp) of the same type as the
1405     elements of this vector. tmp is used in finding if a given value is in
1406     the list.
1407   */
1408   struct packed_longlong
1409   {
1410     longlong val;
1411     longlong unsigned_flag;  // Use longlong, not bool, to preserve alignment
1412   } tmp;
1413 public:
1414   in_longlong(THD *thd, uint elements);
1415   void set(uint pos,Item *item);
1416   uchar *get_value(Item *item);
1417   Item* create_item(THD *thd);
value_to_item(uint pos,Item * item)1418   void value_to_item(uint pos, Item *item)
1419   {
1420     ((Item_int*) item)->value= ((packed_longlong*) base)[pos].val;
1421     ((Item_int*) item)->unsigned_flag= (bool)
1422       ((packed_longlong*) base)[pos].unsigned_flag;
1423   }
type_handler()1424   const Type_handler *type_handler() const { return &type_handler_longlong; }
1425 
1426   friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
1427 };
1428 
1429 
1430 class in_timestamp :public in_vector
1431 {
1432   Timestamp_or_zero_datetime tmp;
1433 public:
1434   in_timestamp(THD *thd, uint elements);
1435   void set(uint pos,Item *item);
1436   uchar *get_value(Item *item);
1437   Item* create_item(THD *thd);
1438   void value_to_item(uint pos, Item *item);
type_handler()1439   const Type_handler *type_handler() const { return &type_handler_timestamp2; }
1440 };
1441 
1442 
1443 /*
1444   Class to represent a vector of constant DATE/DATETIME values.
1445 */
1446 class in_temporal :public in_longlong
1447 {
1448 public:
1449   /* Cache for the left item. */
1450 
in_temporal(THD * thd,uint elements)1451   in_temporal(THD *thd, uint elements)
1452     :in_longlong(thd, elements) {};
1453   Item *create_item(THD *thd);
value_to_item(uint pos,Item * item)1454   void value_to_item(uint pos, Item *item)
1455   {
1456     packed_longlong *val= reinterpret_cast<packed_longlong*>(base)+pos;
1457     Item_datetime *dt= static_cast<Item_datetime*>(item);
1458     dt->set(val->val, type_handler()->mysql_timestamp_type());
1459   }
1460   friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
1461 };
1462 
1463 
1464 class in_datetime :public in_temporal
1465 {
1466 public:
in_datetime(THD * thd,uint elements)1467   in_datetime(THD *thd, uint elements)
1468    :in_temporal(thd, elements)
1469   {}
1470   void set(uint pos,Item *item);
1471   uchar *get_value(Item *item);
type_handler()1472   const Type_handler *type_handler() const { return &type_handler_datetime2; }
1473 };
1474 
1475 
1476 class in_time :public in_temporal
1477 {
1478 public:
in_time(THD * thd,uint elements)1479   in_time(THD *thd, uint elements)
1480    :in_temporal(thd, elements)
1481   {}
1482   void set(uint pos,Item *item);
1483   uchar *get_value(Item *item);
type_handler()1484   const Type_handler *type_handler() const { return &type_handler_time2; }
1485 };
1486 
1487 
1488 class in_double :public in_vector
1489 {
1490   double tmp;
1491 public:
1492   in_double(THD *thd, uint elements);
1493   void set(uint pos,Item *item);
1494   uchar *get_value(Item *item);
1495   Item *create_item(THD *thd);
value_to_item(uint pos,Item * item)1496   void value_to_item(uint pos, Item *item)
1497   {
1498     ((Item_float*)item)->value= ((double*) base)[pos];
1499   }
type_handler()1500   const Type_handler *type_handler() const { return &type_handler_double; }
1501 };
1502 
1503 
1504 class in_decimal :public in_vector
1505 {
1506   my_decimal val;
1507 public:
1508   in_decimal(THD *thd, uint elements);
1509   void set(uint pos, Item *item);
1510   uchar *get_value(Item *item);
1511   Item *create_item(THD *thd);
value_to_item(uint pos,Item * item)1512   void value_to_item(uint pos, Item *item)
1513   {
1514     my_decimal *dec= ((my_decimal *)base) + pos;
1515     Item_decimal *item_dec= (Item_decimal*)item;
1516     item_dec->set_decimal_value(dec);
1517   }
type_handler()1518   const Type_handler *type_handler() const { return &type_handler_newdecimal; }
1519 };
1520 
1521 
1522 /*
1523 ** Classes for easy comparing of non const items
1524 */
1525 
1526 class cmp_item :public Sql_alloc
1527 {
1528 public:
1529   CHARSET_INFO *cmp_charset;
cmp_item()1530   cmp_item() { cmp_charset= &my_charset_bin; }
~cmp_item()1531   virtual ~cmp_item() {}
1532   virtual void store_value(Item *item)= 0;
1533   /**
1534      @returns result (TRUE, FALSE or UNKNOWN) of
1535      "stored argument's value <> item's value"
1536   */
1537   virtual int cmp(Item *item)= 0;
1538   virtual int cmp_not_null(const Value *value)= 0;
1539   // for optimized IN with row
1540   virtual int compare(cmp_item *item)= 0;
1541   virtual cmp_item *make_same()= 0;
store_value_by_template(THD * thd,cmp_item * tmpl,Item * item)1542   virtual void store_value_by_template(THD *thd, cmp_item *tmpl, Item *item)
1543   {
1544     store_value(item);
1545   }
1546 };
1547 
1548 /// cmp_item which stores a scalar (i.e. non-ROW).
1549 class cmp_item_scalar : public cmp_item
1550 {
1551 protected:
1552   bool m_null_value;                            ///< If stored value is NULL
1553 };
1554 
1555 class cmp_item_string : public cmp_item_scalar
1556 {
1557 protected:
1558   String *value_res;
1559 public:
cmp_item_string()1560   cmp_item_string () {}
cmp_item_string(CHARSET_INFO * cs)1561   cmp_item_string (CHARSET_INFO *cs) { cmp_charset= cs; }
set_charset(CHARSET_INFO * cs)1562   void set_charset(CHARSET_INFO *cs) { cmp_charset= cs; }
1563   friend class cmp_item_sort_string;
1564   friend class cmp_item_sort_string_in_static;
1565 };
1566 
1567 class cmp_item_sort_string :public cmp_item_string
1568 {
1569 protected:
1570   char value_buff[STRING_BUFFER_USUAL_SIZE];
1571   String value;
1572 public:
cmp_item_sort_string()1573   cmp_item_sort_string():
1574     cmp_item_string() {}
cmp_item_sort_string(CHARSET_INFO * cs)1575   cmp_item_sort_string(CHARSET_INFO *cs):
1576     cmp_item_string(cs),
1577     value(value_buff, sizeof(value_buff), cs) {}
store_value(Item * item)1578   void store_value(Item *item)
1579   {
1580     value_res= item->val_str(&value);
1581     m_null_value= item->null_value;
1582     // Make sure to cache the result String inside "value"
1583     if (value_res && value_res != &value)
1584     {
1585       if (value.copy(*value_res))
1586         value.set("", 0, item->collation.collation);
1587       value_res= &value;
1588     }
1589   }
cmp_not_null(const Value * val)1590   int cmp_not_null(const Value *val)
1591   {
1592     DBUG_ASSERT(!val->is_null());
1593     DBUG_ASSERT(val->is_string());
1594     return sortcmp(value_res, &val->m_string, cmp_charset) != 0;
1595   }
cmp(Item * arg)1596   int cmp(Item *arg)
1597   {
1598     char buff[STRING_BUFFER_USUAL_SIZE];
1599     String tmp(buff, sizeof(buff), cmp_charset), *res= arg->val_str(&tmp);
1600     if (m_null_value || arg->null_value)
1601       return UNKNOWN;
1602     if (value_res && res)
1603       return sortcmp(value_res, res, cmp_charset) != 0;
1604     else if (!value_res && !res)
1605       return FALSE;
1606     else
1607       return TRUE;
1608   }
compare(cmp_item * ci)1609   int compare(cmp_item *ci)
1610   {
1611     cmp_item_string *l_cmp= (cmp_item_string *) ci;
1612     return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1613   }
1614   cmp_item *make_same();
set_charset(CHARSET_INFO * cs)1615   void set_charset(CHARSET_INFO *cs)
1616   {
1617     cmp_charset= cs;
1618     value.set_quick(value_buff, sizeof(value_buff), cs);
1619   }
1620 };
1621 
1622 class cmp_item_int : public cmp_item_scalar
1623 {
1624   longlong value;
1625 public:
cmp_item_int()1626   cmp_item_int() {}                           /* Remove gcc warning */
store_value(Item * item)1627   void store_value(Item *item)
1628   {
1629     value= item->val_int();
1630     m_null_value= item->null_value;
1631   }
cmp_not_null(const Value * val)1632   int cmp_not_null(const Value *val)
1633   {
1634     DBUG_ASSERT(!val->is_null());
1635     DBUG_ASSERT(val->is_longlong());
1636     return value != val->value.m_longlong;
1637   }
cmp(Item * arg)1638   int cmp(Item *arg)
1639   {
1640     const bool rc= value != arg->val_int();
1641     return (m_null_value || arg->null_value) ? UNKNOWN : rc;
1642   }
compare(cmp_item * ci)1643   int compare(cmp_item *ci)
1644   {
1645     cmp_item_int *l_cmp= (cmp_item_int *)ci;
1646     return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
1647   }
1648   cmp_item *make_same();
1649 };
1650 
1651 /*
1652   Compare items in the DATETIME context.
1653 */
1654 class cmp_item_temporal: public cmp_item_scalar
1655 {
1656 protected:
1657   longlong value;
1658 public:
cmp_item_temporal()1659   cmp_item_temporal() {}
1660   int compare(cmp_item *ci);
1661 };
1662 
1663 
1664 class cmp_item_datetime: public cmp_item_temporal
1665 {
1666 public:
cmp_item_datetime()1667   cmp_item_datetime()
1668    :cmp_item_temporal()
1669   { }
store_value(Item * item)1670   void store_value(Item *item)
1671   {
1672     value= item->val_datetime_packed(current_thd);
1673     m_null_value= item->null_value;
1674   }
1675   int cmp_not_null(const Value *val);
1676   int cmp(Item *arg);
1677   cmp_item *make_same();
1678 };
1679 
1680 
1681 class cmp_item_time: public cmp_item_temporal
1682 {
1683 public:
cmp_item_time()1684   cmp_item_time()
1685    :cmp_item_temporal()
1686   { }
store_value(Item * item)1687   void store_value(Item *item)
1688   {
1689     value= item->val_time_packed(current_thd);
1690     m_null_value= item->null_value;
1691   }
1692   int cmp_not_null(const Value *val);
1693   int cmp(Item *arg);
1694   cmp_item *make_same();
1695 };
1696 
1697 
1698 class cmp_item_timestamp: public cmp_item_scalar
1699 {
1700   Timestamp_or_zero_datetime_native m_native;
1701 public:
cmp_item_timestamp()1702   cmp_item_timestamp() :cmp_item_scalar() { }
1703   void store_value(Item *item);
1704   int cmp_not_null(const Value *val);
1705   int cmp(Item *arg);
1706   int compare(cmp_item *ci);
1707   cmp_item *make_same();
1708 };
1709 
1710 
1711 class cmp_item_real : public cmp_item_scalar
1712 {
1713   double value;
1714 public:
cmp_item_real()1715   cmp_item_real() {}                          /* Remove gcc warning */
store_value(Item * item)1716   void store_value(Item *item)
1717   {
1718     value= item->val_real();
1719     m_null_value= item->null_value;
1720   }
cmp_not_null(const Value * val)1721   int cmp_not_null(const Value *val)
1722   {
1723     DBUG_ASSERT(!val->is_null());
1724     DBUG_ASSERT(val->is_double());
1725     return value != val->value.m_double;
1726   }
cmp(Item * arg)1727   int cmp(Item *arg)
1728   {
1729     const bool rc= value != arg->val_real();
1730     return (m_null_value || arg->null_value) ? UNKNOWN : rc;
1731   }
compare(cmp_item * ci)1732   int compare(cmp_item *ci)
1733   {
1734     cmp_item_real *l_cmp= (cmp_item_real *) ci;
1735     return (value < l_cmp->value)? -1 : ((value == l_cmp->value) ? 0 : 1);
1736   }
1737   cmp_item *make_same();
1738 };
1739 
1740 
1741 class cmp_item_decimal : public cmp_item_scalar
1742 {
1743   my_decimal value;
1744 public:
cmp_item_decimal()1745   cmp_item_decimal() {}                       /* Remove gcc warning */
1746   void store_value(Item *item);
1747   int cmp(Item *arg);
1748   int cmp_not_null(const Value *val);
1749   int compare(cmp_item *c);
1750   cmp_item *make_same();
1751 };
1752 
1753 
1754 /*
1755    cmp_item for optimized IN with row (right part string, which never
1756    be changed)
1757 */
1758 
1759 class cmp_item_sort_string_in_static :public cmp_item_string
1760 {
1761  protected:
1762   String value;
1763 public:
cmp_item_sort_string_in_static(CHARSET_INFO * cs)1764   cmp_item_sort_string_in_static(CHARSET_INFO *cs):
1765     cmp_item_string(cs) {}
store_value(Item * item)1766   void store_value(Item *item)
1767   {
1768     value_res= item->val_str(&value);
1769     m_null_value= item->null_value;
1770   }
cmp_not_null(const Value * val)1771   int cmp_not_null(const Value *val)
1772   {
1773     DBUG_ASSERT(false);
1774     return TRUE;
1775   }
cmp(Item * item)1776   int cmp(Item *item)
1777   {
1778     // Should never be called
1779     DBUG_ASSERT(false);
1780     return TRUE;
1781   }
compare(cmp_item * ci)1782   int compare(cmp_item *ci)
1783   {
1784     cmp_item_string *l_cmp= (cmp_item_string *) ci;
1785     return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1786   }
make_same()1787   cmp_item *make_same()
1788   {
1789     return new cmp_item_sort_string_in_static(cmp_charset);
1790   }
1791 };
1792 
1793 
1794 /**
1795   A helper class to handle situations when some item "pred" (the predicant)
1796   is consequently compared to a list of other items value0..valueN (the values).
1797   Currently used to handle:
1798   - <in predicate>
1799     pred IN (value0, value1, value2)
1800   - <simple case>
1801     CASE pred WHEN value0 .. WHEN value1 .. WHEN value2 .. END
1802 
1803   Every pair {pred,valueN} can be compared by its own Type_handler.
1804   Some pairs can use the same Type_handler.
1805   In cases when all pairs use exactly the same Type_handler,
1806   we say "all types are compatible".
1807 
1808   For example, for an expression
1809     1 IN (1, 1e0, 1.0, 2)
1810   - pred   is 1
1811   - value0 is 1
1812   - value1 is 1e0
1813   - value2 is 1.1
1814   - value3 is 2
1815 
1816   Pairs (pred,valueN) are compared as follows:
1817     N   expr1  Type
1818     -   -----  ----
1819     0       1   INT
1820     1     1e0   DOUBLE
1821     2     1.0   DECIMAL
1822     3       2   INT
1823 
1824   Types are not compatible in this example.
1825 
1826   During add_value() calls, each pair {pred,valueN} is analysed:
1827   - If valueN is an explicit NULL, it can be ignored in the caller asks to do so
1828   - If valueN is not an explicit NULL (or if the caller didn't ask to skip
1829     NULLs), then the value add an element in the array m_comparators[].
1830 
1831   Every element m_comparators[] stores the following information:
1832   1. m_arg_index - the position of the value expression in the original
1833      argument array, e.g. in Item_func_in::args[] or Item_func_case::args[].
1834 
1835   2. m_handler - the pointer to the data type handler that the owner
1836      will use to compare the pair {args[m_predicate_index],args[m_arg_index]}.
1837 
1838   3. m_handler_index - the index of an m_comparators[] element corresponding
1839      to the leftmost pair that uses exactly the same Type_handler for
1840      comparison. m_handler_index helps to maintain unique data type handlers.
1841    - m_comparators[i].m_handler_index==i means that this is the
1842      leftmost pair that uses the Type_handler m_handler for comparision.
1843    - If m_comparators[i].m_handlex_index!=i, it means that some earlier
1844      element m_comparators[j<i] is already using this Type_handler
1845      pointed by m_handler.
1846 
1847   4. m_cmp_item - the pointer to a cmp_item instance to handle comparison
1848      for this pair. Only unique type handlers have m_cmp_item!=NULL.
1849      Non-unique type handlers share the same cmp_item instance.
1850      For all m_comparators[] elements the following assersion it true:
1851        (m_handler_index==i) == (m_cmp_item!=NULL)
1852 */
1853 class Predicant_to_list_comparator
1854 {
1855   // Allocate memory on thd memory root for "nvalues" values.
1856   bool alloc_comparators(THD *thd, uint nvalues);
1857 
1858   /**
1859     Look up m_comparators[] for a comparator using the given data type handler.
1860     @param [OUT] idx     - the index of the found comparator is returned here
1861     @param [IN]  handler - the data type handler to find
1862     @param [IN]  count   - search in the range [0,count) only
1863     @retval true         - this type handler was not found
1864                            (*idx is not defined in this case).
1865     @retval false        - this type handler was found (the position of the
1866                            found handler is returned in idx).
1867   */
find_handler(uint * idx,const Type_handler * handler,uint count)1868   bool find_handler(uint *idx, const Type_handler *handler, uint count)
1869   {
1870     DBUG_ASSERT(count < m_comparator_count);
1871     for (uint i= 0 ; i < count; i++)
1872     {
1873       if (m_comparators[i].m_handler == handler)
1874       {
1875         *idx= i;
1876         return false;
1877       }
1878     }
1879     return true;
1880   }
1881 
1882   /**
1883     Populate m_comparators[i].m_handler_index for all elements in
1884     m_comparators using the information in m_comparators[i].m_handlers,
1885     which was previously populated by a add_predicant() call and a number
1886     of add_value() calls.
1887     @param [OUT] compatible - If all comparator types are compatible,
1888                               their data type handler is returned here.
1889     @param [OUT] unuque_cnt - The number of unique data type handlers found.
1890                               If the value returned in *unique_cnt is 0,
1891                               it means all values were explicit NULLs:
1892                                 expr0 IN (NULL,NULL,..,NULL)
1893     @param [OUT] found_type - The bit mask for all found cmp_type()'s.
1894   */
1895   void detect_unique_handlers(Type_handler_hybrid_field_type *compatible,
1896                               uint *unique_cnt, uint *found_types);
1897   /**
1898     Creates a cmp_item instances for all unique handlers and stores
1899     them into m_comparators[i].m_cmp_item, using the information previously
1900     populated by add_predicant(), add_value(), detect_unque_handlers().
1901   */
1902 
1903   /*
1904     Compare the predicant to the value pointed by m_comparators[i].
1905     @param  args    - the same argument array which was previously used
1906                       with add_predicant() and add_value().
1907     @param  i       - which pair to check.
1908     @retval true    - the predicant is not equal to the value.
1909     @retval false   - the predicant is equal to the value.
1910     @retval UNKNOWN - the result is uncertain yet because the predicant
1911                       and/or the value returned NULL,
1912                       more pairs {pred,valueN} should be checked.
1913   */
cmp_arg(Item_args * args,uint i)1914   int cmp_arg(Item_args *args, uint i)
1915   {
1916     Predicant_to_value_comparator *cmp=
1917       &m_comparators[m_comparators[i].m_handler_index];
1918     cmp_item *in_item= cmp->m_cmp_item;
1919     DBUG_ASSERT(in_item);
1920     /*
1921       If this is the leftmost pair that uses the data type handler
1922       pointed by m_comparators[i].m_handler, then we need to cache
1923       the predicant value representation used by this handler.
1924     */
1925     if (m_comparators[i].m_handler_index == i)
1926       in_item->store_value(args->arguments()[m_predicant_index]);
1927     /*
1928       If the predicant item has null_value==true then:
1929       - In case of scalar expression we can returns UNKNOWN immediately.
1930         No needs to check the result of the value item.
1931       - In case of ROW, null_value==true means that *some* row elements
1932         returned NULL, but *some* elements can still be non-NULL!
1933         We need to get the result of the value item and test
1934         if non-NULL elements in the predicant and the value produce
1935         TRUE (not equal), or UNKNOWN.
1936     */
1937     if (args->arguments()[m_predicant_index]->null_value &&
1938         m_comparators[i].m_handler != &type_handler_row)
1939       return UNKNOWN;
1940     return in_item->cmp(args->arguments()[m_comparators[i].m_arg_index]);
1941   }
cmp_args_nulls_equal(THD * thd,Item_args * args,uint i)1942   int cmp_args_nulls_equal(THD *thd, Item_args *args, uint i)
1943   {
1944     Predicant_to_value_comparator *cmp=
1945       &m_comparators[m_comparators[i].m_handler_index];
1946     cmp_item *in_item= cmp->m_cmp_item;
1947     DBUG_ASSERT(in_item);
1948     Item *predicant= args->arguments()[m_predicant_index];
1949     Item *arg= args->arguments()[m_comparators[i].m_arg_index];
1950     ValueBuffer<MAX_FIELD_WIDTH> val;
1951     if (m_comparators[i].m_handler_index == i)
1952       in_item->store_value(predicant);
1953     m_comparators[i].m_handler->Item_save_in_value(thd, arg, &val);
1954     if (predicant->null_value && val.is_null())
1955       return FALSE; // Two nulls are equal
1956     if (predicant->null_value || val.is_null())
1957       return UNKNOWN;
1958     return in_item->cmp_not_null(&val);
1959   }
1960   /**
1961     Predicant_to_value_comparator - a comparator for one pair (pred,valueN).
1962     See comments above.
1963   */
1964   struct Predicant_to_value_comparator
1965   {
1966     const Type_handler *m_handler;
1967     cmp_item *m_cmp_item;
1968     uint m_arg_index;
1969     uint m_handler_index;
cleanupPredicant_to_value_comparator1970     void cleanup()
1971     {
1972       if (m_cmp_item)
1973         delete m_cmp_item;
1974       memset(this, 0, sizeof(*this));
1975     }
1976   };
1977 
1978   Predicant_to_value_comparator *m_comparators; // The comparator array
1979   uint m_comparator_count;// The number of elements in m_comparators[]
1980   uint m_predicant_index; // The position of the predicant in its argument list,
1981                           // e.g. for Item_func_in m_predicant_index is 0,
1982                           // as predicant is stored in Item_func_in::args[0].
1983                           // For Item_func_case m_predicant_index is
1984                           // set to Item_func_case::first_expr_num.
1985 
1986 public:
Predicant_to_list_comparator(THD * thd,uint nvalues)1987   Predicant_to_list_comparator(THD *thd, uint nvalues)
1988    :m_comparator_count(0),
1989     m_predicant_index(0)
1990   {
1991     alloc_comparators(thd, nvalues);
1992   }
1993 
comparator_count()1994   uint comparator_count() const { return m_comparator_count; }
get_comparator_type_handler(uint i)1995   const Type_handler *get_comparator_type_handler(uint i) const
1996   {
1997     DBUG_ASSERT(i < m_comparator_count);
1998     return m_comparators[i].m_handler;
1999   }
get_comparator_arg_index(uint i)2000   uint get_comparator_arg_index(uint i) const
2001   {
2002     DBUG_ASSERT(i < m_comparator_count);
2003     return m_comparators[i].m_arg_index;
2004   }
get_comparator_cmp_item(uint i)2005   cmp_item *get_comparator_cmp_item(uint i) const
2006   {
2007     DBUG_ASSERT(i < m_comparator_count);
2008     return m_comparators[i].m_cmp_item;
2009   }
2010 
2011 #ifndef DBUG_OFF
debug_print(THD * thd)2012   void debug_print(THD *thd)
2013   {
2014     for (uint i= 0; i < m_comparator_count; i++)
2015     {
2016       DBUG_EXECUTE_IF("Predicant_to_list_comparator",
2017                       push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
2018                       ER_UNKNOWN_ERROR, "DBUG: [%d] arg=%d handler=%d (%s)", i,
2019                       m_comparators[i].m_arg_index,
2020                       m_comparators[i].m_handler_index,
2021                       m_comparators[m_comparators[i].m_handler_index].
2022                                     m_handler->name().ptr()););
2023     }
2024   }
2025 #endif
2026 
add_predicant(Item_args * args,uint predicant_index)2027   void add_predicant(Item_args *args, uint predicant_index)
2028   {
2029     DBUG_ASSERT(m_comparator_count == 0); // Set in constructor
2030     DBUG_ASSERT(m_predicant_index == 0);  // Set in constructor
2031     DBUG_ASSERT(predicant_index < args->argument_count());
2032     m_predicant_index= predicant_index;
2033   }
2034   /**
2035     Add a new element into m_comparators[], using a {pred,valueN} pair.
2036 
2037     @param funcname        - the name of the operation, for error reporting
2038     @param args            - the owner function's argument list
2039     @param value_index     - the value position in args
2040     @retval true           - could not add an element because of non-comparable
2041                              arguments (e.g. ROWs with size)
2042     @retval false          - a new element was successfully added.
2043   */
2044   bool add_value(const char *funcname, Item_args *args, uint value_index);
2045 
2046   /**
2047     Add a new element into m_comparators[], ignoring explicit NULL values.
2048     If the value appeared to be an explicit NULL, nulls_found[0] is set to true.
2049   */
2050   bool add_value_skip_null(const char *funcname,
2051                            Item_args *args, uint value_index,
2052                            bool *nulls_found);
2053 
2054   /**
2055     Signal "this" that there will be no new add_value*() calls,
2056     so it can prepare its internal structures for comparison.
2057 
2058     @param [OUT] compatible - If all comparators are compatible,
2059                               their data type handler is returned here.
2060     @param [OUT] unuque_cnt - The number of unique data type handlers found.
2061                               If the value returned in *unique_cnt is 0,
2062                               it means all values were explicit NULLs:
2063                                 expr0 IN (NULL,NULL,..,NULL)
2064     @param [OUT] found_type - The bit mask for all found cmp_type()'s.
2065   */
all_values_added(Type_handler_hybrid_field_type * compatible,uint * unique_cnt,uint * found_types)2066   void all_values_added(Type_handler_hybrid_field_type *compatible,
2067                         uint *unique_cnt, uint *found_types)
2068   {
2069     detect_unique_handlers(compatible, unique_cnt, found_types);
2070   }
2071   /**
2072     Creates cmp_item instances for all unique handlers and stores
2073     them into m_comparators[].m_cmp_item, using the information previously
2074     populated by add_predicant(), add_value() and detect_unque_handlers().
2075   */
2076   bool make_unique_cmp_items(THD *thd, CHARSET_INFO *cs);
cleanup()2077   void cleanup()
2078   {
2079     DBUG_ASSERT(m_comparators);
2080     for (uint i= 0; i < m_comparator_count; i++)
2081       m_comparators[i].cleanup();
2082     memset(m_comparators, 0, sizeof(m_comparators[0]) * m_comparator_count);
2083     m_comparator_count= 0;
2084     m_predicant_index= 0;
2085   }
init_clone(THD * thd,uint nvalues)2086   bool init_clone(THD *thd, uint nvalues)
2087   {
2088     m_comparator_count= 0;
2089     m_predicant_index= 0;
2090     return alloc_comparators(thd, nvalues);
2091   }
2092   /**
2093     @param [IN] args  - The argument list that was previously used with
2094                         add_predicant() and add_value().
2095     @param [OUT] idx  - In case if a value that is equal to the predicant
2096                         was found, the index of the matching value is returned
2097                         here. Otherwise, *idx is not changed.
2098     @param [IN/OUT] found_unknown_values - how to handle UNKNOWN results.
2099                         If found_unknown_values is NULL (e.g. Item_func_case),
2100                         cmp() returns immediately when the first UNKNOWN
2101                         result is found.
2102                         If found_unknown_values is non-NULL (Item_func_in),
2103                         cmp() does not return when an UNKNOWN result is found,
2104                         sets *found_unknown_values to true, and continues
2105                         to compare the remaining pairs to find FALSE
2106                         (i.e. the value that is equal to the predicant).
2107 
2108     @retval     false - Found a value that is equal to the predicant
2109     @retval     true  - Didn't find an equal value
2110   */
cmp(Item_args * args,uint * idx,bool * found_unknown_values)2111   bool cmp(Item_args *args, uint *idx, bool *found_unknown_values)
2112   {
2113     for (uint i= 0 ; i < m_comparator_count ; i++)
2114     {
2115       DBUG_ASSERT(m_comparators[i].m_handler != NULL);
2116       const int rc= cmp_arg(args, i);
2117       if (rc == FALSE)
2118       {
2119         *idx= m_comparators[i].m_arg_index;
2120         return false; // Found a matching value
2121       }
2122       if (rc == UNKNOWN)
2123       {
2124         if (!found_unknown_values)
2125           return true;
2126         *found_unknown_values= true;
2127       }
2128     }
2129     return true; // Not found
2130   }
2131   /*
2132     Same as above, but treats two NULLs as equal, e.g. as in DECODE_ORACLE().
2133   */
cmp_nulls_equal(THD * thd,Item_args * args,uint * idx)2134   bool cmp_nulls_equal(THD *thd, Item_args *args, uint *idx)
2135   {
2136     for (uint i= 0 ; i < m_comparator_count ; i++)
2137     {
2138       DBUG_ASSERT(m_comparators[i].m_handler != NULL);
2139       if (cmp_args_nulls_equal(thd, args, i) == FALSE)
2140       {
2141         *idx= m_comparators[i].m_arg_index;
2142         return false; // Found a matching value
2143       }
2144     }
2145     return true; // Not found
2146   }
2147 };
2148 
2149 
2150 /*
2151   The class Item_func_case is the CASE ... WHEN ... THEN ... END function
2152   implementation.
2153 */
2154 
2155 class Item_func_case :public Item_func_case_expression
2156 {
2157 protected:
2158   String tmp_value;
2159   DTCollation cmp_collation;
2160   bool aggregate_then_and_else_arguments(THD *thd, uint count);
2161   virtual Item **else_expr_addr() const= 0;
2162   virtual Item *find_item()= 0;
2163   inline void print_when_then_arguments(String *str,
2164                                         enum_query_type query_type,
2165                                         Item **items, uint count);
2166   inline void print_else_argument(String *str, enum_query_type query_type,
2167                                   Item *item);
2168   void reorder_args(uint start);
2169 public:
Item_func_case(THD * thd,List<Item> & list)2170   Item_func_case(THD *thd, List<Item> &list)
2171    :Item_func_case_expression(thd, list)
2172   { }
2173   double real_op();
2174   longlong int_op();
2175   String *str_op(String *);
2176   my_decimal *decimal_op(my_decimal *);
2177   bool date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
2178   bool time_op(THD *thd, MYSQL_TIME *ltime);
2179   bool native_op(THD *thd, Native *to);
2180   bool fix_fields(THD *thd, Item **ref);
not_null_tables()2181   table_map not_null_tables() const { return 0; }
func_name()2182   const char *func_name() const { return "case"; }
compare_collation()2183   CHARSET_INFO *compare_collation() const { return cmp_collation.collation; }
need_parentheses_in_default()2184   bool need_parentheses_in_default() { return true; }
2185 };
2186 
2187 
2188 /*
2189   CASE WHEN cond THEN res [WHEN cond THEN res...] [ELSE res] END
2190 
2191   Searched CASE checks all WHEN expressions one after another.
2192   When some WHEN expression evaluated to TRUE then the
2193   value of the corresponding THEN expression is returned.
2194 */
2195 class Item_func_case_searched: public Item_func_case
2196 {
when_count()2197   uint when_count() const { return arg_count / 2; }
with_else()2198   bool with_else() const { return arg_count % 2; }
else_expr_addr()2199   Item **else_expr_addr() const { return with_else() ? &args[arg_count - 1] : 0; }
2200 public:
Item_func_case_searched(THD * thd,List<Item> & list)2201   Item_func_case_searched(THD *thd, List<Item> &list)
2202    :Item_func_case(thd, list)
2203   {
2204     DBUG_ASSERT(arg_count >= 2);
2205     reorder_args(0);
2206   }
functype()2207   enum Functype functype() const   { return CASE_SEARCHED_FUNC; }
2208   void print(String *str, enum_query_type query_type);
2209   bool fix_length_and_dec();
propagate_equal_fields(THD * thd,const Context & ctx,COND_EQUAL * cond)2210   Item *propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
2211   {
2212     // None of the arguments are in a comparison context
2213     Item_args::propagate_equal_fields(thd, Context_identity(), cond);
2214     return this;
2215   }
2216   Item *find_item();
get_copy(THD * thd)2217   Item *get_copy(THD *thd)
2218   { return get_item_copy<Item_func_case_searched>(thd, this); }
2219 };
2220 
2221 
2222 /*
2223   CASE pred WHEN value THEN res [WHEN value THEN res...] [ELSE res] END
2224 
2225   When the predicant expression is specified then it is compared to each WHEN
2226   expression individually. When an equal WHEN expression is found
2227   the corresponding THEN expression is returned.
2228   In order to do correct comparisons several comparators are used. One for
2229   each result type. Different result types that are used in particular
2230   CASE ... END expression are collected in the fix_length_and_dec() member
2231   function and only comparators for there result types are used.
2232 */
2233 class Item_func_case_simple: public Item_func_case,
2234                              public Predicant_to_list_comparator
2235 {
2236 protected:
2237   uint m_found_types;
when_count()2238   uint when_count() const { return (arg_count - 1) / 2; }
with_else()2239   bool with_else() const { return arg_count % 2 == 0; }
else_expr_addr()2240   Item **else_expr_addr() const { return with_else() ? &args[arg_count - 1] : 0; }
2241   bool aggregate_switch_and_when_arguments(THD *thd, bool nulls_equal);
2242   bool prepare_predicant_and_values(THD *thd, uint *found_types,
2243                                               bool nulls_equal);
2244 public:
Item_func_case_simple(THD * thd,List<Item> & list)2245   Item_func_case_simple(THD *thd, List<Item> &list)
2246    :Item_func_case(thd, list),
2247     Predicant_to_list_comparator(thd, arg_count),
2248     m_found_types(0)
2249   {
2250     DBUG_ASSERT(arg_count >= 3);
2251     reorder_args(1);
2252   }
cleanup()2253   void cleanup()
2254   {
2255     DBUG_ENTER("Item_func_case_simple::cleanup");
2256     Item_func::cleanup();
2257     Predicant_to_list_comparator::cleanup();
2258     DBUG_VOID_RETURN;
2259   }
functype()2260   enum Functype functype() const   { return CASE_SIMPLE_FUNC; }
2261   void print(String *str, enum_query_type query_type);
2262   bool fix_length_and_dec();
2263   Item *propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond);
2264   Item *find_item();
build_clone(THD * thd)2265   Item *build_clone(THD *thd)
2266   {
2267     Item_func_case_simple *clone= (Item_func_case_simple *)
2268                                   Item_func_case::build_clone(thd);
2269     uint ncases= when_count();
2270     if (clone && clone->Predicant_to_list_comparator::init_clone(thd, ncases))
2271       return NULL;
2272     return clone;
2273   }
get_copy(THD * thd)2274   Item *get_copy(THD *thd)
2275   { return get_item_copy<Item_func_case_simple>(thd, this); }
2276 };
2277 
2278 
2279 class Item_func_decode_oracle: public Item_func_case_simple
2280 {
2281 public:
Item_func_decode_oracle(THD * thd,List<Item> & list)2282   Item_func_decode_oracle(THD *thd, List<Item> &list)
2283    :Item_func_case_simple(thd, list)
2284   { }
func_name()2285   const char *func_name() const { return "decode_oracle"; }
2286   void print(String *str, enum_query_type query_type);
2287   bool fix_length_and_dec();
2288   Item *find_item();
get_copy(THD * thd)2289   Item *get_copy(THD *thd)
2290   { return get_item_copy<Item_func_decode_oracle>(thd, this); }
2291 };
2292 
2293 
2294 /*
2295   The Item_func_in class implements
2296   in_expr IN (<in value list>)
2297   and
2298   in_expr NOT IN (<in value list>)
2299 
2300   The current implementation distinguishes 2 cases:
2301   1) all items in <in value list> are constants and have the same
2302     result type. This case is handled by in_vector class,
2303     implementing fast bisection search.
2304   2) otherwise Item_func_in employs several cmp_item objects to perform
2305     comparisons of in_expr and an item from <in value list>. One cmp_item
2306     object for each result type. Different result types are collected in the
2307     fix_length_and_dec() member function by means of collect_cmp_types()
2308     function.
2309 
2310   Bisection is possible when:
2311   1. All types are similar
2312   2. All expressions in <in value list> are const
2313   In the presence of NULLs, the correct result of evaluating this item
2314   must be UNKNOWN or FALSE. To achieve that:
2315   - If type is scalar, we can use bisection and the "have_null" boolean.
2316   - If type is ROW, we will need to scan all of <in value list> when
2317     searching, so bisection is impossible. Unless:
2318   3. UNKNOWN and FALSE are equivalent results
2319   4. Neither left expression nor <in value list> contain any NULL value
2320 */
2321 class Item_func_in :public Item_func_opt_neg,
2322                     public Predicant_to_list_comparator
2323 {
2324   /**
2325      Usable if <in value list> is made only of constants. Returns true if one
2326      of these constants contains a NULL. Example:
2327      IN ( (-5, (12,NULL)), ... ).
2328   */
2329   bool list_contains_null();
all_items_are_consts(Item ** items,uint nitems)2330   bool all_items_are_consts(Item **items, uint nitems) const
2331   {
2332     for (uint i= 0; i < nitems; i++)
2333     {
2334       if (!items[i]->const_item() || items[i]->is_expensive())
2335         return false;
2336     }
2337     return true;
2338   }
2339   bool prepare_predicant_and_values(THD *thd, uint *found_types);
check_arguments()2340   bool check_arguments() const
2341   {
2342     return check_argument_types_like_args0();
2343   }
2344 protected:
2345   SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
2346                              Field *field, Item *value);
2347   bool transform_into_subq;
2348 public:
2349   /// An array of values, created when the bisection lookup method is used
2350   in_vector *array;
2351   /**
2352     If there is some NULL among <in value list>, during a val_int() call; for
2353     example
2354     IN ( (1,(3,'col')), ... ), where 'col' is a column which evaluates to
2355     NULL.
2356   */
2357   bool have_null;
2358   /**
2359     true when all arguments of the IN list are of compatible types
2360     and can be used safely as comparisons for key conditions
2361   */
2362   bool arg_types_compatible;
2363 
2364   TABLE_LIST *emb_on_expr_nest;
2365 
Item_func_in(THD * thd,List<Item> & list)2366   Item_func_in(THD *thd, List<Item> &list):
2367     Item_func_opt_neg(thd, list),
2368     Predicant_to_list_comparator(thd, arg_count - 1),
2369     transform_into_subq(false),
2370     array(0), have_null(0),
2371     arg_types_compatible(FALSE), emb_on_expr_nest(0)
2372   { }
2373   longlong val_int();
2374   bool fix_fields(THD *, Item **);
2375   bool fix_length_and_dec();
compatible_types_scalar_bisection_possible()2376   bool compatible_types_scalar_bisection_possible()
2377   {
2378     DBUG_ASSERT(m_comparator.cmp_type() != ROW_RESULT);
2379     return all_items_are_consts(args + 1, arg_count - 1);     // Bisection #2
2380   }
compatible_types_row_bisection_possible()2381   bool compatible_types_row_bisection_possible()
2382   {
2383     DBUG_ASSERT(m_comparator.cmp_type() == ROW_RESULT);
2384     return all_items_are_consts(args + 1, arg_count - 1) &&   // Bisection #2
2385            ((is_top_level_item() && !negated) ||              // Bisection #3
2386             (!list_contains_null() && !args[0]->maybe_null)); // Bisection #4
2387   }
agg_all_arg_charsets_for_comparison()2388   bool agg_all_arg_charsets_for_comparison()
2389   {
2390     return agg_arg_charsets_for_comparison(cmp_collation, args, arg_count);
2391   }
2392   void fix_in_vector();
2393   bool value_list_convert_const_to_int(THD *thd);
fix_for_scalar_comparison_using_bisection(THD * thd)2394   bool fix_for_scalar_comparison_using_bisection(THD *thd)
2395   {
2396     array= m_comparator.type_handler()->make_in_vector(thd, this, arg_count - 1);
2397     if (!array)      // OOM
2398       return true;
2399     fix_in_vector();
2400     return false;
2401   }
2402   bool fix_for_scalar_comparison_using_cmp_items(THD *thd, uint found_types);
2403 
2404   bool fix_for_row_comparison_using_cmp_items(THD *thd);
2405   bool fix_for_row_comparison_using_bisection(THD *thd);
2406 
cleanup()2407   void cleanup()
2408   {
2409     DBUG_ENTER("Item_func_in::cleanup");
2410     Item_int_func::cleanup();
2411     delete array;
2412     array= 0;
2413     Predicant_to_list_comparator::cleanup();
2414     DBUG_VOID_RETURN;
2415   }
2416   void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
2417                       table_map usable_tables, SARGABLE_PARAM **sargables);
2418   SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
2419   SEL_TREE *get_func_row_mm_tree(RANGE_OPT_PARAM *param, Item_row *key_row);
propagate_equal_fields(THD * thd,const Context & ctx,COND_EQUAL * cond)2420   Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
2421   {
2422     /*
2423       Note, we pass ANY_SUBST, this makes sure that non of the args
2424       will be replaced to a zero-filled Item_string.
2425       Such a change would require rebuilding of cmp_items.
2426     */
2427     if (arg_types_compatible)
2428     {
2429       Context cmpctx(ANY_SUBST, m_comparator.type_handler(),
2430                      Item_func_in::compare_collation());
2431       args[0]->propagate_equal_fields_and_change_item_tree(thd, cmpctx,
2432                                                            cond, &args[0]);
2433     }
2434     for (uint i= 0; i < comparator_count(); i++)
2435     {
2436       Context cmpctx(ANY_SUBST, get_comparator_type_handler(i),
2437                      Item_func_in::compare_collation());
2438       uint idx= get_comparator_arg_index(i);
2439       args[idx]->propagate_equal_fields_and_change_item_tree(thd, cmpctx,
2440                                                              cond, &args[idx]);
2441     }
2442     return this;
2443   }
2444   virtual void print(String *str, enum_query_type query_type);
functype()2445   enum Functype functype() const { return IN_FUNC; }
func_name()2446   const char *func_name() const { return "in"; }
precedence()2447   enum precedence precedence() const { return IN_PRECEDENCE; }
2448   bool eval_not_null_tables(void *opt_arg);
2449   void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
2450   bool count_sargable_conds(void *arg);
get_copy(THD * thd)2451   Item *get_copy(THD *thd)
2452   { return get_item_copy<Item_func_in>(thd, this); }
build_clone(THD * thd)2453   Item *build_clone(THD *thd)
2454   {
2455     Item_func_in *clone= (Item_func_in *) Item_func::build_clone(thd);
2456     if (clone)
2457     {
2458       clone->array= 0;
2459       if (clone->Predicant_to_list_comparator::init_clone(thd, arg_count - 1))
2460         return NULL;
2461     }
2462     return clone;
2463   }
2464   void mark_as_condition_AND_part(TABLE_LIST *embedding);
2465   bool to_be_transformed_into_in_subq(THD *thd);
2466   bool create_value_list_for_tvc(THD *thd, List< List<Item> > *values);
2467   Item *in_predicate_to_in_subs_transformer(THD *thd, uchar *arg);
2468   uint32 max_length_of_left_expr();
2469 };
2470 
2471 class cmp_item_row :public cmp_item
2472 {
2473   cmp_item **comparators;
2474   uint n;
2475   bool alloc_comparators(THD *thd, uint n);
2476   bool aggregate_row_elements_for_comparison(THD *thd,
2477                                              Type_handler_hybrid_field_type *cmp,
2478                                              Item_args *tmp,
2479                                              const char *funcname,
2480                                              uint col,
2481                                              uint level);
2482 public:
cmp_item_row()2483   cmp_item_row(): comparators(0), n(0) {}
2484   ~cmp_item_row();
2485   void store_value(Item *item);
2486   bool prepare_comparators(THD *, const char *funcname,
2487                            const Item_args *args, uint level);
2488   int cmp(Item *arg);
cmp_not_null(const Value * val)2489   int cmp_not_null(const Value *val)
2490   {
2491     DBUG_ASSERT(false);
2492     return TRUE;
2493   }
2494   int compare(cmp_item *arg);
2495   cmp_item *make_same();
2496   void store_value_by_template(THD *thd, cmp_item *tmpl, Item *);
2497   friend class Item_func_in;
get_comparator(uint i)2498   cmp_item *get_comparator(uint i) { return comparators[i]; }
2499 };
2500 
2501 
2502 class in_row :public in_vector
2503 {
2504   cmp_item_row tmp;
2505 public:
2506   in_row(THD *thd, uint elements, Item *);
2507   ~in_row();
2508   void set(uint pos,Item *item);
2509   uchar *get_value(Item *item);
2510   friend class Item_func_in;
type_handler()2511   const Type_handler *type_handler() const { return &type_handler_row; }
get_cmp_item()2512   cmp_item *get_cmp_item() { return &tmp; }
2513 };
2514 
2515 /* Functions used by where clause */
2516 class Item_func_null_predicate :public Item_bool_func
2517 {
2518 protected:
get_func_mm_tree(RANGE_OPT_PARAM * param,Field * field,Item * value)2519   SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
2520                              Field *field, Item *value)
2521   {
2522     DBUG_ENTER("Item_func_null_predicate::get_func_mm_tree");
2523     DBUG_RETURN(get_mm_parts(param, field, functype(), value));
2524   }
2525   SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param, Field *field,
2526                        KEY_PART *key_part,
2527                        Item_func::Functype type, Item *value);
2528 public:
Item_func_null_predicate(THD * thd,Item * a)2529   Item_func_null_predicate(THD *thd, Item *a): Item_bool_func(thd, a) { }
2530   void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
2531                       table_map usable_tables, SARGABLE_PARAM **sargables);
get_mm_tree(RANGE_OPT_PARAM * param,Item ** cond_ptr)2532   SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
2533   {
2534     DBUG_ENTER("Item_func_null_predicate::get_mm_tree");
2535     SEL_TREE *ftree= get_full_func_mm_tree_for_args(param, args[0], NULL);
2536     if (!ftree)
2537       ftree= Item_func::get_mm_tree(param, cond_ptr);
2538     DBUG_RETURN(ftree);
2539   }
compare_collation()2540   CHARSET_INFO *compare_collation() const
2541   { return args[0]->collation.collation; }
fix_length_and_dec()2542   bool fix_length_and_dec()
2543   {
2544     decimals=0; max_length=1; maybe_null=0;
2545     return FALSE;
2546   }
2547   bool count_sargable_conds(void *arg);
2548 };
2549 
2550 
2551 class Item_func_isnull :public Item_func_null_predicate
2552 {
2553 public:
Item_func_isnull(THD * thd,Item * a)2554   Item_func_isnull(THD *thd, Item *a): Item_func_null_predicate(thd, a) {}
2555   longlong val_int();
functype()2556   enum Functype functype() const { return ISNULL_FUNC; }
func_name()2557   const char *func_name() const { return "isnull"; }
2558   void print(String *str, enum_query_type query_type);
precedence()2559   enum precedence precedence() const { return CMP_PRECEDENCE; }
2560 
arg_is_datetime_notnull_field()2561   bool arg_is_datetime_notnull_field()
2562   {
2563     Item **args= arguments();
2564     if (args[0]->real_item()->type() == Item::FIELD_ITEM)
2565     {
2566       Field *field=((Item_field*) args[0]->real_item())->field;
2567 
2568       if ((field->flags & NOT_NULL_FLAG) &&
2569           field->type_handler()->cond_notnull_field_isnull_to_field_eq_zero())
2570         return true;
2571     }
2572     return false;
2573   }
2574 
2575   /* Optimize case of not_null_column IS NULL */
update_used_tables()2576   virtual void update_used_tables()
2577   {
2578     if (!args[0]->maybe_null && !arg_is_datetime_notnull_field())
2579     {
2580       used_tables_cache= 0;			/* is always false */
2581       const_item_cache= 1;
2582     }
2583     else
2584     {
2585       args[0]->update_used_tables();
2586       used_tables_cache= args[0]->used_tables();
2587       const_item_cache= args[0]->const_item();
2588     }
2589   }
2590   COND *remove_eq_conds(THD *thd, Item::cond_result *cond_value,
2591                         bool top_level);
not_null_tables()2592   table_map not_null_tables() const { return 0; }
2593   Item *neg_transformer(THD *thd);
get_copy(THD * thd)2594   Item *get_copy(THD *thd)
2595   { return get_item_copy<Item_func_isnull>(thd, this); }
2596 };
2597 
2598 /* Functions used by HAVING for rewriting IN subquery */
2599 
2600 class Item_in_subselect;
2601 
2602 /*
2603   This is like IS NOT NULL but it also remembers if it ever has
2604   encountered a NULL.
2605 */
2606 class Item_is_not_null_test :public Item_func_isnull
2607 {
2608   Item_in_subselect* owner;
2609 public:
Item_is_not_null_test(THD * thd,Item_in_subselect * ow,Item * a)2610   Item_is_not_null_test(THD *thd, Item_in_subselect* ow, Item *a):
2611     Item_func_isnull(thd, a), owner(ow)
2612   {}
functype()2613   enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
2614   longlong val_int();
func_name()2615   const char *func_name() const { return "<is_not_null_test>"; }
2616   void update_used_tables();
2617   /*
2618     we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
2619   */
used_tables()2620   table_map used_tables() const
2621     { return used_tables_cache | RAND_TABLE_BIT; }
const_item()2622   bool const_item() const { return FALSE; }
2623 };
2624 
2625 
2626 class Item_func_isnotnull :public Item_func_null_predicate
2627 {
2628   bool abort_on_null;
2629 public:
Item_func_isnotnull(THD * thd,Item * a)2630   Item_func_isnotnull(THD *thd, Item *a):
2631     Item_func_null_predicate(thd, a), abort_on_null(0)
2632   { }
2633   longlong val_int();
functype()2634   enum Functype functype() const { return ISNOTNULL_FUNC; }
func_name()2635   const char *func_name() const { return "isnotnull"; }
precedence()2636   enum precedence precedence() const { return CMP_PRECEDENCE; }
not_null_tables()2637   table_map not_null_tables() const
2638   { return abort_on_null ? not_null_tables_cache : 0; }
2639   Item *neg_transformer(THD *thd);
2640   void print(String *str, enum_query_type query_type);
top_level_item()2641   void top_level_item() { abort_on_null=1; }
get_copy(THD * thd)2642   Item *get_copy(THD *thd)
2643   { return get_item_copy<Item_func_isnotnull>(thd, this); }
2644 };
2645 
2646 
2647 class Item_func_like :public Item_bool_func2
2648 {
2649   // Turbo Boyer-Moore data
2650   bool        canDoTurboBM;	// pattern is '%abcd%' case
2651   const char* pattern;
2652   int         pattern_len;
2653 
2654   // TurboBM buffers, *this is owner
2655   int* bmGs; //   good suffix shift table, size is pattern_len + 1
2656   int* bmBc; // bad character shift table, size is alphabet_size
2657 
2658   void turboBM_compute_suffixes(int* suff);
2659   void turboBM_compute_good_suffix_shifts(int* suff);
2660   void turboBM_compute_bad_character_shifts();
2661   bool turboBM_matches(const char* text, int text_len) const;
2662   enum { alphabet_size = 256 };
2663 
2664   Item *escape_item;
2665 
2666   bool escape_used_in_parsing;
2667   bool use_sampling;
2668 
2669   DTCollation cmp_collation;
2670   String cmp_value1, cmp_value2;
2671   bool with_sargable_pattern() const;
2672 protected:
get_func_mm_tree(RANGE_OPT_PARAM * param,Field * field,Item * value)2673   SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
2674                              Field *field, Item *value)
2675   {
2676     DBUG_ENTER("Item_func_like::get_func_mm_tree");
2677     DBUG_RETURN(get_mm_parts(param, field, LIKE_FUNC, value));
2678   }
2679   SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param, Field *field,
2680                        KEY_PART *key_part,
2681                        Item_func::Functype type, Item *value);
2682 public:
2683   int escape;
2684   bool negated;
2685 
Item_func_like(THD * thd,Item * a,Item * b,Item * escape_arg,bool escape_used)2686   Item_func_like(THD *thd, Item *a, Item *b, Item *escape_arg, bool escape_used):
2687     Item_bool_func2(thd, a, b), canDoTurboBM(FALSE), pattern(0), pattern_len(0),
2688     bmGs(0), bmBc(0), escape_item(escape_arg),
2689     escape_used_in_parsing(escape_used), use_sampling(0), negated(0) {}
2690 
get_negated()2691   bool get_negated() const { return negated; } // Used by ColumnStore
2692 
2693   Sql_mode_dependency value_depends_on_sql_mode() const;
2694   longlong val_int();
functype()2695   enum Functype functype() const { return LIKE_FUNC; }
2696   void print(String *str, enum_query_type query_type);
compare_collation()2697   CHARSET_INFO *compare_collation() const
2698   { return cmp_collation.collation; }
eq_cmp_result()2699   cond_result eq_cmp_result() const
2700   {
2701     /**
2702       We cannot always rewrite conditions as follows:
2703         from:  WHERE expr1=const AND expr1 LIKE expr2
2704         to:    WHERE expr1=const AND const LIKE expr2
2705       or
2706         from:  WHERE expr1=const AND expr2 LIKE expr1
2707         to:    WHERE expr1=const AND expr2 LIKE const
2708 
2709       because LIKE works differently comparing to the regular "=" operator:
2710 
2711       1. LIKE performs a stricter one-character-to-one-character comparison
2712          and does not recognize contractions and expansions.
2713          Replacing "expr1" to "const in LIKE would make the condition
2714          stricter in case of a complex collation.
2715 
2716       2. LIKE does not ignore trailing spaces and thus works differently
2717          from the "=" operator in case of "PAD SPACE" collations
2718          (which are the majority in MariaDB). So, for "PAD SPACE" collations:
2719 
2720          - expr1=const       - ignores trailing spaces
2721          - const LIKE expr2  - does not ignore trailing spaces
2722          - expr2 LIKE const  - does not ignore trailing spaces
2723 
2724       Allow only "binary" for now.
2725       It neither ignores trailing spaces nor has contractions/expansions.
2726 
2727       TODO:
2728       We could still replace "expr1" to "const" in "expr1 LIKE expr2"
2729       in case of a "PAD SPACE" collation, but only if "expr2" has '%'
2730       at the end.
2731     */
2732     return compare_collation() == &my_charset_bin ? COND_TRUE : COND_OK;
2733   }
2734   void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
2735                       table_map usable_tables, SARGABLE_PARAM **sargables);
2736   SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
propagate_equal_fields(THD * thd,const Context & ctx,COND_EQUAL * cond)2737   Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
2738   {
2739     /*
2740       LIKE differs from the regular comparison operator ('=') in the following:
2741       - LIKE never ignores trailing spaces (even for PAD SPACE collations)
2742         Propagation of equal fields with a PAD SPACE collation into LIKE
2743         is not safe.
2744         Example:
2745           WHERE a='a ' AND a LIKE 'a'     - returns true for 'a'
2746         cannot be rewritten to:
2747           WHERE a='a ' AND 'a ' LIKE 'a'  - returns false for 'a'
2748         Note, binary collations in MySQL/MariaDB, e.g. latin1_bin,
2749         still have the PAD SPACE attribute and ignore trailing spaces!
2750       - LIKE does not take into account contractions, expansions,
2751         and ignorable characters.
2752         Propagation of equal fields with contractions/expansions/ignorables
2753         is also not safe.
2754 
2755       It's safe to propagate my_charset_bin (BINARY/VARBINARY/BLOB) values,
2756       because they do not ignore trailing spaces and have one-to-one mapping
2757       between a string and its weights.
2758       The below condition should be true only for my_charset_bin
2759       (as of version 10.1.7).
2760     */
2761     uint flags= Item_func_like::compare_collation()->state;
2762     if ((flags & MY_CS_NOPAD) && !(flags & MY_CS_NON1TO1))
2763       Item_args::propagate_equal_fields(thd,
2764                                         Context(ANY_SUBST,
2765                                                 &type_handler_long_blob,
2766                                                 compare_collation()),
2767                                         cond);
2768     return this;
2769   }
func_name()2770   const char *func_name() const { return "like"; }
precedence()2771   enum precedence precedence() const { return IN_PRECEDENCE; }
2772   bool fix_fields(THD *thd, Item **ref);
fix_length_and_dec()2773   bool fix_length_and_dec()
2774   {
2775     max_length= 1;
2776     return agg_arg_charsets_for_comparison(cmp_collation, args, 2);
2777   }
2778   void cleanup();
2779 
neg_transformer(THD * thd)2780   Item *neg_transformer(THD *thd)
2781   {
2782     negated= !negated;
2783     return this;
2784   }
2785 
walk(Item_processor processor,bool walk_subquery,void * arg)2786   bool walk(Item_processor processor, bool walk_subquery, void *arg)
2787   {
2788     return walk_args(processor, walk_subquery, arg)
2789       ||   escape_item->walk(processor, walk_subquery, arg)
2790       ||  (this->*processor)(arg);
2791   }
2792 
2793   bool find_selective_predicates_list_processor(void *arg);
2794 
get_copy(THD * thd)2795   Item *get_copy(THD *thd)
2796   { return get_item_copy<Item_func_like>(thd, this); }
2797 };
2798 
2799 
2800 class Regexp_processor_pcre
2801 {
2802   pcre *m_pcre;
2803   pcre_extra m_pcre_extra;
2804   bool m_conversion_is_needed;
2805   bool m_is_const;
2806   int m_library_flags;
2807   CHARSET_INFO *m_data_charset;
2808   CHARSET_INFO *m_library_charset;
2809   String m_prev_pattern;
2810   int m_pcre_exec_rc;
2811   int m_SubStrVec[30];
2812   void pcre_exec_warn(int rc) const;
2813   int pcre_exec_with_warn(const pcre *code, const pcre_extra *extra,
2814                           const char *subject, int length, int startoffset,
2815                           int options, int *ovector, int ovecsize);
2816 public:
2817   String *convert_if_needed(String *src, String *converter);
2818   String subject_converter;
2819   String pattern_converter;
2820   String replace_converter;
Regexp_processor_pcre()2821   Regexp_processor_pcre() :
2822     m_pcre(NULL), m_conversion_is_needed(true), m_is_const(0),
2823     m_library_flags(0),
2824     m_data_charset(&my_charset_utf8_general_ci),
2825     m_library_charset(&my_charset_utf8_general_ci)
2826   {
2827     m_pcre_extra.flags= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
2828     m_pcre_extra.match_limit_recursion= 100L;
2829   }
2830   int default_regex_flags();
2831   void set_recursion_limit(THD *);
init(CHARSET_INFO * data_charset,int extra_flags)2832   void init(CHARSET_INFO *data_charset, int extra_flags)
2833   {
2834     m_library_flags= default_regex_flags() | extra_flags |
2835                     (data_charset != &my_charset_bin ?
2836                      (PCRE_UTF8 | PCRE_UCP) : 0) |
2837                     ((data_charset->state &
2838                      (MY_CS_BINSORT | MY_CS_CSSORT)) ? 0 : PCRE_CASELESS);
2839 
2840     // Convert text data to utf-8.
2841     m_library_charset= data_charset == &my_charset_bin ?
2842                        &my_charset_bin : &my_charset_utf8_general_ci;
2843 
2844     m_conversion_is_needed= (data_charset != &my_charset_bin) &&
2845                             !my_charset_same(data_charset, m_library_charset);
2846   }
2847   void fix_owner(Item_func *owner, Item *subject_arg, Item *pattern_arg);
2848   bool compile(String *pattern, bool send_error);
2849   bool compile(Item *item, bool send_error);
recompile(Item * item)2850   bool recompile(Item *item)
2851   {
2852     return !m_is_const && compile(item, false);
2853   }
2854   bool exec(const char *str, size_t length, size_t offset);
2855   bool exec(String *str, int offset, uint n_result_offsets_to_convert);
2856   bool exec(Item *item, int offset, uint n_result_offsets_to_convert);
match()2857   bool match() const { return m_pcre_exec_rc < 0 ? 0 : 1; }
nsubpatterns()2858   int nsubpatterns() const { return m_pcre_exec_rc <= 0 ? 0 : m_pcre_exec_rc; }
subpattern_start(int n)2859   int subpattern_start(int n) const
2860   {
2861     return m_pcre_exec_rc <= 0 ? 0 : m_SubStrVec[n * 2];
2862   }
subpattern_end(int n)2863   int subpattern_end(int n) const
2864   {
2865     return m_pcre_exec_rc <= 0 ? 0 : m_SubStrVec[n * 2 + 1];
2866   }
subpattern_length(int n)2867   int subpattern_length(int n) const
2868   {
2869     return subpattern_end(n) - subpattern_start(n);
2870   }
reset()2871   void reset()
2872   {
2873     m_pcre= NULL;
2874     m_prev_pattern.length(0);
2875   }
cleanup()2876   void cleanup()
2877   {
2878     pcre_free(m_pcre);
2879     reset();
2880   }
is_compiled()2881   bool is_compiled() const { return m_pcre != NULL; }
is_const()2882   bool is_const() const { return m_is_const; }
set_const(bool arg)2883   void set_const(bool arg) { m_is_const= arg; }
library_charset()2884   CHARSET_INFO * library_charset() const { return m_library_charset; }
2885 };
2886 
2887 
2888 class Item_func_regex :public Item_bool_func
2889 {
2890   Regexp_processor_pcre re;
2891   DTCollation cmp_collation;
2892 public:
Item_func_regex(THD * thd,Item * a,Item * b)2893   Item_func_regex(THD *thd, Item *a, Item *b): Item_bool_func(thd, a, b)
2894   {}
cleanup()2895   void cleanup()
2896   {
2897     DBUG_ENTER("Item_func_regex::cleanup");
2898     Item_bool_func::cleanup();
2899     re.cleanup();
2900     DBUG_VOID_RETURN;
2901   }
2902   longlong val_int();
2903   bool fix_fields(THD *thd, Item **ref);
2904   bool fix_length_and_dec();
func_name()2905   const char *func_name() const { return "regexp"; }
precedence()2906   enum precedence precedence() const { return IN_PRECEDENCE; }
get_copy(THD *)2907   Item *get_copy(THD *) { return 0; }
print(String * str,enum_query_type query_type)2908   void print(String *str, enum_query_type query_type)
2909   {
2910     print_op(str, query_type);
2911   }
2912 
compare_collation()2913   CHARSET_INFO *compare_collation() const { return cmp_collation.collation; }
2914 };
2915 
2916 
2917 /*
2918   In the corner case REGEXP_INSTR could return (2^32 + 1),
2919   which would not fit into Item_long_func range.
2920   But string lengths are limited with max_allowed_packet,
2921   which cannot be bigger than 1024*1024*1024.
2922 */
2923 class Item_func_regexp_instr :public Item_long_func
2924 {
check_arguments()2925   bool check_arguments() const
2926   {
2927     return args[0]->check_type_can_return_str(func_name()) ||
2928            args[1]->check_type_can_return_text(func_name());
2929   }
2930   Regexp_processor_pcre re;
2931   DTCollation cmp_collation;
2932 public:
Item_func_regexp_instr(THD * thd,Item * a,Item * b)2933   Item_func_regexp_instr(THD *thd, Item *a, Item *b)
2934    :Item_long_func(thd, a, b)
2935   {}
cleanup()2936   void cleanup()
2937   {
2938     DBUG_ENTER("Item_func_regexp_instr::cleanup");
2939     Item_int_func::cleanup();
2940     re.cleanup();
2941     DBUG_VOID_RETURN;
2942   }
2943   longlong val_int();
2944   bool fix_fields(THD *thd, Item **ref);
2945   bool fix_length_and_dec();
func_name()2946   const char *func_name() const { return "regexp_instr"; }
get_copy(THD * thd)2947   Item *get_copy(THD *thd) { return 0; }
2948 };
2949 
2950 
2951 typedef class Item COND;
2952 
2953 class Item_cond :public Item_bool_func
2954 {
2955 protected:
2956   List<Item> list;
2957   bool abort_on_null;
2958   table_map and_tables_cache;
2959 
2960 public:
2961   /* Item_cond() is only used to create top level items */
Item_cond(THD * thd)2962   Item_cond(THD *thd): Item_bool_func(thd), abort_on_null(1)
2963   { const_item_cache=0; }
2964   Item_cond(THD *thd, Item *i1, Item *i2);
2965   Item_cond(THD *thd, Item_cond *item);
Item_cond(THD * thd,List<Item> & nlist)2966   Item_cond(THD *thd, List<Item> &nlist):
2967     Item_bool_func(thd), list(nlist), abort_on_null(0) {}
add(Item * item,MEM_ROOT * root)2968   bool add(Item *item, MEM_ROOT *root)
2969   {
2970     DBUG_ASSERT(item);
2971     return list.push_back(item, root);
2972   }
add_at_head(Item * item,MEM_ROOT * root)2973   bool add_at_head(Item *item, MEM_ROOT *root)
2974   {
2975     DBUG_ASSERT(item);
2976     return list.push_front(item, root);
2977   }
add_at_head(List<Item> * nlist)2978   void add_at_head(List<Item> *nlist)
2979   {
2980     DBUG_ASSERT(nlist->elements);
2981     list.prepend(nlist);
2982   }
add_at_end(List<Item> * nlist)2983   void add_at_end(List<Item> *nlist)
2984   {
2985     DBUG_ASSERT(nlist->elements);
2986     list.append(nlist);
2987   }
2988   bool fix_fields(THD *, Item **ref);
2989   void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
2990 
type()2991   enum Type type() const { return COND_ITEM; }
argument_list()2992   List<Item>* argument_list() { return &list; }
2993   table_map used_tables() const;
update_used_tables()2994   void update_used_tables()
2995   {
2996     used_tables_and_const_cache_init();
2997     used_tables_and_const_cache_update_and_join(list);
2998   }
2999   COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
3000                           bool link_item_fields,
3001                           COND_EQUAL **cond_equal_ref);
3002   COND *remove_eq_conds(THD *thd, Item::cond_result *cond_value,
3003                         bool top_level);
3004   void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
3005                       uint *and_level, table_map usable_tables,
3006                       SARGABLE_PARAM **sargables);
3007   SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
3008   virtual void print(String *str, enum_query_type query_type);
3009   void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
3010                       List<Item> &fields, uint flags);
3011   friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
3012                          COND **conds);
top_level_item()3013   void top_level_item() { abort_on_null=1; }
top_level()3014   bool top_level() { return abort_on_null; }
3015   void copy_andor_arguments(THD *thd, Item_cond *item);
3016   bool walk(Item_processor processor, bool walk_subquery, void *arg);
3017   Item *transform(THD *thd, Item_transformer transformer, uchar *arg);
3018   void traverse_cond(Cond_traverser, void *arg, traverse_order order);
3019   void neg_arguments(THD *thd);
3020   Item* propagate_equal_fields(THD *, const Context &, COND_EQUAL *);
3021   Item *compile(THD *thd, Item_analyzer analyzer, uchar **arg_p,
3022                 Item_transformer transformer, uchar *arg_t);
3023   bool eval_not_null_tables(void *opt_arg);
3024   Item *build_clone(THD *thd);
3025   bool excl_dep_on_table(table_map tab_map);
3026   bool excl_dep_on_grouping_fields(st_select_lex *sel);
3027 };
3028 
3029 template <template<class> class LI, class T> class Item_equal_iterator;
3030 
3031 /*
3032   The class Item_equal is used to represent conjunctions of equality
3033   predicates of the form field1 = field2, and field=const in where
3034   conditions and on expressions.
3035 
3036   All equality predicates of the form field1=field2 contained in a
3037   conjunction are substituted for a sequence of items of this class.
3038   An item of this class Item_equal(f1,f2,...fk) represents a
3039   multiple equality f1=f2=...=fk.l
3040 
3041   If a conjunction contains predicates f1=f2 and f2=f3, a new item of
3042   this class is created Item_equal(f1,f2,f3) representing the multiple
3043   equality f1=f2=f3 that substitutes the above equality predicates in
3044   the conjunction.
3045   A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
3046   substituted for the item representing the same multiple equality
3047   f1=f2=f3.
3048   An item Item_equal(f1,f2) can appear instead of a conjunction of
3049   f2=f1 and f1=f2, or instead of just the predicate f1=f2.
3050 
3051   An item of the class Item_equal inherits equalities from outer
3052   conjunctive levels.
3053 
3054   Suppose we have a where condition of the following form:
3055   WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
3056   In this case:
3057     f1=f2 will be substituted for Item_equal(f1,f2);
3058     f3=f4 and f3=f5  will be substituted for Item_equal(f3,f4,f5);
3059     f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
3060 
3061   An object of the class Item_equal can contain an optional constant
3062   item c. Then it represents a multiple equality of the form
3063   c=f1=...=fk.
3064 
3065   Objects of the class Item_equal are used for the following:
3066 
3067   1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
3068   pair of tables ti and tj as joined by an equi-condition.
3069   Thus it provide us with additional access paths from table to table.
3070 
3071   2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
3072   SARGable predicates:
3073     f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
3074   It also can give us additional index scans and can allow us to
3075   improve selectivity estimates.
3076 
3077   3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
3078   selected execution plan for the query: if table ti is accessed
3079   before the table tj then in any predicate P in the where condition
3080   the occurrence of tj.fj is substituted for ti.fi. This can allow
3081   an evaluation of the predicate at an earlier step.
3082 
3083   When feature 1 is supported they say that join transitive closure
3084   is employed.
3085   When feature 2 is supported they say that search argument transitive
3086   closure is employed.
3087   Both features are usually supported by preprocessing original query and
3088   adding additional predicates.
3089   We do not just add predicates, we rather dynamically replace some
3090   predicates that can not be used to access tables in the investigated
3091   plan for those, obtained by substitution of some fields for equal fields,
3092   that can be used.
3093 
3094   Prepared Statements/Stored Procedures note: instances of class
3095   Item_equal are created only at the time a PS/SP is executed and
3096   are deleted in the end of execution. All changes made to these
3097   objects need not be registered in the list of changes of the parse
3098   tree and do not harm PS/SP re-execution.
3099 
3100   Item equal objects are employed only at the optimize phase. Usually they are
3101   not supposed to be evaluated.  Yet in some cases we call the method val_int()
3102   for them. We have to take care of restricting the predicate such an
3103   object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
3104 */
3105 
3106 class Item_equal: public Item_bool_func
3107 {
3108   /*
3109     The list of equal items. Currently the list can contain:
3110      - Item_fields items for references to table columns
3111      - Item_direct_view_ref items for references to view columns
3112      - one const item
3113 
3114     If the list contains a constant item this item is always first in the list.
3115     The list contains at least two elements.
3116     Currently all Item_fields/Item_direct_view_ref items in the list should
3117     refer to table columns with equavalent type definitions. In particular
3118     if these are string columns they should have the same charset/collation.
3119 
3120     Use objects of the companion class Item_equal_fields_iterator to iterate
3121     over all items from the list of the Item_field/Item_direct_view_ref classes.
3122   */
3123   List<Item> equal_items;
3124   /*
3125      TRUE <-> one of the items is a const item.
3126      Such item is always first in in the equal_items list
3127   */
3128   bool with_const;
3129   /*
3130     The field eval_item is used when this item is evaluated
3131     with the method val_int()
3132   */
3133   cmp_item *eval_item;
3134   /*
3135     This initially is set to FALSE. It becomes TRUE when this item is evaluated
3136     as being always false. If the flag is TRUE the contents of the list
3137     the equal_items should be ignored.
3138   */
3139   bool cond_false;
3140   /*
3141     This initially is set to FALSE. It becomes TRUE when this item is evaluated
3142     as being always true. If the flag is TRUE the contents of the list
3143     the equal_items should be ignored.
3144   */
3145   bool cond_true;
3146   /*
3147     For Item_equal objects inside an OR clause: one of the fields that were
3148     used in the original equality.
3149   */
3150   Item_field *context_field;
3151 
3152   bool link_equal_fields;
3153 
3154   const Type_handler *m_compare_handler;
3155   CHARSET_INFO *m_compare_collation;
3156 public:
3157 
3158   COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
3159 
3160   Item_equal(THD *thd, const Type_handler *handler,
3161              Item *f1, Item *f2, bool with_const_item);
3162   Item_equal(THD *thd, Item_equal *item_equal);
3163   /* Currently the const item is always the first in the list of equal items */
get_const()3164   inline Item* get_const() { return with_const ? equal_items.head() : NULL; }
3165   void add_const(THD *thd, Item *c);
3166   /** Add a non-constant item to the multiple equality */
add(Item * f,MEM_ROOT * root)3167   void add(Item *f, MEM_ROOT *root) { equal_items.push_back(f, root); }
3168   bool contains(Field *field);
3169   Item* get_first(struct st_join_table *context, Item *field);
3170   /** Get number of field items / references to field items in this object */
n_field_items()3171   uint n_field_items() { return equal_items.elements - MY_TEST(with_const); }
3172   void merge(THD *thd, Item_equal *item);
3173   bool merge_with_check(THD *thd, Item_equal *equal_item, bool save_merged);
3174   void merge_into_list(THD *thd, List<Item_equal> *list, bool save_merged,
3175                       bool only_intersected);
3176   void update_const(THD *thd);
functype()3177   enum Functype functype() const { return MULT_EQUAL_FUNC; }
3178   longlong val_int();
func_name()3179   const char *func_name() const { return "multiple equal"; }
3180   void sort(Item_field_cmpfunc compare, void *arg);
3181   bool fix_length_and_dec();
3182   bool fix_fields(THD *thd, Item **ref);
cleanup()3183   void cleanup()
3184   {
3185     delete eval_item;
3186     eval_item= NULL;
3187   }
3188   void update_used_tables();
3189   COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
3190                           bool link_item_fields,
3191                           COND_EQUAL **cond_equal_ref);
3192   void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
3193                       uint *and_level, table_map usable_tables,
3194                       SARGABLE_PARAM **sargables);
3195   SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
3196   bool walk(Item_processor processor, bool walk_subquery, void *arg);
3197   Item *transform(THD *thd, Item_transformer transformer, uchar *arg);
3198   virtual void print(String *str, enum_query_type query_type);
compare_type_handler()3199   const Type_handler *compare_type_handler() const { return m_compare_handler; }
compare_collation()3200   CHARSET_INFO *compare_collation() const { return m_compare_collation; }
3201 
set_context_field(Item_field * ctx_field)3202   void set_context_field(Item_field *ctx_field) { context_field= ctx_field; }
set_link_equal_fields(bool flag)3203   void set_link_equal_fields(bool flag) { link_equal_fields= flag; }
get_copy(THD * thd)3204   Item* get_copy(THD *thd) { return 0; }
3205   /*
3206     This does not comply with the specification of the virtual method,
3207     but Item_equal items are processed distinguishly anyway
3208   */
excl_dep_on_table(table_map tab_map)3209   bool excl_dep_on_table(table_map tab_map)
3210   {
3211     return used_tables() & tab_map;
3212   }
3213   bool excl_dep_on_in_subq_left_part(Item_in_subselect *subq_pred);
3214   bool excl_dep_on_grouping_fields(st_select_lex *sel);
3215   bool create_pushable_equalities(THD *thd, List<Item> *equalities,
3216                                   Pushdown_checker checker, uchar *arg,
3217                                   bool clone_const);
3218   /* Return the number of elements in this multiple equality */
elements_count()3219   uint elements_count() { return equal_items.elements; }
3220   friend class Item_equal_fields_iterator;
3221   bool count_sargable_conds(void *arg);
3222   Item *multiple_equality_transformer(THD *thd, uchar *arg);
3223   friend class Item_equal_iterator<List_iterator_fast,Item>;
3224   friend class Item_equal_iterator<List_iterator,Item>;
3225   friend Item *eliminate_item_equal(THD *thd, COND *cond,
3226                                     COND_EQUAL *upper_levels,
3227                                     Item_equal *item_equal);
3228   friend bool setup_sj_materialization_part1(struct st_join_table *tab);
3229   friend bool setup_sj_materialization_part2(struct st_join_table *tab);
3230 };
3231 
3232 class COND_EQUAL: public Sql_alloc
3233 {
3234 public:
3235   uint max_members;               /* max number of members the current level
3236                                      list and all lower level lists */
3237   COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
3238   List<Item_equal> current_level; /* list of multiple equalities of
3239                                      the current and level           */
COND_EQUAL()3240   COND_EQUAL()
3241   {
3242     upper_levels= 0;
3243   }
COND_EQUAL(Item_equal * item,MEM_ROOT * mem_root)3244   COND_EQUAL(Item_equal *item, MEM_ROOT *mem_root)
3245    :upper_levels(0)
3246   {
3247     current_level.push_back(item, mem_root);
3248   }
copy(COND_EQUAL & cond_equal)3249   void copy(COND_EQUAL &cond_equal)
3250   {
3251     max_members= cond_equal.max_members;
3252     upper_levels= cond_equal.upper_levels;
3253     if (cond_equal.current_level.is_empty())
3254       current_level.empty();
3255     else
3256       current_level= cond_equal.current_level;
3257   }
is_empty()3258   bool is_empty()
3259   {
3260     return (current_level.elements == 0);
3261   }
3262 };
3263 
3264 
3265 /*
3266   The template Item_equal_iterator is used to define classes
3267   Item_equal_fields_iterator and Item_equal_fields_iterator_slow.
3268   These are helper classes for the class Item equal
3269   Both classes are used to iterate over references to table/view columns
3270   from the list of equal items that included in an Item_equal object.
3271   The second class supports the operation of removal of the current member
3272   from the list when performing an iteration.
3273 */
3274 
3275 template <template<class> class LI, typename T> class Item_equal_iterator
3276   : public LI<T>
3277 {
3278 protected:
3279   Item_equal *item_equal;
3280   Item *curr_item;
3281 public:
3282   Item_equal_iterator<LI,T>(Item_equal &item_eq)
3283     :LI<T> (item_eq.equal_items)
3284   {
3285     curr_item= NULL;
3286     item_equal= &item_eq;
3287     if (item_eq.with_const)
3288     {
3289       LI<T> *list_it= this;
3290       curr_item=  (*list_it)++;
3291     }
3292   }
3293   Item* operator++(int)
3294   {
3295     LI<T> *list_it= this;
3296     curr_item= (*list_it)++;
3297     return curr_item;
3298   }
rewind(void)3299   void rewind(void)
3300   {
3301     LI<T> *list_it= this;
3302     list_it->rewind();
3303     if (item_equal->with_const)
3304       curr_item= (*list_it)++;
3305   }
get_curr_field()3306   Field *get_curr_field()
3307   {
3308     Item_field *item= (Item_field *) (curr_item->real_item());
3309      return item->field;
3310   }
3311 };
3312 
3313 typedef  Item_equal_iterator<List_iterator_fast,Item >  Item_equal_iterator_fast;
3314 
3315 class Item_equal_fields_iterator
3316   :public Item_equal_iterator_fast
3317 {
3318 public:
Item_equal_fields_iterator(Item_equal & item_eq)3319   Item_equal_fields_iterator(Item_equal &item_eq)
3320     :Item_equal_iterator_fast(item_eq)
3321   { }
ref()3322   Item ** ref()
3323   {
3324     return List_iterator_fast<Item>::ref();
3325   }
3326 };
3327 
3328 typedef Item_equal_iterator<List_iterator,Item > Item_equal_iterator_iterator_slow;
3329 
3330 class Item_equal_fields_iterator_slow
3331   :public Item_equal_iterator_iterator_slow
3332 {
3333 public:
Item_equal_fields_iterator_slow(Item_equal & item_eq)3334   Item_equal_fields_iterator_slow(Item_equal &item_eq)
3335     :Item_equal_iterator_iterator_slow(item_eq)
3336   { }
remove()3337   void remove()
3338   {
3339     List_iterator<Item>::remove();
3340   }
3341 };
3342 
3343 
3344 class Item_cond_and :public Item_cond
3345 {
3346 public:
3347   COND_EQUAL m_cond_equal;  /* contains list of Item_equal objects for
3348                                the current and level and reference
3349                                to multiple equalities of upper and levels */
Item_cond_and(THD * thd)3350   Item_cond_and(THD *thd): Item_cond(thd) {}
Item_cond_and(THD * thd,Item * i1,Item * i2)3351   Item_cond_and(THD *thd, Item *i1,Item *i2): Item_cond(thd, i1, i2) {}
Item_cond_and(THD * thd,Item_cond_and * item)3352   Item_cond_and(THD *thd, Item_cond_and *item): Item_cond(thd, item) {}
Item_cond_and(THD * thd,List<Item> & list_arg)3353   Item_cond_and(THD *thd, List<Item> &list_arg): Item_cond(thd, list_arg) {}
functype()3354   enum Functype functype() const { return COND_AND_FUNC; }
3355   longlong val_int();
func_name()3356   const char *func_name() const { return "and"; }
precedence()3357   enum precedence precedence() const { return AND_PRECEDENCE; }
not_null_tables()3358   table_map not_null_tables() const
3359   { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
3360   Item *copy_andor_structure(THD *thd);
3361   Item *neg_transformer(THD *thd);
3362   void mark_as_condition_AND_part(TABLE_LIST *embedding);
exists2in_reserved_items()3363   virtual uint exists2in_reserved_items() { return list.elements; };
3364   COND *build_equal_items(THD *thd, COND_EQUAL *inherited,
3365                           bool link_item_fields,
3366                           COND_EQUAL **cond_equal_ref);
3367   void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
3368                       table_map usable_tables, SARGABLE_PARAM **sargables);
3369   SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
get_copy(THD * thd)3370   Item *get_copy(THD *thd)
3371   { return get_item_copy<Item_cond_and>(thd, this); }
3372 };
3373 
is_cond_and(Item * item)3374 inline bool is_cond_and(Item *item)
3375 {
3376   Item_func *func_item= item->get_item_func();
3377   return func_item && func_item->functype() == Item_func::COND_AND_FUNC;
3378 }
3379 
3380 class Item_cond_or :public Item_cond
3381 {
3382 public:
Item_cond_or(THD * thd)3383   Item_cond_or(THD *thd): Item_cond(thd) {}
Item_cond_or(THD * thd,Item * i1,Item * i2)3384   Item_cond_or(THD *thd, Item *i1,Item *i2): Item_cond(thd, i1, i2) {}
Item_cond_or(THD * thd,Item_cond_or * item)3385   Item_cond_or(THD *thd, Item_cond_or *item): Item_cond(thd, item) {}
Item_cond_or(THD * thd,List<Item> & list_arg)3386   Item_cond_or(THD *thd, List<Item> &list_arg): Item_cond(thd, list_arg) {}
functype()3387   enum Functype functype() const { return COND_OR_FUNC; }
3388   longlong val_int();
func_name()3389   const char *func_name() const { return "or"; }
precedence()3390   enum precedence precedence() const { return OR_PRECEDENCE; }
not_null_tables()3391   table_map not_null_tables() const { return and_tables_cache; }
3392   Item *copy_andor_structure(THD *thd);
3393   Item *neg_transformer(THD *thd);
get_copy(THD * thd)3394   Item *get_copy(THD *thd)
3395   { return get_item_copy<Item_cond_or>(thd, this); }
3396 };
3397 
3398 class Item_func_dyncol_check :public Item_bool_func
3399 {
3400 public:
Item_func_dyncol_check(THD * thd,Item * str)3401   Item_func_dyncol_check(THD *thd, Item *str): Item_bool_func(thd, str) {}
3402   longlong val_int();
func_name()3403   const char *func_name() const { return "column_check"; }
need_parentheses_in_default()3404   bool need_parentheses_in_default() { return false; }
get_copy(THD * thd)3405   Item *get_copy(THD *thd)
3406   { return get_item_copy<Item_func_dyncol_check>(thd, this); }
3407 };
3408 
3409 class Item_func_dyncol_exists :public Item_bool_func
3410 {
3411 public:
Item_func_dyncol_exists(THD * thd,Item * str,Item * num)3412   Item_func_dyncol_exists(THD *thd, Item *str, Item *num):
3413     Item_bool_func(thd, str, num) {}
3414   longlong val_int();
func_name()3415   const char *func_name() const { return "column_exists"; }
need_parentheses_in_default()3416   bool need_parentheses_in_default() { return false; }
get_copy(THD * thd)3417   Item *get_copy(THD *thd)
3418   { return get_item_copy<Item_func_dyncol_exists>(thd, this); }
3419 };
3420 
3421 
3422 class Item_func_cursor_bool_attr: public Item_bool_func, public Cursor_ref
3423 {
3424 public:
Item_func_cursor_bool_attr(THD * thd,const LEX_CSTRING * name,uint offset)3425   Item_func_cursor_bool_attr(THD *thd, const LEX_CSTRING *name, uint offset)
3426    :Item_bool_func(thd), Cursor_ref(name, offset)
3427   { }
check_vcol_func_processor(void * arg)3428   bool check_vcol_func_processor(void *arg)
3429   {
3430     return mark_unsupported_function(func_name(), arg, VCOL_SESSION_FUNC);
3431   }
print(String * str,enum_query_type query_type)3432   void print(String *str, enum_query_type query_type)
3433   {
3434     Cursor_ref::print_func(str, func_name());
3435   }
3436 };
3437 
3438 
3439 class Item_func_cursor_isopen: public Item_func_cursor_bool_attr
3440 {
3441 public:
Item_func_cursor_isopen(THD * thd,const LEX_CSTRING * name,uint offset)3442   Item_func_cursor_isopen(THD *thd, const LEX_CSTRING *name, uint offset)
3443    :Item_func_cursor_bool_attr(thd, name, offset) { }
func_name()3444   const char *func_name() const { return "%ISOPEN"; }
3445   longlong val_int();
get_copy(THD * thd)3446   Item *get_copy(THD *thd)
3447   { return get_item_copy<Item_func_cursor_isopen>(thd, this); }
3448 };
3449 
3450 
3451 class Item_func_cursor_found: public Item_func_cursor_bool_attr
3452 {
3453 public:
Item_func_cursor_found(THD * thd,const LEX_CSTRING * name,uint offset)3454   Item_func_cursor_found(THD *thd, const LEX_CSTRING *name, uint offset)
3455    :Item_func_cursor_bool_attr(thd, name, offset) { maybe_null= true; }
func_name()3456   const char *func_name() const { return "%FOUND"; }
3457   longlong val_int();
get_copy(THD * thd)3458   Item *get_copy(THD *thd)
3459   { return get_item_copy<Item_func_cursor_found>(thd, this); }
3460 };
3461 
3462 
3463 class Item_func_cursor_notfound: public Item_func_cursor_bool_attr
3464 {
3465 public:
Item_func_cursor_notfound(THD * thd,const LEX_CSTRING * name,uint offset)3466   Item_func_cursor_notfound(THD *thd, const LEX_CSTRING *name, uint offset)
3467    :Item_func_cursor_bool_attr(thd, name, offset) { maybe_null= true; }
func_name()3468   const char *func_name() const { return "%NOTFOUND"; }
3469   longlong val_int();
get_copy(THD * thd)3470   Item *get_copy(THD *thd)
3471   { return get_item_copy<Item_func_cursor_notfound>(thd, this); }
3472 };
3473 
3474 
3475 
is_cond_or(Item * item)3476 inline bool is_cond_or(Item *item)
3477 {
3478   Item_func *func_item= item->get_item_func();
3479   return func_item && func_item->functype() == Item_func::COND_OR_FUNC;
3480 }
3481 
3482 Item *and_expressions(Item *a, Item *b, Item **org_item);
3483 
3484 class Comp_creator
3485 {
3486 public:
Comp_creator()3487   Comp_creator() {}                           /* Remove gcc warning */
~Comp_creator()3488   virtual ~Comp_creator() {}                  /* Remove gcc warning */
3489   /**
3490     Create operation with given arguments.
3491   */
3492   virtual Item_bool_rowready_func2* create(THD *thd, Item *a, Item *b)
3493                                            const = 0;
3494   /**
3495     Create operation with given arguments in swap order.
3496   */
3497   virtual Item_bool_rowready_func2* create_swap(THD *thd, Item *a, Item *b)
3498                                                 const = 0;
3499   virtual const char* symbol(bool invert) const = 0;
3500   virtual bool eqne_op() const = 0;
3501   virtual bool l_op() const = 0;
3502 };
3503 
3504 class Eq_creator :public Comp_creator
3505 {
3506 public:
Eq_creator()3507   Eq_creator() {}                             /* Remove gcc warning */
~Eq_creator()3508   virtual ~Eq_creator() {}                    /* Remove gcc warning */
3509   Item_bool_rowready_func2* create(THD *thd, Item *a, Item *b) const;
3510   Item_bool_rowready_func2* create_swap(THD *thd, Item *a, Item *b) const;
symbol(bool invert)3511   const char* symbol(bool invert) const { return invert? "<>" : "="; }
eqne_op()3512   bool eqne_op() const { return 1; }
l_op()3513   bool l_op() const { return 0; }
3514 };
3515 
3516 class Ne_creator :public Comp_creator
3517 {
3518 public:
Ne_creator()3519   Ne_creator() {}                             /* Remove gcc warning */
~Ne_creator()3520   virtual ~Ne_creator() {}                    /* Remove gcc warning */
3521   Item_bool_rowready_func2* create(THD *thd, Item *a, Item *b) const;
3522   Item_bool_rowready_func2* create_swap(THD *thd, Item *a, Item *b) const;
symbol(bool invert)3523   const char* symbol(bool invert) const { return invert? "=" : "<>"; }
eqne_op()3524   bool eqne_op() const { return 1; }
l_op()3525   bool l_op() const { return 0; }
3526 };
3527 
3528 class Gt_creator :public Comp_creator
3529 {
3530 public:
Gt_creator()3531   Gt_creator() {}                             /* Remove gcc warning */
~Gt_creator()3532   virtual ~Gt_creator() {}                    /* Remove gcc warning */
3533   Item_bool_rowready_func2* create(THD *thd, Item *a, Item *b) const;
3534   Item_bool_rowready_func2* create_swap(THD *thd, Item *a, Item *b) const;
symbol(bool invert)3535   const char* symbol(bool invert) const { return invert? "<=" : ">"; }
eqne_op()3536   bool eqne_op() const { return 0; }
l_op()3537   bool l_op() const { return 0; }
3538 };
3539 
3540 class Lt_creator :public Comp_creator
3541 {
3542 public:
Lt_creator()3543   Lt_creator() {}                             /* Remove gcc warning */
~Lt_creator()3544   virtual ~Lt_creator() {}                    /* Remove gcc warning */
3545   Item_bool_rowready_func2* create(THD *thd, Item *a, Item *b) const;
3546   Item_bool_rowready_func2* create_swap(THD *thd, Item *a, Item *b) const;
symbol(bool invert)3547   const char* symbol(bool invert) const { return invert? ">=" : "<"; }
eqne_op()3548   bool eqne_op() const { return 0; }
l_op()3549   bool l_op() const { return 1; }
3550 };
3551 
3552 class Ge_creator :public Comp_creator
3553 {
3554 public:
Ge_creator()3555   Ge_creator() {}                             /* Remove gcc warning */
~Ge_creator()3556   virtual ~Ge_creator() {}                    /* Remove gcc warning */
3557   Item_bool_rowready_func2* create(THD *thd, Item *a, Item *b) const;
3558   Item_bool_rowready_func2* create_swap(THD *thd, Item *a, Item *b) const;
symbol(bool invert)3559   const char* symbol(bool invert) const { return invert? "<" : ">="; }
eqne_op()3560   bool eqne_op() const { return 0; }
l_op()3561   bool l_op() const { return 0; }
3562 };
3563 
3564 class Le_creator :public Comp_creator
3565 {
3566 public:
Le_creator()3567   Le_creator() {}                             /* Remove gcc warning */
~Le_creator()3568   virtual ~Le_creator() {}                    /* Remove gcc warning */
3569   Item_bool_rowready_func2* create(THD *thd, Item *a, Item *b) const;
3570   Item_bool_rowready_func2* create_swap(THD *thd, Item *a, Item *b) const;
symbol(bool invert)3571   const char* symbol(bool invert) const { return invert? ">" : "<="; }
eqne_op()3572   bool eqne_op() const { return 0; }
l_op()3573   bool l_op() const { return 1; }
3574 };
3575 
3576 /*
3577   These need definitions from this file but the variables are defined
3578   in mysqld.h. The variables really belong in this component, but for
3579   the time being we leave them in mysqld.cc to avoid merge problems.
3580 */
3581 extern Eq_creator eq_creator;
3582 extern Ne_creator ne_creator;
3583 extern Gt_creator gt_creator;
3584 extern Lt_creator lt_creator;
3585 extern Ge_creator ge_creator;
3586 extern Le_creator le_creator;
3587 
3588 #endif /* ITEM_CMPFUNC_INCLUDED */
3589