mirror of
https://github.com/MariaDB/server.git
synced 2025-07-04 01:23:45 +03:00
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.
This commit is contained in:
@ -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;
|
|||||||
#
|
#
|
||||||
# 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
|
|||||||
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
|
|||||||
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;
|
|||||||
--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;
|
||||||
|
47
sql/item.cc
47
sql/item.cc
@ -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,
|
|||||||
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()
|
|||||||
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()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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(<ime, 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(<ime, fuzzydate))
|
||||||
|
{
|
||||||
|
if (ltime.time_type == MYSQL_TIMESTAMP_TIME &&
|
||||||
|
!(fuzzydate & TIME_TIME_ONLY) &&
|
||||||
|
convert_time_to_datetime(current_thd, <ime, fuzzydate))
|
||||||
|
return true;
|
||||||
value= pack_time(<ime);
|
value= pack_time(<ime);
|
||||||
|
}
|
||||||
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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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()
|
|||||||
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()
|
|||||||
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()
|
|||||||
|
|
||||||
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)
|
|||||||
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()
|
|||||||
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()
|
|||||||
|
|
||||||
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()
|
|||||||
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()
|
|||||||
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 @@ public:
|
|||||||
/*
|
/*
|
||||||
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 @@ public:
|
|||||||
/*
|
/*
|
||||||
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
|
|||||||
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)
|
|||||||
|
|
||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
||||||
|
Reference in New Issue
Block a user