21
21
This file defines all compare functions
24
#include <drizzled/server_includes.h>
25
#include <drizzled/sql_select.h>
27
static bool convert_constant_item(THD *, Item_field *, Item **);
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"
38
using namespace drizzled;
41
extern const double log_10[309];
43
static Eq_creator eq_creator;
44
static Ne_creator ne_creator;
45
static Gt_creator gt_creator;
46
static Lt_creator lt_creator;
47
static Ge_creator ge_creator;
48
static Le_creator le_creator;
50
static bool convert_constant_item(Session *, Item_field *, Item **);
29
52
static Item_result item_store_type(Item_result a, Item *item,
30
53
bool unsigned_flag)
194
218
Bitmap of collected types - otherwise
197
static uint collect_cmp_types(Item **items, uint nitems)
221
static uint32_t collect_cmp_types(Item **items, uint32_t nitems, bool skip_nulls= false)
224
uint32_t found_types;
201
225
Item_result left_result= items[0]->result_type();
202
226
assert(nitems > 1);
204
228
for (i= 1; i < nitems ; i++)
206
if ((left_result == ROW_RESULT ||
230
if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
231
continue; // Skip NULL constant items
232
if ((left_result == ROW_RESULT ||
207
233
items[i]->result_type() == ROW_RESULT) &&
208
234
cmp_row_type(items[0], items[i]))
210
found_types|= 1<< (uint)item_cmp_type(left_result,
236
found_types|= 1<< (uint32_t)item_cmp_type(left_result,
211
237
items[i]->result_type());
240
Even if all right-hand items are NULLs and we are skipping them all, we need
241
at least one type bit in the found_type bitmask.
243
if (skip_nulls && !found_types)
244
found_types= 1 << (uint)left_result;
213
245
return found_types;
216
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2,
219
my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
220
c1.collation->name,c1.derivation_name(),
221
c2.collation->name,c2.derivation_name(),
226
249
Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
255
const Eq_creator* Eq_creator::instance()
232
261
Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
234
263
return new Item_func_ne(a, b);
267
const Ne_creator* Ne_creator::instance()
238
273
Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
240
275
return new Item_func_gt(a, b);
279
const Gt_creator* Gt_creator::instance()
244
285
Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
246
287
return new Item_func_lt(a, b);
291
const Lt_creator* Lt_creator::instance()
250
297
Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
252
299
return new Item_func_ge(a, b);
303
const Ge_creator* Ge_creator::instance()
256
309
Item_bool_func2* Le_creator::create(Item *a, Item *b) const
258
311
return new Item_func_le(a, b);
314
const Le_creator* Le_creator::instance()
263
322
Most of these returns 0LL if false and 1LL if true and
378
437
1 Item was replaced with an integer version of the item
381
static bool convert_constant_item(THD *thd, Item_field *field_item,
440
static bool convert_constant_item(Session *session, Item_field *field_item,
384
443
Field *field= field_item->field;
446
field->setWriteSet();
387
448
if (!(*item)->with_subselect && (*item)->const_item())
389
TABLE *table= field->table;
390
ulong orig_sql_mode= thd->variables.sql_mode;
391
enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
392
my_bitmap_map *old_write_map;
393
my_bitmap_map *old_read_map;
450
ulong orig_sql_mode= session->variables.sql_mode;
451
enum_check_fields orig_count_cuted_fields= session->count_cuted_fields;
394
452
uint64_t orig_field_val= 0; /* original field value if valid */
398
old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
399
old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
401
454
/* For comparison purposes allow invalid dates like 2000-01-32 */
402
thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
455
session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
403
456
MODE_INVALID_DATES;
404
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
457
session->count_cuted_fields= CHECK_FIELD_IGNORE;
407
460
Store the value of the field if it references an outer field because
448
496
if (!args[0] || !args[1])
452
500
We allow to convert to Unicode character sets in some cases.
453
501
The conditions when conversion is possible are:
454
502
- arguments A and B have different charsets
455
503
- A wins according to coercibility rules
456
504
- character set of A is superset for character set of B
458
506
If all of the above is true, then it's possible to convert
459
507
B into the character set of A, and then compare according
460
508
to the collation of A.
464
512
DTCollation coll;
465
513
if (args[0]->result_type() == STRING_RESULT &&
466
514
args[1]->result_type() == STRING_RESULT &&
467
515
agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
470
518
args[0]->cmp_context= args[1]->cmp_context=
471
519
item_cmp_type(args[0]->result_type(), args[1]->result_type());
472
520
// Make a special case of compare with fields to get nicer DATE comparisons
528
session= current_session;
529
Item_field *field_item= NULL;
482
531
if (args[0]->real_item()->type() == FIELD_ITEM)
484
Item_field *field_item= (Item_field*) (args[0]->real_item());
533
field_item= static_cast<Item_field*>(args[0]->real_item());
485
534
if (field_item->field->can_be_compared_as_int64_t() &&
486
535
!(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
488
if (convert_constant_item(thd, field_item, &args[1]))
537
if (convert_constant_item(session, field_item, &args[1]))
490
539
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
491
540
INT_RESULT); // Works for all types.
497
546
if (args[1]->real_item()->type() == FIELD_ITEM)
499
Item_field *field_item= (Item_field*) (args[1]->real_item());
548
field_item= static_cast<Item_field*>(args[1]->real_item());
500
549
if (field_item->field->can_be_compared_as_int64_t() &&
501
550
!(field_item->is_datetime() &&
502
551
args[0]->result_type() == STRING_RESULT))
504
if (convert_constant_item(thd, field_item, &args[0]))
553
if (convert_constant_item(session, field_item, &args[0]))
506
555
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
507
556
INT_RESULT); // Works for all types.
644
get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
693
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
645
694
char *warn_name, bool *error_arg)
647
696
uint64_t value= 0;
649
698
DRIZZLE_TIME l_time;
650
enum_drizzle_timestamp_type ret;
699
enum enum_drizzle_timestamp_type ret;
652
701
ret= str_to_datetime(str->ptr(), str->length(), &l_time,
653
702
(TIME_FUZZY_DATE | MODE_INVALID_DATES |
654
(thd->variables.sql_mode &
655
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))),
703
(session->variables.sql_mode & MODE_NO_ZERO_DATE)),
658
706
if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
696
744
int result and the other item (b or a) is an item with string result.
697
745
If the second item is a constant one then it's checked to be
698
746
convertible to the DATE/DATETIME type. If the constant can't be
699
converted to a DATE/DATETIME then the compare_datetime() comparator
700
isn't used and the warning about wrong DATE/DATETIME value is issued.
747
converted to a DATE/DATETIME then an error is issued back to the Session.
701
748
In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
702
749
the comparison is handled by other comparators.
703
751
If the datetime comparator can be used and one the operands of the
704
752
comparison is a string constant that was successfully converted to a
705
753
DATE/DATETIME type then the result of the conversion is returned in the
748
796
(str_arg->type() != Item::FUNC_ITEM ||
749
797
((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
751
THD *thd= current_thd;
800
* OK, we are here if we've got a date field (or something which can be
801
* compared as a date field) on one side of the equation, and a constant
802
* string on the other side. In this case, we must verify that the constant
803
* string expression can indeed be evaluated as a datetime. If it cannot,
804
* we throw an error here and stop processsing. Bad data should ALWAYS
805
* produce an error, and no implicit conversion or truncation should take place.
807
* If the conversion to a DateTime temporal is successful, then we convert
808
* the Temporal instance to a uint64_t for the comparison operator, which
809
* compares date(times) using int64_t semantics.
813
* Does a uint64_t conversion really have to happen here? Fields return int64_t
814
* from val_int(), not uint64_t...
754
String tmp, *str_val= 0;
755
timestamp_type t_type= (date_arg->field_type() == DRIZZLE_TYPE_NEWDATE ?
756
DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
819
/* DateTime used to pick up as many string conversion possibilities as possible. */
820
drizzled::DateTime temporal;
758
822
str_val= str_arg->val_str(&tmp);
759
if (str_arg->null_value)
760
return CMP_DATE_DFLT;
761
value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
763
return CMP_DATE_DFLT;
826
* If we are here, it is most likely due to the comparison item
827
* being a NULL. Although this is incorrect (SQL demands that the term IS NULL
828
* be used, not = NULL since no item can be equal to NULL).
830
* So, return gracefully.
832
return CMP_DATE_DFLT;
834
if (! temporal.from_string(str_val->c_ptr(), str_val->length()))
836
/* Chuck an error. Bad datetime input. */
837
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
838
return CMP_DATE_DFLT; /* :( What else can I return... */
841
/* String conversion was good. Convert to an integer for comparison purposes. */
843
temporal.to_int64_t(&int_value);
844
value= (uint64_t) int_value;
765
847
*const_value= value;
773
Retrieves correct TIME value from the given item.
778
item_arg [in/out] item to retrieve TIME value from
779
cache_arg [in/out] pointer to place to store the cache item to
780
warn_item [in] unused
781
is_null [out] true <=> the item_arg is null
784
Retrieves the correct TIME value from given item for comparison by the
785
compare_datetime() function.
786
If item's result can be compared as int64_t then its int value is used
787
and a value returned by get_time function is used otherwise.
788
If an item is a constant one then its value is cached and it isn't
789
get parsed again. An Item_cache_int object is used for for cached values.
790
It seamlessly substitutes the original item. The cache item is marked as
791
non-constant to prevent re-caching it again.
798
get_time_value(THD *thd __attribute__((unused)),
799
Item ***item_arg, Item **cache_arg,
800
Item *warn_item __attribute__((unused)),
804
Item *item= **item_arg;
807
if (item->result_as_int64_t())
809
value= item->val_int();
810
*is_null= item->null_value;
814
*is_null= item->get_time(<ime);
815
value= !*is_null ? TIME_to_uint64_t_datetime(<ime) : 0;
818
Do not cache GET_USER_VAR() function as its const_item() may return true
819
for the current thread but it still may change during the execution.
821
if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
822
((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
824
Item_cache_int *cache= new Item_cache_int();
825
/* Mark the cache as non-const to prevent re-caching. */
826
cache->set_used_tables(1);
827
cache->store(item, value);
829
*item_arg= cache_arg;
835
854
int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
836
855
Item **a1, Item **a2,
837
856
Item_result type)
979
985
enum_field_types f_type= warn_item->field_type();
980
timestamp_type t_type= f_type ==
981
DRIZZLE_TYPE_NEWDATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
982
value= get_date_from_str(thd, str, t_type, warn_item->name, &error);
986
enum enum_drizzle_timestamp_type t_type= f_type ==
987
DRIZZLE_TYPE_DATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
988
value= get_date_from_str(session, str, t_type, warn_item->name, &error);
984
990
If str did not contain a valid date according to the current
985
991
SQL_MODE, get_date_from_str() has already thrown a warning,
2217
uint Item_func_ifnull::decimal_precision() const
2215
uint32_t Item_func_ifnull::decimal_precision() const
2219
int max_int_part=max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2217
int max_int_part= max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2220
2218
return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2224
enum_field_types Item_func_ifnull::field_type() const
2222
enum_field_types Item_func_ifnull::field_type() const
2226
2224
return cached_field_type;
2229
Field *Item_func_ifnull::tmp_table_field(TABLE *table)
2227
Field *Item_func_ifnull::tmp_table_field(Table *table)
2231
2229
return tmp_table_field_from_field_type(table, 0);
2345
2343
Item_func_if::fix_length_and_dec()
2347
maybe_null=args[1]->maybe_null || args[2]->maybe_null;
2345
maybe_null= args[1]->maybe_null || args[2]->maybe_null;
2348
2346
decimals= max(args[1]->decimals, args[2]->decimals);
2349
unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
2347
unsigned_flag= args[1]->unsigned_flag && args[2]->unsigned_flag;
2351
enum Item_result arg1_type=args[1]->result_type();
2352
enum Item_result arg2_type=args[2]->result_type();
2353
bool null1=args[1]->const_item() && args[1]->null_value;
2354
bool null2=args[2]->const_item() && args[2]->null_value;
2349
enum Item_result arg1_type= args[1]->result_type();
2350
enum Item_result arg2_type= args[2]->result_type();
2351
bool null1= args[1]->const_item() && args[1]->null_value;
2352
bool null2= args[2]->const_item() && args[2]->null_value;
2389
2387
int len2= args[2]->max_length - args[2]->decimals
2390
2388
- (args[2]->unsigned_flag ? 0 : 1);
2392
max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
2390
max_length= max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
2395
2393
max_length= max(args[1]->max_length, args[2]->max_length);
2399
uint Item_func_if::decimal_precision() const
2397
uint32_t Item_func_if::decimal_precision() const
2401
int precision=(max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
2399
int precision= (max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
2403
2401
return min(precision, DECIMAL_MAX_PRECISION);
2585
2583
/* Compare every WHEN argument with it and return the first match */
2586
for (uint i=0 ; i < ncases ; i+=2)
2584
for (uint32_t i=0 ; i < ncases ; i+=2)
2588
2586
cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
2589
2587
assert(cmp_type != ROW_RESULT);
2590
assert(cmp_items[(uint)cmp_type]);
2591
if (!(value_added_map & (1<<(uint)cmp_type)))
2588
assert(cmp_items[(uint32_t)cmp_type]);
2589
if (!(value_added_map & (1<<(uint32_t)cmp_type)))
2593
cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
2591
cmp_items[(uint32_t)cmp_type]->store_value(args[first_expr_num]);
2594
2592
if ((null_value=args[first_expr_num]->null_value))
2595
2593
return else_expr_num != -1 ? args[else_expr_num] : 0;
2596
value_added_map|= 1<<(uint)cmp_type;
2594
value_added_map|= 1<<(uint32_t)cmp_type;
2598
if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2596
if (!cmp_items[(uint32_t)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2599
2597
return args[i + 1];
2682
bool Item_func_case::fix_fields(THD *thd, Item **ref)
2680
bool Item_func_case::fix_fields(Session *session, Item **ref)
2685
2683
buff should match stack usage from
2686
2684
Item_func_case::val_int() -> Item_func_case::find_item()
2688
uchar buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(int64_t)*2];
2689
bool res= Item_func::fix_fields(thd, ref);
2686
unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2
2687
+sizeof(double)*2+sizeof(int64_t)*2];
2688
bool res= Item_func::fix_fields(session, ref);
2691
2690
Call check_stack_overrun after fix_fields to be sure that stack variable
2692
2691
is not optimized away
2694
if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
2693
if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
2695
2694
return true; // Fatal error flag is set!
2708
2707
void Item_func_case::agg_num_lengths(Item *arg)
2710
uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2709
uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2711
2710
arg->unsigned_flag) - arg->decimals;
2712
set_if_bigger(max_length, len);
2711
set_if_bigger(max_length, len);
2713
2712
set_if_bigger(decimals, arg->decimals);
2714
unsigned_flag= unsigned_flag && arg->unsigned_flag;
2713
unsigned_flag= unsigned_flag && arg->unsigned_flag;
2718
2717
void Item_func_case::fix_length_and_dec()
2722
uint found_types= 0;
2723
if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2721
uint32_t found_types= 0;
2722
if (!(agg= (Item**) memory::sql_alloc(sizeof(Item*)*(ncases+1))))
2727
2726
Aggregate all THEN and ELSE expression types
2728
2727
and collations when string result
2731
2730
for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2732
2731
agg[nagg]= args[nagg*2+1];
2734
2733
if (else_expr_num != -1)
2735
2734
agg[nagg++]= args[else_expr_num];
2737
2736
agg_result_type(&cached_result_type, agg, nagg);
2738
2737
if ((cached_result_type == STRING_RESULT) &&
2739
2738
agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2742
2741
cached_field_type= agg_field_type(agg, nagg);
2744
2743
Aggregate first expression and all THEN expression types
3016
3015
0 left argument is equal to the right argument.
3017
3016
1 left argument is greater than the right argument.
3019
int cmp_int64_t(void *cmp_arg __attribute__((unused)),
3020
in_int64_t::packed_int64_t *a,
3021
in_int64_t::packed_int64_t *b)
3018
int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
3019
in_int64_t::packed_int64_t *b)
3023
3021
if (a->unsigned_flag != b->unsigned_flag)
3026
One of the args is unsigned and is too big to fit into the
3024
One of the args is unsigned and is too big to fit into the
3027
3025
positive signed range. Report no match.
3029
3027
if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3030
3028
(b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
3031
3029
return a->unsigned_flag ? 1 : -1;
3033
Although the signedness differs both args can fit into the signed
3031
Although the signedness differs both args can fit into the signed
3034
3032
positive range. Make them signed and compare as usual.
3036
3034
return cmp_longs (a->val, b->val);
3038
3036
if (a->unsigned_flag)
3041
3039
return cmp_longs (a->val, b->val);
3044
static int cmp_double(void *cmp_arg __attribute__((unused)), double *a,double *b)
3042
static int cmp_double(void *, double *a, double *b)
3046
3044
return *a < *b ? -1 : *a == *b ? 0 : 1;
3049
static int cmp_row(void *cmp_arg __attribute__((unused)), cmp_item_row *a, cmp_item_row *b)
3047
static int cmp_row(void *, cmp_item_row *a, cmp_item_row *b)
3051
3049
return a->compare(b);
3055
static int cmp_decimal(void *cmp_arg __attribute__((unused)), my_decimal *a, my_decimal *b)
3053
static int cmp_decimal(void *, my_decimal *a, my_decimal *b)
3058
3056
We need call of fixing buffer pointer, because fast sort just copy
3148
3152
delete [] (cmp_item_row*) base;
3151
uchar *in_row::get_value(Item *item)
3155
unsigned char *in_row::get_value(Item *item)
3153
3157
tmp.store_value(item);
3154
3158
if (item->is_null())
3156
return (uchar *)&tmp;
3160
return (unsigned char *)&tmp;
3159
void in_row::set(uint pos, Item *item)
3163
void in_row::set(uint32_t pos, Item *item)
3161
3165
((cmp_item_row*) base)[pos].store_value_by_template(&tmp, item);
3165
in_int64_t::in_int64_t(uint elements)
3169
in_int64_t::in_int64_t(uint32_t elements)
3166
3170
:in_vector(elements,sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
3169
void in_int64_t::set(uint pos,Item *item)
3173
void in_int64_t::set(uint32_t pos,Item *item)
3171
3175
struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3173
3177
buff->val= item->val_int();
3174
3178
buff->unsigned_flag= item->unsigned_flag;
3177
uchar *in_int64_t::get_value(Item *item)
3181
unsigned char *in_int64_t::get_value(Item *item)
3179
3183
tmp.val= item->val_int();
3180
3184
if (item->null_value)
3182
3186
tmp.unsigned_flag= item->unsigned_flag;
3183
return (uchar*) &tmp;
3187
return (unsigned char*) &tmp;
3186
void in_datetime::set(uint pos,Item *item)
3190
void in_datetime::set(uint32_t pos,Item *item)
3188
3192
Item **tmp_item= &item;
3190
3194
struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3192
buff->val= get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3196
buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3193
3197
buff->unsigned_flag= 1L;
3196
uchar *in_datetime::get_value(Item *item)
3200
unsigned char *in_datetime::get_value(Item *item)
3199
3203
Item **tmp_item= lval_cache ? &lval_cache : &item;
3200
tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
3204
tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3201
3205
if (item->null_value)
3203
3207
tmp.unsigned_flag= 1L;
3204
return (uchar*) &tmp;
3208
return (unsigned char*) &tmp;
3207
in_double::in_double(uint elements)
3211
in_double::in_double(uint32_t elements)
3208
3212
:in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
3211
void in_double::set(uint pos,Item *item)
3215
void in_double::set(uint32_t pos,Item *item)
3213
3217
((double*) base)[pos]= item->val_real();
3216
uchar *in_double::get_value(Item *item)
3220
unsigned char *in_double::get_value(Item *item)
3218
3222
tmp= item->val_real();
3219
3223
if (item->null_value)
3220
return 0; /* purecov: inspected */
3221
return (uchar*) &tmp;
3225
return (unsigned char*) &tmp;
3225
in_decimal::in_decimal(uint elements)
3229
in_decimal::in_decimal(uint32_t elements)
3226
3230
:in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0)
3230
void in_decimal::set(uint pos, Item *item)
3234
void in_decimal::set(uint32_t pos, Item *item)
3232
3236
/* as far as 'item' is constant, we can store reference on my_decimal */
3233
3237
my_decimal *dec= ((my_decimal *)base) + pos;
3234
3238
dec->len= DECIMAL_BUFF_LENGTH;
3235
3239
dec->fix_buffer_pointer();
3236
3240
my_decimal *res= item->val_decimal(dec);
3237
/* if item->val_decimal() is evaluated to NULL then res == 0 */
3241
/* if item->val_decimal() is evaluated to NULL then res == 0 */
3238
3242
if (!item->null_value && res != dec)
3239
3243
my_decimal2decimal(res, dec);
3243
uchar *in_decimal::get_value(Item *item)
3247
unsigned char *in_decimal::get_value(Item *item)
3245
3249
my_decimal *result= item->val_decimal(&val);
3246
3250
if (item->null_value)
3248
return (uchar *)result;
3252
return (unsigned char *)result;
3802
3808
return (int64_t) (!null_value && tmp != negated);
3805
for (uint i= 1 ; i < arg_count ; i++)
3811
for (uint32_t i= 1 ; i < arg_count ; i++)
3807
3813
Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
3808
in_item= cmp_items[(uint)cmp_type];
3814
in_item= cmp_items[(uint32_t)cmp_type];
3809
3815
assert(in_item);
3810
if (!(value_added_map & (1 << (uint)cmp_type)))
3816
if (!(value_added_map & (1 << (uint32_t)cmp_type)))
3812
3818
in_item->store_value(args[0]);
3813
3819
if ((null_value=args[0]->null_value))
3816
value_added_map|= 1 << (uint)cmp_type;
3822
value_added_map|= 1 << (uint32_t)cmp_type;
3818
3824
if (!in_item->cmp(args[i]) && !args[i]->null_value)
3819
3825
return (int64_t) (!negated);
3828
int64_t Item_func_bit_or::val_int()
3831
uint64_t arg1= (uint64_t) args[0]->val_int();
3832
if (args[0]->null_value)
3834
null_value=1; /* purecov: inspected */
3835
return 0; /* purecov: inspected */
3837
uint64_t arg2= (uint64_t) args[1]->val_int();
3838
if (args[1]->null_value)
3844
return (int64_t) (arg1 | arg2);
3848
int64_t Item_func_bit_and::val_int()
3851
uint64_t arg1= (uint64_t) args[0]->val_int();
3852
if (args[0]->null_value)
3854
null_value=1; /* purecov: inspected */
3855
return 0; /* purecov: inspected */
3857
uint64_t arg2= (uint64_t) args[1]->val_int();
3858
if (args[1]->null_value)
3860
null_value=1; /* purecov: inspected */
3861
return 0; /* purecov: inspected */
3864
return (int64_t) (arg1 & arg2);
3867
Item_cond::Item_cond(THD *thd, Item_cond *item)
3868
:Item_bool_func(thd, item),
3834
Item_cond::Item_cond(Session *session, Item_cond *item)
3835
:Item_bool_func(session, item),
3869
3836
abort_on_null(item->abort_on_null),
3870
3837
and_tables_cache(item->and_tables_cache)
3878
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
3845
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
3880
3847
List_iterator_fast<Item> li(item->list);
3881
3848
while (Item *it= li++)
3882
list.push_back(it->copy_andor_structure(thd));
3849
list.push_back(it->copy_andor_structure(session));
3887
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((unused)))
3854
Item_cond::fix_fields(Session *session, Item **)
3889
3856
assert(fixed == 0);
3890
3857
List_iterator<Item> li(list);
3892
void *orig_thd_marker= thd->thd_marker;
3893
uchar buff[sizeof(char*)]; // Max local vars in function
3859
void *orig_session_marker= session->session_marker;
3860
unsigned char buff[sizeof(char*)]; // Max local vars in function
3894
3861
not_null_tables_cache= used_tables_cache= 0;
3895
3862
const_item_cache= 1;
3897
3864
if (functype() == COND_OR_FUNC)
3865
session->session_marker= 0;
3900
3867
and_table_cache is the value that Item_cond_or() returns for
3901
3868
not_null_tables()
3903
3870
and_tables_cache= ~(table_map) 0;
3905
if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
3872
if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
3906
3873
return true; // Fatal error flag is set!
3908
3875
The following optimization reduces the depth of an AND-OR tree.
3947
3914
not_null_tables_cache|= tmp_table_map;
3948
3915
and_tables_cache&= tmp_table_map;
3949
3916
const_item_cache= false;
3951
3918
with_sum_func= with_sum_func || item->with_sum_func;
3952
3919
with_subselect|= item->with_subselect;
3953
3920
if (item->maybe_null)
3956
thd->lex->current_select->cond_count+= list.elements;
3957
thd->thd_marker= orig_thd_marker;
3923
session->lex->current_select->cond_count+= list.elements;
3924
session->session_marker= orig_session_marker;
3958
3925
fix_length_and_dec();
3964
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref __attribute__((unused)))
3931
void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
3966
3933
List_iterator<Item> li(list);
4008
3975
Transform an Item_cond object with a transformer callback function.
4010
3977
The function recursively applies the transform method to each
4011
3978
member item of the condition list.
4012
3979
If the call of the method for a member item returns a new item
4013
3980
the old item is substituted for a new one.
4014
3981
After this the transformer is applied to the root node
4015
of the Item_cond object.
3982
of the Item_cond object.
4017
3984
@param transformer the transformer callback function to be applied to
4018
3985
the nodes of the tree of the object
4019
3986
@param arg parameter to be passed to the transformer
4022
Item returned as the result of transformation of the root node
3989
Item returned as the result of transformation of the root node
4025
Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
3992
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
4027
3994
List_iterator<Item> li(list);
4066
4033
@param arg_t parameter to be passed to the transformer
4069
Item returned as the result of transformation of the root node
4036
Item returned as the result of transformation of the root node
4072
Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
4073
Item_transformer transformer, uchar *arg_t)
4039
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4040
Item_transformer transformer, unsigned char *arg_t)
4075
4042
if (!(this->*analyzer)(arg_p))
4078
4045
List_iterator<Item> li(list);
4080
4047
while ((item= li++))
4083
4050
The same parameter value of arg_p must be passed
4084
4051
to analyze any argument of the condition formula.
4086
uchar *arg_v= *arg_p;
4053
unsigned char *arg_v= *arg_p;
4087
4054
Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4088
4055
if (new_item && new_item != item)
4089
4056
li.replace(new_item);
4384
4352
if (canDoTurboBM)
4385
4353
return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
4386
4354
return my_wildcmp(cmp.cmp_collation.collation,
4387
res->ptr(),res->ptr()+res->length(),
4355
res->ptr(),res->ptr()+res->length(),
4388
4356
res2->ptr(),res2->ptr()+res2->length(),
4389
escape,wild_one,wild_many) ? 0 : 1;
4357
make_escape_code(cmp.cmp_collation.collation, escape),
4358
wild_one,wild_many) ? 0 : 1;
4425
4394
my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4429
4398
if (escape_item->const_item())
4431
4401
/* If we are on execution stage */
4432
4402
String *escape_str= escape_item->val_str(&tmp_value1);
4433
4403
if (escape_str)
4435
if (escape_used_in_parsing && (
4436
(((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
4437
escape_str->numchars() != 1) ||
4438
escape_str->numchars() > 1)))
4440
my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4444
if (use_mb(cmp.cmp_collation.collation))
4446
const CHARSET_INFO * const cs= escape_str->charset();
4448
int rc= cs->cset->mb_wc(cs, &wc,
4449
(const uchar*) escape_str->ptr(),
4450
(const uchar*) escape_str->ptr() +
4451
escape_str->length());
4452
escape= (int) (rc > 0 ? wc : '\\');
4457
In the case of 8bit character set, we pass native
4458
code instead of Unicode code as "escape" argument.
4459
Convert to "cs" if charset of escape differs.
4461
const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
4463
if (escape_str->needs_conversion(escape_str->length(),
4464
escape_str->charset(), cs, &unused))
4468
uint32_t cnvlen= copy_and_convert(&ch, 1, cs, escape_str->ptr(),
4469
escape_str->length(),
4470
escape_str->charset(), &errors);
4471
escape= cnvlen ? ch : '\\';
4474
escape= *(escape_str->ptr());
4405
escape= (char *)memory::sql_alloc(escape_str->length());
4406
strcpy(escape, escape_str->ptr());
4410
escape= (char *)memory::sql_alloc(1);
4411
strcpy(escape, "\\");
4481
4415
We could also do boyer-more for non-const items, but as we would have to
4482
4416
recompute the tables for each row it's not worth it.
4484
if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
4485
!(specialflag & SPECIAL_NO_NEW_FUNC))
4418
if (args[1]->const_item() && !use_strnxfrm(collation.collation))
4487
4420
String* res2 = args[1]->val_str(&tmp_value2);
4489
4422
return false; // Null argument
4491
4424
const size_t len = res2->length();
4492
4425
const char* first = res2->ptr();
4493
4426
const char* last = first + len - 1;
4551
4489
if (!cs->sort_order)
4554
for (i = pattern_len - 2; i >= 0; i--)
4491
for (int i = pattern_len - 2; i >= 0; i--)
4556
4493
int tmp = *(splm1 + i - f);
4557
4494
if (g < i && tmp < i - g)
4562
g = i; // g = min(i, g)
4564
while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
4501
while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
4573
for (i = pattern_len - 2; 0 <= i; --i)
4509
for (int i = pattern_len - 2; 0 <= i; --i)
4575
4511
int tmp = *(splm1 + i - f);
4576
4512
if (g < i && tmp < i - g)
4581
g = i; // g = min(i, g)
4584
likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4520
likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4720
4656
register int i = plm1;
4721
4657
while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4724
if (i == plm1 - shift)
4660
if (i == plm1 - shift)
4730
register const int v = plm1 - i;
4732
bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
4733
shift = (turboShift > bcShift) ? turboShift : bcShift;
4734
shift = max(shift, bmGs[i]);
4667
register const int v= plm1 - i;
4669
bcShift= bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
4670
shift= (turboShift > bcShift) ? turboShift : bcShift;
4671
shift= max(shift, bmGs[i]);
4735
4673
if (shift == bmGs[i])
4736
u = (pattern_len - shift < v) ? pattern_len - shift : v;
4674
u= (pattern_len - shift < v) ? pattern_len - shift : v;
4739
if (turboShift < bcShift)
4740
shift = max(shift, u + 1);
4677
if (turboShift < bcShift)
4678
shift= max(shift, u + 1);
4835
4774
a IS NOT NULL -> a IS NULL.
4837
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((unused)))
4776
Item *Item_func_isnotnull::neg_transformer(Session *)
4839
4778
Item *item= new Item_func_isnull(args[0]);
4844
Item *Item_cond_and::neg_transformer(THD *thd) /* NOT(a AND b AND ...) -> */
4783
Item *Item_cond_and::neg_transformer(Session *session) /* NOT(a AND b AND ...) -> */
4845
4784
/* NOT a OR NOT b OR ... */
4786
neg_arguments(session);
4848
4787
Item *item= new Item_cond_or(list);
4853
Item *Item_cond_or::neg_transformer(THD *thd) /* NOT(a OR b OR ...) -> */
4792
Item *Item_cond_or::neg_transformer(Session *session) /* NOT(a OR b OR ...) -> */
4854
4793
/* NOT a AND NOT b AND ... */
4795
neg_arguments(session);
4857
4796
Item *item= new Item_cond_and(list);
4862
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((unused)))
4801
Item *Item_func_nop_all::neg_transformer(Session *)
4864
4803
/* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4865
4804
Item_func_not_all *new_item= new Item_func_not_all(args[0]);