Commit d390e501 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-11839 move value caching from get_datetime_value to fix_fields time

Refactor get_datetime_value() not to create Item_cache_temporal(),
but do it always in ::fix_fields() or ::fix_length_and_dec().

Creating items at the execution time doesn't work very well with
virtual columns and check constraints that are fixed and executed
in different THDs.
parent 1c6f6dc8
...@@ -7,7 +7,6 @@ a ...@@ -7,7 +7,6 @@ a
2002-03-04 2002-03-04
Warnings: Warnings:
Note 1003 2000-01-01 Note 1003 2000-01-01
Note 1003 2000-01-06
set debug_dbug=''; set debug_dbug='';
drop table t1; drop table t1;
create table t1 (id int not null, ut timestamp(6) not null); create table t1 (id int not null, ut timestamp(6) not null);
......
...@@ -403,3 +403,37 @@ DROP TABLE t1; ...@@ -403,3 +403,37 @@ DROP TABLE t1;
# #
# End of 10.1 test # End of 10.1 test
# #
select case 'foo' when time'10:00:00' then 'never' when '0' then 'bug' else 'ok' end;
case 'foo' when time'10:00:00' then 'never' when '0' then 'bug' else 'ok' end
ok
Warnings:
Warning 1292 Truncated incorrect time value: 'foo'
select 'foo' in (time'10:00:00','0');
'foo' in (time'10:00:00','0')
0
Warnings:
Warning 1292 Truncated incorrect time value: 'foo'
create table t1 (a time);
insert t1 values (100000), (102030), (203040);
select case 'foo' when a then 'never' when '0' then 'bug' else 'ok' end from t1;
case 'foo' when a then 'never' when '0' then 'bug' else 'ok' end
ok
ok
ok
Warnings:
Warning 1292 Truncated incorrect time value: 'foo'
Warning 1292 Truncated incorrect time value: 'foo'
Warning 1292 Truncated incorrect time value: 'foo'
select 'foo' in (a,'0') from t1;
'foo' in (a,'0')
0
0
0
Warnings:
Warning 1292 Truncated incorrect time value: 'foo'
Warning 1292 Truncated incorrect time value: 'foo'
Warning 1292 Truncated incorrect time value: 'foo'
drop table t1;
select case '20:10:05' when date'2020-10-10' then 'never' when time'20:10:5' then 'ok' else 'bug' end;
case '20:10:05' when date'2020-10-10' then 'never' when time'20:10:5' then 'ok' else 'bug' end
bug
...@@ -1595,8 +1595,6 @@ NULL ...@@ -1595,8 +1595,6 @@ NULL
Warnings: Warnings:
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20'; SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20';
str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20' str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20'
1 1
......
...@@ -1597,8 +1597,6 @@ NULL ...@@ -1597,8 +1597,6 @@ NULL
Warnings: Warnings:
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20'; SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20';
str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20' str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20'
1 1
......
...@@ -287,3 +287,22 @@ DROP TABLE t1; ...@@ -287,3 +287,22 @@ DROP TABLE t1;
--echo # --echo #
--echo # End of 10.1 test --echo # End of 10.1 test
--echo # --echo #
#
# caching of first argument in CASE/IN for temporal types
#
#
# should not convert all values to time
select case 'foo' when time'10:00:00' then 'never' when '0' then 'bug' else 'ok' end;
select 'foo' in (time'10:00:00','0');
create table t1 (a time);
insert t1 values (100000), (102030), (203040);
# only one warning, TIME('foo') should be cached
select case 'foo' when a then 'never' when '0' then 'bug' else 'ok' end from t1;
select 'foo' in (a,'0') from t1;
drop table t1;
# first comparison should be as date, second as time
select case '20:10:05' when date'2020-10-10' then 'never' when time'20:10:5' then 'ok' else 'bug' end;
...@@ -9361,13 +9361,16 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) ...@@ -9361,13 +9361,16 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
switch (res_type) { switch (res_type) {
case TIME_RESULT: case TIME_RESULT:
{ {
bool is_null;
Item **ref_copy= ref;
/* the following call creates a constant and puts it in new_item */
enum_field_types type= item->field_type_for_temporal_comparison(comp_item); enum_field_types type= item->field_type_for_temporal_comparison(comp_item);
get_datetime_value(thd, &ref_copy, &new_item, type, &is_null); longlong value= item->val_temporal_packed(type);
if (is_null) if (item->null_value)
new_item= new (mem_root) Item_null(thd, name); new_item= new (mem_root) Item_null(thd, name);
else
{
Item_cache_temporal *cache= new (mem_root) Item_cache_temporal(thd, type);
cache->store_packed(value, item);
new_item= cache;
}
break; break;
} }
case STRING_RESULT: case STRING_RESULT:
...@@ -9702,8 +9705,7 @@ Item_cache_temporal::Item_cache_temporal(THD *thd, ...@@ -9702,8 +9705,7 @@ Item_cache_temporal::Item_cache_temporal(THD *thd,
longlong Item_cache_temporal::val_datetime_packed() longlong Item_cache_temporal::val_datetime_packed()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
if (Item_cache_temporal::field_type() == MYSQL_TYPE_TIME) DBUG_ASSERT(Item_cache_temporal::field_type() != MYSQL_TYPE_TIME);
return Item::val_datetime_packed(); // TIME-to-DATETIME conversion needed
if ((!value_cached && !cache_value()) || null_value) if ((!value_cached && !cache_value()) || null_value)
{ {
null_value= TRUE; null_value= TRUE;
...@@ -9716,8 +9718,7 @@ longlong Item_cache_temporal::val_datetime_packed() ...@@ -9716,8 +9718,7 @@ longlong Item_cache_temporal::val_datetime_packed()
longlong Item_cache_temporal::val_time_packed() longlong Item_cache_temporal::val_time_packed()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
if (Item_cache_temporal::field_type() != MYSQL_TYPE_TIME) DBUG_ASSERT(Item_cache_temporal::field_type() == MYSQL_TYPE_TIME);
return Item::val_time_packed(); // DATETIME-to-TIME conversion needed
if ((!value_cached && !cache_value()) || null_value) if ((!value_cached && !cache_value()) || null_value)
{ {
null_value= TRUE; null_value= TRUE;
...@@ -9775,18 +9776,26 @@ double Item_cache_temporal::val_real() ...@@ -9775,18 +9776,26 @@ double Item_cache_temporal::val_real()
} }
bool Item_cache_temporal::cache_value() bool Item_cache_temporal::cache_value()
{ {
if (!example) if (!example)
return false; return false;
value_cached= true; value_cached= true;
MYSQL_TIME ltime; MYSQL_TIME ltime;
if (example->get_date_result(&ltime, 0)) uint fuzzydate= TIME_FUZZY_DATES | TIME_INVALID_DATES;
value=0; if (Item_cache_temporal::field_type() == MYSQL_TYPE_TIME)
else fuzzydate|= TIME_TIME_ONLY;
value= 0;
if (!example->get_date_result(&ltime, fuzzydate))
{
if (ltime.time_type == MYSQL_TIMESTAMP_TIME &&
!(fuzzydate & TIME_TIME_ONLY) &&
convert_time_to_datetime(current_thd, &ltime, fuzzydate))
return true;
value= pack_time(&ltime); value= pack_time(&ltime);
}
null_value= example->null_value; null_value= example->null_value;
return true; return true;
} }
...@@ -9806,11 +9815,15 @@ bool Item_cache_temporal::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) ...@@ -9806,11 +9815,15 @@ bool Item_cache_temporal::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
ltime->time_type= mysql_type_to_time_type(field_type()); ltime->time_type= mysql_type_to_time_type(field_type());
if (ltime->time_type == MYSQL_TIMESTAMP_TIME) if (ltime->time_type == MYSQL_TIMESTAMP_TIME)
{ {
ltime->hour+= (ltime->month*32+ltime->day)*24; if (fuzzydate & TIME_TIME_ONLY)
ltime->month= ltime->day= 0; {
ltime->hour+= (ltime->month*32+ltime->day)*24;
ltime->month= ltime->day= 0;
}
else if (convert_time_to_datetime(current_thd, ltime, fuzzydate))
return true;
} }
return 0; return 0;
} }
......
...@@ -41,10 +41,14 @@ static Item** cache_converted_constant(THD *thd, Item **value, ...@@ -41,10 +41,14 @@ static Item** cache_converted_constant(THD *thd, Item **value,
find an temporal type (item) that others will be converted to find an temporal type (item) that others will be converted to
for the purpose of comparison. for the purpose of comparison.
for IN/CASE conversion only happens if the first item defines the
comparison context.
this is the type that will be used in warnings like this is the type that will be used in warnings like
"Incorrect <<TYPE>> value". "Incorrect <<TYPE>> value".
*/ */
static Item *find_date_time_item(Item **args, uint nargs, uint col) static Item *find_date_time_item(THD *thd, Item **args, uint nargs, uint col,
bool in_case)
{ {
Item *date_arg= 0, **arg, **arg_end; Item *date_arg= 0, **arg, **arg_end;
for (arg= args, arg_end= args + nargs; arg != arg_end ; arg++) for (arg= args, arg_end= args + nargs; arg != arg_end ; arg++)
...@@ -52,10 +56,22 @@ static Item *find_date_time_item(Item **args, uint nargs, uint col) ...@@ -52,10 +56,22 @@ static Item *find_date_time_item(Item **args, uint nargs, uint col)
Item *item= arg[0]->element_index(col); Item *item= arg[0]->element_index(col);
if (item->cmp_type() != TIME_RESULT) if (item->cmp_type() != TIME_RESULT)
continue; continue;
if (item->field_type() == MYSQL_TYPE_DATETIME)
return item;
if (!date_arg) if (!date_arg)
date_arg= item; date_arg= item;
if (item->field_type() == MYSQL_TYPE_DATETIME)
break;
}
if (in_case ? date_arg == args[0]->element_index(col) : date_arg != NULL)
{
enum_field_types f_type= date_arg->field_type();
for (arg= args, arg_end= args + nargs; arg != arg_end ; arg++)
{
Item *cache, **a= arg[0]->addr(col);
if (!a)
a= arg;
if (cache_converted_constant(thd, a, &cache, TIME_RESULT, f_type) != a)
thd->change_item_tree(a, cache);
}
} }
return date_arg; return date_arg;
} }
...@@ -658,6 +674,8 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg, ...@@ -658,6 +674,8 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
func= is_owner_equal_func() ? &Arg_comparator::compare_e_datetime : func= is_owner_equal_func() ? &Arg_comparator::compare_e_datetime :
&Arg_comparator::compare_datetime; &Arg_comparator::compare_datetime;
} }
a= cache_converted_constant(thd, a, &a_cache, m_compare_type, f_type);
b= cache_converted_constant(thd, b, &b_cache, m_compare_type, f_type);
return 0; return 0;
} }
...@@ -685,9 +703,11 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg, ...@@ -685,9 +703,11 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
func= is_owner_equal_func() ? &Arg_comparator::compare_e_datetime : func= is_owner_equal_func() ? &Arg_comparator::compare_e_datetime :
&Arg_comparator::compare_datetime; &Arg_comparator::compare_datetime;
} }
else
a= cache_converted_constant(thd, a, &a_cache, m_compare_type); {
b= cache_converted_constant(thd, b, &b_cache, m_compare_type); a= cache_converted_constant(thd, a, &a_cache, m_compare_type, (*a)->field_type());
b= cache_converted_constant(thd, b, &b_cache, m_compare_type, (*b)->field_type());
}
return set_compare_func(owner_arg, m_compare_type); return set_compare_func(owner_arg, m_compare_type);
} }
...@@ -710,18 +730,13 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg, ...@@ -710,18 +730,13 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
*/ */
static Item** cache_converted_constant(THD *thd, Item **value, static Item** cache_converted_constant(THD *thd, Item **value,
Item **cache_item, Item_result type) Item **cache_item, Item_result type, enum_field_types f_type)
{ {
/* /* Don't need cache if doing context analysis only. */
Don't need cache if doing context analysis only.
Also, get_datetime_value creates Item_cache internally.
Unless fixed, we should not do it here.
*/
if (!thd->lex->is_ps_or_view_context_analysis() && if (!thd->lex->is_ps_or_view_context_analysis() &&
(*value)->const_item() && type != (*value)->result_type() && (*value)->const_item() && type != (*value)->result_type())
type != TIME_RESULT)
{ {
Item_cache *cache= Item_cache::get_cache(thd, *value, type); Item_cache *cache= Item_cache::get_cache(thd, *value, type, f_type);
cache->setup(thd, *value); cache->setup(thd, *value);
*cache_item= cache; *cache_item= cache;
return cache_item; return cache_item;
...@@ -761,26 +776,11 @@ static Item** cache_converted_constant(THD *thd, Item **value, ...@@ -761,26 +776,11 @@ static Item** cache_converted_constant(THD *thd, Item **value,
MYSQL_TIME value, packed in a longlong, suitable for comparison. MYSQL_TIME value, packed in a longlong, suitable for comparison.
*/ */
longlong longlong get_datetime_value(Item *item, enum_field_types f_type, bool *is_null)
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
enum_field_types f_type, bool *is_null)
{ {
longlong UNINIT_VAR(value); longlong value= item->val_temporal_packed(f_type);
Item *item= **item_arg;
value= item->val_temporal_packed(f_type);
if ((*is_null= item->null_value)) if ((*is_null= item->null_value))
return ~(ulonglong) 0; return ~(ulonglong) 0;
if (cache_arg && item->const_item() &&
!(item->type() == Item::CACHE_ITEM && item->cmp_type() == TIME_RESULT))
{
if (!thd)
thd= current_thd;
Item_cache_temporal *cache= new (thd->mem_root) Item_cache_temporal(thd, f_type);
cache->store_packed(value, item);
*cache_arg= cache;
*item_arg= cache_arg;
}
return value; return value;
} }
...@@ -811,12 +811,12 @@ int Arg_comparator::compare_temporal(enum_field_types type) ...@@ -811,12 +811,12 @@ int Arg_comparator::compare_temporal(enum_field_types type)
owner->null_value= 1; owner->null_value= 1;
/* Get DATE/DATETIME/TIME value of the 'a' item. */ /* Get DATE/DATETIME/TIME value of the 'a' item. */
a_value= get_datetime_value(0, &a, &a_cache, type, &a_is_null); a_value= get_datetime_value(*a, type, &a_is_null);
if (a_is_null) if (a_is_null)
return -1; return -1;
/* Get DATE/DATETIME/TIME value of the 'b' item. */ /* Get DATE/DATETIME/TIME value of the 'b' item. */
b_value= get_datetime_value(0, &b, &b_cache, type, &b_is_null); b_value= get_datetime_value(*b, type, &b_is_null);
if (b_is_null) if (b_is_null)
return -1; return -1;
...@@ -834,10 +834,10 @@ int Arg_comparator::compare_e_temporal(enum_field_types type) ...@@ -834,10 +834,10 @@ int Arg_comparator::compare_e_temporal(enum_field_types type)
longlong a_value, b_value; longlong a_value, b_value;
/* Get DATE/DATETIME/TIME value of the 'a' item. */ /* Get DATE/DATETIME/TIME value of the 'a' item. */
a_value= get_datetime_value(0, &a, &a_cache, type, &a_is_null); a_value= get_datetime_value(*a, type, &a_is_null);
/* Get DATE/DATETIME/TIME value of the 'b' item. */ /* Get DATE/DATETIME/TIME value of the 'b' item. */
b_value= get_datetime_value(0, &b, &b_cache, type, &b_is_null); b_value= get_datetime_value(*b, type, &b_is_null);
return a_is_null || b_is_null ? a_is_null == b_is_null return a_is_null || b_is_null ? a_is_null == b_is_null
: a_value == b_value; : a_value == b_value;
} }
...@@ -2170,7 +2170,7 @@ void Item_func_between::fix_length_and_dec() ...@@ -2170,7 +2170,7 @@ void Item_func_between::fix_length_and_dec()
strings as. strings as.
*/ */
if (m_compare_type == TIME_RESULT) if (m_compare_type == TIME_RESULT)
compare_as_dates= find_date_time_item(args, 3, 0); compare_as_dates= find_date_time_item(thd, args, 3, 0, false);
/* See the comment for Item_func::convert_const_compared_to_int_field */ /* See the comment for Item_func::convert_const_compared_to_int_field */
if (args[0]->real_item()->type() == FIELD_ITEM && if (args[0]->real_item()->type() == FIELD_ITEM &&
...@@ -2196,29 +2196,17 @@ longlong Item_func_between::val_int() ...@@ -2196,29 +2196,17 @@ longlong Item_func_between::val_int()
switch (m_compare_type) { switch (m_compare_type) {
case TIME_RESULT: case TIME_RESULT:
{ {
THD *thd= current_thd;
longlong value, a, b; longlong value, a, b;
Item *cache, **ptr;
bool value_is_null, a_is_null, b_is_null; bool value_is_null, a_is_null, b_is_null;
ptr= &args[0];
enum_field_types f_type= field_type_for_temporal_comparison(compare_as_dates); enum_field_types f_type= field_type_for_temporal_comparison(compare_as_dates);
value= get_datetime_value(thd, &ptr, &cache, f_type, &value_is_null); value= get_datetime_value(args[0], f_type, &value_is_null);
if (ptr != &args[0])
thd->change_item_tree(&args[0], *ptr);
if ((null_value= value_is_null)) if ((null_value= value_is_null))
return 0; return 0;
ptr= &args[1]; a= get_datetime_value(args[1], f_type, &a_is_null);
a= get_datetime_value(thd, &ptr, &cache, f_type, &a_is_null); b= get_datetime_value(args[2], f_type, &b_is_null);
if (ptr != &args[1])
thd->change_item_tree(&args[1], *ptr);
ptr= &args[2];
b= get_datetime_value(thd, &ptr, &cache, f_type, &b_is_null);
if (ptr != &args[2])
thd->change_item_tree(&args[2], *ptr);
if (!a_is_null && !b_is_null) if (!a_is_null && !b_is_null)
return (longlong) ((value >= a && value <= b) != negated); return (longlong) ((value >= a && value <= b) != negated);
...@@ -3248,7 +3236,7 @@ void Item_func_case::fix_length_and_dec() ...@@ -3248,7 +3236,7 @@ void Item_func_case::fix_length_and_dec()
Item *date_arg= 0; Item *date_arg= 0;
if (m_found_types & (1U << TIME_RESULT)) if (m_found_types & (1U << TIME_RESULT))
date_arg= find_date_time_item(args, nwhens + 1, 0); date_arg= find_date_time_item(current_thd, args, nwhens + 1, 0, true);
if (m_found_types & (1U << STRING_RESULT)) if (m_found_types & (1U << STRING_RESULT))
{ {
...@@ -3790,10 +3778,8 @@ void in_datetime::set(uint pos,Item *item) ...@@ -3790,10 +3778,8 @@ void in_datetime::set(uint pos,Item *item)
uchar *in_datetime::get_value(Item *item) uchar *in_datetime::get_value(Item *item)
{ {
bool is_null; bool is_null;
Item **tmp_item= lval_cache ? &lval_cache : &item; enum_field_types f_type= item->field_type_for_temporal_comparison(warn_item);
enum_field_types f_type= tmp.val= get_datetime_value(item, f_type, &is_null);
tmp_item[0]->field_type_for_temporal_comparison(warn_item);
tmp.val= get_datetime_value(0, &tmp_item, &lval_cache, f_type, &is_null);
if (item->null_value) if (item->null_value)
return 0; return 0;
tmp.unsigned_flag= 1L; tmp.unsigned_flag= 1L;
...@@ -4055,10 +4041,8 @@ cmp_item* cmp_item_decimal::make_same() ...@@ -4055,10 +4041,8 @@ cmp_item* cmp_item_decimal::make_same()
void cmp_item_datetime::store_value(Item *item) void cmp_item_datetime::store_value(Item *item)
{ {
bool is_null; bool is_null;
Item **tmp_item= lval_cache ? &lval_cache : &item; enum_field_types f_type= item->field_type_for_temporal_comparison(warn_item);
enum_field_types f_type= value= get_datetime_value(item, f_type, &is_null);
tmp_item[0]->field_type_for_temporal_comparison(warn_item);
value= get_datetime_value(0, &tmp_item, &lval_cache, f_type, &is_null);
m_null_value= item->null_value; m_null_value= item->null_value;
} }
...@@ -4263,7 +4247,7 @@ void Item_func_in::fix_length_and_dec() ...@@ -4263,7 +4247,7 @@ void Item_func_in::fix_length_and_dec()
for (uint col= 0; col < cols; col++) for (uint col= 0; col < cols; col++)
{ {
date_arg= find_date_time_item(args, arg_count, col); date_arg= find_date_time_item(thd, args, arg_count, col, true);
if (date_arg) if (date_arg)
{ {
cmp_item **cmp= 0; cmp_item **cmp= 0;
...@@ -4329,7 +4313,7 @@ void Item_func_in::fix_length_and_dec() ...@@ -4329,7 +4313,7 @@ void Item_func_in::fix_length_and_dec()
array= new (thd->mem_root) in_decimal(thd, arg_count - 1); array= new (thd->mem_root) in_decimal(thd, arg_count - 1);
break; break;
case TIME_RESULT: case TIME_RESULT:
date_arg= find_date_time_item(args, arg_count, 0); date_arg= find_date_time_item(thd, args, arg_count, 0, true);
array= new (thd->mem_root) in_datetime(thd, date_arg, arg_count - 1); array= new (thd->mem_root) in_datetime(thd, date_arg, arg_count - 1);
break; break;
} }
...@@ -4356,7 +4340,7 @@ void Item_func_in::fix_length_and_dec() ...@@ -4356,7 +4340,7 @@ void Item_func_in::fix_length_and_dec()
else else
{ {
if (found_types & (1U << TIME_RESULT)) if (found_types & (1U << TIME_RESULT))
date_arg= find_date_time_item(args, arg_count, 0); date_arg= find_date_time_item(thd, args, arg_count, 0, true);
if (found_types & (1U << STRING_RESULT) && if (found_types & (1U << STRING_RESULT) &&
agg_arg_charsets_for_comparison(cmp_collation, args, arg_count)) agg_arg_charsets_for_comparison(cmp_collation, args, arg_count))
return; return;
......
...@@ -1267,19 +1267,15 @@ class in_longlong :public in_vector ...@@ -1267,19 +1267,15 @@ class in_longlong :public in_vector
/* /*
Class to represent a vector of constant DATE/DATETIME values. Class to represent a vector of constant DATE/DATETIME values.
Values are obtained with help of the get_datetime_value() function. Values are obtained with help of the get_datetime_value() function.
If the left item is a constant one then its value is cached in the
lval_cache variable.
*/ */
class in_datetime :public in_longlong class in_datetime :public in_longlong
{ {
public: public:
/* An item used to issue warnings. */ /* An item used to issue warnings. */
Item *warn_item; Item *warn_item;
/* Cache for the left item. */
Item *lval_cache;
in_datetime(THD *thd, Item *warn_item_arg, uint elements) in_datetime(THD *thd, Item *warn_item_arg, uint elements)
:in_longlong(thd, elements), warn_item(warn_item_arg), lval_cache(0) {}; :in_longlong(thd, elements), warn_item(warn_item_arg) {}
void set(uint pos,Item *item); void set(uint pos,Item *item);
uchar *get_value(Item *item); uchar *get_value(Item *item);
Item *create_item(THD *thd); Item *create_item(THD *thd);
...@@ -1441,8 +1437,6 @@ class cmp_item_int : public cmp_item_scalar ...@@ -1441,8 +1437,6 @@ class cmp_item_int : public cmp_item_scalar
/* /*
Compare items in the DATETIME context. Compare items in the DATETIME context.
Values are obtained with help of the get_datetime_value() function. Values are obtained with help of the get_datetime_value() function.
If the left item is a constant one then its value is cached in the
lval_cache variable.
*/ */
class cmp_item_datetime : public cmp_item_scalar class cmp_item_datetime : public cmp_item_scalar
{ {
...@@ -1450,11 +1444,9 @@ class cmp_item_datetime : public cmp_item_scalar ...@@ -1450,11 +1444,9 @@ class cmp_item_datetime : public cmp_item_scalar
public: public:
/* Item used for issuing warnings. */ /* Item used for issuing warnings. */
Item *warn_item; Item *warn_item;
/* Cache for the left item. */
Item *lval_cache;
cmp_item_datetime(Item *warn_item_arg) cmp_item_datetime(Item *warn_item_arg)
: warn_item(warn_item_arg), lval_cache(0) {} : warn_item(warn_item_arg) {}
void store_value(Item *item); void store_value(Item *item);
int cmp(Item *arg); int cmp(Item *arg);
int compare(cmp_item *ci); int compare(cmp_item *ci);
...@@ -2622,7 +2614,7 @@ inline bool is_cond_or(Item *item) ...@@ -2622,7 +2614,7 @@ inline bool is_cond_or(Item *item)
Item *and_expressions(Item *a, Item *b, Item **org_item); Item *and_expressions(Item *a, Item *b, Item **org_item);
longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, longlong get_datetime_value(Item ***item_arg, Item **cache_arg,
enum_field_types f_type, bool *is_null); enum_field_types f_type, bool *is_null);
......
...@@ -25,6 +25,6 @@ id title average max ...@@ -25,6 +25,6 @@ id title average max
SELECT * FROM running_records SELECT * FROM running_records
WHERE average BETWEEN "-838:59:59.000000" AND "01:00:00.000001"; WHERE average BETWEEN "-838:59:59.000000" AND "01:00:00.000001";
id title average max id title average max
3 record failure -838:59:59.000000 -838:59:59.000000
1 normal condition 01:00:00.000001 01:05:00.000001 1 normal condition 01:00:00.000001 01:05:00.000001
3 record failure -838:59:59.000000 -838:59:59.000000
DROP TABLE running_records; DROP TABLE running_records;
...@@ -25,6 +25,6 @@ id title average max ...@@ -25,6 +25,6 @@ id title average max
SELECT * FROM running_records SELECT * FROM running_records
WHERE average BETWEEN "-838:59:59" AND "01:00:00"; WHERE average BETWEEN "-838:59:59" AND "01:00:00";
id title average max id title average max
3 record failure -838:59:59 -838:59:59
1 normal condition 01:00:00 01:05:00 1 normal condition 01:00:00 01:05:00
3 record failure -838:59:59 -838:59:59
DROP TABLE running_records; DROP TABLE running_records;
...@@ -2080,7 +2080,7 @@ explain ...@@ -2080,7 +2080,7 @@ explain
select kp1,kp2 from t1 force index (kp1) select kp1,kp2 from t1 force index (kp1)
where kp1 between '09:01:00' and '09:05:00'; where kp1 between '09:01:00' and '09:05:00';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range kp1 kp1 4 NULL # Using where; Using index 1 SIMPLE t1 index kp1 kp1 9 NULL # Using where; Using index
select kp1,kp2 from t1 force index (kp1) select kp1,kp2 from t1 force index (kp1)
where kp1 between '09:01:00' and '09:05:00'; where kp1 between '09:01:00' and '09:05:00';
kp1 kp2 kp1 kp2
...@@ -2103,7 +2103,7 @@ explain ...@@ -2103,7 +2103,7 @@ explain
select kp1,kp2 from t2 force index (kp1) select kp1,kp2 from t2 force index (kp1)
where kp1 between '09:01:00' and '09:05:00'; where kp1 between '09:01:00' and '09:05:00';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range kp1 kp1 3 NULL # Using where; Using index 1 SIMPLE t2 index kp1 kp1 8 NULL # Using where; Using index
select kp1,kp2 from t2 force index (kp1) select kp1,kp2 from t2 force index (kp1)
where kp1 between '09:01:00' and '09:05:00'; where kp1 between '09:01:00' and '09:05:00';
kp1 kp2 kp1 kp2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment