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
22
23
/* compare and test functions */
24
#include <drizzled/common.h>
25
#include <drizzled/comp_creator.h>
26
#include <drizzled/function/math/int.h>
27
#include <drizzled/function/numhybrid.h>
28
#include <drizzled/item/decimal.h>
29
#include <drizzled/item/float.h>
30
#include <drizzled/item/function/boolean.h>
31
#include <drizzled/item/int.h>
32
#include <drizzled/item/row.h>
33
#include <drizzled/item/string.h>
34
#include <drizzled/item/sum.h>
35
#include <drizzled/qsort_cmp.h>
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"
39
41
extern Item_result item_cmp_type(Item_result a,Item_result b);
43
class Item_bool_func2;
45
class Item_sum_hybrid;
41
49
typedef int (Arg_comparator::*arg_cmp_func)();
43
51
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
68
76
DTCollation cmp_collation;
79
session(current_session),
72
Arg_comparator(Item **a1, Item **a2);
84
Arg_comparator(Item **a1, Item **a2):
87
session(current_session),
74
92
int set_compare_func(Item_bool_func2 *owner, Item_result type);
75
93
inline int set_compare_func(Item_bool_func2 *owner_arg)
131
149
virtual bool val_bool();
132
150
virtual int64_t val_int();
133
151
virtual void fix_length_and_dec();
134
virtual void print(String *str);
152
virtual void print(String *str, enum_query_type query_type);
137
155
Item_func_truth(Item *a, bool a_value, bool a_affirmative)
342
361
virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
343
362
bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
345
virtual inline void print(String *str)
364
virtual inline void print(String *str, enum_query_type query_type)
347
Item_func::print_op(str);
366
Item_func::print_op(str, query_type);
350
369
bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
351
370
bool is_bool_func() { return 1; }
352
const charset_info_st *compare_collation() { return cmp.cmp_collation.collation; }
371
const CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
353
372
uint32_t decimal_precision() const { return 1; }
354
373
void top_level_item() { abort_on_null= true; }
377
396
enum Functype functype() const { return NOT_FUNC; }
378
397
const char *func_name() const { return "not"; }
379
398
Item *neg_transformer(Session *session);
380
virtual void print(String *str);
399
virtual void print(String *str, enum_query_type query_type);
402
class Item_maxmin_subselect;
384
405
trigcond<param>(arg) ::= param? arg : TRUE
442
463
int64_t val_int();
443
464
enum Functype functype() const { return NOT_ALL_FUNC; }
444
465
const char *func_name() const { return "<not>"; }
445
virtual void print(String *str);
466
virtual void print(String *str, enum_query_type query_type);
446
467
void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
447
468
void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
448
469
bool empty_underlying_subquery();
604
625
const char *func_name() const { return "between"; }
605
626
bool fix_fields(Session *, Item **);
606
627
void fix_length_and_dec();
607
virtual void print(String *str);
628
virtual void print(String *str, enum_query_type query_type);
608
629
bool is_bool_func() { return 1; }
609
const charset_info_st *compare_collation() { return cmp_collation.collation; }
630
const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
610
631
uint32_t decimal_precision() const { return 1; }
619
640
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
620
641
const char *func_name() const { return "strcmp"; }
622
virtual inline void print(String *str)
643
virtual inline void print(String *str, enum_query_type query_type)
624
Item_func::print(str);
645
Item_func::print(str, query_type);
730
751
uint32_t decimal_precision() const { return args[0]->decimal_precision(); }
731
752
const char *func_name() const { return "nullif"; }
733
virtual inline void print(String *str)
754
virtual inline void print(String *str, enum_query_type query_type)
735
Item_func::print(str);
756
Item_func::print(str, query_type);
738
759
table_map not_null_tables() const { return 0; }
753
774
qsort2_cmp compare;
754
const charset_info_st *collation;
775
const CHARSET_INFO *collation;
756
777
uint32_t used_count;
758
779
in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func,
759
const charset_info_st * const cmp_coll)
780
const CHARSET_INFO * const cmp_coll)
760
781
:base((char*) memory::sql_calloc(elements*element_length)),
761
782
size(element_length), compare(cmp_func), collation(cmp_coll),
762
783
count(elements), used_count(elements) {}
799
820
char buff[STRING_BUFFER_USUAL_SIZE];
802
in_string(uint32_t elements,qsort2_cmp cmp_func, const charset_info_st * const cs);
823
in_string(uint32_t elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs);
804
825
void set(uint32_t pos,Item *item);
805
826
unsigned char *get_value(Item *item);
869
890
/* Cache for the left item. */
870
891
Item *lval_cache;
872
in_datetime(Item *warn_item_arg, uint32_t elements);
893
in_datetime(Item *warn_item_arg, uint32_t elements)
894
:in_int64_t(elements), session(current_session), warn_item(warn_item_arg),
874
896
void set(uint32_t pos,Item *item);
875
897
unsigned char *get_value(Item *item);
876
898
friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
937
959
virtual int cmp(Item *item)= 0;
938
960
// for optimized IN with row
939
961
virtual int compare(cmp_item *item)= 0;
940
static cmp_item* get_comparator(Item_result type, const charset_info_st * const cs);
962
static cmp_item* get_comparator(Item_result type, const CHARSET_INFO * const cs);
941
963
virtual cmp_item *make_same()= 0;
942
964
virtual void store_value_by_template(cmp_item *, Item *item)
951
973
String *value_res;
953
975
cmp_item_string () {}
954
cmp_item_string (const charset_info_st * const cs) { cmp_charset= cs; }
955
void set_charset(const charset_info_st * const cs) { cmp_charset= cs; }
976
cmp_item_string (const CHARSET_INFO * const cs) { cmp_charset= cs; }
977
void set_charset(const CHARSET_INFO * const cs) { cmp_charset= cs; }
956
978
friend class cmp_item_sort_string;
957
979
friend class cmp_item_sort_string_in_static;
966
988
cmp_item_sort_string():
967
989
cmp_item_string() {}
968
cmp_item_sort_string(const charset_info_st * const cs):
990
cmp_item_sort_string(const CHARSET_INFO * const cs):
969
991
cmp_item_string(cs),
970
992
value(value_buff, sizeof(value_buff), cs) {}
971
993
void store_value(Item *item)
986
1008
return sortcmp(value_res, l_cmp->value_res, cmp_charset);
988
1010
cmp_item *make_same();
989
void set_charset(const charset_info_st * const cs)
1011
void set_charset(const CHARSET_INFO * const cs)
991
1013
cmp_charset= cs;
992
1014
value.set_quick(value_buff, sizeof(value_buff), cs);
1031
1053
/* Cache for the left item. */
1032
1054
Item *lval_cache;
1034
cmp_item_datetime(Item *warn_item_arg);
1056
cmp_item_datetime(Item *warn_item_arg)
1057
:session(current_session), warn_item(warn_item_arg), lval_cache(0) {}
1036
1058
void store_value(Item *item);
1037
1059
int cmp(Item *arg);
1038
1060
int compare(cmp_item *ci);
1141
1163
:Item_func(), first_expr_num(-1), else_expr_num(-1),
1142
1164
cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
1144
ncases= list.size();
1166
ncases= list.elements;
1145
1167
if (first_expr_arg)
1147
first_expr_num= list.size();
1169
first_expr_num= list.elements;
1148
1170
list.push_back(first_expr_arg);
1150
1172
if (else_expr_arg)
1152
else_expr_num= list.size();
1174
else_expr_num= list.elements;
1153
1175
list.push_back(else_expr_arg);
1155
1177
set_arguments(list);
1166
1188
enum Item_result result_type () const { return cached_result_type; }
1167
1189
enum_field_types field_type() const { return cached_field_type; }
1168
1190
const char *func_name() const { return "case"; }
1169
virtual void print(String *str);
1191
virtual void print(String *str, enum_query_type query_type);
1170
1192
Item *find_item(String *str);
1171
const charset_info_st *compare_collation() { return cmp_collation.collation; }
1193
const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1172
1194
void cleanup();
1173
1195
void agg_str_lengths(Item *arg);
1174
1196
void agg_num_lengths(Item *arg);
1232
1254
optimize_type select_optimize() const
1233
1255
{ return OPTIMIZE_KEY; }
1234
virtual void print(String *str);
1256
virtual void print(String *str, enum_query_type query_type);
1235
1257
enum Functype functype() const { return IN_FUNC; }
1236
1258
const char *func_name() const { return " IN "; }
1237
1259
bool nulls_in_row();
1238
1260
bool is_bool_func() { return 1; }
1239
const charset_info_st *compare_collation() { return cmp_collation.collation; }
1261
const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1242
1264
class cmp_item_row :public cmp_item
1307
1329
table_map not_null_tables() const { return 0; }
1308
1330
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1309
1331
Item *neg_transformer(Session *session);
1310
const charset_info_st *compare_collation() { return args[0]->collation.collation; }
1332
const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1313
1335
/* Functions used by HAVING for rewriting IN subquery */
1337
class Item_in_subselect;
1316
1340
This is like IS NOT NULL but it also remembers if it ever has
1317
1341
encountered a NULL.
1351
1375
table_map not_null_tables() const
1352
1376
{ return abort_on_null ? not_null_tables_cache : 0; }
1353
1377
Item *neg_transformer(Session *session);
1354
virtual void print(String *str);
1355
const charset_info_st *compare_collation() { return args[0]->collation.collation; }
1378
virtual void print(String *str, enum_query_type query_type);
1379
const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1356
1380
void top_level_item() { abort_on_null=1; }
1420
1446
Item_cond(Session *session, Item_cond *item);
1421
1447
Item_cond(List<Item> &nlist)
1422
1448
:item::function::Boolean(), list(nlist), abort_on_null(0) {}
1423
void add(Item *item) { list.push_back(item); }
1424
void add_at_head(Item *item) { list.push_front(item); }
1449
bool add(Item *item) { return list.push_back(item); }
1450
bool add_at_head(Item *item) { return list.push_front(item); }
1425
1451
void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1426
1452
bool fix_fields(Session *, Item **ref);
1427
1453
void fix_after_pullout(Select_Lex *new_parent, Item **ref);
1430
1456
List<Item>* argument_list() { return &list; }
1431
1457
table_map used_tables() const;
1432
1458
void update_used_tables();
1433
virtual void print(String *str);
1459
virtual void print(String *str, enum_query_type query_type);
1434
1460
void split_sum_func(Session *session, Item **ref_pointer_array, List<Item> &fields);
1435
1461
friend int setup_conds(Session *session, TableList *tables, TableList *leaves,
1526
1552
class Item_equal: public item::function::Boolean
1554
List<Item_field> fields; /* list of equal field items */
1555
Item *const_item; /* optional constant item equal to fields items */
1556
cmp_item *eval_item;
1529
typedef List<Item_field> fields_t;
1560
inline Item_equal() :
1561
item::function::Boolean(),
1536
1566
const_item_cache=0;
1539
fields_t::iterator begin()
1541
return fields.begin();
1544
1569
Item_equal(Item_field *f1, Item_field *f2);
1545
1570
Item_equal(Item *c, Item_field *f);
1546
1571
Item_equal(Item_equal *item_equal);
1549
1574
void add(Item_field *f);
1550
1575
uint32_t members();
1551
1576
bool contains(Field *field);
1552
Item_field* get_first() { return &fields.front(); }
1577
Item_field* get_first() { return fields.head(); }
1553
1578
void merge(Item_equal *item);
1554
1579
void update_const();
1555
1580
enum Functype functype() const { return MULT_EQUAL_FUNC; }
1557
1582
const char *func_name() const { return "multiple equal"; }
1558
1583
optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1559
1584
void sort(Item_field_cmpfunc cmp, void *arg);
1585
friend class Item_equal_iterator;
1560
1586
void fix_length_and_dec();
1561
1587
bool fix_fields(Session *session, Item **ref);
1562
1588
void update_used_tables();
1563
1589
bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1564
1590
Item *transform(Item_transformer transformer, unsigned char *arg);
1565
virtual void print(String *str);
1566
const charset_info_st *compare_collation()
1567
{ return fields.front().collation.collation; }
1569
fields_t fields; /* list of equal field items */
1570
Item *const_item; /* optional constant item equal to fields items */
1571
cmp_item *eval_item;
1591
virtual void print(String *str, enum_query_type query_type);
1592
const CHARSET_INFO *compare_collation()
1593
{ return fields.head()->collation.collation; }
1576
1596
class COND_EQUAL: public memory::SqlAlloc
1590
typedef List<Item_field>::iterator Item_equal_iterator;
1611
class Item_equal_iterator : public List_iterator_fast<Item_field>
1614
inline Item_equal_iterator(Item_equal &item_equal)
1615
:List_iterator_fast<Item_field> (item_equal.fields)
1617
inline Item_field* operator++(int)
1619
Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1622
inline void rewind(void)
1624
List_iterator_fast<Item_field>::rewind();
1592
1628
class Item_cond_and :public Item_cond