1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#ifndef DRIZZLED_ITEM_CMPFUNC_H
21
#define DRIZZLED_ITEM_CMPFUNC_H
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 */
23
17
/* compare and test functions */
25
#include "drizzled/comp_creator.h"
26
#include "drizzled/item/row.h"
27
#include "drizzled/item/sum.h"
28
#include "drizzled/item/int.h"
29
#include "drizzled/item/float.h"
30
#include "drizzled/item/string.h"
31
#include "drizzled/item/decimal.h"
32
#include "drizzled/function/math/int.h"
33
#include "drizzled/function/numhybrid.h"
34
#include "drizzled/session.h"
35
#include "drizzled/common.h"
36
#include "drizzled/qsort_cmp.h"
19
#ifdef USE_PRAGMA_INTERFACE
20
#pragma interface /* gcc class implementation */
41
23
extern Item_result item_cmp_type(Item_result a,Item_result b);
42
24
class Item_bool_func2;
43
25
class Arg_comparator;
44
class Item_sum_hybrid;
47
27
typedef int (Arg_comparator::*arg_cmp_func)();
49
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
51
uint64_t get_datetime_value(Session *session,
57
class Arg_comparator: public memory::SqlAlloc
29
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
31
class Arg_comparator: public Sql_alloc
62
36
Arg_comparator *comparators; // used only for compare_row()
64
38
/* Fields used in DATE/DATETIME comparison. */
66
40
enum_field_types a_type, b_type; // Types of a and b items
67
41
Item *a_cache, *b_cache; // Cached values of a and b items
68
42
bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
69
43
enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
70
44
CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
71
uint64_t (*get_value_func)(Session *session, Item ***item_arg, Item **cache_arg,
45
ulonglong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
72
46
Item *warn_item, bool *is_null);
74
48
DTCollation cmp_collation;
76
Arg_comparator(): session(0), a_cache(0), b_cache(0) {};
77
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), session(0),
50
Arg_comparator(): thd(0), a_cache(0), b_cache(0) {};
51
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
78
52
a_cache(0), b_cache(0) {};
80
54
int set_compare_func(Item_bool_func2 *owner, Item_result type);
131
105
Item_bool_func() :Item_int_func() {}
132
106
Item_bool_func(Item *a) :Item_int_func(a) {}
133
107
Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
134
Item_bool_func(Session *session, Item_bool_func *item) :Item_int_func(session, item) {}
108
Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
135
109
bool is_bool_func() { return 1; }
136
110
void fix_length_and_dec() { decimals=0; max_length=1; }
137
uint32_t decimal_precision() const { return 1; }
111
uint decimal_precision() const { return 1; }
248
222
Item_cache *cache;
251
225
Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
252
226
UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
253
227
FALSE - result is FALSE
254
228
TRUE - result is NULL
256
bool result_for_null_param;
230
my_bool result_for_null_param;
258
232
Item_in_optimizer(Item *a, Item_in_subselect *b):
259
Item_bool_func(a, reinterpret_cast<Item *>(b)), cache(0),
233
Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0),
260
234
save_cache(0), result_for_null_param(UNKNOWN)
261
235
{ with_subselect= true; }
262
bool fix_fields(Session *, Item **);
263
bool fix_left(Session *session, Item **ref);
236
bool fix_fields(THD *, Item **);
237
bool fix_left(THD *thd, Item **ref);
267
241
const char *func_name() const { return "<in_optimizer>"; }
268
242
Item_cache **get_cache() { return &cache; }
269
243
void keep_top_level_cache();
270
Item *transform(Item_transformer transformer, unsigned char *arg);
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;
273
258
class Eq_creator :public Comp_creator
369
348
bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
370
349
bool is_bool_func() { return 1; }
371
const CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
372
uint32_t decimal_precision() const { return 1; }
350
CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
351
uint decimal_precision() const { return 1; }
373
352
void top_level_item() { abort_on_null= true; }
375
354
friend class Arg_comparator;
405
384
trigcond<param>(arg) ::= param? arg : TRUE
407
The class Item_func_trig_cond is used for guarded predicates
386
The class Item_func_trig_cond is used for guarded predicates
408
387
which are employed only for internal purposes.
409
388
A guarded predicate is an object consisting of an a regular or
410
a guarded predicate P and a pointer to a boolean guard variable g.
389
a guarded predicate P and a pointer to a boolean guard variable g.
411
390
A guarded predicate P/g is evaluated to true if the value of the
412
391
guard g is false, otherwise it is evaluated to the same value that
413
392
the predicate P: val(P/g)= g ? val(P):true.
419
398
the objects consisting of three elements: a predicate P, a pointer
420
399
to a variable g and a firing value s with following evaluation
421
400
rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
422
one item for the objects of the form P/g1/g2...
401
one item for the objects of the form P/g1/g2...
424
403
Objects of this class are built only for query execution after
425
404
the execution plan has been already selected. That's why this
426
class needs only val_int out of generic methods.
405
class needs only val_int out of generic methods.
428
407
Current uses of Item_func_trig_cond objects:
429
408
- To wrap selection conditions when executing outer joins
430
409
- To wrap condition that is pushed down into subquery
461
440
virtual void top_level_item() { abort_on_null= 1; }
462
441
bool top_level() { return abort_on_null; }
464
443
enum Functype functype() const { return NOT_ALL_FUNC; }
465
444
const char *func_name() const { return "<not>"; }
466
445
virtual void print(String *str, enum_query_type query_type);
467
446
void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
468
447
void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
469
448
bool empty_underlying_subquery();
470
Item *neg_transformer(Session *session);
449
Item *neg_transformer(THD *thd);
500
479
Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
502
481
void fix_length_and_dec();
503
482
table_map not_null_tables() const { return 0; }
504
483
enum Functype functype() const { return EQUAL_FUNC; }
505
484
enum Functype rev_functype() const { return EQUAL_FUNC; }
506
485
cond_result eq_cmp_result() const { return COND_TRUE; }
507
486
const char *func_name() const { return "<=>"; }
508
Item *neg_transformer(Session *) { return 0; }
487
Item *neg_transformer(THD *thd __attribute__((__unused__))) { return 0; }
619
598
Arg_comparator ge_cmp, le_cmp;
620
599
Item_func_between(Item *a, Item *b, Item *c)
621
600
:Item_func_opt_neg(a, b, c), compare_as_dates(false) {}
623
602
optimize_type select_optimize() const { return OPTIMIZE_KEY; }
624
603
enum Functype functype() const { return BETWEEN; }
625
604
const char *func_name() const { return "between"; }
626
bool fix_fields(Session *, Item **);
605
bool fix_fields(THD *, Item **);
627
606
void fix_length_and_dec();
628
607
virtual void print(String *str, enum_query_type query_type);
629
608
bool is_bool_func() { return 1; }
630
const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
631
uint32_t decimal_precision() const { return 1; }
609
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
610
uint decimal_precision() const { return 1; }
700
679
Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
701
680
double real_op();
703
682
String *str_op(String *str);
704
683
my_decimal *decimal_op(my_decimal *);
705
684
enum_field_types field_type() const;
706
685
void fix_length_and_dec();
707
686
const char *func_name() const { return "ifnull"; }
708
Field *tmp_table_field()
710
return Item_func::tmp_table_field();
712
Field *tmp_table_field(Table *table);
713
uint32_t decimal_precision() const;
687
Field *tmp_table_field(TABLE *table);
688
uint decimal_precision() const;
723
698
:Item_func(a,b,c), cached_result_type(INT_RESULT)
725
700
double val_real();
727
702
String *val_str(String *str);
728
703
my_decimal *val_decimal(my_decimal *);
729
704
enum Item_result result_type () const { return cached_result_type; }
730
705
enum_field_types field_type() const { return cached_field_type; }
731
bool fix_fields(Session *, Item **);
706
bool fix_fields(THD *, Item **);
732
707
void fix_length_and_dec();
733
uint32_t decimal_precision() const;
708
uint decimal_precision() const;
734
709
const char *func_name() const { return "if"; }
743
718
:Item_bool_func2(a,b), cached_result_type(INT_RESULT)
745
720
double val_real();
747
722
String *val_str(String *str);
748
723
my_decimal *val_decimal(my_decimal *);
749
724
enum Item_result result_type () const { return cached_result_type; }
750
725
void fix_length_and_dec();
751
uint32_t decimal_precision() const { return args[0]->decimal_precision(); }
726
uint decimal_precision() const { return args[0]->decimal_precision(); }
752
727
const char *func_name() const { return "nullif"; }
754
729
virtual inline void print(String *str, enum_query_type query_type)
767
742
/* A vector of values of some type */
769
class in_vector :public memory::SqlAlloc
744
class in_vector :public Sql_alloc
774
749
qsort2_cmp compare;
775
const CHARSET_INFO *collation;
750
CHARSET_INFO *collation;
779
in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func,
780
const CHARSET_INFO * const cmp_coll)
781
:base((char*) memory::sql_calloc(elements*element_length)),
754
in_vector(uint elements,uint element_length,qsort2_cmp cmp_func,
755
CHARSET_INFO *cmp_coll)
756
:base((char*) sql_calloc(elements*element_length)),
782
757
size(element_length), compare(cmp_func), collation(cmp_coll),
783
758
count(elements), used_count(elements) {}
784
759
virtual ~in_vector() {}
785
virtual void set(uint32_t pos,Item *item)=0;
786
virtual unsigned char *get_value(Item *item)=0;
760
virtual void set(uint pos,Item *item)=0;
761
virtual uchar *get_value(Item *item)=0;
764
my_qsort2(base,used_count,size,compare,collation);
788
766
int find(Item *item);
791
769
Create an instance of Item_{type} (e.g. Item_decimal) constant object
792
770
which type allows it to hold an element of this vector without any
805
783
item Constant item to store value into. The item must be of the same
806
784
type that create_item() returns.
808
virtual void value_to_item(uint32_t, Item *) { }
786
virtual void value_to_item(uint pos __attribute__((__unused__)),
787
Item *item __attribute__((__unused__))) { }
810
789
/* Compare values number pos1 and pos2 for equality */
811
bool compare_elems(uint32_t pos1, uint32_t pos2)
790
bool compare_elems(uint pos1, uint pos2)
813
792
return test(compare(collation, base + pos1*size, base + pos2*size));
820
799
char buff[STRING_BUFFER_USUAL_SIZE];
823
in_string(uint32_t elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs);
802
in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs);
825
void set(uint32_t pos,Item *item);
826
unsigned char *get_value(Item *item);
804
void set(uint pos,Item *item);
805
uchar *get_value(Item *item);
827
806
Item* create_item()
829
808
return new Item_string(collation);
831
void value_to_item(uint32_t pos, Item *item)
810
void value_to_item(uint pos, Item *item)
833
812
String *str=((String*) base)+pos;
834
813
Item_string *to= (Item_string*)item;
835
814
to->str_value= *str;
837
816
Item_result result_type() { return STRING_RESULT; }
840
class in_int64_t :public in_vector
819
class in_longlong :public in_vector
844
823
Here we declare a temporary variable (tmp) of the same type as the
845
elements of this vector. tmp is used in finding if a given value is in
824
elements of this vector. tmp is used in finding if a given value is in
848
struct packed_int64_t
827
struct packed_longlong
851
int64_t unsigned_flag; // Use int64_t, not bool, to preserve alignment
830
longlong unsigned_flag; // Use longlong, not bool, to preserve alignment
854
in_int64_t(uint32_t elements);
855
void set(uint32_t pos,Item *item);
856
unsigned char *get_value(Item *item);
833
in_longlong(uint elements);
834
void set(uint pos,Item *item);
835
uchar *get_value(Item *item);
858
837
Item* create_item()
861
We're created a signed INT, this may not be correct in
840
We're created a signed INT, this may not be correct in
862
841
general case (see BUG#19342).
864
return new Item_int((int64_t)0);
843
return new Item_int((longlong)0);
866
void value_to_item(uint32_t pos, Item *item)
845
void value_to_item(uint pos, Item *item)
868
((Item_int*) item)->value= ((packed_int64_t*) base)[pos].val;
869
((Item_int*) item)->unsigned_flag= (bool)
870
((packed_int64_t*) base)[pos].unsigned_flag;
847
((Item_int*) item)->value= ((packed_longlong*) base)[pos].val;
848
((Item_int*) item)->unsigned_flag= (my_bool)
849
((packed_longlong*) base)[pos].unsigned_flag;
872
851
Item_result result_type() { return INT_RESULT; }
874
friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
853
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
881
860
If the left item is a constant one then its value is cached in the
882
861
lval_cache variable.
884
class in_datetime :public in_int64_t
863
class in_datetime :public in_longlong
888
867
/* An item used to issue warnings. */
890
869
/* Cache for the left item. */
891
870
Item *lval_cache;
893
in_datetime(Item *warn_item_arg, uint32_t elements)
894
:in_int64_t(elements), session(current_session), warn_item(warn_item_arg),
872
in_datetime(Item *warn_item_arg, uint elements)
873
:in_longlong(elements), thd(current_thd), warn_item(warn_item_arg),
895
874
lval_cache(0) {};
896
void set(uint32_t pos,Item *item);
897
unsigned char *get_value(Item *item);
898
friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
875
void set(uint pos,Item *item);
876
uchar *get_value(Item *item);
877
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
906
in_double(uint32_t elements);
907
void set(uint32_t pos,Item *item);
908
unsigned char *get_value(Item *item);
885
in_double(uint elements);
886
void set(uint pos,Item *item);
887
uchar *get_value(Item *item);
909
888
Item *create_item()
911
890
return new Item_float(0.0, 0);
913
void value_to_item(uint32_t pos, Item *item)
892
void value_to_item(uint pos, Item *item)
915
894
((Item_float*)item)->value= ((double*) base)[pos];
925
in_decimal(uint32_t elements);
926
void set(uint32_t pos, Item *item);
927
unsigned char *get_value(Item *item);
904
in_decimal(uint elements);
905
void set(uint pos, Item *item);
906
uchar *get_value(Item *item);
928
907
Item *create_item()
930
909
return new Item_decimal(0, false);
932
void value_to_item(uint32_t pos, Item *item)
911
void value_to_item(uint pos, Item *item)
934
913
my_decimal *dec= ((my_decimal *)base) + pos;
935
914
Item_decimal *item_dec= (Item_decimal*)item;
944
923
** Classes for easy comparing of non const items
947
class cmp_item :public memory::SqlAlloc
926
class cmp_item :public Sql_alloc
950
const CHARSET_INFO *cmp_charset;
929
CHARSET_INFO *cmp_charset;
951
930
cmp_item() { cmp_charset= &my_charset_bin; }
952
931
virtual ~cmp_item() {}
953
932
virtual void store_value(Item *item)= 0;
954
933
virtual int cmp(Item *item)= 0;
955
934
// for optimized IN with row
956
935
virtual int compare(cmp_item *item)= 0;
957
static cmp_item* get_comparator(Item_result type, const CHARSET_INFO * const cs);
936
static cmp_item* get_comparator(Item_result type, CHARSET_INFO *cs);
958
937
virtual cmp_item *make_same()= 0;
959
virtual void store_value_by_template(cmp_item *, Item *item)
938
virtual void store_value_by_template(cmp_item *tmpl __attribute__((__unused__)),
961
941
store_value(item);
965
class cmp_item_string :public cmp_item
945
class cmp_item_string :public cmp_item
968
948
String *value_res;
970
950
cmp_item_string () {}
971
cmp_item_string (const CHARSET_INFO * const cs) { cmp_charset= cs; }
972
void set_charset(const CHARSET_INFO * const cs) { cmp_charset= cs; }
951
cmp_item_string (CHARSET_INFO *cs) { cmp_charset= cs; }
952
void set_charset(CHARSET_INFO *cs) { cmp_charset= cs; }
973
953
friend class cmp_item_sort_string;
974
954
friend class cmp_item_sort_string_in_static;
1040
1020
class cmp_item_datetime :public cmp_item
1045
1025
/* Item used for issuing warnings. */
1046
1026
Item *warn_item;
1047
1027
/* Cache for the left item. */
1048
1028
Item *lval_cache;
1050
1030
cmp_item_datetime(Item *warn_item_arg)
1051
:session(current_session), warn_item(warn_item_arg), lval_cache(0) {}
1031
:thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
1052
1032
void store_value(Item *item);
1053
1033
int cmp(Item *arg);
1054
1034
int compare(cmp_item *ci);
1146
1126
int first_expr_num, else_expr_num;
1147
1127
enum Item_result cached_result_type, left_result_type;
1148
1128
String tmp_value;
1150
1130
Item_result cmp_type;
1151
1131
DTCollation cmp_collation;
1152
1132
enum_field_types cached_field_type;
1153
cmp_item *cmp_items[DECIMAL_RESULT+1]; /* For all result types */
1133
cmp_item *cmp_items[5]; /* For all result types */
1154
1134
cmp_item *case_item;
1156
1136
Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
1169
1149
list.push_back(else_expr_arg);
1171
1151
set_arguments(list);
1172
memset(&cmp_items, 0, sizeof(cmp_items));
1152
bzero(&cmp_items, sizeof(cmp_items));
1174
1154
double val_real();
1176
1156
String *val_str(String *);
1177
1157
my_decimal *val_decimal(my_decimal *);
1178
bool fix_fields(Session *session, Item **ref);
1158
bool fix_fields(THD *thd, Item **ref);
1179
1159
void fix_length_and_dec();
1180
uint32_t decimal_precision() const;
1160
uint decimal_precision() const;
1181
1161
table_map not_null_tables() const { return 0; }
1182
1162
enum Item_result result_type () const { return cached_result_type; }
1183
1163
enum_field_types field_type() const { return cached_field_type; }
1184
1164
const char *func_name() const { return "case"; }
1185
1165
virtual void print(String *str, enum_query_type query_type);
1186
1166
Item *find_item(String *str);
1187
const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1167
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1188
1168
void cleanup();
1189
1169
void agg_str_lengths(Item *arg);
1190
1170
void agg_num_lengths(Item *arg);
1226
1206
:Item_func_opt_neg(list), array(0), have_null(0),
1227
1207
arg_types_compatible(false)
1229
memset(&cmp_items, 0, sizeof(cmp_items));
1209
bzero(&cmp_items, sizeof(cmp_items));
1230
1210
allowed_arg_cols= 0; // Fetch this value from first argument
1233
bool fix_fields(Session *, Item **);
1213
bool fix_fields(THD *, Item **);
1234
1214
void fix_length_and_dec();
1235
uint32_t decimal_precision() const { return 1; }
1215
uint decimal_precision() const { return 1; }
1238
1219
Item_int_func::cleanup();
1241
for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
1222
for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1243
1224
delete cmp_items[i];
1244
1225
cmp_items[i]= 0;
1277
1258
cmp_item_row tmp;
1279
in_row(uint32_t elements, Item *);
1260
in_row(uint elements, Item *);
1281
void set(uint32_t pos,Item *item);
1282
unsigned char *get_value(Item *item);
1262
void set(uint pos,Item *item);
1263
uchar *get_value(Item *item);
1283
1264
friend void Item_func_in::fix_length_and_dec();
1284
1265
Item_result result_type() { return ROW_RESULT; }
1316
1297
!with_subselect)
1318
1299
/* Remember if the value is always NULL or never NULL */
1319
cached_value= (int64_t) args[0]->is_null();
1300
cached_value= (longlong) args[0]->is_null();
1323
1304
table_map not_null_tables() const { return 0; }
1324
1305
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1325
Item *neg_transformer(Session *session);
1326
const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1306
Item *neg_transformer(THD *thd);
1307
CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1329
1310
/* Functions used by HAVING for rewriting IN subquery */
1331
1312
class Item_in_subselect;
1334
1315
This is like IS NOT NULL but it also remembers if it ever has
1335
1316
encountered a NULL.
1368
1349
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1369
1350
table_map not_null_tables() const
1370
1351
{ return abort_on_null ? not_null_tables_cache : 0; }
1371
Item *neg_transformer(Session *session);
1352
Item *neg_transformer(THD *thd);
1372
1353
virtual void print(String *str, enum_query_type query_type);
1373
const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1354
CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1374
1355
void top_level_item() { abort_on_null=1; }
1393
1374
enum { alphabet_size = 256 };
1395
1376
Item *escape_item;
1397
1378
bool escape_used_in_parsing;
1404
1383
Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1405
:Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0),
1384
:Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0),
1406
1385
bmGs(0), bmBc(0), escape_item(escape_arg),
1407
escape_used_in_parsing(escape_used), escape(NULL) {}
1386
escape_used_in_parsing(escape_used) {}
1409
1388
enum Functype functype() const { return LIKE_FUNC; }
1410
1389
optimize_type select_optimize() const;
1411
1390
cond_result eq_cmp_result() const { return COND_TRUE; }
1412
1391
const char *func_name() const { return "like"; }
1413
bool fix_fields(Session *session, Item **ref);
1392
bool fix_fields(THD *thd, Item **ref);
1414
1393
void cleanup();
1437
1413
list.push_back(i1);
1438
1414
list.push_back(i2);
1440
Item_cond(Session *session, Item_cond *item);
1416
Item_cond(THD *thd, Item_cond *item);
1441
1417
Item_cond(List<Item> &nlist)
1442
1418
:Item_bool_func(), list(nlist), abort_on_null(0) {}
1443
1419
bool add(Item *item) { return list.push_back(item); }
1444
1420
bool add_at_head(Item *item) { return list.push_front(item); }
1445
1421
void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1446
bool fix_fields(Session *, Item **ref);
1447
void fix_after_pullout(Select_Lex *new_parent, Item **ref);
1422
bool fix_fields(THD *, Item **ref);
1423
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
1449
1425
enum Type type() const { return COND_ITEM; }
1450
1426
List<Item>* argument_list() { return &list; }
1451
1427
table_map used_tables() const;
1452
1428
void update_used_tables();
1453
1429
virtual void print(String *str, enum_query_type query_type);
1454
void split_sum_func(Session *session, Item **ref_pointer_array, List<Item> &fields);
1455
friend int setup_conds(Session *session, TableList *tables, TableList *leaves,
1430
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
1431
friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
1457
1433
void top_level_item() { abort_on_null=1; }
1458
void copy_andor_arguments(Session *session, Item_cond *item);
1459
bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1460
Item *transform(Item_transformer transformer, unsigned char *arg);
1434
void copy_andor_arguments(THD *thd, Item_cond *item);
1435
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1436
Item *transform(Item_transformer transformer, uchar *arg);
1461
1437
void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1462
void neg_arguments(Session *session);
1463
enum_field_types field_type() const { return DRIZZLE_TYPE_LONGLONG; }
1464
bool subst_argument_checker(unsigned char **)
1438
void neg_arguments(THD *thd);
1439
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
1440
bool subst_argument_checker(uchar **arg __attribute__((__unused__)))
1465
1441
{ return true; }
1466
Item *compile(Item_analyzer analyzer, unsigned char **arg_p,
1467
Item_transformer transformer, unsigned char *arg_t);
1442
Item *compile(Item_analyzer analyzer, uchar **arg_p,
1443
Item_transformer transformer, uchar *arg_t);
1485
1461
A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1486
1462
substituted for the item representing the same multiple equality
1488
An item Item_equal(f1,f2) can appear instead of a conjunction of
1464
An item Item_equal(f1,f2) can appear instead of a conjunction of
1489
1465
f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1491
An item of the class Item_equal inherits equalities from outer
1467
An item of the class Item_equal inherits equalities from outer
1492
1468
conjunctive levels.
1494
1470
Suppose we have a where condition of the following form:
1514
1490
It also can give us additional index scans and can allow us to
1515
1491
improve selectivity estimates.
1517
3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
1518
selected execution plan for the query: if table ti is accessed
1493
3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
1494
selected execution plan for the query: if table ti is accessed
1519
1495
before the table tj then in any predicate P in the where condition
1520
1496
the occurrence of tj.fj is substituted for ti.fi. This can allow
1521
1497
an evaluation of the predicate at an earlier step.
1523
When feature 1 is supported they say that join transitive closure
1499
When feature 1 is supported they say that join transitive closure
1525
1501
When feature 2 is supported they say that search argument transitive
1526
1502
closure is employed.
1559
1535
inline Item* get_const() { return const_item; }
1560
1536
void add(Item *c);
1561
1537
void add(Item_field *f);
1563
1539
bool contains(Field *field);
1564
1540
Item_field* get_first() { return fields.head(); }
1565
1541
void merge(Item_equal *item);
1566
1542
void update_const();
1567
1543
enum Functype functype() const { return MULT_EQUAL_FUNC; }
1569
1545
const char *func_name() const { return "multiple equal"; }
1570
1546
optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1571
1547
void sort(Item_field_cmpfunc cmp, void *arg);
1572
1548
friend class Item_equal_iterator;
1573
1549
void fix_length_and_dec();
1574
bool fix_fields(Session *session, Item **ref);
1550
bool fix_fields(THD *thd, Item **ref);
1575
1551
void update_used_tables();
1576
bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1577
Item *transform(Item_transformer transformer, unsigned char *arg);
1552
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1553
Item *transform(Item_transformer transformer, uchar *arg);
1578
1554
virtual void print(String *str, enum_query_type query_type);
1579
const CHARSET_INFO *compare_collation()
1555
CHARSET_INFO *compare_collation()
1580
1556
{ return fields.head()->collation.collation; }
1583
class COND_EQUAL: public memory::SqlAlloc
1559
class COND_EQUAL: public Sql_alloc
1586
uint32_t max_members; /* max number of members the current level
1587
list and all lower level lists */
1562
uint max_members; /* max number of members the current level
1563
list and all lower level lists */
1588
1564
COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
1589
List<Item_equal> current_level; /* list of multiple equalities of
1565
List<Item_equal> current_level; /* list of multiple equalities of
1590
1566
the current and level */
1593
1569
upper_levels= 0;
1615
1591
class Item_cond_and :public Item_cond
1618
COND_EQUAL cond_equal; /* contains list of Item_equal objects for
1594
COND_EQUAL cond_equal; /* contains list of Item_equal objects for
1619
1595
the current and level and reference
1620
to multiple equalities of upper and levels */
1596
to multiple equalities of upper and levels */
1621
1597
Item_cond_and() :Item_cond() {}
1622
1598
Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1623
Item_cond_and(Session *session, Item_cond_and *item) :Item_cond(session, item) {}
1599
Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
1624
1600
Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1625
1601
enum Functype functype() const { return COND_AND_FUNC; }
1627
1603
const char *func_name() const { return "and"; }
1628
1604
table_map not_null_tables() const
1629
1605
{ return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1630
Item* copy_andor_structure(Session *session)
1606
Item* copy_andor_structure(THD *thd)
1632
1608
Item_cond_and *item;
1633
if ((item= new Item_cond_and(session, this)))
1634
item->copy_andor_arguments(session, this);
1609
if ((item= new Item_cond_and(thd, this)))
1610
item->copy_andor_arguments(thd, this);
1637
Item *neg_transformer(Session *session);
1613
Item *neg_transformer(THD *thd);
1640
1616
inline bool is_cond_and(Item *item)
1652
1628
Item_cond_or() :Item_cond() {}
1653
1629
Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1654
Item_cond_or(Session *session, Item_cond_or *item) :Item_cond(session, item) {}
1630
Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
1655
1631
Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1656
1632
enum Functype functype() const { return COND_OR_FUNC; }
1658
1634
const char *func_name() const { return "or"; }
1659
1635
table_map not_null_tables() const { return and_tables_cache; }
1660
Item* copy_andor_structure(Session *session)
1636
Item* copy_andor_structure(THD *thd)
1662
1638
Item_cond_or *item;
1663
if ((item= new Item_cond_or(session, this)))
1664
item->copy_andor_arguments(session, this);
1639
if ((item= new Item_cond_or(thd, this)))
1640
item->copy_andor_arguments(thd, this);
1667
Item *neg_transformer(Session *session);
1643
Item *neg_transformer(THD *thd);
1670
1646
inline bool is_cond_or(Item *item)