21
21
This file defines all compare functions
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"
43
extern const double log_10[309];
45
static Eq_creator eq_creator;
46
static Ne_creator ne_creator;
47
static Gt_creator gt_creator;
48
static Lt_creator lt_creator;
49
static Ge_creator ge_creator;
50
static Le_creator le_creator;
52
static bool convert_constant_item(Session *, Item_field *, Item **);
24
#ifdef USE_PRAGMA_IMPLEMENTATION
25
#pragma implementation // gcc: Class implementation
28
#include "mysql_priv.h"
30
#include "sql_select.h"
32
static bool convert_constant_item(THD *, Item_field *, Item **);
54
34
static Item_result item_store_type(Item_result a, Item *item,
35
my_bool unsigned_flag)
57
37
Item_result b= item->result_type();
220
199
Bitmap of collected types - otherwise
223
static uint32_t collect_cmp_types(Item **items, uint32_t nitems, bool skip_nulls= false)
202
static uint collect_cmp_types(Item **items, uint nitems)
226
uint32_t found_types;
227
206
Item_result left_result= items[0]->result_type();
228
207
assert(nitems > 1);
230
209
for (i= 1; i < nitems ; i++)
232
if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
233
continue; // Skip NULL constant items
234
if ((left_result == ROW_RESULT ||
211
if ((left_result == ROW_RESULT ||
235
212
items[i]->result_type() == ROW_RESULT) &&
236
213
cmp_row_type(items[0], items[i]))
238
found_types|= 1<< (uint32_t)item_cmp_type(left_result,
215
found_types|= 1<< (uint)item_cmp_type(left_result,
239
216
items[i]->result_type());
242
Even if all right-hand items are NULLs and we are skipping them all, we need
243
at least one type bit in the found_type bitmask.
245
if (skip_nulls && !found_types)
246
found_types= 1 << (uint)left_result;
247
218
return found_types;
221
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2,
224
my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
225
c1.collation->name,c1.derivation_name(),
226
c2.collation->name,c2.derivation_name(),
251
231
Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
257
const Eq_creator* Eq_creator::instance()
263
237
Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
265
239
return new Item_func_ne(a, b);
269
const Ne_creator* Ne_creator::instance()
275
243
Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
277
245
return new Item_func_gt(a, b);
281
const Gt_creator* Gt_creator::instance()
287
249
Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
289
251
return new Item_func_lt(a, b);
293
const Lt_creator* Lt_creator::instance()
299
255
Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
301
257
return new Item_func_ge(a, b);
305
const Ge_creator* Ge_creator::instance()
311
261
Item_bool_func2* Le_creator::create(Item *a, Item *b) const
313
263
return new Item_func_le(a, b);
316
const Le_creator* Le_creator::instance()
324
268
Most of these returns 0LL if false and 1LL if true and
439
383
1 Item was replaced with an integer version of the item
442
static bool convert_constant_item(Session *session, Item_field *field_item,
386
static bool convert_constant_item(THD *thd, Item_field *field_item,
445
389
Field *field= field_item->field;
448
field->setWriteSet();
450
392
if (!(*item)->with_subselect && (*item)->const_item())
452
ulong orig_sql_mode= session->variables.sql_mode;
453
enum_check_fields orig_count_cuted_fields= session->count_cuted_fields;
394
TABLE *table= field->table;
395
ulong orig_sql_mode= thd->variables.sql_mode;
396
enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
397
my_bitmap_map *old_write_map;
398
my_bitmap_map *old_read_map;
454
399
uint64_t orig_field_val= 0; /* original field value if valid */
403
old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
404
old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
456
406
/* For comparison purposes allow invalid dates like 2000-01-32 */
457
session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
407
thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
458
408
MODE_INVALID_DATES;
459
session->count_cuted_fields= CHECK_FIELD_IGNORE;
409
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
462
412
Store the value of the field if it references an outer field because
498
453
if (!args[0] || !args[1])
502
457
We allow to convert to Unicode character sets in some cases.
503
458
The conditions when conversion is possible are:
504
459
- arguments A and B have different charsets
505
460
- A wins according to coercibility rules
506
461
- character set of A is superset for character set of B
508
463
If all of the above is true, then it's possible to convert
509
464
B into the character set of A, and then compare according
510
465
to the collation of A.
514
469
DTCollation coll;
515
470
if (args[0]->result_type() == STRING_RESULT &&
516
471
args[1]->result_type() == STRING_RESULT &&
517
472
agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
520
475
args[0]->cmp_context= args[1]->cmp_context=
521
476
item_cmp_type(args[0]->result_type(), args[1]->result_type());
522
477
// Make a special case of compare with fields to get nicer DATE comparisons
572
526
func= comparator_matrix[type]
573
[test(owner->functype() == Item_func::EQUAL_FUNC)];
527
[test(owner->functype() == Item_func::EQUAL_FUNC)];
578
uint32_t n= (*a)->cols();
579
if (n != (*b)->cols())
581
my_error(ER_OPERAND_COLUMNS, MYF(0), n);
585
if (!(comparators= new Arg_comparator[n]))
587
for (uint32_t i=0; i < n; i++)
589
if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
591
my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
594
comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
531
uint n= (*a)->cols();
532
if (n != (*b)->cols())
534
my_error(ER_OPERAND_COLUMNS, MYF(0), n);
538
if (!(comparators= new Arg_comparator[n]))
540
for (uint i=0; i < n; i++)
542
if ((*a)->element_index(i)->cols() != (*b)->element_index(i)->cols())
544
my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
547
comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
599
551
case STRING_RESULT:
554
We must set cmp_charset here as we may be called from for an automatic
555
generated item, like in natural join
557
if (cmp_collation.set((*a)->collation, (*b)->collation) ||
558
cmp_collation.derivation == DERIVATION_NONE)
560
my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
563
if (cmp_collation.collation == &my_charset_bin)
602
We must set cmp_charset here as we may be called from for an automatic
603
generated item, like in natural join
566
We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
567
without removing end space
605
if (cmp_collation.set((*a)->collation, (*b)->collation) ||
606
cmp_collation.derivation == DERIVATION_NONE)
608
my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
611
if (cmp_collation.collation == &my_charset_bin)
614
We are using BLOB/BINARY/VARBINARY, change to compare byte by byte,
615
without removing end space
617
if (func == &Arg_comparator::compare_string)
618
func= &Arg_comparator::compare_binary_string;
619
else if (func == &Arg_comparator::compare_e_string)
620
func= &Arg_comparator::compare_e_binary_string;
569
if (func == &Arg_comparator::compare_string)
570
func= &Arg_comparator::compare_binary_string;
571
else if (func == &Arg_comparator::compare_e_string)
572
func= &Arg_comparator::compare_e_binary_string;
623
As this is binary compassion, mark all fields that they can't be
624
transformed. Otherwise we would get into trouble with comparisons
626
WHERE col= 'j' AND col LIKE BINARY 'j'
627
which would be transformed to:
575
As this is binary compassion, mark all fields that they can't be
576
transformed. Otherwise we would get into trouble with comparisons
578
WHERE col= 'j' AND col LIKE BINARY 'j'
579
which would be transformed to:
630
(*a)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
631
(*b)->walk(&Item::set_no_const_sub, false, (unsigned char*) 0);
582
(*a)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
583
(*b)->walk(&Item::set_no_const_sub, false, (uchar*) 0);
637
if (func == &Arg_comparator::compare_int_signed)
639
if ((*a)->unsigned_flag)
640
func= (((*b)->unsigned_flag)?
641
&Arg_comparator::compare_int_unsigned :
642
&Arg_comparator::compare_int_unsigned_signed);
643
else if ((*b)->unsigned_flag)
644
func= &Arg_comparator::compare_int_signed_unsigned;
646
else if (func== &Arg_comparator::compare_e_int)
648
if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
649
func= &Arg_comparator::compare_e_int_diff_signedness;
589
if (func == &Arg_comparator::compare_int_signed)
591
if ((*a)->unsigned_flag)
592
func= (((*b)->unsigned_flag)?
593
&Arg_comparator::compare_int_unsigned :
594
&Arg_comparator::compare_int_unsigned_signed);
595
else if ((*b)->unsigned_flag)
596
func= &Arg_comparator::compare_int_signed_unsigned;
598
else if (func== &Arg_comparator::compare_e_int)
600
if ((*a)->unsigned_flag ^ (*b)->unsigned_flag)
601
func= &Arg_comparator::compare_e_int_diff_signedness;
653
605
case DECIMAL_RESULT:
655
607
case REAL_RESULT:
609
if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
657
if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
659
precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
660
if (func == &Arg_comparator::compare_real)
661
func= &Arg_comparator::compare_real_fixed;
662
else if (func == &Arg_comparator::compare_e_real)
663
func= &Arg_comparator::compare_e_real_fixed;
611
precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
612
if (func == &Arg_comparator::compare_real)
613
func= &Arg_comparator::compare_real_fixed;
614
else if (func == &Arg_comparator::compare_e_real)
615
func= &Arg_comparator::compare_e_real_fixed;
696
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
649
get_date_from_str(THD *thd, String *str, timestamp_type warn_type,
697
650
char *warn_name, bool *error_arg)
699
652
uint64_t value= 0;
702
enum enum_drizzle_timestamp_type ret;
655
enum_mysql_timestamp_type ret;
704
657
ret= str_to_datetime(str->ptr(), str->length(), &l_time,
705
658
(TIME_FUZZY_DATE | MODE_INVALID_DATES |
706
(session->variables.sql_mode & MODE_NO_ZERO_DATE)),
659
(thd->variables.sql_mode &
660
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))),
709
if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
663
if (ret == MYSQL_TIMESTAMP_DATETIME || ret == MYSQL_TIMESTAMP_DATE)
712
666
Do not return yet, we may still want to throw a "trailing garbage"
767
719
enum Arg_comparator::enum_date_cmp_type
768
Arg_comparator::can_compare_as_dates(Item *in_a, Item *in_b,
769
uint64_t *const_value)
720
Arg_comparator::can_compare_as_dates(Item *a, Item *b, uint64_t *const_value)
771
722
enum enum_date_cmp_type cmp_type= CMP_DATE_DFLT;
772
723
Item *str_arg= 0, *date_arg= 0;
774
if (in_a->type() == Item::ROW_ITEM || in_b->type() == Item::ROW_ITEM)
725
if (a->type() == Item::ROW_ITEM || b->type() == Item::ROW_ITEM)
775
726
return CMP_DATE_DFLT;
777
if (in_a->is_datetime())
728
if (a->is_datetime())
779
if (in_b->is_datetime())
730
if (b->is_datetime())
780
731
cmp_type= CMP_DATE_WITH_DATE;
781
else if (in_b->result_type() == STRING_RESULT)
732
else if (b->result_type() == STRING_RESULT)
783
734
cmp_type= CMP_DATE_WITH_STR;
788
else if (in_b->is_datetime() && in_a->result_type() == STRING_RESULT)
739
else if (b->is_datetime() && a->result_type() == STRING_RESULT)
790
741
cmp_type= CMP_STR_WITH_DATE;
795
746
if (cmp_type != CMP_DATE_DFLT)
802
753
(str_arg->type() != Item::FUNC_ITEM ||
803
754
((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
806
* OK, we are here if we've got a date field (or something which can be
807
* compared as a date field) on one side of the equation, and a constant
808
* string on the other side. In this case, we must verify that the constant
809
* string expression can indeed be evaluated as a datetime. If it cannot,
810
* we throw an error here and stop processsing. Bad data should ALWAYS
811
* produce an error, and no implicit conversion or truncation should take place.
813
* If the conversion to a DateTime temporal is successful, then we convert
814
* the Temporal instance to a uint64_t for the comparison operator, which
815
* compares date(times) using int64_t semantics.
819
* Does a uint64_t conversion really have to happen here? Fields return int64_t
820
* from val_int(), not uint64_t...
756
THD *thd= current_thd;
825
/* DateTime used to pick up as many string conversion possibilities as possible. */
759
String tmp, *str_val= 0;
760
timestamp_type t_type= (date_arg->field_type() == MYSQL_TYPE_NEWDATE ?
761
MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME);
828
763
str_val= str_arg->val_str(&tmp);
832
* If we are here, it is most likely due to the comparison item
833
* being a NULL. Although this is incorrect (SQL demands that the term IS NULL
834
* be used, not = NULL since no item can be equal to NULL).
836
* So, return gracefully.
838
return CMP_DATE_DFLT;
840
if (! temporal.from_string(str_val->c_ptr(), str_val->length()))
842
/* Chuck an error. Bad datetime input. */
843
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
844
return CMP_DATE_DFLT; /* :( What else can I return... */
847
/* String conversion was good. Convert to an integer for comparison purposes. */
849
temporal.to_int64_t(&int_value);
850
value= (uint64_t) int_value;
764
if (str_arg->null_value)
765
return CMP_DATE_DFLT;
766
value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
768
return CMP_DATE_DFLT;
853
770
*const_value= value;
778
Retrieves correct TIME value from the given item.
783
item_arg [in/out] item to retrieve TIME value from
784
cache_arg [in/out] pointer to place to store the cache item to
785
warn_item [in] unused
786
is_null [out] true <=> the item_arg is null
789
Retrieves the correct TIME value from given item for comparison by the
790
compare_datetime() function.
791
If item's result can be compared as int64_t then its int value is used
792
and a value returned by get_time function is used otherwise.
793
If an item is a constant one then its value is cached and it isn't
794
get parsed again. An Item_cache_int object is used for for cached values.
795
It seamlessly substitutes the original item. The cache item is marked as
796
non-constant to prevent re-caching it again.
803
get_time_value(THD *thd __attribute__((__unused__)),
804
Item ***item_arg, Item **cache_arg,
805
Item *warn_item __attribute__((__unused__)),
809
Item *item= **item_arg;
812
if (item->result_as_int64_t())
814
value= item->val_int();
815
*is_null= item->null_value;
819
*is_null= item->get_time(<ime);
820
value= !*is_null ? TIME_to_uint64_t_datetime(<ime) : 0;
823
Do not cache GET_USER_VAR() function as its const_item() may return true
824
for the current thread but it still may change during the execution.
826
if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
827
((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
829
Item_cache_int *cache= new Item_cache_int();
830
/* Mark the cache as non-const to prevent re-caching. */
831
cache->set_used_tables(1);
832
cache->store(item, value);
834
*item_arg= cache_arg;
860
840
int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
861
841
Item **a1, Item **a2,
862
842
Item_result type)
2196
2199
max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
2200
2202
max_length= max(args[0]->max_length, args[1]->max_length);
2203
switch (hybrid_type)
2204
switch (hybrid_type) {
2205
2205
case STRING_RESULT:
2206
2206
agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
2209
2208
case DECIMAL_RESULT:
2210
2209
case REAL_RESULT:
2213
2211
case INT_RESULT:
2217
2214
case ROW_RESULT:
2221
2218
cached_field_type= agg_field_type(args, 2);
2225
uint32_t Item_func_ifnull::decimal_precision() const
2222
uint Item_func_ifnull::decimal_precision() const
2227
int max_int_part= max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2224
int max_int_part=max(args[0]->decimal_int_part(),args[1]->decimal_int_part());
2228
2225
return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
2232
enum_field_types Item_func_ifnull::field_type() const
2229
enum_field_types Item_func_ifnull::field_type() const
2234
2231
return cached_field_type;
2237
Field *Item_func_ifnull::tmp_table_field(Table *table)
2234
Field *Item_func_ifnull::tmp_table_field(TABLE *table)
2239
2236
return tmp_table_field_from_field_type(table, 0);
2593
2590
/* Compare every WHEN argument with it and return the first match */
2594
for (uint32_t i=0 ; i < ncases ; i+=2)
2591
for (uint i=0 ; i < ncases ; i+=2)
2596
2593
cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
2597
2594
assert(cmp_type != ROW_RESULT);
2598
assert(cmp_items[(uint32_t)cmp_type]);
2599
if (!(value_added_map & (1<<(uint32_t)cmp_type)))
2595
assert(cmp_items[(uint)cmp_type]);
2596
if (!(value_added_map & (1<<(uint)cmp_type)))
2601
cmp_items[(uint32_t)cmp_type]->store_value(args[first_expr_num]);
2598
cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
2602
2599
if ((null_value=args[first_expr_num]->null_value))
2603
2600
return else_expr_num != -1 ? args[else_expr_num] : 0;
2604
value_added_map|= 1<<(uint32_t)cmp_type;
2601
value_added_map|= 1<<(uint)cmp_type;
2606
if (!cmp_items[(uint32_t)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2603
if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2607
2604
return args[i + 1];
2690
bool Item_func_case::fix_fields(Session *session, Item **ref)
2687
bool Item_func_case::fix_fields(THD *thd, Item **ref)
2693
2690
buff should match stack usage from
2694
2691
Item_func_case::val_int() -> Item_func_case::find_item()
2696
unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2
2697
+sizeof(double)*2+sizeof(int64_t)*2];
2698
bool res= Item_func::fix_fields(session, ref);
2693
uchar buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(int64_t)*2];
2694
bool res= Item_func::fix_fields(thd, ref);
2700
2696
Call check_stack_overrun after fix_fields to be sure that stack variable
2701
2697
is not optimized away
2703
if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
2699
if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
2704
2700
return true; // Fatal error flag is set!
2717
2713
void Item_func_case::agg_num_lengths(Item *arg)
2719
uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2715
uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2720
2716
arg->unsigned_flag) - arg->decimals;
2721
set_if_bigger(max_length, len);
2717
set_if_bigger(max_length, len);
2722
2718
set_if_bigger(decimals, arg->decimals);
2723
unsigned_flag= unsigned_flag && arg->unsigned_flag;
2719
unsigned_flag= unsigned_flag && arg->unsigned_flag;
2727
2723
void Item_func_case::fix_length_and_dec()
2731
uint32_t found_types= 0;
2732
if (!(agg= (Item**) memory::sql_alloc(sizeof(Item*)*(ncases+1))))
2727
uint found_types= 0;
2728
if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2736
2732
Aggregate all THEN and ELSE expression types
2737
2733
and collations when string result
2740
2736
for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2741
2737
agg[nagg]= args[nagg*2+1];
2743
2739
if (else_expr_num != -1)
2744
2740
agg[nagg++]= args[else_expr_num];
2746
2742
agg_result_type(&cached_result_type, agg, nagg);
2747
2743
if ((cached_result_type == STRING_RESULT) &&
2748
2744
agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2751
2747
cached_field_type= agg_field_type(agg, nagg);
2753
2749
Aggregate first expression and all THEN expression types
3026
3021
0 left argument is equal to the right argument.
3027
3022
1 left argument is greater than the right argument.
3029
int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
3030
in_int64_t::packed_int64_t *b)
3024
int cmp_int64_t(void *cmp_arg __attribute__((__unused__)),
3025
in_int64_t::packed_int64_t *a,
3026
in_int64_t::packed_int64_t *b)
3032
3028
if (a->unsigned_flag != b->unsigned_flag)
3035
One of the args is unsigned and is too big to fit into the
3031
One of the args is unsigned and is too big to fit into the
3036
3032
positive signed range. Report no match.
3038
3034
if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3039
3035
(b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
3040
3036
return a->unsigned_flag ? 1 : -1;
3042
Although the signedness differs both args can fit into the signed
3038
Although the signedness differs both args can fit into the signed
3043
3039
positive range. Make them signed and compare as usual.
3045
3041
return cmp_longs (a->val, b->val);
3047
3043
if (a->unsigned_flag)
3163
3153
delete [] (cmp_item_row*) base;
3166
unsigned char *in_row::get_value(Item *item)
3156
uchar *in_row::get_value(Item *item)
3168
3158
tmp.store_value(item);
3169
3159
if (item->is_null())
3171
return (unsigned char *)&tmp;
3161
return (uchar *)&tmp;
3174
void in_row::set(uint32_t pos, Item *item)
3164
void in_row::set(uint pos, Item *item)
3176
3166
((cmp_item_row*) base)[pos].store_value_by_template(&tmp, item);
3180
in_int64_t::in_int64_t(uint32_t elements)
3170
in_int64_t::in_int64_t(uint elements)
3181
3171
:in_vector(elements,sizeof(packed_int64_t),(qsort2_cmp) cmp_int64_t, 0)
3184
void in_int64_t::set(uint32_t pos,Item *item)
3174
void in_int64_t::set(uint pos,Item *item)
3186
3176
struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3188
3178
buff->val= item->val_int();
3189
3179
buff->unsigned_flag= item->unsigned_flag;
3192
unsigned char *in_int64_t::get_value(Item *item)
3182
uchar *in_int64_t::get_value(Item *item)
3194
3184
tmp.val= item->val_int();
3195
3185
if (item->null_value)
3197
3187
tmp.unsigned_flag= item->unsigned_flag;
3198
return (unsigned char*) &tmp;
3188
return (uchar*) &tmp;
3201
void in_datetime::set(uint32_t pos,Item *item)
3191
void in_datetime::set(uint pos,Item *item)
3203
3193
Item **tmp_item= &item;
3205
3195
struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3207
buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3197
buff->val= get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3208
3198
buff->unsigned_flag= 1L;
3211
unsigned char *in_datetime::get_value(Item *item)
3201
uchar *in_datetime::get_value(Item *item)
3214
3204
Item **tmp_item= lval_cache ? &lval_cache : &item;
3215
tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3205
tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
3216
3206
if (item->null_value)
3218
3208
tmp.unsigned_flag= 1L;
3219
return (unsigned char*) &tmp;
3209
return (uchar*) &tmp;
3222
in_double::in_double(uint32_t elements)
3212
in_double::in_double(uint elements)
3223
3213
:in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
3226
void in_double::set(uint32_t pos,Item *item)
3216
void in_double::set(uint pos,Item *item)
3228
3218
((double*) base)[pos]= item->val_real();
3231
unsigned char *in_double::get_value(Item *item)
3221
uchar *in_double::get_value(Item *item)
3233
3223
tmp= item->val_real();
3234
3224
if (item->null_value)
3236
return (unsigned char*) &tmp;
3225
return 0; /* purecov: inspected */
3226
return (uchar*) &tmp;
3240
in_decimal::in_decimal(uint32_t elements)
3230
in_decimal::in_decimal(uint elements)
3241
3231
:in_vector(elements, sizeof(my_decimal),(qsort2_cmp) cmp_decimal, 0)
3245
void in_decimal::set(uint32_t pos, Item *item)
3235
void in_decimal::set(uint pos, Item *item)
3247
3237
/* as far as 'item' is constant, we can store reference on my_decimal */
3248
3238
my_decimal *dec= ((my_decimal *)base) + pos;
3249
3239
dec->len= DECIMAL_BUFF_LENGTH;
3250
3240
dec->fix_buffer_pointer();
3251
3241
my_decimal *res= item->val_decimal(dec);
3252
/* if item->val_decimal() is evaluated to NULL then res == 0 */
3242
/* if item->val_decimal() is evaluated to NULL then res == 0 */
3253
3243
if (!item->null_value && res != dec)
3254
3244
my_decimal2decimal(res, dec);
3258
unsigned char *in_decimal::get_value(Item *item)
3248
uchar *in_decimal::get_value(Item *item)
3260
3250
my_decimal *result= item->val_decimal(&val);
3261
3251
if (item->null_value)
3263
return (unsigned char *)result;
3253
return (uchar *)result;
3267
3257
cmp_item* cmp_item::get_comparator(Item_result type,
3268
const CHARSET_INFO * const cs)
3270
3260
switch (type) {
3271
3261
case STRING_RESULT:
3272
3262
return new cmp_item_sort_string(cs);
3274
3263
case INT_RESULT:
3275
3264
return new cmp_item_int;
3277
3265
case REAL_RESULT:
3278
3266
return new cmp_item_real;
3280
3267
case ROW_RESULT:
3281
3268
return new cmp_item_row;
3283
3269
case DECIMAL_RESULT:
3284
3270
return new cmp_item_decimal;
3287
3275
return 0; // to satisfy compiler :)
3851
Item_cond::Item_cond(Session *session, Item_cond *item)
3852
:Item_bool_func(session, item),
3833
int64_t Item_func_bit_or::val_int()
3836
uint64_t arg1= (uint64_t) args[0]->val_int();
3837
if (args[0]->null_value)
3839
null_value=1; /* purecov: inspected */
3840
return 0; /* purecov: inspected */
3842
uint64_t arg2= (uint64_t) args[1]->val_int();
3843
if (args[1]->null_value)
3849
return (int64_t) (arg1 | arg2);
3853
int64_t Item_func_bit_and::val_int()
3856
uint64_t arg1= (uint64_t) args[0]->val_int();
3857
if (args[0]->null_value)
3859
null_value=1; /* purecov: inspected */
3860
return 0; /* purecov: inspected */
3862
uint64_t arg2= (uint64_t) args[1]->val_int();
3863
if (args[1]->null_value)
3865
null_value=1; /* purecov: inspected */
3866
return 0; /* purecov: inspected */
3869
return (int64_t) (arg1 & arg2);
3872
Item_cond::Item_cond(THD *thd, Item_cond *item)
3873
:Item_bool_func(thd, item),
3853
3874
abort_on_null(item->abort_on_null),
3854
3875
and_tables_cache(item->and_tables_cache)
3862
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
3883
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
3864
3885
List_iterator_fast<Item> li(item->list);
3865
3886
while (Item *it= li++)
3866
list.push_back(it->copy_andor_structure(session));
3887
list.push_back(it->copy_andor_structure(thd));
3871
Item_cond::fix_fields(Session *session, Item **)
3892
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((__unused__)))
3873
3894
assert(fixed == 0);
3874
3895
List_iterator<Item> li(list);
3876
void *orig_session_marker= session->session_marker;
3877
unsigned char buff[sizeof(char*)]; // Max local vars in function
3897
void *orig_thd_marker= thd->thd_marker;
3898
uchar buff[sizeof(char*)]; // Max local vars in function
3878
3899
not_null_tables_cache= used_tables_cache= 0;
3879
3900
const_item_cache= 1;
3881
3902
if (functype() == COND_OR_FUNC)
3882
session->session_marker= 0;
3884
3905
and_table_cache is the value that Item_cond_or() returns for
3885
3906
not_null_tables()
3887
3908
and_tables_cache= ~(table_map) 0;
3889
if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
3910
if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
3890
3911
return true; // Fatal error flag is set!
3892
3913
The following optimization reduces the depth of an AND-OR tree.
4050
4071
@param arg_t parameter to be passed to the transformer
4053
Item returned as the result of transformation of the root node
4074
Item returned as the result of transformation of the root node
4056
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4057
Item_transformer transformer, unsigned char *arg_t)
4077
Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
4078
Item_transformer transformer, uchar *arg_t)
4059
4080
if (!(this->*analyzer)(arg_p))
4062
4083
List_iterator<Item> li(list);
4064
4085
while ((item= li++))
4067
4088
The same parameter value of arg_p must be passed
4068
4089
to analyze any argument of the condition formula.
4070
unsigned char *arg_v= *arg_p;
4091
uchar *arg_v= *arg_p;
4071
4092
Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4072
4093
if (new_item && new_item != item)
4073
4094
li.replace(new_item);
4411
4430
my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4415
4434
if (escape_item->const_item())
4418
4436
/* If we are on execution stage */
4419
4437
String *escape_str= escape_item->val_str(&tmp_value1);
4420
4438
if (escape_str)
4422
escape= (char *)memory::sql_alloc(escape_str->length());
4423
strcpy(escape, escape_str->ptr());
4440
if (escape_used_in_parsing && (
4441
(((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
4442
escape_str->numchars() != 1) ||
4443
escape_str->numchars() > 1)))
4445
my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE");
4449
if (use_mb(cmp.cmp_collation.collation))
4451
CHARSET_INFO *cs= escape_str->charset();
4453
int rc= cs->cset->mb_wc(cs, &wc,
4454
(const uchar*) escape_str->ptr(),
4455
(const uchar*) escape_str->ptr() +
4456
escape_str->length());
4457
escape= (int) (rc > 0 ? wc : '\\');
4462
In the case of 8bit character set, we pass native
4463
code instead of Unicode code as "escape" argument.
4464
Convert to "cs" if charset of escape differs.
4466
CHARSET_INFO *cs= cmp.cmp_collation.collation;
4468
if (escape_str->needs_conversion(escape_str->length(),
4469
escape_str->charset(), cs, &unused))
4473
uint32 cnvlen= copy_and_convert(&ch, 1, cs, escape_str->ptr(),
4474
escape_str->length(),
4475
escape_str->charset(), &errors);
4476
escape= cnvlen ? ch : '\\';
4479
escape= *(escape_str->ptr());
4427
escape= (char *)memory::sql_alloc(1);
4428
strcpy(escape, "\\");
4432
4486
We could also do boyer-more for non-const items, but as we would have to
4433
4487
recompute the tables for each row it's not worth it.
4435
if (args[1]->const_item() && !use_strnxfrm(collation.collation))
4489
if (args[1]->const_item() && !use_strnxfrm(collation.collation) &&
4490
!(specialflag & SPECIAL_NO_NEW_FUNC))
4437
4492
String* res2 = args[1]->val_str(&tmp_value2);
4439
4494
return false; // Null argument
4441
4496
const size_t len = res2->length();
4442
4497
const char* first = res2->ptr();
4443
4498
const char* last = first + len - 1;
4501
4551
int *const splm1 = suff + plm1;
4502
const CHARSET_INFO * const cs= cmp.cmp_collation.collation;
4552
CHARSET_INFO *cs= cmp.cmp_collation.collation;
4504
4554
*splm1 = pattern_len;
4506
4556
if (!cs->sort_order)
4508
for (int i = pattern_len - 2; i >= 0; i--)
4559
for (i = pattern_len - 2; i >= 0; i--)
4510
4561
int tmp = *(splm1 + i - f);
4511
4562
if (g < i && tmp < i - g)
4518
while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
4567
g = i; // g = min(i, g)
4569
while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
4526
for (int i = pattern_len - 2; 0 <= i; --i)
4578
for (i = pattern_len - 2; 0 <= i; --i)
4528
4580
int tmp = *(splm1 + i - f);
4529
4581
if (g < i && tmp < i - g)
4537
likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4586
g = i; // g = min(i, g)
4589
likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
4673
4725
register int i = plm1;
4674
4726
while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j]))
4677
if (i == plm1 - shift)
4729
if (i == plm1 - shift)
4684
register const int v= plm1 - i;
4686
bcShift= bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
4687
shift= (turboShift > bcShift) ? turboShift : bcShift;
4688
shift= max(shift, bmGs[i]);
4735
register const int v = plm1 - i;
4737
bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
4738
shift = max(turboShift, bcShift);
4739
shift = max(shift, bmGs[i]);
4690
4740
if (shift == bmGs[i])
4691
u= (pattern_len - shift < v) ? pattern_len - shift : v;
4741
u = min(pattern_len - shift, v);
4694
if (turboShift < bcShift)
4695
shift= max(shift, u + 1);
4744
if (turboShift < bcShift)
4745
shift = max(shift, u + 1);
4791
4840
a IS NOT NULL -> a IS NULL.
4793
Item *Item_func_isnotnull::neg_transformer(Session *)
4842
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((__unused__)))
4795
4844
Item *item= new Item_func_isnull(args[0]);
4800
Item *Item_cond_and::neg_transformer(Session *session) /* NOT(a AND b AND ...) -> */
4849
Item *Item_cond_and::neg_transformer(THD *thd) /* NOT(a AND b AND ...) -> */
4801
4850
/* NOT a OR NOT b OR ... */
4803
neg_arguments(session);
4804
4853
Item *item= new Item_cond_or(list);
4809
Item *Item_cond_or::neg_transformer(Session *session) /* NOT(a OR b OR ...) -> */
4858
Item *Item_cond_or::neg_transformer(THD *thd) /* NOT(a OR b OR ...) -> */
4810
4859
/* NOT a AND NOT b AND ... */
4812
neg_arguments(session);
4813
4862
Item *item= new Item_cond_and(list);
4818
Item *Item_func_nop_all::neg_transformer(Session *)
4867
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((__unused__)))
4820
4869
/* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4821
4870
Item_func_not_all *new_item= new Item_func_not_all(args[0]);