From 118ffa6db6744b69d78be0bc81a4c90ad084fc87 Mon Sep 17 00:00:00 2001 From: "wangyunlai.wyl" Date: Tue, 21 Jun 2022 13:41:24 +0800 Subject: [PATCH] first step --- .gitignore | 9 +- Dockerfile | 9 +- deps/googletest | 1 + deps/jsoncpp | 1 + deps/libevent | 1 + etc/observer.ini | 17 +- src/observer/event/#sql_event.cpp# | 29 +++ ...n_event.cpp => execute_plan_event.cpp.bak} | 0 ..._plan_event.h => execute_plan_event.h.bak} | 26 +-- src/observer/event/optimize_event.h | 42 ++++ src/observer/event/query_cache_event.h.bak | 42 ++++ ...torage_event.cpp => resolve_event.cpp.bak} | 17 +- src/observer/event/resolve_event.h.bak | 35 +++ src/observer/event/session_event.cpp | 13 +- src/observer/event/session_event.h | 3 + src/observer/event/sql_event.cpp | 4 +- src/observer/event/sql_event.h | 29 ++- src/observer/event/storage_event.h | 12 +- src/observer/rc.cpp | 3 +- src/observer/rc.h | 3 +- src/observer/session/session.cpp | 27 ++- src/observer/session/session.h | 12 +- src/observer/session/session_stage.cpp | 7 +- src/observer/session/session_stage.h | 4 +- src/observer/sql/executor/delete_operator.h | 37 +++ src/observer/sql/executor/execute_stage.cpp | 218 +++++++++++++----- src/observer/sql/executor/execute_stage.h | 9 +- src/observer/sql/executor/insert_operator.cpp | 36 +++ src/observer/sql/executor/insert_operator.h | 39 ++++ .../sql/executor/join_operator.cpp.bak | 82 +++++++ src/observer/sql/executor/join_operator.h | 40 ++++ src/observer/sql/executor/operator.h | 34 +++ src/observer/sql/executor/predicate.cpp | 17 ++ src/observer/sql/executor/predicate.h | 27 +++ .../sql/executor/table_scan_operator.cpp | 46 ++++ .../sql/executor/table_scan_operator.h | 47 ++++ src/observer/sql/optimizer/optimize_stage.cpp | 5 +- src/observer/sql/optimizer/optimize_stage.h | 2 +- src/observer/sql/parser/#parse_stage.h# | 42 ++++ src/observer/sql/parser/parse_defs.h | 2 +- src/observer/sql/parser/parse_stage.cpp | 39 ++-- src/observer/sql/parser/parse_stage.h | 4 +- src/observer/sql/parser/resolve_stage.cpp | 32 ++- src/observer/sql/parser/resolve_stage.h | 2 +- .../sql/plan_cache/plan_cache_stage.cpp | 6 +- .../sql/plan_cache/plan_cache_stage.h | 3 +- .../sql/query_cache/query_cache_stage.cpp | 20 +- .../sql/query_cache/query_cache_stage.h | 2 +- src/observer/sql/stmt/delete_stmt.cpp | 58 +++++ src/observer/sql/stmt/delete_stmt.h | 42 ++++ src/observer/sql/stmt/filter_stmt.cpp | 106 +++++++++ src/observer/sql/stmt/filter_stmt.h | 134 +++++++++++ src/observer/sql/stmt/insert_stmt.cpp | 65 ++++++ src/observer/sql/stmt/insert_stmt.h | 46 ++++ src/observer/sql/stmt/select_stmt.cpp | 165 +++++++++++++ src/observer/sql/stmt/select_stmt.h | 57 +++++ src/observer/sql/stmt/stmt.cpp | 44 ++++ src/observer/sql/stmt/stmt.h | 59 +++++ src/observer/sql/stmt/update_stmt.cpp | 65 ++++++ src/observer/sql/stmt/update_stmt.h | 42 ++++ src/observer/storage/common/record.h | 49 ++++ src/observer/storage/common/table.cpp | 9 + src/observer/storage/common/table.h | 7 +- src/observer/storage/common/table_meta.h | 4 +- .../storage/default/default_handler.h | 11 - .../storage/default/default_storage_stage.cpp | 71 ++---- src/observer/storage/row/row.h | 42 ++++ src/observer/util/comparator.cpp | 45 ++++ src/observer/util/comparator.h | 19 ++ 69 files changed, 2017 insertions(+), 260 deletions(-) create mode 160000 deps/googletest create mode 160000 deps/jsoncpp create mode 160000 deps/libevent create mode 100644 src/observer/event/#sql_event.cpp# rename src/observer/event/{execution_plan_event.cpp => execute_plan_event.cpp.bak} (100%) rename src/observer/event/{execution_plan_event.h => execute_plan_event.h.bak} (62%) create mode 100644 src/observer/event/optimize_event.h create mode 100644 src/observer/event/query_cache_event.h.bak rename src/observer/event/{storage_event.cpp => resolve_event.cpp.bak} (61%) create mode 100644 src/observer/event/resolve_event.h.bak create mode 100644 src/observer/sql/executor/delete_operator.h create mode 100644 src/observer/sql/executor/insert_operator.cpp create mode 100644 src/observer/sql/executor/insert_operator.h create mode 100644 src/observer/sql/executor/join_operator.cpp.bak create mode 100644 src/observer/sql/executor/join_operator.h create mode 100644 src/observer/sql/executor/operator.h create mode 100644 src/observer/sql/executor/predicate.cpp create mode 100644 src/observer/sql/executor/predicate.h create mode 100644 src/observer/sql/executor/table_scan_operator.cpp create mode 100644 src/observer/sql/executor/table_scan_operator.h create mode 100644 src/observer/sql/parser/#parse_stage.h# create mode 100644 src/observer/sql/stmt/delete_stmt.cpp create mode 100644 src/observer/sql/stmt/delete_stmt.h create mode 100644 src/observer/sql/stmt/filter_stmt.cpp create mode 100644 src/observer/sql/stmt/filter_stmt.h create mode 100644 src/observer/sql/stmt/insert_stmt.cpp create mode 100644 src/observer/sql/stmt/insert_stmt.h create mode 100644 src/observer/sql/stmt/select_stmt.cpp create mode 100644 src/observer/sql/stmt/select_stmt.h create mode 100644 src/observer/sql/stmt/stmt.cpp create mode 100644 src/observer/sql/stmt/stmt.h create mode 100644 src/observer/sql/stmt/update_stmt.cpp create mode 100644 src/observer/sql/stmt/update_stmt.h create mode 100644 src/observer/storage/common/record.h create mode 100644 src/observer/storage/row/row.h create mode 100644 src/observer/util/comparator.cpp create mode 100644 src/observer/util/comparator.h diff --git a/.gitignore b/.gitignore index c13744b..7ab9b70 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ -./deps/libevent/* -./deps/googletest/* -./deps/jsoncpp/* +./deps/libevent +./deps/googletest +./deps/jsoncpp build/* cmake-build-*/* .vscode/* @@ -12,3 +12,6 @@ compile_commands.json ./vcs.xml ./workspace.xml ./modules.xml +GRTAGS +GPATH +GTAGS diff --git a/Dockerfile b/Dockerfile index 5f5de0e..a5b7682 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,17 +29,20 @@ RUN wget http://yum-test.obvos.alibaba-inc.com/oceanbase/development-kit/el/7/x8 RUN git clone https://github.com/libevent/libevent -b release-2.1.12-stable \ && mkdir -p ${HOME_DIR}/deps/libevent/build \ - && cmake -DEVENT__DISABLE_OPENSSL=ON -B ${HOME_DIR}/deps/libevent/build ${HOME_DIR}/deps/libevent && make -C ${HOME_DIR}/deps/libevent/build -j install \ + && cmake -DEVENT__DISABLE_OPENSSL=ON -B ${HOME_DIR}/deps/libevent/build ${HOME_DIR}/deps/libevent \ + && make -C ${HOME_DIR}/deps/libevent/build -j install \ && rm -rf ${HOME_DIR}/deps/* RUN git clone https://github.com/open-source-parsers/jsoncpp.git \ && mkdir -p ${HOME_DIR}/deps/jsoncpp/build \ - && cmake -DJSONCPP_WITH_TESTS=OFF -DJSONCPP_WITH_POST_BUILD_UNITTEST=OFF -B ${HOME_DIR}/deps/jsoncpp/build ${HOME_DIR}/deps/jsoncpp/ && make -C ${HOME_DIR}/deps/jsoncpp/build -j install \ + && cmake -DJSONCPP_WITH_TESTS=OFF -DJSONCPP_WITH_POST_BUILD_UNITTEST=OFF -B ${HOME_DIR}/deps/jsoncpp/build ${HOME_DIR}/deps/jsoncpp/ \ + && make -C ${HOME_DIR}/deps/jsoncpp/build -j install \ && rm -rf ${HOME_DIR}/deps/* RUN git clone https://github.com/google/googletest \ && mkdir -p ${HOME_DIR}/deps/googletest/build \ - && cmake -B ${HOME_DIR}/deps/googletest/build ${HOME_DIR}/deps/googletest && make -C ${HOME_DIR}/deps/googletest/build -j install \ + && cmake -B ${HOME_DIR}/deps/googletest/build ${HOME_DIR}/deps/googletest \ + && make -C ${HOME_DIR}/deps/googletest/build -j install \ && rm -rf ${HOME_DIR}/deps/* RUN wget http://ftp.gnu.org/gnu/bison/bison-3.7.tar.gz \ diff --git a/deps/googletest b/deps/googletest new file mode 160000 index 0000000..b1f84bf --- /dev/null +++ b/deps/googletest @@ -0,0 +1 @@ +Subproject commit b1f84bf1763b1010597bff13c79b5388eebdf205 diff --git a/deps/jsoncpp b/deps/jsoncpp new file mode 160000 index 0000000..42e892d --- /dev/null +++ b/deps/jsoncpp @@ -0,0 +1 @@ +Subproject commit 42e892d96e47b1f6e29844cc705e148ec4856448 diff --git a/deps/libevent b/deps/libevent new file mode 160000 index 0000000..5df3037 --- /dev/null +++ b/deps/libevent @@ -0,0 +1 @@ +Subproject commit 5df3037d10556bfcb675bc73e516978b75fc7bc7 diff --git a/etc/observer.ini b/etc/observer.ini index 294aad5..73b9832 100644 --- a/etc/observer.ini +++ b/etc/observer.ini @@ -57,21 +57,22 @@ count=3 [SessionStage] ThreadId=SQLThreads -NextStages=ResolveStage +NextStages=PlanCacheStage -[ResolveStage] +[PlanCacheStage] ThreadId=SQLThreads -NextStages=QueryCacheStage +#NextStages=OptimizeStage +NextStages=ParseStage -[QueryCacheStage] +[ParseStage] ThreadId=SQLThreads -NextStages=PlanCacheStage +NextStages=ResolveStage -[PlanCacheStage] +[ResolveStage] ThreadId=SQLThreads -NextStages=ExecuteStage,ParseStage +NextStages=QueryCacheStage -[ParseStage] +[QueryCacheStage] ThreadId=SQLThreads NextStages=OptimizeStage diff --git a/src/observer/event/#sql_event.cpp# b/src/observer/event/#sql_event.cpp# new file mode 100644 index 0000000..3b0835d --- /dev/null +++ b/src/observer/event/#sql_event.cpp# @@ -0,0 +1,29 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 Longda on 2021/4/14. +// + +#include "event/sql_event.h" +#include "event/session_event.h" + +SQLStageEvent::SQLStageEvent(SessionEvent *event, const std::string &sql) : session_event_(event), sql_(sql) +{} + +SQLStageEvent::~SQLStageEvent() noexcept +{ + if (session_event_ != nullptr) { + session_event_ = nullptr; + // SessionEvent *session_event = session_event_; + // session_event_ = nullptr; + // session_event->doneImmediate(); + } +} diff --git a/src/observer/event/execution_plan_event.cpp b/src/observer/event/execute_plan_event.cpp.bak similarity index 100% rename from src/observer/event/execution_plan_event.cpp rename to src/observer/event/execute_plan_event.cpp.bak diff --git a/src/observer/event/execution_plan_event.h b/src/observer/event/execute_plan_event.h.bak similarity index 62% rename from src/observer/event/execution_plan_event.h rename to src/observer/event/execute_plan_event.h.bak index 67b33d7..24f8aa5 100644 --- a/src/observer/event/execution_plan_event.h +++ b/src/observer/event/execute_plan_event.h.bak @@ -12,32 +12,32 @@ See the Mulan PSL v2 for more details. */ // Created by Wangyunlai on 2021/5/11. // -#ifndef __OBSERVER_EVENT_EXECUTION_PLAN_EVENT_H__ -#define __OBSERVER_EVENT_EXECUTION_PLAN_EVENT_H__ +#pragma once #include "common/seda/stage_event.h" -#include "sql/parser/parse.h" class SQLStageEvent; -class ExecutionPlanEvent : public common::StageEvent { +class ExecutePlanEvent : public common::StageEvent { public: - ExecutionPlanEvent(SQLStageEvent *sql_event, Query *sqls); - virtual ~ExecutionPlanEvent(); + ExecutePlanEvent(SQLStageEvent *sql_event, common::StageEvent *parent_event) + : sql_event_(sql_event), parent_event_(parent_event) + {} - Query *sqls() const - { - return sqls_; - } + virtual ~ExecutePlanEvent() = default; SQLStageEvent *sql_event() const { return sql_event_; } + common::StageEvent *parent_event() const { + return parent_event_; + } + private: - SQLStageEvent *sql_event_; - Query *sqls_; + SQLStageEvent *sql_event_ = nullptr; + common::StageEvent *parent_event_ = nullptr; }; -#endif // __OBSERVER_EVENT_EXECUTION_PLAN_EVENT_H__ \ No newline at end of file +#endif // __OBSERVER_EVENT_EXECUTION_PLAN_EVENT_H__ diff --git a/src/observer/event/optimize_event.h b/src/observer/event/optimize_event.h new file mode 100644 index 0000000..2e7d98f --- /dev/null +++ b/src/observer/event/optimize_event.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/6/7. +// + +#pragma once + +#include "common/seda/stage_event.h" + +class SQLStageEvent; +class Stmt; + +class OptimizeEvent : public common::StageEvent { +public: + OptimizeEvent(SQLStageEvent *sql_event, common::StageEvent *parent_event) + : sql_event_(sql_event), parent_event_(parent_event) + {} + + virtual ~OptimizeEvent() noexcept = default; + + SQLStageEvent *sql_event() const { + return sql_event_; + } + + common::StageEvent *parent_event() const { + return parent_event_; + } + +private: + SQLStageEvent *sql_event_ = nullptr; + common::StageEvent *parent_event_ = nullptr; +}; + diff --git a/src/observer/event/query_cache_event.h.bak b/src/observer/event/query_cache_event.h.bak new file mode 100644 index 0000000..d2773dd --- /dev/null +++ b/src/observer/event/query_cache_event.h.bak @@ -0,0 +1,42 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/23. +// + +#pragma once + +#include "common/seda/stage_event.h" + +class SQLStageEvent; +class Stmt; + +class QueryCacheEvent : public common::StageEvent { +public: + QueryCacheEvent(SQLStageEvent *sql_event, common::StageEvent *parent_event) + : sql_event_(sql_event), parent_event_(parent_event) + {} + + virtual ~QueryCacheEvent() noexcept = default; + + SQLStageEvent *sql_event() const { + return sql_event_; + } + + common::StageEvent *parent_event() const { + return parent_event_; + } + +private: + SQLStageEvent *sql_event_ = nullptr; + common::StageEvent *parent_event_ = nullptr; +}; + diff --git a/src/observer/event/storage_event.cpp b/src/observer/event/resolve_event.cpp.bak similarity index 61% rename from src/observer/event/storage_event.cpp rename to src/observer/event/resolve_event.cpp.bak index 605c4d7..78f8680 100644 --- a/src/observer/event/storage_event.cpp +++ b/src/observer/event/resolve_event.cpp.bak @@ -9,20 +9,15 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. */ // -// Created by Longda on 2021/4/14. +// Created by Wangyunlai on 2022/5/23. // -#include "event/storage_event.h" -#include "event/execution_plan_event.h" +#include "event/resolve_event.h" +#include "event/session_event.h" -StorageEvent::StorageEvent(ExecutionPlanEvent *exe_event) : exe_event_(exe_event) +ResolveStageEvent(SessionEvent *event) : session_event_(event) {} -StorageEvent::~StorageEvent() +ResolveStageEvent::~ResolveStageEvent() noexcept { - exe_event_ = nullptr; - // if (exe_event_ != nullptr) { - // ExecutionPlanEvent *exe_event = exe_event_; - // exe_event->doneImmediate(); - // } -} \ No newline at end of file +} diff --git a/src/observer/event/resolve_event.h.bak b/src/observer/event/resolve_event.h.bak new file mode 100644 index 0000000..05e2de0 --- /dev/null +++ b/src/observer/event/resolve_event.h.bak @@ -0,0 +1,35 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/23. +// + +#pragma once + +#include "common/seda/stage_event.h" + +class SessionEvent; +class Stmt; + +class ResolveStageEvent : public BaseEvent { +public: + ResolveStageEvent(SessionEvent *event); + virtual ~ResolveStageEvent() noexcept; + + SessionEvent *session_event() const + { + return session_event_; + } + +private: + SessionEvent *session_event_ = nullptr; +}; + diff --git a/src/observer/event/session_event.cpp b/src/observer/event/session_event.cpp index 14aef42..1ba7b4d 100644 --- a/src/observer/event/session_event.cpp +++ b/src/observer/event/session_event.cpp @@ -15,16 +15,23 @@ See the Mulan PSL v2 for more details. */ #include "session_event.h" SessionEvent::SessionEvent(ConnectionContext *client) : client_(client) -{} +{ +} SessionEvent::~SessionEvent() -{} +{ +} ConnectionContext *SessionEvent::get_client() const { return client_; } +Session *SessionEvent::session() const +{ + return client_->session; +} + const char *SessionEvent::get_response() const { return response_.c_str(); @@ -58,4 +65,4 @@ char *SessionEvent::get_request_buf() int SessionEvent::get_request_buf_len() { return SOCKET_BUFFER_SIZE; -} \ No newline at end of file +} diff --git a/src/observer/event/session_event.h b/src/observer/event/session_event.h index 67e9b75..933aafd 100644 --- a/src/observer/event/session_event.h +++ b/src/observer/event/session_event.h @@ -21,12 +21,15 @@ See the Mulan PSL v2 for more details. */ #include "common/seda/stage_event.h" #include "net/connection_context.h" +class Session; + class SessionEvent : public common::StageEvent { public: SessionEvent(ConnectionContext *client); virtual ~SessionEvent(); ConnectionContext *get_client() const; + Session *session() const; const char *get_response() const; void set_response(const char *response); diff --git a/src/observer/event/sql_event.cpp b/src/observer/event/sql_event.cpp index d157970..3b0835d 100644 --- a/src/observer/event/sql_event.cpp +++ b/src/observer/event/sql_event.cpp @@ -15,7 +15,7 @@ See the Mulan PSL v2 for more details. */ #include "event/sql_event.h" #include "event/session_event.h" -SQLStageEvent::SQLStageEvent(SessionEvent *event, std::string &sql) : session_event_(event), sql_(sql) +SQLStageEvent::SQLStageEvent(SessionEvent *event, const std::string &sql) : session_event_(event), sql_(sql) {} SQLStageEvent::~SQLStageEvent() noexcept @@ -26,4 +26,4 @@ SQLStageEvent::~SQLStageEvent() noexcept // session_event_ = nullptr; // session_event->doneImmediate(); } -} \ No newline at end of file +} diff --git a/src/observer/event/sql_event.h b/src/observer/event/sql_event.h index 9f2090a..c1b5ad6 100644 --- a/src/observer/event/sql_event.h +++ b/src/observer/event/sql_event.h @@ -15,30 +15,37 @@ See the Mulan PSL v2 for more details. */ #ifndef __OBSERVER_SQL_EVENT_SQLEVENT_H__ #define __OBSERVER_SQL_EVENT_SQLEVENT_H__ -#include "common/seda/stage_event.h" #include +#include "common/seda/stage_event.h" class SessionEvent; +class Stmt; +struct Query; -class SQLStageEvent : public common::StageEvent { +class SQLStageEvent : public common::StageEvent +{ public: - SQLStageEvent(SessionEvent *event, std::string &sql); + SQLStageEvent(SessionEvent *event, const std::string &sql); virtual ~SQLStageEvent() noexcept; - const std::string &get_sql() const - { - return sql_; - } - SessionEvent *session_event() const { return session_event_; } + const std::string &sql() const { return sql_; } + Query *query() const { return query_; } + Stmt *stmt() const { return stmt_; } + + void set_sql(const char *sql) { sql_ = sql; } + void set_query(Query *query) { query_ = query; } + void set_stmt(Stmt *stmt) { stmt_ = stmt; } + private: - SessionEvent *session_event_; - std::string &sql_; - // void *context_; + SessionEvent *session_event_ = nullptr; + std::string sql_; + Query *query_ = nullptr; + Stmt *stmt_ = nullptr; }; #endif //__SRC_OBSERVER_SQL_EVENT_SQLEVENT_H__ diff --git a/src/observer/event/storage_event.h b/src/observer/event/storage_event.h index 53564f9..a4aacf5 100644 --- a/src/observer/event/storage_event.h +++ b/src/observer/event/storage_event.h @@ -17,20 +17,22 @@ See the Mulan PSL v2 for more details. */ #include "common/seda/stage_event.h" -class ExecutionPlanEvent; +class SQLStageEvent; class StorageEvent : public common::StageEvent { public: - StorageEvent(ExecutionPlanEvent *exe_event); + StorageEvent(SQLStageEvent *sql_event) : sql_event_(sql_event) + {} + virtual ~StorageEvent(); - ExecutionPlanEvent *exe_event() const + SQLStageEvent *sql_event() const { - return exe_event_; + return sql_event_; } private: - ExecutionPlanEvent *exe_event_; + SQLStageEvent *sql_event_; }; #endif //__OBSERVER_SQL_EVENT_STORAGEEVENT_H__ diff --git a/src/observer/rc.cpp b/src/observer/rc.cpp index db3f053..b6b9344 100644 --- a/src/observer/rc.cpp +++ b/src/observer/rc.cpp @@ -24,6 +24,7 @@ const char *strrc(RC rc) RC_CASE_STRING(SUCCESS); RC_CASE_STRING(GENERIC_ERROR); RC_CASE_STRING(INVALID_ARGUMENT); + RC_CASE_STRING(UNIMPLENMENT); RC_CASE_STRING(SQL_SYNTAX); RC_CASE_STRING(BUFFERPOOL); RC_CASE_STRING(RECORD); @@ -179,4 +180,4 @@ const char *strrc(RC rc) return "UNKNOWN"; } } -} \ No newline at end of file +} diff --git a/src/observer/rc.h b/src/observer/rc.h index e6240a7..e8db88f 100644 --- a/src/observer/rc.h +++ b/src/observer/rc.h @@ -172,10 +172,11 @@ enum RC { /* beginning-of-error-codes */ GENERIC_ERROR, /* Generic error */ INVALID_ARGUMENT, /* Invalid argument */ + UNIMPLENMENT, /* not implenment yet */ SQL_SYNTAX, /* SQL Syntax error */ BUFFERPOOL, /* Buffer pool error*/ RECORD, /* Record error */ - INTERNAL, /* Internal logic error in SQLite */ + INTERNAL, /* Internal logic error in SQL */ PERM, /* Access permission denied */ ABORT, /* Callback routine requested an abort */ BUSY, /* The database file is locked */ diff --git a/src/observer/session/session.cpp b/src/observer/session/session.cpp index 94a46f1..4a91482 100644 --- a/src/observer/session/session.cpp +++ b/src/observer/session/session.cpp @@ -14,6 +14,8 @@ See the Mulan PSL v2 for more details. */ #include "session/session.h" #include "storage/trx/trx.h" +#include "storage/common/db.h" +#include "storage/default/default_handler.h" Session &Session::default_session() { @@ -21,7 +23,7 @@ Session &Session::default_session() return session; } -Session::Session(const Session &other) : current_db_(other.current_db_) +Session::Session(const Session &other) : db_(other.db_) {} Session::~Session() @@ -30,13 +32,30 @@ Session::~Session() trx_ = nullptr; } -const std::string &Session::get_current_db() const +const char *Session::get_current_db_name() const { - return current_db_; + if (db_ != nullptr) + return db_->name(); + else + return ""; } + +Db *Session::get_current_db() const +{ + return db_; +} + void Session::set_current_db(const std::string &dbname) { - current_db_ = dbname; + DefaultHandler &handler = DefaultHandler::get_default(); + Db *db = handler.find_db(dbname.c_str()); + if (db == nullptr) { + LOG_WARN("no such database: %s", dbname.c_str()); + return; + } + + LOG_TRACE("change db to %s", dbname.c_str()); + db_ = db; } void Session::set_trx_multi_operation_mode(bool multi_operation_mode) diff --git a/src/observer/session/session.h b/src/observer/session/session.h index 8376782..c3b7e68 100644 --- a/src/observer/session/session.h +++ b/src/observer/session/session.h @@ -12,12 +12,12 @@ See the Mulan PSL v2 for more details. */ // Created by Wangyunlai on 2021/5/12. // -#ifndef __OBSERVER_SESSION_SESSION_H__ -#define __OBSERVER_SESSION_SESSION_H__ +#pragma once #include class Trx; +class Db; class Session { public: @@ -31,7 +31,9 @@ public: Session(const Session &other); void operator=(Session &) = delete; - const std::string &get_current_db() const; + const char *get_current_db_name() const; + Db *get_current_db() const; + void set_current_db(const std::string &dbname); void set_trx_multi_operation_mode(bool multi_operation_mode); @@ -40,9 +42,7 @@ public: Trx *current_trx(); private: - std::string current_db_; + Db *db_ = nullptr; Trx *trx_ = nullptr; bool trx_multi_operation_mode_ = false; // 当前事务的模式,是否多语句模式. 单语句模式自动提交 }; - -#endif // __OBSERVER_SESSION_SESSION_H__ \ No newline at end of file diff --git a/src/observer/session/session_stage.cpp b/src/observer/session/session_stage.cpp index 6a7c051..7639e20 100644 --- a/src/observer/session/session_stage.cpp +++ b/src/observer/session/session_stage.cpp @@ -34,7 +34,7 @@ using namespace common; const std::string SessionStage::SQL_METRIC_TAG = "SessionStage.sql"; // Constructor -SessionStage::SessionStage(const char *tag) : Stage(tag), resolve_stage_(nullptr), sql_metric_(nullptr) +SessionStage::SessionStage(const char *tag) : Stage(tag), plan_cache_stage_(nullptr), sql_metric_(nullptr) {} // Destructor @@ -73,7 +73,7 @@ bool SessionStage::initialize() LOG_TRACE("Enter"); std::list::iterator stgp = next_stage_list_.begin(); - resolve_stage_ = *(stgp++); + plan_cache_stage_ = *(stgp++); MetricsRegistry &metricsRegistry = get_metrics_registry(); sql_metric_ = new SimpleTimer(); @@ -138,7 +138,6 @@ void SessionStage::callback_event(StageEvent *event, CallbackContext *context) void SessionStage::handle_request(StageEvent *event) { - SessionEvent *sev = dynamic_cast(event); if (nullptr == sev) { LOG_ERROR("Cannot cat event to sessionEvent"); @@ -169,5 +168,5 @@ void SessionStage::handle_request(StageEvent *event) sev->push_callback(cb); SQLStageEvent *sql_event = new SQLStageEvent(sev, sql); - resolve_stage_->handle_event(sql_event); + plan_cache_stage_->handle_event(sql_event); } diff --git a/src/observer/session/session_stage.h b/src/observer/session/session_stage.h index 39639ad..00136cc 100644 --- a/src/observer/session/session_stage.h +++ b/src/observer/session/session_stage.h @@ -47,8 +47,8 @@ protected: void handle_request(common::StageEvent *event); private: - Stage *resolve_stage_; - common::SimpleTimer *sql_metric_; + Stage *plan_cache_stage_ = nullptr; + common::SimpleTimer *sql_metric_ = nullptr; static const std::string SQL_METRIC_TAG; }; diff --git a/src/observer/sql/executor/delete_operator.h b/src/observer/sql/executor/delete_operator.h new file mode 100644 index 0000000..13e8520 --- /dev/null +++ b/src/observer/sql/executor/delete_operator.h @@ -0,0 +1,37 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2021/6/9. +// + +#pragma once + +#include "sql/parser/parse.h" +#include "rc.h" + +class DeleteStmt; + +class DeleteOperator : public Operator +{ +public: + DeleteOperator(DeleteStmt *delete_stmt) + : delete_stmt_(delete_stmt) + {} + + virtual ~InsertOperator() = default; + + RC open() override; + RC next() override; + RC close() override; + +private: + InsertStmt *insert_stmt_ = nullptr; +}; diff --git a/src/observer/sql/executor/execute_stage.cpp b/src/observer/sql/executor/execute_stage.cpp index ce18b01..1523f80 100644 --- a/src/observer/sql/executor/execute_stage.cpp +++ b/src/observer/sql/executor/execute_stage.cpp @@ -25,9 +25,14 @@ See the Mulan PSL v2 for more details. */ #include "event/storage_event.h" #include "event/sql_event.h" #include "event/session_event.h" -#include "event/execution_plan_event.h" #include "sql/executor/execution_node.h" #include "sql/executor/tuple.h" +#include "sql/executor/table_scan_operator.h" +#include "sql/stmt/stmt.h" +#include "sql/stmt/select_stmt.h" +#include "sql/stmt/update_stmt.h" +#include "sql/stmt/delete_stmt.h" +#include "sql/stmt/insert_stmt.h" #include "storage/common/table.h" #include "storage/default/default_handler.h" #include "storage/common/condition_filter.h" @@ -108,9 +113,6 @@ void ExecuteStage::callback_event(StageEvent *event, CallbackContext *context) LOG_TRACE("Enter\n"); // here finish read all data from disk or network, but do nothing here. - ExecutionPlanEvent *exe_event = static_cast(event); - SQLStageEvent *sql_event = exe_event->sql_event(); - sql_event->done_immediate(); LOG_TRACE("Exit\n"); return; @@ -118,88 +120,83 @@ void ExecuteStage::callback_event(StageEvent *event, CallbackContext *context) void ExecuteStage::handle_request(common::StageEvent *event) { - ExecutionPlanEvent *exe_event = static_cast(event); - SessionEvent *session_event = exe_event->sql_event()->session_event(); - Query *sql = exe_event->sqls(); - const char *current_db = session_event->get_client()->session->get_current_db().c_str(); - - CompletionCallback *cb = new (std::nothrow) CompletionCallback(this, nullptr); - if (cb == nullptr) { - LOG_ERROR("Failed to new callback for ExecutionPlanEvent"); - exe_event->done_immediate(); - return; + SQLStageEvent *sql_event = static_cast(event); + SessionEvent *session_event = sql_event->session_event(); + Stmt *stmt = sql_event->stmt(); + Session *session = session_event->session(); + Db *current_db = session->get_current_db(); + Query *sql = sql_event->query(); + + if (stmt != nullptr) { + switch (stmt->type()) { + case StmtType::SELECT: { + do_select((SelectStmt *)stmt, session_event); + } break; + case StmtType::UPDATE: { + //do_update((UpdateStmt *)stmt, session_event); + } break; + case StmtType::DELETE: { + //do_delete((DeleteStmt *)stmt, session_event); + } break; + } + } else { + switch (sql->flag) { + case SCF_HELP: { + do_help(sql_event); + } break; + case SCF_CREATE_TABLE: { + do_create_table(sql_event); + } break; + case SCF_CREATE_INDEX: { + do_create_index(sql_event); + } break; + case SCF_SHOW_TABLES: { + do_show_tables(sql_event); + } break; + case SCF_DESC_TABLE: { + do_desc_table(sql_event); + } break; + } } - exe_event->push_callback(cb); switch (sql->flag) { - case SCF_SELECT: { // select - do_select(current_db, sql, exe_event->sql_event()->session_event()); - exe_event->done_immediate(); - } break; + //case SCF_SELECT: { // select + // do_select(current_db, sql, exe_event->sql_event()->session_event()); + // exe_event->done_immediate(); + //} bre case SCF_INSERT: - case SCF_UPDATE: - case SCF_DELETE: - case SCF_CREATE_TABLE: - case SCF_SHOW_TABLES: - case SCF_DESC_TABLE: case SCF_DROP_TABLE: - case SCF_CREATE_INDEX: case SCF_DROP_INDEX: case SCF_LOAD_DATA: { - StorageEvent *storage_event = new (std::nothrow) StorageEvent(exe_event); - if (storage_event == nullptr) { - LOG_ERROR("Failed to new StorageEvent"); - event->done_immediate(); - return; - } - - default_storage_stage_->handle_event(storage_event); + default_storage_stage_->handle_event(event); } break; case SCF_SYNC: { RC rc = DefaultHandler::get_default().sync(); session_event->set_response(strrc(rc)); - exe_event->done_immediate(); } break; case SCF_BEGIN: { - session_event->get_client()->session->set_trx_multi_operation_mode(true); + session->set_trx_multi_operation_mode(true); session_event->set_response(strrc(RC::SUCCESS)); - exe_event->done_immediate(); } break; case SCF_COMMIT: { - Trx *trx = session_event->get_client()->session->current_trx(); + Trx *trx = session->current_trx(); RC rc = trx->commit(); - session_event->get_client()->session->set_trx_multi_operation_mode(false); + session->set_trx_multi_operation_mode(false); session_event->set_response(strrc(rc)); - exe_event->done_immediate(); } break; case SCF_ROLLBACK: { Trx *trx = session_event->get_client()->session->current_trx(); RC rc = trx->rollback(); - session_event->get_client()->session->set_trx_multi_operation_mode(false); + session->set_trx_multi_operation_mode(false); session_event->set_response(strrc(rc)); - exe_event->done_immediate(); - } break; - case SCF_HELP: { - const char *response = "show tables;\n" - "desc `table name`;\n" - "create table `table name` (`column name` `column type`, ...);\n" - "create index `index name` on `table` (`column`);\n" - "insert into `table` values(`value1`,`value2`);\n" - "update `table` set column=value [where `column`=`value`];\n" - "delete from `table` [where `column`=`value`];\n" - "select [ * | `columns` ] from `table`;\n"; - session_event->set_response(response); - exe_event->done_immediate(); } break; case SCF_EXIT: { // do nothing const char *response = "Unsupported\n"; session_event->set_response(response); - exe_event->done_immediate(); } break; default: { - exe_event->done_immediate(); LOG_ERROR("Unsupported command=%d\n", sql->flag); } } @@ -216,6 +213,37 @@ void end_trx_if_need(Session *session, Trx *trx, bool all_right) } } +RC ExecuteStage::do_select(SelectStmt *select_stmt, SessionEvent *session_event) +{ + RC rc = RC::SUCCESS; + if (select_stmt->tables().size() != 1) { + LOG_WARN("select more than 1 tables is not supported"); + rc = RC::UNIMPLENMENT; + return rc; + } + + Table *table = select_stmt->tables().front(); + TableScanOperator table_scan_operator(table); + rc = table_scan_operator.open(); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to open operator"); + return rc; + } + + while ((rc = table_scan_operator.next()) == RC::SUCCESS) { + // get current record + // write to response + } + if (rc != RC::RECORD_EOF) { + LOG_WARN("something wrong while iterate operator. rc=%s", strrc(rc)); + table_scan_operator.close(); + } else { + rc = table_scan_operator.close(); + } + return rc; +} + +#if 0 // 这里没有对输入的某些信息做合法性校验,比如查询的列名、where条件中的列名等,没有做必要的合法性校验 // 需要补充上这一部分. 校验部分也可以放在resolve,不过跟execution放一起也没有关系 RC ExecuteStage::do_select(const char *db, Query *sql, SessionEvent *session_event) @@ -357,3 +385,83 @@ RC create_selection_executor( return select_node.init(trx, table, std::move(schema), std::move(condition_filters)); } +#endif + +RC ExecuteStage::do_help(SQLStageEvent *sql_event) +{ + SessionEvent *session_event = sql_event->session_event(); + const char *response = "show tables;\n" + "desc `table name`;\n" + "create table `table name` (`column name` `column type`, ...);\n" + "create index `index name` on `table` (`column`);\n" + "insert into `table` values(`value1`,`value2`);\n" + "update `table` set column=value [where `column`=`value`];\n" + "delete from `table` [where `column`=`value`];\n" + "select [ * | `columns` ] from `table`;\n"; + session_event->set_response(response); + return RC::SUCCESS; +} + +RC ExecuteStage::do_create_table(SQLStageEvent *sql_event) +{ + const CreateTable &create_table = sql_event->query()->sstr.create_table; + SessionEvent *session_event = sql_event->session_event(); + Db *db = session_event->session()->get_current_db(); + RC rc = db->create_table(create_table.relation_name, + create_table.attribute_count, create_table.attributes); + if (rc == RC::SUCCESS) { + session_event->set_response("SUCCESS"); + } else { + session_event->set_response("FAILURE"); + } + return rc; +} +RC ExecuteStage::do_create_index(SQLStageEvent *sql_event) +{ + SessionEvent *session_event = sql_event->session_event(); + Db *db = session_event->session()->get_current_db(); + const CreateIndex &create_index = sql_event->query()->sstr.create_index; + Table *table = db->find_table(create_index.relation_name); + if (nullptr == table) { + session_event->set_response("FAILURE"); + return RC::SCHEMA_TABLE_NOT_EXIST; + } + + RC rc = table->create_index(nullptr, create_index.index_name, create_index.attribute_name); + sql_event->session_event()->set_response(rc == RC::SUCCESS ? "SUCCESS" : "FAILURE"); + return rc; +} + +RC ExecuteStage::do_show_tables(SQLStageEvent *sql_event) +{ + SessionEvent *session_event = sql_event->session_event(); + Db *db = session_event->session()->get_current_db(); + std::vector all_tables; + db->all_tables(all_tables); + if (all_tables.empty()) { + session_event->set_response("No table\n"); + } else { + std::stringstream ss; + for (const auto &table : all_tables) { + ss << table << std::endl; + } + session_event->set_response(ss.str().c_str()); + } + return RC::SUCCESS; +} + +RC ExecuteStage::do_desc_table(SQLStageEvent *sql_event) +{ + Query *query = sql_event->query(); + Db *db = sql_event->session_event()->session()->get_current_db(); + const char *table_name = query->sstr.desc_table.relation_name; + Table *table = db->find_table(table_name); + std::stringstream ss; + if (table != nullptr) { + table->table_meta().desc(ss); + } else { + ss << "No such table: " << table_name << std::endl; + } + sql_event->session_event()->set_response(ss.str().c_str()); + return RC::SUCCESS; +} diff --git a/src/observer/sql/executor/execute_stage.h b/src/observer/sql/executor/execute_stage.h index 12d977d..7eb78c6 100644 --- a/src/observer/sql/executor/execute_stage.h +++ b/src/observer/sql/executor/execute_stage.h @@ -19,7 +19,9 @@ See the Mulan PSL v2 for more details. */ #include "sql/parser/parse.h" #include "rc.h" +class SQLStageEvent; class SessionEvent; +class SelectStmt; class ExecuteStage : public common::Stage { public: @@ -37,7 +39,12 @@ protected: void callback_event(common::StageEvent *event, common::CallbackContext *context) override; void handle_request(common::StageEvent *event); - RC do_select(const char *db, Query *sql, SessionEvent *session_event); + RC do_help(SQLStageEvent *session_event); + RC do_create_table(SQLStageEvent *sql_event); + RC do_create_index(SQLStageEvent *sql_event); + RC do_show_tables(SQLStageEvent *sql_event); + RC do_desc_table(SQLStageEvent *sql_event); + RC do_select(SelectStmt *select_stmt, SessionEvent *session_event); protected: private: diff --git a/src/observer/sql/executor/insert_operator.cpp b/src/observer/sql/executor/insert_operator.cpp new file mode 100644 index 0000000..a92362e --- /dev/null +++ b/src/observer/sql/executor/insert_operator.cpp @@ -0,0 +1,36 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2021/6/9. +// + +#include "sql/executor/insert_operator.h" +#include "sql/stmt/insert_stmt.h" +#include "storage/common/table.h" +#include "rc.h" + +RC InsertOperator::open() +{ + Table *table = insert_stmt_->table(); + const Value *values = insert_stmt_->values(); + int value_amount = insert_stmt_->value_amount(); + return table->insert_record(nullptr, value_amount, values); // TODO trx +} + +RC InsertOperator::next() +{ + return RC::RECORD_EOF; +} + +RC InsertOperator::close() +{ + return RC::SUCCESS; +} diff --git a/src/observer/sql/executor/insert_operator.h b/src/observer/sql/executor/insert_operator.h new file mode 100644 index 0000000..a501cb8 --- /dev/null +++ b/src/observer/sql/executor/insert_operator.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2021/6/7. +// + +#pragma once + +#include "common/seda/stage.h" +#include "sql/executor/operator.h" +#include "sql/parser/parse.h" +#include "rc.h" + +class InsertStmt; + +class InsertOperator : public Operator +{ +public: + InsertOperator(InsertStmt *insert_stmt) + : insert_stmt_(insert_stmt) + {} + + virtual ~InsertOperator() = default; + + RC open() override; + RC next() override; + RC close() override; + +private: + InsertStmt *insert_stmt_ = nullptr; +}; diff --git a/src/observer/sql/executor/join_operator.cpp.bak b/src/observer/sql/executor/join_operator.cpp.bak new file mode 100644 index 0000000..19dd586 --- /dev/null +++ b/src/observer/sql/executor/join_operator.cpp.bak @@ -0,0 +1,82 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2021/6/10. +// + +#include "sql/executor/join_operator.h" + +RC JoinOperator::open() +{ + RC rc = left_->open(); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to open left operator. rc=%d:%s", rc, strrc(rc)); + return rc; + } + + rc = right_->open(); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to open right operator. rc=%d:%s", rc, strrc(rc)); + return rc; + } + return rc; +} + +RC JoinOperator::step_right() +{ + rc = right_->next(); + while (rc == RC::SUCCESS) { + if (predicate_->filter()) { + return rc; + } + + rc = right_->next(); + } + return rc; +} + +RC JoinOperator::next() +{ + RC rc = RC::SUCCESS; + while (true) { + if (round_done_) { + rc = left_->next(); + if (rc != RC::SUCCESS) { + return rc; + } + + round_done_ = false; + + right_->close(); + right_->open(); // TODO + } + + rc = step_right(); + if (rc == RC::SUCCESS) { + return rc; + } + + if (rc == RC::RECORD_EOF) { + round_done_ = true; + } else { + return rc; + } + } + + return RC::RECORD_EOF; +} + +RC JoinOperator::close() +{ + left_->close(); + right_->close(); + return RC::SUCCESS; +} diff --git a/src/observer/sql/executor/join_operator.h b/src/observer/sql/executor/join_operator.h new file mode 100644 index 0000000..538c93c --- /dev/null +++ b/src/observer/sql/executor/join_operator.h @@ -0,0 +1,40 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2021/6/10. +// + +#pragma once + +#include "sql/parser/parse.h" +#include "sql/executor/operator.h" +#include "rc.h" + +class JoinPredicate; + +class JoinOperator : public Operator +{ +public: + JoinOperator(Operator *left, Operator *right) + {} + + virtual ~JoinOperator() = default; + + RC open() override; + RC next() override; + RC close() override; + +private: + Operator *left_ = nullptr; + Operator *right_ = nullptr; + JoinPredicate *predicate_ = nullptr; + bool round_done_ = true; +}; diff --git a/src/observer/sql/executor/operator.h b/src/observer/sql/executor/operator.h new file mode 100644 index 0000000..03a508f --- /dev/null +++ b/src/observer/sql/executor/operator.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2021/6/7. +// + +#pragma once + +#include "common/seda/stage.h" +#include "sql/parser/parse.h" +#include "rc.h" + +class Operator +{ +public: + Operator() + {} + + virtual ~Operator() = default; + + virtual RC open() = 0; + virtual RC next() = 0; + virtual RC close() = 0; + +private: +}; diff --git a/src/observer/sql/executor/predicate.cpp b/src/observer/sql/executor/predicate.cpp new file mode 100644 index 0000000..b8dfafa --- /dev/null +++ b/src/observer/sql/executor/predicate.cpp @@ -0,0 +1,17 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2021/6/9. +// + +#include "sql/executor/predicate.h" + + diff --git a/src/observer/sql/executor/predicate.h b/src/observer/sql/executor/predicate.h new file mode 100644 index 0000000..164b96e --- /dev/null +++ b/src/observer/sql/executor/predicate.h @@ -0,0 +1,27 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2021/6/10. +// + +#pragma once + +class Predicate +{ +public: + Predicate() + {} + + virtual ~Predicate() = default; + + +private: +}; diff --git a/src/observer/sql/executor/table_scan_operator.cpp b/src/observer/sql/executor/table_scan_operator.cpp new file mode 100644 index 0000000..ceb8273 --- /dev/null +++ b/src/observer/sql/executor/table_scan_operator.cpp @@ -0,0 +1,46 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2021/6/9. +// + +#include "sql/executor/table_scan_operator.h" +#include "storage/common/table.h" +#include "rc.h" + +RC TableScanOperator::open() +{ + return table_->get_record_scanner(record_scanner_); +} + +RC TableScanOperator::next() +{ + if (!record_scanner_.has_next()) { + return RC::RECORD_EOF; + } + + RC rc = record_scanner_.next(current_record_); + while (rc == RC::SUCCESS) { + //if (predicate_ != nullptr && predicate_->filter(current_record_)) { + // return rc; + //} + + if (record_scanner_.has_next()) { + rc = record_scanner_.next(current_record_); + } + } + return rc; +} + +RC TableScanOperator::close() +{ + return record_scanner_.close_scan(); +} diff --git a/src/observer/sql/executor/table_scan_operator.h b/src/observer/sql/executor/table_scan_operator.h new file mode 100644 index 0000000..7c20df7 --- /dev/null +++ b/src/observer/sql/executor/table_scan_operator.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2021/6/7. +// + +#pragma once + +#include "sql/executor/predicate.h" +#include "sql/executor/operator.h" +#include "storage/common/record_manager.h" +#include "rc.h" + +class Table; +class Predicate; + +class TableScanOperator : public Operator +{ +public: + TableScanOperator(Table *table) + : table_(table), predicate_(nullptr) + {} + + TableScanOperator(Table *table, Predicate *pred) + : table_(table), predicate_(pred) + {} + + virtual ~TableScanOperator() = default; + + RC open() override; + RC next() override; + RC close() override; + +private: + Table *table_ = nullptr; + RecordFileScanner record_scanner_; + Predicate *predicate_ = nullptr; + Record current_record_; +}; diff --git a/src/observer/sql/optimizer/optimize_stage.cpp b/src/observer/sql/optimizer/optimize_stage.cpp index 4ce4f84..f283e48 100644 --- a/src/observer/sql/optimizer/optimize_stage.cpp +++ b/src/observer/sql/optimizer/optimize_stage.cpp @@ -65,7 +65,7 @@ bool OptimizeStage::initialize() LOG_TRACE("Enter"); std::list::iterator stgp = next_stage_list_.begin(); - execute_stage = *(stgp++); + execute_stage_ = *(stgp++); LOG_TRACE("Exit"); return true; @@ -84,7 +84,7 @@ void OptimizeStage::handle_event(StageEvent *event) LOG_TRACE("Enter\n"); // optimize sql plan, here just pass the event to the next stage - execute_stage->handle_event(event); + execute_stage_->handle_event(event); LOG_TRACE("Exit\n"); return; @@ -93,7 +93,6 @@ void OptimizeStage::handle_event(StageEvent *event) void OptimizeStage::callback_event(StageEvent *event, CallbackContext *context) { LOG_TRACE("Enter\n"); - LOG_TRACE("Exit\n"); return; } diff --git a/src/observer/sql/optimizer/optimize_stage.h b/src/observer/sql/optimizer/optimize_stage.h index 47df973..67fac0a 100644 --- a/src/observer/sql/optimizer/optimize_stage.h +++ b/src/observer/sql/optimizer/optimize_stage.h @@ -34,7 +34,7 @@ protected: protected: private: - Stage *execute_stage = nullptr; + Stage *execute_stage_ = nullptr; }; #endif //__OBSERVER_SQL_OPTIMIZE_STAGE_H__ diff --git a/src/observer/sql/parser/#parse_stage.h# b/src/observer/sql/parser/#parse_stage.h# new file mode 100644 index 0000000..b14e40a --- /dev/null +++ b/src/observer/sql/parser/#parse_stage.h# @@ -0,0 +1,42 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 Longda on 2021/4/13. +// + +#ifndef __OBSERVER_SQL_PARSE_STAGE_H__ +#define __OBSERVER_SQL_PARSE_STAGE_H__ + +#include "common/seda/stage.h" + +class ParseStage : public common::Stage { +public: + ~ParseStage(); + static Stage *make_stage(const std::string &tag); + +protected: + // common function + ParseStage(const char *tag); + bool set_properties(); + + bool initialize(); + void cleanup(); + void handle_event(common::StageEvent *event); + void callback_event(common::StageEvent *event, common::CallbackContext *context); + +protected: + common::StageEvent *handle_request(common::StageEvent *event); + +private: + Stage *resolve_stage_ = nullptr; +}; + +#endif //__OBSERVER_SQL_PARSE_STAGE_H__ diff --git a/src/observer/sql/parser/parse_defs.h b/src/observer/sql/parser/parse_defs.h index 28df590..9b8f243 100644 --- a/src/observer/sql/parser/parse_defs.h +++ b/src/observer/sql/parser/parse_defs.h @@ -238,4 +238,4 @@ void query_destroy(Query *query); // reset and delete } #endif // __cplusplus -#endif // __OBSERVER_SQL_PARSER_PARSE_DEFS_H__ \ No newline at end of file +#endif // __OBSERVER_SQL_PARSER_PARSE_DEFS_H__ diff --git a/src/observer/sql/parser/parse_stage.cpp b/src/observer/sql/parser/parse_stage.cpp index ede57bf..5647273 100644 --- a/src/observer/sql/parser/parse_stage.cpp +++ b/src/observer/sql/parser/parse_stage.cpp @@ -25,7 +25,6 @@ See the Mulan PSL v2 for more details. */ #include "event/session_event.h" #include "event/sql_event.h" #include "sql/parser/parse.h" -#include "event/execution_plan_event.h" using namespace common; @@ -69,7 +68,8 @@ bool ParseStage::initialize() LOG_TRACE("Enter"); std::list::iterator stgp = next_stage_list_.begin(); - optimize_stage_ = *(stgp++); + // optimize_stage_ = *(stgp++); + resolve_stage_ = *(stgp++); LOG_TRACE("Exit"); return true; @@ -87,9 +87,8 @@ void ParseStage::handle_event(StageEvent *event) { LOG_TRACE("Enter\n"); - StageEvent *new_event = handle_request(event); - if (nullptr == new_event) { - callback_event(event, nullptr); + RC rc = handle_request(event); + if (RC::SUCCESS != rc) { event->done_immediate(); return; } @@ -97,12 +96,13 @@ void ParseStage::handle_event(StageEvent *event) CompletionCallback *cb = new (std::nothrow) CompletionCallback(this, nullptr); if (cb == nullptr) { LOG_ERROR("Failed to new callback for SQLStageEvent"); - callback_event(event, nullptr); event->done_immediate(); return; } + event->push_callback(cb); - optimize_stage_->handle_event(new_event); + resolve_stage_->handle_event(event); + event->done_immediate(); LOG_TRACE("Exit\n"); return; @@ -113,31 +113,30 @@ void ParseStage::callback_event(StageEvent *event, CallbackContext *context) LOG_TRACE("Enter\n"); SQLStageEvent *sql_event = static_cast(event); sql_event->session_event()->done_immediate(); + sql_event->done_immediate(); LOG_TRACE("Exit\n"); return; } -StageEvent *ParseStage::handle_request(StageEvent *event) +RC ParseStage::handle_request(StageEvent *event) { SQLStageEvent *sql_event = static_cast(event); - const std::string &sql = sql_event->get_sql(); + const std::string &sql = sql_event->sql(); - Query *result = query_create(); - if (nullptr == result) { + Query *query_result = query_create(); + if (nullptr == query_result) { LOG_ERROR("Failed to create query."); - return nullptr; + return RC::INTERNAL; } - RC ret = parse(sql.c_str(), result); + RC ret = parse(sql.c_str(), query_result); if (ret != RC::SUCCESS) { // set error information to event - const char *error = result->sstr.errors != nullptr ? result->sstr.errors : "Unknown error"; - char response[256]; - snprintf(response, sizeof(response), "Failed to parse sql: %s, error msg: %s\n", sql.c_str(), error); - sql_event->session_event()->set_response(response); - query_destroy(result); - return nullptr; + sql_event->session_event()->set_response("Failed to parse sql"); + query_destroy(query_result); + return RC::INTERNAL; } - return new ExecutionPlanEvent(sql_event, result); + sql_event->set_query(query_result); + return RC::SUCCESS; } diff --git a/src/observer/sql/parser/parse_stage.h b/src/observer/sql/parser/parse_stage.h index e708bb0..aba6e3f 100644 --- a/src/observer/sql/parser/parse_stage.h +++ b/src/observer/sql/parser/parse_stage.h @@ -16,6 +16,7 @@ See the Mulan PSL v2 for more details. */ #define __OBSERVER_SQL_PARSE_STAGE_H__ #include "common/seda/stage.h" +#include "rc.h" class ParseStage : public common::Stage { public: @@ -33,10 +34,11 @@ protected: void callback_event(common::StageEvent *event, common::CallbackContext *context); protected: - common::StageEvent *handle_request(common::StageEvent *event); + RC handle_request(common::StageEvent *event); private: Stage *optimize_stage_ = nullptr; + Stage *resolve_stage_ = nullptr; }; #endif //__OBSERVER_SQL_PARSE_STAGE_H__ diff --git a/src/observer/sql/parser/resolve_stage.cpp b/src/observer/sql/parser/resolve_stage.cpp index 9dc48c2..9c46bb7 100644 --- a/src/observer/sql/parser/resolve_stage.cpp +++ b/src/observer/sql/parser/resolve_stage.cpp @@ -23,6 +23,10 @@ See the Mulan PSL v2 for more details. */ #include "common/log/log.h" #include "common/seda/timer_stage.h" #include "event/sql_event.h" +#include "event/session_event.h" +#include "session/session.h" +#include "sql/stmt/stmt.h" +#include "storage/default/default_handler.h" using namespace common; @@ -66,7 +70,7 @@ bool ResolveStage::initialize() LOG_TRACE("Enter"); std::list::iterator stgp = next_stage_list_.begin(); - query_cache_stage = *(stgp++); + query_cache_stage_ = *(stgp++); LOG_TRACE("Exit"); return true; @@ -85,9 +89,31 @@ void ResolveStage::handle_event(StageEvent *event) LOG_TRACE("Enter\n"); SQLStageEvent *sql_event = static_cast(event); + if (nullptr == sql_event) { + LOG_WARN("failed to get sql stage event"); + return; + } + + SessionEvent *session_event = sql_event->session_event(); + + DefaultHandler &handler = DefaultHandler::get_default(); + Db *db = session_event->session()->get_current_db(); + if (nullptr == db) { + LOG_ERROR("cannot current db"); + return ; + } + + Query *query = sql_event->query(); + Stmt *stmt = nullptr; + RC rc = Stmt::create_stmt(db, *query, stmt); + if (rc != RC::SUCCESS && rc != RC::UNIMPLENMENT) { + LOG_WARN("failed to create stmt. rc=%d:%s", rc, strrc(rc)); + return; + } + + sql_event->set_stmt(stmt); - // do nothing here - query_cache_stage->handle_event(sql_event); + query_cache_stage_->handle_event(sql_event); LOG_TRACE("Exit\n"); return; diff --git a/src/observer/sql/parser/resolve_stage.h b/src/observer/sql/parser/resolve_stage.h index 63c52ab..08897aa 100644 --- a/src/observer/sql/parser/resolve_stage.h +++ b/src/observer/sql/parser/resolve_stage.h @@ -34,7 +34,7 @@ protected: protected: private: - Stage *query_cache_stage = nullptr; + Stage *query_cache_stage_ = nullptr; }; #endif //__OBSERVER_SQL_RESOLVE_STAGE_H__ diff --git a/src/observer/sql/plan_cache/plan_cache_stage.cpp b/src/observer/sql/plan_cache/plan_cache_stage.cpp index c2c1c3d..7692bc4 100644 --- a/src/observer/sql/plan_cache/plan_cache_stage.cpp +++ b/src/observer/sql/plan_cache/plan_cache_stage.cpp @@ -65,8 +65,8 @@ bool PlanCacheStage::initialize() LOG_TRACE("Enter"); std::list::iterator stgp = next_stage_list_.begin(); - execute_stage = *(stgp++); - parse_stage = *(stgp++); + // execute_stage = *(stgp++); + parse_stage_ = *(stgp++); LOG_TRACE("Exit"); return true; @@ -96,7 +96,7 @@ void PlanCacheStage::handle_event(StageEvent *event) event->push_callback(cb); */ // do nothing here, pass the event to the next stage - parse_stage->handle_event(event); + parse_stage_->handle_event(event); LOG_TRACE("Exit\n"); return; diff --git a/src/observer/sql/plan_cache/plan_cache_stage.h b/src/observer/sql/plan_cache/plan_cache_stage.h index ebafeef..0099f27 100644 --- a/src/observer/sql/plan_cache/plan_cache_stage.h +++ b/src/observer/sql/plan_cache/plan_cache_stage.h @@ -34,8 +34,7 @@ protected: protected: private: - Stage *parse_stage = nullptr; - Stage *execute_stage = nullptr; + Stage *parse_stage_ = nullptr; }; #endif //__OBSERVER_SQL_PLAN_CACHE_STAGE_H__ diff --git a/src/observer/sql/query_cache/query_cache_stage.cpp b/src/observer/sql/query_cache/query_cache_stage.cpp index 650f2b2..80b5a60 100644 --- a/src/observer/sql/query_cache/query_cache_stage.cpp +++ b/src/observer/sql/query_cache/query_cache_stage.cpp @@ -65,7 +65,7 @@ bool QueryCacheStage::initialize() LOG_TRACE("Enter"); std::list::iterator stgp = next_stage_list_.begin(); - plan_cache_stage = *(stgp++); + optimize_stage_ = *(stgp++); LOG_TRACE("Exit"); return true; @@ -83,19 +83,7 @@ void QueryCacheStage::handle_event(StageEvent *event) { LOG_TRACE("Enter\n"); - // Add callback to update query cache - /* - CompletionCallback *cb = new (std::nothrow) CompletionCallback(this, nullptr); - if (cb == nullptr) { - LOG_ERROR("Failed to new callback for SQLStageEvent"); - event->done_immediate(); - return; - } - - event->push_callback(cb); - */ - // do nothing here, pass the event to the next stage - plan_cache_stage->handle_event(event); + optimize_stage_->handle_event(event); LOG_TRACE("Exit\n"); return; @@ -104,10 +92,6 @@ void QueryCacheStage::handle_event(StageEvent *event) void QueryCacheStage::callback_event(StageEvent *event, CallbackContext *context) { LOG_TRACE("Enter\n"); - - // update data to query cache here - // event->done_immediate(); - LOG_TRACE("Exit\n"); return; } diff --git a/src/observer/sql/query_cache/query_cache_stage.h b/src/observer/sql/query_cache/query_cache_stage.h index 27731bb..f889d3c 100644 --- a/src/observer/sql/query_cache/query_cache_stage.h +++ b/src/observer/sql/query_cache/query_cache_stage.h @@ -34,7 +34,7 @@ protected: protected: private: - Stage *plan_cache_stage = nullptr; + Stage *optimize_stage_ = nullptr; }; #endif //__OBSERVER_SQL_QUERY_CACHE_STAGE_H__ diff --git a/src/observer/sql/stmt/delete_stmt.cpp b/src/observer/sql/stmt/delete_stmt.cpp new file mode 100644 index 0000000..e5b5529 --- /dev/null +++ b/src/observer/sql/stmt/delete_stmt.cpp @@ -0,0 +1,58 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/22. +// + +#include "common/log/log.h" +#include "sql/stmt/delete_stmt.h" +#include "sql/stmt/filter_stmt.h" +#include "storage/common/db.h" +#include "storage/common/table.h" + +DeleteStmt::DeleteStmt(Table *table, FilterStmt *filter_stmt) + : table_ (table), filter_stmt_(filter_stmt) +{} + +DeleteStmt::~DeleteStmt() +{ + if (nullptr != filter_stmt_) { + delete filter_stmt_; + filter_stmt_ = nullptr; + } +} + +RC DeleteStmt::create(Db *db, const Deletes &delete_sql, Stmt *&stmt) +{ + const char *table_name = delete_sql.relation_name; + if (nullptr == db || nullptr == table_name) { + LOG_WARN("invalid argument. db=%p, table_name=%p", + db, table_name); + return RC::INVALID_ARGUMENT; + } + + // check whether the table exists + Table *table = db->find_table(table_name); + if (nullptr == table) { + LOG_WARN("no such table. db=%s, table_name=%s", db->name(), table_name); + return RC::SCHEMA_TABLE_NOT_EXIST; + } + + FilterStmt *filter_stmt = nullptr; + RC rc = FilterStmt::create(db, table, delete_sql.conditions, delete_sql.condition_num, filter_stmt); + if (rc != RC::SUCCESS) { + LOG_WARN("failed to create filter statement. rc=%d:%s", rc, strrc(rc)); + return rc; + } + + stmt = new DeleteStmt(table, filter_stmt); + return rc; +} diff --git a/src/observer/sql/stmt/delete_stmt.h b/src/observer/sql/stmt/delete_stmt.h new file mode 100644 index 0000000..295d13a --- /dev/null +++ b/src/observer/sql/stmt/delete_stmt.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/27. +// + +#pragma once + +#include "rc.h" +#include "sql/stmt/stmt.h" +#include "sql/parser/parse_defs.h" + +class Table; +class FilterStmt; + +class DeleteStmt : public Stmt +{ +public: + + DeleteStmt(Table *table, FilterStmt *filter_stmt); + ~DeleteStmt() override; + + Table *table() const { return table_; } + FilterStmt *filter_stmt() const { return filter_stmt_; } + + StmtType type() const override { return StmtType::DELETE; } +public: + static RC create(Db *db, const Deletes &delete_sql, Stmt *&stmt); + +private: + Table *table_ = nullptr; + FilterStmt *filter_stmt_ = nullptr; +}; + diff --git a/src/observer/sql/stmt/filter_stmt.cpp b/src/observer/sql/stmt/filter_stmt.cpp new file mode 100644 index 0000000..01a1b60 --- /dev/null +++ b/src/observer/sql/stmt/filter_stmt.cpp @@ -0,0 +1,106 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/22. +// + +#include "rc.h" +#include "common/log/log.h" +#include "common/lang/string.h" +#include "sql/stmt/filter_stmt.h" +#include "storage/common/db.h" +#include "storage/common/table.h" + +RC FilterStmt::create(Db *db, Table *default_table, + const Condition *conditions, int condition_num, + FilterStmt *&stmt) +{ + RC rc = RC::SUCCESS; + stmt = nullptr; + + FilterStmt *tmp_stmt = new FilterStmt(); + for (int i = 0; i < condition_num; i++) { + FilterUnit filter_unit; + rc = create_filter_unit(db, default_table, conditions[i], filter_unit); + if (rc != RC::SUCCESS) { + delete tmp_stmt; + LOG_WARN("failed to create filter unit. condition index=%d", i); + return rc; + } + tmp_stmt->filter_units_.push_back(filter_unit); + } + + stmt = tmp_stmt; + return rc; +} + +RC get_table_and_field(Db *db, Table *default_table, const RelAttr &attr, Table *&table, const FieldMeta *&field) +{ + if (common::is_blank(attr.relation_name)) { + table = default_table; + } else { + table = db->find_table(attr.relation_name); + } + if (nullptr == table) { + LOG_WARN("No such table: attr.relation_name: %s", attr.relation_name); + return RC::SCHEMA_TABLE_NOT_EXIST; + } + + field = table->table_meta().field(attr.attribute_name); + if (nullptr == field) { + LOG_WARN("no such field in table: table %s, field %s", table->name(), attr.attribute_name); + table = nullptr; + return RC::SCHEMA_FIELD_NOT_EXIST; + } + + return RC::SUCCESS; +} + +RC FilterStmt::create_filter_unit(Db *db, Table *default_table, + const Condition &condition, FilterUnit &filter_unit) +{ + RC rc = RC::SUCCESS; + + CompOp comp = condition.comp; + FilterItem &left_item = filter_unit.left(); + FilterItem &right_item = filter_unit.right(); + + if (condition.left_is_attr) { + Table *table = nullptr; + const FieldMeta *field = nullptr; + rc = get_table_and_field(db, default_table, condition.left_attr, table, field); + if (rc != RC::SUCCESS) { + LOG_WARN("cannot find attr"); + return rc; + } + left_item.set_field(table, field); + } else { + left_item.set_value(condition.left_value); + } + + if (condition.right_is_attr) { + Table *table = nullptr; + const FieldMeta *field = nullptr; + rc = get_table_and_field(db, default_table, condition.right_attr, table, field); + if (rc != RC::SUCCESS) { + LOG_WARN("cannot find attr"); + return rc; + } + right_item.set_field(table, field); + } else { + right_item.set_value(condition.right_value); + } + + // 检查两个类型是否能够比较 + return rc; +} + + diff --git a/src/observer/sql/stmt/filter_stmt.h b/src/observer/sql/stmt/filter_stmt.h new file mode 100644 index 0000000..211e4be --- /dev/null +++ b/src/observer/sql/stmt/filter_stmt.h @@ -0,0 +1,134 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/22. +// + +#pragma once + +#include +#include "rc.h" +#include "sql/parser/parse_defs.h" +#include "sql/stmt/stmt.h" + +class Db; +class Table; +class FieldMeta; + +class FilterField +{ +public: + FilterField() = default; + + FilterField(Table *table, FieldMeta *field) : table_(table), field_(field) + {} + + Table *table() const { + return table_; + } + + const FieldMeta *field() const { + return field_; + } + + void set_table(Table *table) { + table_ = table; + } + void set_field(const FieldMeta *field) { + field_ = field; + } +private: + Table *table_ = nullptr; + const FieldMeta *field_ = nullptr; +}; + +class FilterItem +{ +public: + FilterItem() = default; + + void set_field(Table *table, const FieldMeta *field) { + is_attr_ = true; + field_.set_table(table); + field_.set_field(field); + } + + void set_value(const Value &value) { + is_attr_ = false; + value_ = value; + } + + bool is_attr() const { + return is_attr_; + } + + const FilterField &field() const { + return field_; + } + + const Value &value() const { + return value_; + } + +private: + bool is_attr_ = false; // is an attribute or a value + FilterField field_; + Value value_; +}; + +class FilterUnit +{ +public: + FilterUnit() = default; + + void set_comp(CompOp comp) { + comp_ = comp; + } + FilterItem &left() { + return left_; + } + FilterItem &right() { + return right_; + } + const FilterItem &left() const { + return left_; + } + const FilterItem &right() const { + return right_; + } +private: + CompOp comp_; + FilterItem left_; + FilterItem right_; +}; + +class FilterStmt +{ +public: + + FilterStmt() = default; + +public: + const std::vector &filter_units() const + { + return filter_units_; + } + +public: + static RC create(Db *db, Table *default_table, + const Condition *conditions, int condition_num, + FilterStmt *&stmt); + + static RC create_filter_unit(Db *db, Table *default_table, const Condition &condition, FilterUnit &filter_unit); + +private: + std::vector filter_units_; // 默认当前都是AND关系 +}; diff --git a/src/observer/sql/stmt/insert_stmt.cpp b/src/observer/sql/stmt/insert_stmt.cpp new file mode 100644 index 0000000..32ff3f9 --- /dev/null +++ b/src/observer/sql/stmt/insert_stmt.cpp @@ -0,0 +1,65 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/22. +// + +#include "sql/stmt/insert_stmt.h" +#include "common/log/log.h" +#include "storage/common/db.h" +#include "storage/common/table.h" + +InsertStmt::InsertStmt(Table *table, const Value *values, int value_amount) + : table_ (table), values_(values), value_amount_(value_amount) +{} + +RC InsertStmt::create(Db *db, const Inserts &inserts, Stmt *&stmt) +{ + const char *table_name = inserts.relation_name; + if (nullptr == db || nullptr == table_name || inserts.value_num <= 0) { + LOG_WARN("invalid argument. db=%p, table_name=%p, value_num=%d", + db, table_name, inserts.value_num); + return RC::INVALID_ARGUMENT; + } + + // check whether the table exists + Table *table = db->find_table(table_name); + if (nullptr == table) { + LOG_WARN("no such table. db=%s, table_name=%s", db->name(), table_name); + return RC::SCHEMA_TABLE_NOT_EXIST; + } + + // check the fields number + const Value *values = inserts.values; + const int value_num = inserts.value_num; + const TableMeta &table_meta = table->table_meta(); + const int field_num = table_meta.field_num() - table_meta.sys_field_num(); + if (field_num != value_num) { + LOG_WARN("schema mismatch. value num=%d, field num in schema=%d", value_num, field_num); + return RC::SCHEMA_FIELD_MISSING; + } + + // check fields type + for (int i = table_meta.sys_field_num(); i < table_meta.field_num(); i++) { + const FieldMeta *field_meta = table_meta.field(i); + const AttrType field_type = field_meta->type(); + const AttrType value_type = values[i].type; + if (field_type != value_type) { // TODO try to convert the value type to field type + LOG_WARN("field type mismatch. table=%s, field=%s, field type=%d, value_type=%d", + table_name, field_meta->name(), field_type, value_type); + return RC::SCHEMA_FIELD_TYPE_MISMATCH; + } + } + + // everything alright + stmt = new InsertStmt(table, values, value_num); + return RC::SUCCESS; +} diff --git a/src/observer/sql/stmt/insert_stmt.h b/src/observer/sql/stmt/insert_stmt.h new file mode 100644 index 0000000..70fcf78 --- /dev/null +++ b/src/observer/sql/stmt/insert_stmt.h @@ -0,0 +1,46 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/22. +// + +#pragma once + +#include "rc.h" +#include "sql/stmt/stmt.h" + +class Table; +class Db; + +class InsertStmt : public Stmt +{ +public: + + InsertStmt() = default; + InsertStmt(Table *table, const Value *values, int value_amount); + + StmtType type() const override { + return StmtType::INSERT; + } +public: + static RC create(Db *db, const Inserts &insert_sql, Stmt *&stmt); + +public: + Table *table() const {return table_;} + const Value *values() const { return values_; } + int value_amount() const { return value_amount_; } + +private: + Table *table_ = nullptr; + const Value *values_ = nullptr; + int value_amount_ = 0; +}; + diff --git a/src/observer/sql/stmt/select_stmt.cpp b/src/observer/sql/stmt/select_stmt.cpp new file mode 100644 index 0000000..c0f8daf --- /dev/null +++ b/src/observer/sql/stmt/select_stmt.cpp @@ -0,0 +1,165 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/6/6. +// + +#include "sql/stmt/select_stmt.h" +#include "sql/stmt/filter_stmt.h" +#include "common/log/log.h" +#include "common/lang/string.h" +#include "storage/common/db.h" +#include "storage/common/table.h" + +SelectStmt::~SelectStmt() +{ + if (nullptr != filter_stmt_) { + delete filter_stmt_; + filter_stmt_ = nullptr; + } +} + +static void wildcard_fields(Table *table, std::vector &field_metas) +{ + const TableMeta &table_meta = table->table_meta(); + const int field_num = table_meta.field_num(); + for (int i = table_meta.sys_field_num(); i < field_num; i++) { + field_metas.push_back(FieldDesc(table, table_meta.field(i))); + } +} + +RC SelectStmt::create(Db *db, const Selects &select_sql, Stmt *&stmt) +{ + if (nullptr == db) { + LOG_WARN("invalid argument. db is null"); + return RC::INVALID_ARGUMENT; + } + + std::vector tables; + std::map table_map; + for (int i = 0; i < select_sql.relation_num; i++) { + const char *table_name = select_sql.relations[i]; + if (nullptr == table_name) { + LOG_WARN("invalid argument. relation name is null. index=%d", i); + return RC::INVALID_ARGUMENT; + } + + Table *table = db->find_table(table_name); + if (nullptr == table) { + LOG_WARN("no such table. db=%s, table_name=%s", db->name(), table_name); + return RC::SCHEMA_TABLE_NOT_EXIST; + } + + tables.push_back(table); + table_map.insert(std::pair(table_name, table)); + } + + std::vector query_fields; + for (int i = 0; i < select_sql.attr_num; i++) { + const RelAttr &relation_attr = select_sql.attributes[i]; + + if (common::is_blank(relation_attr.relation_name) && 0 == strcmp(relation_attr.attribute_name, "*")) { + for (Table *table : tables) { + wildcard_fields(table, query_fields); + } + + } else if (!common::is_blank(relation_attr.relation_name)) { // TODO + const char *table_name = relation_attr.relation_name; + const char *field_name = relation_attr.attribute_name; + + if (0 == strcmp(table_name, "*")) { + if (0 != strcmp(field_name, "*")) { + LOG_WARN("invalid field name while table is *. attr=%s", field_name); + return RC::SCHEMA_FIELD_MISSING; + } + for (Table *table : tables) { + wildcard_fields(table, query_fields); + } + } else { + auto iter = table_map.find(table_name); + if (iter == table_map.end()) { + LOG_WARN("no such table in from list: %s", table_name); + return RC::SCHEMA_FIELD_MISSING; + } + + Table *table = iter->second; + if (field_name == "*") { + wildcard_fields(table, query_fields); + } else { + const FieldMeta *field_meta = table->table_meta().field(field_name); + if (nullptr == field_meta) { + LOG_WARN("no such field. field=%s.%s.%s", db->name(), table->name(), field_name); + return RC::SCHEMA_FIELD_MISSING; + } + + query_fields.push_back(FieldDesc(table, field_meta)); + } + } + } else { + if (tables.size() != 1) { + LOG_WARN("invalid. I do not know the attr's table. attr=%s", relation_attr.attribute_name); + return RC::SCHEMA_FIELD_MISSING; + } + + Table *table = tables[0]; + const FieldMeta *field_meta = table->table_meta().field(relation_attr.attribute_name); + if (nullptr == field_meta) { + LOG_WARN("no such field. field=%s.%s.%s", db->name(), table->name(), relation_attr.attribute_name); + return RC::SCHEMA_FIELD_MISSING; + } + + query_fields.push_back(FieldDesc(table, field_meta)); + } + } + + LOG_INFO("got %d tables in from stmt and %d fields in query stmt", tables.size(), query_fields.size()); + + Table *default_table = nullptr; + if (tables.size() == 1) { + default_table = tables[0]; + } + + FilterStmt *filter_stmt = nullptr; + RC rc = FilterStmt::create(db, default_table, select_sql.conditions, select_sql.condition_num, filter_stmt); + if (rc != RC::SUCCESS) { + LOG_WARN("cannot construct filter stmt"); + return rc; + } + + // make sure all tables in predicate are exists in from stmt + const std::vector &filter_units = filter_stmt->filter_units(); + for (const FilterUnit &filter_unit : filter_units) { + const FilterItem &left = filter_unit.left(); + const FilterItem &right = filter_unit.right(); + if (left.is_attr()) { + Table *table = left.field().table(); + if (table_map.find(table->name()) == table_map.end()) { + LOG_WARN("the table in predicate is not in from stmt: %s", table->name()); + return RC::SCHEMA_TABLE_NOT_EXIST; + } + } + if (right.is_attr()) { + Table *table = right.field().table(); + if (table_map.find(table->name()) == table_map.end()) { + LOG_WARN("the table in predicate is not in from stmt: %s", table->name()); + return RC::SCHEMA_TABLE_NOT_EXIST; + } + } + } + + // everything alright + SelectStmt *select_stmt = new SelectStmt(); + select_stmt->tables_.swap(tables); + select_stmt->query_fields_.swap(query_fields); + select_stmt->filter_stmt_ = filter_stmt; + stmt = select_stmt; + return RC::SUCCESS; +} diff --git a/src/observer/sql/stmt/select_stmt.h b/src/observer/sql/stmt/select_stmt.h new file mode 100644 index 0000000..df4f91f --- /dev/null +++ b/src/observer/sql/stmt/select_stmt.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/6/5. +// + +#pragma once + +#include + +#include "rc.h" +#include "sql/stmt/stmt.h" + +class FieldMeta; +class FilterStmt; +class Db; +class Table; + +// better to create a field class +struct FieldDesc +{ + Table *table_ = nullptr; + const FieldMeta *field_meta_ = nullptr; + + FieldDesc() = default; + FieldDesc(Table *table, const FieldMeta *field_meta) : table_(table), field_meta_(field_meta) {} +}; + +class SelectStmt : public Stmt +{ +public: + + SelectStmt() = default; + ~SelectStmt() override; + + StmtType type() const override { return StmtType::SELECT; } +public: + static RC create(Db *db, const Selects &select_sql, Stmt *&stmt); + +public: + const std::vector
&tables() const { return tables_; } + FilterStmt *filter_stmt() const { return filter_stmt_; } + +private: + std::vector query_fields_; + std::vector
tables_; + FilterStmt *filter_stmt_ = nullptr; +}; + diff --git a/src/observer/sql/stmt/stmt.cpp b/src/observer/sql/stmt/stmt.cpp new file mode 100644 index 0000000..81185c1 --- /dev/null +++ b/src/observer/sql/stmt/stmt.cpp @@ -0,0 +1,44 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/22. +// + +#include "rc.h" +#include "common/log/log.h" +#include "sql/stmt/insert_stmt.h" +#include "sql/stmt/delete_stmt.h" +#include "sql/stmt/select_stmt.h" + +RC Stmt::create_stmt(Db *db, const Query &query, Stmt *&stmt) +{ + stmt = nullptr; + + switch (query.flag) { + case SCF_INSERT: { + return InsertStmt::create(db, query.sstr.insertion, stmt); + } + break; + case SCF_DELETE: { + return DeleteStmt::create(db, query.sstr.deletion, stmt); + } + case SCF_SELECT: { + return SelectStmt::create(db, query.sstr.selection, stmt); + } + default: { + LOG_WARN("unknown query command"); + } + break; + } + return RC::UNIMPLENMENT; +} + + diff --git a/src/observer/sql/stmt/stmt.h b/src/observer/sql/stmt/stmt.h new file mode 100644 index 0000000..67020a2 --- /dev/null +++ b/src/observer/sql/stmt/stmt.h @@ -0,0 +1,59 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/22. +// + +#pragma once + +#include "rc.h" +#include "sql/parser/parse_defs.h" + +class Db; + +enum class StmtType +{ + SELECT, + INSERT, + UPDATE, + DELETE, + CREATE_TABLE, + DROP_TABLE, + CREATE_INDEX, + DROP_INDEX, + SYNC, + SHOW_TABLES, + DESC_TABLE, + BEGIN, + COMMIT, + ROLLBACK, + LOAD_DATA, + HELP, + EXIT, + + PREDICATE, +}; + +class Stmt +{ +public: + + Stmt() = default; + virtual ~Stmt() = default; + + virtual StmtType type() const = 0; + +public: + static RC create_stmt(Db *db, const Query &query, Stmt *&stmt); + +private: +}; + diff --git a/src/observer/sql/stmt/update_stmt.cpp b/src/observer/sql/stmt/update_stmt.cpp new file mode 100644 index 0000000..a0cf4bf --- /dev/null +++ b/src/observer/sql/stmt/update_stmt.cpp @@ -0,0 +1,65 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/22. +// + +#include "sql/stmt/update_stmt.h" + +UpdateStmt::UpdateStmt(Table *table, Value *values, int value_amount) + : table_ (table), values_(values), value_amount_(value_amount) +{} + +RC UpdateStmt::create(Db *db, const Updates &update, Stmt *&stmt) +{ + // TODO + #if 0 + const char *table_name = update.relation_name; + if (nullptr == db || nullptr == table_name || update.value_num <= 0) { + LOG_WARN("invalid argument. db=%p, table_name=%p, value_num=%d", + db, table_name, inserts.value_num); + return RC::INVALID_ARGUMENT; + } + + // check whether the table exists + Table *table = db->find_table(table_name); + if (nullptr == table) { + LOG_WARN("no such table. db=%s, table_name=%s", db->name(), table_name); + return RC::SCHEMA_TABLE_NOT_EXIST; + } + + // check the fields number + const Value *values = inserts.values; + const int value_num = inserts.value_num; + const TableMeta &table_meta = table->table_meta(); + const int field_num = table_meta.field_num() - table_meta.sys_field_num(); + if (field_num != value_num) { + LOG_WARN("schema mismatch. value num=%d, field num in schema=%d", value_num, field_num); + return RC::SCHEMA_FIELD_MISSING; + } + + // check fields type + for (int i = table_meta.sys_field_num(); i < table_meta.field_num(); i++) { + const FieldMeta *field_meta = table_meta.field(i); + const AttrType field_type = field_meta->type(); + const AttrType value_type = values[i].type; + if (field_type != value_type) { // TODO try to convert the value type to field type + LOG_WARN("field type mismatch. table=%s, field=%s, field type=%d, value_type=%d", + table_name, field_meta->name(), field_type, value_type); + return RC::SCHEMA_FIELD_TYPE_MISMATCH; + } + } + + // everything alright + stmt = new InsertStmt(table, values, value_num); + #endif + return RC::INTERNAL; +} diff --git a/src/observer/sql/stmt/update_stmt.h b/src/observer/sql/stmt/update_stmt.h new file mode 100644 index 0000000..ca56661 --- /dev/null +++ b/src/observer/sql/stmt/update_stmt.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/22. +// + +#pragma once + +#include "rc.h" +#include "sql/stmt/stmt.h" + +class Table; + +class UpdateStmt : public Stmt +{ +public: + + UpdateStmt() = default; + UpdateStmt(Table *table, Value *values, int value_amount); + +public: + static RC create(Db *db, const Updates &update_sql, Stmt *&stmt); + +public: + Table *table() const {return table_;} + Value *values() const { return values_; } + int value_amount() const { return value_amount_; } + +private: + Table *table_ = nullptr; + Value *values_ = nullptr; + int value_amount_ = 0; +}; + diff --git a/src/observer/storage/common/record.h b/src/observer/storage/common/record.h new file mode 100644 index 0000000..3eccdff --- /dev/null +++ b/src/observer/storage/common/record.h @@ -0,0 +1,49 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/4. +// + +#pragma once + +#include +#include + +#include "rc.h" +#include "storage/common/index_meta.h" +#include "storage/common/field_meta.h" +#include "storage/common/record_manager.h" + +class Record +{ +public: + Record() = default; + ~Record() = default; + + void set_data(char *data); + char *data(); + const char *data() const; + + void set_rid(const RID &rid); + RID & rid(); + const RID &rid() const; + + RC set_field_value(const Value &value, int index); + RC set_field_values(const Value *values, int value_num, int start_index); + +private: + std::vector * fields_ = nullptr; + RID rid_; + + // the data buffer + // record will not release the memory + char * data_ = nullptr; +}; diff --git a/src/observer/storage/common/table.cpp b/src/observer/storage/common/table.cpp index e4a3936..292aa0f 100644 --- a/src/observer/storage/common/table.cpp +++ b/src/observer/storage/common/table.cpp @@ -357,6 +357,15 @@ RC Table::init_record_handler(const char *base_dir) return rc; } +RC Table::get_record_scanner(RecordFileScanner &scanner) +{ + RC rc = scanner.open_scan(*data_buffer_pool_, nullptr); + if (rc != RC::SUCCESS) { + LOG_ERROR("failed to open scanner. rc=%d:%s", rc, strrc(rc)); + } + return rc; +} + /** * 为了不把Record暴露出去,封装一下 */ diff --git a/src/observer/storage/common/table.h b/src/observer/storage/common/table.h index c0cfb0e..1b18035 100644 --- a/src/observer/storage/common/table.h +++ b/src/observer/storage/common/table.h @@ -17,12 +17,13 @@ See the Mulan PSL v2 for more details. */ #include "storage/common/table_meta.h" +struct Record; +struct RID; class DiskBufferPool; class RecordFileHandler; +class RecordFileScanner; class ConditionFilter; class DefaultConditionFilter; -struct Record; -struct RID; class Index; class IndexScanner; class RecordDeleter; @@ -60,6 +61,8 @@ public: RC create_index(Trx *trx, const char *index_name, const char *attribute_name); + RC get_record_scanner(RecordFileScanner &scanner); + public: const char *name() const; diff --git a/src/observer/storage/common/table_meta.h b/src/observer/storage/common/table_meta.h index 2a2de6d..7326982 100644 --- a/src/observer/storage/common/table_meta.h +++ b/src/observer/storage/common/table_meta.h @@ -42,7 +42,7 @@ public: const FieldMeta *field(int index) const; const FieldMeta *field(const char *name) const; const FieldMeta *find_field_by_offset(int offset) const; - int field_num() const; + int field_num() const; // sys field included int sys_field_num() const; const IndexMeta *index(const char *name) const; @@ -73,4 +73,4 @@ protected: static std::vector sys_fields_; }; -#endif // __OBSERVER_STORAGE_COMMON_TABLE_META_H__ \ No newline at end of file +#endif // __OBSERVER_STORAGE_COMMON_TABLE_META_H__ diff --git a/src/observer/storage/default/default_handler.h b/src/observer/storage/default/default_handler.h index e4fb243..4378a1d 100644 --- a/src/observer/storage/default/default_handler.h +++ b/src/observer/storage/default/default_handler.h @@ -97,9 +97,6 @@ public: * 否则,创建该索引。 * 创建索引的工作包括:①创建并打开索引文件; * ②逐个扫描被索引的记录,并向索引文件中插入索引项;③关闭索引 - * @param indexName - * @param relName - * @param attrName * @return */ RC create_index( @@ -118,9 +115,6 @@ public: * nValues为属性值个数,values为对应的属性值数组。 * 函数根据给定的属性值构建元组,调用记录管理模块的函数插入该元组, * 然后在该表的每个索引中为该元组创建合适的索引项 - * @param relName - * @param nValues - * @param values * @return */ RC insert_record(Trx *trx, const char *dbname, const char *relation_name, int value_num, const Value *values); @@ -142,11 +136,6 @@ public: * 在每一个更新的元组中将属性attrName的值设置为一个新的值。 * 如果没有指定条件,则此方法更新relName中所有元组。 * 如果要更新一个被索引的属性,应当先删除每个被更新元组对应的索引条目,然后插入一个新的索引条目 - * @param relName - * @param attrName - * @param value - * @param nConditions - * @param conditions * @return */ RC update_record(Trx *trx, const char *dbname, const char *relation_name, const char *attribute_name, diff --git a/src/observer/storage/default/default_storage_stage.cpp b/src/observer/storage/default/default_storage_stage.cpp index 539ea10..5fb9413 100644 --- a/src/observer/storage/default/default_storage_stage.cpp +++ b/src/observer/storage/default/default_storage_stage.cpp @@ -29,7 +29,6 @@ See the Mulan PSL v2 for more details. */ #include "storage/common/table.h" #include "storage/common/table_meta.h" #include "storage/trx/trx.h" -#include "event/execution_plan_event.h" #include "event/session_event.h" #include "event/sql_event.h" #include "event/storage_event.h" @@ -143,21 +142,15 @@ void DefaultStorageStage::handle_event(StageEvent *event) LOG_TRACE("Enter\n"); TimerStat timerStat(*query_metric_); - StorageEvent *storage_event = static_cast(event); - CompletionCallback *cb = new (std::nothrow) CompletionCallback(this, nullptr); - if (cb == nullptr) { - LOG_ERROR("Failed to new callback for SessionEvent"); - storage_event->done_immediate(); - return; - } - storage_event->push_callback(cb); + SQLStageEvent *sql_event = static_cast(event); - Query *sql = storage_event->exe_event()->sqls(); + Query *sql = sql_event->query(); - SessionEvent *session_event = storage_event->exe_event()->sql_event()->session_event(); + SessionEvent *session_event = sql_event->session_event(); Session *session = session_event->get_client()->session; - const char *current_db = session->get_current_db().c_str(); + Db *db = session->get_current_db(); + const char *dbname = db->name(); Trx *current_trx = session->current_trx(); @@ -168,7 +161,7 @@ void DefaultStorageStage::handle_event(StageEvent *event) case SCF_INSERT: { // insert into const Inserts &inserts = sql->sstr.insertion; const char *table_name = inserts.relation_name; - rc = handler_->insert_record(current_trx, current_db, table_name, inserts.value_num, inserts.values); + //rc = handler_->insert_record(current_trx, current_db, table_name, inserts.value_num, inserts.values); snprintf(response, sizeof(response), "%s\n", rc == RC::SUCCESS ? "SUCCESS" : "FAILURE"); } break; case SCF_UPDATE: { @@ -176,6 +169,7 @@ void DefaultStorageStage::handle_event(StageEvent *event) const char *table_name = updates.relation_name; const char *field_name = updates.attribute_name; int updated_count = 0; + #if 0 rc = handler_->update_record(current_trx, current_db, table_name, @@ -184,58 +178,19 @@ void DefaultStorageStage::handle_event(StageEvent *event) updates.condition_num, updates.conditions, &updated_count); + #endif snprintf(response, sizeof(response), "%s\n", rc == RC::SUCCESS ? "SUCCESS" : "FAILURE"); } break; case SCF_DELETE: { const Deletes &deletes = sql->sstr.deletion; const char *table_name = deletes.relation_name; int deleted_count = 0; + #if 0 rc = handler_->delete_record( current_trx, current_db, table_name, deletes.condition_num, deletes.conditions, &deleted_count); + #endif snprintf(response, sizeof(response), "%s\n", rc == RC::SUCCESS ? "SUCCESS" : "FAILURE"); } break; - case SCF_CREATE_TABLE: { // create table - const CreateTable &create_table = sql->sstr.create_table; - rc = handler_->create_table( - current_db, create_table.relation_name, create_table.attribute_count, create_table.attributes); - snprintf(response, sizeof(response), "%s\n", rc == RC::SUCCESS ? "SUCCESS" : "FAILURE"); - } break; - case SCF_CREATE_INDEX: { - const CreateIndex &create_index = sql->sstr.create_index; - rc = handler_->create_index( - current_trx, current_db, create_index.relation_name, create_index.index_name, create_index.attribute_name); - snprintf(response, sizeof(response), "%s\n", rc == RC::SUCCESS ? "SUCCESS" : "FAILURE"); - } break; - - case SCF_SHOW_TABLES: { - Db *db = handler_->find_db(current_db); - if (nullptr == db) { - snprintf(response, sizeof(response), "No such database: %s\n", current_db); - } else { - std::vector all_tables; - db->all_tables(all_tables); - if (all_tables.empty()) { - snprintf(response, sizeof(response), "No table\n"); - } else { - std::stringstream ss; - for (const auto &table : all_tables) { - ss << table << std::endl; - } - snprintf(response, sizeof(response), "%s\n", ss.str().c_str()); - } - } - } break; - case SCF_DESC_TABLE: { - const char *table_name = sql->sstr.desc_table.relation_name; - Table *table = handler_->find_table(current_db, table_name); - std::stringstream ss; - if (table != nullptr) { - table->table_meta().desc(ss); - } else { - ss << "No such table: " << table_name << std::endl; - } - snprintf(response, sizeof(response), "%s", ss.str().c_str()); - } break; case SCF_LOAD_DATA: { /* @@ -244,7 +199,7 @@ void DefaultStorageStage::handle_event(StageEvent *event) */ const char *table_name = sql->sstr.load_data.relation_name; const char *file_name = sql->sstr.load_data.file_name; - std::string result = load_data(current_db, table_name, file_name); + std::string result = load_data(dbname, table_name, file_name); snprintf(response, sizeof(response), "%s", result.c_str()); } break; default: @@ -269,7 +224,7 @@ void DefaultStorageStage::callback_event(StageEvent *event, CallbackContext *con { LOG_TRACE("Enter\n"); StorageEvent *storage_event = static_cast(event); - storage_event->exe_event()->done_immediate(); + storage_event->sql_event()->done_immediate(); LOG_TRACE("Exit\n"); return; } @@ -411,4 +366,4 @@ std::string DefaultStorageStage::load_data(const char *db_name, const char *tabl << " record(s) loaded, total cost " << cost_nano / 1000000000.0 << " second(s)" << std::endl; } return result_string.str(); -} \ No newline at end of file +} diff --git a/src/observer/storage/row/row.h b/src/observer/storage/row/row.h new file mode 100644 index 0000000..6898c06 --- /dev/null +++ b/src/observer/storage/row/row.h @@ -0,0 +1,42 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2022/5/3. +// + +#ifndef __OBSERVER_STORAGE_ROW_ROW_H_ +#define __OBSERVER_STORAGE_ROW_ROW_H_ + +#include +#include + +#include "rc.h" +#include "storage/common/index_meta.h" +#include "storage/common/field_meta.h" +#include "storage/common/record_manager.h" + +class Row { + +public: + Row() = default; + ~Row() = default; + + RC init(const FieldMeta *fields_, int num); + + RC set_projector(); + +private: + std::vector fields_; + std::vector projector_; + char *data_; +}; + +#endif // __OBSERVER_STORAGE_ROW_ROW_H_ diff --git a/src/observer/util/comparator.cpp b/src/observer/util/comparator.cpp new file mode 100644 index 0000000..f7e6a8e --- /dev/null +++ b/src/observer/util/comparator.cpp @@ -0,0 +1,45 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2021/6/11. +// + +#include + +const double epsilon = 1E-6; + +int compare_int(void *arg1, void *arg2) +{ + int v1 = *(int *)arg1; + int v2 = *(int *)arg2; + return v1 - v2; +} + +int compare_float(void *arg1, void *arg2) +{ + float v1 = *(float *)arg1; + float v2 = *(float *)arg2; + float cmp = v1 - v2; + if (cmp > epsilon) { + return 1; + } + if (cmp < -epsilon) { + return -1; + } + return 0; +} + +int compare_string(void *arg1, void *arg2, int maxlen) +{ + const char *s1 = (const char *)arg1; + const char *s2 = (const char *)arg2; + return strncmp(s1, s2, maxlen); +} diff --git a/src/observer/util/comparator.h b/src/observer/util/comparator.h new file mode 100644 index 0000000..5451583 --- /dev/null +++ b/src/observer/util/comparator.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and 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 2021/6/11 +// + +#pragma once + +int compare_int(void *arg1, void *arg2); +int compare_float(void *arg1, void *arg2); +int compare_string(void *arg1, void *arg2); -- GitLab