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 **);
24
#include "drizzled/server_includes.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"
40
static Eq_creator eq_creator;
41
static Ne_creator ne_creator;
42
static Gt_creator gt_creator;
43
static Lt_creator lt_creator;
44
static Ge_creator ge_creator;
45
static Le_creator le_creator;
47
static bool convert_constant_item(Session *, Item_field *, Item **);
29
49
static Item_result item_store_type(Item_result a, Item *item,
30
50
bool unsigned_flag)
194
215
Bitmap of collected types - otherwise
197
static uint collect_cmp_types(Item **items, uint nitems)
218
static uint32_t collect_cmp_types(Item **items, uint32_t nitems, bool skip_nulls= false)
221
uint32_t found_types;
201
222
Item_result left_result= items[0]->result_type();
202
223
assert(nitems > 1);
204
225
for (i= 1; i < nitems ; i++)
206
if ((left_result == ROW_RESULT ||
227
if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
228
continue; // Skip NULL constant items
229
if ((left_result == ROW_RESULT ||
207
230
items[i]->result_type() == ROW_RESULT) &&
208
231
cmp_row_type(items[0], items[i]))
210
found_types|= 1<< (uint)item_cmp_type(left_result,
233
found_types|= 1<< (uint32_t)item_cmp_type(left_result,
211
234
items[i]->result_type());
237
Even if all right-hand items are NULLs and we are skipping them all, we need
238
at least one type bit in the found_type bitmask.
240
if (skip_nulls && !found_types)
241
found_types= 1 << (uint)left_result;
213
242
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
246
Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
252
const Eq_creator* Eq_creator::instance()
232
258
Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
234
260
return new Item_func_ne(a, b);
264
const Ne_creator* Ne_creator::instance()
238
270
Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
240
272
return new Item_func_gt(a, b);
276
const Gt_creator* Gt_creator::instance()
244
282
Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
246
284
return new Item_func_lt(a, b);
288
const Lt_creator* Lt_creator::instance()
250
294
Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
252
296
return new Item_func_ge(a, b);
300
const Ge_creator* Ge_creator::instance()
256
306
Item_bool_func2* Le_creator::create(Item *a, Item *b) const
258
308
return new Item_func_le(a, b);
311
const Le_creator* Le_creator::instance()
263
319
Most of these returns 0LL if false and 1LL if true and
378
434
1 Item was replaced with an integer version of the item
381
static bool convert_constant_item(THD *thd, Item_field *field_item,
437
static bool convert_constant_item(Session *session, Item_field *field_item,
384
440
Field *field= field_item->field;
443
field->setWriteSet();
387
445
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;
447
ulong orig_sql_mode= session->variables.sql_mode;
448
enum_check_fields orig_count_cuted_fields= session->count_cuted_fields;
394
449
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
451
/* For comparison purposes allow invalid dates like 2000-01-32 */
402
thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
452
session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
403
453
MODE_INVALID_DATES;
404
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
454
session->count_cuted_fields= CHECK_FIELD_IGNORE;
407
457
Store the value of the field if it references an outer field because
448
493
if (!args[0] || !args[1])
452
497
We allow to convert to Unicode character sets in some cases.
453
498
The conditions when conversion is possible are:
454
499
- arguments A and B have different charsets
455
500
- A wins according to coercibility rules
456
501
- character set of A is superset for character set of B
458
503
If all of the above is true, then it's possible to convert
459
504
B into the character set of A, and then compare according
460
505
to the collation of A.
464
509
DTCollation coll;
465
510
if (args[0]->result_type() == STRING_RESULT &&
466
511
args[1]->result_type() == STRING_RESULT &&
467
512
agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
470
515
args[0]->cmp_context= args[1]->cmp_context=
471
516
item_cmp_type(args[0]->result_type(), args[1]->result_type());
472
517
// Make a special case of compare with fields to get nicer DATE comparisons
525
session= current_session;
526
Item_field *field_item= NULL;
482
528
if (args[0]->real_item()->type() == FIELD_ITEM)
484
Item_field *field_item= (Item_field*) (args[0]->real_item());
530
field_item= static_cast<Item_field*>(args[0]->real_item());
485
531
if (field_item->field->can_be_compared_as_int64_t() &&
486
532
!(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
488
if (convert_constant_item(thd, field_item, &args[1]))
534
if (convert_constant_item(session, field_item, &args[1]))
490
536
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
491
537
INT_RESULT); // Works for all types.
497
543
if (args[1]->real_item()->type() == FIELD_ITEM)
499
Item_field *field_item= (Item_field*) (args[1]->real_item());
545
field_item= static_cast<Item_field*>(args[1]->real_item());
500
546
if (field_item->field->can_be_compared_as_int64_t() &&
501
547
!(field_item->is_datetime() &&
502
548
args[0]->result_type() == STRING_RESULT))
504
if (convert_constant_item(thd, field_item, &args[0]))
550
if (convert_constant_item(session, field_item, &args[0]))
506
552
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
507
553
INT_RESULT); // Works for all types.
644
get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
690
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
645
691
char *warn_name, bool *error_arg)
647
693
uint64_t value= 0;
649
695
DRIZZLE_TIME l_time;
650
enum_drizzle_timestamp_type ret;
696
enum enum_drizzle_timestamp_type ret;
652
698
ret= str_to_datetime(str->ptr(), str->length(), &l_time,
653
699
(TIME_FUZZY_DATE | MODE_INVALID_DATES |
654
(thd->variables.sql_mode &
655
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))),
700
(session->variables.sql_mode & MODE_NO_ZERO_DATE)),
658
703
if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
696
741
int result and the other item (b or a) is an item with string result.
697
742
If the second item is a constant one then it's checked to be
698
743
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.
744
converted to a DATE/DATETIME then an error is issued back to the Session.
701
745
In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
702
746
the comparison is handled by other comparators.
703
748
If the datetime comparator can be used and one the operands of the
704
749
comparison is a string constant that was successfully converted to a
705
750
DATE/DATETIME type then the result of the conversion is returned in the
748
793
(str_arg->type() != Item::FUNC_ITEM ||
749
794
((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
751
THD *thd= current_thd;
797
* OK, we are here if we've got a date field (or something which can be
798
* compared as a date field) on one side of the equation, and a constant
799
* string on the other side. In this case, we must verify that the constant
800
* string expression can indeed be evaluated as a datetime. If it cannot,
801
* we throw an error here and stop processsing. Bad data should ALWAYS
802
* produce an error, and no implicit conversion or truncation should take place.
804
* If the conversion to a DateTime temporal is successful, then we convert
805
* the Temporal instance to a uint64_t for the comparison operator, which
806
* compares date(times) using int64_t semantics.
810
* Does a uint64_t conversion really have to happen here? Fields return int64_t
811
* 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);
816
/* DateTime used to pick up as many string conversion possibilities as possible. */
817
drizzled::DateTime temporal;
758
819
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;
823
* If we are here, it is most likely due to the comparison item
824
* being a NULL. Although this is incorrect (SQL demands that the term IS NULL
825
* be used, not = NULL since no item can be equal to NULL).
827
* So, return gracefully.
829
return CMP_DATE_DFLT;
831
if (! temporal.from_string(str_val->c_ptr(), str_val->length()))
833
/* Chuck an error. Bad datetime input. */
834
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
835
return CMP_DATE_DFLT; /* :( What else can I return... */
838
/* String conversion was good. Convert to an integer for comparison purposes. */
840
temporal.to_int64_t(&int_value);
841
value= (uint64_t) int_value;
765
844
*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
851
int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
836
852
Item **a1, Item **a2,
837
853
Item_result type)
979
982
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);
983
enum enum_drizzle_timestamp_type t_type= f_type ==
984
DRIZZLE_TYPE_DATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
985
value= get_date_from_str(session, str, t_type, warn_item->name, &error);
984
987
If str did not contain a valid date according to the current
985
988
SQL_MODE, get_date_from_str() has already thrown a warning,
2217
uint Item_func_ifnull::decimal_precision() const
2212
uint32_t Item_func_ifnull::decimal_precision() const
2219
int max_int_part=max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2214
int max_int_part= max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2220
2215
return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2224
enum_field_types Item_func_ifnull::field_type() const
2219
enum_field_types Item_func_ifnull::field_type() const
2226
2221
return cached_field_type;
2229
Field *Item_func_ifnull::tmp_table_field(TABLE *table)
2224
Field *Item_func_ifnull::tmp_table_field(Table *table)
2231
2226
return tmp_table_field_from_field_type(table, 0);
2345
2340
Item_func_if::fix_length_and_dec()
2347
maybe_null=args[1]->maybe_null || args[2]->maybe_null;
2342
maybe_null= args[1]->maybe_null || args[2]->maybe_null;
2348
2343
decimals= max(args[1]->decimals, args[2]->decimals);
2349
unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
2344
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;
2346
enum Item_result arg1_type= args[1]->result_type();
2347
enum Item_result arg2_type= args[2]->result_type();
2348
bool null1= args[1]->const_item() && args[1]->null_value;
2349
bool null2= args[2]->const_item() && args[2]->null_value;
2389
2384
int len2= args[2]->max_length - args[2]->decimals
2390
2385
- (args[2]->unsigned_flag ? 0 : 1);
2392
max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
2387
max_length= max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
2395
2390
max_length= max(args[1]->max_length, args[2]->max_length);
2399
uint Item_func_if::decimal_precision() const
2394
uint32_t Item_func_if::decimal_precision() const
2401
int precision=(max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
2396
int precision= (max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+
2403
2398
return min(precision, DECIMAL_MAX_PRECISION);
2585
2580
/* Compare every WHEN argument with it and return the first match */
2586
for (uint i=0 ; i < ncases ; i+=2)
2581
for (uint32_t i=0 ; i < ncases ; i+=2)
2588
2583
cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
2589
2584
assert(cmp_type != ROW_RESULT);
2590
assert(cmp_items[(uint)cmp_type]);
2591
if (!(value_added_map & (1<<(uint)cmp_type)))
2585
assert(cmp_items[(uint32_t)cmp_type]);
2586
if (!(value_added_map & (1<<(uint32_t)cmp_type)))
2593
cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
2588
cmp_items[(uint32_t)cmp_type]->store_value(args[first_expr_num]);
2594
2589
if ((null_value=args[first_expr_num]->null_value))
2595
2590
return else_expr_num != -1 ? args[else_expr_num] : 0;
2596
value_added_map|= 1<<(uint)cmp_type;
2591
value_added_map|= 1<<(uint32_t)cmp_type;
2598
if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2593
if (!cmp_items[(uint32_t)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2599
2594
return args[i + 1];
2682
bool Item_func_case::fix_fields(THD *thd, Item **ref)
2677
bool Item_func_case::fix_fields(Session *session, Item **ref)
2685
2680
buff should match stack usage from
2686
2681
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);
2683
unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2
2684
+sizeof(double)*2+sizeof(int64_t)*2];
2685
bool res= Item_func::fix_fields(session, ref);
2691
2687
Call check_stack_overrun after fix_fields to be sure that stack variable
2692
2688
is not optimized away
2694
if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
2690
if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
2695
2691
return true; // Fatal error flag is set!
2708
2704
void Item_func_case::agg_num_lengths(Item *arg)
2710
uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2706
uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2711
2707
arg->unsigned_flag) - arg->decimals;
2712
set_if_bigger(max_length, len);
2708
set_if_bigger(max_length, len);
2713
2709
set_if_bigger(decimals, arg->decimals);
2714
unsigned_flag= unsigned_flag && arg->unsigned_flag;
2710
unsigned_flag= unsigned_flag && arg->unsigned_flag;
2718
2714
void Item_func_case::fix_length_and_dec()
2722
uint found_types= 0;
2718
uint32_t found_types= 0;
2723
2719
if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2727
2723
Aggregate all THEN and ELSE expression types
2728
2724
and collations when string result
2731
2727
for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2732
2728
agg[nagg]= args[nagg*2+1];
2734
2730
if (else_expr_num != -1)
2735
2731
agg[nagg++]= args[else_expr_num];
2737
2733
agg_result_type(&cached_result_type, agg, nagg);
2738
2734
if ((cached_result_type == STRING_RESULT) &&
2739
2735
agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2742
2738
cached_field_type= agg_field_type(agg, nagg);
2744
2740
Aggregate first expression and all THEN expression types
3016
3012
0 left argument is equal to the right argument.
3017
3013
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)
3015
int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
3016
in_int64_t::packed_int64_t *b)
3023
3018
if (a->unsigned_flag != b->unsigned_flag)
3026
One of the args is unsigned and is too big to fit into the
3021
One of the args is unsigned and is too big to fit into the
3027
3022
positive signed range. Report no match.
3029
3024
if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3030
3025
(b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
3031
3026
return a->unsigned_flag ? 1 : -1;
3033
Although the signedness differs both args can fit into the signed
3028
Although the signedness differs both args can fit into the signed
3034
3029
positive range. Make them signed and compare as usual.
3036
3031
return cmp_longs (a->val, b->val);
3038
3033
if (a->unsigned_flag)
3041
3036
return cmp_longs (a->val, b->val);
3044
static int cmp_double(void *cmp_arg __attribute__((unused)), double *a,double *b)
3039
static int cmp_double(void *, double *a, double *b)
3046
3041
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)
3044
static int cmp_row(void *, cmp_item_row *a, cmp_item_row *b)
3051
3046
return a->compare(b);
3055
static int cmp_decimal(void *cmp_arg __attribute__((unused)), my_decimal *a, my_decimal *b)
3050
static int cmp_decimal(void *, my_decimal *a, my_decimal *b)
3058
3053
We need call of fixing buffer pointer, because fast sort just copy
3148
3143
delete [] (cmp_item_row*) base;
3151
uchar *in_row::get_value(Item *item)
3146
unsigned char *in_row::get_value(Item *item)
3153
3148
tmp.store_value(item);
3154
3149
if (item->is_null())
3156
return (uchar *)&tmp;
3151
return (unsigned char *)&tmp;
3159
void in_row::set(uint pos, Item *item)
3154
void in_row::set(uint32_t pos, Item *item)
3161
3156
((cmp_item_row*) base)[pos].store_value_by_template(&tmp, item);
3165
in_int64_t::in_int64_t(uint elements)
3160
in_int64_t::in_int64_t(uint32_t elements)
3166
3161
:in_vector(elements,sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
3169
void in_int64_t::set(uint pos,Item *item)
3164
void in_int64_t::set(uint32_t pos,Item *item)
3171
3166
struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3173
3168
buff->val= item->val_int();
3174
3169
buff->unsigned_flag= item->unsigned_flag;
3177
uchar *in_int64_t::get_value(Item *item)
3172
unsigned char *in_int64_t::get_value(Item *item)
3179
3174
tmp.val= item->val_int();
3180
3175
if (item->null_value)
3182
3177
tmp.unsigned_flag= item->unsigned_flag;
3183
return (uchar*) &tmp;
3178
return (unsigned char*) &tmp;
3186
void in_datetime::set(uint pos,Item *item)
3181
void in_datetime::set(uint32_t pos,Item *item)
3188
3183
Item **tmp_item= &item;
3190
3185
struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3192
buff->val= get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3187
buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3193
3188
buff->unsigned_flag= 1L;
3196
uchar *in_datetime::get_value(Item *item)
3191
unsigned char *in_datetime::get_value(Item *item)
3199
3194
Item **tmp_item= lval_cache ? &lval_cache : &item;
3200
tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
3195
tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3201
3196
if (item->null_value)
3203
3198
tmp.unsigned_flag= 1L;
3204
return (uchar*) &tmp;
3199
return (unsigned char*) &tmp;
3207
in_double::in_double(uint elements)
3202
in_double::in_double(uint32_t elements)
3208
3203
:in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
3211
void in_double::set(uint pos,Item *item)
3206
void in_double::set(uint32_t pos,Item *item)
3213
3208
((double*) base)[pos]= item->val_real();
3216
uchar *in_double::get_value(Item *item)
3211
unsigned char *in_double::get_value(Item *item)
3218
3213
tmp= item->val_real();
3219
3214
if (item->null_value)
3220
return 0; /* purecov: inspected */
3221
return (uchar*) &tmp;
3216
return (unsigned char*) &tmp;
3225
in_decimal::in_decimal(uint elements)
3220
in_decimal::in_decimal(uint32_t elements)
3226
3221
:in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0)
3230
void in_decimal::set(uint pos, Item *item)
3225
void in_decimal::set(uint32_t pos, Item *item)
3232
3227
/* as far as 'item' is constant, we can store reference on my_decimal */
3233
3228
my_decimal *dec= ((my_decimal *)base) + pos;
3234
3229
dec->len= DECIMAL_BUFF_LENGTH;
3235
3230
dec->fix_buffer_pointer();
3236
3231
my_decimal *res= item->val_decimal(dec);
3237
/* if item->val_decimal() is evaluated to NULL then res == 0 */
3232
/* if item->val_decimal() is evaluated to NULL then res == 0 */
3238
3233
if (!item->null_value && res != dec)
3239
3234
my_decimal2decimal(res, dec);
3243
uchar *in_decimal::get_value(Item *item)
3238
unsigned char *in_decimal::get_value(Item *item)
3245
3240
my_decimal *result= item->val_decimal(&val);
3246
3241
if (item->null_value)
3248
return (uchar *)result;
3243
return (unsigned char *)result;
3802
3799
return (int64_t) (!null_value && tmp != negated);
3805
for (uint i= 1 ; i < arg_count ; i++)
3802
for (uint32_t i= 1 ; i < arg_count ; i++)
3807
3804
Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
3808
in_item= cmp_items[(uint)cmp_type];
3805
in_item= cmp_items[(uint32_t)cmp_type];
3809
3806
assert(in_item);
3810
if (!(value_added_map & (1 << (uint)cmp_type)))
3807
if (!(value_added_map & (1 << (uint32_t)cmp_type)))
3812
3809
in_item->store_value(args[0]);
3813
3810
if ((null_value=args[0]->null_value))
3816
value_added_map|= 1 << (uint)cmp_type;
3813
value_added_map|= 1 << (uint32_t)cmp_type;
3818
3815
if (!in_item->cmp(args[i]) && !args[i]->null_value)
3819
3816
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),
3825
Item_cond::Item_cond(Session *session, Item_cond *item)
3826
:Item_bool_func(session, item),
3869
3827
abort_on_null(item->abort_on_null),
3870
3828
and_tables_cache(item->and_tables_cache)
3878
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
3836
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
3880
3838
List_iterator_fast<Item> li(item->list);
3881
3839
while (Item *it= li++)
3882
list.push_back(it->copy_andor_structure(thd));
3840
list.push_back(it->copy_andor_structure(session));
3887
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((unused)))
3845
Item_cond::fix_fields(Session *session, Item **)
3889
3847
assert(fixed == 0);
3890
3848
List_iterator<Item> li(list);
3892
void *orig_thd_marker= thd->thd_marker;
3893
uchar buff[sizeof(char*)]; // Max local vars in function
3850
void *orig_session_marker= session->session_marker;
3851
unsigned char buff[sizeof(char*)]; // Max local vars in function
3894
3852
not_null_tables_cache= used_tables_cache= 0;
3895
3853
const_item_cache= 1;
3897
3855
if (functype() == COND_OR_FUNC)
3856
session->session_marker= 0;
3900
3858
and_table_cache is the value that Item_cond_or() returns for
3901
3859
not_null_tables()
3903
3861
and_tables_cache= ~(table_map) 0;
3905
if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
3863
if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
3906
3864
return true; // Fatal error flag is set!
3908
3866
The following optimization reduces the depth of an AND-OR tree.
3947
3905
not_null_tables_cache|= tmp_table_map;
3948
3906
and_tables_cache&= tmp_table_map;
3949
3907
const_item_cache= false;
3951
3909
with_sum_func= with_sum_func || item->with_sum_func;
3952
3910
with_subselect|= item->with_subselect;
3953
3911
if (item->maybe_null)
3956
thd->lex->current_select->cond_count+= list.elements;
3957
thd->thd_marker= orig_thd_marker;
3914
session->lex->current_select->cond_count+= list.elements;
3915
session->session_marker= orig_session_marker;
3958
3916
fix_length_and_dec();
3964
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref __attribute__((unused)))
3922
void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
3966
3924
List_iterator<Item> li(list);
4008
3966
Transform an Item_cond object with a transformer callback function.
4010
3968
The function recursively applies the transform method to each
4011
3969
member item of the condition list.
4012
3970
If the call of the method for a member item returns a new item
4013
3971
the old item is substituted for a new one.
4014
3972
After this the transformer is applied to the root node
4015
of the Item_cond object.
3973
of the Item_cond object.
4017
3975
@param transformer the transformer callback function to be applied to
4018
3976
the nodes of the tree of the object
4019
3977
@param arg parameter to be passed to the transformer
4022
Item returned as the result of transformation of the root node
3980
Item returned as the result of transformation of the root node
4025
Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
3983
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
4027
3985
List_iterator<Item> li(list);
4066
4024
@param arg_t parameter to be passed to the transformer
4069
Item returned as the result of transformation of the root node
4027
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)
4030
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4031
Item_transformer transformer, unsigned char *arg_t)
4075
4033
if (!(this->*analyzer)(arg_p))
4078
4036
List_iterator<Item> li(list);
4080
4038
while ((item= li++))
4083
4041
The same parameter value of arg_p must be passed
4084
4042
to analyze any argument of the condition formula.
4086
uchar *arg_v= *arg_p;
4044
unsigned char *arg_v= *arg_p;
4087
4045
Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4088
4046
if (new_item && new_item != item)
4089
4047
li.replace(new_item);
4384
4343
if (canDoTurboBM)
4385
4344
return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
4386
4345
return my_wildcmp(cmp.cmp_collation.collation,
4387
res->ptr(),res->ptr()+res->length(),
4346
res->ptr(),res->ptr()+res->length(),
4388
4347
res2->ptr(),res2->ptr()+res2->length(),
4389
escape,wild_one,wild_many) ? 0 : 1;
4348
make_escape_code(cmp.cmp_collation.collation, escape),
4349
wild_one,wild_many) ? 0 : 1;
4425
4385
my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4429
4389
if (escape_item->const_item())
4431
4392
/* If we are on execution stage */
4432
4393
String *escape_str= escape_item->val_str(&tmp_value1);
4433
4394
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());
4396
escape= (char *)sql_alloc(escape_str->length());
4397
strcpy(escape, escape_str->ptr());
4401
escape= (char *)sql_alloc(1);
4402
strcpy(escape, "\\");
4481
4406
We could also do boyer-more for non-const items, but as we would have to
4482
4407
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))
4409
if (args[1]->const_item() && !use_strnxfrm(collation.collation))
4487
4411
String* res2 = args[1]->val_str(&tmp_value2);
4489
4413
return false; // Null argument
4491
4415
const size_t len = res2->length();
4492
4416
const char* first = res2->ptr();
4493
4417
const char* last = first + len - 1;
4551
4480
if (!cs->sort_order)
4554
for (i = pattern_len - 2; i >= 0; i--)
4482
for (int i = pattern_len - 2; i >= 0; i--)
4556
4484
int tmp = *(splm1 + i - f);
4557
4485
if (g < i && tmp < i - g)
4562
g = i; // g = min(i, g)
4564
while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
4492
while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
4573
for (i = pattern_len - 2; 0 <= i; --i)
4500
for (int i = pattern_len - 2; 0 <= i; --i)
4575
4502
int tmp = *(splm1 + i - f);
4576
4503
if (g < i && tmp < i - g)
4581
g = i; // g = min(i, g)
4584
likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4511
likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4720
4647
register int i = plm1;
4721
4648
while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4724
if (i == plm1 - shift)
4651
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]);
4658
register const int v= plm1 - i;
4660
bcShift= bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
4661
shift= (turboShift > bcShift) ? turboShift : bcShift;
4662
shift= max(shift, bmGs[i]);
4735
4664
if (shift == bmGs[i])
4736
u = (pattern_len - shift < v) ? pattern_len - shift : v;
4665
u= (pattern_len - shift < v) ? pattern_len - shift : v;
4739
if (turboShift < bcShift)
4740
shift = max(shift, u + 1);
4668
if (turboShift < bcShift)
4669
shift= max(shift, u + 1);
4835
4765
a IS NOT NULL -> a IS NULL.
4837
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((unused)))
4767
Item *Item_func_isnotnull::neg_transformer(Session *)
4839
4769
Item *item= new Item_func_isnull(args[0]);
4844
Item *Item_cond_and::neg_transformer(THD *thd) /* NOT(a AND b AND ...) -> */
4774
Item *Item_cond_and::neg_transformer(Session *session) /* NOT(a AND b AND ...) -> */
4845
4775
/* NOT a OR NOT b OR ... */
4777
neg_arguments(session);
4848
4778
Item *item= new Item_cond_or(list);
4853
Item *Item_cond_or::neg_transformer(THD *thd) /* NOT(a OR b OR ...) -> */
4783
Item *Item_cond_or::neg_transformer(Session *session) /* NOT(a OR b OR ...) -> */
4854
4784
/* NOT a AND NOT b AND ... */
4786
neg_arguments(session);
4857
4787
Item *item= new Item_cond_and(list);
4862
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((unused)))
4792
Item *Item_func_nop_all::neg_transformer(Session *)
4864
4794
/* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4865
4795
Item_func_not_all *new_item= new Item_func_not_all(args[0]);