Skip to content

Commit a610da4

Browse files
author
Mattias Jonsson
committed
Bug#14789301: CRASHING SERVER BY STORED FUNCTION
REFERENCING USER DEFINED VARIABLE IN QUERY There are 2 steps resulting in the crash: 1) the stored procedure was executed during JOIN::prepare resulting in setting thd->user_var_events_alloc to NULL (due to LTM_NONE) 2) the next time the stored procedure was executed in the same statement it crashes due to thd->user_var_events_alloc was null. (it was not set to thd->mem_root since LTM_PRELOCKED). The fix is to: * avoid executing the stored program during prepare phase of Item_func_isnull (update_used_tables). Also updated a comment which got out of date after bug 14247298. Also added test case copied from the duplicate bug: BUG#11765560 - SEGFAULT ON SHOW TABLE STATUS (MYSQLDUMP) OF NESTED VIEWS which is a duplicate in 5.6 (other cause in 5.1/5.5), but with another crash. In 5.1/5.5 this patch cannot be used since it lacks of with_stored_program, and the problem is caching strategy for is_not_null/isnull and DETERMINISTIC stored programs.
1 parent b410d34 commit a610da4

File tree

3 files changed

+7
-4
lines changed

3 files changed

+7
-4
lines changed

sql/item_cmpfunc.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5160,7 +5160,7 @@ longlong Item_func_isnull::val_int()
51605160
Handle optimization if the argument can't be null
51615161
This has to be here because of the test in update_used_tables().
51625162
*/
5163-
if (!used_tables_cache && !with_subselect)
5163+
if (!used_tables_cache && !with_subselect && !with_stored_program)
51645164
return cached_value;
51655165
return args[0]->is_null() ? 1: 0;
51665166
}
@@ -5169,7 +5169,7 @@ longlong Item_is_not_null_test::val_int()
51695169
{
51705170
DBUG_ASSERT(fixed == 1);
51715171
DBUG_ENTER("Item_is_not_null_test::val_int");
5172-
if (!used_tables_cache && !with_subselect)
5172+
if (!used_tables_cache && !with_subselect && !with_stored_program)
51735173
{
51745174
owner->was_null|= (!cached_value);
51755175
DBUG_PRINT("info", ("cached: %ld", (long) cached_value));
@@ -5201,7 +5201,8 @@ void Item_is_not_null_test::update_used_tables()
52015201
with_subselect= args[0]->has_subquery();
52025202
with_stored_program= args[0]->has_stored_program();
52035203
used_tables_cache|= args[0]->used_tables();
5204-
if (used_tables_cache == initial_pseudo_tables && !with_subselect)
5204+
if (used_tables_cache == initial_pseudo_tables && !with_subselect &&
5205+
!with_stored_program)
52055206
/* Remember if the value is always NULL or never NULL */
52065207
cached_value= !args[0]->is_null();
52075208
}

sql/item_cmpfunc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1492,7 +1492,7 @@ class Item_func_isnull :public Item_bool_func
14921492
with_stored_program= args[0]->has_stored_program();
14931493

14941494
if ((const_item_cache= !(used_tables_cache= args[0]->used_tables()) &&
1495-
!with_subselect))
1495+
!with_subselect && !with_stored_program))
14961496
{
14971497
/* Remember if the value is always NULL or never NULL */
14981498
cached_value= (longlong) args[0]->is_null();

sql/opt_range.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6131,6 +6131,8 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,Item *cond)
61316131
/*
61326132
Here when simple cond
61336133
There are limits on what kinds of const items we can evaluate.
6134+
At this stage a subquery in 'cond' might not be fully transformed yet
6135+
(example: semijoin) thus cannot be evaluated.
61346136
*/
61356137
if (cond->const_item() && !cond->is_expensive() && !cond->has_subquery())
61366138
{

0 commit comments

Comments
 (0)