mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Bug #11766860 - 60085: CRASH IN ITEM::SAVE_IN_FIELD() WITH TIME DATA TYPE
This assumption in Item_cache_datetime::cache_value_int was wrong: - /* Assume here that the underlying item will do correct conversion.*/ - int_value= example->val_int_result();
This commit is contained in:
@ -245,3 +245,12 @@ x
|
|||||||
NULL
|
NULL
|
||||||
drop procedure p1;
|
drop procedure p1;
|
||||||
drop tables t1,t2,t3;
|
drop tables t1,t2,t3;
|
||||||
|
#
|
||||||
|
# Bug#60085 crash in Item::save_in_field() with time data type
|
||||||
|
#
|
||||||
|
CREATE TABLE t1(a date, b int, unique(b), unique(a), key(b)) engine=innodb;
|
||||||
|
INSERT INTO t1 VALUES ('2011-05-13', 0);
|
||||||
|
SELECT * FROM t1 WHERE b < (SELECT CAST(a as date) FROM t1 GROUP BY a);
|
||||||
|
a b
|
||||||
|
2011-05-13 0
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -238,3 +238,12 @@ call p1();
|
|||||||
call p1();
|
call p1();
|
||||||
drop procedure p1;
|
drop procedure p1;
|
||||||
drop tables t1,t2,t3;
|
drop tables t1,t2,t3;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#60085 crash in Item::save_in_field() with time data type
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1(a date, b int, unique(b), unique(a), key(b)) engine=innodb;
|
||||||
|
INSERT INTO t1 VALUES ('2011-05-13', 0);
|
||||||
|
SELECT * FROM t1 WHERE b < (SELECT CAST(a as date) FROM t1 GROUP BY a);
|
||||||
|
DROP TABLE t1;
|
||||||
|
41
sql/item.cc
41
sql/item.cc
@ -1059,7 +1059,9 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions)
|
|||||||
ulonglong sql_mode= thd->variables.sql_mode;
|
ulonglong sql_mode= thd->variables.sql_mode;
|
||||||
thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
|
thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
|
||||||
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
|
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
|
||||||
|
|
||||||
res= save_in_field(field, no_conversions);
|
res= save_in_field(field, no_conversions);
|
||||||
|
|
||||||
thd->count_cuted_fields= tmp;
|
thd->count_cuted_fields= tmp;
|
||||||
dbug_tmp_restore_column_map(table->write_set, old_map);
|
dbug_tmp_restore_column_map(table->write_set, old_map);
|
||||||
thd->variables.sql_mode= sql_mode;
|
thd->variables.sql_mode= sql_mode;
|
||||||
@ -7462,16 +7464,43 @@ longlong Item_cache_int::val_int()
|
|||||||
bool Item_cache_datetime::cache_value_int()
|
bool Item_cache_datetime::cache_value_int()
|
||||||
{
|
{
|
||||||
if (!example)
|
if (!example)
|
||||||
return FALSE;
|
return false;
|
||||||
|
|
||||||
value_cached= TRUE;
|
value_cached= true;
|
||||||
// Mark cached string value obsolete
|
// Mark cached string value obsolete
|
||||||
str_value_cached= FALSE;
|
str_value_cached= false;
|
||||||
/* Assume here that the underlying item will do correct conversion.*/
|
|
||||||
int_value= example->val_int_result();
|
MYSQL_TIME ltime;
|
||||||
|
const bool eval_error=
|
||||||
|
(field_type() == MYSQL_TYPE_TIME) ?
|
||||||
|
example->get_time(<ime) :
|
||||||
|
example->get_date(<ime, TIME_FUZZY_DATE);
|
||||||
|
|
||||||
|
if (eval_error)
|
||||||
|
int_value= 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(field_type())
|
||||||
|
{
|
||||||
|
case MYSQL_TYPE_DATETIME:
|
||||||
|
case MYSQL_TYPE_TIMESTAMP:
|
||||||
|
int_value= TIME_to_ulonglong_datetime(<ime);
|
||||||
|
break;
|
||||||
|
case MYSQL_TYPE_TIME:
|
||||||
|
int_value= TIME_to_ulonglong_time(<ime);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
int_value= TIME_to_ulonglong_date(<ime);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ltime.neg)
|
||||||
|
int_value= -int_value;
|
||||||
|
}
|
||||||
|
|
||||||
null_value= example->null_value;
|
null_value= example->null_value;
|
||||||
unsigned_flag= example->unsigned_flag;
|
unsigned_flag= example->unsigned_flag;
|
||||||
return TRUE;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3449,7 +3449,7 @@ class Item_cache_datetime: public Item_cache
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
String str_value;
|
String str_value;
|
||||||
ulonglong int_value;
|
longlong int_value;
|
||||||
bool str_value_cached;
|
bool str_value_cached;
|
||||||
public:
|
public:
|
||||||
Item_cache_datetime(enum_field_types field_type_arg):
|
Item_cache_datetime(enum_field_types field_type_arg):
|
||||||
|
@ -403,6 +403,7 @@ static bool convert_constant_item(THD *thd, Item_field *field_item,
|
|||||||
Field *field= field_item->field;
|
Field *field= field_item->field;
|
||||||
int result= 0;
|
int result= 0;
|
||||||
|
|
||||||
|
// TODO: revert Bug#59685 here, as we now cache datetimes correctly.
|
||||||
if (!(*item)->with_subselect && (*item)->const_item())
|
if (!(*item)->with_subselect && (*item)->const_item())
|
||||||
{
|
{
|
||||||
TABLE *table= field->table;
|
TABLE *table= field->table;
|
||||||
|
@ -256,30 +256,31 @@ bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
|
|||||||
|
|
||||||
bool Item_subselect::exec()
|
bool Item_subselect::exec()
|
||||||
{
|
{
|
||||||
int res;
|
DBUG_ENTER("Item_subselect::exec");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Do not execute subselect in case of a fatal error
|
Do not execute subselect in case of a fatal error
|
||||||
or if the query has been killed.
|
or if the query has been killed.
|
||||||
*/
|
*/
|
||||||
if (thd->is_error() || thd->killed)
|
if (thd->is_error() || thd->killed)
|
||||||
return 1;
|
DBUG_RETURN(true);
|
||||||
|
|
||||||
DBUG_ASSERT(!thd->lex->context_analysis_only);
|
DBUG_ASSERT(!thd->lex->context_analysis_only);
|
||||||
/*
|
/*
|
||||||
Simulate a failure in sub-query execution. Used to test e.g.
|
Simulate a failure in sub-query execution. Used to test e.g.
|
||||||
out of memory or query being killed conditions.
|
out of memory or query being killed conditions.
|
||||||
*/
|
*/
|
||||||
DBUG_EXECUTE_IF("subselect_exec_fail", return 1;);
|
DBUG_EXECUTE_IF("subselect_exec_fail", DBUG_RETURN(true););
|
||||||
|
|
||||||
res= engine->exec();
|
bool res= engine->exec();
|
||||||
|
|
||||||
if (engine_changed)
|
if (engine_changed)
|
||||||
{
|
{
|
||||||
engine_changed= 0;
|
engine_changed= 0;
|
||||||
return exec();
|
res= exec();
|
||||||
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
return (res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
Item::Type Item_subselect::type() const
|
Item::Type Item_subselect::type() const
|
||||||
|
Reference in New Issue
Block a user