淘宝数据库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

openclose分别为打开一个运算符,关闭一个运算符。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编译器部分 源码阅读--生成物理查询计划的更多相关文章

  1. 淘宝数据库OceanBase SQL编译器部分 源码阅读--生成逻辑计划

    body, td { font-family: tahoma; font-size: 10pt; } 淘宝数据库OceanBase SQL编译器部分 源码阅读--生成逻辑计划 SQL编译解析三部曲分为 ...

  2. 《淘宝数据库OceanBase SQL编译器部分 源码阅读--解析SQL语法树》

    淘宝数据库OceanBase SQL编译器部分 源码阅读--解析SQL语法树   曾经的学渣 2014-06-05 18:38:00 浏览1455 云数据库Oceanbase   OceanBase是 ...

  3. 淘宝数据库OceanBase SQL编译器部分 源代码阅读--Schema模式

    淘宝数据库OceanBase SQL编译器部分 源代码阅读--Schema模式 什么是Database,什么是Schema,什么是Table,什么是列,什么是行,什么是User?我们能够能够把Data ...

  4. 淘宝数据库OceanBase SQL编译器部分 源代码阅读--生成物理查询计划

    SQL编译解析三部曲分为:构建语法树,制定逻辑计划,生成物理运行计划. 前两个步骤请參见我的博客<<淘宝数据库OceanBase SQL编译器部分 源代码阅读--解析SQL语法树>& ...

  5. 淘宝数据库OceanBase SQL编译器部分 源代码阅读--生成逻辑计划

    淘宝数据库OceanBase SQL编译器部分 源代码阅读--生成逻辑计划 SQL编译解析三部曲分为:构建语法树.生成逻辑计划.指定物理运行计划. 第一步骤,在我的上一篇博客淘宝数据库OceanBas ...

  6. 淘宝数据库OceanBase SQL编译器部分 源代码阅读--解析SQL语法树

    OceanBase是阿里巴巴集团自主研发的可扩展的关系型数据库,实现了跨行跨表的事务,支持数千亿条记录.数百TB数据上的SQL操作. 在阿里巴巴集团下,OceanBase数据库支持了多个重要业务的数据 ...

  7. 安卓sdk webview获取淘宝个人信息100项,源码。

    1.贴出主要代码.这个不是python,python只涉及了服务端对信息提取结果的接受.主体是java  + android + js.由于淘宝各模块都是二级子域名,不能只在一个页面完成所有请求,aj ...

  8. android文件选择器、仿淘宝编辑页面、新手引导层等源码

    Android精选源码 单片机和安卓应用,传感器 文件选择器 android滑动选择的尺子view源码 android视频录制 视频压缩的源码 仿今日头条顶部导航指示器源码 Android框架+常用控 ...

  9. Spark之SQL解析(源码阅读十)

    如何能更好的运用与监控sparkSQL?或许我们改更深层次的了解它深层次的原理是什么.之前总结的已经写了传统数据库与Spark的sql解析之间的差别.那么我们下来直切主题~ 如今的Spark已经支持多 ...

随机推荐

  1. linux相关技术

    1.查询服务器tcp连接状态及连接数 netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

  2. Knockout v3.4.0 中文版教程-14-控制文本内容和外观-style绑定

    5. style绑定 目的 style绑定用来给关联的DOM元素添加或移除一个或多个样式值.在如下情况很有用,比如,当某些值为负时,高亮显示,或者设置容器元素的宽度来匹配数值的改变. (注意:如果你不 ...

  3. PYDay6- 内置函数、验证码、文件操作、发送邮件函数

    1.内置函数 1.1Python的内置函数 abs() dict() help() min() setattr() all() dir() hex() next() slice() any() div ...

  4. 牛客网Wannafly模拟赛

    A矩阵 时间限制:1秒 空间限制:131072K 题目描述 给出一个n * m的矩阵.让你从中发现一个最大的正方形.使得这样子的正方形在矩阵中出现了至少两次.输出最大正方形的边长. 输入描述: 第一行 ...

  5. POJ 3469 Dual Core CPU ——网络流

    [题目分析] 构造一个最小割的模型. S向每一个点连Ai,每一个点向T连Bi. 对于每一个限制条件,在i和j之间连一条Cij的双向边即可. 然后求出最小割就是最少的花费. 验证最小割的合理性很容易. ...

  6. 转载:sql2005 Microsoft SQL Server Management Studio Express的安装问题

    转载地址:http://blog.csdn.net/rjc20098022/article/details/26958105 在这个网址http://www.microsoft.com/zh-cn/d ...

  7. eclipse中AXIS2发布过程

    Axis2服务端研究好几个小时,终于解决了 需要下载: 地址1: 可以从镜像站下载: 上海大学开源镜像站 地址2: 链接:从百度网盘下载; 密码:8nwu 其中第二个可以不用下: 解压后 将3,4解压 ...

  8. springboot收集

    Spring Boot实战:拦截器与过滤器 参考:https://blog.csdn.net/m0_37106742/article/details/64438892 https://www.ibm. ...

  9. linux的crontab定时任务命令

    linux的crontab定时任务命令 cron是一个linux下的定时执行工具. 启动.停止.重启.重新载入配置/sbin/service crond start|stop|restart|relo ...

  10. 关于整合spring+mybatis 第二种方式

    和第一种方式一样的步骤,不过bean.xml中有些许差异 <!-- 配置sqlSessionFactory --> <bean id="sqlSessionFactory& ...