淘宝数据库OceanBase SQL编译器部分 源码阅读--生成物理查询计划
淘宝数据库OceanBase SQL编译器部分 源码阅读--生成物理查询计划
SQL编译解析三部曲分为:构建语法树,制定逻辑计划,生成物理执行计划。前两个步骤请参见我的博客<<淘宝数据库OceanBase SQL编译器部分 源码阅读--解析SQL语法树>>和<<淘宝数据库OceanBase SQL编译器部分 源码阅读--生成逻辑计划>>.这篇博客主要研究第三步,生成物理查询计划。
一、 什么是物理查询计划
与之前的阅读方法一致,这篇博客的两个主要问题是what 和how。那么什么是物理查询计划?物理查询计划能够直接执行并返回数据结果数据。它包含了一系列的基本操作,比如选择,投影,聚集,排序等。因此,本质上,物理查询计划是一系列数据操作的有序集合。为了更好的研究关系数据的操作,有人提出了关系代数模型。而物理查询计划的基本原理就来自于关系代数模型。
1.1 关系代数
在《数据库系统原理及应用》等很多数据库相关书籍中都提到了关系代数。关系代数是SQL查询的理论支撑。
关系代数有六个原始元算符:“选择”、“投影”、笛卡尔积(也叫做“叉积”或“交叉连接”)、并集、差集和“重命名”。这些运算符作用于一个或多个关系上来生成一个新的关系。
- 选择(Selection) :在关系R中选择满足给定条件的诸元组。SQL 语句中的where子句就是该运算的最佳代表。
- 投影(Projection):从R中选择出若干属性列组成新的关系。SQL中Select 的列表时该运算的代表
- 连接(Join):连接也称为θ连接。它是从两个关系的笛卡尔积中选取属性间满足一定条件的元组。连接运算中有两种最为重要也最为常用的连接,一种是等值连接(equi-join),另一种是自然连接(Natural join)。 自然连接(Natural join)是一种特殊的等值连接,它要求两个关系中进行比较的分量必须是相同的属性组,并且要在结果中把重复的属性去掉。
- 重命名:它被简单的用来重命名关系的属性或关系自身。如SQL语句中的alias。
- 并集:是两个关系所有元组的集合
- 差集: A-B表示属于A但不属于B的元组集合
并集和差集的定义在数学中的定义基本相同。
1.2 流水线
如下面这条SQL:
select id,name,sex from student where sex='M' order by id;
执行这条SQL会用到多个操作符,如选择、投影、排序等。一种方法是以一定的顺序每次执行一个操作,每次计算的结果被实体化到一个临时关系中以备后用。实体化计算的代价包括所有运算的代价和把中间结果写回磁盘的代价。其中磁盘I/O的代价很高。
另一种方法是在流水线上同时执行多个运算,一个运算结果传递给下一个,而不必保存到临时关系中。在实现中,每个运算符有3个迭代函数:open
,close
,get_next
。
open
和close
分别为打开一个运算符,关闭一个运算符。get_next
函数用于获取一行元组。
二、 OceanBase中的物理查询计划
2.1 物理操作符
在0.3版本OceanBase中,物理上运算符接口为 ObPhyOperator
。其定义如下:
/// 物理运算符接口
class ObPhyOperator
{
public:
/// 打开物理运算符。申请资源,打开子运算符等。构造row description
virtual int open() = 0;
/// 关闭物理运算符。释放资源,关闭子运算符等。
virtual int close() = 0;
/// 获得下一行的引用
virtual int get_next_row(const common::ObRow *&row) = 0;
};
ObPhyOperator
定义了open
,close
,get_next_row
3个函数用于实现运算符的流水化操作。并根据子节点的个数定义了几种类型的运算符,它们都继承自ObPhyOperator
.
ObNoChildrenPhyOperator
:无子节点的运算符ObSingleChildPhyOperator
:只有一个子节点的运算符ObDoubleChildrenPhyOperator
:有两个子节点的运算符ObMultiChildrenPhyOperator
:有多个子节点的运算符(0.4版本才出现的)此外还有:
ObRowkeyPhyOperator
:(不是很清楚,自我觉得是)带返回RowKey的运算符,也就是返回的时候不是返回Row,而是返回RowKey。 磁盘表扫描运算符ObSstableScan
继承自该类。ObNoRowsPhyOperator
:无返回列的运算符,如插入运算符ObInsert
继承自该类
以上几个运算符依然是接口部分,真正使用时的运算符如同在关系代数中所说的一般,但SQL语句并不是完全的关系代数运算,为了方便实现时都会定义更多的运算符。
以下是0.3版本时的部分运算符及继承关系摘录:
运算符类名 | 父类 | 作用 |
---|---|---|
ObFilter | ObSingleChildPhyOperator | 选择运算符 |
ObProject | ObSingleChildPhyOperator | 投影运算符 |
ObGroupBy | ObSingleChildPhyOperator | 分组运算符 |
ObHashGroupBy | ObGroupBy | hash分组运算符 |
ObInsert | ObSingleChildPhyOperator,ObNoRowsPhyOperator | 插入运算符 |
ObJoin | ObDoubleChildrenPhyOperator | 连接运算符 |
ObLimit | ObSingleChildPhyOperator | 限制行数的运算符 |
ObMergeDistinct | ObSingleChildPhyOperator | 归并去重运算符 |
ObSort | ObSingleChildPhyOperator | 排序运算符 |
ObRpcScan | ObPhyOperator | MS全表扫描 |
ObSstableScan | ObRowkeyPhyOperator | 用于CS从磁盘或缓冲区扫描一个tablet |
ObTableScan | ObSingleChildPhyOperator | 全表扫描符 |
实际上还有很多运算符,这里没有一一列举,而且在后来的版本里还会有更多的运算符会被添加进来。
这些运算符是物理查询计划的主要构成。
2.2 物理查询计划的定义
物理查询计划由一系列运算符构成。OceanBase中物理查询计划ObPhysicalPlan定义如下:
class ObPhysicalPlan
{
/*省略其他方法*/
private:
oceanbase::common::ObArray<ObPhyOperator *> phy_querys_;
oceanbase::common::ObArray<ObPhyOperator *> operators_store_;
};
与逻辑计划类似,operators_store_
用于存储查询计划中使用到的所有运算符。在逻辑计划中我们已经知道,一个查询计划会有多个查询实例,在物理查询计划ObPhysicalPlan
中与之对应的是 phy_querys_
保存每个查询实例的第一个运算符。
三、 从逻辑计划如何生成物理查询计划
转换步骤很简单,添加逻辑计划,生存物理查询计划,示例代码如下:
trans.add_logical_plans(multi_plan);
physical_plan = trans.get_physical_plan(0);
trans
是转换类ObTransformer
类,该类的功能就是将逻辑计划转换为物理查询计划。
3.1 SQL的语法执行顺序
SQL作为一种声明式语言,它并不关心如何取数这个过程,而是通过SQL语句它声明它所需要的数据,有系统为其挑出符合要求的数据。
之前在讨论逻辑计划时,没有讨论到这一点,但是SQL的语法执行顺序直接影响了计划的生成过程。
SQL的语法顺序和执行顺序并不一致。以下面这条SQL为例:
select student.name,math.score, from student,math where student.sex='M' order by student.id;
其语法声明顺序为:
- SELECT
- FROM
- WHERE
- ORDER BY
但其执行顺序为:
- FROM
- WHERE
- SELECT
- ORDER BY
而物理查询计划,显然是以SQL执行顺序为准的。
3.2 OceanBase中生成物理查询计划的系列函数
逻辑计划生成物理查询计划或物理操作符的操作由下面一系列函数完成.
//物理查询计划生成函数
ObPhysicalPlan* ObTransformer::generate_physical_plan(ObLogicalPlan *logical_plan)
//select 语句-->物理查询计划
int64_t ObTransformer::gen_phy_mono_select
//order by -->排序运算符
ObPhyOperator* ObTransformer::gen_phy_order_by
//distinct-->去重运算符
ObPhyOperator* ObTransformer::gen_phy_distinct
//group by-->分组运算符
ObPhyOperator* ObTransformer::gen_phy_group_by
//聚集函数-->聚集运算符
ObPhyOperator* ObTransformer::gen_phy_scalar_aggregate
//表连接运算
int ObTransformer::gen_phy_joins
//from-->多表连接
int ObTransformer::gen_phy_tables
//表-->表扫描查询计划
ObPhyOperator* ObTransformer::gen_phy_table
//select语句-->物理查询计划,调用gen_phy_mono_select完成
ObPhysicalPlan* ObTransformer::gen_physical_select
//delete语句-->物理查询计划
ObPhysicalPlan* ObTransformer::gen_physical_delete
//insert语句-->物理查询计划
ObPhysicalPlan* ObTransformer::gen_physical_insert
//update语句-->物理查询计划
ObPhysicalPlan* ObTransformer::gen_physical_update
0.3中仅支持SELECT语句,其他语句还不支持。其生成逻辑在gen_phy_mono_select
中,与SQL的执行顺序一致.
int64_t ObTransformer::gen_phy_mono_select(
ObLogicalPlan *logical_plan,
ObPhysicalPlan *physical_plan,
uint64_t query_id)
{
//int err = OB_SUCCESS;
int64_t idx = OB_INVALID_INDEX;
ObSelectStmt *select_stmt = NULL;
if (query_id == OB_INVALID_ID)
select_stmt = dynamic_cast<ObSelectStmt*>(logical_plan->get_main_stmt());
else
select_stmt = dynamic_cast<ObSelectStmt*>(logical_plan->get_query(query_id));
if (!select_stmt)
return OB_INVALID_INDEX;
ObSelectStmt::SetOperator set_type = select_stmt->get_set_op();
if (set_type != ObSelectStmt::NONE)
{
//带set 的SELECT语句的物理查询计划生成
}
else
{
/* 普通Select语句*/
ObPhyOperator *result_op = NULL;
// 1. generate physical plan for base-table/outer-join-table/temporary table
ObList<ObPhyOperator*> phy_table_list;
ObList<ObBitSet> bitset_list;
ObList<ObSqlRawExpr*> remainder_cnd_list;
gen_phy_tables(
logical_plan,
select_stmt,
physical_plan,
phy_table_list,
bitset_list,
remainder_cnd_list);
// 2. Join all tables
if (phy_table_list.size() > 1)
gen_phy_joins(
logical_plan,
select_stmt,
physical_plan,
phy_table_list,
bitset_list,
remainder_cnd_list);
phy_table_list.pop_front(result_op);
// 3. add filter(s) to the join-op/table-scan-op result
if (remainder_cnd_list.size() >= 1)
{
ObFilter *filter_op = NULL;
CREATE_PHY_OPERRATOR(filter_op, ObFilter, physical_plan);
filter_op->set_child(0, *result_op);
oceanbase::common::ObList<ObSqlRawExpr*>::iterator cnd_it;
for (cnd_it = remainder_cnd_list.begin(); cnd_it != remainder_cnd_list.end(); cnd_it++)
{
ObSqlExpression filter;
(*cnd_it)->fill_sql_expression(filter, this, logical_plan, physical_plan);
filter_op->add_filter(filter);
}
result_op = filter_op;
}
// 4. generate physical plan for group by/aggregate
if (select_stmt->get_group_expr_size() > 0)
result_op = gen_phy_group_by(logical_plan, select_stmt, physical_plan, result_op);
else if (select_stmt->get_agg_fun_size() > 0)
result_op = gen_phy_scalar_aggregate(logical_plan, select_stmt, physical_plan, result_op);
// 5. generate physical plan for having
if (select_stmt->get_having_expr_size() > 0)
{
ObFilter *having_op = NULL;
CREATE_PHY_OPERRATOR(having_op, ObFilter, physical_plan);
ObSqlRawExpr *having_expr;
int32_t num = select_stmt->get_having_expr_size();
for (int32_t i = 0; i < num; i++)
{
having_expr = logical_plan->get_expr(select_stmt->get_having_expr_id(i));
ObSqlExpression having_filter;
having_expr->fill_sql_expression(having_filter, this, logical_plan, physical_plan);
having_op->add_filter(having_filter);
}
having_op->set_child(0, *result_op);
result_op = having_op;
}
// 6. generate physical plan for distinct
if (select_stmt->is_distinct())
result_op = gen_phy_distinct(logical_plan, select_stmt, physical_plan, result_op);
// 7. generate physical plan for order by
if (select_stmt->get_order_item_size() > 0)
result_op = gen_phy_order_by(logical_plan, select_stmt, physical_plan, result_op);
// 8. generate physical plan for limit
if (select_stmt->get_limit() != -1 || select_stmt->get_offset() != 0)
{
ObLimit *limit_op = NULL;
CREATE_PHY_OPERRATOR(limit_op, ObLimit, physical_plan);
limit_op->set_limit(select_stmt->get_limit(), select_stmt->get_offset());
limit_op->set_child(0, *result_op);
result_op = limit_op;
}
// 8. generate physical plan for select clause
if (select_stmt->get_select_item_size() > 0)
{
ObProject *project_op = NULL;
CREATE_PHY_OPERRATOR(project_op, ObProject, physical_plan);
project_op->set_child(0, *result_op);
ObSqlRawExpr *select_expr;
int32_t num = select_stmt->get_select_item_size();
for (int32_t i = 0; i < num; i++)
{
const SelectItem& select_item = select_stmt->get_select_item(i);
select_expr = logical_plan->get_expr(select_item.expr_id_);
if (select_item.is_real_alias_)
{
ObBinaryRefRawExpr col_raw(OB_INVALID_ID, select_expr->get_column_id(), T_REF_COLUMN);
ObSqlRawExpr col_sql_raw(*select_expr);
col_sql_raw.set_expr(&col_raw);
ObSqlExpression col_expr;
col_sql_raw.fill_sql_expression(col_expr);
project_op ->add_output_column(col_expr);
}
else
{
ObSqlExpression col_expr;
select_expr->fill_sql_expression(col_expr, this, logical_plan, physical_plan);
project_op ->add_output_column(col_expr);
}
}
result_op = project_op;
}
physical_plan->add_phy_query(result_op, idx);
}
return idx;
}
四、 总结
物理查询计划的生成过程比逻辑计划和语法树解析部分更复杂。你需要了解相关的基础知识包括关系代数查询,流水线方式下的运算符构成,SQL语法的执行顺序等。
欢迎光临我的网站----蝴蝶忽然的博客园----人既无名的专栏。
如果阅读本文过程中有任何问题,请联系作者,转载请注明出处!
%23%u6DD8%u5B9D%u6570%u636E%u5E93OceanBase%20SQL%u7F16%u8BD1%u5668%u90E8%u5206%20%u6E90%u7801%u9605%u8BFB--%u751F%u6210%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%0A%0A%3ESQL%u7F16%u8BD1%u89E3%u6790%u4E09%u90E8%u66F2%u5206%u4E3A%uFF1A%u6784%u5EFA%u8BED%u6CD5%u6811%uFF0C%u5236%u5B9A%u903B%u8F91%u8BA1%u5212%uFF0C%u751F%u6210%u7269%u7406%u6267%u884C%u8BA1%u5212%u3002%u524D%u4E24%u4E2A%u6B65%u9AA4%u8BF7%u53C2%u89C1%u6211%u7684%u535A%u5BA2%5B%3C%3C%u6DD8%u5B9D%u6570%u636E%u5E93OceanBase%20SQL%u7F16%u8BD1%u5668%u90E8%u5206%20%u6E90%u7801%u9605%u8BFB--%u89E3%u6790SQL%u8BED%u6CD5%u6811%3E%3E%5D%28http%3A//blog.csdn.net/qq910894904/article/details/28658421%29%u548C%5B%3C%3C%u6DD8%u5B9D%u6570%u636E%u5E93OceanBase%20SQL%u7F16%u8BD1%u5668%u90E8%u5206%20%u6E90%u7801%u9605%u8BFB--%u751F%u6210%u903B%u8F91%u8BA1%u5212%3E%3E%5D%28http%3A//blog.csdn.net/qq910894904/article/details/29364871%29.%u8FD9%u7BC7%u535A%u5BA2%u4E3B%u8981%u7814%u7A76%u7B2C%u4E09%u6B65%uFF0C%u751F%u6210%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%u3002%0A%0A%23%23%u4E00%u3001%20%u4EC0%u4E48%u662F%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%0A%u4E0E%u4E4B%u524D%u7684%u9605%u8BFB%u65B9%u6CD5%u4E00%u81F4%uFF0C%u8FD9%u7BC7%u535A%u5BA2%u7684%u4E24%u4E2A%u4E3B%u8981%u95EE%u9898%u662Fwhat%20%u548Chow%u3002%u90A3%u4E48%u4EC0%u4E48%u662F%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%uFF1F%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%u80FD%u591F%u76F4%u63A5%u6267%u884C%u5E76%u8FD4%u56DE%u6570%u636E%u7ED3%u679C%u6570%u636E%u3002%u5B83%u5305%u542B%u4E86%u4E00%u7CFB%u5217%u7684%u57FA%u672C%u64CD%u4F5C%uFF0C%u6BD4%u5982%u9009%u62E9%uFF0C%u6295%u5F71%uFF0C%u805A%u96C6%uFF0C%u6392%u5E8F%u7B49%u3002%u56E0%u6B64%uFF0C%u672C%u8D28%u4E0A%uFF0C**%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%u662F%u4E00%u7CFB%u5217%u6570%u636E%u64CD%u4F5C%u7684%u6709%u5E8F%u96C6%u5408**%u3002%u4E3A%u4E86%u66F4%u597D%u7684%u7814%u7A76%u5173%u7CFB%u6570%u636E%u7684%u64CD%u4F5C%uFF0C%u6709%u4EBA%u63D0%u51FA%u4E86**%u5173%u7CFB%u4EE3%u6570%u6A21%u578B**%u3002%u800C%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%u7684%u57FA%u672C%u539F%u7406%u5C31%u6765%u81EA%u4E8E%u5173%u7CFB%u4EE3%u6570%u6A21%u578B%u3002%0A%0A%23%23%231.1%20%u5173%u7CFB%u4EE3%u6570%0A%20%20%20%20%0A%u5728%u300A%u6570%u636E%u5E93%u7CFB%u7EDF%u539F%u7406%u53CA%u5E94%u7528%u300B%u7B49%u5F88%u591A%u6570%u636E%u5E93%u76F8%u5173%u4E66%u7C4D%u4E2D%u90FD%u63D0%u5230%u4E86%u5173%u7CFB%u4EE3%u6570%u3002%u5173%u7CFB%u4EE3%u6570%u662FSQL%u67E5%u8BE2%u7684%u7406%u8BBA%u652F%u6491%u3002%0A%u5173%u7CFB%u4EE3%u6570%u6709%u516D%u4E2A%u539F%u59CB%u5143%u7B97%u7B26%uFF1A%u201C%u9009%u62E9%u201D%u3001%u201C%u6295%u5F71%u201D%u3001%u7B1B%u5361%u5C14%u79EF%uFF08%u4E5F%u53EB%u505A%u201C%u53C9%u79EF%u201D%u6216%u201C%u4EA4%u53C9%u8FDE%u63A5%u201D%uFF09%u3001%u5E76%u96C6%u3001%u5DEE%u96C6%u548C%u201C%u91CD%u547D%u540D%u201D%u3002%u8FD9%u4E9B%u8FD0%u7B97%u7B26%u4F5C%u7528%u4E8E%u4E00%u4E2A%u6216%u591A%u4E2A%u5173%u7CFB%u4E0A%u6765%u751F%u6210%u4E00%u4E2A%u65B0%u7684%u5173%u7CFB%u3002%0A*%20**%u9009%u62E9%28Selection%29**%20%3A%u5728%u5173%u7CFBR%u4E2D%u9009%u62E9%u6EE1%u8DB3%u7ED9%u5B9A%u6761%u4EF6%u7684%u8BF8%u5143%u7EC4%u3002SQL%20%u8BED%u53E5%u4E2D%u7684where%u5B50%u53E5%u5C31%u662F%u8BE5%u8FD0%u7B97%u7684%u6700%u4F73%u4EE3%u8868%u3002%0A*%20**%u6295%u5F71%28Projection%29**%3A%u4ECER%u4E2D%u9009%u62E9%u51FA%u82E5%u5E72%u5C5E%u6027%u5217%u7EC4%u6210%u65B0%u7684%u5173%u7CFB%u3002SQL%u4E2DSelect%20%u7684%u5217%u8868%u65F6%u8BE5%u8FD0%u7B97%u7684%u4EE3%u8868%0A*%20**%u8FDE%u63A5%28Join%29**%3A%u8FDE%u63A5%u4E5F%u79F0%u4E3A%u03B8%u8FDE%u63A5%u3002%u5B83%u662F%u4ECE%u4E24%u4E2A%u5173%u7CFB%u7684%u7B1B%u5361%u5C14%u79EF%u4E2D%u9009%u53D6%u5C5E%u6027%u95F4%u6EE1%u8DB3%u4E00%u5B9A%u6761%u4EF6%u7684%u5143%u7EC4%u3002%u8FDE%u63A5%u8FD0%u7B97%u4E2D%u6709%u4E24%u79CD%u6700%u4E3A%u91CD%u8981%u4E5F%u6700%u4E3A%u5E38%u7528%u7684%u8FDE%u63A5%uFF0C%u4E00%u79CD%u662F**%u7B49%u503C%u8FDE%u63A5**%uFF08equi-join%uFF09%uFF0C%u53E6%u4E00%u79CD%u662F**%u81EA%u7136%u8FDE%u63A5**%uFF08Natural%20join%uFF09%u3002%20%u81EA%u7136%u8FDE%u63A5%uFF08Natural%20join%uFF09%u662F%u4E00%u79CD%u7279%u6B8A%u7684%u7B49%u503C%u8FDE%u63A5%uFF0C%u5B83%u8981%u6C42%u4E24%u4E2A%u5173%u7CFB%u4E2D%u8FDB%u884C%u6BD4%u8F83%u7684%u5206%u91CF%u5FC5%u987B%u662F%u76F8%u540C%u7684%u5C5E%u6027%u7EC4%uFF0C%u5E76%u4E14%u8981%u5728%u7ED3%u679C%u4E2D%u628A%u91CD%u590D%u7684%u5C5E%u6027%u53BB%u6389%u3002%20%0A*%20**%u91CD%u547D%u540D**%uFF1A%u5B83%u88AB%u7B80%u5355%u7684%u7528%u6765%u91CD%u547D%u540D%u5173%u7CFB%u7684%u5C5E%u6027%u6216%u5173%u7CFB%u81EA%u8EAB%u3002%u5982SQL%u8BED%u53E5%u4E2D%u7684alias%u3002%0A*%20**%u5E76%u96C6**%uFF1A%u662F%u4E24%u4E2A%u5173%u7CFB%u6240%u6709%u5143%u7EC4%u7684%u96C6%u5408%0A*%20**%u5DEE%u96C6**%3A%20A-B%u8868%u793A%u5C5E%u4E8EA%u4F46%u4E0D%u5C5E%u4E8EB%u7684%u5143%u7EC4%u96C6%u5408%0A%20%20%20%20%0A%u5E76%u96C6%u548C%u5DEE%u96C6%u7684%u5B9A%u4E49%u5728%u6570%u5B66%u4E2D%u7684%u5B9A%u4E49%u57FA%u672C%u76F8%u540C%u3002%0A%0A%23%23%231.2%20%u6D41%u6C34%u7EBF%0A%0A%u5982%u4E0B%u9762%u8FD9%u6761SQL%uFF1A%0A%0A%60%60%60%0Aselect%20id%2Cname%2Csex%20from%20student%20where%20sex%3D%27M%27%20order%20by%20id%3B%0A%60%60%60%0A%0A%u6267%u884C%u8FD9%u6761SQL%u4F1A%u7528%u5230%u591A%u4E2A%u64CD%u4F5C%u7B26%uFF0C%u5982%u9009%u62E9%u3001%u6295%u5F71%u3001%u6392%u5E8F%u7B49%u3002%u4E00%u79CD%u65B9%u6CD5%u662F%u4EE5%u4E00%u5B9A%u7684%u987A%u5E8F%u6BCF%u6B21%u6267%u884C%u4E00%u4E2A%u64CD%u4F5C%uFF0C%u6BCF%u6B21%u8BA1%u7B97%u7684%u7ED3%u679C%u88AB%u5B9E%u4F53%u5316%u5230%u4E00%u4E2A%u4E34%u65F6%u5173%u7CFB%u4E2D%u4EE5%u5907%u540E%u7528%u3002%u5B9E%u4F53%u5316%u8BA1%u7B97%u7684%u4EE3%u4EF7%u5305%u62EC%u6240%u6709%u8FD0%u7B97%u7684%u4EE3%u4EF7%u548C%u628A%u4E2D%u95F4%u7ED3%u679C%u5199%u56DE%u78C1%u76D8%u7684%u4EE3%u4EF7%u3002%u5176%u4E2D%u78C1%u76D8I/O%u7684%u4EE3%u4EF7%u5F88%u9AD8%u3002%0A%u53E6%u4E00%u79CD%u65B9%u6CD5%u662F%u5728**%u6D41%u6C34%u7EBF**%u4E0A%u540C%u65F6%u6267%u884C%u591A%u4E2A%u8FD0%u7B97%uFF0C%u4E00%u4E2A%u8FD0%u7B97%u7ED3%u679C%u4F20%u9012%u7ED9%u4E0B%u4E00%u4E2A%uFF0C%u800C%u4E0D%u5FC5%u4FDD%u5B58%u5230%u4E34%u65F6%u5173%u7CFB%u4E2D%u3002%u5728%u5B9E%u73B0%u4E2D%uFF0C%u6BCF%u4E2A%u8FD0%u7B97%u7B26%u67093%u4E2A%u8FED%u4EE3%u51FD%u6570%uFF1A%60open%60%2C%60close%60%2C%60get_next%60%u3002%0A%60open%60%u548C%60close%60%u5206%u522B%u4E3A%u6253%u5F00%u4E00%u4E2A%u8FD0%u7B97%u7B26%uFF0C%u5173%u95ED%u4E00%u4E2A%u8FD0%u7B97%u7B26%u3002%60get_next%60%u51FD%u6570%u7528%u4E8E%u83B7%u53D6%u4E00%u884C%u5143%u7EC4%u3002%0A%0A%23%23%u4E8C%u3001%20OceanBase%u4E2D%u7684%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%0A%0A%23%23%232.1%20%u7269%u7406%u64CD%u4F5C%u7B26%0A%0A%u57280.3%u7248%u672COceanBase%u4E2D%uFF0C%u7269%u7406%u4E0A%u8FD0%u7B97%u7B26%u63A5%u53E3%u4E3A%20%60ObPhyOperator%60%u3002%u5176%u5B9A%u4E49%u5982%u4E0B%uFF1A%0A%0A%60%60%60%0A///%20%u7269%u7406%u8FD0%u7B97%u7B26%u63A5%u53E3%0A%20%20%20%20class%20ObPhyOperator%0A%20%20%20%20%7B%0A%20%20%20%20%20%20public%3A%0A%20%20%20%20%20%20%20%20///%20%u6253%u5F00%u7269%u7406%u8FD0%u7B97%u7B26%u3002%u7533%u8BF7%u8D44%u6E90%uFF0C%u6253%u5F00%u5B50%u8FD0%u7B97%u7B26%u7B49%u3002%u6784%u9020row%20description%0A%20%20%20%20%20%20%20%20virtual%20int%20open%28%29%20%3D%200%3B%0A%0A%20%20%20%20%20%20%20%20///%20%u5173%u95ED%u7269%u7406%u8FD0%u7B97%u7B26%u3002%u91CA%u653E%u8D44%u6E90%uFF0C%u5173%u95ED%u5B50%u8FD0%u7B97%u7B26%u7B49%u3002%0A%20%20%20%20%20%20%20%20virtual%20int%20close%28%29%20%3D%200%3B%0A%0A%20%20%20%20%20%20%20%20///%20%u83B7%u5F97%u4E0B%u4E00%u884C%u7684%u5F15%u7528%0A%20%20%20%20%20%20%20%20virtual%20int%20get_next_row%28const%20common%3A%3AObRow%20*%26row%29%20%3D%200%3B%0A%20%20%20%20%7D%3B%0A%60%60%60%0A%60ObPhyOperator%60%u5B9A%u4E49%u4E86%60open%60%2C%60close%60%2C%60get_next_row%60%203%u4E2A%u51FD%u6570%u7528%u4E8E%u5B9E%u73B0%u8FD0%u7B97%u7B26%u7684%u6D41%u6C34%u5316%u64CD%u4F5C%u3002%u5E76%u6839%u636E%u5B50%u8282%u70B9%u7684%u4E2A%u6570%u5B9A%u4E49%u4E86%u51E0%u79CD%u7C7B%u578B%u7684%u8FD0%u7B97%u7B26%uFF0C%u5B83%u4EEC%u90FD%u7EE7%u627F%u81EA%60ObPhyOperator%60.%0A-%20%20%60ObNoChildrenPhyOperator%60%3A%u65E0%u5B50%u8282%u70B9%u7684%u8FD0%u7B97%u7B26%0A-%20%20%60ObSingleChildPhyOperator%60%3A%u53EA%u6709%u4E00%u4E2A%u5B50%u8282%u70B9%u7684%u8FD0%u7B97%u7B26%0A-%20%20%60ObDoubleChildrenPhyOperator%60%uFF1A%u6709%u4E24%u4E2A%u5B50%u8282%u70B9%u7684%u8FD0%u7B97%u7B26%0A-%20%20%60ObMultiChildrenPhyOperator%60%3A%u6709%u591A%u4E2A%u5B50%u8282%u70B9%u7684%u8FD0%u7B97%u7B26%uFF080.4%u7248%u672C%u624D%u51FA%u73B0%u7684%uFF09%0A%u6B64%u5916%u8FD8%u6709%3A%0A-%20%20%60ObRowkeyPhyOperator%60%3A%28_%u4E0D%u662F%u5F88%u6E05%u695A%2C%u81EA%u6211%u89C9%u5F97%u662F_%29%u5E26%u8FD4%u56DERowKey%u7684%u8FD0%u7B97%u7B26%2C%u4E5F%u5C31%u662F%u8FD4%u56DE%u7684%u65F6%u5019%u4E0D%u662F%u8FD4%u56DERow%uFF0C%u800C%u662F%u8FD4%u56DERowKey%u3002%20%u78C1%u76D8%u8868%u626B%u63CF%u8FD0%u7B97%u7B26%60ObSstableScan%60%u7EE7%u627F%u81EA%u8BE5%u7C7B%u3002%0A-%20%20%60ObNoRowsPhyOperator%60%3A%u65E0%u8FD4%u56DE%u5217%u7684%u8FD0%u7B97%u7B26%2C%u5982%u63D2%u5165%u8FD0%u7B97%u7B26%60ObInsert%60%u7EE7%u627F%u81EA%u8BE5%u7C7B%0A%0A%u4EE5%u4E0A%u51E0%u4E2A%u8FD0%u7B97%u7B26%u4F9D%u7136%u662F%u63A5%u53E3%u90E8%u5206%uFF0C%u771F%u6B63%u4F7F%u7528%u65F6%u7684%u8FD0%u7B97%u7B26%u5982%u540C%u5728%u5173%u7CFB%u4EE3%u6570%u4E2D%u6240%u8BF4%u7684%u4E00%u822C%uFF0C%u4F46SQL%u8BED%u53E5%u5E76%u4E0D%u662F%u5B8C%u5168%u7684%u5173%u7CFB%u4EE3%u6570%u8FD0%u7B97%uFF0C%u4E3A%u4E86%u65B9%u4FBF%u5B9E%u73B0%u65F6%u90FD%u4F1A%u5B9A%u4E49%u66F4%u591A%u7684%u8FD0%u7B97%u7B26%u3002%0A%u4EE5%u4E0B%u662F0.3%u7248%u672C%u65F6%u7684**%u90E8%u5206%u8FD0%u7B97%u7B26**%u53CA%u7EE7%u627F%u5173%u7CFB%u6458%u5F55%uFF1A%0A%0A%7C%u8FD0%u7B97%u7B26%u7C7B%u540D%7C%u7236%u7C7B%7C%u4F5C%u7528%7C%0A%7C%3A--%7C%3A--%7C%3A--%7C%0A%7CObFilter%7CObSingleChildPhyOperator%7C%u9009%u62E9%u8FD0%u7B97%u7B26%0A%7CObProject%7C%20ObSingleChildPhyOperator%7C%u6295%u5F71%u8FD0%u7B97%u7B26%0A%7CObGroupBy%7CObSingleChildPhyOperator%7C%u5206%u7EC4%u8FD0%u7B97%u7B26%0A%7CObHashGroupBy%7CObGroupBy%7Chash%u5206%u7EC4%u8FD0%u7B97%u7B26%0A%7CObInsert%7CObSingleChildPhyOperator%2CObNoRowsPhyOperator%7C%u63D2%u5165%u8FD0%u7B97%u7B26%0A%7CObJoin%7CObDoubleChildrenPhyOperator%7C%u8FDE%u63A5%u8FD0%u7B97%u7B26%0A%7CObLimit%7CObSingleChildPhyOperator%7C%u9650%u5236%u884C%u6570%u7684%u8FD0%u7B97%u7B26%0A%7CObMergeDistinct%7CObSingleChildPhyOperator%7C%u5F52%u5E76%u53BB%u91CD%u8FD0%u7B97%u7B26%0A%7CObSort%7CObSingleChildPhyOperator%7C%u6392%u5E8F%u8FD0%u7B97%u7B26%0A%7CObRpcScan%7CObPhyOperator%7CMS%u5168%u8868%u626B%u63CF%0A%7CObSstableScan%7CObRowkeyPhyOperator%7C%u7528%u4E8ECS%u4ECE%u78C1%u76D8%u6216%u7F13%u51B2%u533A%u626B%u63CF%u4E00%u4E2Atablet%0A%7CObTableScan%7CObSingleChildPhyOperator%7C%u5168%u8868%u626B%u63CF%u7B26%0A%0A%u5B9E%u9645%u4E0A%u8FD8%u6709%u5F88%u591A%u8FD0%u7B97%u7B26%uFF0C%u8FD9%u91CC%u6CA1%u6709%u4E00%u4E00%u5217%u4E3E%uFF0C%u800C%u4E14%u5728%u540E%u6765%u7684%u7248%u672C%u91CC%u8FD8%u4F1A%u6709%u66F4%u591A%u7684%u8FD0%u7B97%u7B26%u4F1A%u88AB%u6DFB%u52A0%u8FDB%u6765%u3002%0A%u8FD9%u4E9B%u8FD0%u7B97%u7B26%u662F%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%u7684%u4E3B%u8981%u6784%u6210%u3002%0A%0A%23%23%232.2%20%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%u7684%u5B9A%u4E49%0A%0A%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%u7531%u4E00%u7CFB%u5217%u8FD0%u7B97%u7B26%u6784%u6210%u3002OceanBase%u4E2D%u7269%u7406%u67E5%u8BE2%u8BA1%u5212ObPhysicalPlan%u5B9A%u4E49%u5982%u4E0B%uFF1A%0A%60%60%60%0Aclass%20ObPhysicalPlan%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20/*%u7701%u7565%u5176%u4ED6%u65B9%u6CD5*/%0A%20%20%20%20%20%20private%3A%0A%20%20%20%20%20%20%20%20oceanbase%3A%3Acommon%3A%3AObArray%3CObPhyOperator%20*%3E%20phy_querys_%3B%0A%20%20%20%20%20%20%20%20oceanbase%3A%3Acommon%3A%3AObArray%3CObPhyOperator%20*%3E%20operators_store_%3B%0A%20%20%20%20%7D%3B%0A%60%60%60%0A%u4E0E%u903B%u8F91%u8BA1%u5212%u7C7B%u4F3C%2C%60operators_store_%60%u7528%u4E8E%u5B58%u50A8%u67E5%u8BE2%u8BA1%u5212%u4E2D%u4F7F%u7528%u5230%u7684%u6240%u6709%u8FD0%u7B97%u7B26%u3002%u5728%u903B%u8F91%u8BA1%u5212%u4E2D%u6211%u4EEC%u5DF2%u7ECF%u77E5%u9053%uFF0C%u4E00%u4E2A%u67E5%u8BE2%u8BA1%u5212%u4F1A%u6709%u591A%u4E2A%u67E5%u8BE2%u5B9E%u4F8B%uFF0C%u5728%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%60ObPhysicalPlan%60%u4E2D%u4E0E%u4E4B%u5BF9%u5E94%u7684%u662F%20%60phy_querys_%60%20%u4FDD%u5B58%u6BCF%u4E2A%u67E5%u8BE2%u5B9E%u4F8B%u7684%u7B2C%u4E00%u4E2A%u8FD0%u7B97%u7B26%u3002%0A%0A%0A%23%23%u4E09%u3001%20%u4ECE%u903B%u8F91%u8BA1%u5212%u5982%u4F55%u751F%u6210%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%0A%0A%u8F6C%u6362%u6B65%u9AA4%u5F88%u7B80%u5355%uFF0C%u6DFB%u52A0%u903B%u8F91%u8BA1%u5212%uFF0C%u751F%u5B58%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%uFF0C%u793A%u4F8B%u4EE3%u7801%u5982%u4E0B%uFF1A%0A%60trans.add_logical_plans%28multi_plan%29%3B%60%0A%60physical_plan%20%3D%20trans.get_physical_plan%280%29%3B%60%0A%0A%60trans%60%u662F%u8F6C%u6362%u7C7B%60ObTransformer%60%u7C7B%2C%u8BE5%u7C7B%u7684%u529F%u80FD%u5C31%u662F%u5C06%u903B%u8F91%u8BA1%u5212%u8F6C%u6362%u4E3A%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%u3002%0A%0A%23%23%233.1%20SQL%u7684%u8BED%u6CD5%u6267%u884C%u987A%u5E8F%0A%0ASQL%u4F5C%u4E3A%u4E00%u79CD%u58F0%u660E%u5F0F%u8BED%u8A00%uFF0C%u5B83%u5E76%u4E0D%u5173%u5FC3%u5982%u4F55%u53D6%u6570%u8FD9%u4E2A%u8FC7%u7A0B%uFF0C%u800C%u662F%u901A%u8FC7SQL%u8BED%u53E5%u5B83%u58F0%u660E%u5B83%u6240%u9700%u8981%u7684%u6570%u636E%uFF0C%u6709%u7CFB%u7EDF%u4E3A%u5176%u6311%u51FA%u7B26%u5408%u8981%u6C42%u7684%u6570%u636E%u3002%0A%u4E4B%u524D%u5728%u8BA8%u8BBA%u903B%u8F91%u8BA1%u5212%u65F6%uFF0C%u6CA1%u6709%u8BA8%u8BBA%u5230%u8FD9%u4E00%u70B9%uFF0C%u4F46%u662FSQL%u7684%u8BED%u6CD5%u6267%u884C%u987A%u5E8F%u76F4%u63A5%u5F71%u54CD%u4E86%u8BA1%u5212%u7684%u751F%u6210%u8FC7%u7A0B%u3002%0ASQL%u7684%u8BED%u6CD5%u987A%u5E8F%u548C%u6267%u884C%u987A%u5E8F%u5E76%u4E0D%u4E00%u81F4%u3002%u4EE5%u4E0B%u9762%u8FD9%u6761SQL%u4E3A%u4F8B%uFF1A%0A%60%60%60%0Aselect%20student.name%2Cmath.score%2C%20from%20student%2Cmath%20where%20student.sex%3D%27M%27%20order%20by%20student.id%3B%0A%60%60%60%0A%0A%u5176%u8BED%u6CD5%u58F0%u660E%u987A%u5E8F%u4E3A%uFF1A%0A*%20SELECT%0A*%20FROM%0A*%20WHERE%0A*%20ORDER%20BY%0A%0A%u4F46%u5176%u6267%u884C%u987A%u5E8F%u4E3A%uFF1A%0A*%20FROM%0A*%20WHERE%0A*%20SELECT%0A*%20ORDER%20BY%0A%0A%u800C**%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%uFF0C%u663E%u7136%u662F%u4EE5SQL%u6267%u884C%u987A%u5E8F%u4E3A%u51C6%u7684**%u3002%0A%23%23%233.2%20OceanBase%u4E2D%u751F%u6210%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%u7684%u7CFB%u5217%u51FD%u6570%0A%u903B%u8F91%u8BA1%u5212%u751F%u6210%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%u6216%u7269%u7406%u64CD%u4F5C%u7B26%u7684%u64CD%u4F5C%u7531%u4E0B%u9762%u4E00%u7CFB%u5217%u51FD%u6570%u5B8C%u6210.%0A%60%60%60%0A//%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%u751F%u6210%u51FD%u6570%0AObPhysicalPlan*%20ObTransformer%3A%3Agenerate_physical_plan%28ObLogicalPlan%20*logical_plan%29%0A%0A//select%20%u8BED%u53E5--%3E%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%0Aint64_t%20ObTransformer%3A%3Agen_phy_mono_select%0A//order%20by%20--%3E%u6392%u5E8F%u8FD0%u7B97%u7B26%0AObPhyOperator*%20ObTransformer%3A%3Agen_phy_order_by%0A//distinct--%3E%u53BB%u91CD%u8FD0%u7B97%u7B26%0AObPhyOperator*%20ObTransformer%3A%3Agen_phy_distinct%0A//group%20by--%3E%u5206%u7EC4%u8FD0%u7B97%u7B26%0AObPhyOperator*%20ObTransformer%3A%3Agen_phy_group_by%0A//%u805A%u96C6%u51FD%u6570--%3E%u805A%u96C6%u8FD0%u7B97%u7B26%0AObPhyOperator*%20ObTransformer%3A%3Agen_phy_scalar_aggregate%0A//%u8868%u8FDE%u63A5%u8FD0%u7B97%0Aint%20ObTransformer%3A%3Agen_phy_joins%0A//from--%3E%u591A%u8868%u8FDE%u63A5%0Aint%20ObTransformer%3A%3Agen_phy_tables%0A//%u8868--%3E%u8868%u626B%u63CF%u67E5%u8BE2%u8BA1%u5212%0AObPhyOperator*%20ObTransformer%3A%3Agen_phy_table%0A//select%u8BED%u53E5--%3E%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%2C%u8C03%u7528gen_phy_mono_select%u5B8C%u6210%0AObPhysicalPlan*%20ObTransformer%3A%3Agen_physical_select%0A//delete%u8BED%u53E5--%3E%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%0AObPhysicalPlan*%20ObTransformer%3A%3Agen_physical_delete%0A//insert%u8BED%u53E5--%3E%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%0AObPhysicalPlan*%20ObTransformer%3A%3Agen_physical_insert%0A//update%u8BED%u53E5--%3E%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%0AObPhysicalPlan*%20ObTransformer%3A%3Agen_physical_update%0A%60%60%60%0A0.3%u4E2D%u4EC5%u652F%u6301SELECT%u8BED%u53E5%uFF0C%u5176%u4ED6%u8BED%u53E5%u8FD8%u4E0D%u652F%u6301%u3002%u5176%u751F%u6210%u903B%u8F91%u5728%60gen_phy_mono_select%60%u4E2D%uFF0C%u4E0ESQL%u7684%u6267%u884C%u987A%u5E8F%u4E00%u81F4.%0A%0A%60%60%60%0Aint64_t%20ObTransformer%3A%3Agen_phy_mono_select%28%0A%20%20%20%20ObLogicalPlan%20*logical_plan%2C%0A%20%20%20%20ObPhysicalPlan%20*physical_plan%2C%0A%20%20%20%20uint64_t%20query_id%29%0A%7B%0A%20%20//int%20err%20%3D%20OB_SUCCESS%3B%0A%20%20int64_t%20idx%20%3D%20OB_INVALID_INDEX%3B%0A%20%20ObSelectStmt%20*select_stmt%20%3D%20NULL%3B%0A%20%20if%20%28query_id%20%3D%3D%20OB_INVALID_ID%29%0A%20%20%20%20select_stmt%20%3D%20dynamic_cast%3CObSelectStmt*%3E%28logical_plan-%3Eget_main_stmt%28%29%29%3B%0A%20%20else%0A%20%20%20%20select_stmt%20%3D%20dynamic_cast%3CObSelectStmt*%3E%28logical_plan-%3Eget_query%28query_id%29%29%3B%0A%20%20if%20%28%21select_stmt%29%0A%20%20%20%20return%20OB_INVALID_INDEX%3B%0A%0A%20%20ObSelectStmt%3A%3ASetOperator%20set_type%20%3D%20select_stmt-%3Eget_set_op%28%29%3B%0A%20%20if%20%28set_type%20%21%3D%20ObSelectStmt%3A%3ANONE%29%0A%20%20%7B%0A%20%20%20%20//%u5E26set%20%u7684SELECT%u8BED%u53E5%u7684%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%u751F%u6210%0A%20%20%7D%0A%20%20else%0A%20%20%7B%0A%20%20%20%20/*%20%u666E%u901ASelect%u8BED%u53E5*/%0A%0A%20%20%20%20ObPhyOperator%20*result_op%20%3D%20NULL%3B%0A%0A%20%20%20%20//%201.%20generate%20physical%20plan%20for%20base-table/outer-join-table/temporary%20table%0A%20%20%20%20ObList%3CObPhyOperator*%3E%20phy_table_list%3B%0A%20%20%20%20ObList%3CObBitSet%3E%20bitset_list%3B%0A%20%20%20%20ObList%3CObSqlRawExpr*%3E%20remainder_cnd_list%3B%0A%20%20%20%20gen_phy_tables%28%0A%20%20%20%20%20%20%20%20logical_plan%2C%0A%20%20%20%20%20%20%20%20select_stmt%2C%0A%20%20%20%20%20%20%20%20physical_plan%2C%0A%20%20%20%20%20%20%20%20phy_table_list%2C%0A%20%20%20%20%20%20%20%20bitset_list%2C%0A%20%20%20%20%20%20%20%20remainder_cnd_list%29%3B%0A%0A%20%20%20%20//%202.%20Join%20all%20tables%0A%20%20%20%20if%20%28phy_table_list.size%28%29%20%3E%201%29%0A%20%20%20%20%20%20gen_phy_joins%28%0A%20%20%20%20%20%20%20%20%20%20logical_plan%2C%0A%20%20%20%20%20%20%20%20%20%20select_stmt%2C%0A%20%20%20%20%20%20%20%20%20%20physical_plan%2C%0A%20%20%20%20%20%20%20%20%20%20phy_table_list%2C%0A%20%20%20%20%20%20%20%20%20%20bitset_list%2C%0A%20%20%20%20%20%20%20%20%20%20remainder_cnd_list%29%3B%0A%20%20%20%20phy_table_list.pop_front%28result_op%29%3B%0A%0A%20%20%20%20//%203.%20add%20filter%28s%29%20to%20the%20join-op/table-scan-op%20result%0A%20%20%20%20if%20%28remainder_cnd_list.size%28%29%20%3E%3D%201%29%0A%20%20%20%20%7B%0A%20%20%20%20%20%20ObFilter%20*filter_op%20%3D%20NULL%3B%0A%20%20%20%20%20%20CREATE_PHY_OPERRATOR%28filter_op%2C%20ObFilter%2C%20physical_plan%29%3B%0A%20%20%20%20%20%20filter_op-%3Eset_child%280%2C%20*result_op%29%3B%0A%20%20%20%20%20%20oceanbase%3A%3Acommon%3A%3AObList%3CObSqlRawExpr*%3E%3A%3Aiterator%20cnd_it%3B%0A%20%20%20%20%20%20for%20%28cnd_it%20%3D%20remainder_cnd_list.begin%28%29%3B%20cnd_it%20%21%3D%20remainder_cnd_list.end%28%29%3B%20cnd_it++%29%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20ObSqlExpression%20filter%3B%0A%20%20%20%20%20%20%20%20%28*cnd_it%29-%3Efill_sql_expression%28filter%2C%20this%2C%20logical_plan%2C%20physical_plan%29%3B%0A%20%20%20%20%20%20%20%20filter_op-%3Eadd_filter%28filter%29%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20result_op%20%3D%20filter_op%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%204.%20generate%20physical%20plan%20for%20group%20by/aggregate%0A%20%20%20%20if%20%28select_stmt-%3Eget_group_expr_size%28%29%20%3E%200%29%0A%20%20%20%20%20%20result_op%20%3D%20gen_phy_group_by%28logical_plan%2C%20select_stmt%2C%20physical_plan%2C%20result_op%29%3B%0A%20%20%20%20else%20if%20%28select_stmt-%3Eget_agg_fun_size%28%29%20%3E%200%29%0A%20%20%20%20%20%20result_op%20%3D%20gen_phy_scalar_aggregate%28logical_plan%2C%20select_stmt%2C%20physical_plan%2C%20result_op%29%3B%0A%0A%20%20%20%20//%205.%20generate%20physical%20plan%20for%20having%0A%20%20%20%20if%20%28select_stmt-%3Eget_having_expr_size%28%29%20%3E%200%29%0A%20%20%20%20%7B%0A%20%20%20%20%20%20ObFilter%20*having_op%20%3D%20NULL%3B%0A%20%20%20%20%20%20CREATE_PHY_OPERRATOR%28having_op%2C%20ObFilter%2C%20physical_plan%29%3B%0A%20%20%20%20%20%20ObSqlRawExpr%20*having_expr%3B%0A%20%20%20%20%20%20int32_t%20num%20%3D%20select_stmt-%3Eget_having_expr_size%28%29%3B%0A%20%20%20%20%20%20for%20%28int32_t%20i%20%3D%200%3B%20i%20%3C%20num%3B%20i++%29%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20having_expr%20%3D%20logical_plan-%3Eget_expr%28select_stmt-%3Eget_having_expr_id%28i%29%29%3B%0A%20%20%20%20%20%20%20%20ObSqlExpression%20having_filter%3B%0A%20%20%20%20%20%20%20%20having_expr-%3Efill_sql_expression%28having_filter%2C%20this%2C%20logical_plan%2C%20physical_plan%29%3B%0A%20%20%20%20%20%20%20%20having_op-%3Eadd_filter%28having_filter%29%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20having_op-%3Eset_child%280%2C%20*result_op%29%3B%0A%20%20%20%20%20%20result_op%20%3D%20having_op%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%206.%20generate%20physical%20plan%20for%20distinct%0A%20%20%20%20if%20%28select_stmt-%3Eis_distinct%28%29%29%0A%20%20%20%20%20%20result_op%20%3D%20gen_phy_distinct%28logical_plan%2C%20select_stmt%2C%20physical_plan%2C%20result_op%29%3B%0A%0A%20%20%20%20//%207.%20generate%20physical%20plan%20for%20order%20by%0A%20%20%20%20if%20%28select_stmt-%3Eget_order_item_size%28%29%20%3E%200%29%0A%20%20%20%20%20%20result_op%20%3D%20gen_phy_order_by%28logical_plan%2C%20select_stmt%2C%20physical_plan%2C%20result_op%29%3B%0A%0A%20%20%20%20//%208.%20generate%20physical%20plan%20for%20limit%0A%20%20%20%20if%20%28select_stmt-%3Eget_limit%28%29%20%21%3D%20-1%20%7C%7C%20select_stmt-%3Eget_offset%28%29%20%21%3D%200%29%0A%20%20%20%20%7B%0A%20%20%20%20%20%20ObLimit%20*limit_op%20%3D%20NULL%3B%0A%20%20%20%20%20%20CREATE_PHY_OPERRATOR%28limit_op%2C%20ObLimit%2C%20physical_plan%29%3B%0A%20%20%20%20%20%20limit_op-%3Eset_limit%28select_stmt-%3Eget_limit%28%29%2C%20select_stmt-%3Eget_offset%28%29%29%3B%0A%20%20%20%20%20%20limit_op-%3Eset_child%280%2C%20*result_op%29%3B%0A%20%20%20%20%20%20result_op%20%3D%20limit_op%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20//%208.%20generate%20physical%20plan%20for%20select%20clause%0A%20%20%20%20if%20%28select_stmt-%3Eget_select_item_size%28%29%20%3E%200%29%0A%20%20%20%20%7B%0A%20%20%20%20%20%20ObProject%20*project_op%20%3D%20NULL%3B%0A%20%20%20%20%20%20CREATE_PHY_OPERRATOR%28project_op%2C%20ObProject%2C%20physical_plan%29%3B%0A%20%20%20%20%20%20project_op-%3Eset_child%280%2C%20*result_op%29%3B%0A%0A%20%20%20%20%20%20ObSqlRawExpr%20*select_expr%3B%0A%20%20%20%20%20%20int32_t%20num%20%3D%20select_stmt-%3Eget_select_item_size%28%29%3B%0A%20%20%20%20%20%20for%20%28int32_t%20i%20%3D%200%3B%20i%20%3C%20num%3B%20i++%29%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20const%20SelectItem%26%20select_item%20%3D%20select_stmt-%3Eget_select_item%28i%29%3B%0A%20%20%20%20%20%20%20%20select_expr%20%3D%20logical_plan-%3Eget_expr%28select_item.expr_id_%29%3B%0A%20%20%20%20%20%20%20%20if%20%28select_item.is_real_alias_%29%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20ObBinaryRefRawExpr%20col_raw%28OB_INVALID_ID%2C%20select_expr-%3Eget_column_id%28%29%2C%20T_REF_COLUMN%29%3B%0A%20%20%20%20%20%20%20%20%20%20ObSqlRawExpr%20col_sql_raw%28*select_expr%29%3B%0A%20%20%20%20%20%20%20%20%20%20col_sql_raw.set_expr%28%26col_raw%29%3B%0A%20%20%20%20%20%20%20%20%20%20ObSqlExpression%20%20col_expr%3B%0A%20%20%20%20%20%20%20%20%20%20col_sql_raw.fill_sql_expression%28col_expr%29%3B%0A%20%20%20%20%20%20%20%20%20%20project_op%20-%3Eadd_output_column%28col_expr%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20else%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20ObSqlExpression%20%20col_expr%3B%0A%20%20%20%20%20%20%20%20%20%20select_expr-%3Efill_sql_expression%28col_expr%2C%20this%2C%20logical_plan%2C%20physical_plan%29%3B%0A%20%20%20%20%20%20%20%20%20%20project_op%20-%3Eadd_output_column%28col_expr%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20result_op%20%3D%20project_op%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20physical_plan-%3Eadd_phy_query%28result_op%2C%20idx%29%3B%0A%20%20%7D%0A%0A%20%20return%20idx%3B%0A%7D%0A%60%60%60%0A%23%23%u56DB%u3001%20%u603B%u7ED3%0A%u7269%u7406%u67E5%u8BE2%u8BA1%u5212%u7684%u751F%u6210%u8FC7%u7A0B%u6BD4%u903B%u8F91%u8BA1%u5212%u548C%u8BED%u6CD5%u6811%u89E3%u6790%u90E8%u5206%u66F4%u590D%u6742%u3002%u4F60%u9700%u8981%u4E86%u89E3%u76F8%u5173%u7684%u57FA%u7840%u77E5%u8BC6%u5305%u62EC%u5173%u7CFB%u4EE3%u6570%u67E5%u8BE2%uFF0C%u6D41%u6C34%u7EBF%u65B9%u5F0F%u4E0B%u7684%u8FD0%u7B97%u7B26%u6784%u6210%uFF0CSQL%u8BED%u6CD5%u7684%u6267%u884C%u987A%u5E8F%u7B49%u3002%0A%0A----%0A%u6B22%u8FCE%u5149%u4E34%5B%u6211%u7684%u7F51%u7AD9%5D%28http%3A//www.cxueyou.sinaapp.com/%29----%5B%u8774%u8776%u5FFD%u7136%u7684%u535A%u5BA2%u56ED%5D%28http%3A//www.cnblogs.com/chenxueyou/%29----%5B%u4EBA%u65E2%u65E0%u540D%u7684%u4E13%u680F%5D%28http%3A//blog.csdn.net/qq910894904/%29%u3002%0A%u5982%u679C%u9605%u8BFB%u672C%u6587%u8FC7%u7A0B%u4E2D%u6709%u4EFB%u4F55%u95EE%u9898%uFF0C%u8BF7%5B%u8054%u7CFB%u4F5C%u8005%5D%28http%3A//mail.qq.com/cgi-bin/qm_share%3Ft%3Dqm_mailme%26email%3DJx4WFx8eEx4XE2dWVglESEo%29%uFF0C%u8F6C%u8F7D%u8BF7%u6CE8%u660E%u51FA%u5904%uFF01
淘宝数据库OceanBase SQL编译器部分 源码阅读--生成物理查询计划的更多相关文章
- 淘宝数据库OceanBase SQL编译器部分 源码阅读--生成逻辑计划
body, td { font-family: tahoma; font-size: 10pt; } 淘宝数据库OceanBase SQL编译器部分 源码阅读--生成逻辑计划 SQL编译解析三部曲分为 ...
- 《淘宝数据库OceanBase SQL编译器部分 源码阅读--解析SQL语法树》
淘宝数据库OceanBase SQL编译器部分 源码阅读--解析SQL语法树 曾经的学渣 2014-06-05 18:38:00 浏览1455 云数据库Oceanbase OceanBase是 ...
- 淘宝数据库OceanBase SQL编译器部分 源代码阅读--Schema模式
淘宝数据库OceanBase SQL编译器部分 源代码阅读--Schema模式 什么是Database,什么是Schema,什么是Table,什么是列,什么是行,什么是User?我们能够能够把Data ...
- 淘宝数据库OceanBase SQL编译器部分 源代码阅读--生成物理查询计划
SQL编译解析三部曲分为:构建语法树,制定逻辑计划,生成物理运行计划. 前两个步骤请參见我的博客<<淘宝数据库OceanBase SQL编译器部分 源代码阅读--解析SQL语法树>& ...
- 淘宝数据库OceanBase SQL编译器部分 源代码阅读--生成逻辑计划
淘宝数据库OceanBase SQL编译器部分 源代码阅读--生成逻辑计划 SQL编译解析三部曲分为:构建语法树.生成逻辑计划.指定物理运行计划. 第一步骤,在我的上一篇博客淘宝数据库OceanBas ...
- 淘宝数据库OceanBase SQL编译器部分 源代码阅读--解析SQL语法树
OceanBase是阿里巴巴集团自主研发的可扩展的关系型数据库,实现了跨行跨表的事务,支持数千亿条记录.数百TB数据上的SQL操作. 在阿里巴巴集团下,OceanBase数据库支持了多个重要业务的数据 ...
- 安卓sdk webview获取淘宝个人信息100项,源码。
1.贴出主要代码.这个不是python,python只涉及了服务端对信息提取结果的接受.主体是java + android + js.由于淘宝各模块都是二级子域名,不能只在一个页面完成所有请求,aj ...
- android文件选择器、仿淘宝编辑页面、新手引导层等源码
Android精选源码 单片机和安卓应用,传感器 文件选择器 android滑动选择的尺子view源码 android视频录制 视频压缩的源码 仿今日头条顶部导航指示器源码 Android框架+常用控 ...
- Spark之SQL解析(源码阅读十)
如何能更好的运用与监控sparkSQL?或许我们改更深层次的了解它深层次的原理是什么.之前总结的已经写了传统数据库与Spark的sql解析之间的差别.那么我们下来直切主题~ 如今的Spark已经支持多 ...
随机推荐
- luogu3980 [NOI2008]志愿者招募
神题,还不太清楚 #include <iostream> #include <cstring> #include <cstdio> #include <que ...
- 用python计算100以内的素数
用python计算100以内的素数 : break else: list.append(i)print(list)
- CentOS7搭建Maven的Nexus私服仓库
1.下载nexus 打开一下链接: https://www.sonatype.com/nexus-repository-oss 下载安装包. 2.解压安装包 tar zxvf nexus-3.9.0- ...
- PHP 接入支付宝即时到账功能
首先请到支付宝那边申请一个及时到账的接口账户,需要提交相关材料申请.然后根据即时到账的API文档进行接入.API文档提供了各种语言版本的demo,我这里是下的php版demo,然后再进行相关修改操作. ...
- Convolution Fundamental II
Practical Advice Using Open-Source Implementation We have learned a lot of NNs and ConvNets architec ...
- python刷toj
1452 import sys a , b , c = map(int,sys.stdin.readline().split()) print ((a+b+c),(a*b*c), '%.2f' %(( ...
- git 本地保存账号密码
用ssh连接的项目都不用输账号密码 如果https的话 每次都用输入账号密码 很繁琐 解决方法,在本地的工程文件夹的.git下打开config文件添加: [credential] he ...
- 性能学习笔记之四--事务,思考时间,检查点,集合点和手写lr接口
一.事物,思考时间,检查点,集合点 1.事务 lr里面的事物是lr运行脚本的基础.lr里面 要测试的三个维度都以事物为单位,所以一定要有事物.事务的概念贯穿loadrunner的使用,比如我们说的响应 ...
- BZOJ 2431: [HAOI2009]逆序对数列【dp】
Description 对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数.那么逆序 ...
- rest-assured 将log()中的信息打印到log日志中去的方法
rest-assured 将log()中的信息打印到log日志中去的方法: ============方法1============== PrintStream fileOutPutStream = n ...