Features of MySQL 4.1 and 5.0 put a new demand on the execution process: prepared statements and stored routines need to reuse the same parsed tree to execute a query many times.
So far no easy mechanism that would allow query reexecution using the conventional query processing code has been found. For instance, copying of the parsed tree before each reexecution is not simple to implement as a parsed tree, which can contain instances of more than 300 different classes, has a lot of cross-references between its objects.
The present solution introduces a concept of change management for the changes of the parsed tree and is largely a unification of numerous fixes of bugs in reexecution. The solution has two aspects.
The first one is that modifications of the parsed tree are tracked and a way to restore the tree to a state that allows reexecution is introduced.
The second aspect is that a dedicated block allocator (memory root) is used to store the parsed tree, and the memory allocated in this memory root is freed only when the parsed tree is destroyed. Later this memory root will be denoted as the permanent memory root of a statement.
In order to properly restore the parsed tree to a usable state, all modifications of the tree are classified as destructive or non-destructive and an appropriate action is taken for every type of modification.
A non-destructive modification does not depend on actual values of prepared statement placeholders or contents of the tables used in a query. Such modification is [and should be, for future changes] made only once and the memory for it is allocated in the permanent memory root of the statement.
As a result, the modified parsed tree remains usable.
Examples of non-destructive and useful modifications of the parsed tree are:
LEFT JOINelimination, when it can be done based on the constants explicitly specified in the query
The rest of modifications are destructive, generally because they are based on actual contents of tables or placeholders.
Examples of destructive modifications are:
Sorting of members of
INarray for quick evaluation of
Destructive modifications are (and should be for all future
changes) allocated in a memory root dedicated to execution, are
THD::change_list and rolled back
in the end of each execution. Later the memory root dedicated to
execution of a statement will be denoted as the runtime memory
root of the statement. Because allocations are done indirectly via
at any given moment of time can point either to the permanent or
to the runtime memory root of the statement. Consequently,
THD::free_list can be denoted as 'currently
active arena' of THD.