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_bool_func2 *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
enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
44
CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
45
ulonglong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
46
Item *warn_item, bool *is_null);
48
DTCollation cmp_collation;
50
Arg_comparator(): thd(0), a_cache(0), b_cache(0) {};
51
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
52
a_cache(0), b_cache(0) {};
54
int set_compare_func(Item_bool_func2 *owner, Item_result type);
55
inline int set_compare_func(Item_bool_func2 *owner_arg)
57
return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
58
(*b)->result_type()));
60
int set_cmp_func(Item_bool_func2 *owner_arg,
64
inline int set_cmp_func(Item_bool_func2 *owner_arg,
67
return set_cmp_func(owner_arg, a1, a2,
68
item_cmp_type((*a1)->result_type(),
69
(*a2)->result_type()));
71
inline int compare() { return (this->*func)(); }
73
int compare_string(); // compare args[0] & args[1]
74
int compare_binary_string(); // compare args[0] & args[1]
75
int compare_real(); // compare args[0] & args[1]
76
int compare_decimal(); // compare args[0] & args[1]
77
int compare_int_signed(); // compare args[0] & args[1]
78
int compare_int_signed_unsigned();
79
int compare_int_unsigned_signed();
80
int compare_int_unsigned();
81
int compare_row(); // compare args[0] & args[1]
82
int compare_e_string(); // compare args[0] & args[1]
83
int compare_e_binary_string(); // compare args[0] & args[1]
84
int compare_e_real(); // compare args[0] & args[1]
85
int compare_e_decimal(); // compare args[0] & args[1]
86
int compare_e_int(); // compare args[0] & args[1]
87
int compare_e_int_diff_signedness();
88
int compare_e_row(); // compare args[0] & args[1]
89
int compare_real_fixed();
90
int compare_e_real_fixed();
91
int compare_datetime(); // compare args[0] & args[1] as DATETIMEs
93
static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b,
94
ulonglong *const_val_arg);
96
void set_datetime_cmp_func(Item **a1, Item **b1);
97
static arg_cmp_func comparator_matrix [5][2];
99
friend class Item_func;
102
class Item_bool_func :public Item_int_func
105
Item_bool_func() :Item_int_func() {}
106
Item_bool_func(Item *a) :Item_int_func(a) {}
107
Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
108
Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
109
bool is_bool_func() { return 1; }
110
void fix_length_and_dec() { decimals=0; max_length=1; }
111
uint decimal_precision() const { return 1; }
116
Abstract Item class, to represent <code>X IS [NOT] (TRUE | FALSE)</code>
120
class Item_func_truth : public Item_bool_func
123
virtual bool val_bool();
124
virtual longlong val_int();
125
virtual void fix_length_and_dec();
126
virtual void print(String *str, enum_query_type query_type);
129
Item_func_truth(Item *a, bool a_value, bool a_affirmative)
130
: Item_bool_func(a), value(a_value), affirmative(a_affirmative)
137
True for <code>X IS [NOT] TRUE</code>,
138
false for <code>X IS [NOT] FALSE</code> predicates.
142
True for <code>X IS Y</code>, false for <code>X IS NOT Y</code> predicates.
144
const bool affirmative;
149
This Item represents a <code>X IS TRUE</code> boolean predicate.
152
class Item_func_istrue : public Item_func_truth
155
Item_func_istrue(Item *a) : Item_func_truth(a, true, true) {}
156
~Item_func_istrue() {}
157
virtual const char* func_name() const { return "istrue"; }
162
This Item represents a <code>X IS NOT TRUE</code> boolean predicate.
165
class Item_func_isnottrue : public Item_func_truth
168
Item_func_isnottrue(Item *a) : Item_func_truth(a, true, false) {}
169
~Item_func_isnottrue() {}
170
virtual const char* func_name() const { return "isnottrue"; }
175
This Item represents a <code>X IS FALSE</code> boolean predicate.
178
class Item_func_isfalse : public Item_func_truth
181
Item_func_isfalse(Item *a) : Item_func_truth(a, false, true) {}
182
~Item_func_isfalse() {}
183
virtual const char* func_name() const { return "isfalse"; }
188
This Item represents a <code>X IS NOT FALSE</code> boolean predicate.
191
class Item_func_isnotfalse : public Item_func_truth
194
Item_func_isnotfalse(Item *a) : Item_func_truth(a, false, false) {}
195
~Item_func_isnotfalse() {}
196
virtual const char* func_name() const { return "isnotfalse"; }
201
#define UNKNOWN ((my_bool)-1)
205
Item_in_optimizer(left_expr, Item_in_subselect(...))
207
Item_in_optimizer is used to wrap an instance of Item_in_subselect. This
208
class does the following:
209
- Evaluate the left expression and store it in Item_cache_* object (to
210
avoid re-evaluating it many times during subquery execution)
211
- Shortcut the evaluation of "NULL IN (...)" to NULL in the cases where we
212
don't care if the result is NULL or FALSE.
215
It is not quite clear why the above listed functionality should be
216
placed into a separate class called 'Item_in_optimizer'.
219
class Item_in_optimizer: public Item_bool_func
225
Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
226
UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
227
FALSE - result is FALSE
228
TRUE - result is NULL
230
my_bool result_for_null_param;
232
Item_in_optimizer(Item *a, Item_in_subselect *b):
233
Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0),
234
save_cache(0), result_for_null_param(UNKNOWN)
235
{ with_subselect= TRUE; }
236
bool fix_fields(THD *, Item **);
237
bool fix_left(THD *thd, Item **ref);
241
const char *func_name() const { return "<in_optimizer>"; }
242
Item_cache **get_cache() { return &cache; }
243
void keep_top_level_cache();
244
Item *transform(Item_transformer transformer, uchar *arg);
250
Comp_creator() {} /* Remove gcc warning */
251
virtual ~Comp_creator() {} /* Remove gcc warning */
252
virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
253
virtual const char* symbol(bool invert) const = 0;
254
virtual bool eqne_op() const = 0;
255
virtual bool l_op() const = 0;
258
class Eq_creator :public Comp_creator
261
Eq_creator() {} /* Remove gcc warning */
262
virtual ~Eq_creator() {} /* Remove gcc warning */
263
virtual Item_bool_func2* create(Item *a, Item *b) const;
264
virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
265
virtual bool eqne_op() const { return 1; }
266
virtual bool l_op() const { return 0; }
269
class Ne_creator :public Comp_creator
272
Ne_creator() {} /* Remove gcc warning */
273
virtual ~Ne_creator() {} /* Remove gcc warning */
274
virtual Item_bool_func2* create(Item *a, Item *b) const;
275
virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
276
virtual bool eqne_op() const { return 1; }
277
virtual bool l_op() const { return 0; }
280
class Gt_creator :public Comp_creator
283
Gt_creator() {} /* Remove gcc warning */
284
virtual ~Gt_creator() {} /* Remove gcc warning */
285
virtual Item_bool_func2* create(Item *a, Item *b) const;
286
virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
287
virtual bool eqne_op() const { return 0; }
288
virtual bool l_op() const { return 0; }
291
class Lt_creator :public Comp_creator
294
Lt_creator() {} /* Remove gcc warning */
295
virtual ~Lt_creator() {} /* Remove gcc warning */
296
virtual Item_bool_func2* create(Item *a, Item *b) const;
297
virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
298
virtual bool eqne_op() const { return 0; }
299
virtual bool l_op() const { return 1; }
302
class Ge_creator :public Comp_creator
305
Ge_creator() {} /* Remove gcc warning */
306
virtual ~Ge_creator() {} /* Remove gcc warning */
307
virtual Item_bool_func2* create(Item *a, Item *b) const;
308
virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
309
virtual bool eqne_op() const { return 0; }
310
virtual bool l_op() const { return 0; }
313
class Le_creator :public Comp_creator
316
Le_creator() {} /* Remove gcc warning */
317
virtual ~Le_creator() {} /* Remove gcc warning */
318
virtual Item_bool_func2* create(Item *a, Item *b) const;
319
virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
320
virtual bool eqne_op() const { return 0; }
321
virtual bool l_op() const { return 1; }
324
class Item_bool_func2 :public Item_int_func
325
{ /* Bool with 2 string args */
328
String tmp_value1,tmp_value2;
332
Item_bool_func2(Item *a,Item *b)
333
:Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(FALSE) {}
334
void fix_length_and_dec();
337
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1);
339
optimize_type select_optimize() const { return OPTIMIZE_OP; }
340
virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
341
bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
343
virtual inline void print(String *str, enum_query_type query_type)
345
Item_func::print_op(str, query_type);
348
bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
349
bool is_bool_func() { return 1; }
350
CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
351
uint decimal_precision() const { return 1; }
352
void top_level_item() { abort_on_null= TRUE; }
354
friend class Arg_comparator;
357
class Item_bool_rowready_func2 :public Item_bool_func2
360
Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b)
362
allowed_arg_cols= 0; // Fetch this value from first argument
364
Item *neg_transformer(THD *thd);
365
virtual Item *negated_item();
366
bool subst_argument_checker(uchar **arg) { return TRUE; }
369
class Item_func_not :public Item_bool_func
372
Item_func_not(Item *a) :Item_bool_func(a) {}
374
enum Functype functype() const { return NOT_FUNC; }
375
const char *func_name() const { return "not"; }
376
Item *neg_transformer(THD *thd);
377
virtual void print(String *str, enum_query_type query_type);
380
class Item_maxmin_subselect;
383
trigcond<param>(arg) ::= param? arg : TRUE
385
The class Item_func_trig_cond is used for guarded predicates
386
which are employed only for internal purposes.
387
A guarded predicate is an object consisting of an a regular or
388
a guarded predicate P and a pointer to a boolean guard variable g.
389
A guarded predicate P/g is evaluated to true if the value of the
390
guard g is false, otherwise it is evaluated to the same value that
391
the predicate P: val(P/g)= g ? val(P):true.
392
Guarded predicates allow us to include predicates into a conjunction
393
conditionally. Currently they are utilized for pushed down predicates
394
in queries with outer join operations.
396
In the future, probably, it makes sense to extend this class to
397
the objects consisting of three elements: a predicate P, a pointer
398
to a variable g and a firing value s with following evaluation
399
rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
400
one item for the objects of the form P/g1/g2...
402
Objects of this class are built only for query execution after
403
the execution plan has been already selected. That's why this
404
class needs only val_int out of generic methods.
406
Current uses of Item_func_trig_cond objects:
407
- To wrap selection conditions when executing outer joins
408
- To wrap condition that is pushed down into subquery
411
class Item_func_trig_cond: public Item_bool_func
415
Item_func_trig_cond(Item *a, bool *f) : Item_bool_func(a) { trig_var= f; }
416
longlong val_int() { return *trig_var ? args[0]->val_int() : 1; }
417
enum Functype functype() const { return TRIG_COND_FUNC; };
418
const char *func_name() const { return "trigcond"; };
419
bool const_item() const { return FALSE; }
420
bool *get_trig_var() { return trig_var; }
421
/* The following is needed for ICP: */
422
table_map used_tables() const { return args[0]->used_tables(); }
425
class Item_func_not_all :public Item_func_not
427
/* allow to check presence of values in max/min optimization */
428
Item_sum_hybrid *test_sum_item;
429
Item_maxmin_subselect *test_sub_item;
435
Item_func_not_all(Item *a)
436
:Item_func_not(a), test_sum_item(0), test_sub_item(0), abort_on_null(0),
439
virtual void top_level_item() { abort_on_null= 1; }
440
bool top_level() { return abort_on_null; }
442
enum Functype functype() const { return NOT_ALL_FUNC; }
443
const char *func_name() const { return "<not>"; }
444
virtual void print(String *str, enum_query_type query_type);
445
void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
446
void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
447
bool empty_underlying_subquery();
448
Item *neg_transformer(THD *thd);
452
class Item_func_nop_all :public Item_func_not_all
456
Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
458
const char *func_name() const { return "<nop>"; }
459
Item *neg_transformer(THD *thd);
463
class Item_func_eq :public Item_bool_rowready_func2
466
Item_func_eq(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
468
enum Functype functype() const { return EQ_FUNC; }
469
enum Functype rev_functype() const { return EQ_FUNC; }
470
cond_result eq_cmp_result() const { return COND_TRUE; }
471
const char *func_name() const { return "="; }
472
Item *negated_item();
475
class Item_func_equal :public Item_bool_rowready_func2
478
Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
480
void fix_length_and_dec();
481
table_map not_null_tables() const { return 0; }
482
enum Functype functype() const { return EQUAL_FUNC; }
483
enum Functype rev_functype() const { return EQUAL_FUNC; }
484
cond_result eq_cmp_result() const { return COND_TRUE; }
485
const char *func_name() const { return "<=>"; }
486
Item *neg_transformer(THD *thd) { return 0; }
490
class Item_func_ge :public Item_bool_rowready_func2
493
Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
495
enum Functype functype() const { return GE_FUNC; }
496
enum Functype rev_functype() const { return LE_FUNC; }
497
cond_result eq_cmp_result() const { return COND_TRUE; }
498
const char *func_name() const { return ">="; }
499
Item *negated_item();
503
class Item_func_gt :public Item_bool_rowready_func2
506
Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
508
enum Functype functype() const { return GT_FUNC; }
509
enum Functype rev_functype() const { return LT_FUNC; }
510
cond_result eq_cmp_result() const { return COND_FALSE; }
511
const char *func_name() const { return ">"; }
512
Item *negated_item();
516
class Item_func_le :public Item_bool_rowready_func2
519
Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
521
enum Functype functype() const { return LE_FUNC; }
522
enum Functype rev_functype() const { return GE_FUNC; }
523
cond_result eq_cmp_result() const { return COND_TRUE; }
524
const char *func_name() const { return "<="; }
525
Item *negated_item();
529
class Item_func_lt :public Item_bool_rowready_func2
532
Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
534
enum Functype functype() const { return LT_FUNC; }
535
enum Functype rev_functype() const { return GT_FUNC; }
536
cond_result eq_cmp_result() const { return COND_FALSE; }
537
const char *func_name() const { return "<"; }
538
Item *negated_item();
542
class Item_func_ne :public Item_bool_rowready_func2
545
Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
547
enum Functype functype() const { return NE_FUNC; }
548
cond_result eq_cmp_result() const { return COND_FALSE; }
549
optimize_type select_optimize() const { return OPTIMIZE_KEY; }
550
const char *func_name() const { return "<>"; }
551
Item *negated_item();
556
The class Item_func_opt_neg is defined to factor out the functionality
557
common for the classes Item_func_between and Item_func_in. The objects
558
of these classes can express predicates or there negations.
559
The alternative approach would be to create pairs Item_func_between,
560
Item_func_notbetween and Item_func_in, Item_func_notin.
564
class Item_func_opt_neg :public Item_int_func
567
bool negated; /* <=> the item represents NOT <func> */
568
bool pred_level; /* <=> [NOT] <func> is used on a predicate level */
570
Item_func_opt_neg(Item *a, Item *b, Item *c)
571
:Item_int_func(a, b, c), negated(0), pred_level(0) {}
572
Item_func_opt_neg(List<Item> &list)
573
:Item_int_func(list), negated(0), pred_level(0) {}
575
inline void negate() { negated= !negated; }
576
inline void top_level_item() { pred_level= 1; }
577
Item *neg_transformer(THD *thd)
582
bool eq(const Item *item, bool binary_cmp) const;
583
bool subst_argument_checker(uchar **arg) { return TRUE; }
587
class Item_func_between :public Item_func_opt_neg
589
DTCollation cmp_collation;
591
Item_result cmp_type;
592
String value0,value1,value2;
593
/* TRUE <=> arguments will be compared as dates. */
594
bool compare_as_dates;
595
/* Comparators used for DATE/DATETIME comparison. */
596
Arg_comparator ge_cmp, le_cmp;
597
Item_func_between(Item *a, Item *b, Item *c)
598
:Item_func_opt_neg(a, b, c), compare_as_dates(FALSE) {}
600
optimize_type select_optimize() const { return OPTIMIZE_KEY; }
601
enum Functype functype() const { return BETWEEN; }
602
const char *func_name() const { return "between"; }
603
bool fix_fields(THD *, Item **);
604
void fix_length_and_dec();
605
virtual void print(String *str, enum_query_type query_type);
606
bool is_bool_func() { return 1; }
607
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
608
uint decimal_precision() const { return 1; }
612
class Item_func_strcmp :public Item_bool_func2
615
Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
617
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
618
const char *func_name() const { return "strcmp"; }
620
virtual inline void print(String *str, enum_query_type query_type)
622
Item_func::print(str, query_type);
627
struct interval_range
634
class Item_func_interval :public Item_int_func
637
my_bool use_decimal_comparison;
638
interval_range *intervals;
640
Item_func_interval(Item_row *a)
641
:Item_int_func(a),row(a),intervals(0)
643
allowed_arg_cols= 0; // Fetch this value from first argument
646
void fix_length_and_dec();
647
const char *func_name() const { return "interval"; }
648
uint decimal_precision() const { return 2; }
652
class Item_func_coalesce :public Item_func_numhybrid
655
enum_field_types cached_field_type;
656
Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
658
Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
661
String *str_op(String *);
662
my_decimal *decimal_op(my_decimal *);
663
void fix_length_and_dec();
664
void find_num_type() {}
665
enum Item_result result_type () const { return hybrid_type; }
666
const char *func_name() const { return "coalesce"; }
667
table_map not_null_tables() const { return 0; }
668
enum_field_types field_type() const { return cached_field_type; }
672
class Item_func_ifnull :public Item_func_coalesce
675
bool field_type_defined;
677
Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
680
String *str_op(String *str);
681
my_decimal *decimal_op(my_decimal *);
682
enum_field_types field_type() const;
683
void fix_length_and_dec();
684
const char *func_name() const { return "ifnull"; }
685
Field *tmp_table_field(TABLE *table);
686
uint decimal_precision() const;
690
class Item_func_if :public Item_func
692
enum Item_result cached_result_type;
693
enum_field_types cached_field_type;
695
Item_func_if(Item *a,Item *b,Item *c)
696
:Item_func(a,b,c), cached_result_type(INT_RESULT)
700
String *val_str(String *str);
701
my_decimal *val_decimal(my_decimal *);
702
enum Item_result result_type () const { return cached_result_type; }
703
enum_field_types field_type() const { return cached_field_type; }
704
bool fix_fields(THD *, Item **);
705
void fix_length_and_dec();
706
uint decimal_precision() const;
707
const char *func_name() const { return "if"; }
711
class Item_func_nullif :public Item_bool_func2
713
enum Item_result cached_result_type;
715
Item_func_nullif(Item *a,Item *b)
716
:Item_bool_func2(a,b), cached_result_type(INT_RESULT)
720
String *val_str(String *str);
721
my_decimal *val_decimal(my_decimal *);
722
enum Item_result result_type () const { return cached_result_type; }
723
void fix_length_and_dec();
724
uint decimal_precision() const { return args[0]->decimal_precision(); }
725
const char *func_name() const { return "nullif"; }
727
virtual inline void print(String *str, enum_query_type query_type)
729
Item_func::print(str, query_type);
732
table_map not_null_tables() const { return 0; }
737
/* Functions to handle the optimized IN */
740
/* A vector of values of some type */
742
class in_vector :public Sql_alloc
748
CHARSET_INFO *collation;
752
in_vector(uint elements,uint element_length,qsort2_cmp cmp_func,
753
CHARSET_INFO *cmp_coll)
754
:base((char*) sql_calloc(elements*element_length)),
755
size(element_length), compare(cmp_func), collation(cmp_coll),
756
count(elements), used_count(elements) {}
757
virtual ~in_vector() {}
758
virtual void set(uint pos,Item *item)=0;
759
virtual uchar *get_value(Item *item)=0;
762
my_qsort2(base,used_count,size,compare,collation);
764
int find(Item *item);
767
Create an instance of Item_{type} (e.g. Item_decimal) constant object
768
which type allows it to hold an element of this vector without any
770
The purpose of this function is to be able to get elements of this
771
vector in form of Item_xxx constants without creating Item_xxx object
772
for every array element you get (i.e. this implements "FlyWeight" pattern)
774
virtual Item* create_item() { return NULL; }
777
Store the value at position #pos into provided item object
780
pos Index of value to store
781
item Constant item to store value into. The item must be of the same
782
type that create_item() returns.
784
virtual void value_to_item(uint pos, Item *item) { }
786
/* Compare values number pos1 and pos2 for equality */
787
bool compare_elems(uint pos1, uint pos2)
789
return test(compare(collation, base + pos1*size, base + pos2*size));
791
virtual Item_result result_type()= 0;
794
class in_string :public in_vector
796
char buff[STRING_BUFFER_USUAL_SIZE];
799
in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs);
801
void set(uint pos,Item *item);
802
uchar *get_value(Item *item);
805
return new Item_string(collation);
807
void value_to_item(uint pos, Item *item)
809
String *str=((String*) base)+pos;
810
Item_string *to= (Item_string*)item;
813
Item_result result_type() { return STRING_RESULT; }
816
class in_longlong :public in_vector
820
Here we declare a temporary variable (tmp) of the same type as the
821
elements of this vector. tmp is used in finding if a given value is in
824
struct packed_longlong
827
longlong unsigned_flag; // Use longlong, not bool, to preserve alignment
830
in_longlong(uint elements);
831
void set(uint pos,Item *item);
832
uchar *get_value(Item *item);
837
We're created a signed INT, this may not be correct in
838
general case (see BUG#19342).
840
return new Item_int((longlong)0);
842
void value_to_item(uint pos, Item *item)
844
((Item_int*) item)->value= ((packed_longlong*) base)[pos].val;
845
((Item_int*) item)->unsigned_flag= (my_bool)
846
((packed_longlong*) base)[pos].unsigned_flag;
848
Item_result result_type() { return INT_RESULT; }
850
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
855
Class to represent a vector of constant DATE/DATETIME values.
856
Values are obtained with help of the get_datetime_value() function.
857
If the left item is a constant one then its value is cached in the
860
class in_datetime :public in_longlong
864
/* An item used to issue warnings. */
866
/* Cache for the left item. */
869
in_datetime(Item *warn_item_arg, uint elements)
870
:in_longlong(elements), thd(current_thd), warn_item(warn_item_arg),
872
void set(uint pos,Item *item);
873
uchar *get_value(Item *item);
874
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
878
class in_double :public in_vector
882
in_double(uint elements);
883
void set(uint pos,Item *item);
884
uchar *get_value(Item *item);
887
return new Item_float(0.0, 0);
889
void value_to_item(uint pos, Item *item)
891
((Item_float*)item)->value= ((double*) base)[pos];
893
Item_result result_type() { return REAL_RESULT; }
897
class in_decimal :public in_vector
901
in_decimal(uint elements);
902
void set(uint pos, Item *item);
903
uchar *get_value(Item *item);
906
return new Item_decimal(0, FALSE);
908
void value_to_item(uint pos, Item *item)
910
my_decimal *dec= ((my_decimal *)base) + pos;
911
Item_decimal *item_dec= (Item_decimal*)item;
912
item_dec->set_decimal_value(dec);
914
Item_result result_type() { return DECIMAL_RESULT; }
920
** Classes for easy comparing of non const items
923
class cmp_item :public Sql_alloc
926
CHARSET_INFO *cmp_charset;
927
cmp_item() { cmp_charset= &my_charset_bin; }
928
virtual ~cmp_item() {}
929
virtual void store_value(Item *item)= 0;
930
virtual int cmp(Item *item)= 0;
931
// for optimized IN with row
932
virtual int compare(cmp_item *item)= 0;
933
static cmp_item* get_comparator(Item_result type, CHARSET_INFO *cs);
934
virtual cmp_item *make_same()= 0;
935
virtual void store_value_by_template(cmp_item *tmpl, Item *item)
941
class cmp_item_string :public cmp_item
946
cmp_item_string () {}
947
cmp_item_string (CHARSET_INFO *cs) { cmp_charset= cs; }
948
void set_charset(CHARSET_INFO *cs) { cmp_charset= cs; }
949
friend class cmp_item_sort_string;
950
friend class cmp_item_sort_string_in_static;
953
class cmp_item_sort_string :public cmp_item_string
956
char value_buff[STRING_BUFFER_USUAL_SIZE];
959
cmp_item_sort_string():
961
cmp_item_sort_string(CHARSET_INFO *cs):
963
value(value_buff, sizeof(value_buff), cs) {}
964
void store_value(Item *item)
966
value_res= item->val_str(&value);
970
char buff[STRING_BUFFER_USUAL_SIZE];
971
String tmp(buff, sizeof(buff), cmp_charset), *res;
972
res= arg->val_str(&tmp);
973
return (value_res ? (res ? sortcmp(value_res, res, cmp_charset) : 1) :
976
int compare(cmp_item *ci)
978
cmp_item_string *l_cmp= (cmp_item_string *) ci;
979
return sortcmp(value_res, l_cmp->value_res, cmp_charset);
981
cmp_item *make_same();
982
void set_charset(CHARSET_INFO *cs)
985
value.set_quick(value_buff, sizeof(value_buff), cs);
989
class cmp_item_int :public cmp_item
993
cmp_item_int() {} /* Remove gcc warning */
994
void store_value(Item *item)
996
value= item->val_int();
1000
return value != arg->val_int();
1002
int compare(cmp_item *ci)
1004
cmp_item_int *l_cmp= (cmp_item_int *)ci;
1005
return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
1007
cmp_item *make_same();
1011
Compare items in the DATETIME context.
1012
Values are obtained with help of the get_datetime_value() function.
1013
If the left item is a constant one then its value is cached in the
1014
lval_cache variable.
1016
class cmp_item_datetime :public cmp_item
1021
/* Item used for issuing warnings. */
1023
/* Cache for the left item. */
1026
cmp_item_datetime(Item *warn_item_arg)
1027
:thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
1028
void store_value(Item *item);
1030
int compare(cmp_item *ci);
1031
cmp_item *make_same();
1034
class cmp_item_real :public cmp_item
1038
cmp_item_real() {} /* Remove gcc warning */
1039
void store_value(Item *item)
1041
value= item->val_real();
1045
return value != arg->val_real();
1047
int compare(cmp_item *ci)
1049
cmp_item_real *l_cmp= (cmp_item_real *) ci;
1050
return (value < l_cmp->value)? -1 : ((value == l_cmp->value) ? 0 : 1);
1052
cmp_item *make_same();
1056
class cmp_item_decimal :public cmp_item
1060
cmp_item_decimal() {} /* Remove gcc warning */
1061
void store_value(Item *item);
1063
int compare(cmp_item *c);
1064
cmp_item *make_same();
1069
cmp_item for optimized IN with row (right part string, which never
1073
class cmp_item_sort_string_in_static :public cmp_item_string
1078
cmp_item_sort_string_in_static(CHARSET_INFO *cs):
1079
cmp_item_string(cs) {}
1080
void store_value(Item *item)
1082
value_res= item->val_str(&value);
1086
// Should never be called
1090
int compare(cmp_item *ci)
1092
cmp_item_string *l_cmp= (cmp_item_string *) ci;
1093
return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1095
cmp_item *make_same()
1097
return new cmp_item_sort_string_in_static(cmp_charset);
1103
The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1106
When there is no expression between CASE and the first WHEN
1107
(the CASE expression) then this function simple checks all WHEN expressions
1108
one after another. When some WHEN expression evaluated to TRUE then the
1109
value of the corresponding THEN expression is returned.
1111
When the CASE expression is specified then it is compared to each WHEN
1112
expression individually. When an equal WHEN expression is found
1113
corresponding THEN expression is returned.
1114
In order to do correct comparisons several comparators are used. One for
1115
each result type. Different result types that are used in particular
1116
CASE ... END expression are collected in the fix_length_and_dec() member
1117
function and only comparators for there result types are used.
1120
class Item_func_case :public Item_func
1122
int first_expr_num, else_expr_num;
1123
enum Item_result cached_result_type, left_result_type;
1126
Item_result cmp_type;
1127
DTCollation cmp_collation;
1128
enum_field_types cached_field_type;
1129
cmp_item *cmp_items[5]; /* For all result types */
1130
cmp_item *case_item;
1132
Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
1133
:Item_func(), first_expr_num(-1), else_expr_num(-1),
1134
cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
1136
ncases= list.elements;
1139
first_expr_num= list.elements;
1140
list.push_back(first_expr_arg);
1144
else_expr_num= list.elements;
1145
list.push_back(else_expr_arg);
1147
set_arguments(list);
1148
bzero(&cmp_items, sizeof(cmp_items));
1152
String *val_str(String *);
1153
my_decimal *val_decimal(my_decimal *);
1154
bool fix_fields(THD *thd, Item **ref);
1155
void fix_length_and_dec();
1156
uint decimal_precision() const;
1157
table_map not_null_tables() const { return 0; }
1158
enum Item_result result_type () const { return cached_result_type; }
1159
enum_field_types field_type() const { return cached_field_type; }
1160
const char *func_name() const { return "case"; }
1161
virtual void print(String *str, enum_query_type query_type);
1162
Item *find_item(String *str);
1163
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1165
void agg_str_lengths(Item *arg);
1166
void agg_num_lengths(Item *arg);
1170
The Item_func_in class implements the in_expr IN(values_list) function.
1172
The current implementation distinguishes 2 cases:
1173
1) all items in the value_list are constants and have the same
1174
result type. This case is handled by in_vector class.
1175
2) items in the value_list have different result types or there is some
1177
In this case Item_func_in employs several cmp_item objects to performs
1178
comparisons of in_expr and an item from the values_list. One cmp_item
1179
object for each result type. Different result types are collected in the
1180
fix_length_and_dec() member function by means of collect_cmp_types()
1183
class Item_func_in :public Item_func_opt_neg
1187
an array of values when the right hand arguments of IN
1188
are all SQL constant and there are no nulls
1193
true when all arguments of the IN clause are of compatible types
1194
and can be used safely as comparisons for key conditions
1196
bool arg_types_compatible;
1197
Item_result left_result_type;
1198
cmp_item *cmp_items[6]; /* One cmp_item for each result type */
1199
DTCollation cmp_collation;
1201
Item_func_in(List<Item> &list)
1202
:Item_func_opt_neg(list), array(0), have_null(0),
1203
arg_types_compatible(FALSE)
1205
bzero(&cmp_items, sizeof(cmp_items));
1206
allowed_arg_cols= 0; // Fetch this value from first argument
1209
bool fix_fields(THD *, Item **);
1210
void fix_length_and_dec();
1211
uint decimal_precision() const { return 1; }
1215
DBUG_ENTER("Item_func_in::cleanup");
1216
Item_int_func::cleanup();
1219
for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1221
delete cmp_items[i];
1226
optimize_type select_optimize() const
1227
{ return OPTIMIZE_KEY; }
1228
virtual void print(String *str, enum_query_type query_type);
1229
enum Functype functype() const { return IN_FUNC; }
1230
const char *func_name() const { return " IN "; }
1231
bool nulls_in_row();
1232
bool is_bool_func() { return 1; }
1233
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1236
class cmp_item_row :public cmp_item
1238
cmp_item **comparators;
1241
cmp_item_row(): comparators(0), n(0) {}
1243
void store_value(Item *item);
1244
inline void alloc_comparators();
1246
int compare(cmp_item *arg);
1247
cmp_item *make_same();
1248
void store_value_by_template(cmp_item *tmpl, Item *);
1249
friend void Item_func_in::fix_length_and_dec();
1253
class in_row :public in_vector
1257
in_row(uint elements, Item *);
1259
void set(uint pos,Item *item);
1260
uchar *get_value(Item *item);
1261
friend void Item_func_in::fix_length_and_dec();
1262
Item_result result_type() { return ROW_RESULT; }
1265
/* Functions used by where clause */
1267
class Item_func_isnull :public Item_bool_func
1270
longlong cached_value;
1272
Item_func_isnull(Item *a) :Item_bool_func(a) {}
1274
enum Functype functype() const { return ISNULL_FUNC; }
1275
void fix_length_and_dec()
1277
decimals=0; max_length=1; maybe_null=0;
1278
update_used_tables();
1280
const char *func_name() const { return "isnull"; }
1281
/* Optimize case of not_null_column IS NULL */
1282
virtual void update_used_tables()
1284
if (!args[0]->maybe_null)
1286
used_tables_cache= 0; /* is always false */
1287
const_item_cache= 1;
1288
cached_value= (longlong) 0;
1292
args[0]->update_used_tables();
1293
if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) &&
1296
/* Remember if the value is always NULL or never NULL */
1297
cached_value= (longlong) args[0]->is_null();
1301
table_map not_null_tables() const { return 0; }
1302
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1303
Item *neg_transformer(THD *thd);
1304
CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1307
/* Functions used by HAVING for rewriting IN subquery */
1309
class Item_in_subselect;
1312
This is like IS NOT NULL but it also remembers if it ever has
1315
class Item_is_not_null_test :public Item_func_isnull
1317
Item_in_subselect* owner;
1319
Item_is_not_null_test(Item_in_subselect* ow, Item *a)
1320
:Item_func_isnull(a), owner(ow)
1322
enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
1324
const char *func_name() const { return "<is_not_null_test>"; }
1325
void update_used_tables();
1327
we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
1329
table_map used_tables() const
1330
{ return used_tables_cache | RAND_TABLE_BIT; }
1334
class Item_func_isnotnull :public Item_bool_func
1338
Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
1340
enum Functype functype() const { return ISNOTNULL_FUNC; }
1341
void fix_length_and_dec()
1343
decimals=0; max_length=1; maybe_null=0;
1345
const char *func_name() const { return "isnotnull"; }
1346
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1347
table_map not_null_tables() const
1348
{ return abort_on_null ? not_null_tables_cache : 0; }
1349
Item *neg_transformer(THD *thd);
1350
virtual void print(String *str, enum_query_type query_type);
1351
CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1352
void top_level_item() { abort_on_null=1; }
1356
class Item_func_like :public Item_bool_func2
1358
// Turbo Boyer-Moore data
1359
bool canDoTurboBM; // pattern is '%abcd%' case
1360
const char* pattern;
1363
// TurboBM buffers, *this is owner
1364
int* bmGs; // good suffix shift table, size is pattern_len + 1
1365
int* bmBc; // bad character shift table, size is alphabet_size
1367
void turboBM_compute_suffixes(int* suff);
1368
void turboBM_compute_good_suffix_shifts(int* suff);
1369
void turboBM_compute_bad_character_shifts();
1370
bool turboBM_matches(const char* text, int text_len) const;
1371
enum { alphabet_size = 256 };
1375
bool escape_used_in_parsing;
1380
Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1381
:Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0),
1382
bmGs(0), bmBc(0), escape_item(escape_arg),
1383
escape_used_in_parsing(escape_used) {}
1385
enum Functype functype() const { return LIKE_FUNC; }
1386
optimize_type select_optimize() const;
1387
cond_result eq_cmp_result() const { return COND_TRUE; }
1388
const char *func_name() const { return "like"; }
1389
bool fix_fields(THD *thd, Item **ref);
1394
typedef class Item COND;
1396
class Item_cond :public Item_bool_func
1401
table_map and_tables_cache;
1404
/* Item_cond() is only used to create top level items */
1405
Item_cond(): Item_bool_func(), abort_on_null(1)
1406
{ const_item_cache=0; }
1407
Item_cond(Item *i1,Item *i2)
1408
:Item_bool_func(), abort_on_null(0)
1413
Item_cond(THD *thd, Item_cond *item);
1414
Item_cond(List<Item> &nlist)
1415
:Item_bool_func(), list(nlist), abort_on_null(0) {}
1416
bool add(Item *item) { return list.push_back(item); }
1417
bool add_at_head(Item *item) { return list.push_front(item); }
1418
void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1419
bool fix_fields(THD *, Item **ref);
1420
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
1422
enum Type type() const { return COND_ITEM; }
1423
List<Item>* argument_list() { return &list; }
1424
table_map used_tables() const;
1425
void update_used_tables();
1426
virtual void print(String *str, enum_query_type query_type);
1427
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
1428
friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
1430
void top_level_item() { abort_on_null=1; }
1431
void copy_andor_arguments(THD *thd, Item_cond *item);
1432
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1433
Item *transform(Item_transformer transformer, uchar *arg);
1434
void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1435
void neg_arguments(THD *thd);
1436
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
1437
bool subst_argument_checker(uchar **arg) { return TRUE; }
1438
Item *compile(Item_analyzer analyzer, uchar **arg_p,
1439
Item_transformer transformer, uchar *arg_t);
1444
The class Item_equal is used to represent conjunctions of equality
1445
predicates of the form field1 = field2, and field=const in where
1446
conditions and on expressions.
1448
All equality predicates of the form field1=field2 contained in a
1449
conjunction are substituted for a sequence of items of this class.
1450
An item of this class Item_equal(f1,f2,...fk) represents a
1451
multiple equality f1=f2=...=fk.
1453
If a conjunction contains predicates f1=f2 and f2=f3, a new item of
1454
this class is created Item_equal(f1,f2,f3) representing the multiple
1455
equality f1=f2=f3 that substitutes the above equality predicates in
1457
A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1458
substituted for the item representing the same multiple equality
1460
An item Item_equal(f1,f2) can appear instead of a conjunction of
1461
f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1463
An item of the class Item_equal inherits equalities from outer
1466
Suppose we have a where condition of the following form:
1467
WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
1469
f1=f2 will be substituted for Item_equal(f1,f2);
1470
f3=f4 and f3=f5 will be substituted for Item_equal(f3,f4,f5);
1471
f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1473
An object of the class Item_equal can contain an optional constant
1474
item c. Then it represents a multiple equality of the form
1477
Objects of the class Item_equal are used for the following:
1479
1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
1480
pair of tables ti and tj as joined by an equi-condition.
1481
Thus it provide us with additional access paths from table to table.
1483
2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
1484
SARGable predicates:
1485
f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
1486
It also can give us additional index scans and can allow us to
1487
improve selectivity estimates.
1489
3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
1490
selected execution plan for the query: if table ti is accessed
1491
before the table tj then in any predicate P in the where condition
1492
the occurrence of tj.fj is substituted for ti.fi. This can allow
1493
an evaluation of the predicate at an earlier step.
1495
When feature 1 is supported they say that join transitive closure
1497
When feature 2 is supported they say that search argument transitive
1498
closure is employed.
1499
Both features are usually supported by preprocessing original query and
1500
adding additional predicates.
1501
We do not just add predicates, we rather dynamically replace some
1502
predicates that can not be used to access tables in the investigated
1503
plan for those, obtained by substitution of some fields for equal fields,
1506
Prepared Statements/Stored Procedures note: instances of class
1507
Item_equal are created only at the time a PS/SP is executed and
1508
are deleted in the end of execution. All changes made to these
1509
objects need not be registered in the list of changes of the parse
1510
tree and do not harm PS/SP re-execution.
1512
Item equal objects are employed only at the optimize phase. Usually they are
1513
not supposed to be evaluated. Yet in some cases we call the method val_int()
1514
for them. We have to take care of restricting the predicate such an
1515
object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
1518
class Item_equal: public Item_bool_func
1520
List<Item_field> fields; /* list of equal field items */
1521
Item *const_item; /* optional constant item equal to fields items */
1522
cmp_item *eval_item;
1526
: Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
1527
{ const_item_cache=0 ;}
1528
Item_equal(Item_field *f1, Item_field *f2);
1529
Item_equal(Item *c, Item_field *f);
1530
Item_equal(Item_equal *item_equal);
1531
inline Item* get_const() { return const_item; }
1533
void add(Item_field *f);
1535
bool contains(Field *field);
1536
Item_field* get_first() { return fields.head(); }
1537
void merge(Item_equal *item);
1538
void update_const();
1539
enum Functype functype() const { return MULT_EQUAL_FUNC; }
1541
const char *func_name() const { return "multiple equal"; }
1542
optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1543
void sort(Item_field_cmpfunc cmp, void *arg);
1544
friend class Item_equal_iterator;
1545
void fix_length_and_dec();
1546
bool fix_fields(THD *thd, Item **ref);
1547
void update_used_tables();
1548
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1549
Item *transform(Item_transformer transformer, uchar *arg);
1550
virtual void print(String *str, enum_query_type query_type);
1551
CHARSET_INFO *compare_collation()
1552
{ return fields.head()->collation.collation; }
1555
class COND_EQUAL: public Sql_alloc
1558
uint max_members; /* max number of members the current level
1559
list and all lower level lists */
1560
COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
1561
List<Item_equal> current_level; /* list of multiple equalities of
1562
the current and level */
1570
class Item_equal_iterator : public List_iterator_fast<Item_field>
1573
inline Item_equal_iterator(Item_equal &item_equal)
1574
:List_iterator_fast<Item_field> (item_equal.fields)
1576
inline Item_field* operator++(int)
1578
Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1581
inline void rewind(void)
1583
List_iterator_fast<Item_field>::rewind();
1587
class Item_cond_and :public Item_cond
1590
COND_EQUAL cond_equal; /* contains list of Item_equal objects for
1591
the current and level and reference
1592
to multiple equalities of upper and levels */
1593
Item_cond_and() :Item_cond() {}
1594
Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1595
Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
1596
Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1597
enum Functype functype() const { return COND_AND_FUNC; }
1599
const char *func_name() const { return "and"; }
1600
table_map not_null_tables() const
1601
{ return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1602
Item* copy_andor_structure(THD *thd)
1604
Item_cond_and *item;
1605
if ((item= new Item_cond_and(thd, this)))
1606
item->copy_andor_arguments(thd, this);
1609
Item *neg_transformer(THD *thd);
1612
inline bool is_cond_and(Item *item)
1614
if (item->type() != Item::COND_ITEM)
1617
Item_cond *cond_item= (Item_cond*) item;
1618
return (cond_item->functype() == Item_func::COND_AND_FUNC);
1621
class Item_cond_or :public Item_cond
1624
Item_cond_or() :Item_cond() {}
1625
Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1626
Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
1627
Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1628
enum Functype functype() const { return COND_OR_FUNC; }
1630
const char *func_name() const { return "or"; }
1631
table_map not_null_tables() const { return and_tables_cache; }
1632
Item* copy_andor_structure(THD *thd)
1635
if ((item= new Item_cond_or(thd, this)))
1636
item->copy_andor_arguments(thd, this);
1639
Item *neg_transformer(THD *thd);
1642
inline bool is_cond_or(Item *item)
1644
if (item->type() != Item::COND_ITEM)
1647
Item_cond *cond_item= (Item_cond*) item;
1648
return (cond_item->functype() == Item_func::COND_OR_FUNC);
1652
XOR is Item_cond, not an Item_int_func because we could like to
1653
optimize (a XOR b) later on. It's low prio, though
1656
class Item_cond_xor :public Item_cond
1659
Item_cond_xor() :Item_cond() {}
1660
Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1661
enum Functype functype() const { return COND_XOR_FUNC; }
1662
/* TODO: remove the next line when implementing XOR optimization */
1663
enum Type type() const { return FUNC_ITEM; }
1665
const char *func_name() const { return "xor"; }
1666
void top_level_item() {}
1670
/* Some useful inline functions */
1672
inline Item *and_conds(Item *a, Item *b)
1676
return new Item_cond_and(a, b);
1679
Item *and_expressions(Item *a, Item *b, Item **org_item);