Skip to content
Permalink
Browse files
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.
  • Loading branch information
vuvova committed Mar 14, 2018
1 parent 1c6f6dc commit d390e50
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 102 deletions.
@@ -7,7 +7,6 @@ a
2002-03-04
Warnings:
Note 1003 2000-01-01
Note 1003 2000-01-06
set debug_dbug='';
drop table t1;
create table t1 (id int not null, ut timestamp(6) not null);
@@ -403,3 +403,37 @@ DROP TABLE t1;
#
# 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:
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';
str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20'
1
@@ -1597,8 +1597,6 @@ NULL
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
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'
1
@@ -287,3 +287,22 @@ DROP TABLE t1;
--echo #
--echo # End of 10.1 test
--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)
switch (res_type) {
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);
get_datetime_value(thd, &ref_copy, &new_item, type, &is_null);
if (is_null)
longlong value= item->val_temporal_packed(type);
if (item->null_value)
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;
}
case STRING_RESULT:
@@ -9702,8 +9705,7 @@ Item_cache_temporal::Item_cache_temporal(THD *thd,
longlong Item_cache_temporal::val_datetime_packed()
{
DBUG_ASSERT(fixed == 1);
if (Item_cache_temporal::field_type() == MYSQL_TYPE_TIME)
return Item::val_datetime_packed(); // TIME-to-DATETIME conversion needed
DBUG_ASSERT(Item_cache_temporal::field_type() != MYSQL_TYPE_TIME);
if ((!value_cached && !cache_value()) || null_value)
{
null_value= TRUE;
@@ -9716,8 +9718,7 @@ longlong Item_cache_temporal::val_datetime_packed()
longlong Item_cache_temporal::val_time_packed()
{
DBUG_ASSERT(fixed == 1);
if (Item_cache_temporal::field_type() != MYSQL_TYPE_TIME)
return Item::val_time_packed(); // DATETIME-to-TIME conversion needed
DBUG_ASSERT(Item_cache_temporal::field_type() == MYSQL_TYPE_TIME);
if ((!value_cached && !cache_value()) || null_value)
{
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)
return false;

value_cached= true;

MYSQL_TIME ltime;
if (example->get_date_result(&ltime, 0))
value=0;
else
uint fuzzydate= TIME_FUZZY_DATES | TIME_INVALID_DATES;
if (Item_cache_temporal::field_type() == MYSQL_TYPE_TIME)
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);
}
null_value= example->null_value;
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());
if (ltime->time_type == MYSQL_TIMESTAMP_TIME)
{
ltime->hour+= (ltime->month*32+ltime->day)*24;
ltime->month= ltime->day= 0;
if (fuzzydate & TIME_TIME_ONLY)
{
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;

}


0 comments on commit d390e50

Please sign in to comment.