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, Inc.
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/common.h"
35
#include "drizzled/qsort_cmp.h"
36
#include "drizzled/item/function/boolean.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);
43
24
class Item_bool_func2;
44
25
class Arg_comparator;
45
class Item_sum_hybrid;
49
27
typedef int (Arg_comparator::*arg_cmp_func)();
51
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
53
int64_t get_datetime_value(Session *session,
59
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
64
36
Arg_comparator *comparators; // used only for compare_row()
66
38
/* Fields used in DATE/DATETIME comparison. */
68
40
enum_field_types a_type, b_type; // Types of a and b items
69
41
Item *a_cache, *b_cache; // Cached values of a and b items
70
42
bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
71
43
enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
72
44
CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
73
int64_t (*get_value_func)(Session *session, Item ***item_arg, Item **cache_arg,
74
Item *warn_item, bool *is_null);
45
uint64_t (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
46
Item *warn_item, bool *is_null);
76
48
DTCollation cmp_collation;
79
session(current_session),
84
Arg_comparator(Item **a1, Item **a2):
87
session(current_session),
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) {};
92
54
int set_compare_func(Item_bool_func2 *owner, Item_result type);
93
55
inline int set_compare_func(Item_bool_func2 *owner_arg)
137
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; }
142
116
Abstract Item class, to represent <code>X IS [NOT] (TRUE | FALSE)</code>
143
117
boolean predicates.
146
class Item_func_truth : public item::function::Boolean
120
class Item_func_truth : public Item_bool_func
149
123
virtual bool val_bool();
242
216
placed into a separate class called 'Item_in_optimizer'.
245
class Item_in_optimizer: public item::function::Boolean
219
class Item_in_optimizer: public Item_bool_func
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::function::Boolean(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);
265
239
int64_t val_int();
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
383
362
allowed_arg_cols= 0; // Fetch this value from first argument
385
Item *neg_transformer(Session *session);
364
Item *neg_transformer(THD *thd);
386
365
virtual Item *negated_item();
387
bool subst_argument_checker(unsigned char **)
366
bool subst_argument_checker(uchar **arg __attribute__((__unused__)))
391
class Item_func_not :public item::function::Boolean
370
class Item_func_not :public Item_bool_func
394
Item_func_not(Item *a) :item::function::Boolean(a) {}
373
Item_func_not(Item *a) :Item_bool_func(a) {}
395
374
int64_t val_int();
396
375
enum Functype functype() const { return NOT_FUNC; }
397
376
const char *func_name() const { return "not"; }
398
Item *neg_transformer(Session *session);
377
Item *neg_transformer(THD *thd);
399
378
virtual void print(String *str, enum_query_type query_type);
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
433
class Item_func_trig_cond: public item::function::Boolean
412
class Item_func_trig_cond: public Item_bool_func
437
Item_func_trig_cond(Item *a, bool *f) : item::function::Boolean(a) { trig_var= f; }
416
Item_func_trig_cond(Item *a, bool *f) : Item_bool_func(a) { trig_var= f; }
438
417
int64_t val_int() { return *trig_var ? args[0]->val_int() : 1; }
439
418
enum Functype functype() const { return TRIG_COND_FUNC; };
440
419
const char *func_name() const { return "trigcond"; };
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; }
701
680
double real_op();
702
681
int64_t int_op();
703
682
String *str_op(String *str);
704
type::Decimal *decimal_op(type::Decimal *);
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;
725
700
double val_real();
726
701
int64_t val_int();
727
702
String *val_str(String *str);
728
type::Decimal *val_decimal(type::Decimal *);
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"; }
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;
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_int64_t
851
830
int64_t unsigned_flag; // Use int64_t, 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_int64_t(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
843
return new Item_int((int64_t)0);
866
void value_to_item(uint32_t pos, Item *item)
845
void value_to_item(uint pos, Item *item)
868
847
((Item_int*) item)->value= ((packed_int64_t*) base)[pos].val;
869
((Item_int*) item)->unsigned_flag= (bool)
848
((Item_int*) item)->unsigned_flag= (my_bool)
870
849
((packed_int64_t*) base)[pos].unsigned_flag;
872
851
Item_result result_type() { return INT_RESULT; }
884
863
class in_datetime :public in_int64_t
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_int64_t(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);
875
void set(uint pos,Item *item);
876
uchar *get_value(Item *item);
898
877
friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *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];
921
900
class in_decimal :public in_vector
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
type::Decimal *dec= ((type::Decimal *)base) + pos;
913
my_decimal *dec= ((my_decimal *)base) + pos;
935
914
Item_decimal *item_dec= (Item_decimal*)item;
936
915
item_dec->set_decimal_value(dec);
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;
954
cmp_charset= &my_charset_bin;
929
CHARSET_INFO *cmp_charset;
930
cmp_item() { cmp_charset= &my_charset_bin; }
957
931
virtual ~cmp_item() {}
958
932
virtual void store_value(Item *item)= 0;
959
933
virtual int cmp(Item *item)= 0;
960
934
// for optimized IN with row
961
935
virtual int compare(cmp_item *item)= 0;
962
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);
963
937
virtual cmp_item *make_same()= 0;
964
virtual void store_value_by_template(cmp_item *, Item *item)
938
virtual void store_value_by_template(cmp_item *tmpl __attribute__((__unused__)),
966
941
store_value(item);
970
class cmp_item_string :public cmp_item
945
class cmp_item_string :public cmp_item
973
948
String *value_res;
975
950
cmp_item_string () {}
976
cmp_item_string (const CHARSET_INFO * const cs) { cmp_charset= cs; }
977
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; }
978
953
friend class cmp_item_sort_string;
979
954
friend class cmp_item_sort_string_in_static;
1175
1149
list.push_back(else_expr_arg);
1177
1151
set_arguments(list);
1178
memset(&cmp_items, 0, sizeof(cmp_items));
1152
bzero(&cmp_items, sizeof(cmp_items));
1180
1154
double val_real();
1181
1155
int64_t val_int();
1182
1156
String *val_str(String *);
1183
type::Decimal *val_decimal(type::Decimal *);
1184
bool fix_fields(Session *session, Item **ref);
1157
my_decimal *val_decimal(my_decimal *);
1158
bool fix_fields(THD *thd, Item **ref);
1185
1159
void fix_length_and_dec();
1186
uint32_t decimal_precision() const;
1160
uint decimal_precision() const;
1187
1161
table_map not_null_tables() const { return 0; }
1188
1162
enum Item_result result_type () const { return cached_result_type; }
1189
1163
enum_field_types field_type() const { return cached_field_type; }
1190
1164
const char *func_name() const { return "case"; }
1191
1165
virtual void print(String *str, enum_query_type query_type);
1192
1166
Item *find_item(String *str);
1193
const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1167
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1194
1168
void cleanup();
1195
1169
void agg_str_lengths(Item *arg);
1196
1170
void agg_num_lengths(Item *arg);
1232
1206
:Item_func_opt_neg(list), array(0), have_null(0),
1233
1207
arg_types_compatible(false)
1235
memset(&cmp_items, 0, sizeof(cmp_items));
1209
bzero(&cmp_items, sizeof(cmp_items));
1236
1210
allowed_arg_cols= 0; // Fetch this value from first argument
1238
1212
int64_t val_int();
1239
bool fix_fields(Session *, Item **);
1213
bool fix_fields(THD *, Item **);
1240
1214
void fix_length_and_dec();
1241
uint32_t decimal_precision() const { return 1; }
1215
uint decimal_precision() const { return 1; }
1244
1219
Item_int_func::cleanup();
1247
for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
1222
for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1249
1224
delete cmp_items[i];
1250
1225
cmp_items[i]= 0;
1283
1258
cmp_item_row tmp;
1285
in_row(uint32_t elements, Item *);
1260
in_row(uint elements, Item *);
1287
void set(uint32_t pos,Item *item);
1288
unsigned char *get_value(Item *item);
1262
void set(uint pos,Item *item);
1263
uchar *get_value(Item *item);
1289
1264
friend void Item_func_in::fix_length_and_dec();
1290
1265
Item_result result_type() { return ROW_RESULT; }
1293
1268
/* Functions used by where clause */
1295
class Item_func_isnull :public item::function::Boolean
1270
class Item_func_isnull :public Item_bool_func
1298
1273
int64_t cached_value;
1300
Item_func_isnull(Item *a) :item::function::Boolean(a) {}
1275
Item_func_isnull(Item *a) :Item_bool_func(a) {}
1301
1276
int64_t val_int();
1302
1277
enum Functype functype() const { return ISNULL_FUNC; }
1303
1278
void fix_length_and_dec()
1399
1374
enum { alphabet_size = 256 };
1401
1376
Item *escape_item;
1403
1378
bool escape_used_in_parsing;
1410
1383
Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1411
: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),
1412
1385
bmGs(0), bmBc(0), escape_item(escape_arg),
1413
escape_used_in_parsing(escape_used), escape(NULL) {}
1386
escape_used_in_parsing(escape_used) {}
1414
1387
int64_t val_int();
1415
1388
enum Functype functype() const { return LIKE_FUNC; }
1416
1389
optimize_type select_optimize() const;
1417
1390
cond_result eq_cmp_result() const { return COND_TRUE; }
1418
1391
const char *func_name() const { return "like"; }
1419
bool fix_fields(Session *session, Item **ref);
1392
bool fix_fields(THD *thd, Item **ref);
1420
1393
void cleanup();
1424
1397
typedef class Item COND;
1426
class Item_cond :public item::function::Boolean
1399
class Item_cond :public Item_bool_func
1429
1402
List<Item> list;
1431
1404
table_map and_tables_cache;
1435
using Item::split_sum_func;
1437
1407
/* Item_cond() is only used to create top level items */
1438
Item_cond(): item::function::Boolean(), abort_on_null(1)
1408
Item_cond(): Item_bool_func(), abort_on_null(1)
1439
1409
{ const_item_cache=0; }
1440
1410
Item_cond(Item *i1,Item *i2)
1441
:item::function::Boolean(), abort_on_null(0)
1411
:Item_bool_func(), abort_on_null(0)
1443
1413
list.push_back(i1);
1444
1414
list.push_back(i2);
1446
Item_cond(Session *session, Item_cond *item);
1416
Item_cond(THD *thd, Item_cond *item);
1447
1417
Item_cond(List<Item> &nlist)
1448
:item::function::Boolean(), list(nlist), abort_on_null(0) {}
1418
:Item_bool_func(), list(nlist), abort_on_null(0) {}
1449
1419
bool add(Item *item) { return list.push_back(item); }
1450
1420
bool add_at_head(Item *item) { return list.push_front(item); }
1451
1421
void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1452
bool fix_fields(Session *, Item **ref);
1453
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);
1455
1425
enum Type type() const { return COND_ITEM; }
1456
1426
List<Item>* argument_list() { return &list; }
1457
1427
table_map used_tables() const;
1458
1428
void update_used_tables();
1459
1429
virtual void print(String *str, enum_query_type query_type);
1460
void split_sum_func(Session *session, Item **ref_pointer_array, List<Item> &fields);
1461
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,
1463
1433
void top_level_item() { abort_on_null=1; }
1464
void copy_andor_arguments(Session *session, Item_cond *item);
1465
bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1466
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);
1467
1437
void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1468
void neg_arguments(Session *session);
1469
enum_field_types field_type() const { return DRIZZLE_TYPE_LONGLONG; }
1470
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__)))
1471
1441
{ return true; }
1472
Item *compile(Item_analyzer analyzer, unsigned char **arg_p,
1473
Item_transformer transformer, unsigned char *arg_t);
1442
Item *compile(Item_analyzer analyzer, uchar **arg_p,
1443
Item_transformer transformer, uchar *arg_t);
1520
1490
It also can give us additional index scans and can allow us to
1521
1491
improve selectivity estimates.
1523
3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
1524
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
1525
1495
before the table tj then in any predicate P in the where condition
1526
1496
the occurrence of tj.fj is substituted for ti.fi. This can allow
1527
1497
an evaluation of the predicate at an earlier step.
1529
When feature 1 is supported they say that join transitive closure
1499
When feature 1 is supported they say that join transitive closure
1531
1501
When feature 2 is supported they say that search argument transitive
1532
1502
closure is employed.
1549
1519
object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
1552
class Item_equal: public item::function::Boolean
1522
class Item_equal: public Item_bool_func
1554
1524
List<Item_field> fields; /* list of equal field items */
1555
1525
Item *const_item; /* optional constant item equal to fields items */
1556
1526
cmp_item *eval_item;
1557
1527
bool cond_false;
1560
inline Item_equal() :
1561
item::function::Boolean(),
1530
: Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
1531
{ const_item_cache=0 ;}
1569
1532
Item_equal(Item_field *f1, Item_field *f2);
1570
1533
Item_equal(Item *c, Item_field *f);
1571
1534
Item_equal(Item_equal *item_equal);
1572
1535
inline Item* get_const() { return const_item; }
1573
1536
void add(Item *c);
1574
1537
void add(Item_field *f);
1576
1539
bool contains(Field *field);
1577
1540
Item_field* get_first() { return fields.head(); }
1578
1541
void merge(Item_equal *item);
1579
1542
void update_const();
1580
1543
enum Functype functype() const { return MULT_EQUAL_FUNC; }
1582
1545
const char *func_name() const { return "multiple equal"; }
1583
1546
optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1584
1547
void sort(Item_field_cmpfunc cmp, void *arg);
1585
1548
friend class Item_equal_iterator;
1586
1549
void fix_length_and_dec();
1587
bool fix_fields(Session *session, Item **ref);
1550
bool fix_fields(THD *thd, Item **ref);
1588
1551
void update_used_tables();
1589
bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1590
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);
1591
1554
virtual void print(String *str, enum_query_type query_type);
1592
const CHARSET_INFO *compare_collation()
1555
CHARSET_INFO *compare_collation()
1593
1556
{ return fields.head()->collation.collation; }
1596
class COND_EQUAL: public memory::SqlAlloc
1559
class COND_EQUAL: public Sql_alloc
1599
uint32_t max_members; /* max number of members the current level
1600
list and all lower level lists */
1562
uint max_members; /* max number of members the current level
1563
list and all lower level lists */
1601
1564
COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
1602
List<Item_equal> current_level; /* list of multiple equalities of
1565
List<Item_equal> current_level; /* list of multiple equalities of
1603
1566
the current and level */
1606
1569
upper_levels= 0;
1628
1591
class Item_cond_and :public Item_cond
1631
COND_EQUAL cond_equal; /* contains list of Item_equal objects for
1594
COND_EQUAL cond_equal; /* contains list of Item_equal objects for
1632
1595
the current and level and reference
1633
to multiple equalities of upper and levels */
1596
to multiple equalities of upper and levels */
1634
1597
Item_cond_and() :Item_cond() {}
1635
1598
Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1636
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) {}
1637
1600
Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1638
1601
enum Functype functype() const { return COND_AND_FUNC; }
1639
1602
int64_t val_int();
1640
1603
const char *func_name() const { return "and"; }
1641
1604
table_map not_null_tables() const
1642
1605
{ return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1643
Item* copy_andor_structure(Session *session)
1606
Item* copy_andor_structure(THD *thd)
1645
1608
Item_cond_and *item;
1646
if ((item= new Item_cond_and(session, this)))
1647
item->copy_andor_arguments(session, this);
1609
if ((item= new Item_cond_and(thd, this)))
1610
item->copy_andor_arguments(thd, this);
1650
Item *neg_transformer(Session *session);
1613
Item *neg_transformer(THD *thd);
1653
1616
inline bool is_cond_and(Item *item)
1665
1628
Item_cond_or() :Item_cond() {}
1666
1629
Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1667
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) {}
1668
1631
Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1669
1632
enum Functype functype() const { return COND_OR_FUNC; }
1670
1633
int64_t val_int();
1671
1634
const char *func_name() const { return "or"; }
1672
1635
table_map not_null_tables() const { return and_tables_cache; }
1673
Item* copy_andor_structure(Session *session)
1636
Item* copy_andor_structure(THD *thd)
1675
1638
Item_cond_or *item;
1676
if ((item= new Item_cond_or(session, this)))
1677
item->copy_andor_arguments(session, this);
1639
if ((item= new Item_cond_or(thd, this)))
1640
item->copy_andor_arguments(thd, this);
1680
Item *neg_transformer(Session *session);
1643
Item *neg_transformer(THD *thd);
1683
1646
inline bool is_cond_or(Item *item)