在ObLogicalPlan中,存储使用的是vector
2.4 逻辑计划中的Stmt的定义
Stmt表示一个单独的查询所包含的内容,一个逻辑计划可以包含多个Stmt.
class ObStmt
{
/*省略部分内容...*/
protected:
common::ObVector table_items_;
common::ObVector column_items_;
private:
StmtType type_;
uint64_t query_id_;
//uint64_t where_expr_id_;
common::ObVector where_expr_ids_;
};
Stmt包括了一个查询所有的表table_items_,列column_items_,表达式where_expr_ids_和一个唯一的查询标识query_id_。注意这里存储的只有表达式的id,而不是表达式的实际内容。
从上述的定义总结来看,一个逻辑计划拥有多条查询实例Stmt和多个表达式,一个查询实例Stmt包含了多个表和多个列及所需表达式的引用。表,列,表达式,查询实例都有唯一的标识符进行标记。
ObLogicalPlan
----ObStmt : 1...n
--------TableItem : 0...n
--------ColnumItem : 0...n
--------expr_id_ref : 0...n
----ObRawExpr : 0...n
三、 如何制定逻辑计划?
3.1 reslove系列解析函数
制定逻辑计划的源码在build_plan.h和build_plan.cpp中,在OceanBase0.4中,则增加了dml_build_plan.h和dml_build_plan.cpp。制定逻辑对外提供的接口只有两个,解析函数resolove和销毁函数destroy_plan,其他的为自用,可以浏览下其函数声明及用途,基本的结构就是这样,因为目前OceanBase中支持的SQL语句不多,相应的解析函数也比较少,还有一些没有完成,可以想见未来还会添加更多的函数。
//解析多重查询 int resolve_multi_stmt(ResultPlan* result_plan, ParseNode* node) //解析独立表达式 int resolve_independ_expr() //解析and表达式 int resolve_and_exprs() //解析表达式 int resolve_expr() //解析聚集函数 int resolve_agg_func() //解析join表连接 int resolve_joined_table() //解析表 int resolve_table() //解析from子句 int resolve_from_clause() //解析列 int resolve_table_columns() //解析* int resolve_star() //解析select的投影列表 int resolve_select_clause() //解析where子句 int resolve_where_clause() //解析group by子句 int resolve_group_clause() //解析having子句 int resolve_having_clause() //解析order子句 int resolve_order_clause() //解析limit子句 int resolve_limit_clause() //解析select查询 int resolve_select_stmt() //解析delete查询 int resolve_delete_stmt() //解析insert的插入列 int resolve_insert_columns() //解析intsert查询的插入值 int resolve_insert_values() //解析insert查询 int resolve_insert_stmt() //解析update查询 int resolve_update_stmt() //解析函数。对外提供 int resolve(ResultPlan* result_plan, ParseNode* node) //销毁函数,对外提供 extern void destroy_plan(ResultPlan* result_plan)
resolve函数根据语法树node的类型调用不同的查询解析实例。以下是部分代码摘抄:
int resolve(ResultPlan* result_plan, ParseNode* node)
{
/*...*/
uint64_t query_id = OB_INVALID_ID;
if (ret == OB_SUCCESS && node != NULL)
{
switch (node->type_)
{
case T_STMT_LIST:
{
ret = resolve_multi_stmt(result_plan, node);
break;
}
case T_SELECT:
{
ret = resolve_select_stmt(result_plan, node, query_id);
break;
}
case T_DELETE:
{
ret = resolve_delete_stmt(result_plan, node, query_id);
break;
}
case T_INSERT:
{
ret = resolve_insert_stmt(result_plan, node, query_id);
break;
}
case T_UPDATE:
{
ret = resolve_update_stmt(result_plan, node, query_id);
break;
}
default:
ret = OB_ERROR;
break;
};
}
return ret;
}
int resolve_update_stmt(ResultPlan* result_plan, ParseNode* node, uint64_t& query_id)
{
int& ret = result_plan->err_stat_.err_code_ = OB_SUCCESS;
uint64_t table_id = OB_INVALID_ID;
query_id = OB_INVALID_ID;
ObLogicalPlan* logical_plan logical_plan = new(logical_plan) ObLogicalPlan(name_pool);
result_plan->plan_tree_ = logical_plan;
update_stmt = new(update_stmt) ObUpdateStmt(name_pool);
query_id = logical_plan->generate_query_id();
//为update_stmt设置新的标识qid
update_stmt->set_query_id(query_id);
logical_plan->add_query(update_stmt);
Parse