mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
- implement inheritance of sp_instr: public Query_arena.
We need every instruction to have its own arena, because we want to track instruction's state (INITIALIZED_FOR_SP -> EXECUTED). Because of `if' statements and other conditional instructions used in stored procedures, not every instruction of a stored procedure gets executed during the first (or even subsequent) execution of the procedure. So it's better if we track the execution state of every instruction independently. All instructions of a given procedure now also share sp_head's mem_root, but keep their own free_list. This simplifies juggling with free Item lists in sp_head::execute. - free_items() moved to be a member of Query_arena. - logic of 'backup_arena' debug member of Query_arena has been changed to support multi-backups. Until now, TRUE 'backup_arena' meant that there is exactly one active backup of the THD arena. Now it means simply that the arena is used for backup, so that we can't accidentally overwrite an existing backup. This allows doing multiple backups, e.g. in sp_head::execute and Cursor::fetch, when THD arena is already backed up but we want to set yet another arena (usually the 'permanent' arena, to save permanent transformations/optimizations of a parsed tree).
This commit is contained in:
@ -171,9 +171,6 @@ THD::THD()
|
||||
spcont(NULL)
|
||||
{
|
||||
current_arena= this;
|
||||
#ifndef DBUG_OFF
|
||||
backup_arena= 0;
|
||||
#endif
|
||||
host= user= priv_user= db= ip= 0;
|
||||
catalog= (char*)"std"; // the only catalog we have for now
|
||||
host_or_ip= "connecting host";
|
||||
@ -528,7 +525,7 @@ void THD::cleanup_after_query()
|
||||
next_insert_id= 0;
|
||||
}
|
||||
/* Free Items that were created during this execution */
|
||||
free_items(free_list);
|
||||
free_items();
|
||||
/*
|
||||
In the rest of code we assume that free_list never points to garbage:
|
||||
Keep this predicate true.
|
||||
@ -1485,6 +1482,21 @@ Query_arena::Type Query_arena::type() const
|
||||
}
|
||||
|
||||
|
||||
void Query_arena::free_items()
|
||||
{
|
||||
Item *next;
|
||||
DBUG_ENTER("Query_arena::free_items");
|
||||
/* This works because items are allocated with sql_alloc() */
|
||||
for (; free_list; free_list= next)
|
||||
{
|
||||
next= free_list->next;
|
||||
free_list->delete_self();
|
||||
}
|
||||
/* Postcondition: free_list is 0 */
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Statement functions
|
||||
*/
|
||||
@ -1556,11 +1568,11 @@ void THD::end_statement()
|
||||
void Query_arena::set_n_backup_item_arena(Query_arena *set, Query_arena *backup)
|
||||
{
|
||||
DBUG_ENTER("Query_arena::set_n_backup_item_arena");
|
||||
DBUG_ASSERT(backup_arena == 0);
|
||||
DBUG_ASSERT(backup->is_backup_arena == FALSE);
|
||||
backup->set_item_arena(this);
|
||||
set_item_arena(set);
|
||||
#ifndef DBUG_OFF
|
||||
backup_arena= 1;
|
||||
backup->is_backup_arena= TRUE;
|
||||
#endif
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -1569,10 +1581,11 @@ void Query_arena::set_n_backup_item_arena(Query_arena *set, Query_arena *backup)
|
||||
void Query_arena::restore_backup_item_arena(Query_arena *set, Query_arena *backup)
|
||||
{
|
||||
DBUG_ENTER("Query_arena::restore_backup_item_arena");
|
||||
DBUG_ASSERT(backup->is_backup_arena);
|
||||
set->set_item_arena(this);
|
||||
set_item_arena(backup);
|
||||
#ifndef DBUG_OFF
|
||||
backup_arena= 0;
|
||||
backup->is_backup_arena= FALSE;
|
||||
#endif
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
Reference in New Issue
Block a user