21
21
This file defines all compare functions
26
#include <drizzled/cached_item.h>
27
#include <drizzled/check_stack_overrun.h>
28
#include <drizzled/current_session.h>
29
#include <drizzled/error.h>
30
#include <drizzled/internal/my_sys.h>
31
#include <drizzled/item/cache_int.h>
32
#include <drizzled/item/cmpfunc.h>
33
#include <drizzled/item/int_with_ref.h>
34
#include <drizzled/item/subselect.h>
35
#include <drizzled/session.h>
36
#include <drizzled/sql_select.h>
37
#include <drizzled/temporal.h>
38
#include <drizzled/time_functions.h>
25
#include "drizzled/sql_select.h"
26
#include "drizzled/error.h"
27
#include "drizzled/temporal.h"
28
#include "drizzled/item/cmpfunc.h"
29
#include "drizzled/cached_item.h"
30
#include "drizzled/item/cache_int.h"
31
#include "drizzled/item/int_with_ref.h"
32
#include "drizzled/check_stack_overrun.h"
33
#include "drizzled/time_functions.h"
34
#include "drizzled/internal/my_sys.h"
41
36
#include <algorithm>
543
540
if (field_item->field->can_be_compared_as_int64_t() &&
544
541
!(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
546
if (convert_constant_item(&getSession(), field_item, &args[1]))
543
if (convert_constant_item(session, field_item, &args[1]))
548
545
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
549
546
INT_RESULT); // Works for all types.
559
556
!(field_item->is_datetime() &&
560
557
args[0]->result_type() == STRING_RESULT))
562
if (convert_constant_item(&getSession(), field_item, &args[0]))
559
if (convert_constant_item(session, field_item, &args[0]))
564
561
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
565
562
INT_RESULT); // Works for all types.
575
Arg_comparator::Arg_comparator():
576
session(current_session),
581
Arg_comparator::Arg_comparator(Item **a1, Item **a2):
584
session(current_session),
589
573
int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
712
696
converted value. 0 on error and on zero-dates -- check 'failure'
716
get_date_from_str(Session *session, String *str, type::timestamp_t warn_type,
700
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
717
701
char *warn_name, bool *error_arg)
720
type::cut_t error= type::VALID;
721
705
type::Time l_time;
722
type::timestamp_t ret;
724
ret= l_time.store(str->ptr(), str->length(),
725
(TIME_FUZZY_DATE | MODE_INVALID_DATES | (session->variables.sql_mode & MODE_NO_ZERO_DATE)),
728
if (ret == type::DRIZZLE_TIMESTAMP_DATETIME || ret == type::DRIZZLE_TIMESTAMP_DATE)
706
enum enum_drizzle_timestamp_type ret;
708
ret= str_to_datetime(str->ptr(), str->length(), &l_time,
709
(TIME_FUZZY_DATE | MODE_INVALID_DATES |
710
(session->variables.sql_mode & MODE_NO_ZERO_DATE)),
713
if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
731
716
Do not return yet, we may still want to throw a "trailing garbage"
734
719
*error_arg= false;
735
l_time.convert(value);
720
value= TIME_to_uint64_t_datetime(&l_time);
739
724
*error_arg= true;
740
error= type::CUT; /* force warning */
725
error= 1; /* force warning */
743
if (error != type::VALID)
745
730
make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
746
731
str->ptr(), str->length(),
786
771
enum Arg_comparator::enum_date_cmp_type
787
772
Arg_comparator::can_compare_as_dates(Item *in_a, Item *in_b,
788
int64_t *const_value)
773
uint64_t *const_value)
790
775
enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
791
776
Item *str_arg= 0, *date_arg= 0;
880
865
Item **a1, Item **a2,
881
866
Item_result type)
883
enum_date_cmp_type cmp_type;
884
int64_t const_value= -1;
868
enum enum_date_cmp_type cmp_type;
869
uint64_t const_value= (uint64_t)-1;
888
873
if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
875
session= current_session;
890
876
owner= owner_arg;
891
877
a_type= (*a)->field_type();
892
878
b_type= (*b)->field_type();
896
if (const_value != -1)
882
if (const_value != (uint64_t)-1)
898
884
Item_cache_int *cache= new Item_cache_int();
899
885
/* Mark the cache as non-const to prevent re-caching. */
1011
995
enum_field_types f_type= warn_item->field_type();
1012
type::timestamp_t t_type= f_type == DRIZZLE_TYPE_DATE ? type::DRIZZLE_TIMESTAMP_DATE : type::DRIZZLE_TIMESTAMP_DATETIME;
996
enum enum_drizzle_timestamp_type t_type= f_type ==
997
DRIZZLE_TYPE_DATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
1013
998
value= get_date_from_str(session, str, t_type, warn_item->name, &error);
1015
1000
If str did not contain a valid date according to the current
1684
1668
change records at each execution.
1686
1670
if ((*args) != new_item)
1687
getSession().change_item_tree(args, new_item);
1671
current_session->change_item_tree(args, new_item);
1690
1674
Transform the right IN operand which should be an Item_in_subselect or a
1997
1981
if (Item_func_opt_neg::fix_fields(session, ref))
2000
session->getLex()->current_select->between_count++;
1984
session->lex->current_select->between_count++;
2002
1986
/* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
2003
1987
if (pred_level && !negated)
2064
2049
The following can't be recoded with || as convert_constant_item
2065
2050
changes the argument
2067
if (convert_constant_item(&getSession(), field_item, &args[1]))
2052
if (convert_constant_item(session, field_item, &args[1]))
2068
2053
cmp_type=INT_RESULT; // Works for all types.
2069
if (convert_constant_item(&getSession(), field_item, &args[2]))
2054
if (convert_constant_item(session, field_item, &args[2]))
2070
2055
cmp_type=INT_RESULT; // Works for all types.
3199
in_int64_t::in_int64_t(uint32_t elements) :
3200
in_vector(elements, sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
3184
in_int64_t::in_int64_t(uint32_t elements)
3185
:in_vector(elements,sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
3203
3188
void in_int64_t::set(uint32_t pos,Item *item)
3217
3202
return (unsigned char*) &tmp;
3220
in_datetime::in_datetime(Item *warn_item_arg, uint32_t elements) :
3221
in_int64_t(elements),
3222
session(current_session),
3223
warn_item(warn_item_arg),
3227
void in_datetime::set(uint32_t pos, Item *item)
3205
void in_datetime::set(uint32_t pos,Item *item)
3229
3207
Item **tmp_item= &item;
3721
3700
bool all_converted= true;
3722
3701
for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3724
if (!convert_constant_item (&getSession(), field_item, &arg[0]))
3703
if (!convert_constant_item (session, field_item, &arg[0]))
3725
3704
all_converted= false;
3727
3706
if (all_converted)
3887
3866
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
3889
List<Item>::iterator li(item->list.begin());
3868
List_iterator_fast<Item> li(item->list);
3890
3869
while (Item *it= li++)
3891
3870
list.push_back(it->copy_andor_structure(session));
3896
3875
Item_cond::fix_fields(Session *session, Item **)
3898
3877
assert(fixed == 0);
3899
List<Item>::iterator li(list.begin());
3878
List_iterator<Item> li(list);
3901
3880
void *orig_session_marker= session->session_marker;
3902
3881
unsigned char buff[sizeof(char*)]; // Max local vars in function
3936
3915
!((Item_cond*) item)->list.is_empty())
3937
3916
{ // Identical function
3938
3917
li.replace(((Item_cond*) item)->list);
3939
((Item_cond*) item)->list.clear();
3918
((Item_cond*) item)->list.empty();
3940
3919
item= *li.ref(); // new current item
3942
3921
if (abort_on_null)
4005
3984
bool Item_cond::walk(Item_processor processor, bool walk_subquery, unsigned char *arg)
4007
List<Item>::iterator li(list.begin());
3986
List_iterator_fast<Item> li(list);
4009
3988
while ((item= li++))
4010
3989
if (item->walk(processor, walk_subquery, arg))
4048
4027
change records at each execution.
4050
4029
if (new_item != item)
4051
getSession().change_item_tree(li.ref(), new_item);
4030
current_session->change_item_tree(li.ref(), new_item);
4053
4032
return Item_func::transform(transformer, arg);
4103
4082
void Item_cond::traverse_cond(Cond_traverser traverser,
4104
4083
void *arg, traverse_order order)
4106
List<Item>::iterator li(list.begin());
4085
List_iterator<Item> li(list);
4109
4088
switch (order) {
4144
4123
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
4145
4124
List<Item> &fields)
4147
List<Item>::iterator li(list.begin());
4126
List_iterator<Item> li(list);
4149
4128
while ((item= li++))
4150
4129
item->split_sum_func(session, ref_pointer_array,
4178
4157
void Item_cond::print(String *str, enum_query_type query_type)
4180
4159
str->append('(');
4181
List<Item>::iterator li(list.begin());
4160
List_iterator_fast<Item> li(list);
4183
4162
if ((item=li++))
4184
4163
item->print(str, query_type);
4489
4468
pattern = first + 1;
4490
4469
pattern_len = (int) len - 2;
4491
int *suff = (int*) session->getMemRoot()->allocate((int) (sizeof(int)*
4492
((pattern_len + 1)*2+
4470
int *suff = (int*) session->alloc((int) (sizeof(int)*
4471
((pattern_len + 1)*2+
4494
4473
bmGs = suff + pattern_len + 1;
4495
4474
bmBc = bmGs + pattern_len + 1;
4496
4475
turboBM_compute_good_suffix_shifts(suff);
4507
4486
Item_bool_func2::cleanup();
4510
static unsigned char likeconv(const CHARSET_INFO *cs, unsigned char a)
4512
4489
#ifdef LIKE_CMP_TOUPPER
4513
return cs->toupper(a);
4490
#define likeconv(cs,A) (unsigned char) (cs)->toupper(A)
4515
return cs->sort_order[a];
4492
#define likeconv(cs,A) (unsigned char) (cs)->sort_order[(unsigned char) (A)]
4520
4497
Precomputation dependent only on pattern_len.
5096
5073
bool Item_equal::fix_fields(Session *, Item **)
5098
List<Item_field>::iterator li(fields.begin());
5075
List_iterator_fast<Item_field> li(fields);
5100
5077
not_null_tables_cache= used_tables_cache= 0;
5101
5078
const_item_cache= false;
5116
5093
void Item_equal::update_used_tables()
5118
List<Item_field>::iterator li(fields.begin());
5095
List_iterator_fast<Item_field> li(fields);
5120
5097
not_null_tables_cache= used_tables_cache= 0;
5121
5098
if ((const_item_cache= cond_false))
5133
5110
Item_field *item_field;
5134
5111
if (cond_false)
5136
List<Item_field>::iterator it(fields.begin());
5113
List_iterator_fast<Item_field> it(fields);
5137
5114
Item *item= const_item ? const_item : it++;
5115
if ((null_value= item->null_value))
5138
5117
eval_item->store_value(item);
5139
if ((null_value= item->null_value))
5141
5118
while ((item_field= it++))
5143
5120
/* Skip fields of non-const tables. They haven't been read yet */
5144
5121
if (item_field->field->getTable()->const_table)
5146
if (eval_item->cmp(item_field) || (null_value= item_field->null_value))
5123
if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
5186
5163
change records at each execution.
5188
5165
if (new_item != item)
5189
getSession().change_item_tree((Item **) it.ref(), new_item);
5166
current_session->change_item_tree((Item **) it.ref(), new_item);
5191
5168
return Item_func::transform(transformer, arg);
5196
5173
str->append(func_name());
5197
5174
str->append('(');
5198
List<Item_field>::iterator it(fields.begin());
5175
List_iterator_fast<Item_field> it(fields);
5200
5177
if (const_item)
5201
5178
const_item->print(str, query_type);
5213
5190
str->append(')');
5216
cmp_item_datetime::cmp_item_datetime(Item *warn_item_arg) :
5217
session(current_session),
5218
warn_item(warn_item_arg),
5222
5193
} /* namespace drizzled */