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