1
0
mirror of https://github.com/MariaDB/server.git synced 2025-09-02 09:41:40 +03:00

Fix for Bug#5034 "prepared "select 1 into @arg15", second

execute crashes server": we were deleting lex->result
after each execute, but prepared statements assumed that
it's left intact.
The fix adds cleanup() method to select_result hierarchy,
so that result objects can be reused.
Plus we now need to delete result objects more wisely.
This commit is contained in:
konstantin@mysql.com
2004-08-24 20:17:11 +04:00
parent f0fffbe21b
commit ae18dc3ec8
10 changed files with 161 additions and 75 deletions

View File

@@ -1967,8 +1967,6 @@ mysql_execute_command(THD *thd)
else
thd->send_explain_fields(result);
res= mysql_explain_union(thd, &thd->lex->unit, result);
MYSQL_LOCK *save_lock= thd->lock;
thd->lock= (MYSQL_LOCK *)0;
if (lex->describe & DESCRIBE_EXTENDED)
{
char buff[1024];
@@ -1980,20 +1978,19 @@ mysql_execute_command(THD *thd)
ER_YES, str.ptr());
}
result->send_eof();
thd->lock= save_lock;
delete result;
}
else
{
if (!result)
if (!result && !(result= new select_send()))
{
if (!(result=new select_send()))
{
res= -1;
break;
}
res= -1;
break;
}
query_cache_store_query(thd, tables);
res=handle_select(thd, lex, result);
res= handle_select(thd, lex, result);
if (result != lex->result)
delete result;
}
}
break;
@@ -2708,23 +2705,24 @@ unsent_create_error:
}
if (!(res=open_and_lock_tables(thd, tables)))
if (!(res= open_and_lock_tables(thd, tables)) &&
(result= new select_insert(tables->table, &lex->field_list,
lex->duplicates)))
{
if ((result=new select_insert(tables->table,&lex->field_list,
lex->duplicates)))
/* Skip first table, which is the table we are inserting in */
lex->select_lex.table_list.first= (byte*) first_local_table->next;
/*
insert/replace from SELECT give its SELECT_LEX for SELECT,
and item_list belong to SELECT
*/
lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE;
res=handle_select(thd,lex,result);
/* revert changes for SP */
lex->select_lex.table_list.first= (byte*) first_local_table;
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
/* Skip first table, which is the table we are inserting in */
lex->select_lex.table_list.first= (byte*) first_local_table->next;
/*
insert/replace from SELECT give its SELECT_LEX for SELECT,
and item_list belong to SELECT
*/
lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE;
res= handle_select(thd, lex, result);
/* revert changes for SP */
lex->select_lex.table_list.first= (byte*) first_local_table;
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
delete result;
if (thd->net.report_error)
res= -1;
res= -1;
}
else
res= -1;
@@ -3904,8 +3902,8 @@ mysql_init_select(LEX *lex)
select_lex->select_limit= HA_POS_ERROR;
if (select_lex == &lex->select_lex)
{
DBUG_ASSERT(lex->result == 0);
lex->exchange= 0;
lex->result= 0;
lex->proc_list.first= 0;
}
}
@@ -4047,9 +4045,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
query_cache_abort(&thd->net);
}
thd->proc_info="freeing items";
free_items(thd->free_list); /* Free strings used by items */
thd->free_list= 0;
lex_end(lex);
thd->end_statement();
}
DBUG_VOID_RETURN;
}
@@ -4074,10 +4070,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
if (!yyparse((void*) thd) && ! thd->is_fatal_error &&
all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
error= 1; /* Ignore question */
free_items(thd->free_list); /* Free strings used by items */
thd->free_list= 0;
lex_end(lex);
thd->end_statement();
return error;
}
#endif