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/decimal.h"
31
#include "drizzled/function/math/int.h"
32
#include "drizzled/function/numhybrid.h"
33
#include "drizzled/session.h"
34
#include "drizzled/common.h"
35
#include "drizzled/qsort_cmp.h"
19
#ifdef USE_PRAGMA_INTERFACE
20
#pragma interface /* gcc class implementation */
40
23
extern Item_result item_cmp_type(Item_result a,Item_result b);
41
24
class Item_bool_func2;
42
25
class Arg_comparator;
43
class Item_sum_hybrid;
46
27
typedef int (Arg_comparator::*arg_cmp_func)();
48
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
50
uint64_t get_datetime_value(Session *session,
56
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
61
36
Arg_comparator *comparators; // used only for compare_row()
63
38
/* Fields used in DATE/DATETIME comparison. */
65
40
enum_field_types a_type, b_type; // Types of a and b items
66
41
Item *a_cache, *b_cache; // Cached values of a and b items
67
42
bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
68
43
enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
69
44
CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
70
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,
71
46
Item *warn_item, bool *is_null);
73
48
DTCollation cmp_collation;
75
Arg_comparator(): session(0), a_cache(0), b_cache(0) {};
76
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),
77
52
a_cache(0), b_cache(0) {};
79
54
int set_compare_func(Item_bool_func2 *owner, Item_result type);
130
105
Item_bool_func() :Item_int_func() {}
131
106
Item_bool_func(Item *a) :Item_int_func(a) {}
132
107
Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
133
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) {}
134
109
bool is_bool_func() { return 1; }
135
110
void fix_length_and_dec() { decimals=0; max_length=1; }
136
uint32_t decimal_precision() const { return 1; }
111
uint decimal_precision() const { return 1; }
247
222
Item_cache *cache;
250
225
Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
251
226
UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
252
227
FALSE - result is FALSE
253
228
TRUE - result is NULL
255
bool result_for_null_param;
230
my_bool result_for_null_param;
257
232
Item_in_optimizer(Item *a, Item_in_subselect *b):
258
Item_bool_func(a, reinterpret_cast<Item *>(b)), cache(0),
233
Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0),
259
234
save_cache(0), result_for_null_param(UNKNOWN)
260
235
{ with_subselect= true; }
261
bool fix_fields(Session *, Item **);
262
bool fix_left(Session *session, Item **ref);
236
bool fix_fields(THD *, Item **);
237
bool fix_left(THD *thd, Item **ref);
266
241
const char *func_name() const { return "<in_optimizer>"; }
267
242
Item_cache **get_cache() { return &cache; }
268
243
void keep_top_level_cache();
269
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;
272
258
class Eq_creator :public Comp_creator
368
348
bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
369
349
bool is_bool_func() { return 1; }
370
const CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
371
uint32_t decimal_precision() const { return 1; }
350
CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
351
uint decimal_precision() const { return 1; }
372
352
void top_level_item() { abort_on_null= true; }
374
354
friend class Arg_comparator;
404
384
trigcond<param>(arg) ::= param? arg : TRUE
406
The class Item_func_trig_cond is used for guarded predicates
386
The class Item_func_trig_cond is used for guarded predicates
407
387
which are employed only for internal purposes.
408
388
A guarded predicate is an object consisting of an a regular or
409
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.
410
390
A guarded predicate P/g is evaluated to true if the value of the
411
391
guard g is false, otherwise it is evaluated to the same value that
412
392
the predicate P: val(P/g)= g ? val(P):true.
418
398
the objects consisting of three elements: a predicate P, a pointer
419
399
to a variable g and a firing value s with following evaluation
420
400
rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
421
one item for the objects of the form P/g1/g2...
401
one item for the objects of the form P/g1/g2...
423
403
Objects of this class are built only for query execution after
424
404
the execution plan has been already selected. That's why this
425
class needs only val_int out of generic methods.
405
class needs only val_int out of generic methods.
427
407
Current uses of Item_func_trig_cond objects:
428
408
- To wrap selection conditions when executing outer joins
429
409
- To wrap condition that is pushed down into subquery
460
440
virtual void top_level_item() { abort_on_null= 1; }
461
441
bool top_level() { return abort_on_null; }
463
443
enum Functype functype() const { return NOT_ALL_FUNC; }
464
444
const char *func_name() const { return "<not>"; }
465
445
virtual void print(String *str, enum_query_type query_type);
466
446
void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
467
447
void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
468
448
bool empty_underlying_subquery();
469
Item *neg_transformer(Session *session);
449
Item *neg_transformer(THD *thd);
499
479
Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
501
481
void fix_length_and_dec();
502
482
table_map not_null_tables() const { return 0; }
503
483
enum Functype functype() const { return EQUAL_FUNC; }
504
484
enum Functype rev_functype() const { return EQUAL_FUNC; }
505
485
cond_result eq_cmp_result() const { return COND_TRUE; }
506
486
const char *func_name() const { return "<=>"; }
507
Item *neg_transformer(Session *) { return 0; }
487
Item *neg_transformer(THD *thd __attribute__((__unused__))) { return 0; }
618
598
Arg_comparator ge_cmp, le_cmp;
619
599
Item_func_between(Item *a, Item *b, Item *c)
620
600
:Item_func_opt_neg(a, b, c), compare_as_dates(false) {}
622
602
optimize_type select_optimize() const { return OPTIMIZE_KEY; }
623
603
enum Functype functype() const { return BETWEEN; }
624
604
const char *func_name() const { return "between"; }
625
bool fix_fields(Session *, Item **);
605
bool fix_fields(THD *, Item **);
626
606
void fix_length_and_dec();
627
607
virtual void print(String *str, enum_query_type query_type);
628
608
bool is_bool_func() { return 1; }
629
const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
630
uint32_t decimal_precision() const { return 1; }
609
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
610
uint decimal_precision() const { return 1; }
699
679
Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
700
680
double real_op();
702
682
String *str_op(String *str);
703
683
my_decimal *decimal_op(my_decimal *);
704
684
enum_field_types field_type() const;
705
685
void fix_length_and_dec();
706
686
const char *func_name() const { return "ifnull"; }
707
Field *tmp_table_field()
709
return Item_func::tmp_table_field();
711
Field *tmp_table_field(Table *table);
712
uint32_t decimal_precision() const;
687
Field *tmp_table_field(TABLE *table);
688
uint decimal_precision() const;
722
698
:Item_func(a,b,c), cached_result_type(INT_RESULT)
724
700
double val_real();
726
702
String *val_str(String *str);
727
703
my_decimal *val_decimal(my_decimal *);
728
704
enum Item_result result_type () const { return cached_result_type; }
729
705
enum_field_types field_type() const { return cached_field_type; }
730
bool fix_fields(Session *, Item **);
706
bool fix_fields(THD *, Item **);
731
707
void fix_length_and_dec();
732
uint32_t decimal_precision() const;
708
uint decimal_precision() const;
733
709
const char *func_name() const { return "if"; }
742
718
:Item_bool_func2(a,b), cached_result_type(INT_RESULT)
744
720
double val_real();
746
722
String *val_str(String *str);
747
723
my_decimal *val_decimal(my_decimal *);
748
724
enum Item_result result_type () const { return cached_result_type; }
749
725
void fix_length_and_dec();
750
uint32_t decimal_precision() const { return args[0]->decimal_precision(); }
726
uint decimal_precision() const { return args[0]->decimal_precision(); }
751
727
const char *func_name() const { return "nullif"; }
753
729
virtual inline void print(String *str, enum_query_type query_type)
766
742
/* A vector of values of some type */
768
class in_vector :public memory::SqlAlloc
744
class in_vector :public Sql_alloc
773
749
qsort2_cmp compare;
774
const CHARSET_INFO *collation;
750
CHARSET_INFO *collation;
778
in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func,
779
const CHARSET_INFO * const cmp_coll)
780
: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)),
781
757
size(element_length), compare(cmp_func), collation(cmp_coll),
782
758
count(elements), used_count(elements) {}
783
759
virtual ~in_vector() {}
784
virtual void set(uint32_t pos,Item *item)=0;
785
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);
787
766
int find(Item *item);
790
769
Create an instance of Item_{type} (e.g. Item_decimal) constant object
791
770
which type allows it to hold an element of this vector without any
804
783
item Constant item to store value into. The item must be of the same
805
784
type that create_item() returns.
807
virtual void value_to_item(uint32_t, Item *) { }
786
virtual void value_to_item(uint pos __attribute__((__unused__)),
787
Item *item __attribute__((__unused__))) { }
809
789
/* Compare values number pos1 and pos2 for equality */
810
bool compare_elems(uint32_t pos1, uint32_t pos2)
790
bool compare_elems(uint pos1, uint pos2)
812
792
return test(compare(collation, base + pos1*size, base + pos2*size));
819
799
char buff[STRING_BUFFER_USUAL_SIZE];
822
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);
824
void set(uint32_t pos,Item *item);
825
unsigned char *get_value(Item *item);
804
void set(uint pos,Item *item);
805
uchar *get_value(Item *item);
826
806
Item* create_item()
828
808
return new Item_string(collation);
830
void value_to_item(uint32_t pos, Item *item)
810
void value_to_item(uint pos, Item *item)
832
812
String *str=((String*) base)+pos;
833
813
Item_string *to= (Item_string*)item;
834
814
to->str_value= *str;
836
816
Item_result result_type() { return STRING_RESULT; }
839
class in_int64_t :public in_vector
819
class in_longlong :public in_vector
843
823
Here we declare a temporary variable (tmp) of the same type as the
844
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
847
struct packed_int64_t
827
struct packed_longlong
850
int64_t unsigned_flag; // Use int64_t, not bool, to preserve alignment
830
longlong unsigned_flag; // Use longlong, not bool, to preserve alignment
853
in_int64_t(uint32_t elements);
854
void set(uint32_t pos,Item *item);
855
unsigned char *get_value(Item *item);
833
in_longlong(uint elements);
834
void set(uint pos,Item *item);
835
uchar *get_value(Item *item);
857
837
Item* create_item()
860
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
861
841
general case (see BUG#19342).
863
return new Item_int((int64_t)0);
843
return new Item_int((longlong)0);
865
void value_to_item(uint32_t pos, Item *item)
845
void value_to_item(uint pos, Item *item)
867
((Item_int*) item)->value= ((packed_int64_t*) base)[pos].val;
868
((Item_int*) item)->unsigned_flag= (bool)
869
((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;
871
851
Item_result result_type() { return INT_RESULT; }
873
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);
880
860
If the left item is a constant one then its value is cached in the
881
861
lval_cache variable.
883
class in_datetime :public in_int64_t
863
class in_datetime :public in_longlong
887
867
/* An item used to issue warnings. */
889
869
/* Cache for the left item. */
890
870
Item *lval_cache;
892
in_datetime(Item *warn_item_arg, uint32_t elements)
893
: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),
894
874
lval_cache(0) {};
895
void set(uint32_t pos,Item *item);
896
unsigned char *get_value(Item *item);
897
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);
905
in_double(uint32_t elements);
906
void set(uint32_t pos,Item *item);
907
unsigned char *get_value(Item *item);
885
in_double(uint elements);
886
void set(uint pos,Item *item);
887
uchar *get_value(Item *item);
908
888
Item *create_item()
910
890
return new Item_float(0.0, 0);
912
void value_to_item(uint32_t pos, Item *item)
892
void value_to_item(uint pos, Item *item)
914
894
((Item_float*)item)->value= ((double*) base)[pos];
924
in_decimal(uint32_t elements);
925
void set(uint32_t pos, Item *item);
926
unsigned char *get_value(Item *item);
904
in_decimal(uint elements);
905
void set(uint pos, Item *item);
906
uchar *get_value(Item *item);
927
907
Item *create_item()
929
909
return new Item_decimal(0, false);
931
void value_to_item(uint32_t pos, Item *item)
911
void value_to_item(uint pos, Item *item)
933
913
my_decimal *dec= ((my_decimal *)base) + pos;
934
914
Item_decimal *item_dec= (Item_decimal*)item;
943
923
** Classes for easy comparing of non const items
946
class cmp_item :public memory::SqlAlloc
926
class cmp_item :public Sql_alloc
949
const CHARSET_INFO *cmp_charset;
929
CHARSET_INFO *cmp_charset;
950
930
cmp_item() { cmp_charset= &my_charset_bin; }
951
931
virtual ~cmp_item() {}
952
932
virtual void store_value(Item *item)= 0;
953
933
virtual int cmp(Item *item)= 0;
954
934
// for optimized IN with row
955
935
virtual int compare(cmp_item *item)= 0;
956
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);
957
937
virtual cmp_item *make_same()= 0;
958
virtual void store_value_by_template(cmp_item *, Item *item)
938
virtual void store_value_by_template(cmp_item *tmpl __attribute__((__unused__)),
960
941
store_value(item);
964
class cmp_item_string :public cmp_item
945
class cmp_item_string :public cmp_item
967
948
String *value_res;
969
950
cmp_item_string () {}
970
cmp_item_string (const CHARSET_INFO * const cs) { cmp_charset= cs; }
971
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; }
972
953
friend class cmp_item_sort_string;
973
954
friend class cmp_item_sort_string_in_static;
1039
1020
class cmp_item_datetime :public cmp_item
1044
1025
/* Item used for issuing warnings. */
1045
1026
Item *warn_item;
1046
1027
/* Cache for the left item. */
1047
1028
Item *lval_cache;
1049
1030
cmp_item_datetime(Item *warn_item_arg)
1050
:session(current_session), warn_item(warn_item_arg), lval_cache(0) {}
1031
:thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
1051
1032
void store_value(Item *item);
1052
1033
int cmp(Item *arg);
1053
1034
int compare(cmp_item *ci);
1168
1149
list.push_back(else_expr_arg);
1170
1151
set_arguments(list);
1171
memset(&cmp_items, 0, sizeof(cmp_items));
1152
bzero(&cmp_items, sizeof(cmp_items));
1173
1154
double val_real();
1175
1156
String *val_str(String *);
1176
1157
my_decimal *val_decimal(my_decimal *);
1177
bool fix_fields(Session *session, Item **ref);
1158
bool fix_fields(THD *thd, Item **ref);
1178
1159
void fix_length_and_dec();
1179
uint32_t decimal_precision() const;
1160
uint decimal_precision() const;
1180
1161
table_map not_null_tables() const { return 0; }
1181
1162
enum Item_result result_type () const { return cached_result_type; }
1182
1163
enum_field_types field_type() const { return cached_field_type; }
1183
1164
const char *func_name() const { return "case"; }
1184
1165
virtual void print(String *str, enum_query_type query_type);
1185
1166
Item *find_item(String *str);
1186
const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1167
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1187
1168
void cleanup();
1188
1169
void agg_str_lengths(Item *arg);
1189
1170
void agg_num_lengths(Item *arg);
1225
1206
:Item_func_opt_neg(list), array(0), have_null(0),
1226
1207
arg_types_compatible(false)
1228
memset(&cmp_items, 0, sizeof(cmp_items));
1209
bzero(&cmp_items, sizeof(cmp_items));
1229
1210
allowed_arg_cols= 0; // Fetch this value from first argument
1232
bool fix_fields(Session *, Item **);
1213
bool fix_fields(THD *, Item **);
1233
1214
void fix_length_and_dec();
1234
uint32_t decimal_precision() const { return 1; }
1215
uint decimal_precision() const { return 1; }
1238
1219
Item_int_func::cleanup();
1241
for (i= 0; i <= (uint32_t)DECIMAL_RESULT + 1; 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)