1 语法的表达:
语法中,不同的对象,都被Item和其子对象表示, 这样,我们可以方便的查阅/掌握SQL语句中不同的对象, 不同的类别(本系列第三篇表达的继承关系,可以区分类别)
2 SQL的执行:
对于SQL语句, SQL的执行过程,可以从对象入手跟踪. 如本节后面的示例,是一个小技巧,但实用(通过跟踪一个函数对象,来跟踪 SQL执行器对于多表连接的执行过程)
3 SQL的优化:
对于查询语句, 在优化阶段,尤其是涉及到"条件化简"的时候,要对不同的对象进行运算,这个时候掌握Item对象和其子类就很有必要了.
4 结果集的发送:
SQL执行, 产生出的结果集要发送到客户端,这个时候,依赖的对象,也是Item和其子类(如Item_field对象).
5 代码的分布情况:
可以看出以“Item”开头的一些文件(文件名称)和对象(对象名称),就知道一部分功能的实现位置了。如Item_fun.cc文件中可以找到MySQL提供的各类函数的实现代码。
应用示例:
目的: 跟踪多表连接的过程
存在的问题: 初次入手,不知道执行器具体的执行过程,想通过调用栈(call stack)查看函数调用情况.
小方法:
构造 如下SQL语句, 把断点设置在Item_fun.cc文件的longlong Item_func_abs::int_op()函数上。
select ABS(k1),k2,k3 from t1, t2, t3;
就可以得到如下的调用栈:
exec()->do_select()->sub_select()->sub_select_op()->JOIN_CACHE::end_send()->JOIN_CACHE::join_records()->JOIN_CACHE_BNL::join_matching_records()->JOIN_CACHE::generate_full_extensions()->end_send()->send_data()->Protocol::send_result_set_row ......
这样就能方便掌握执行器对于查询语句的基本执行过程了。
而关注如下代码,则可以跟进到发送结果集到客户端的相应代码中:
static enum_nested_loop_state
end_send(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
{......
List<Item> *fields= join_tab ? (join_tab-1)->fields : join->fields;
......
if (join->do_send_rows)
error=join->result->send_data(*fields);
......}
注意:Item不是表示所有对象的父类。