Skip to content

Commit d390e50

Browse files
committed
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.
1 parent 1c6f6dc commit d390e50

File tree

11 files changed

+139
-102
lines changed

11 files changed

+139
-102
lines changed

mysql-test/r/cache_temporal_4265.result

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ a
77
2002-03-04
88
Warnings:
99
Note 1003 2000-01-01
10-
Note 1003 2000-01-06
1110
set debug_dbug='';
1211
drop table t1;
1312
create table t1 (id int not null, ut timestamp(6) not null);

mysql-test/r/case.result

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,3 +403,37 @@ DROP TABLE t1;
403403
#
404404
# End of 10.1 test
405405
#
406+
select case 'foo' when time'10:00:00' then 'never' when '0' then 'bug' else 'ok' end;
407+
case 'foo' when time'10:00:00' then 'never' when '0' then 'bug' else 'ok' end
408+
ok
409+
Warnings:
410+
Warning 1292 Truncated incorrect time value: 'foo'
411+
select 'foo' in (time'10:00:00','0');
412+
'foo' in (time'10:00:00','0')
413+
0
414+
Warnings:
415+
Warning 1292 Truncated incorrect time value: 'foo'
416+
create table t1 (a time);
417+
insert t1 values (100000), (102030), (203040);
418+
select case 'foo' when a then 'never' when '0' then 'bug' else 'ok' end from t1;
419+
case 'foo' when a then 'never' when '0' then 'bug' else 'ok' end
420+
ok
421+
ok
422+
ok
423+
Warnings:
424+
Warning 1292 Truncated incorrect time value: 'foo'
425+
Warning 1292 Truncated incorrect time value: 'foo'
426+
Warning 1292 Truncated incorrect time value: 'foo'
427+
select 'foo' in (a,'0') from t1;
428+
'foo' in (a,'0')
429+
0
430+
0
431+
0
432+
Warnings:
433+
Warning 1292 Truncated incorrect time value: 'foo'
434+
Warning 1292 Truncated incorrect time value: 'foo'
435+
Warning 1292 Truncated incorrect time value: 'foo'
436+
drop table t1;
437+
select case '20:10:05' when date'2020-10-10' then 'never' when time'20:10:5' then 'ok' else 'bug' end;
438+
case '20:10:05' when date'2020-10-10' then 'never' when time'20:10:5' then 'ok' else 'bug' end
439+
bug

mysql-test/r/range.result

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,8 +1595,6 @@ NULL
15951595
Warnings:
15961596
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
15971597
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
1598-
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
1599-
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
16001598
SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20';
16011599
str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20'
16021600
1

mysql-test/r/range_mrr_icp.result

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,8 +1597,6 @@ NULL
15971597
Warnings:
15981598
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
15991599
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
1600-
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
1601-
Warning 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
16021600
SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20';
16031601
str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20'
16041602
1

mysql-test/t/case.test

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,22 @@ DROP TABLE t1;
287287
--echo #
288288
--echo # End of 10.1 test
289289
--echo #
290+
291+
#
292+
# caching of first argument in CASE/IN for temporal types
293+
#
294+
#
295+
296+
# should not convert all values to time
297+
select case 'foo' when time'10:00:00' then 'never' when '0' then 'bug' else 'ok' end;
298+
select 'foo' in (time'10:00:00','0');
299+
300+
create table t1 (a time);
301+
insert t1 values (100000), (102030), (203040);
302+
# only one warning, TIME('foo') should be cached
303+
select case 'foo' when a then 'never' when '0' then 'bug' else 'ok' end from t1;
304+
select 'foo' in (a,'0') from t1;
305+
drop table t1;
306+
307+
# first comparison should be as date, second as time
308+
select case '20:10:05' when date'2020-10-10' then 'never' when time'20:10:5' then 'ok' else 'bug' end;

