原创文章,转载请注明: 转载自 镜中影的技术博客
本文链接地址: OceanBase SQL解析源码分析(三)
URL:http://blog.csdn.net/linkpark1904/article/details/50779680
四、 Oceanbase SQL解析整体流程
基本上每一个SQL解析到最终物理任务执行经历的流程大同小异,从入口点开始,首先通过Flex和Bison生成的语法解析工具,对SQL进行语法解析,生成语法树。在生成的语法树的基础上,生成内部描述的逻辑计划,通过逻辑计划进行查询优化,生成具体的物理执行计划。
4.1 OceanBase词法语法解析
OceanBase词法语法解析在前面大都已经叙述完毕,这里OceanBase关于SQL解析部分的入口点在ob_sql.h文件中,入口函数如下所示:
/**
* execute the SQL statement directly
*
* @param stmt [in]
* @param result [out]
*
* @return oceanbase error code defined in ob_define.h
*/
static int direct_execute(const common::ObString &stmt, ObResultSet &result, ObSqlContext &context);
在函数的实现中可以看到这样一段代码:
parse_sql(&parse_result,stmt.ptr(),static_cast<size_t>(stmt.length())
这就进入了由Flex和Bison编译生成的词法语法解析器中,最终生成的语法树就存储在parse_result中,作为后续的逻辑计划生成的前提条件。
4.2 OceanBase逻辑计划生成
在OceanBase中,通过结构体ResultPlan来存储具体的逻辑计划结果,跟踪源代码,可以发现ResultPlan的定义在parse_node.h中,具体结构定义如下所示:
typedef struct
{
void* plan_tree_;
void* name_pool_; // ObStringBuf
void* schema_checker_; // ObSchemaChecker
ErrStat err_stat_;
int is_prepare_;
} ResultPlan;
Plan_tree_ 成员用来存储具体的逻辑计划树,name_pool_和OceanBase中的内存管理部分挂钩,schema_checker_为表结构的检查类,用来检查数据表是否有效,包括列检查等等相关操作。
ret = resolve(&result_plan, parse_result.result_tree_);
在这段代码中,输入参数包括存储逻辑计划结果的result_plan以及上一步解析生成的语法树也就是parse_result.result_tree_;所以逻辑计划的核心就在resolve函数中。
4.2.1 resolve函数
Resolve函数主要根据语法树来生成具体的逻辑计划,进入resolve函数后,发现实际上resolve函数是OceanBase逻辑计划生成对外暴露的一个接口,其内部由一系列reolve*函数来构成,具体代码在build_plan.cpp中,声明如下:
int resolve_crea