1
/* Copyright (C) 2000-2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
/* compare and test functions */
19
#ifdef USE_PRAGMA_INTERFACE
20
#pragma interface /* gcc class implementation */
23
extern Item_result item_cmp_type(Item_result a,Item_result b);
24
class Item_bool_func2;
27
typedef int (Arg_comparator::*arg_cmp_func)();
29
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
31
class Arg_comparator: public Sql_alloc
35
Item_result_field *owner;
36
Arg_comparator *comparators; // used only for compare_row()
38
/* Fields used in DATE/DATETIME comparison. */
40
enum_field_types a_type, b_type; // Types of a and b items
41
Item *a_cache, *b_cache; // Cached values of a and b items
42
bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
43
bool set_null; // TRUE <=> set owner->null_value
44
// when one of arguments is NULL.
45
enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
46
CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
47
longlong (*get_value_a_func)(THD *thd, Item ***item_arg, Item **cache_arg,
48
Item *warn_item, bool *is_null);
49
longlong (*get_value_b_func)(THD *thd, Item ***item_arg, Item **cache_arg,
50
Item *warn_item, bool *is_null);
51
bool try_year_cmp_func(Item_result type);
53
DTCollation cmp_collation;
54
/* Allow owner function to use string buffers. */
55
String value1, value2;
57
Arg_comparator(): thd(0), a_cache(0), b_cache(0), set_null(TRUE),
58
get_value_a_func(0), get_value_b_func(0) {};
59
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
60
a_cache(0), b_cache(0), set_null(TRUE),
61
get_value_a_func(0), get_value_b_func(0) {};
63
int set_compare_func(Item_result_field *owner, Item_result type);
64
inline int set_compare_func(Item_result_field *owner_arg)
66
return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
67
(*b)->result_type()));
69
int set_cmp_func(Item_result_field *owner_arg,
73
inline int set_cmp_func(Item_result_field *owner_arg,
74
Item **a1, Item **a2, bool set_null_arg)
76
set_null= set_null_arg;
77
return set_cmp_func(owner_arg, a1, a2,
78
item_cmp_type((*a1)->result_type(),
79
(*a2)->result_type()));
81
inline int compare() { return (this->*func)(); }
83
int compare_string(); // compare args[0] & args[1]
84
int compare_binary_string(); // compare args[0] & args[1]
85
int compare_real(); // compare args[0] & args[1]
86
int compare_decimal(); // compare args[0] & args[1]
87
int compare_int_signed(); // compare args[0] & args[1]
88
int compare_int_signed_unsigned();
89
int compare_int_unsigned_signed();
90
int compare_int_unsigned();
91
int compare_row(); // compare args[0] & args[1]
92
int compare_e_string(); // compare args[0] & args[1]
93
int compare_e_binary_string(); // compare args[0] & args[1]
94
int compare_e_real(); // compare args[0] & args[1]
95
int compare_e_decimal(); // compare args[0] & args[1]
96
int compare_e_int(); // compare args[0] & args[1]
97
int compare_e_int_diff_signedness();
98
int compare_e_row(); // compare args[0] & args[1]
99
int compare_real_fixed();
100
int compare_e_real_fixed();
101
int compare_datetime(); // compare args[0] & args[1] as DATETIMEs
103
static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b,
104
ulonglong *const_val_arg);
106
Item** cache_converted_constant(THD *thd, Item **value, Item **cache,
108
void set_datetime_cmp_func(Item_result_field *owner_arg, Item **a1, Item **b1);
109
static arg_cmp_func comparator_matrix [5][2];
110
inline bool is_owner_equal_func()
112
return (owner->type() == Item::FUNC_ITEM &&
113
((Item_func*)owner)->functype() == Item_func::EQUAL_FUNC);
116
friend class Item_func;
119
class Item_bool_func :public Item_int_func
122
Item_bool_func() :Item_int_func() {}
123
Item_bool_func(Item *a) :Item_int_func(a) {}
124
Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
125
Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
126
bool is_bool_func() { return 1; }
127
void fix_length_and_dec() { decimals=0; max_length=1; }
128
uint decimal_precision() const { return 1; }
133
Abstract Item class, to represent <code>X IS [NOT] (TRUE | FALSE)</code>
137
class Item_func_truth : public Item_bool_func
140
virtual bool val_bool();
141
virtual longlong val_int();
142
virtual void fix_length_and_dec();
143
virtual void print(String *str, enum_query_type query_type);
146
Item_func_truth(Item *a, bool a_value, bool a_affirmative)
147
: Item_bool_func(a), value(a_value), affirmative(a_affirmative)
154
True for <code>X IS [NOT] TRUE</code>,
155
false for <code>X IS [NOT] FALSE</code> predicates.
159
True for <code>X IS Y</code>, false for <code>X IS NOT Y</code> predicates.
161
const bool affirmative;
166
This Item represents a <code>X IS TRUE</code> boolean predicate.
169
class Item_func_istrue : public Item_func_truth
172
Item_func_istrue(Item *a) : Item_func_truth(a, true, true) {}
173
~Item_func_istrue() {}
174
virtual const char* func_name() const { return "istrue"; }
179
This Item represents a <code>X IS NOT TRUE</code> boolean predicate.
182
class Item_func_isnottrue : public Item_func_truth
185
Item_func_isnottrue(Item *a) : Item_func_truth(a, true, false) {}
186
~Item_func_isnottrue() {}
187
virtual const char* func_name() const { return "isnottrue"; }
192
This Item represents a <code>X IS FALSE</code> boolean predicate.
195
class Item_func_isfalse : public Item_func_truth
198
Item_func_isfalse(Item *a) : Item_func_truth(a, false, true) {}
199
~Item_func_isfalse() {}
200
virtual const char* func_name() const { return "isfalse"; }
205
This Item represents a <code>X IS NOT FALSE</code> boolean predicate.
208
class Item_func_isnotfalse : public Item_func_truth
211
Item_func_isnotfalse(Item *a) : Item_func_truth(a, false, false) {}
212
~Item_func_isnotfalse() {}
213
virtual const char* func_name() const { return "isnotfalse"; }
218
#define UNKNOWN ((my_bool)-1)
222
Item_in_optimizer(left_expr, Item_in_subselect(...))
224
Item_in_optimizer is used to wrap an instance of Item_in_subselect. This
225
class does the following:
226
- Evaluate the left expression and store it in Item_cache_* object (to
227
avoid re-evaluating it many times during subquery execution)
228
- Shortcut the evaluation of "NULL IN (...)" to NULL in the cases where we
229
don't care if the result is NULL or FALSE.
232
It is not quite clear why the above listed functionality should be
233
placed into a separate class called 'Item_in_optimizer'.
236
class Item_in_optimizer: public Item_bool_func
242
Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
243
UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
244
FALSE - result is FALSE
245
TRUE - result is NULL
247
my_bool result_for_null_param;
249
Item_in_optimizer(Item *a, Item_in_subselect *b):
250
Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0),
251
save_cache(0), result_for_null_param(UNKNOWN)
253
bool fix_fields(THD *, Item **);
254
bool fix_left(THD *thd, Item **ref);
258
const char *func_name() const { return "<in_optimizer>"; }
259
Item_cache **get_cache() { return &cache; }
260
void keep_top_level_cache();
266
Comp_creator() {} /* Remove gcc warning */
267
virtual ~Comp_creator() {} /* Remove gcc warning */
268
virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
269
virtual const char* symbol(bool invert) const = 0;
270
virtual bool eqne_op() const = 0;
271
virtual bool l_op() const = 0;
274
class Eq_creator :public Comp_creator
277
Eq_creator() {} /* Remove gcc warning */
278
virtual ~Eq_creator() {} /* Remove gcc warning */
279
virtual Item_bool_func2* create(Item *a, Item *b) const;
280
virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
281
virtual bool eqne_op() const { return 1; }
282
virtual bool l_op() const { return 0; }
285
class Ne_creator :public Comp_creator
288
Ne_creator() {} /* Remove gcc warning */
289
virtual ~Ne_creator() {} /* Remove gcc warning */
290
virtual Item_bool_func2* create(Item *a, Item *b) const;
291
virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
292
virtual bool eqne_op() const { return 1; }
293
virtual bool l_op() const { return 0; }
296
class Gt_creator :public Comp_creator
299
Gt_creator() {} /* Remove gcc warning */
300
virtual ~Gt_creator() {} /* Remove gcc warning */
301
virtual Item_bool_func2* create(Item *a, Item *b) const;
302
virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
303
virtual bool eqne_op() const { return 0; }
304
virtual bool l_op() const { return 0; }
307
class Lt_creator :public Comp_creator
310
Lt_creator() {} /* Remove gcc warning */
311
virtual ~Lt_creator() {} /* Remove gcc warning */
312
virtual Item_bool_func2* create(Item *a, Item *b) const;
313
virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
314
virtual bool eqne_op() const { return 0; }
315
virtual bool l_op() const { return 1; }
318
class Ge_creator :public Comp_creator
321
Ge_creator() {} /* Remove gcc warning */
322
virtual ~Ge_creator() {} /* Remove gcc warning */
323
virtual Item_bool_func2* create(Item *a, Item *b) const;
324
virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
325
virtual bool eqne_op() const { return 0; }
326
virtual bool l_op() const { return 0; }
329
class Le_creator :public Comp_creator
332
Le_creator() {} /* Remove gcc warning */
333
virtual ~Le_creator() {} /* Remove gcc warning */
334
virtual Item_bool_func2* create(Item *a, Item *b) const;
335
virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
336
virtual bool eqne_op() const { return 0; }
337
virtual bool l_op() const { return 1; }
340
class Item_bool_func2 :public Item_int_func
341
{ /* Bool with 2 string args */
347
Item_bool_func2(Item *a,Item *b)
348
:Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(FALSE) {}
349
void fix_length_and_dec();
352
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, TRUE);
354
optimize_type select_optimize() const { return OPTIMIZE_OP; }
355
virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
356
bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
358
virtual inline void print(String *str, enum_query_type query_type)
360
Item_func::print_op(str, query_type);
363
bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
364
bool is_bool_func() { return 1; }
365
CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
366
uint decimal_precision() const { return 1; }
367
void top_level_item() { abort_on_null= TRUE; }
369
friend class Arg_comparator;
372
class Item_bool_rowready_func2 :public Item_bool_func2
375
Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b)
377
allowed_arg_cols= 0; // Fetch this value from first argument
379
Item *neg_transformer(THD *thd);
380
virtual Item *negated_item();
381
bool subst_argument_checker(uchar **arg) { return TRUE; }
384
class Item_func_not :public Item_bool_func
387
Item_func_not(Item *a) :Item_bool_func(a) {}
389
enum Functype functype() const { return NOT_FUNC; }
390
const char *func_name() const { return "not"; }
391
Item *neg_transformer(THD *thd);
392
virtual void print(String *str, enum_query_type query_type);
395
class Item_maxmin_subselect;
398
trigcond<param>(arg) ::= param? arg : TRUE
400
The class Item_func_trig_cond is used for guarded predicates
401
which are employed only for internal purposes.
402
A guarded predicate is an object consisting of an a regular or
403
a guarded predicate P and a pointer to a boolean guard variable g.
404
A guarded predicate P/g is evaluated to true if the value of the
405
guard g is false, otherwise it is evaluated to the same value that
406
the predicate P: val(P/g)= g ? val(P):true.
407
Guarded predicates allow us to include predicates into a conjunction
408
conditionally. Currently they are utilized for pushed down predicates
409
in queries with outer join operations.
411
In the future, probably, it makes sense to extend this class to
412
the objects consisting of three elements: a predicate P, a pointer
413
to a variable g and a firing value s with following evaluation
414
rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
415
one item for the objects of the form P/g1/g2...
417
Objects of this class are built only for query execution after
418
the execution plan has been already selected. That's why this
419
class needs only val_int out of generic methods.
421
Current uses of Item_func_trig_cond objects:
422
- To wrap selection conditions when executing outer joins
423
- To wrap condition that is pushed down into subquery
426
class Item_func_trig_cond: public Item_bool_func
430
Item_func_trig_cond(Item *a, bool *f) : Item_bool_func(a) { trig_var= f; }
431
longlong val_int() { return *trig_var ? args[0]->val_int() : 1; }
432
enum Functype functype() const { return TRIG_COND_FUNC; };
433
const char *func_name() const { return "trigcond"; };
434
bool const_item() const { return FALSE; }
435
bool *get_trig_var() { return trig_var; }
438
class Item_func_not_all :public Item_func_not
440
/* allow to check presence of values in max/min optimization */
441
Item_sum_hybrid *test_sum_item;
442
Item_maxmin_subselect *test_sub_item;
448
Item_func_not_all(Item *a)
449
:Item_func_not(a), test_sum_item(0), test_sub_item(0), abort_on_null(0),
452
virtual void top_level_item() { abort_on_null= 1; }
453
bool top_level() { return abort_on_null; }
455
enum Functype functype() const { return NOT_ALL_FUNC; }
456
const char *func_name() const { return "<not>"; }
457
virtual void print(String *str, enum_query_type query_type);
458
void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
459
void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
460
bool empty_underlying_subquery();
461
Item *neg_transformer(THD *thd);
465
class Item_func_nop_all :public Item_func_not_all
469
Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
471
const char *func_name() const { return "<nop>"; }
472
Item *neg_transformer(THD *thd);
476
class Item_func_eq :public Item_bool_rowready_func2
479
Item_func_eq(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
481
enum Functype functype() const { return EQ_FUNC; }
482
enum Functype rev_functype() const { return EQ_FUNC; }
483
cond_result eq_cmp_result() const { return COND_TRUE; }
484
const char *func_name() const { return "="; }
485
Item *negated_item();
488
class Item_func_equal :public Item_bool_rowready_func2
491
Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
493
void fix_length_and_dec();
494
table_map not_null_tables() const { return 0; }
495
enum Functype functype() const { return EQUAL_FUNC; }
496
enum Functype rev_functype() const { return EQUAL_FUNC; }
497
cond_result eq_cmp_result() const { return COND_TRUE; }
498
const char *func_name() const { return "<=>"; }
499
Item *neg_transformer(THD *thd) { return 0; }
503
class Item_func_ge :public Item_bool_rowready_func2
506
Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
508
enum Functype functype() const { return GE_FUNC; }
509
enum Functype rev_functype() const { return LE_FUNC; }
510
cond_result eq_cmp_result() const { return COND_TRUE; }
511
const char *func_name() const { return ">="; }
512
Item *negated_item();
516
class Item_func_gt :public Item_bool_rowready_func2
519
Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
521
enum Functype functype() const { return GT_FUNC; }
522
enum Functype rev_functype() const { return LT_FUNC; }
523
cond_result eq_cmp_result() const { return COND_FALSE; }
524
const char *func_name() const { return ">"; }
525
Item *negated_item();
529
class Item_func_le :public Item_bool_rowready_func2
532
Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
534
enum Functype functype() const { return LE_FUNC; }
535
enum Functype rev_functype() const { return GE_FUNC; }
536
cond_result eq_cmp_result() const { return COND_TRUE; }
537
const char *func_name() const { return "<="; }
538
Item *negated_item();
542
class Item_func_lt :public Item_bool_rowready_func2
545
Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
547
enum Functype functype() const { return LT_FUNC; }
548
enum Functype rev_functype() const { return GT_FUNC; }
549
cond_result eq_cmp_result() const { return COND_FALSE; }
550
const char *func_name() const { return "<"; }
551
Item *negated_item();
555
class Item_func_ne :public Item_bool_rowready_func2
558
Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
560
enum Functype functype() const { return NE_FUNC; }
561
cond_result eq_cmp_result() const { return COND_FALSE; }
562
optimize_type select_optimize() const { return OPTIMIZE_KEY; }
563
const char *func_name() const { return "<>"; }
564
Item *negated_item();
569
The class Item_func_opt_neg is defined to factor out the functionality
570
common for the classes Item_func_between and Item_func_in. The objects
571
of these classes can express predicates or there negations.
572
The alternative approach would be to create pairs Item_func_between,
573
Item_func_notbetween and Item_func_in, Item_func_notin.
577
class Item_func_opt_neg :public Item_int_func
580
bool negated; /* <=> the item represents NOT <func> */
581
bool pred_level; /* <=> [NOT] <func> is used on a predicate level */
583
Item_func_opt_neg(Item *a, Item *b, Item *c)
584
:Item_int_func(a, b, c), negated(0), pred_level(0) {}
585
Item_func_opt_neg(List<Item> &list)
586
:Item_int_func(list), negated(0), pred_level(0) {}
588
inline void negate() { negated= !negated; }
589
inline void top_level_item() { pred_level= 1; }
590
Item *neg_transformer(THD *thd)
595
bool eq(const Item *item, bool binary_cmp) const;
596
bool subst_argument_checker(uchar **arg) { return TRUE; }
600
class Item_func_between :public Item_func_opt_neg
602
DTCollation cmp_collation;
604
Item_result cmp_type;
605
String value0,value1,value2;
606
/* TRUE <=> arguments will be compared as dates. */
607
bool compare_as_dates;
608
/* Comparators used for DATE/DATETIME comparison. */
609
Arg_comparator ge_cmp, le_cmp;
610
Item_func_between(Item *a, Item *b, Item *c)
611
:Item_func_opt_neg(a, b, c), compare_as_dates(FALSE) {}
613
optimize_type select_optimize() const { return OPTIMIZE_KEY; }
614
enum Functype functype() const { return BETWEEN; }
615
const char *func_name() const { return "between"; }
616
bool fix_fields(THD *, Item **);
617
void fix_length_and_dec();
618
virtual void print(String *str, enum_query_type query_type);
619
bool is_bool_func() { return 1; }
620
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
621
uint decimal_precision() const { return 1; }
625
class Item_func_strcmp :public Item_bool_func2
628
Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
630
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
631
const char *func_name() const { return "strcmp"; }
633
virtual inline void print(String *str, enum_query_type query_type)
635
Item_func::print(str, query_type);
640
struct interval_range
647
class Item_func_interval :public Item_int_func
650
my_bool use_decimal_comparison;
651
interval_range *intervals;
653
Item_func_interval(Item_row *a)
654
:Item_int_func(a),row(a),intervals(0)
656
allowed_arg_cols= 0; // Fetch this value from first argument
659
void fix_length_and_dec();
660
const char *func_name() const { return "interval"; }
661
uint decimal_precision() const { return 2; }
665
class Item_func_coalesce :public Item_func_numhybrid
668
enum_field_types cached_field_type;
669
Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
671
Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
674
String *str_op(String *);
675
my_decimal *decimal_op(my_decimal *);
676
void fix_length_and_dec();
677
void find_num_type() {}
678
enum Item_result result_type () const { return hybrid_type; }
679
const char *func_name() const { return "coalesce"; }
680
table_map not_null_tables() const { return 0; }
681
enum_field_types field_type() const { return cached_field_type; }
685
class Item_func_ifnull :public Item_func_coalesce
688
bool field_type_defined;
690
Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
693
String *str_op(String *str);
694
my_decimal *decimal_op(my_decimal *);
695
enum_field_types field_type() const;
696
void fix_length_and_dec();
697
const char *func_name() const { return "ifnull"; }
698
Field *tmp_table_field(TABLE *table);
699
uint decimal_precision() const;
703
class Item_func_if :public Item_func
705
enum Item_result cached_result_type;
706
enum_field_types cached_field_type;
708
Item_func_if(Item *a,Item *b,Item *c)
709
:Item_func(a,b,c), cached_result_type(INT_RESULT)
713
String *val_str(String *str);
714
my_decimal *val_decimal(my_decimal *);
715
enum Item_result result_type () const { return cached_result_type; }
716
enum_field_types field_type() const { return cached_field_type; }
717
bool fix_fields(THD *, Item **);
718
void fix_length_and_dec();
719
uint decimal_precision() const;
720
const char *func_name() const { return "if"; }
724
class Item_func_nullif :public Item_bool_func2
726
enum Item_result cached_result_type;
728
Item_func_nullif(Item *a,Item *b)
729
:Item_bool_func2(a,b), cached_result_type(INT_RESULT)
733
String *val_str(String *str);
734
my_decimal *val_decimal(my_decimal *);
735
enum Item_result result_type () const { return cached_result_type; }
736
void fix_length_and_dec();
737
uint decimal_precision() const { return args[0]->decimal_precision(); }
738
const char *func_name() const { return "nullif"; }
740
virtual inline void print(String *str, enum_query_type query_type)
742
Item_func::print(str, query_type);
745
table_map not_null_tables() const { return 0; }
750
/* Functions to handle the optimized IN */
753
/* A vector of values of some type */
755
class in_vector :public Sql_alloc
761
CHARSET_INFO *collation;
765
in_vector(uint elements,uint element_length,qsort2_cmp cmp_func,
766
CHARSET_INFO *cmp_coll)
767
:base((char*) sql_calloc(elements*element_length)),
768
size(element_length), compare(cmp_func), collation(cmp_coll),
769
count(elements), used_count(elements) {}
770
virtual ~in_vector() {}
771
virtual void set(uint pos,Item *item)=0;
772
virtual uchar *get_value(Item *item)=0;
775
my_qsort2(base,used_count,size,compare,collation);
777
int find(Item *item);
780
Create an instance of Item_{type} (e.g. Item_decimal) constant object
781
which type allows it to hold an element of this vector without any
783
The purpose of this function is to be able to get elements of this
784
vector in form of Item_xxx constants without creating Item_xxx object
785
for every array element you get (i.e. this implements "FlyWeight" pattern)
787
virtual Item* create_item() { return NULL; }
790
Store the value at position #pos into provided item object
793
pos Index of value to store
794
item Constant item to store value into. The item must be of the same
795
type that create_item() returns.
797
virtual void value_to_item(uint pos, Item *item) { }
799
/* Compare values number pos1 and pos2 for equality */
800
bool compare_elems(uint pos1, uint pos2)
802
return test(compare(collation, base + pos1*size, base + pos2*size));
804
virtual Item_result result_type()= 0;
807
class in_string :public in_vector
809
char buff[STRING_BUFFER_USUAL_SIZE];
812
in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs);
814
void set(uint pos,Item *item);
815
uchar *get_value(Item *item);
818
return new Item_string(collation);
820
void value_to_item(uint pos, Item *item)
822
String *str=((String*) base)+pos;
823
Item_string *to= (Item_string*)item;
826
Item_result result_type() { return STRING_RESULT; }
829
class in_longlong :public in_vector
833
Here we declare a temporary variable (tmp) of the same type as the
834
elements of this vector. tmp is used in finding if a given value is in
837
struct packed_longlong
840
longlong unsigned_flag; // Use longlong, not bool, to preserve alignment
843
in_longlong(uint elements);
844
void set(uint pos,Item *item);
845
uchar *get_value(Item *item);
850
We're created a signed INT, this may not be correct in
851
general case (see BUG#19342).
853
return new Item_int((longlong)0);
855
void value_to_item(uint pos, Item *item)
857
((Item_int*) item)->value= ((packed_longlong*) base)[pos].val;
858
((Item_int*) item)->unsigned_flag= (my_bool)
859
((packed_longlong*) base)[pos].unsigned_flag;
861
Item_result result_type() { return INT_RESULT; }
863
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
868
Class to represent a vector of constant DATE/DATETIME values.
869
Values are obtained with help of the get_datetime_value() function.
870
If the left item is a constant one then its value is cached in the
873
class in_datetime :public in_longlong
877
/* An item used to issue warnings. */
879
/* Cache for the left item. */
882
in_datetime(Item *warn_item_arg, uint elements)
883
:in_longlong(elements), thd(current_thd), warn_item(warn_item_arg),
885
void set(uint pos,Item *item);
886
uchar *get_value(Item *item);
887
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
891
class in_double :public in_vector
895
in_double(uint elements);
896
void set(uint pos,Item *item);
897
uchar *get_value(Item *item);
900
return new Item_float(0.0, 0);
902
void value_to_item(uint pos, Item *item)
904
((Item_float*)item)->value= ((double*) base)[pos];
906
Item_result result_type() { return REAL_RESULT; }
910
class in_decimal :public in_vector
914
in_decimal(uint elements);
915
void set(uint pos, Item *item);
916
uchar *get_value(Item *item);
919
return new Item_decimal(0, FALSE);
921
void value_to_item(uint pos, Item *item)
923
my_decimal *dec= ((my_decimal *)base) + pos;
924
Item_decimal *item_dec= (Item_decimal*)item;
925
item_dec->set_decimal_value(dec);
927
Item_result result_type() { return DECIMAL_RESULT; }
933
** Classes for easy comparing of non const items
936
class cmp_item :public Sql_alloc
939
CHARSET_INFO *cmp_charset;
940
cmp_item() { cmp_charset= &my_charset_bin; }
941
virtual ~cmp_item() {}
942
virtual void store_value(Item *item)= 0;
943
virtual int cmp(Item *item)= 0;
944
// for optimized IN with row
945
virtual int compare(cmp_item *item)= 0;
946
static cmp_item* get_comparator(Item_result type, CHARSET_INFO *cs);
947
virtual cmp_item *make_same()= 0;
948
virtual void store_value_by_template(cmp_item *tmpl, Item *item)
954
class cmp_item_string :public cmp_item
959
cmp_item_string () {}
960
cmp_item_string (CHARSET_INFO *cs) { cmp_charset= cs; }
961
void set_charset(CHARSET_INFO *cs) { cmp_charset= cs; }
962
friend class cmp_item_sort_string;
963
friend class cmp_item_sort_string_in_static;
966
class cmp_item_sort_string :public cmp_item_string
969
char value_buff[STRING_BUFFER_USUAL_SIZE];
972
cmp_item_sort_string():
974
cmp_item_sort_string(CHARSET_INFO *cs):
976
value(value_buff, sizeof(value_buff), cs) {}
977
void store_value(Item *item)
979
value_res= item->val_str(&value);
983
char buff[STRING_BUFFER_USUAL_SIZE];
984
String tmp(buff, sizeof(buff), cmp_charset), *res;
985
res= arg->val_str(&tmp);
986
return (value_res ? (res ? sortcmp(value_res, res, cmp_charset) : 1) :
989
int compare(cmp_item *ci)
991
cmp_item_string *l_cmp= (cmp_item_string *) ci;
992
return sortcmp(value_res, l_cmp->value_res, cmp_charset);
994
cmp_item *make_same();
995
void set_charset(CHARSET_INFO *cs)
998
value.set_quick(value_buff, sizeof(value_buff), cs);
1002
class cmp_item_int :public cmp_item
1006
cmp_item_int() {} /* Remove gcc warning */
1007
void store_value(Item *item)
1009
value= item->val_int();
1013
return value != arg->val_int();
1015
int compare(cmp_item *ci)
1017
cmp_item_int *l_cmp= (cmp_item_int *)ci;
1018
return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
1020
cmp_item *make_same();
1024
Compare items in the DATETIME context.
1025
Values are obtained with help of the get_datetime_value() function.
1026
If the left item is a constant one then its value is cached in the
1027
lval_cache variable.
1029
class cmp_item_datetime :public cmp_item
1034
/* Item used for issuing warnings. */
1036
/* Cache for the left item. */
1039
cmp_item_datetime(Item *warn_item_arg)
1040
:thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
1041
void store_value(Item *item);
1043
int compare(cmp_item *ci);
1044
cmp_item *make_same();
1047
class cmp_item_real :public cmp_item
1051
cmp_item_real() {} /* Remove gcc warning */
1052
void store_value(Item *item)
1054
value= item->val_real();
1058
return value != arg->val_real();
1060
int compare(cmp_item *ci)
1062
cmp_item_real *l_cmp= (cmp_item_real *) ci;
1063
return (value < l_cmp->value)? -1 : ((value == l_cmp->value) ? 0 : 1);
1065
cmp_item *make_same();
1069
class cmp_item_decimal :public cmp_item
1073
cmp_item_decimal() {} /* Remove gcc warning */
1074
void store_value(Item *item);
1076
int compare(cmp_item *c);
1077
cmp_item *make_same();
1082
cmp_item for optimized IN with row (right part string, which never
1086
class cmp_item_sort_string_in_static :public cmp_item_string
1091
cmp_item_sort_string_in_static(CHARSET_INFO *cs):
1092
cmp_item_string(cs) {}
1093
void store_value(Item *item)
1095
value_res= item->val_str(&value);
1099
// Should never be called
1103
int compare(cmp_item *ci)
1105
cmp_item_string *l_cmp= (cmp_item_string *) ci;
1106
return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1108
cmp_item *make_same()
1110
return new cmp_item_sort_string_in_static(cmp_charset);
1116
The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1119
When there is no expression between CASE and the first WHEN
1120
(the CASE expression) then this function simple checks all WHEN expressions
1121
one after another. When some WHEN expression evaluated to TRUE then the
1122
value of the corresponding THEN expression is returned.
1124
When the CASE expression is specified then it is compared to each WHEN
1125
expression individually. When an equal WHEN expression is found
1126
corresponding THEN expression is returned.
1127
In order to do correct comparisons several comparators are used. One for
1128
each result type. Different result types that are used in particular
1129
CASE ... END expression are collected in the fix_length_and_dec() member
1130
function and only comparators for there result types are used.
1133
class Item_func_case :public Item_func
1135
int first_expr_num, else_expr_num;
1136
enum Item_result cached_result_type, left_result_type;
1139
Item_result cmp_type;
1140
DTCollation cmp_collation;
1141
enum_field_types cached_field_type;
1142
cmp_item *cmp_items[5]; /* For all result types */
1143
cmp_item *case_item;
1145
Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
1146
:Item_func(), first_expr_num(-1), else_expr_num(-1),
1147
cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
1149
ncases= list.elements;
1152
first_expr_num= list.elements;
1153
list.push_back(first_expr_arg);
1157
else_expr_num= list.elements;
1158
list.push_back(else_expr_arg);
1160
set_arguments(list);
1161
bzero(&cmp_items, sizeof(cmp_items));
1165
String *val_str(String *);
1166
my_decimal *val_decimal(my_decimal *);
1167
bool fix_fields(THD *thd, Item **ref);
1168
void fix_length_and_dec();
1169
uint decimal_precision() const;
1170
table_map not_null_tables() const { return 0; }
1171
enum Item_result result_type () const { return cached_result_type; }
1172
enum_field_types field_type() const { return cached_field_type; }
1173
const char *func_name() const { return "case"; }
1174
virtual void print(String *str, enum_query_type query_type);
1175
Item *find_item(String *str);
1176
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1178
void agg_str_lengths(Item *arg);
1179
void agg_num_lengths(Item *arg);
1183
The Item_func_in class implements the in_expr IN(values_list) function.
1185
The current implementation distinguishes 2 cases:
1186
1) all items in the value_list are constants and have the same
1187
result type. This case is handled by in_vector class.
1188
2) items in the value_list have different result types or there is some
1190
In this case Item_func_in employs several cmp_item objects to performs
1191
comparisons of in_expr and an item from the values_list. One cmp_item
1192
object for each result type. Different result types are collected in the
1193
fix_length_and_dec() member function by means of collect_cmp_types()
1196
class Item_func_in :public Item_func_opt_neg
1200
an array of values when the right hand arguments of IN
1201
are all SQL constant and there are no nulls
1206
true when all arguments of the IN clause are of compatible types
1207
and can be used safely as comparisons for key conditions
1209
bool arg_types_compatible;
1210
Item_result left_result_type;
1211
cmp_item *cmp_items[6]; /* One cmp_item for each result type */
1212
DTCollation cmp_collation;
1214
Item_func_in(List<Item> &list)
1215
:Item_func_opt_neg(list), array(0), have_null(0),
1216
arg_types_compatible(FALSE)
1218
bzero(&cmp_items, sizeof(cmp_items));
1219
allowed_arg_cols= 0; // Fetch this value from first argument
1222
bool fix_fields(THD *, Item **);
1223
void fix_length_and_dec();
1224
uint decimal_precision() const { return 1; }
1228
DBUG_ENTER("Item_func_in::cleanup");
1229
Item_int_func::cleanup();
1232
for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1234
delete cmp_items[i];
1239
optimize_type select_optimize() const
1240
{ return OPTIMIZE_KEY; }
1241
virtual void print(String *str, enum_query_type query_type);
1242
enum Functype functype() const { return IN_FUNC; }
1243
const char *func_name() const { return " IN "; }
1244
bool nulls_in_row();
1245
bool is_bool_func() { return 1; }
1246
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1249
class cmp_item_row :public cmp_item
1251
cmp_item **comparators;
1254
cmp_item_row(): comparators(0), n(0) {}
1256
void store_value(Item *item);
1257
inline void alloc_comparators();
1259
int compare(cmp_item *arg);
1260
cmp_item *make_same();
1261
void store_value_by_template(cmp_item *tmpl, Item *);
1262
friend void Item_func_in::fix_length_and_dec();
1266
class in_row :public in_vector
1270
in_row(uint elements, Item *);
1272
void set(uint pos,Item *item);
1273
uchar *get_value(Item *item);
1274
friend void Item_func_in::fix_length_and_dec();
1275
Item_result result_type() { return ROW_RESULT; }
1278
/* Functions used by where clause */
1280
class Item_func_isnull :public Item_bool_func
1283
longlong cached_value;
1285
Item_func_isnull(Item *a) :Item_bool_func(a) {}
1287
enum Functype functype() const { return ISNULL_FUNC; }
1288
void fix_length_and_dec()
1290
decimals=0; max_length=1; maybe_null=0;
1291
update_used_tables();
1293
const char *func_name() const { return "isnull"; }
1294
/* Optimize case of not_null_column IS NULL */
1295
virtual void update_used_tables()
1297
if (!args[0]->maybe_null)
1299
used_tables_cache= 0; /* is always false */
1300
const_item_cache= 1;
1301
cached_value= (longlong) 0;
1305
args[0]->update_used_tables();
1306
if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) &&
1309
/* Remember if the value is always NULL or never NULL */
1310
cached_value= (longlong) args[0]->is_null();
1314
table_map not_null_tables() const { return 0; }
1315
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1316
Item *neg_transformer(THD *thd);
1317
CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1320
/* Functions used by HAVING for rewriting IN subquery */
1322
class Item_in_subselect;
1325
This is like IS NOT NULL but it also remembers if it ever has
1328
class Item_is_not_null_test :public Item_func_isnull
1330
Item_in_subselect* owner;
1332
Item_is_not_null_test(Item_in_subselect* ow, Item *a)
1333
:Item_func_isnull(a), owner(ow)
1335
enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
1337
const char *func_name() const { return "<is_not_null_test>"; }
1338
void update_used_tables();
1340
we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
1342
table_map used_tables() const
1343
{ return used_tables_cache | RAND_TABLE_BIT; }
1347
class Item_func_isnotnull :public Item_bool_func
1351
Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
1353
enum Functype functype() const { return ISNOTNULL_FUNC; }
1354
void fix_length_and_dec()
1356
decimals=0; max_length=1; maybe_null=0;
1358
const char *func_name() const { return "isnotnull"; }
1359
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1360
table_map not_null_tables() const
1361
{ return abort_on_null ? not_null_tables_cache : 0; }
1362
Item *neg_transformer(THD *thd);
1363
virtual void print(String *str, enum_query_type query_type);
1364
CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1365
void top_level_item() { abort_on_null=1; }
1369
class Item_func_like :public Item_bool_func2
1371
// Turbo Boyer-Moore data
1372
bool canDoTurboBM; // pattern is '%abcd%' case
1373
const char* pattern;
1376
// TurboBM buffers, *this is owner
1377
int* bmGs; // good suffix shift table, size is pattern_len + 1
1378
int* bmBc; // bad character shift table, size is alphabet_size
1380
void turboBM_compute_suffixes(int* suff);
1381
void turboBM_compute_good_suffix_shifts(int* suff);
1382
void turboBM_compute_bad_character_shifts();
1383
bool turboBM_matches(const char* text, int text_len) const;
1384
enum { alphabet_size = 256 };
1388
bool escape_used_in_parsing;
1393
Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1394
:Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0),
1395
bmGs(0), bmBc(0), escape_item(escape_arg),
1396
escape_used_in_parsing(escape_used) {}
1398
enum Functype functype() const { return LIKE_FUNC; }
1399
optimize_type select_optimize() const;
1400
cond_result eq_cmp_result() const { return COND_TRUE; }
1401
const char *func_name() const { return "like"; }
1402
bool fix_fields(THD *thd, Item **ref);
1408
#include "my_regex.h"
1410
class Item_func_regex :public Item_bool_func
1413
bool regex_compiled;
1414
bool regex_is_const;
1416
DTCollation cmp_collation;
1417
CHARSET_INFO *regex_lib_charset;
1418
int regex_lib_flags;
1420
int regcomp(bool send_error);
1422
Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b),
1423
regex_compiled(0),regex_is_const(0) {}
1426
bool fix_fields(THD *thd, Item **ref);
1427
const char *func_name() const { return "regexp"; }
1429
virtual inline void print(String *str, enum_query_type query_type)
1431
print_op(str, query_type);
1434
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1439
class Item_func_regex :public Item_bool_func
1442
Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b) {}
1443
longlong val_int() { return 0;}
1444
const char *func_name() const { return "regex"; }
1446
virtual inline void print(String *str, enum_query_type query_type)
1448
print_op(str, query_type);
1452
#endif /* USE_REGEX */
1455
typedef class Item COND;
1457
class Item_cond :public Item_bool_func
1462
table_map and_tables_cache;
1465
/* Item_cond() is only used to create top level items */
1466
Item_cond(): Item_bool_func(), abort_on_null(1)
1467
{ const_item_cache=0; }
1468
Item_cond(Item *i1,Item *i2)
1469
:Item_bool_func(), abort_on_null(0)
1474
Item_cond(THD *thd, Item_cond *item);
1475
Item_cond(List<Item> &nlist)
1476
:Item_bool_func(), list(nlist), abort_on_null(0) {}
1477
bool add(Item *item)
1480
return list.push_back(item);
1482
bool add_at_head(Item *item)
1485
return list.push_front(item);
1487
void add_at_head(List<Item> *nlist)
1489
DBUG_ASSERT(nlist->elements);
1490
list.prepand(nlist);
1492
bool fix_fields(THD *, Item **ref);
1494
enum Type type() const { return COND_ITEM; }
1495
List<Item>* argument_list() { return &list; }
1496
table_map used_tables() const;
1497
void update_used_tables();
1498
virtual void print(String *str, enum_query_type query_type);
1499
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
1500
friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
1502
void top_level_item() { abort_on_null=1; }
1503
void copy_andor_arguments(THD *thd, Item_cond *item);
1504
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1505
Item *transform(Item_transformer transformer, uchar *arg);
1506
void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1507
void neg_arguments(THD *thd);
1508
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
1509
bool subst_argument_checker(uchar **arg) { return TRUE; }
1510
Item *compile(Item_analyzer analyzer, uchar **arg_p,
1511
Item_transformer transformer, uchar *arg_t);
1516
The class Item_equal is used to represent conjunctions of equality
1517
predicates of the form field1 = field2, and field=const in where
1518
conditions and on expressions.
1520
All equality predicates of the form field1=field2 contained in a
1521
conjunction are substituted for a sequence of items of this class.
1522
An item of this class Item_equal(f1,f2,...fk) represents a
1523
multiple equality f1=f2=...=fk.
1525
If a conjunction contains predicates f1=f2 and f2=f3, a new item of
1526
this class is created Item_equal(f1,f2,f3) representing the multiple
1527
equality f1=f2=f3 that substitutes the above equality predicates in
1529
A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1530
substituted for the item representing the same multiple equality
1532
An item Item_equal(f1,f2) can appear instead of a conjunction of
1533
f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1535
An item of the class Item_equal inherits equalities from outer
1538
Suppose we have a where condition of the following form:
1539
WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
1541
f1=f2 will be substituted for Item_equal(f1,f2);
1542
f3=f4 and f3=f5 will be substituted for Item_equal(f3,f4,f5);
1543
f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1545
An object of the class Item_equal can contain an optional constant
1546
item c. Then it represents a multiple equality of the form
1549
Objects of the class Item_equal are used for the following:
1551
1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
1552
pair of tables ti and tj as joined by an equi-condition.
1553
Thus it provide us with additional access paths from table to table.
1555
2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
1556
SARGable predicates:
1557
f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
1558
It also can give us additional index scans and can allow us to
1559
improve selectivity estimates.
1561
3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
1562
selected execution plan for the query: if table ti is accessed
1563
before the table tj then in any predicate P in the where condition
1564
the occurrence of tj.fj is substituted for ti.fi. This can allow
1565
an evaluation of the predicate at an earlier step.
1567
When feature 1 is supported they say that join transitive closure
1569
When feature 2 is supported they say that search argument transitive
1570
closure is employed.
1571
Both features are usually supported by preprocessing original query and
1572
adding additional predicates.
1573
We do not just add predicates, we rather dynamically replace some
1574
predicates that can not be used to access tables in the investigated
1575
plan for those, obtained by substitution of some fields for equal fields,
1578
Prepared Statements/Stored Procedures note: instances of class
1579
Item_equal are created only at the time a PS/SP is executed and
1580
are deleted in the end of execution. All changes made to these
1581
objects need not be registered in the list of changes of the parse
1582
tree and do not harm PS/SP re-execution.
1584
Item equal objects are employed only at the optimize phase. Usually they are
1585
not supposed to be evaluated. Yet in some cases we call the method val_int()
1586
for them. We have to take care of restricting the predicate such an
1587
object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
1590
class Item_equal: public Item_bool_func
1592
List<Item_field> fields; /* list of equal field items */
1593
Item *const_item; /* optional constant item equal to fields items */
1594
cmp_item *eval_item;
1597
bool compare_as_dates;
1600
: Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
1601
{ const_item_cache=0 ;}
1602
Item_equal(Item_field *f1, Item_field *f2);
1603
Item_equal(Item *c, Item_field *f);
1604
Item_equal(Item_equal *item_equal);
1605
inline Item* get_const() { return const_item; }
1606
void compare_const(Item *c);
1607
void add(Item *c, Item_field *f);
1609
void add(Item_field *f);
1611
bool contains(Field *field);
1612
Item_field* get_first() { return fields.head(); }
1613
void merge(Item_equal *item);
1614
void update_const();
1615
enum Functype functype() const { return MULT_EQUAL_FUNC; }
1617
const char *func_name() const { return "multiple equal"; }
1618
optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1619
void sort(Item_field_cmpfunc cmp, void *arg);
1620
friend class Item_equal_iterator;
1621
void fix_length_and_dec();
1622
bool fix_fields(THD *thd, Item **ref);
1623
void update_used_tables();
1624
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1625
Item *transform(Item_transformer transformer, uchar *arg);
1626
virtual void print(String *str, enum_query_type query_type);
1627
CHARSET_INFO *compare_collation()
1628
{ return fields.head()->collation.collation; }
1631
class COND_EQUAL: public Sql_alloc
1634
uint max_members; /* max number of members the current level
1635
list and all lower level lists */
1636
COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
1637
List<Item_equal> current_level; /* list of multiple equalities of
1638
the current and level */
1646
class Item_equal_iterator : public List_iterator_fast<Item_field>
1649
inline Item_equal_iterator(Item_equal &item_equal)
1650
:List_iterator_fast<Item_field> (item_equal.fields)
1652
inline Item_field* operator++(int)
1654
Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1657
inline void rewind(void)
1659
List_iterator_fast<Item_field>::rewind();
1663
class Item_cond_and :public Item_cond
1666
COND_EQUAL cond_equal; /* contains list of Item_equal objects for
1667
the current and level and reference
1668
to multiple equalities of upper and levels */
1669
Item_cond_and() :Item_cond() {}
1670
Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1671
Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
1672
Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1673
enum Functype functype() const { return COND_AND_FUNC; }
1675
const char *func_name() const { return "and"; }
1676
table_map not_null_tables() const
1677
{ return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1678
Item* copy_andor_structure(THD *thd)
1680
Item_cond_and *item;
1681
if ((item= new Item_cond_and(thd, this)))
1682
item->copy_andor_arguments(thd, this);
1685
Item *neg_transformer(THD *thd);
1688
inline bool is_cond_and(Item *item)
1690
if (item->type() != Item::COND_ITEM)
1693
Item_cond *cond_item= (Item_cond*) item;
1694
return (cond_item->functype() == Item_func::COND_AND_FUNC);
1697
class Item_cond_or :public Item_cond
1700
Item_cond_or() :Item_cond() {}
1701
Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1702
Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
1703
Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1704
enum Functype functype() const { return COND_OR_FUNC; }
1706
const char *func_name() const { return "or"; }
1707
table_map not_null_tables() const { return and_tables_cache; }
1708
Item* copy_andor_structure(THD *thd)
1711
if ((item= new Item_cond_or(thd, this)))
1712
item->copy_andor_arguments(thd, this);
1715
Item *neg_transformer(THD *thd);
1718
inline bool is_cond_or(Item *item)
1720
if (item->type() != Item::COND_ITEM)
1723
Item_cond *cond_item= (Item_cond*) item;
1724
return (cond_item->functype() == Item_func::COND_OR_FUNC);
1728
XOR is Item_cond, not an Item_int_func because we could like to
1729
optimize (a XOR b) later on. It's low prio, though
1732
class Item_cond_xor :public Item_cond
1735
Item_cond_xor() :Item_cond() {}
1736
Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1737
enum Functype functype() const { return COND_XOR_FUNC; }
1738
/* TODO: remove the next line when implementing XOR optimization */
1739
enum Type type() const { return FUNC_ITEM; }
1741
const char *func_name() const { return "xor"; }
1742
void top_level_item() {}
1746
/* Some useful inline functions */
1748
inline Item *and_conds(Item *a, Item *b)
1752
return new Item_cond_and(a, b);
1755
Item *and_expressions(Item *a, Item *b, Item **org_item);
1757
bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
1758
const char *warn_name, MYSQL_TIME *l_time);