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/function/bit.h"
33
#include "drizzled/check_stack_overrun.h"
36
static Eq_creator eq_creator;
37
static Ne_creator ne_creator;
38
static Gt_creator gt_creator;
39
static Lt_creator lt_creator;
40
static Ge_creator ge_creator;
41
static Le_creator le_creator;
43
static bool convert_constant_item(Session *, Item_field *, Item **);
29
45
static Item_result item_store_type(Item_result a, Item *item,
30
46
bool unsigned_flag)
80
96
The function checks that two expressions have compatible row signatures
81
97
i.e. that the number of columns they return are the same and that if they
82
are both row expressions then each component from the first expression has
98
are both row expressions then each component from the first expression has
83
99
a row signature compatible with the signature of the corresponding component
84
100
of the second expression.
140
156
of the first row expression has a compatible row signature with
141
157
the signature of the corresponding component of the second row
144
160
if (type[0] == ROW_RESULT && cmp_row_type(items[0], items[i]))
145
161
return 1; // error found: invalid usage of rows
204
220
for (i= 1; i < nitems ; i++)
206
if ((left_result == ROW_RESULT ||
222
if ((left_result == ROW_RESULT ||
207
223
items[i]->result_type() == ROW_RESULT) &&
208
224
cmp_row_type(items[0], items[i]))
210
found_types|= 1<< (uint)item_cmp_type(left_result,
226
found_types|= 1<< (uint32_t)item_cmp_type(left_result,
211
227
items[i]->result_type());
213
229
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
233
Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
239
const Eq_creator* Eq_creator::instance()
232
245
Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
234
247
return new Item_func_ne(a, b);
251
const Ne_creator* Ne_creator::instance()
238
257
Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
240
259
return new Item_func_gt(a, b);
263
const Gt_creator* Gt_creator::instance()
244
269
Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
246
271
return new Item_func_lt(a, b);
275
const Lt_creator* Lt_creator::instance()
250
281
Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
252
283
return new Item_func_ge(a, b);
287
const Ge_creator* Ge_creator::instance()
256
293
Item_bool_func2* Le_creator::create(Item *a, Item *b) const
258
295
return new Item_func_le(a, b);
298
const Le_creator* Le_creator::instance()
263
306
Most of these returns 0LL if false and 1LL if true and
361
404
also when comparing bigint to strings (in which case strings
362
405
are converted to bigints).
364
@param thd thread handle
407
@param session thread handle
365
408
@param field_item item will be converted using the type of this field
366
409
@param[in,out] item reference to the item to convert
378
421
1 Item was replaced with an integer version of the item
381
static bool convert_constant_item(THD *thd, Item_field *field_item,
424
static bool convert_constant_item(Session *session, Item_field *field_item,
384
427
Field *field= field_item->field;
387
430
if (!(*item)->with_subselect && (*item)->const_item())
389
ulong orig_sql_mode= thd->variables.sql_mode;
390
enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
432
ulong orig_sql_mode= session->variables.sql_mode;
433
enum_check_fields orig_count_cuted_fields= session->count_cuted_fields;
391
434
uint64_t orig_field_val= 0; /* original field value if valid */
393
436
/* For comparison purposes allow invalid dates like 2000-01-32 */
394
thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
437
session->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
395
438
MODE_INVALID_DATES;
396
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
439
session->count_cuted_fields= CHECK_FIELD_IGNORE;
399
442
Store the value of the field if it references an outer field because
406
449
Item *tmp= new Item_int_with_ref(field->val_int(), *item,
407
450
test(field->flags & UNSIGNED_FLAG));
409
thd->change_item_tree(item, tmp);
452
session->change_item_tree(item, tmp);
410
453
result= 1; // Item was replaced
412
455
/* Restore the original field value. */
416
459
/* orig_field_val must be a valid value that can be restored back. */
419
thd->variables.sql_mode= orig_sql_mode;
420
thd->count_cuted_fields= orig_count_cuted_fields;
462
session->variables.sql_mode= orig_sql_mode;
463
session->count_cuted_fields= orig_count_cuted_fields;
435
478
if (!args[0] || !args[1])
439
482
We allow to convert to Unicode character sets in some cases.
440
483
The conditions when conversion is possible are:
441
484
- arguments A and B have different charsets
442
485
- A wins according to coercibility rules
443
486
- character set of A is superset for character set of B
445
488
If all of the above is true, then it's possible to convert
446
489
B into the character set of A, and then compare according
447
490
to the collation of A.
451
494
DTCollation coll;
452
495
if (args[0]->result_type() == STRING_RESULT &&
453
496
args[1]->result_type() == STRING_RESULT &&
454
497
agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1))
457
500
args[0]->cmp_context= args[1]->cmp_context=
458
501
item_cmp_type(args[0]->result_type(), args[1]->result_type());
459
502
// Make a special case of compare with fields to get nicer DATE comparisons
510
session= current_session;
511
Item_field *field_item= NULL;
469
513
if (args[0]->real_item()->type() == FIELD_ITEM)
471
Item_field *field_item= (Item_field*) (args[0]->real_item());
515
field_item= static_cast<Item_field*>(args[0]->real_item());
472
516
if (field_item->field->can_be_compared_as_int64_t() &&
473
517
!(field_item->is_datetime() && args[1]->result_type() == STRING_RESULT))
475
if (convert_constant_item(thd, field_item, &args[1]))
519
if (convert_constant_item(session, field_item, &args[1]))
477
521
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
478
522
INT_RESULT); // Works for all types.
484
528
if (args[1]->real_item()->type() == FIELD_ITEM)
486
Item_field *field_item= (Item_field*) (args[1]->real_item());
530
field_item= static_cast<Item_field*>(args[1]->real_item());
487
531
if (field_item->field->can_be_compared_as_int64_t() &&
488
532
!(field_item->is_datetime() &&
489
533
args[0]->result_type() == STRING_RESULT))
491
if (convert_constant_item(thd, field_item, &args[0]))
535
if (convert_constant_item(session, field_item, &args[0]))
493
537
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
494
538
INT_RESULT); // Works for all types.
536
580
We must set cmp_charset here as we may be called from for an automatic
537
581
generated item, like in natural join
539
if (cmp_collation.set((*a)->collation, (*b)->collation) ||
583
if (cmp_collation.set((*a)->collation, (*b)->collation) ||
540
584
cmp_collation.derivation == DERIVATION_NONE)
542
586
my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
609
653
@brief Convert date provided in a string to the int representation.
611
@param[in] thd thread handle
655
@param[in] session thread handle
612
656
@param[in] str a string to convert
613
657
@param[in] warn_type type of the timestamp for issuing the warning
614
658
@param[in] warn_name field name for issuing the warning
631
get_date_from_str(THD *thd, String *str, enum enum_drizzle_timestamp_type warn_type,
675
get_date_from_str(Session *session, String *str, enum enum_drizzle_timestamp_type warn_type,
632
676
char *warn_name, bool *error_arg)
634
678
uint64_t value= 0;
639
683
ret= str_to_datetime(str->ptr(), str->length(), &l_time,
640
684
(TIME_FUZZY_DATE | MODE_INVALID_DATES |
641
(thd->variables.sql_mode & MODE_NO_ZERO_DATE)),
685
(session->variables.sql_mode & MODE_NO_ZERO_DATE)),
644
688
if (ret == DRIZZLE_TIMESTAMP_DATETIME || ret == DRIZZLE_TIMESTAMP_DATE)
660
make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
704
make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
661
705
str->ptr(), str->length(),
662
706
warn_type, warn_name);
682
726
int result and the other item (b or a) is an item with string result.
683
727
If the second item is a constant one then it's checked to be
684
728
convertible to the DATE/DATETIME type. If the constant can't be
685
converted to a DATE/DATETIME then the compare_datetime() comparator
686
isn't used and the warning about wrong DATE/DATETIME value is issued.
729
converted to a DATE/DATETIME then an error is issued back to the Session.
687
730
In all other cases (date-[int|real|decimal]/[int|real|decimal]-date)
688
731
the comparison is handled by other comparators.
689
733
If the datetime comparator can be used and one the operands of the
690
734
comparison is a string constant that was successfully converted to a
691
735
DATE/DATETIME type then the result of the conversion is returned in the
734
778
(str_arg->type() != Item::FUNC_ITEM ||
735
779
((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
737
THD *thd= current_thd;
782
* OK, we are here if we've got a date field (or something which can be
783
* compared as a date field) on one side of the equation, and a constant
784
* string on the other side. In this case, we must verify that the constant
785
* string expression can indeed be evaluated as a datetime. If it cannot,
786
* we throw an error here and stop processsing. Bad data should ALWAYS
787
* produce an error, and no implicit conversion or truncation should take place.
789
* If the conversion to a DateTime temporal is successful, then we convert
790
* the Temporal instance to a uint64_t for the comparison operator, which
791
* compares date(times) using int64_t semantics.
795
* Does a uint64_t conversion really have to happen here? Fields return int64_t
796
* from val_int(), not uint64_t...
740
String tmp, *str_val= 0;
741
enum enum_drizzle_timestamp_type t_type= (date_arg->field_type() == DRIZZLE_TYPE_NEWDATE ?
742
DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME);
801
/* DateTime used to pick up as many string conversion possibilities as possible. */
802
drizzled::DateTime temporal;
744
804
str_val= str_arg->val_str(&tmp);
745
if (str_arg->null_value)
746
return CMP_DATE_DFLT;
747
value= get_date_from_str(thd, str_val, t_type, date_arg->name, &error);
749
return CMP_DATE_DFLT;
808
* If we are here, it is most likely due to the comparison item
809
* being a NULL. Although this is incorrect (SQL demands that the term IS NULL
810
* be used, not = NULL since no item can be equal to NULL).
812
* So, return gracefully.
814
return CMP_DATE_DFLT;
816
if (! temporal.from_string(str_val->c_ptr(), str_val->length()))
818
/* Chuck an error. Bad datetime input. */
819
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), str_val->c_ptr());
820
return CMP_DATE_DFLT; /* :( What else can I return... */
823
/* String conversion was good. Convert to an integer for comparison purposes. */
825
temporal.to_int64_t(&int_value);
826
value= (uint64_t) int_value;
751
829
*const_value= value;
784
get_time_value(THD *thd __attribute__((unused)),
862
get_time_value(Session *,
785
863
Item ***item_arg, Item **cache_arg,
786
Item *warn_item __attribute__((unused)),
864
Item *, bool *is_null)
790
867
Item *item= **item_arg;
830
907
if ((cmp_type= can_compare_as_dates(*a, *b, &const_value)))
909
session= current_session;
833
910
owner= owner_arg;
834
911
a_type= (*a)->field_type();
835
912
b_type= (*b)->field_type();
859
936
get_value_func= &get_datetime_value;
862
else if (type == STRING_RESULT && (*a)->field_type() == DRIZZLE_TYPE_TIME &&
863
(*b)->field_type() == DRIZZLE_TYPE_TIME)
865
/* Compare TIME values as integers. */
870
is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC);
871
func= &Arg_comparator::compare_datetime;
872
get_value_func= &get_time_value;
876
940
return set_compare_func(owner_arg, type);
927
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
991
get_datetime_value(Session *session, Item ***item_arg, Item **cache_arg,
928
992
Item *warn_item, bool *is_null)
930
994
uint64_t value= 0;
942
1006
compare it with 100000000L - any DATE value should be less than it.
943
1007
Don't shift cached DATETIME values up for the second time.
945
if (f_type == DRIZZLE_TYPE_NEWDATE ||
1009
if (f_type == DRIZZLE_TYPE_DATE ||
946
1010
(f_type != DRIZZLE_TYPE_DATETIME && value < 100000000L))
947
1011
value*= 1000000L;
965
1029
enum_field_types f_type= warn_item->field_type();
966
1030
enum enum_drizzle_timestamp_type t_type= f_type ==
967
DRIZZLE_TYPE_NEWDATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
968
value= get_date_from_str(thd, str, t_type, warn_item->name, &error);
1031
DRIZZLE_TYPE_DATE ? DRIZZLE_TIMESTAMP_DATE : DRIZZLE_TIMESTAMP_DATETIME;
1032
value= get_date_from_str(session, str, t_type, warn_item->name, &error);
970
1034
If str did not contain a valid date according to the current
971
1035
SQL_MODE, get_date_from_str() has already thrown a warning,
1017
1081
uint64_t a_value, b_value;
1019
1083
/* Get DATE/DATETIME/TIME value of the 'a' item. */
1020
a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null);
1084
a_value= (*get_value_func)(session, &a, &a_cache, *b, &is_null);
1021
1085
if (!is_nulls_eq && is_null)
1028
1092
/* Get DATE/DATETIME/TIME value of the 'b' item. */
1029
b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null);
1093
b_value= (*get_value_func)(session, &b, &b_cache, *a, &is_null);
1446
bool Item_in_optimizer::fix_left(THD *thd, Item **ref __attribute__((unused)))
1510
bool Item_in_optimizer::fix_left(Session *session, Item **)
1448
if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
1512
if ((!args[0]->fixed && args[0]->fix_fields(session, args)) ||
1449
1513
(!cache && !(cache= Item_cache::get_cache(args[0]))))
1480
bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
1544
bool Item_in_optimizer::fix_fields(Session *session, Item **ref)
1482
1546
assert(fixed == 0);
1483
if (fix_left(thd, ref))
1547
if (fix_left(session, ref))
1485
1549
if (args[0]->maybe_null)
1488
if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
1552
if (!args[1]->fixed && args[1]->fix_fields(session, args+1))
1490
1554
Item_in_subselect * sub= (Item_in_subselect *)args[1];
1491
1555
if (args[0]->cols() != sub->engine->cols())
1537
1601
We disable the predicates we've pushed down into subselect, run the
1538
1602
subselect and see if it has produced any rows.
1540
Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
1604
Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
1541
1605
if (cache->cols() == 1)
1543
1607
item_subs->set_cond_guard_var(0, false);
1558
1622
if (cache->element_index(i)->null_value)
1559
1623
item_subs->set_cond_guard_var(i, false);
1562
1626
(void) args[1]->val_bool_result();
1563
1627
result_for_null_param= null_value= !item_subs->engine->no_rows();
1565
1629
/* Turn all predicates back on */
1566
1630
for (i= 0; i < ncols; i++)
1567
1631
item_subs->set_cond_guard_var(i, true);
1635
THD::change_item_tree() should be called only if the tree was
1699
Session::change_item_tree() should be called only if the tree was
1636
1700
really transformed, i.e. when a new item has been created.
1637
1701
Otherwise we'll be allocating a lot of unnecessary memory for
1638
1702
change records at each execution.
1640
1704
if ((*args) != new_item)
1641
current_thd->change_item_tree(args, new_item);
1705
current_session->change_item_tree(args, new_item);
1644
1708
Transform the right IN operand which should be an Item_in_subselect or a
1926
1990
The function saves in ref the pointer to the item or to a newly created
1927
1991
item that is considered as a replacement for the original one.
1929
@param thd reference to the global context of the query thread
1993
@param session reference to the global context of the query thread
1930
1994
@param ref pointer to Item* variable where pointer to resulting "fixed"
1931
1995
item is to be assigned
1949
bool Item_func_between::fix_fields(THD *thd, Item **ref)
2013
bool Item_func_between::fix_fields(Session *session, Item **ref)
1951
if (Item_func_opt_neg::fix_fields(thd, ref))
2015
if (Item_func_opt_neg::fix_fields(session, ref))
1954
thd->lex->current_select->between_count++;
2018
session->lex->current_select->between_count++;
1956
2020
/* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
1957
2021
if (pred_level && !negated)
2014
2074
ge_cmp.set_datetime_cmp_func(args, args + 1);
2015
2075
le_cmp.set_datetime_cmp_func(args, args + 2);
2017
else if (time_items_found == 3)
2019
/* Compare TIME items as integers. */
2020
cmp_type= INT_RESULT;
2022
2077
else if (args[0]->real_item()->type() == FIELD_ITEM &&
2023
thd->lex->sql_command != SQLCOM_SHOW_CREATE)
2078
session->lex->sql_command != SQLCOM_SHOW_CREATE)
2025
2080
Item_field *field_item= (Item_field*) (args[0]->real_item());
2026
2081
if (field_item->field->can_be_compared_as_int64_t())
2029
2084
The following can't be recoded with || as convert_constant_item
2030
2085
changes the argument
2032
if (convert_constant_item(thd, field_item, &args[1]))
2087
if (convert_constant_item(session, field_item, &args[1]))
2033
2088
cmp_type=INT_RESULT; // Works for all types.
2034
if (convert_constant_item(thd, field_item, &args[2]))
2089
if (convert_constant_item(session, field_item, &args[2]))
2035
2090
cmp_type=INT_RESULT; // Works for all types.
2169
2224
decimals= cmax(args[0]->decimals, args[1]->decimals);
2170
2225
unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
2172
if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
2227
if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
2174
2229
int len0= args[0]->max_length - args[0]->decimals
2175
2230
- (args[0]->unsigned_flag ? 0 : 1);
2293
2348
The function saves in ref the pointer to the item or to a newly created
2294
2349
item that is considered as a replacement for the original one.
2296
@param thd reference to the global context of the query thread
2351
@param session reference to the global context of the query thread
2297
2352
@param ref pointer to Item* variable where pointer to resulting "fixed"
2298
2353
item is to be assigned
2315
Item_func_if::fix_fields(THD *thd, Item **ref)
2370
Item_func_if::fix_fields(Session *session, Item **ref)
2317
2372
assert(fixed == 0);
2318
2373
args[0]->top_level_item();
2320
if (Item_func::fix_fields(thd, ref))
2375
if (Item_func::fix_fields(session, ref))
2323
2378
not_null_tables_cache= (args[1]->not_null_tables() &
2574
2629
cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
2575
2630
assert(cmp_type != ROW_RESULT);
2576
assert(cmp_items[(uint)cmp_type]);
2577
if (!(value_added_map & (1<<(uint)cmp_type)))
2631
assert(cmp_items[(uint32_t)cmp_type]);
2632
if (!(value_added_map & (1<<(uint32_t)cmp_type)))
2579
cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
2634
cmp_items[(uint32_t)cmp_type]->store_value(args[first_expr_num]);
2580
2635
if ((null_value=args[first_expr_num]->null_value))
2581
2636
return else_expr_num != -1 ? args[else_expr_num] : 0;
2582
value_added_map|= 1<<(uint)cmp_type;
2637
value_added_map|= 1<<(uint32_t)cmp_type;
2584
if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2639
if (!cmp_items[(uint32_t)cmp_type]->cmp(args[i]) && !args[i]->null_value)
2585
2640
return args[i + 1];
2668
bool Item_func_case::fix_fields(THD *thd, Item **ref)
2723
bool Item_func_case::fix_fields(Session *session, Item **ref)
2671
2726
buff should match stack usage from
2672
2727
Item_func_case::val_int() -> Item_func_case::find_item()
2674
unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2+sizeof(double)*2+sizeof(int64_t)*2];
2675
bool res= Item_func::fix_fields(thd, ref);
2729
unsigned char buff[MAX_FIELD_WIDTH*2+sizeof(String)*2+sizeof(String*)*2
2730
+sizeof(double)*2+sizeof(int64_t)*2];
2731
bool res= Item_func::fix_fields(session, ref);
2677
2733
Call check_stack_overrun after fix_fields to be sure that stack variable
2678
2734
is not optimized away
2680
if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
2736
if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
2681
2737
return true; // Fatal error flag is set!
2696
2752
uint32_t len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
2697
2753
arg->unsigned_flag) - arg->decimals;
2698
set_if_bigger(max_length, len);
2754
set_if_bigger(max_length, len);
2699
2755
set_if_bigger(decimals, arg->decimals);
2700
unsigned_flag= unsigned_flag && arg->unsigned_flag;
2756
unsigned_flag= unsigned_flag && arg->unsigned_flag;
2708
2764
uint32_t found_types= 0;
2709
2765
if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
2713
2769
Aggregate all THEN and ELSE expression types
2714
2770
and collations when string result
2717
2773
for (nagg= 0 ; nagg < ncases/2 ; nagg++)
2718
2774
agg[nagg]= args[nagg*2+1];
2720
2776
if (else_expr_num != -1)
2721
2777
agg[nagg++]= args[else_expr_num];
2723
2779
agg_result_type(&cached_result_type, agg, nagg);
2724
2780
if ((cached_result_type == STRING_RESULT) &&
2725
2781
agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
2728
2784
cached_field_type= agg_field_type(agg, nagg);
2730
2786
Aggregate first expression and all THEN expression types
2742
2798
if (!(found_types= collect_cmp_types(agg, nagg)))
2745
for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
2801
for (i= 0; i <= (uint32_t)DECIMAL_RESULT; i++)
2747
2803
if (found_types & (1 << i) && !cmp_items[i])
2776
2832
for (uint32_t i= 0; i < ncases; i+= 2)
2777
2833
agg_num_lengths(args[i + 1]);
2778
if (else_expr_num != -1)
2834
if (else_expr_num != -1)
2779
2835
agg_num_lengths(args[else_expr_num]);
2780
2836
max_length= my_decimal_precision_to_length(max_length + decimals, decimals,
2781
2837
unsigned_flag);
2789
2845
for (uint32_t i=0 ; i < ncases ; i+=2)
2790
2846
set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
2792
if (else_expr_num != -1)
2848
if (else_expr_num != -1)
2793
2849
set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
2794
2850
return cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
3002
3058
0 left argument is equal to the right argument.
3003
3059
1 left argument is greater than the right argument.
3005
int cmp_int64_t(void *cmp_arg __attribute__((unused)),
3006
in_int64_t::packed_int64_t *a,
3007
in_int64_t::packed_int64_t *b)
3061
int cmp_int64_t(void *, in_int64_t::packed_int64_t *a,
3062
in_int64_t::packed_int64_t *b)
3009
3064
if (a->unsigned_flag != b->unsigned_flag)
3012
One of the args is unsigned and is too big to fit into the
3067
One of the args is unsigned and is too big to fit into the
3013
3068
positive signed range. Report no match.
3015
3070
if ((a->unsigned_flag && ((uint64_t) a->val) > (uint64_t) INT64_MAX) ||
3016
3071
(b->unsigned_flag && ((uint64_t) b->val) > (uint64_t) INT64_MAX))
3017
3072
return a->unsigned_flag ? 1 : -1;
3019
Although the signedness differs both args can fit into the signed
3074
Although the signedness differs both args can fit into the signed
3020
3075
positive range. Make them signed and compare as usual.
3022
3077
return cmp_longs (a->val, b->val);
3024
3079
if (a->unsigned_flag)
3027
3082
return cmp_longs (a->val, b->val);
3030
static int cmp_double(void *cmp_arg __attribute__((unused)), double *a,double *b)
3085
static int cmp_double(void *, double *a, double *b)
3032
3087
return *a < *b ? -1 : *a == *b ? 0 : 1;
3035
static int cmp_row(void *cmp_arg __attribute__((unused)), cmp_item_row *a, cmp_item_row *b)
3090
static int cmp_row(void *, cmp_item_row *a, cmp_item_row *b)
3037
3092
return a->compare(b);
3041
static int cmp_decimal(void *cmp_arg __attribute__((unused)), my_decimal *a, my_decimal *b)
3096
static int cmp_decimal(void *, my_decimal *a, my_decimal *b)
3044
3099
We need call of fixing buffer pointer, because fast sort just copy
3115
3170
return (unsigned char*) item->val_str(&tmp);
3118
in_row::in_row(uint32_t elements, Item * item __attribute__((unused)))
3173
in_row::in_row(uint32_t elements, Item *)
3120
3175
base= (char*) new cmp_item_row[count= elements];
3121
3176
size= sizeof(cmp_item_row);
3155
3210
void in_int64_t::set(uint32_t pos,Item *item)
3157
3212
struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3159
3214
buff->val= item->val_int();
3160
3215
buff->unsigned_flag= item->unsigned_flag;
3176
3231
struct packed_int64_t *buff= &((packed_int64_t*) base)[pos];
3178
buff->val= get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3233
buff->val= get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3179
3234
buff->unsigned_flag= 1L;
3185
3240
Item **tmp_item= lval_cache ? &lval_cache : &item;
3186
tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
3241
tmp.val= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3187
3242
if (item->null_value)
3189
3244
tmp.unsigned_flag= 1L;
3220
3275
dec->len= DECIMAL_BUFF_LENGTH;
3221
3276
dec->fix_buffer_pointer();
3222
3277
my_decimal *res= item->val_decimal(dec);
3223
/* if item->val_decimal() is evaluated to NULL then res == 0 */
3278
/* if item->val_decimal() is evaluated to NULL then res == 0 */
3224
3279
if (!item->null_value && res != dec)
3225
3280
my_decimal2decimal(res, dec);
3420
3475
Item **tmp_item= lval_cache ? &lval_cache : &item;
3421
value= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
3476
value= get_datetime_value(session, &tmp_item, &lval_cache, warn_item, &is_null);
3428
3483
Item **tmp_item= &arg;
3429
3484
return value !=
3430
get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
3485
get_datetime_value(session, &tmp_item, 0, warn_item, &is_null);
3464
3519
The function saves in ref the pointer to the item or to a newly created
3465
3520
item that is considered as a replacement for the original one.
3467
@param thd reference to the global context of the query thread
3522
@param session reference to the global context of the query thread
3468
3523
@param ref pointer to Item* variable where pointer to resulting "fixed"
3469
3524
item is to be assigned
3488
Item_func_in::fix_fields(THD *thd, Item **ref)
3543
Item_func_in::fix_fields(Session *session, Item **ref)
3490
3545
Item **arg, **arg_end;
3492
if (Item_func_opt_neg::fix_fields(thd, ref))
3547
if (Item_func_opt_neg::fix_fields(session, ref))
3495
3550
/* not_null_tables_cache == union(T1(e),union(T1(ei))) */
3528
3583
left_result_type= args[0]->result_type();
3529
3584
if (!(found_types= collect_cmp_types(args, arg_count)))
3532
3587
for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
3534
3589
if (!arg[0]->const_item())
3549
3604
if (type_cnt == 1)
3551
if (cmp_type == STRING_RESULT &&
3606
if (cmp_type == STRING_RESULT &&
3552
3607
agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1))
3554
3609
arg_types_compatible= true;
3579
3634
/* All DATE/DATETIME fields/functions has the STRING result type. */
3580
3635
if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
3582
uint32_t col, cols= args[0]->cols();
3637
uint32_t col, num_cols= args[0]->cols();
3584
for (col= 0; col < cols; col++)
3639
for (col= 0; col < num_cols; col++)
3586
3641
bool skip_column= false;
3651
3706
IN must compare INT columns and constants as int values (the same
3652
3707
way as equality does).
3653
So we must check here if the column on the left and all the constant
3654
values on the right can be compared as integers and adjust the
3708
So we must check here if the column on the left and all the constant
3709
values on the right can be compared as integers and adjust the
3655
3710
comparison type accordingly.
3657
3712
if (args[0]->real_item()->type() == FIELD_ITEM &&
3658
thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
3713
session->lex->sql_command != SQLCOM_SHOW_CREATE &&
3659
3714
cmp_type != INT_RESULT)
3661
3716
Item_field *field_item= (Item_field*) (args[0]->real_item());
3664
3719
bool all_converted= true;
3665
3720
for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
3667
if (!convert_constant_item (thd, field_item, &arg[0]))
3722
if (!convert_constant_item (session, field_item, &arg[0]))
3668
3723
all_converted= false;
3670
3725
if (all_converted)
3674
3729
switch (cmp_type) {
3675
3730
case STRING_RESULT:
3676
array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
3731
array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
3677
3732
cmp_collation.collation);
3679
3734
case INT_RESULT:
3701
if (array && !(thd->is_fatal_error)) // If not EOM
3756
if (array && !(session->is_fatal_error)) // If not EOM
3704
for (uint32_t i=1 ; i < arg_count ; i++)
3759
for (uint32_t arg_num=1 ; arg_num < arg_count ; arg_num++)
3706
array->set(j,args[i]);
3707
if (!args[i]->null_value) // Skip NULL values
3761
array->set(j,args[arg_num]);
3762
if (!args[arg_num]->null_value) // Skip NULL values
3791
3846
for (uint32_t i= 1 ; i < arg_count ; i++)
3793
3848
Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
3794
in_item= cmp_items[(uint)cmp_type];
3849
in_item= cmp_items[(uint32_t)cmp_type];
3795
3850
assert(in_item);
3796
if (!(value_added_map & (1 << (uint)cmp_type)))
3851
if (!(value_added_map & (1 << (uint32_t)cmp_type)))
3798
3853
in_item->store_value(args[0]);
3799
3854
if ((null_value=args[0]->null_value))
3802
value_added_map|= 1 << (uint)cmp_type;
3857
value_added_map|= 1 << (uint32_t)cmp_type;
3804
3859
if (!in_item->cmp(args[i]) && !args[i]->null_value)
3805
3860
return (int64_t) (!negated);
3850
3905
return (int64_t) (arg1 & arg2);
3853
Item_cond::Item_cond(THD *thd, Item_cond *item)
3854
:Item_bool_func(thd, item),
3908
Item_cond::Item_cond(Session *session, Item_cond *item)
3909
:Item_bool_func(session, item),
3855
3910
abort_on_null(item->abort_on_null),
3856
3911
and_tables_cache(item->and_tables_cache)
3864
void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
3919
void Item_cond::copy_andor_arguments(Session *session, Item_cond *item)
3866
3921
List_iterator_fast<Item> li(item->list);
3867
3922
while (Item *it= li++)
3868
list.push_back(it->copy_andor_structure(thd));
3923
list.push_back(it->copy_andor_structure(session));
3873
Item_cond::fix_fields(THD *thd, Item **ref __attribute__((unused)))
3928
Item_cond::fix_fields(Session *session, Item **)
3875
3930
assert(fixed == 0);
3876
3931
List_iterator<Item> li(list);
3878
void *orig_thd_marker= thd->thd_marker;
3933
void *orig_session_marker= session->session_marker;
3879
3934
unsigned char buff[sizeof(char*)]; // Max local vars in function
3880
3935
not_null_tables_cache= used_tables_cache= 0;
3881
3936
const_item_cache= 1;
3883
3938
if (functype() == COND_OR_FUNC)
3939
session->session_marker= 0;
3886
3941
and_table_cache is the value that Item_cond_or() returns for
3887
3942
not_null_tables()
3889
3944
and_tables_cache= ~(table_map) 0;
3891
if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
3946
if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
3892
3947
return true; // Fatal error flag is set!
3894
3949
The following optimization reduces the depth of an AND-OR tree.
3922
3977
// item can be substituted in fix_fields
3923
3978
if ((!item->fixed &&
3924
item->fix_fields(thd, li.ref())) ||
3979
item->fix_fields(session, li.ref())) ||
3925
3980
(item= *li.ref())->check_cols(1))
3926
3981
return true; /* purecov: inspected */
3927
3982
used_tables_cache|= item->used_tables();
3933
3988
not_null_tables_cache|= tmp_table_map;
3934
3989
and_tables_cache&= tmp_table_map;
3935
3990
const_item_cache= false;
3937
3992
with_sum_func= with_sum_func || item->with_sum_func;
3938
3993
with_subselect|= item->with_subselect;
3939
3994
if (item->maybe_null)
3942
thd->lex->current_select->cond_count+= list.elements;
3943
thd->thd_marker= orig_thd_marker;
3997
session->lex->current_select->cond_count+= list.elements;
3998
session->session_marker= orig_session_marker;
3944
3999
fix_length_and_dec();
3950
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref __attribute__((unused)))
4005
void Item_cond::fix_after_pullout(Select_Lex *new_parent, Item **)
3952
4007
List_iterator<Item> li(list);
3994
4049
Transform an Item_cond object with a transformer callback function.
3996
4051
The function recursively applies the transform method to each
3997
4052
member item of the condition list.
3998
4053
If the call of the method for a member item returns a new item
3999
4054
the old item is substituted for a new one.
4000
4055
After this the transformer is applied to the root node
4001
of the Item_cond object.
4056
of the Item_cond object.
4003
4058
@param transformer the transformer callback function to be applied to
4004
4059
the nodes of the tree of the object
4005
4060
@param arg parameter to be passed to the transformer
4008
Item returned as the result of transformation of the root node
4063
Item returned as the result of transformation of the root node
4011
4066
Item *Item_cond::transform(Item_transformer transformer, unsigned char *arg)
4022
THD::change_item_tree() should be called only if the tree was
4077
Session::change_item_tree() should be called only if the tree was
4023
4078
really transformed, i.e. when a new item has been created.
4024
4079
Otherwise we'll be allocating a lot of unnecessary memory for
4025
4080
change records at each execution.
4027
4082
if (new_item != item)
4028
current_thd->change_item_tree(li.ref(), new_item);
4083
current_session->change_item_tree(li.ref(), new_item);
4030
4085
return Item_func::transform(transformer, arg);
4042
4097
If the call of the method for a member item returns a new item
4043
4098
the old item is substituted for a new one.
4044
4099
After this the transformer is applied to the root node
4045
of the Item_cond object.
4100
of the Item_cond object.
4047
4102
@param analyzer the analyzer callback function to be applied to the
4048
4103
nodes of the tree of the object
4049
4104
@param[in,out] arg_p parameter to be passed to the analyzer
4052
4107
@param arg_t parameter to be passed to the transformer
4055
Item returned as the result of transformation of the root node
4110
Item returned as the result of transformation of the root node
4058
4113
Item *Item_cond::compile(Item_analyzer analyzer, unsigned char **arg_p,
4061
4116
if (!(this->*analyzer)(arg_p))
4064
4119
List_iterator<Item> li(list);
4066
4121
while ((item= li++))
4069
4124
The same parameter value of arg_p must be passed
4070
4125
to analyze any argument of the condition formula.
4072
4127
unsigned char *arg_v= *arg_p;
4073
4128
Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
4074
4129
if (new_item && new_item != item)
4109
4164
(Calculation done by update_sum_func() and copy_sum_funcs() in
4112
@param thd Thread handler
4167
@param session Thread handler
4113
4168
@param ref_pointer_array Pointer to array of reference fields
4114
4169
@param fields All fields in select
4118
4173
that have or refer (HAVING) to a SUM expression.
4121
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
4176
void Item_cond::split_sum_func(Session *session, Item **ref_pointer_array,
4122
4177
List<Item> &fields)
4124
4179
List_iterator<Item> li(list);
4126
4181
while ((item= li++))
4127
item->split_sum_func2(thd, ref_pointer_array, fields, li.ref(), true);
4182
item->split_sum_func(session, ref_pointer_array,
4183
fields, li.ref(), true);
4172
void Item_cond::neg_arguments(THD *thd)
4228
void Item_cond::neg_arguments(Session *session)
4174
4230
List_iterator<Item> li(list);
4176
4232
while ((item= li++)) /* Apply not transformation to the arguments */
4178
Item *new_item= item->neg_transformer(thd);
4234
Item *new_item= item->neg_transformer(session);
4181
4237
if (!(new_item= new Item_func_not(item)))
4402
bool Item_func_like::fix_fields(THD *thd, Item **ref)
4458
bool Item_func_like::fix_fields(Session *session, Item **ref)
4404
4460
assert(fixed == 0);
4405
if (Item_bool_func2::fix_fields(thd, ref) ||
4406
escape_item->fix_fields(thd, &escape_item))
4461
if (Item_bool_func2::fix_fields(session, ref) ||
4462
escape_item->fix_fields(session, &escape_item))
4409
4465
if (!escape_item->const_during_execution())
4464
4520
We could also do boyer-more for non-const items, but as we would have to
4465
4521
recompute the tables for each row it's not worth it.
4467
if (args[1]->const_item() && !use_strnxfrm(collation.collation))
4523
if (args[1]->const_item() && !use_strnxfrm(collation.collation))
4469
4525
String* res2 = args[1]->val_str(&tmp_value2);
4471
4527
return false; // Null argument
4473
4529
const size_t len = res2->length();
4474
4530
const char* first = res2->ptr();
4475
4531
const char* last = first + len - 1;
4634
4690
if (!cs->sort_order)
4636
4692
for (j = 0; j < plm1; j++)
4637
bmBc[(uint) (unsigned char) pattern[j]] = plm1 - j;
4693
bmBc[(uint32_t) (unsigned char) pattern[j]] = plm1 - j;
4641
4697
for (j = 0; j < plm1; j++)
4642
bmBc[(uint) likeconv(cs,pattern[j])] = plm1 - j;
4698
bmBc[(uint32_t) likeconv(cs,pattern[j])] = plm1 - j;
4681
4737
register const int v = plm1 - i;
4682
4738
turboShift = u - v;
4683
bcShift = bmBc[(uint) (unsigned char) text[i + j]] - plm1 + i;
4739
bcShift = bmBc[(uint32_t) (unsigned char) text[i + j]] - plm1 + i;
4684
4740
shift = (turboShift > bcShift) ? turboShift : bcShift;
4685
4741
shift = (shift > bmGs[i]) ? shift : bmGs[i];
4686
4742
if (shift == bmGs[i])
4712
4768
register const int v = plm1 - i;
4713
4769
turboShift = u - v;
4714
bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
4770
bcShift = bmBc[(uint32_t) likeconv(cs, text[i + j])] - plm1 + i;
4715
4771
shift = (turboShift > bcShift) ? turboShift : bcShift;
4716
4772
shift = cmax(shift, bmGs[i]);
4717
4773
if (shift == bmGs[i])
4783
4839
IS NOT NULL(a) -> IS NULL(a)
4786
@param thd thread handler
4842
@param session thread handler
4790
4846
NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
4793
Item *Item_func_not::neg_transformer(THD *thd __attribute__((unused))) /* NOT(x) -> x */
4849
Item *Item_func_not::neg_transformer(Session *) /* NOT(x) -> x */
4795
4851
return args[0];
4799
Item *Item_bool_rowready_func2::neg_transformer(THD *thd __attribute__((unused)))
4855
Item *Item_bool_rowready_func2::neg_transformer(Session *)
4801
4857
Item *item= negated_item();
4817
4873
a IS NOT NULL -> a IS NULL.
4819
Item *Item_func_isnotnull::neg_transformer(THD *thd __attribute__((unused)))
4875
Item *Item_func_isnotnull::neg_transformer(Session *)
4821
4877
Item *item= new Item_func_isnull(args[0]);
4826
Item *Item_cond_and::neg_transformer(THD *thd) /* NOT(a AND b AND ...) -> */
4882
Item *Item_cond_and::neg_transformer(Session *session) /* NOT(a AND b AND ...) -> */
4827
4883
/* NOT a OR NOT b OR ... */
4885
neg_arguments(session);
4830
4886
Item *item= new Item_cond_or(list);
4835
Item *Item_cond_or::neg_transformer(THD *thd) /* NOT(a OR b OR ...) -> */
4891
Item *Item_cond_or::neg_transformer(Session *session) /* NOT(a OR b OR ...) -> */
4836
4892
/* NOT a AND NOT b AND ... */
4894
neg_arguments(session);
4839
4895
Item *item= new Item_cond_and(list);
4844
Item *Item_func_nop_all::neg_transformer(THD *thd __attribute__((unused)))
4900
Item *Item_func_nop_all::neg_transformer(Session *)
4846
4902
/* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
4847
4903
Item_func_not_all *new_item= new Item_func_not_all(args[0]);
4852
4908
return new_item;
4855
Item *Item_func_not_all::neg_transformer(THD *thd __attribute__((unused)))
4911
Item *Item_func_not_all::neg_transformer(Session *)
4857
4913
/* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
4858
4914
Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
4995
5051
Join members of another Item_equal object.
4997
5053
The function actually merges two multiple equalities.
4998
5054
After this operation the Item_equal object additionally contains
4999
5055
the field items of another item of the type Item_equal.
5000
5056
If the optional constant items are not equal the cond_false flag is
5002
5058
@param item multiple equality whose members are to be joined
5008
5064
Item *c= item->const_item;
5012
The flag cond_false will be set to 1 after this, if
5013
the multiple equality already contains a constant and its
5068
The flag cond_false will be set to 1 after this, if
5069
the multiple equality already contains a constant and its
5014
5070
value is not equal to the value of c.
5018
5074
cond_false|= item->cond_false;
5182
THD::change_item_tree() should be called only if the tree was
5238
Session::change_item_tree() should be called only if the tree was
5183
5239
really transformed, i.e. when a new item has been created.
5184
5240
Otherwise we'll be allocating a lot of unnecessary memory for
5185
5241
change records at each execution.
5187
5243
if (new_item != item)
5188
current_thd->change_item_tree((Item **) it.ref(), new_item);
5244
current_session->change_item_tree((Item **) it.ref(), new_item);
5190
5246
return Item_func::transform(transformer, arg);