未验证 提交 fa6e5c7f 编写于 作者: 羽飞's avatar 羽飞 提交者: GitHub

refactor logical plan generator (#236)

### What problem were solved in this pull request?

Issue Number: close #230 

Problem:
logical plan的生成代码全放在了optimize中,看起来很不清晰

### What is changed and how it works?
将logical plan的代码提取出来放在logical plan generator中
上级 3cd3c2f9
......@@ -3,7 +3,6 @@ language = "cn"
multilingual = false
src = "src"
title = "MiniOB"
authors = "OceanBase"
[output.html]
git-repository-url = "https://github.com/oceanbase/miniob"
......
/* Copyright (c) 2023 OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2023/08/16.
//
#include "sql/optimizer/logical_plan_generator.h"
#include "sql/operator/logical_operator.h"
#include "sql/operator/calc_logical_operator.h"
#include "sql/operator/project_logical_operator.h"
#include "sql/operator/predicate_logical_operator.h"
#include "sql/operator/table_get_logical_operator.h"
#include "sql/operator/insert_logical_operator.h"
#include "sql/operator/delete_logical_operator.h"
#include "sql/operator/join_logical_operator.h"
#include "sql/operator/project_logical_operator.h"
#include "sql/operator/explain_logical_operator.h"
#include "sql/stmt/stmt.h"
#include "sql/stmt/calc_stmt.h"
#include "sql/stmt/select_stmt.h"
#include "sql/stmt/filter_stmt.h"
#include "sql/stmt/insert_stmt.h"
#include "sql/stmt/delete_stmt.h"
#include "sql/stmt/explain_stmt.h"
using namespace std;
RC LogicalPlanGenerator::create(Stmt *stmt, unique_ptr<LogicalOperator> &logical_operator)
{
RC rc = RC::SUCCESS;
switch (stmt->type()) {
case StmtType::CALC: {
CalcStmt *calc_stmt = static_cast<CalcStmt *>(stmt);
rc = create_plan(calc_stmt, logical_operator);
} break;
case StmtType::SELECT: {
SelectStmt *select_stmt = static_cast<SelectStmt *>(stmt);
rc = create_plan(select_stmt, logical_operator);
} break;
case StmtType::INSERT: {
InsertStmt *insert_stmt = static_cast<InsertStmt *>(stmt);
rc = create_plan(insert_stmt, logical_operator);
} break;
case StmtType::DELETE: {
DeleteStmt *delete_stmt = static_cast<DeleteStmt *>(stmt);
rc = create_plan(delete_stmt, logical_operator);
} break;
case StmtType::EXPLAIN: {
ExplainStmt *explain_stmt = static_cast<ExplainStmt *>(stmt);
rc = create_plan(explain_stmt, logical_operator);
} break;
default: {
rc = RC::UNIMPLENMENT;
}
}
return rc;
}
RC LogicalPlanGenerator::create_plan(CalcStmt *calc_stmt, std::unique_ptr<LogicalOperator> &logical_operator)
{
logical_operator.reset(new CalcLogicalOperator(std::move(calc_stmt->expressions())));
return RC::SUCCESS;
}
RC LogicalPlanGenerator::create_plan(
SelectStmt *select_stmt, unique_ptr<LogicalOperator> &logical_operator)
{
unique_ptr<LogicalOperator> table_oper(nullptr);
const std::vector<Table *> &tables = select_stmt->tables();
const std::vector<Field> &all_fields = select_stmt->query_fields();
for (Table *table : tables) {
std::vector<Field> fields;
for (const Field &field : all_fields) {
if (0 == strcmp(field.table_name(), table->name())) {
fields.push_back(field);
}
}
unique_ptr<LogicalOperator> table_get_oper(new TableGetLogicalOperator(table, fields, true/*readonly*/));
if (table_oper == nullptr) {
table_oper = std::move(table_get_oper);
} else {
JoinLogicalOperator *join_oper = new JoinLogicalOperator;
join_oper->add_child(std::move(table_oper));
join_oper->add_child(std::move(table_get_oper));
table_oper = unique_ptr<LogicalOperator>(join_oper);
}
}
unique_ptr<LogicalOperator> predicate_oper;
RC rc = create_plan(select_stmt->filter_stmt(), predicate_oper);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to create predicate logical plan. rc=%s", strrc(rc));
return rc;
}
unique_ptr<LogicalOperator> project_oper(new ProjectLogicalOperator(all_fields));
if (predicate_oper) {
if (table_oper) {
predicate_oper->add_child(std::move(table_oper));
}
project_oper->add_child(std::move(predicate_oper));
} else {
if (table_oper) {
project_oper->add_child(std::move(table_oper));
}
}
logical_operator.swap(project_oper);
return RC::SUCCESS;
}
RC LogicalPlanGenerator::create_plan(
FilterStmt *filter_stmt, unique_ptr<LogicalOperator> &logical_operator)
{
std::vector<unique_ptr<Expression>> cmp_exprs;
const std::vector<FilterUnit *> &filter_units = filter_stmt->filter_units();
for (const FilterUnit *filter_unit : filter_units) {
const FilterObj &filter_obj_left = filter_unit->left();
const FilterObj &filter_obj_right = filter_unit->right();
unique_ptr<Expression> left(filter_obj_left.is_attr
? static_cast<Expression *>(new FieldExpr(filter_obj_left.field))
: static_cast<Expression *>(new ValueExpr(filter_obj_left.value)));
unique_ptr<Expression> right(filter_obj_right.is_attr
? static_cast<Expression *>(new FieldExpr(filter_obj_right.field))
: static_cast<Expression *>(new ValueExpr(filter_obj_right.value)));
ComparisonExpr *cmp_expr = new ComparisonExpr(filter_unit->comp(), std::move(left), std::move(right));
cmp_exprs.emplace_back(cmp_expr);
}
unique_ptr<PredicateLogicalOperator> predicate_oper;
if (!cmp_exprs.empty()) {
unique_ptr<ConjunctionExpr> conjunction_expr(new ConjunctionExpr(ConjunctionExpr::Type::AND, cmp_exprs));
predicate_oper = unique_ptr<PredicateLogicalOperator>(new PredicateLogicalOperator(std::move(conjunction_expr)));
}
logical_operator = std::move(predicate_oper);
return RC::SUCCESS;
}
RC LogicalPlanGenerator::create_plan(
InsertStmt *insert_stmt, unique_ptr<LogicalOperator> &logical_operator)
{
Table *table = insert_stmt->table();
vector<Value> values(insert_stmt->values(), insert_stmt->values() + insert_stmt->value_amount());
InsertLogicalOperator *insert_operator = new InsertLogicalOperator(table, values);
logical_operator.reset(insert_operator);
return RC::SUCCESS;
}
RC LogicalPlanGenerator::create_plan(
DeleteStmt *delete_stmt, unique_ptr<LogicalOperator> &logical_operator)
{
Table *table = delete_stmt->table();
FilterStmt *filter_stmt = delete_stmt->filter_stmt();
std::vector<Field> fields;
for (int i = table->table_meta().sys_field_num(); i < table->table_meta().field_num(); i++) {
const FieldMeta *field_meta = table->table_meta().field(i);
fields.push_back(Field(table, field_meta));
}
unique_ptr<LogicalOperator> table_get_oper(new TableGetLogicalOperator(table, fields, false/*readonly*/));
unique_ptr<LogicalOperator> predicate_oper;
RC rc = create_plan(filter_stmt, predicate_oper);
if (rc != RC::SUCCESS) {
return rc;
}
unique_ptr<LogicalOperator> delete_oper(new DeleteLogicalOperator(table));
if (predicate_oper) {
predicate_oper->add_child(std::move(table_get_oper));
delete_oper->add_child(std::move(predicate_oper));
} else {
delete_oper->add_child(std::move(table_get_oper));
}
logical_operator = std::move(delete_oper);
return rc;
}
RC LogicalPlanGenerator::create_plan(
ExplainStmt *explain_stmt, unique_ptr<LogicalOperator> &logical_operator)
{
Stmt *child_stmt = explain_stmt->child();
unique_ptr<LogicalOperator> child_oper;
RC rc = create(child_stmt, child_oper);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to create explain's child operator. rc=%s", strrc(rc));
return rc;
}
logical_operator = unique_ptr<LogicalOperator>(new ExplainLogicalOperator);
logical_operator->add_child(std::move(child_oper));
return rc;
}
/* Copyright (c) 2023 OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2023/08/16.
//
#pragma once
#include <memory>
#include "common/rc.h"
class Stmt;
class CalcStmt;
class SelectStmt;
class FilterStmt;
class InsertStmt;
class DeleteStmt;
class ExplainStmt;
class LogicalOperator;
class LogicalPlanGenerator
{
public:
LogicalPlanGenerator() = default;
virtual ~LogicalPlanGenerator() = default;
RC create(Stmt *stmt, std::unique_ptr<LogicalOperator> &logical_operator);
private:
RC create_plan(CalcStmt *calc_stmt, std::unique_ptr<LogicalOperator> &logical_operator);
RC create_plan(SelectStmt *select_stmt, std::unique_ptr<LogicalOperator> &logical_operator);
RC create_plan(FilterStmt *filter_stmt, std::unique_ptr<LogicalOperator> &logical_operator);
RC create_plan(InsertStmt *insert_stmt, std::unique_ptr<LogicalOperator> &logical_operator);
RC create_plan(DeleteStmt *delete_stmt, std::unique_ptr<LogicalOperator> &logical_operator);
RC create_plan(ExplainStmt *explain_stmt, std::unique_ptr<LogicalOperator> &logical_operator);
};
\ No newline at end of file
......@@ -23,23 +23,8 @@ See the Mulan PSL v2 for more details. */
#include "common/log/log.h"
#include "sql/expr/expression.h"
#include "sql/operator/logical_operator.h"
#include "sql/operator/calc_logical_operator.h"
#include "sql/operator/project_logical_operator.h"
#include "sql/operator/predicate_logical_operator.h"
#include "sql/operator/table_get_logical_operator.h"
#include "sql/operator/insert_logical_operator.h"
#include "sql/operator/delete_logical_operator.h"
#include "sql/operator/join_logical_operator.h"
#include "sql/operator/project_logical_operator.h"
#include "sql/operator/explain_logical_operator.h"
#include "sql/executor/sql_result.h"
#include "sql/stmt/stmt.h"
#include "sql/stmt/filter_stmt.h"
#include "sql/stmt/select_stmt.h"
#include "sql/stmt/calc_stmt.h"
#include "sql/stmt/insert_stmt.h"
#include "sql/stmt/delete_stmt.h"
#include "sql/stmt/explain_stmt.h"
#include "event/sql_event.h"
#include "event/session_event.h"
......@@ -115,40 +100,6 @@ RC OptimizeStage::rewrite(unique_ptr<LogicalOperator> &logical_operator)
return rc;
}
RC OptimizeStage::create_logical_plan(Stmt *stmt, unique_ptr<LogicalOperator> &logical_operator)
{
RC rc = RC::SUCCESS;
switch (stmt->type()) {
case StmtType::CALC: {
CalcStmt *calc_stmt = static_cast<CalcStmt *>(stmt);
rc = create_calc_logical_plan(calc_stmt, logical_operator);
} break;
case StmtType::SELECT: {
SelectStmt *select_stmt = static_cast<SelectStmt *>(stmt);
rc = create_select_logical_plan(select_stmt, logical_operator);
} break;
case StmtType::INSERT: {
InsertStmt *insert_stmt = static_cast<InsertStmt *>(stmt);
rc = create_insert_logical_plan(insert_stmt, logical_operator);
} break;
case StmtType::DELETE: {
DeleteStmt *delete_stmt = static_cast<DeleteStmt *>(stmt);
rc = create_delete_logical_plan(delete_stmt, logical_operator);
} break;
case StmtType::EXPLAIN: {
ExplainStmt *explain_stmt = static_cast<ExplainStmt *>(stmt);
rc = create_explain_logical_plan(explain_stmt, logical_operator);
} break;
default: {
rc = RC::UNIMPLENMENT;
}
}
return rc;
}
RC OptimizeStage::create_logical_plan(SQLStageEvent *sql_event, unique_ptr<LogicalOperator> &logical_operator)
{
Stmt *stmt = sql_event->stmt();
......@@ -156,149 +107,5 @@ RC OptimizeStage::create_logical_plan(SQLStageEvent *sql_event, unique_ptr<Logic
return RC::UNIMPLENMENT;
}
return create_logical_plan(stmt, logical_operator);
}
RC OptimizeStage::create_calc_logical_plan(CalcStmt *calc_stmt, std::unique_ptr<LogicalOperator> &logical_operator)
{
logical_operator.reset(new CalcLogicalOperator(std::move(calc_stmt->expressions())));
return RC::SUCCESS;
}
RC OptimizeStage::create_select_logical_plan(
SelectStmt *select_stmt, unique_ptr<LogicalOperator> &logical_operator)
{
unique_ptr<LogicalOperator> table_oper(nullptr);
const std::vector<Table *> &tables = select_stmt->tables();
const std::vector<Field> &all_fields = select_stmt->query_fields();
for (Table *table : tables) {
std::vector<Field> fields;
for (const Field &field : all_fields) {
if (0 == strcmp(field.table_name(), table->name())) {
fields.push_back(field);
}
}
unique_ptr<LogicalOperator> table_get_oper(new TableGetLogicalOperator(table, fields, true/*readonly*/));
if (table_oper == nullptr) {
table_oper = std::move(table_get_oper);
} else {
JoinLogicalOperator *join_oper = new JoinLogicalOperator;
join_oper->add_child(std::move(table_oper));
join_oper->add_child(std::move(table_get_oper));
table_oper = unique_ptr<LogicalOperator>(join_oper);
}
}
unique_ptr<LogicalOperator> predicate_oper;
RC rc = create_predicate_logical_plan(select_stmt->filter_stmt(), predicate_oper);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to create predicate logical plan. rc=%s", strrc(rc));
return rc;
}
unique_ptr<LogicalOperator> project_oper(new ProjectLogicalOperator(all_fields));
if (predicate_oper) {
if (table_oper) {
predicate_oper->add_child(std::move(table_oper));
}
project_oper->add_child(std::move(predicate_oper));
} else {
if (table_oper) {
project_oper->add_child(std::move(table_oper));
}
}
logical_operator.swap(project_oper);
return RC::SUCCESS;
}
RC OptimizeStage::create_predicate_logical_plan(
FilterStmt *filter_stmt, unique_ptr<LogicalOperator> &logical_operator)
{
std::vector<unique_ptr<Expression>> cmp_exprs;
const std::vector<FilterUnit *> &filter_units = filter_stmt->filter_units();
for (const FilterUnit *filter_unit : filter_units) {
const FilterObj &filter_obj_left = filter_unit->left();
const FilterObj &filter_obj_right = filter_unit->right();
unique_ptr<Expression> left(filter_obj_left.is_attr
? static_cast<Expression *>(new FieldExpr(filter_obj_left.field))
: static_cast<Expression *>(new ValueExpr(filter_obj_left.value)));
unique_ptr<Expression> right(filter_obj_right.is_attr
? static_cast<Expression *>(new FieldExpr(filter_obj_right.field))
: static_cast<Expression *>(new ValueExpr(filter_obj_right.value)));
ComparisonExpr *cmp_expr = new ComparisonExpr(filter_unit->comp(), std::move(left), std::move(right));
cmp_exprs.emplace_back(cmp_expr);
}
unique_ptr<PredicateLogicalOperator> predicate_oper;
if (!cmp_exprs.empty()) {
unique_ptr<ConjunctionExpr> conjunction_expr(new ConjunctionExpr(ConjunctionExpr::Type::AND, cmp_exprs));
predicate_oper = unique_ptr<PredicateLogicalOperator>(new PredicateLogicalOperator(std::move(conjunction_expr)));
}
logical_operator = std::move(predicate_oper);
return RC::SUCCESS;
}
RC OptimizeStage::create_insert_logical_plan(
InsertStmt *insert_stmt, unique_ptr<LogicalOperator> &logical_operator)
{
Table *table = insert_stmt->table();
vector<Value> values(insert_stmt->values(), insert_stmt->values() + insert_stmt->value_amount());
InsertLogicalOperator *insert_operator = new InsertLogicalOperator(table, values);
logical_operator.reset(insert_operator);
return RC::SUCCESS;
}
RC OptimizeStage::create_delete_logical_plan(
DeleteStmt *delete_stmt, unique_ptr<LogicalOperator> &logical_operator)
{
Table *table = delete_stmt->table();
FilterStmt *filter_stmt = delete_stmt->filter_stmt();
std::vector<Field> fields;
for (int i = table->table_meta().sys_field_num(); i < table->table_meta().field_num(); i++) {
const FieldMeta *field_meta = table->table_meta().field(i);
fields.push_back(Field(table, field_meta));
}
unique_ptr<LogicalOperator> table_get_oper(new TableGetLogicalOperator(table, fields, false/*readonly*/));
unique_ptr<LogicalOperator> predicate_oper;
RC rc = create_predicate_logical_plan(filter_stmt, predicate_oper);
if (rc != RC::SUCCESS) {
return rc;
}
unique_ptr<LogicalOperator> delete_oper(new DeleteLogicalOperator(table));
if (predicate_oper) {
predicate_oper->add_child(std::move(table_get_oper));
delete_oper->add_child(std::move(predicate_oper));
} else {
delete_oper->add_child(std::move(table_get_oper));
}
logical_operator = std::move(delete_oper);
return rc;
}
RC OptimizeStage::create_explain_logical_plan(
ExplainStmt *explain_stmt, unique_ptr<LogicalOperator> &logical_operator)
{
Stmt *child_stmt = explain_stmt->child();
unique_ptr<LogicalOperator> child_oper;
RC rc = create_logical_plan(child_stmt, child_oper);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to create explain's child operator. rc=%s", strrc(rc));
return rc;
}
logical_operator = unique_ptr<LogicalOperator>(new ExplainLogicalOperator);
logical_operator->add_child(std::move(child_oper));
return rc;
return logical_plan_generator_.create(stmt, logical_operator);
}
......@@ -19,18 +19,13 @@ See the Mulan PSL v2 for more details. */
#include "common/rc.h"
#include "sql/operator/logical_operator.h"
#include "sql/operator/physical_operator.h"
#include "sql/optimizer/logical_plan_generator.h"
#include "sql/optimizer/physical_plan_generator.h"
#include "sql/optimizer/rewriter.h"
class SQLStageEvent;
class LogicalOperator;
class Stmt;
class CalcStmt;
class SelectStmt;
class InsertStmt;
class DeleteStmt;
class FilterStmt;
class ExplainStmt;
/**
* @brief 将解析后的Statement转换成执行计划,并进行优化
......@@ -53,13 +48,6 @@ private:
* @param logical_operator 生成的逻辑计划
*/
RC create_logical_plan(SQLStageEvent *sql_event, std::unique_ptr<LogicalOperator> &logical_operator);
RC create_logical_plan(Stmt *stmt, std::unique_ptr<LogicalOperator> &logical_operator);
RC create_calc_logical_plan(CalcStmt *calc_stmt, std::unique_ptr<LogicalOperator> &logical_operator);
RC create_select_logical_plan(SelectStmt *select_stmt, std::unique_ptr<LogicalOperator> &logical_operator);
RC create_predicate_logical_plan(FilterStmt *filter_stmt, std::unique_ptr<LogicalOperator> &logical_operator);
RC create_insert_logical_plan(InsertStmt *insert_stmt, std::unique_ptr<LogicalOperator> &logical_operator);
RC create_delete_logical_plan(DeleteStmt *delete_stmt, std::unique_ptr<LogicalOperator> &logical_operator);
RC create_explain_logical_plan(ExplainStmt *explain_stmt, std::unique_ptr<LogicalOperator> &logical_operator);
/**
* @brief 重写逻辑计划
......@@ -87,6 +75,7 @@ private:
std::unique_ptr<LogicalOperator> &logical_operator, std::unique_ptr<PhysicalOperator> &physical_operator);
private:
PhysicalPlanGenerator physical_plan_generator_; /// 根据逻辑计划生成物理计划
Rewriter rewriter_; /// 逻辑计划改写
LogicalPlanGenerator logical_plan_generator_; ///< 根据SQL生成逻辑计划
PhysicalPlanGenerator physical_plan_generator_; ///< 根据逻辑计划生成物理计划
Rewriter rewriter_; ///< 逻辑计划改写
};
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册