From fa6e5c7fa33cc7c20925df366445218cce2e3ee0 Mon Sep 17 00:00:00 2001 From: wangyunlai Date: Wed, 16 Aug 2023 20:06:42 +0800 Subject: [PATCH] refactor logical plan generator (#236) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### 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中 --- docs/book.toml | 1 - .../sql/optimizer/logical_plan_generator.cpp | 215 ++++++++++++++++++ .../sql/optimizer/logical_plan_generator.h | 45 ++++ src/observer/sql/optimizer/optimize_stage.cpp | 195 +--------------- src/observer/sql/optimizer/optimize_stage.h | 19 +- 5 files changed, 265 insertions(+), 210 deletions(-) create mode 100644 src/observer/sql/optimizer/logical_plan_generator.cpp create mode 100644 src/observer/sql/optimizer/logical_plan_generator.h diff --git a/docs/book.toml b/docs/book.toml index 9a7a463..8ec29ed 100644 --- a/docs/book.toml +++ b/docs/book.toml @@ -3,7 +3,6 @@ language = "cn" multilingual = false src = "src" title = "MiniOB" -authors = "OceanBase" [output.html] git-repository-url = "https://github.com/oceanbase/miniob" diff --git a/src/observer/sql/optimizer/logical_plan_generator.cpp b/src/observer/sql/optimizer/logical_plan_generator.cpp new file mode 100644 index 0000000..6b72877 --- /dev/null +++ b/src/observer/sql/optimizer/logical_plan_generator.cpp @@ -0,0 +1,215 @@ +/* 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 &logical_operator) +{ + RC rc = RC::SUCCESS; + switch (stmt->type()) { + case StmtType::CALC: { + CalcStmt *calc_stmt = static_cast(stmt); + rc = create_plan(calc_stmt, logical_operator); + } break; + + case StmtType::SELECT: { + SelectStmt *select_stmt = static_cast(stmt); + rc = create_plan(select_stmt, logical_operator); + } break; + + case StmtType::INSERT: { + InsertStmt *insert_stmt = static_cast(stmt); + rc = create_plan(insert_stmt, logical_operator); + } break; + + case StmtType::DELETE: { + DeleteStmt *delete_stmt = static_cast(stmt); + rc = create_plan(delete_stmt, logical_operator); + } break; + + case StmtType::EXPLAIN: { + ExplainStmt *explain_stmt = static_cast(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 &logical_operator) +{ + logical_operator.reset(new CalcLogicalOperator(std::move(calc_stmt->expressions()))); + return RC::SUCCESS; +} + +RC LogicalPlanGenerator::create_plan( + SelectStmt *select_stmt, unique_ptr &logical_operator) +{ + unique_ptr table_oper(nullptr); + + const std::vector &tables = select_stmt->tables(); + const std::vector &all_fields = select_stmt->query_fields(); + for (Table *table : tables) { + std::vector fields; + for (const Field &field : all_fields) { + if (0 == strcmp(field.table_name(), table->name())) { + fields.push_back(field); + } + } + + unique_ptr 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(join_oper); + } + } + + unique_ptr 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 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 &logical_operator) +{ + std::vector> cmp_exprs; + const std::vector &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 left(filter_obj_left.is_attr + ? static_cast(new FieldExpr(filter_obj_left.field)) + : static_cast(new ValueExpr(filter_obj_left.value))); + + unique_ptr right(filter_obj_right.is_attr + ? static_cast(new FieldExpr(filter_obj_right.field)) + : static_cast(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 predicate_oper; + if (!cmp_exprs.empty()) { + unique_ptr conjunction_expr(new ConjunctionExpr(ConjunctionExpr::Type::AND, cmp_exprs)); + predicate_oper = unique_ptr(new PredicateLogicalOperator(std::move(conjunction_expr))); + } + + logical_operator = std::move(predicate_oper); + return RC::SUCCESS; +} + +RC LogicalPlanGenerator::create_plan( + InsertStmt *insert_stmt, unique_ptr &logical_operator) +{ + Table *table = insert_stmt->table(); + vector 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 &logical_operator) +{ + Table *table = delete_stmt->table(); + FilterStmt *filter_stmt = delete_stmt->filter_stmt(); + std::vector 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 table_get_oper(new TableGetLogicalOperator(table, fields, false/*readonly*/)); + + unique_ptr predicate_oper; + RC rc = create_plan(filter_stmt, predicate_oper); + if (rc != RC::SUCCESS) { + return rc; + } + + unique_ptr 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 &logical_operator) +{ + Stmt *child_stmt = explain_stmt->child(); + unique_ptr 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(new ExplainLogicalOperator); + logical_operator->add_child(std::move(child_oper)); + return rc; +} diff --git a/src/observer/sql/optimizer/logical_plan_generator.h b/src/observer/sql/optimizer/logical_plan_generator.h new file mode 100644 index 0000000..37261b8 --- /dev/null +++ b/src/observer/sql/optimizer/logical_plan_generator.h @@ -0,0 +1,45 @@ +/* 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 + +#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 &logical_operator); + +private: + RC create_plan(CalcStmt *calc_stmt, std::unique_ptr &logical_operator); + RC create_plan(SelectStmt *select_stmt, std::unique_ptr &logical_operator); + RC create_plan(FilterStmt *filter_stmt, std::unique_ptr &logical_operator); + RC create_plan(InsertStmt *insert_stmt, std::unique_ptr &logical_operator); + RC create_plan(DeleteStmt *delete_stmt, std::unique_ptr &logical_operator); + RC create_plan(ExplainStmt *explain_stmt, std::unique_ptr &logical_operator); +}; \ No newline at end of file diff --git a/src/observer/sql/optimizer/optimize_stage.cpp b/src/observer/sql/optimizer/optimize_stage.cpp index 0139685..03558fd 100644 --- a/src/observer/sql/optimizer/optimize_stage.cpp +++ b/src/observer/sql/optimizer/optimize_stage.cpp @@ -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 &logical_operator) return rc; } -RC OptimizeStage::create_logical_plan(Stmt *stmt, unique_ptr &logical_operator) -{ - RC rc = RC::SUCCESS; - switch (stmt->type()) { - case StmtType::CALC: { - CalcStmt *calc_stmt = static_cast(stmt); - rc = create_calc_logical_plan(calc_stmt, logical_operator); - } break; - - case StmtType::SELECT: { - SelectStmt *select_stmt = static_cast(stmt); - rc = create_select_logical_plan(select_stmt, logical_operator); - } break; - - case StmtType::INSERT: { - InsertStmt *insert_stmt = static_cast(stmt); - rc = create_insert_logical_plan(insert_stmt, logical_operator); - } break; - - case StmtType::DELETE: { - DeleteStmt *delete_stmt = static_cast(stmt); - rc = create_delete_logical_plan(delete_stmt, logical_operator); - } break; - - case StmtType::EXPLAIN: { - ExplainStmt *explain_stmt = static_cast(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 &logical_operator) { Stmt *stmt = sql_event->stmt(); @@ -156,149 +107,5 @@ RC OptimizeStage::create_logical_plan(SQLStageEvent *sql_event, unique_ptr &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 &logical_operator) -{ - unique_ptr table_oper(nullptr); - - const std::vector
&tables = select_stmt->tables(); - const std::vector &all_fields = select_stmt->query_fields(); - for (Table *table : tables) { - std::vector fields; - for (const Field &field : all_fields) { - if (0 == strcmp(field.table_name(), table->name())) { - fields.push_back(field); - } - } - - unique_ptr 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(join_oper); - } - } - - unique_ptr 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 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 &logical_operator) -{ - std::vector> cmp_exprs; - const std::vector &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 left(filter_obj_left.is_attr - ? static_cast(new FieldExpr(filter_obj_left.field)) - : static_cast(new ValueExpr(filter_obj_left.value))); - - unique_ptr right(filter_obj_right.is_attr - ? static_cast(new FieldExpr(filter_obj_right.field)) - : static_cast(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 predicate_oper; - if (!cmp_exprs.empty()) { - unique_ptr conjunction_expr(new ConjunctionExpr(ConjunctionExpr::Type::AND, cmp_exprs)); - predicate_oper = unique_ptr(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 &logical_operator) -{ - Table *table = insert_stmt->table(); - vector 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 &logical_operator) -{ - Table *table = delete_stmt->table(); - FilterStmt *filter_stmt = delete_stmt->filter_stmt(); - std::vector 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 table_get_oper(new TableGetLogicalOperator(table, fields, false/*readonly*/)); - - unique_ptr predicate_oper; - RC rc = create_predicate_logical_plan(filter_stmt, predicate_oper); - if (rc != RC::SUCCESS) { - return rc; - } - - unique_ptr 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 &logical_operator) -{ - Stmt *child_stmt = explain_stmt->child(); - unique_ptr 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(new ExplainLogicalOperator); - logical_operator->add_child(std::move(child_oper)); - return rc; + return logical_plan_generator_.create(stmt, logical_operator); } diff --git a/src/observer/sql/optimizer/optimize_stage.h b/src/observer/sql/optimizer/optimize_stage.h index 8cfc945..6031a89 100644 --- a/src/observer/sql/optimizer/optimize_stage.h +++ b/src/observer/sql/optimizer/optimize_stage.h @@ -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 &logical_operator); - RC create_logical_plan(Stmt *stmt, std::unique_ptr &logical_operator); - RC create_calc_logical_plan(CalcStmt *calc_stmt, std::unique_ptr &logical_operator); - RC create_select_logical_plan(SelectStmt *select_stmt, std::unique_ptr &logical_operator); - RC create_predicate_logical_plan(FilterStmt *filter_stmt, std::unique_ptr &logical_operator); - RC create_insert_logical_plan(InsertStmt *insert_stmt, std::unique_ptr &logical_operator); - RC create_delete_logical_plan(DeleteStmt *delete_stmt, std::unique_ptr &logical_operator); - RC create_explain_logical_plan(ExplainStmt *explain_stmt, std::unique_ptr &logical_operator); /** * @brief 重写逻辑计划 @@ -87,6 +75,7 @@ private: std::unique_ptr &logical_operator, std::unique_ptr &physical_operator); private: - PhysicalPlanGenerator physical_plan_generator_; /// 根据逻辑计划生成物理计划 - Rewriter rewriter_; /// 逻辑计划改写 + LogicalPlanGenerator logical_plan_generator_; ///< 根据SQL生成逻辑计划 + PhysicalPlanGenerator physical_plan_generator_; ///< 根据逻辑计划生成物理计划 + Rewriter rewriter_; ///< 逻辑计划改写 }; -- GitLab