17
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
21
23
/* compare and test functions */
23
#ifdef USE_PRAGMA_INTERFACE
24
#pragma interface /* gcc class implementation */
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"
27
35
extern Item_result item_cmp_type(Item_result a,Item_result b);
28
36
class Item_bool_func2;
29
37
class Arg_comparator;
38
class Item_sum_hybrid;
31
41
typedef int (Arg_comparator::*arg_cmp_func)();
33
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
43
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
35
45
class Arg_comparator: public Sql_alloc
40
50
Arg_comparator *comparators; // used only for compare_row()
42
52
/* Fields used in DATE/DATETIME comparison. */
44
54
enum_field_types a_type, b_type; // Types of a and b items
45
55
Item *a_cache, *b_cache; // Cached values of a and b items
46
56
bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC
47
57
enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
48
58
CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
49
uint64_t (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
59
uint64_t (*get_value_func)(Session *session, Item ***item_arg, Item **cache_arg,
50
60
Item *warn_item, bool *is_null);
52
62
DTCollation cmp_collation;
54
Arg_comparator(): thd(0), a_cache(0), b_cache(0) {};
55
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
64
Arg_comparator(): session(0), a_cache(0), b_cache(0) {};
65
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), session(0),
56
66
a_cache(0), b_cache(0) {};
58
68
int set_compare_func(Item_bool_func2 *owner, Item_result type);
109
119
Item_bool_func() :Item_int_func() {}
110
120
Item_bool_func(Item *a) :Item_int_func(a) {}
111
121
Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
112
Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
122
Item_bool_func(Session *session, Item_bool_func *item) :Item_int_func(session, item) {}
113
123
bool is_bool_func() { return 1; }
114
124
void fix_length_and_dec() { decimals=0; max_length=1; }
115
125
uint32_t decimal_precision() const { return 1; }
237
247
Item_bool_func(a, reinterpret_cast<Item *>(b)), cache(0),
238
248
save_cache(0), result_for_null_param(UNKNOWN)
239
249
{ with_subselect= true; }
240
bool fix_fields(THD *, Item **);
241
bool fix_left(THD *thd, Item **ref);
250
bool fix_fields(Session *, Item **);
251
bool fix_left(Session *session, Item **ref);
243
253
int64_t val_int();
248
258
Item *transform(Item_transformer transformer, unsigned char *arg);
254
Comp_creator() {} /* Remove gcc warning */
255
virtual ~Comp_creator() {} /* Remove gcc warning */
256
virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
257
virtual const char* symbol(bool invert) const = 0;
258
virtual bool eqne_op() const = 0;
259
virtual bool l_op() const = 0;
262
261
class Eq_creator :public Comp_creator
366
371
allowed_arg_cols= 0; // Fetch this value from first argument
368
Item *neg_transformer(THD *thd);
373
Item *neg_transformer(Session *session);
369
374
virtual Item *negated_item();
370
bool subst_argument_checker(unsigned char **arg __attribute__((unused)))
375
bool subst_argument_checker(unsigned char **)
388
393
trigcond<param>(arg) ::= param? arg : TRUE
390
The class Item_func_trig_cond is used for guarded predicates
395
The class Item_func_trig_cond is used for guarded predicates
391
396
which are employed only for internal purposes.
392
397
A guarded predicate is an object consisting of an a regular or
393
a guarded predicate P and a pointer to a boolean guard variable g.
398
a guarded predicate P and a pointer to a boolean guard variable g.
394
399
A guarded predicate P/g is evaluated to true if the value of the
395
400
guard g is false, otherwise it is evaluated to the same value that
396
401
the predicate P: val(P/g)= g ? val(P):true.
402
407
the objects consisting of three elements: a predicate P, a pointer
403
408
to a variable g and a firing value s with following evaluation
404
409
rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
405
one item for the objects of the form P/g1/g2...
410
one item for the objects of the form P/g1/g2...
407
412
Objects of this class are built only for query execution after
408
413
the execution plan has been already selected. That's why this
409
class needs only val_int out of generic methods.
414
class needs only val_int out of generic methods.
411
416
Current uses of Item_func_trig_cond objects:
412
417
- To wrap selection conditions when executing outer joins
413
418
- To wrap condition that is pushed down into subquery
580
585
inline void negate() { negated= !negated; }
581
586
inline void top_level_item() { pred_level= 1; }
582
Item *neg_transformer(THD *thd __attribute__((unused)))
587
Item *neg_transformer(Session *)
584
589
negated= !negated;
587
592
bool eq(const Item *item, bool binary_cmp) const;
588
bool subst_argument_checker(unsigned char **arg __attribute__((unused)))
593
bool subst_argument_checker(unsigned char **)
606
611
optimize_type select_optimize() const { return OPTIMIZE_KEY; }
607
612
enum Functype functype() const { return BETWEEN; }
608
613
const char *func_name() const { return "between"; }
609
bool fix_fields(THD *, Item **);
614
bool fix_fields(Session *, Item **);
610
615
void fix_length_and_dec();
611
616
virtual void print(String *str, enum_query_type query_type);
612
617
bool is_bool_func() { return 1; }
707
716
my_decimal *val_decimal(my_decimal *);
708
717
enum Item_result result_type () const { return cached_result_type; }
709
718
enum_field_types field_type() const { return cached_field_type; }
710
bool fix_fields(THD *, Item **);
719
bool fix_fields(Session *, Item **);
711
720
void fix_length_and_dec();
712
721
uint32_t decimal_precision() const;
713
722
const char *func_name() const { return "if"; }
756
765
uint32_t used_count;
758
in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func,
767
in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func,
759
768
const CHARSET_INFO * const cmp_coll)
760
769
:base((char*) sql_calloc(elements*element_length)),
761
770
size(element_length), compare(cmp_func), collation(cmp_coll),
787
796
item Constant item to store value into. The item must be of the same
788
797
type that create_item() returns.
790
virtual void value_to_item(uint32_t pos __attribute__((unused)),
791
Item *item __attribute__((unused))) { }
799
virtual void value_to_item(uint32_t, Item *) { }
793
801
/* Compare values number pos1 and pos2 for equality */
794
802
bool compare_elems(uint32_t pos1, uint32_t pos2)
808
816
void set(uint32_t pos,Item *item);
809
817
unsigned char *get_value(Item *item);
810
818
Item* create_item()
812
820
return new Item_string(collation);
814
822
void value_to_item(uint32_t pos, Item *item)
816
824
String *str=((String*) base)+pos;
817
825
Item_string *to= (Item_string*)item;
818
826
to->str_value= *str;
837
845
in_int64_t(uint32_t elements);
838
846
void set(uint32_t pos,Item *item);
839
847
unsigned char *get_value(Item *item);
841
849
Item* create_item()
844
We're created a signed INT, this may not be correct in
852
We're created a signed INT, this may not be correct in
845
853
general case (see BUG#19342).
847
855
return new Item_int((int64_t)0);
867
875
class in_datetime :public in_int64_t
871
879
/* An item used to issue warnings. */
873
881
/* Cache for the left item. */
874
882
Item *lval_cache;
876
884
in_datetime(Item *warn_item_arg, uint32_t elements)
877
:in_int64_t(elements), thd(current_thd), warn_item(warn_item_arg),
885
:in_int64_t(elements), session(current_session), warn_item(warn_item_arg),
878
886
lval_cache(0) {};
879
887
void set(uint32_t pos,Item *item);
880
888
unsigned char *get_value(Item *item);
939
947
virtual int compare(cmp_item *item)= 0;
940
948
static cmp_item* get_comparator(Item_result type, const CHARSET_INFO * const cs);
941
949
virtual cmp_item *make_same()= 0;
942
virtual void store_value_by_template(cmp_item *tmpl __attribute__((unused)),
950
virtual void store_value_by_template(cmp_item *, Item *item)
945
952
store_value(item);
949
class cmp_item_string :public cmp_item
956
class cmp_item_string :public cmp_item
952
959
String *value_res;
1026
1033
uint64_t value;
1029
1036
/* Item used for issuing warnings. */
1030
1037
Item *warn_item;
1031
1038
/* Cache for the left item. */
1032
1039
Item *lval_cache;
1034
1041
cmp_item_datetime(Item *warn_item_arg)
1035
:thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
1042
:session(current_session), warn_item(warn_item_arg), lval_cache(0) {}
1036
1043
void store_value(Item *item);
1037
1044
int cmp(Item *arg);
1038
1045
int compare(cmp_item *ci);
1111
1118
The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1112
1119
implementation.
1114
When there is no expression between CASE and the first WHEN
1121
When there is no expression between CASE and the first WHEN
1115
1122
(the CASE expression) then this function simple checks all WHEN expressions
1116
1123
one after another. When some WHEN expression evaluated to TRUE then the
1117
1124
value of the corresponding THEN expression is returned.
1159
1166
int64_t val_int();
1160
1167
String *val_str(String *);
1161
1168
my_decimal *val_decimal(my_decimal *);
1162
bool fix_fields(THD *thd, Item **ref);
1169
bool fix_fields(Session *session, Item **ref);
1163
1170
void fix_length_and_dec();
1164
1171
uint32_t decimal_precision() const;
1165
1172
table_map not_null_tables() const { return 0; }
1191
1198
class Item_func_in :public Item_func_opt_neg
1195
1202
an array of values when the right hand arguments of IN
1196
are all SQL constant and there are no nulls
1203
are all SQL constant and there are no nulls
1198
1205
in_vector *array;
1199
1206
bool have_null;
1201
1208
true when all arguments of the IN clause are of compatible types
1202
1209
and can be used safely as comparisons for key conditions
1353
1360
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1354
1361
table_map not_null_tables() const
1355
1362
{ return abort_on_null ? not_null_tables_cache : 0; }
1356
Item *neg_transformer(THD *thd);
1363
Item *neg_transformer(Session *session);
1357
1364
virtual void print(String *str, enum_query_type query_type);
1358
1365
const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1359
1366
void top_level_item() { abort_on_null=1; }
1378
1385
enum { alphabet_size = 256 };
1380
1387
Item *escape_item;
1382
1389
bool escape_used_in_parsing;
1387
1394
Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1388
:Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0),
1395
:Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0),
1389
1396
bmGs(0), bmBc(0), escape_item(escape_arg),
1390
1397
escape_used_in_parsing(escape_used) {}
1391
1398
int64_t val_int();
1417
1427
list.push_back(i1);
1418
1428
list.push_back(i2);
1420
Item_cond(THD *thd, Item_cond *item);
1430
Item_cond(Session *session, Item_cond *item);
1421
1431
Item_cond(List<Item> &nlist)
1422
1432
:Item_bool_func(), list(nlist), abort_on_null(0) {}
1423
1433
bool add(Item *item) { return list.push_back(item); }
1424
1434
bool add_at_head(Item *item) { return list.push_front(item); }
1425
1435
void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1426
bool fix_fields(THD *, Item **ref);
1427
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
1436
bool fix_fields(Session *, Item **ref);
1437
void fix_after_pullout(Select_Lex *new_parent, Item **ref);
1429
1439
enum Type type() const { return COND_ITEM; }
1430
1440
List<Item>* argument_list() { return &list; }
1431
1441
table_map used_tables() const;
1432
1442
void update_used_tables();
1433
1443
virtual void print(String *str, enum_query_type query_type);
1434
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
1435
friend int setup_conds(THD *thd, TableList *tables, TableList *leaves,
1444
void split_sum_func(Session *session, Item **ref_pointer_array, List<Item> &fields);
1445
friend int setup_conds(Session *session, TableList *tables, TableList *leaves,
1437
1447
void top_level_item() { abort_on_null=1; }
1438
void copy_andor_arguments(THD *thd, Item_cond *item);
1448
void copy_andor_arguments(Session *session, Item_cond *item);
1439
1449
bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1440
1450
Item *transform(Item_transformer transformer, unsigned char *arg);
1441
1451
void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1442
void neg_arguments(THD *thd);
1452
void neg_arguments(Session *session);
1443
1453
enum_field_types field_type() const { return DRIZZLE_TYPE_LONGLONG; }
1444
bool subst_argument_checker(unsigned char **arg __attribute__((unused)))
1454
bool subst_argument_checker(unsigned char **)
1445
1455
{ return true; }
1446
1456
Item *compile(Item_analyzer analyzer, unsigned char **arg_p,
1447
1457
Item_transformer transformer, unsigned char *arg_t);
1465
1475
A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1466
1476
substituted for the item representing the same multiple equality
1468
An item Item_equal(f1,f2) can appear instead of a conjunction of
1478
An item Item_equal(f1,f2) can appear instead of a conjunction of
1469
1479
f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1471
An item of the class Item_equal inherits equalities from outer
1481
An item of the class Item_equal inherits equalities from outer
1472
1482
conjunctive levels.
1474
1484
Suppose we have a where condition of the following form:
1479
1489
f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1481
1491
An object of the class Item_equal can contain an optional constant
1482
item c. Then it represents a multiple equality of the form
1492
item c. Then it represents a multiple equality of the form
1485
1495
Objects of the class Item_equal are used for the following:
1494
1504
It also can give us additional index scans and can allow us to
1495
1505
improve selectivity estimates.
1497
3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
1498
selected execution plan for the query: if table ti is accessed
1507
3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
1508
selected execution plan for the query: if table ti is accessed
1499
1509
before the table tj then in any predicate P in the where condition
1500
1510
the occurrence of tj.fj is substituted for ti.fi. This can allow
1501
1511
an evaluation of the predicate at an earlier step.
1503
When feature 1 is supported they say that join transitive closure
1513
When feature 1 is supported they say that join transitive closure
1505
1515
When feature 2 is supported they say that search argument transitive
1506
1516
closure is employed.
1509
1519
We do not just add predicates, we rather dynamically replace some
1510
1520
predicates that can not be used to access tables in the investigated
1511
1521
plan for those, obtained by substitution of some fields for equal fields,
1514
1524
Prepared Statements/Stored Procedures note: instances of class
1515
1525
Item_equal are created only at the time a PS/SP is executed and
1545
1555
void merge(Item_equal *item);
1546
1556
void update_const();
1547
1557
enum Functype functype() const { return MULT_EQUAL_FUNC; }
1549
1559
const char *func_name() const { return "multiple equal"; }
1550
1560
optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1551
1561
void sort(Item_field_cmpfunc cmp, void *arg);
1552
1562
friend class Item_equal_iterator;
1553
1563
void fix_length_and_dec();
1554
bool fix_fields(THD *thd, Item **ref);
1564
bool fix_fields(Session *session, Item **ref);
1555
1565
void update_used_tables();
1556
1566
bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1557
1567
Item *transform(Item_transformer transformer, unsigned char *arg);
1558
1568
virtual void print(String *str, enum_query_type query_type);
1559
const CHARSET_INFO *compare_collation()
1569
const CHARSET_INFO *compare_collation()
1560
1570
{ return fields.head()->collation.collation; }
1563
1573
class COND_EQUAL: public Sql_alloc
1566
1576
uint32_t max_members; /* max number of members the current level
1567
list and all lower level lists */
1577
list and all lower level lists */
1568
1578
COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
1569
List<Item_equal> current_level; /* list of multiple equalities of
1579
List<Item_equal> current_level; /* list of multiple equalities of
1570
1580
the current and level */
1573
1583
upper_levels= 0;
1578
1588
class Item_equal_iterator : public List_iterator_fast<Item_field>
1581
inline Item_equal_iterator(Item_equal &item_equal)
1591
inline Item_equal_iterator(Item_equal &item_equal)
1582
1592
:List_iterator_fast<Item_field> (item_equal.fields)
1584
1594
inline Item_field* operator++(int)
1586
1596
Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1589
inline void rewind(void)
1599
inline void rewind(void)
1591
1601
List_iterator_fast<Item_field>::rewind();
1595
1605
class Item_cond_and :public Item_cond
1598
COND_EQUAL cond_equal; /* contains list of Item_equal objects for
1608
COND_EQUAL cond_equal; /* contains list of Item_equal objects for
1599
1609
the current and level and reference
1600
to multiple equalities of upper and levels */
1610
to multiple equalities of upper and levels */
1601
1611
Item_cond_and() :Item_cond() {}
1602
1612
Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1603
Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
1613
Item_cond_and(Session *session, Item_cond_and *item) :Item_cond(session, item) {}
1604
1614
Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1605
1615
enum Functype functype() const { return COND_AND_FUNC; }
1606
1616
int64_t val_int();
1607
1617
const char *func_name() const { return "and"; }
1608
1618
table_map not_null_tables() const
1609
1619
{ return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1610
Item* copy_andor_structure(THD *thd)
1620
Item* copy_andor_structure(Session *session)
1612
1622
Item_cond_and *item;
1613
if ((item= new Item_cond_and(thd, this)))
1614
item->copy_andor_arguments(thd, this);
1623
if ((item= new Item_cond_and(session, this)))
1624
item->copy_andor_arguments(session, this);
1617
Item *neg_transformer(THD *thd);
1627
Item *neg_transformer(Session *session);
1620
1630
inline bool is_cond_and(Item *item)
1632
1642
Item_cond_or() :Item_cond() {}
1633
1643
Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1634
Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
1644
Item_cond_or(Session *session, Item_cond_or *item) :Item_cond(session, item) {}
1635
1645
Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1636
1646
enum Functype functype() const { return COND_OR_FUNC; }
1637
1647
int64_t val_int();
1638
1648
const char *func_name() const { return "or"; }
1639
1649
table_map not_null_tables() const { return and_tables_cache; }
1640
Item* copy_andor_structure(THD *thd)
1650
Item* copy_andor_structure(Session *session)
1642
1652
Item_cond_or *item;
1643
if ((item= new Item_cond_or(thd, this)))
1644
item->copy_andor_arguments(thd, this);
1653
if ((item= new Item_cond_or(session, this)))
1654
item->copy_andor_arguments(session, this);
1647
Item *neg_transformer(THD *thd);
1657
Item *neg_transformer(Session *session);
1650
1660
inline bool is_cond_or(Item *item)