sql/item.cc

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9361,13 +9361,16 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
93619361
switch (res_type) {
93629362
case TIME_RESULT:
93639363
{
9364-
bool is_null;
9365-
Item **ref_copy= ref;
9366-
/* the following call creates a constant and puts it in new_item */
93679364
enum_field_types type= item->field_type_for_temporal_comparison(comp_item);
9368-
get_datetime_value(thd, &ref_copy, &new_item, type, &is_null);
9369-
if (is_null)
9365+
longlong value= item->val_temporal_packed(type);
9366+
if (item->null_value)
93709367
new_item= new (mem_root) Item_null(thd, name);
9368+
else
9369+
{
9370+
Item_cache_temporal *cache= new (mem_root) Item_cache_temporal(thd, type);
9371+
cache->store_packed(value, item);
9372+
new_item= cache;
9373+
}
93719374
break;
93729375
}
93739376
case STRING_RESULT:
@@ -9702,8 +9705,7 @@ Item_cache_temporal::Item_cache_temporal(THD *thd,
97029705
longlong Item_cache_temporal::val_datetime_packed()
97039706
{
97049707
DBUG_ASSERT(fixed == 1);
9705-
if (Item_cache_temporal::field_type() == MYSQL_TYPE_TIME)
9706-
return Item::val_datetime_packed(); // TIME-to-DATETIME conversion needed
9708+
DBUG_ASSERT(Item_cache_temporal::field_type() != MYSQL_TYPE_TIME);
97079709
if ((!value_cached && !cache_value()) || null_value)
97089710
{
97099711
null_value= TRUE;
@@ -9716,8 +9718,7 @@ longlong Item_cache_temporal::val_datetime_packed()
97169718
longlong Item_cache_temporal::val_time_packed()
97179719
{
97189720
DBUG_ASSERT(fixed == 1);
9719-
if (Item_cache_temporal::field_type() != MYSQL_TYPE_TIME)
9720-
return Item::val_time_packed(); // DATETIME-to-TIME conversion needed
9721+
DBUG_ASSERT(Item_cache_temporal::field_type() == MYSQL_TYPE_TIME);
97219722
if ((!value_cached && !cache_value()) || null_value)
97229723
{
97239724
null_value= TRUE;
@@ -9775,18 +9776,26 @@ double Item_cache_temporal::val_real()
97759776
}
97769777

97779778

9778-
bool Item_cache_temporal::cache_value()
9779+
bool Item_cache_temporal::cache_value()
97799780
{
97809781
if (!example)
97819782
return false;
9782-
97839783
value_cached= true;
9784-
9784+
97859785
MYSQL_TIME ltime;
9786-
if (example->get_date_result(&ltime, 0))
9787-
value=0;
9788-
else
9786+
uint fuzzydate= TIME_FUZZY_DATES | TIME_INVALID_DATES;
9787+
if (Item_cache_temporal::field_type() == MYSQL_TYPE_TIME)
9788+
fuzzydate|= TIME_TIME_ONLY;
9789+
9790+
value= 0;
9791+
if (!example->get_date_result(&ltime, fuzzydate))
9792+
{
9793+
if (ltime.time_type == MYSQL_TIMESTAMP_TIME &&
9794+
!(fuzzydate & TIME_TIME_ONLY) &&
9795+
convert_time_to_datetime(current_thd, &ltime, fuzzydate))
9796+
return true;
97899797
value= pack_time(&ltime);
9798+
}
97909799
null_value= example->null_value;
97919800
return true;
97929801
}
@@ -9806,11 +9815,15 @@ bool Item_cache_temporal::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
98069815
ltime->time_type= mysql_type_to_time_type(field_type());
98079816
if (ltime->time_type == MYSQL_TIMESTAMP_TIME)
98089817
{
9809-
ltime->hour+= (ltime->month*32+ltime->day)*24;
9810-
ltime->month= ltime->day= 0;
9818+
if (fuzzydate & TIME_TIME_ONLY)
9819+
{
9820+
ltime->hour+= (ltime->month*32+ltime->day)*24;
9821+
ltime->month= ltime->day= 0;
9822+
}
9823+
else if (convert_time_to_datetime(current_thd, ltime, fuzzydate))
9824+
return true;
98119825
}
98129826
return 0;
9813-
98149827
}
98159828

98169829

0 commit comments

Comments
 (0)