Commit 24693c6f authored by Oleksandr Byelkin's avatar Oleksandr Byelkin

Bug#29363867: LOST CONNECTION TO MYSQL SERVER DURING QUERY

The problem is that sharing default expression among set instruction
leads to attempt access result field of function created in
other instruction runtime MEM_ROOT and already freed
(a bit different then MySQL problem).

Fix is the same as in MySQL (but no optimisation for constant), turn
DECLARE a, b, c type DEFAULT expr;
to
DECLARE a type DEFAULT expr, b type DEFAULT a, c type DEFAULT a;
parent e85b389b
......@@ -8486,4 +8486,19 @@ ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function
DROP PROCEDURE p1;
DROP VIEW v1;
DROP TABLE t1;
#
# BUG#30366310: USING A FUNCTION TO ASSIGN DEFAULT VALUES TO
# 2 OR MORE VARIABLES CRASHES SERVER
#
create function f1() returns bigint return now()-1|
create procedure p1()
begin
declare b, c bigint default f1();
select b-c;
end|
call p1()|
b-c
0
drop procedure p1|
drop function f1|
#End of 10.2 tests
......@@ -10025,4 +10025,23 @@ DROP PROCEDURE p1;
DROP VIEW v1;
DROP TABLE t1;
--echo #
--echo # BUG#30366310: USING A FUNCTION TO ASSIGN DEFAULT VALUES TO
--echo # 2 OR MORE VARIABLES CRASHES SERVER
--echo #
delimiter |;
create function f1() returns bigint return now()-1|
create procedure p1()
begin
declare b, c bigint default f1();
select b-c;
end|
call p1()|
drop procedure p1|
drop function f1|
delimiter ;|
--echo #End of 10.2 tests
......@@ -3104,17 +3104,22 @@ sp_decl:
sp_pcontext *pctx= lex->spcont;
uint num_vars= pctx->context_var_count();
Item *dflt_value_item= $5;
const bool has_default_clause = (dflt_value_item != NULL);
Lex->set_last_field_type($4);
if (!dflt_value_item)
if (!has_default_clause)
{
dflt_value_item= new (thd->mem_root) Item_null(thd);
if (dflt_value_item == NULL)
MYSQL_YYABORT;
/* QQ Set to the var_type with null_value? */
}
for (uint i = num_vars-$2 ; i < num_vars ; i++)
sp_variable *first_spvar = NULL;
const uint first_var_num = num_vars - $2;
for (uint i = first_var_num ; i < num_vars ; i++)
{
uint var_idx= pctx->var_context2runtime(i);
sp_variable *spvar= pctx->find_variable(var_idx);
......@@ -3126,9 +3131,24 @@ sp_decl:
if (!last)
spvar->field_def= *lex->last_field;
if (i == first_var_num) {
first_spvar = spvar;
} else if (has_default_clause) {
Item_splocal *item =
new (thd->mem_root)
Item_splocal(thd, first_spvar->name, first_spvar->offset,
first_spvar->sql_type(), 0, 0);
if (item == NULL)
MYSQL_YYABORT; // OOM
#ifndef DBUG_OFF
item->m_sp = lex->sphead;
#endif
dflt_value_item = item;
}
spvar->default_value= dflt_value_item;
spvar->field_def.field_name= spvar->name.str;
if (lex->sphead->fill_field_definition(thd, lex,
&spvar->field_def))
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment