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