为了调用mysql_execute_command(执行一个语句的功能)一份事先准备好的声明中而不损害其解析树,我们备份和恢复活动Query_arena THD。
我们不希望执行期间产生的垃圾在永久的离开了竞技场的声明。确保,每个语句执行的运行时的舞台
野
。换句话说,当的舞台上活跃mysql_stmt_execute
被用作在其执行语句的运行时的舞台。在调用之前
mysql_stmt_execute
,我们官分配- >查询
使用参数标记(“?”)取代他们的价值观:在运行时分配新的查询。我们需要这个查询一般,二进制,错误和缓慢的日志。在准备阶段创建的执行计划不保存(见17.2节,“准备一份事先准备好的声明中”),在执行我们简单地创建一个新的连接,然后准备和优化它。在第一次执行事先准备好的声明中声明的服务器可能执行无损转换解析树:通常,属于一个单独的步骤执行语句准备,但再一次,这还没有在4.1或5.0完成。这样的转换必须使用的永久竞技场准备语句(保存在
螺纹- > stmt_arena
)。每当我们需要执行一个永久的转换,我们第一次电话::activate_stmt_arena_if_needed
永久的舞台上活跃,将树,和恢复运行时舞台。为了避免双重转换在这种情况下,我们跟踪解析树的当前状态Query_arena:状态
。这种状态可能是下列之一:
初始化
——我们在声明中准备
。INITIALIZED_FOR_SP
——我们在第一次执行存储过程的语句。准备
——我们在第一次执行一份事先准备好的声明中。执行
——我们在随后的执行准备语句或存储过程的语句。CONVENTIONAL_EXECUTION
——我们执行pre - 4.1查询。
一个可以使用的辅助方法
Query_arena
检查这个状态(is_conventional_execution ()
,is_stmt_prepare ()
,is_stmt_execute ()
,is_stmt_prepare_or_first_sp_execute ()
)。此外,
st_select_lex_unit: first_execution
包含一个国家的国旗每个子查询在一个复杂的语句。一个单独的变量是必要的,因为不是所有的子查询可能会在第一次执行期间执行的语句。解析树优化一些损害,例如,取代叶子和子树的项目与其他项目或离开与运行时数据条目对象凌乱。允许re-execution一份事先准备好的声明中以下机制目前使用:
的层次结构
项目::清理()
和st_select_lex:清理()
方法来恢复right-after-parse的条件的解析树。这些清理被称为Prepared_statement: cleanup_stmt ()
语句后执行。为了遏制破坏性的解析树的转换,每更换一个项目与另一个注册
::change_list
通过使用::change_item_tree ()
。最后执行所有这些变化都回滚在相反的顺序。例子:
如果(!(盛名= new Item_field (from_field)))转到错误;螺纹- > change_item_tree(参考,盛名);
如果变换是一种非破坏性,它不应该被注册,但是在永久性存储器根只执行一次。此外,小心不提供一个指针指向堆栈的第一个参数
change_item_tree ()
;这将导致堆栈腐败树时恢复。和
/或
子树的在哪里
和在
为每个执行条款重新创建。容易实现在4.1,变更记录列表中使用的方法(b)不可能被用于和
/或
转换,因为这些转换不仅一项替换为另一个单词,也可以删除一个完整的子树。树叶的和
/或
子树这种机制不是复制,因为目前他们并没有被转换。有关详细信息,请参见项目::copy_andor_structure ()
。没有其他机制目前存在于服务器允许re-execution。如果你要添加的代码转换解析树,您必须使用上面描述的机制之一,或提出并实现一种更好的方法。
当执行完成时,我们回滚的解析树的损害。