From bc7919c30996fc17461e503e075e7374dbd0fcfb Mon Sep 17 00:00:00 2001 From: wangyunlai Date: Fri, 30 Jun 2023 09:47:33 +0800 Subject: [PATCH] Train debug (#203) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### What problem were solved in this pull request? Problem: 与训练营配合,可以在SQL命令请求过程中,添加调试信息 ### What is changed and how it works? 可以参考 debug-output.md 文档。 增加 sql_debug 变量,使用set sql_debug=1; 可以设置。 在SQL命令执行过程中,调用sql_debug函数,增加调试信息。在普通文本通讯协议中,调试信息会以 '#' 开头的形式打印出来。但是注意调试信息中不要带换行符。 ### Other information --- .vscode/launch.json | 2 +- build.sh | 26 +- deps/common/log/log.h | 18 +- docs/src/design/miniob-transaction.md | 2 +- docs/src/game/debug-output.md | 40 ++ docs/src/game/introduction.md | 3 + src/observer/common/ini_setting.h | 2 +- src/observer/common/rc.h | 2 + src/observer/event/optimize_event.h | 43 -- src/observer/event/session_event.h | 31 +- src/observer/event/sql_debug.cpp | 64 ++ src/observer/event/sql_debug.h | 48 ++ src/observer/event/sql_event.h | 11 +- src/observer/net/mysql_communicator.cpp | 4 +- src/observer/net/plain_communicator.cpp | 69 ++- src/observer/net/plain_communicator.h | 3 + src/observer/session/session.cpp | 10 + src/observer/session/session.h | 52 +- src/observer/session/session_stage.cpp | 2 + .../sql/executor/command_executor.cpp | 6 + .../sql/executor/desc_table_executor.cpp | 3 +- src/observer/sql/executor/execute_stage.h | 2 +- .../sql/executor/set_variable_executor.h | 106 ++++ src/observer/sql/executor/sql_result.h | 3 +- src/observer/sql/expr/tuple.h | 96 ++- .../operator/table_scan_physical_operator.cpp | 3 + .../comparison_simplification_rule.h | 6 + .../conjunction_simplification_rule.h | 5 +- .../sql/optimizer/physical_plan_generator.h | 9 +- .../optimizer/predicate_pushdown_rewriter.h | 5 +- .../sql/optimizer/predicate_rewrite.h | 5 + src/observer/sql/optimizer/rewrite_rule.h | 8 + src/observer/sql/optimizer/rewriter.h | 18 + src/observer/sql/parser/parse_defs.h | 12 +- src/observer/sql/parser/value.cpp | 8 +- src/observer/sql/parser/value.h | 4 +- src/observer/sql/parser/yacc_sql.cpp | 552 +++++++++--------- src/observer/sql/parser/yacc_sql.y | 13 + src/observer/sql/stmt/create_table_stmt.cpp | 2 + src/observer/sql/stmt/set_variable_stmt.h | 47 ++ src/observer/sql/stmt/stmt.cpp | 5 + src/observer/sql/stmt/stmt.h | 3 +- src/observer/storage/field/field.h | 4 + src/observer/storage/field/field_meta.h | 5 +- src/observer/storage/index/bplus_tree.h | 24 +- src/observer/storage/table/table.h | 5 +- src/observer/storage/table/table_meta.h | 4 + src/observer/storage/trx/mvcc_trx.h | 3 +- 48 files changed, 973 insertions(+), 425 deletions(-) create mode 100644 docs/src/game/debug-output.md delete mode 100644 src/observer/event/optimize_event.h create mode 100644 src/observer/event/sql_debug.cpp create mode 100644 src/observer/event/sql_debug.h create mode 100644 src/observer/sql/executor/set_variable_executor.h create mode 100644 src/observer/sql/stmt/set_variable_stmt.h diff --git a/.vscode/launch.json b/.vscode/launch.json index eadaf1d..f38eeae 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,7 @@ "request": "launch", "name": "Debug", "program": "${workspaceFolder}/${defaultBuildTask}/bin/observer", - "args": ["-f", "${workspaceFolder}/etc/observer.ini", "-s", "miniob.sock"], + "args": ["-f", "${workspaceFolder}/etc/observer.ini", "-P", "cli"], "cwd": "${workspaceFolder}/${defaultBuildTask}/" } ] diff --git a/build.sh b/build.sh index bb436b5..463458a 100755 --- a/build.sh +++ b/build.sh @@ -5,7 +5,7 @@ TOPDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) BUILD_SH=$TOPDIR/build.sh -CMAKE_COMMAND="cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1" +CMAKE_COMMAND="cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 --log-level=WARNING" ALL_ARGS=("$@") BUILD_ARGS=() @@ -73,38 +73,40 @@ function do_init git submodule update --init || return current_dir=$PWD + MAKE_COMMAND="make --silent" + # build libevent cd ${TOPDIR}/deps/3rd/libevent && \ git checkout release-2.1.12-stable && \ mkdir -p build && \ cd build && \ - cmake .. -DEVENT__DISABLE_OPENSSL=ON -DEVENT__LIBRARY_TYPE=BOTH && \ - make -j4 && \ + ${CMAKE_COMMAND} .. -DEVENT__DISABLE_OPENSSL=ON -DEVENT__LIBRARY_TYPE=BOTH && \ + ${MAKE_COMMAND} -j4 && \ make install # build googletest cd ${TOPDIR}/deps/3rd/googletest && \ mkdir -p build && \ cd build && \ - cmake .. && \ - make -j4 && \ - make install + ${CMAKE_COMMAND} .. && \ + ${MAKE_COMMAND} -j4 && \ + ${MAKE_COMMAND} install # build google benchmark cd ${TOPDIR}/deps/3rd/benchmark && \ mkdir -p build && \ cd build && \ - cmake .. -DBENCHMARK_ENABLE_TESTING=OFF -DBENCHMARK_INSTALL_DOCS=OFF -DBENCHMARK_ENABLE_GTEST_TESTS=OFF -DBENCHMARK_USE_BUNDLED_GTEST=OFF -DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF && \ - make -j4 && \ - make install + ${CMAKE_COMMAND} .. -DBENCHMARK_ENABLE_TESTING=OFF -DBENCHMARK_INSTALL_DOCS=OFF -DBENCHMARK_ENABLE_GTEST_TESTS=OFF -DBENCHMARK_USE_BUNDLED_GTEST=OFF -DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF && \ + ${MAKE_COMMAND} -j4 && \ + ${MAKE_COMMAND} install # build jsoncpp cd ${TOPDIR}/deps/3rd/jsoncpp && \ mkdir -p build && \ cd build && \ - cmake -DJSONCPP_WITH_TESTS=OFF -DJSONCPP_WITH_POST_BUILD_UNITTEST=OFF .. && \ - make && \ - make install + ${CMAKE_COMMAND} -DJSONCPP_WITH_TESTS=OFF -DJSONCPP_WITH_POST_BUILD_UNITTEST=OFF .. && \ + ${MAKE_COMMAND} && \ + ${MAKE_COMMAND} install cd $current_dir } diff --git a/deps/common/log/log.h b/deps/common/log/log.h index 173669f..1ee25df 100644 --- a/deps/common/log/log.h +++ b/deps/common/log/log.h @@ -25,15 +25,13 @@ See the Mulan PSL v2 for more details. */ #include #include #include -#include +#include #include "common/defs.h" namespace common { const unsigned int ONE_KILO = 1024; -const unsigned int ONE_MILLION = ONE_KILO * ONE_KILO; -const unsigned int ONE_GIGA = ONE_MILLION * ONE_KILO; const unsigned int FILENAME_LENGTH_MAX = 256; // the max filename length const int LOG_STATUS_OK = 0; @@ -111,6 +109,11 @@ public: int rotate(const int year = 0, const int month = 0, const int day = 0); + /** + * @brief 设置一个在日志中打印当前上下文信息的回调函数 + * @details 比如设置一个获取当前session标识的函数,那么每次在打印日志时都会输出session信息。 + * 这个回调函数返回了一个intptr_t类型的数据,可能返回字符串更好,但是现在够用了。 + */ void set_context_getter(std::function context_getter); intptr_t context_id(); @@ -328,13 +331,4 @@ int Log::out(const LOG_LEVEL console_level, const LOG_LEVEL log_level, T &msg) */ const char *lbt(); -/** - * @brief 设置一个在日志中打印当前上下文信息的回调函数 - * @details 比如设置一个获取当前session标识的函数,那么每次在打印日志时都会输出session信息。 - * 这个回调函数返回了一个intptr_t类型的数据,可能返回字符串更好,但是现在够用了。 - */ -void set_log_context_getter(std::function context_getter); - -extern std::function g_context_getter; - } // namespace common diff --git a/docs/src/design/miniob-transaction.md b/docs/src/design/miniob-transaction.md index bbc8c40..3ac4673 100644 --- a/docs/src/design/miniob-transaction.md +++ b/docs/src/design/miniob-transaction.md @@ -1,7 +1,7 @@ 本篇文档介绍 MiniOB 中的事务模块是如何工作的。 # 背景 -事务是数据库中非常基础的一个模块,也是非常核心的功能。事务有一些基本的概念,叫做ACID,分别是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。如果你对事务的基本概念不太清楚,建议先学习了解事务的基本概念,比如学习[事务处理](lectures/lecture-6.md)章节,或者在网上搜索更多资料。 +事务是数据库中非常基础的一个模块,也是非常核心的功能。事务有一些基本的概念,叫做ACID,分别是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。如果你对事务的基本概念不太清楚,建议先学习了解事务的基本概念,比如学习[事务处理](../lectures/lecture-6.md)章节,或者在网上搜索更多资料。 # MiniOB 中的事务 ## 实现简介 diff --git a/docs/src/game/debug-output.md b/docs/src/game/debug-output.md new file mode 100644 index 0000000..4bcfa3d --- /dev/null +++ b/docs/src/game/debug-output.md @@ -0,0 +1,40 @@ +本篇文档介绍如何向[训练营](https://open.oceanbase.com/train)输出调试信息。 + +在使用训练营提交测试时,有时候会遇到本地环境没有问题,但是训练营上的输出总是不符合预期。但是训练营没有办法调试,这时候就需要在训练营上输出调试信息,以便于定位问题。 + +**如何输出调试信息** + +可以参考文件 `sql_debug.h`,在需要输出调试信息的地方,调用`sql_debug`函数即可。sql_debug 的使用与打印日志类似,不过可以在向客户端输出正常结果后,再输出调试信息。 +执行`sql_debug`同时会在日志中打印DEBUG级别的日志。 + +**示例** + +1. `CreateTableStmt::create` +2. `TableScanPhysicalOperator::next` + +**注意** +由于训练营上能够容纳的信息有限,所以输出太多信息会被截断。 + +**开关** + +每个连接都可以开启或关闭调试,可以参考 `Session::sql_debug_`。 + +在交互式命令行中,可以使用 `set sql_debug=1` 开启调试,使用 `set sql_debug=0` 关闭调试。 + +> 当前没有实现查看变量的命令。 + +示例 + +```bash +miniob > select * from t; +id +1 + +# get a tuple: 1 +miniob > set sql_debug=0; +SUCCESS +miniob > select * from t; +id +1 + +``` \ No newline at end of file diff --git a/docs/src/game/introduction.md b/docs/src/game/introduction.md index 5b2457e..ae58788 100644 --- a/docs/src/game/introduction.md +++ b/docs/src/game/introduction.md @@ -21,6 +21,9 @@ 训练营的使用方法比较简单,不过这里也有一个小手册: [训练营使用手册](https://ask.oceanbase.com/t/topic/35600372) +为了方便大家使用训练营时获取调试信息,这里有一个小手册: +[训练营调试输出手册](./debug-output.md) + 注意,在训练营开始前,需要注意自己的程序输出需要满足一定的要求,请参考: [提交测试需要满足的输出要求](./miniob-output-convention.md) diff --git a/src/observer/common/ini_setting.h b/src/observer/common/ini_setting.h index d9ada86..74a35de 100644 --- a/src/observer/common/ini_setting.h +++ b/src/observer/common/ini_setting.h @@ -20,7 +20,7 @@ See the Mulan PSL v2 for more details. */ #define MAX_CONNECTION_NUM "MAX_CONNECTION_NUM" #define MAX_CONNECTION_NUM_DEFAULT 8192 #define PORT "PORT" -#define PORT_DEFAULT 16880 +#define PORT_DEFAULT 6789 #define SOCKET_BUFFER_SIZE 8192 diff --git a/src/observer/common/rc.h b/src/observer/common/rc.h index c429714..9acc276 100644 --- a/src/observer/common/rc.h +++ b/src/observer/common/rc.h @@ -71,6 +71,8 @@ See the Mulan PSL v2 for more details. */ DEFINE_RC(FILE_SEEK) \ DEFINE_RC(FILE_READ) \ DEFINE_RC(FILE_WRITE) \ + DEFINE_RC(VARIABLE_NOT_EXISTS) \ + DEFINE_RC(VARIABLE_NOT_VALID) \ DEFINE_RC(LOGBUF_FULL) enum class RC diff --git a/src/observer/event/optimize_event.h b/src/observer/event/optimize_event.h deleted file mode 100644 index 21cafda..0000000 --- a/src/observer/event/optimize_event.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2021 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/session_event.h b/src/observer/event/session_event.h index 088bb0b..61f4ef3 100644 --- a/src/observer/event/session_event.h +++ b/src/observer/event/session_event.h @@ -19,10 +19,15 @@ See the Mulan PSL v2 for more details. */ #include "common/seda/stage_event.h" #include "sql/executor/sql_result.h" +#include "event/sql_debug.h" class Session; class Communicator; +/** + * @brief 表示一个SQL请求 + * + */ class SessionEvent : public common::StageEvent { public: @@ -32,23 +37,17 @@ public: Communicator *get_communicator() const; Session *session() const; - void set_query(const std::string &query) - { - query_ = query; - } + void set_query(const std::string &query) { query_ = query; } - const std::string &query() const - { - return query_; - } - SqlResult *sql_result() - { - return &sql_result_; - } + const std::string &query() const { return query_; } -private: - Communicator *communicator_ = nullptr; - SqlResult sql_result_; + SqlResult *sql_result() { return &sql_result_; } + + SqlDebug &sql_debug() { return sql_debug_; } - std::string query_; +private: + Communicator *communicator_ = nullptr; ///< 与客户端通讯的对象 + SqlResult sql_result_; ///< SQL执行结果 + SqlDebug sql_debug_; ///< SQL调试信息 + std::string query_; ///< SQL语句 }; diff --git a/src/observer/event/sql_debug.cpp b/src/observer/event/sql_debug.cpp new file mode 100644 index 0000000..14d5f7b --- /dev/null +++ b/src/observer/event/sql_debug.cpp @@ -0,0 +1,64 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/6/29. +// + +#include + +#include "event/sql_debug.h" +#include "session/session.h" +#include "event/session_event.h" + +using namespace std; + +void SqlDebug::add_debug_info(const std::string &debug_info) +{ + debug_infos_.push_back(debug_info); +} + +void SqlDebug::clear_debug_info() +{ + debug_infos_.clear(); +} + +const list &SqlDebug::get_debug_infos() const +{ + return debug_infos_; +} + +void sql_debug(const char *fmt, ...) +{ + Session *session = Session::current_session(); + if (nullptr == session) { + return; + } + + SessionEvent *request = session->current_request(); + if (nullptr == request) { + return ; + } + + SqlDebug &sql_debug = request->sql_debug(); + + const int buffer_size = 4096; + char *str = new char[buffer_size]; + + va_list ap; + va_start(ap, fmt); + vsnprintf(str, buffer_size, fmt, ap); + va_end(ap); + + sql_debug.add_debug_info(str); + LOG_DEBUG("sql debug info: %s", str); + + delete[] str; +} diff --git a/src/observer/event/sql_debug.h b/src/observer/event/sql_debug.h new file mode 100644 index 0000000..493afec --- /dev/null +++ b/src/observer/event/sql_debug.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/6/29. +// + +#pragma once + +#include +#include + +/** + * @brief SQL调试信息 + * @details + * 希望在运行SQL时,可以直接输出一些调试信息到客户端。 + * 当前把调试信息都放在了session上,可以随着SQL语句输出。 + * 但是现在还不支持与输出调试信息与行数据同步输出。 + */ +class SqlDebug +{ +public: + SqlDebug() = default; + virtual ~SqlDebug() = default; + + void add_debug_info(const std::string &debug_info); + void clear_debug_info(); + + const std::list &get_debug_infos() const; + +private: + std::list debug_infos_; +}; + +/** + * @brief 增加SQL的调试信息 + * @details 可以在任何执行SQL语句时调用这个函数来增加调试信息。 + * 如果当前上下文不在SQL执行过程中,那么不会生成调试信息。 + * 在普通文本场景下,调试信息会直接输出到客户端,并增加 '#' 作为前缀。 + */ +void sql_debug(const char *fmt, ...); diff --git a/src/observer/event/sql_event.h b/src/observer/event/sql_event.h index 3090deb..c4b26a3 100644 --- a/src/observer/event/sql_event.h +++ b/src/observer/event/sql_event.h @@ -23,6 +23,9 @@ class SessionEvent; class Stmt; class Command; +/** + * @brief 与SessionEvent类似,也是处理SQL请求的事件,只是用在SQL的不同阶段 + */ class SQLStageEvent : public common::StageEvent { public: @@ -74,8 +77,8 @@ public: private: SessionEvent *session_event_ = nullptr; - std::string sql_; - std::unique_ptr command_; - Stmt *stmt_ = nullptr; - std::unique_ptr operator_; + std::string sql_; ///< 处理的SQL语句 + std::unique_ptr command_; ///< 语法解析后的SQL命令 + Stmt *stmt_ = nullptr; ///< Resolver之后生成的数据结构 + std::unique_ptr operator_; ///< 生成的执行计划,也可能没有 }; diff --git a/src/observer/net/mysql_communicator.cpp b/src/observer/net/mysql_communicator.cpp index 768d747..37fa1ab 100644 --- a/src/observer/net/mysql_communicator.cpp +++ b/src/observer/net/mysql_communicator.cpp @@ -973,9 +973,7 @@ RC MysqlCommunicator::send_result_rows(SqlResult *sql_result, bool no_column_def break; // TODO send error packet } - std::stringstream ss; - value.to_string(ss); - pos += store_lenenc_string(buf + pos, ss.str().c_str()); + pos += store_lenenc_string(buf + pos, value.to_string().c_str()); } int payload_length = pos - 4; diff --git a/src/observer/net/plain_communicator.cpp b/src/observer/net/plain_communicator.cpp index cd45994..40b81e2 100644 --- a/src/observer/net/plain_communicator.cpp +++ b/src/observer/net/plain_communicator.cpp @@ -23,6 +23,9 @@ See the Mulan PSL v2 for more details. */ PlainCommunicator::PlainCommunicator() { send_message_delimiter_.assign(1, '\0'); + debug_message_prefix_.resize(2); + debug_message_prefix_[0] = '#'; + debug_message_prefix_[1] = ' '; } RC PlainCommunicator::read_event(SessionEvent *&event) @@ -113,42 +116,67 @@ RC PlainCommunicator::write_state(SessionEvent *event, bool &need_disconnect) need_disconnect = false; delete[] buf; - writer_->flush(); return RC::SUCCESS; } -RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect) +RC PlainCommunicator::write_debug(SessionEvent *request, bool &need_disconnect) { - need_disconnect = true; - - SqlResult *sql_result = event->sql_result(); - if (nullptr == sql_result) { - - const char *response = "Unexpected error: no result"; - int len = strlen(response); + if (!session_->sql_debug_on()) { + return RC::SUCCESS; + } - RC rc = writer_->writen(response, len); + SqlDebug &sql_debug = request->sql_debug(); + const std::list &debug_infos = sql_debug.get_debug_infos(); + for (auto &debug_info : debug_infos) { + RC rc = writer_->writen(debug_message_prefix_.data(), debug_message_prefix_.size()); if (OB_FAIL(rc)) { - LOG_ERROR("Failed to send data back to client. ret=%s, error=%s", strrc(rc), strerror(errno)); + LOG_WARN("failed to send data to client. err=%s", strerror(errno)); + need_disconnect = true; + return RC::IOERR_WRITE; + } - return rc; + rc = writer_->writen(debug_info.data(), debug_info.size()); + if (OB_FAIL(rc)) { + LOG_WARN("failed to send data to client. err=%s", strerror(errno)); + need_disconnect = true; + return RC::IOERR_WRITE; } - rc = writer_->writen(send_message_delimiter_.data(), send_message_delimiter_.size()); + char newline = '\n'; + rc = writer_->writen(&newline, 1); if (OB_FAIL(rc)) { - LOG_ERROR("Failed to send data back to client. ret=%s, error=%s", strrc(rc), strerror(errno)); - return rc; + LOG_WARN("failed to send new line to client. err=%s", strerror(errno)); + need_disconnect = true; + return RC::IOERR_WRITE; } + } - need_disconnect = false; - return RC::SUCCESS; + need_disconnect = false; + return RC::SUCCESS; +} + +RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect) +{ + RC rc = write_result_internal(event, need_disconnect); + if (!need_disconnect) { + (void)write_debug(event, need_disconnect); } + writer_->flush(); // TODO handle error + return rc; +} + +RC PlainCommunicator::write_result_internal(SessionEvent *event, bool &need_disconnect) +{ + RC rc = RC::SUCCESS; + need_disconnect = true; + + SqlResult *sql_result = event->sql_result(); if (RC::SUCCESS != sql_result->return_code() || !sql_result->has_operator()) { return write_state(event, need_disconnect); } - RC rc = sql_result->open(); + rc = sql_result->open(); if (OB_FAIL(rc)) { sql_result->close(); sql_result->set_return_code(rc); @@ -215,9 +243,7 @@ RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect) return rc; } - std::stringstream ss; - value.to_string(ss); - std::string cell_str = ss.str(); + std::string cell_str = value.to_string(); rc = writer_->writen(cell_str.data(), cell_str.size()); if (OB_FAIL(rc)) { LOG_WARN("failed to send data to client. err=%s", strerror(errno)); @@ -266,6 +292,5 @@ RC PlainCommunicator::write_result(SessionEvent *event, bool &need_disconnect) rc = rc_close; } - writer_->flush(); // TODO handle error return rc; } \ No newline at end of file diff --git a/src/observer/net/plain_communicator.h b/src/observer/net/plain_communicator.h index 276823f..9453ccc 100644 --- a/src/observer/net/plain_communicator.h +++ b/src/observer/net/plain_communicator.h @@ -34,7 +34,10 @@ public: private: RC write_state(SessionEvent *event, bool &need_disconnect); + RC write_debug(SessionEvent *event, bool &need_disconnect); + RC write_result_internal(SessionEvent *event, bool &need_disconnect); protected: std::vector send_message_delimiter_; ///< 发送消息分隔符 + std::vector debug_message_prefix_; ///< 调试信息前缀 }; diff --git a/src/observer/session/session.cpp b/src/observer/session/session.cpp index 8b95461..ed75c1d 100644 --- a/src/observer/session/session.cpp +++ b/src/observer/session/session.cpp @@ -90,3 +90,13 @@ Session *Session::current_session() { return thread_session; } + +void Session::set_current_request(SessionEvent *request) +{ + current_request_ = request; +} + +SessionEvent *Session::current_request() const +{ + return current_request_; +} diff --git a/src/observer/session/session.h b/src/observer/session/session.h index ca6fd09..0b5bf9d 100644 --- a/src/observer/session/session.h +++ b/src/observer/session/session.h @@ -18,11 +18,19 @@ See the Mulan PSL v2 for more details. */ class Trx; class Db; +class SessionEvent; +/** + * @brief 表示会话 + * @details 当前一个连接一个会话,没有做特殊的会话管理,这也简化了会话处理 + */ class Session { public: - // static Session ¤t(); + /** + * @brief 获取默认的会话数据,新生成的会话都基于默认会话设置参数 + * @note 当前并没有会话参数 + */ static Session &default_session(); public: @@ -35,18 +43,58 @@ public: const char *get_current_db_name() const; Db *get_current_db() const; + /** + * @brief 设置当前会话关联的数据库 + * + * @param dbname 数据库名字 + */ void set_current_db(const std::string &dbname); + /** + * @brief 设置当前事务为多语句模式,需要明确的指出提交或回滚 + */ void set_trx_multi_operation_mode(bool multi_operation_mode); + + /** + * @brief 当前事务是否为多语句模式 + */ bool is_trx_multi_operation_mode() const; + /** + * @brief 当前会话关联的事务 + * + */ Trx *current_trx(); + /** + * @brief 设置当前正在处理的请求 + */ + void set_current_request(SessionEvent *request); + + /** + * @brief 获取当前正在处理的请求 + */ + SessionEvent *current_request() const; + + void set_sql_debug(bool sql_debug) { sql_debug_ = sql_debug; } + bool sql_debug_on() const { return sql_debug_; } + + /** + * @brief 将指定会话设置到线程变量中 + * + */ static void set_current_session(Session *session); + + /** + * @brief 获取当前的会话 + * @details 当前某个请求开始时,会将会话设置到线程变量中,在整个请求处理过程中不会改变 + */ static Session *current_session(); private: Db *db_ = nullptr; Trx *trx_ = nullptr; - bool trx_multi_operation_mode_ = false; // 当前事务的模式,是否多语句模式. 单语句模式自动提交 + SessionEvent *current_request_ = nullptr; ///< 当前正在处理的请求 + bool trx_multi_operation_mode_ = false; ///< 当前事务的模式,是否多语句模式. 单语句模式自动提交 + bool sql_debug_ = false; ///< 是否输出SQL调试信息 }; diff --git a/src/observer/session/session_stage.cpp b/src/observer/session/session_stage.cpp index d79108f..41939cc 100644 --- a/src/observer/session/session_stage.cpp +++ b/src/observer/session/session_stage.cpp @@ -116,6 +116,7 @@ void SessionStage::handle_request(StageEvent *event) } Session::set_current_session(sev->session()); + sev->session()->set_current_request(sev); SQLStageEvent *sql_event = new SQLStageEvent(sev, sql); query_cache_stage_->handle_event(sql_event); @@ -126,5 +127,6 @@ void SessionStage::handle_request(StageEvent *event) if (need_disconnect) { Server::close_connection(communicator); } + sev->session()->set_current_request(nullptr); Session::set_current_session(nullptr); } diff --git a/src/observer/sql/executor/command_executor.cpp b/src/observer/sql/executor/command_executor.cpp index 541d5f6..56615b6 100644 --- a/src/observer/sql/executor/command_executor.cpp +++ b/src/observer/sql/executor/command_executor.cpp @@ -22,6 +22,7 @@ See the Mulan PSL v2 for more details. */ #include "sql/executor/show_tables_executor.h" #include "sql/executor/trx_begin_executor.h" #include "sql/executor/trx_end_executor.h" +#include "sql/executor/set_variable_executor.h" #include "common/log/log.h" RC CommandExecutor::execute(SQLStageEvent *sql_event) @@ -65,6 +66,11 @@ RC CommandExecutor::execute(SQLStageEvent *sql_event) return executor.execute(sql_event); } + case StmtType::SET_VARIABLE: { + SetVariableExecutor executor; + return executor.execute(sql_event); + } + case StmtType::EXIT: { return RC::SUCCESS; } diff --git a/src/observer/sql/executor/desc_table_executor.cpp b/src/observer/sql/executor/desc_table_executor.cpp index 2feef24..2382a9c 100644 --- a/src/observer/sql/executor/desc_table_executor.cpp +++ b/src/observer/sql/executor/desc_table_executor.cpp @@ -29,6 +29,7 @@ using namespace std; RC DescTableExecutor::execute(SQLStageEvent *sql_event) { + RC rc = RC::SUCCESS; Stmt *stmt = sql_event->stmt(); SessionEvent *session_event = sql_event->session_event(); Session *session = session_event->session(); @@ -65,5 +66,5 @@ RC DescTableExecutor::execute(SQLStageEvent *sql_event) sql_result->set_return_code(RC::SCHEMA_TABLE_NOT_EXIST); sql_result->set_state_string("Table not exists"); } - return RC::SCHEMA_TABLE_NOT_EXIST; + return rc; } \ No newline at end of file diff --git a/src/observer/sql/executor/execute_stage.h b/src/observer/sql/executor/execute_stage.h index d3c87a4..270a616 100644 --- a/src/observer/sql/executor/execute_stage.h +++ b/src/observer/sql/executor/execute_stage.h @@ -26,7 +26,7 @@ class SelectStmt; * @brief 执行SQL语句的Stage,包括DML和DDL * @ingroup SQLStage * @details 根据前面阶段生成的结果,有些语句会生成执行计划,有些不会。 - * 整体上分为两类,带执行计划的,或者 @class CommandExecutor 可以直接执行的。 + * 整体上分为两类,带执行计划的,或者 CommandExecutor 可以直接执行的。 */ class ExecuteStage : public common::Stage { diff --git a/src/observer/sql/executor/set_variable_executor.h b/src/observer/sql/executor/set_variable_executor.h new file mode 100644 index 0000000..728bbce --- /dev/null +++ b/src/observer/sql/executor/set_variable_executor.h @@ -0,0 +1,106 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/6/14. +// + +#pragma once + +#include "common/rc.h" +#include "sql/operator/string_list_physical_operator.h" +#include "event/sql_event.h" +#include "event/session_event.h" +#include "sql/executor/sql_result.h" +#include "session/session.h" +#include "sql/stmt/set_variable_stmt.h" + +/** + * @brief SetVariable语句执行器 + * @ingroup Executor + */ +class SetVariableExecutor +{ +public: + SetVariableExecutor() = default; + virtual ~SetVariableExecutor() = default; + + RC execute(SQLStageEvent *sql_event) + { + RC rc = RC::SUCCESS; + Session *session = sql_event->session_event()->session(); + SetVariableStmt *stmt = (SetVariableStmt *)sql_event->stmt(); + + const char *var_name = stmt->var_name(); + const Value &var_value = stmt->var_value(); + if (strcasecmp(var_name, "sql_debug") == 0) { + bool bool_value = false; + rc = var_value_to_boolean(var_value, bool_value); + if (rc != RC::SUCCESS) { + return rc; + } + + session->set_sql_debug(bool_value); + LOG_TRACE("set sql_debug to %d", bool_value); + } else { + rc = RC::VARIABLE_NOT_EXISTS; + } + + return RC::SUCCESS; + } + +private: + RC var_value_to_boolean(const Value &var_value, bool &bool_value) const + { + RC rc = RC::SUCCESS; + + if (var_value.attr_type() == AttrType::BOOLEANS) { + bool_value = var_value.get_boolean(); + } else if (var_value.attr_type() == AttrType::INTS) { + bool_value = var_value.get_int() != 0; + } else if (var_value.attr_type() == AttrType::FLOATS) { + bool_value = var_value.get_float() != 0.0; + } else if (var_value.attr_type() == AttrType::CHARS) { + + std::string true_strings[] = { + "true", + "on", + "yes", + "t", + "1" + }; + + std::string false_strings[] = { + "false", + "off", + "no", + "f", + "0" + }; + + for (size_t i = 0; i < sizeof(true_strings) / sizeof(true_strings[0]); i++) { + if (strcasecmp(var_value.get_string().c_str(), true_strings[i].c_str()) == 0) { + bool_value = true; + return rc; + } + } + + for (size_t i = 0; i < sizeof(false_strings) / sizeof(false_strings[0]); i++) { + if (strcasecmp(var_value.get_string().c_str(), false_strings[i].c_str()) == 0) { + bool_value = false; + return rc; + } + } + rc = RC::VARIABLE_NOT_VALID; + } + + return rc; + } +}; \ No newline at end of file diff --git a/src/observer/sql/executor/sql_result.h b/src/observer/sql/executor/sql_result.h index dd89067..b21178b 100644 --- a/src/observer/sql/executor/sql_result.h +++ b/src/observer/sql/executor/sql_result.h @@ -24,7 +24,8 @@ class Session; /** * @brief SQL执行结果 - * @details 如果当前SQL生成了执行计划,那么在返回客户端时,调用执行计划返回结果。 + * @details + * 如果当前SQL生成了执行计划,那么在返回客户端时,调用执行计划返回结果。 * 否则返回的结果就是当前SQL的执行结果,比如DDL语句,通过return_code和state_string来描述。 * 如果出现了一些错误,也可以通过return_code和state_string来获取信息。 */ diff --git a/src/observer/sql/expr/tuple.h b/src/observer/sql/expr/tuple.h index 8eadc75..a215d78 100644 --- a/src/observer/sql/expr/tuple.h +++ b/src/observer/sql/expr/tuple.h @@ -16,6 +16,7 @@ See the Mulan PSL v2 for more details. */ #include #include +#include #include "common/log/log.h" #include "sql/expr/tuple_cell.h" @@ -26,6 +27,27 @@ See the Mulan PSL v2 for more details. */ class Table; +/** + * @defgroup Tuple + * @brief Tuple 元组,表示一行数据,当前返回客户端时使用 + * @details + * tuple是一种可以嵌套的数据结构。 + * 比如select t1.a+t2.b from t1, t2; + * 需要使用下面的结构表示: + * @code {.cpp} + * Project(t1.a+t2.b) + * | + * Joined + * / \ + * Row(t1) Row(t2) + * @endcode + * + */ + +/** + * @brief 元组的结构,包含哪些字段(这里成为Cell),每个字段的说明 + * @ingroup Tuple + */ class TupleSchema { public: @@ -54,17 +76,63 @@ private: std::vector cells_; }; +/** + * @brief 元组的抽象描述 + * @ingroup Tuple + */ class Tuple { public: Tuple() = default; virtual ~Tuple() = default; + /** + * @brief 获取元组中的Cell的个数 + * @details 个数应该与tuple_schema一致 + */ virtual int cell_num() const = 0; + + /** + * @brief 获取指定位置的Cell + * + * @param index 位置 + * @param[out] cell 返回的Cell + */ virtual RC cell_at(int index, Value &cell) const = 0; + + /** + * @brief 根据cell的描述,获取cell的值 + * + * @param spec cell的描述 + * @param[out] cell 返回的cell + */ virtual RC find_cell(const TupleCellSpec &spec, Value &cell) const = 0; + + virtual std::string to_string() const + { + std::string str; + const int cell_num = this->cell_num(); + for (int i = 0; i < cell_num - 1; i++) { + Value cell; + cell_at(i, cell); + str += cell.to_string(); + str += ", "; + } + + if (cell_num > 0) { + Value cell; + cell_at(cell_num - 1, cell); + str += cell.to_string(); + } + return str; + } }; +/** + * @brief 一行数据的元组 + * @ingroup Tuple + * @details 直接就是获取表中的一条记录 + */ class RowTuple : public Tuple { public: @@ -156,6 +224,13 @@ private: std::vector speces_; }; +/** + * @brief 从一行数据中,选择部分字段组成的元组,也就是投影操作 + * @ingroup Tuple + * @details 一般在select语句中使用。 + * 投影也可以是很复杂的操作,比如某些字段需要做类型转换、重命名、表达式运算、函数计算等。 + * 当前的实现是比较简单的,只是选择部分字段,不做任何其他操作。 + */ class ProjectTuple : public Tuple { public: @@ -215,6 +290,10 @@ private: Tuple *tuple_ = nullptr; }; +/** + * @brief 一些常量值组成的Tuple + * @ingroup Tuple + */ class ValueListTuple : public Tuple { public: @@ -251,8 +330,9 @@ private: }; /** - * 将两个tuple合并为一个tuple - * 在join算子中使用 + * @brief 将两个tuple合并为一个tuple + * @ingroup Tuple + * @details 在join算子中使用 */ class JoinedTuple : public Tuple { @@ -274,28 +354,28 @@ public: return left_->cell_num() + right_->cell_num(); } - RC cell_at(int index, Value &cell) const override + RC cell_at(int index, Value &value) const override { const int left_cell_num = left_->cell_num(); if (index > 0 && index < left_cell_num) { - return left_->cell_at(index, cell); + return left_->cell_at(index, value); } if (index >= left_cell_num && index < left_cell_num + right_->cell_num()) { - return right_->cell_at(index - left_cell_num, cell); + return right_->cell_at(index - left_cell_num, value); } return RC::NOTFOUND; } - RC find_cell(const TupleCellSpec &spec, Value &cell) const override + RC find_cell(const TupleCellSpec &spec, Value &value) const override { - RC rc = left_->find_cell(spec, cell); + RC rc = left_->find_cell(spec, value); if (rc == RC::SUCCESS || rc != RC::NOTFOUND) { return rc; } - return right_->find_cell(spec, cell); + return right_->find_cell(spec, value); } private: diff --git a/src/observer/sql/operator/table_scan_physical_operator.cpp b/src/observer/sql/operator/table_scan_physical_operator.cpp index 12ee1a9..68dca2f 100644 --- a/src/observer/sql/operator/table_scan_physical_operator.cpp +++ b/src/observer/sql/operator/table_scan_physical_operator.cpp @@ -14,6 +14,7 @@ See the Mulan PSL v2 for more details. */ #include "sql/operator/table_scan_physical_operator.h" #include "storage/table/table.h" +#include "event/sql_debug.h" using namespace std; @@ -48,8 +49,10 @@ RC TableScanPhysicalOperator::next() } if (filter_result) { + sql_debug("get a tuple: %s", tuple_.to_string().c_str()); break; } else { + sql_debug("a tuple is filtered: %s", tuple_.to_string().c_str()); rc = RC::RECORD_EOF; } } diff --git a/src/observer/sql/optimizer/comparison_simplification_rule.h b/src/observer/sql/optimizer/comparison_simplification_rule.h index 4be9432..0551c9f 100644 --- a/src/observer/sql/optimizer/comparison_simplification_rule.h +++ b/src/observer/sql/optimizer/comparison_simplification_rule.h @@ -19,6 +19,12 @@ See the Mulan PSL v2 for more details. */ class LogicalOperator; +/** + * @brief 简单比较的重写规则 + * @ingroup Rewriter + * @details 如果有简单的比较运算,比如比较的两边都是常量,那我们就可以在运行执行计划之前就知道结果, + * 进而直接将表达式改成结果,这样就可以减少运行时的计算量。 + */ class ComparisonSimplificationRule : public ExpressionRewriteRule { public: diff --git a/src/observer/sql/optimizer/conjunction_simplification_rule.h b/src/observer/sql/optimizer/conjunction_simplification_rule.h index 74cfe80..04c67c3 100644 --- a/src/observer/sql/optimizer/conjunction_simplification_rule.h +++ b/src/observer/sql/optimizer/conjunction_simplification_rule.h @@ -19,8 +19,9 @@ See the Mulan PSL v2 for more details. */ class LogicalOperator; /** - * 简化多个表达式联结的运算 - * 比如只有一个表达式,或者表达式可以直接出来 + * @brief 简化多个表达式联结的运算 + * @ingroup Rewriter + * @details 比如只有一个表达式,或者表达式可以直接出来 */ class ConjunctionSimplificationRule : public ExpressionRewriteRule { diff --git a/src/observer/sql/optimizer/physical_plan_generator.h b/src/observer/sql/optimizer/physical_plan_generator.h index ab77898..a0cff68 100644 --- a/src/observer/sql/optimizer/physical_plan_generator.h +++ b/src/observer/sql/optimizer/physical_plan_generator.h @@ -28,7 +28,14 @@ class DeleteLogicalOperator; class ExplainLogicalOperator; class JoinLogicalOperator; -class PhysicalPlanGenerator { +/** + * @brief 物理计划生成器 + * @ingroup PhysicalOperator + * @details 根据逻辑计划生成物理计划。 + * 不会做任何优化,完全根据本意生成物理计划。 + */ +class PhysicalPlanGenerator +{ public: PhysicalPlanGenerator() = default; virtual ~PhysicalPlanGenerator() = default; diff --git a/src/observer/sql/optimizer/predicate_pushdown_rewriter.h b/src/observer/sql/optimizer/predicate_pushdown_rewriter.h index ff8fad3..0ef065f 100644 --- a/src/observer/sql/optimizer/predicate_pushdown_rewriter.h +++ b/src/observer/sql/optimizer/predicate_pushdown_rewriter.h @@ -18,8 +18,9 @@ See the Mulan PSL v2 for more details. */ #include "sql/optimizer/rewrite_rule.h" /** - * 将一些谓词表达式下推到表数据扫描中 - * 这样可以提前过滤一些数据 + * @brief 将一些谓词表达式下推到表数据扫描中 + * @ingroup Rewriter + * @details 这样可以提前过滤一些数据 */ class PredicatePushdownRewriter : public RewriteRule { diff --git a/src/observer/sql/optimizer/predicate_rewrite.h b/src/observer/sql/optimizer/predicate_rewrite.h index a1b0a7b..6db2b3d 100644 --- a/src/observer/sql/optimizer/predicate_rewrite.h +++ b/src/observer/sql/optimizer/predicate_rewrite.h @@ -16,6 +16,11 @@ See the Mulan PSL v2 for more details. */ #include "sql/optimizer/rewrite_rule.h" +/** + * @brief 谓词重写规则 + * @ingroup Rewriter + * @details 有些谓词可以在真正运行之前就知道结果,那么就可以提前运算出来,比如1=1,1=0。 + */ class PredicateRewriteRule : public RewriteRule { public: diff --git a/src/observer/sql/optimizer/rewrite_rule.h b/src/observer/sql/optimizer/rewrite_rule.h index 22769d8..9a0ce14 100644 --- a/src/observer/sql/optimizer/rewrite_rule.h +++ b/src/observer/sql/optimizer/rewrite_rule.h @@ -21,6 +21,10 @@ See the Mulan PSL v2 for more details. */ class LogicalOperator; class Expression; +/** + * @brief 逻辑计划的重写规则 + * @ingroup Rewriter + */ class RewriteRule { public: @@ -29,6 +33,10 @@ public: virtual RC rewrite(std::unique_ptr &oper, bool &change_made) = 0; }; +/** + * @brief 表达式的重写规则 + * @ingroup Rewriter + */ class ExpressionRewriteRule { public: diff --git a/src/observer/sql/optimizer/rewriter.h b/src/observer/sql/optimizer/rewriter.h index 9ea4805..b6d02cd 100644 --- a/src/observer/sql/optimizer/rewriter.h +++ b/src/observer/sql/optimizer/rewriter.h @@ -20,12 +20,30 @@ See the Mulan PSL v2 for more details. */ class LogicalOperator; +/** + * @defgroup Rewriter + * @brief 根据规则对逻辑计划进行重写 + */ + +/** + * @brief 根据一些规则对逻辑计划进行重写 + * @ingroup Rewriter + * @details 当前仅实现了一两个非常简单的规则。 + * 重写包括对逻辑计划和计划中包含的表达式。 + */ class Rewriter { public: Rewriter(); virtual ~Rewriter() = default; + /** + * @brief 对逻辑计划进行重写 + * @details 如果重写发生,change_made为true,否则为false。 + * 通常情况下如果改写发生改变,就会继续重写,直到没有改变为止。 + * @param oper 逻辑计划 + * @param change_made 当前是否有重写发生 + */ RC rewrite(std::unique_ptr &oper, bool &change_made); private: diff --git a/src/observer/sql/parser/parse_defs.h b/src/observer/sql/parser/parse_defs.h index 27997b1..c072a83 100644 --- a/src/observer/sql/parser/parse_defs.h +++ b/src/observer/sql/parser/parse_defs.h @@ -187,6 +187,12 @@ struct LoadData std::string file_name; }; +struct SetVariable +{ + std::string name; + Value value; +}; + class Command; /** @@ -229,7 +235,7 @@ enum SqlCommandFlag SCF_SYNC, SCF_SHOW_TABLES, SCF_DESC_TABLE, - SCF_BEGIN, /// 事务开始语句,可以在这里扩展只读事务 + SCF_BEGIN, ///< 事务开始语句,可以在这里扩展只读事务 SCF_COMMIT, SCF_CLOG_SYNC, SCF_ROLLBACK, @@ -237,6 +243,7 @@ enum SqlCommandFlag SCF_HELP, SCF_EXIT, SCF_EXPLAIN, + SCF_SET_VARIABLE, ///< 设置变量 }; /** * @brief 表示一个SQL语句 @@ -258,6 +265,7 @@ public: DescTable desc_table; LoadData load_data; Explain explain; + SetVariable set_variable; public: Command(); @@ -278,5 +286,5 @@ public: } private: - std::vector> sql_commands_; /// 这里记录SQL命令。虽然看起来支持多个,但是当前仅处理一个 + std::vector> sql_commands_; ///< 这里记录SQL命令。虽然看起来支持多个,但是当前仅处理一个 }; diff --git a/src/observer/sql/parser/value.cpp b/src/observer/sql/parser/value.cpp index 3813d2a..619e30c 100644 --- a/src/observer/sql/parser/value.cpp +++ b/src/observer/sql/parser/value.cpp @@ -145,8 +145,9 @@ const char *Value::data() const } } -void Value::to_string(std::ostream &os) const +std::string Value::to_string() const { + std::stringstream os; switch (attr_type_) { case INTS: { os << num_value_.int_value_; @@ -164,6 +165,7 @@ void Value::to_string(std::ostream &os) const LOG_WARN("unsupported attr type: %d", attr_type_); } break; } + return os.str(); } int Value::compare(const Value &other) const @@ -258,9 +260,7 @@ float Value::get_float() const std::string Value::get_string() const { - std::stringstream ss; - to_string(ss); - return ss.str(); + return this->to_string(); } bool Value::get_boolean() const diff --git a/src/observer/sql/parser/value.h b/src/observer/sql/parser/value.h index 1b9bda4..32206b4 100644 --- a/src/observer/sql/parser/value.h +++ b/src/observer/sql/parser/value.h @@ -14,6 +14,8 @@ See the Mulan PSL v2 for more details. */ #pragma once +#include + /** * @brief 属性的类型 * @@ -67,7 +69,7 @@ public: void set_string(const char *s, int len = 0); void set_value(const Value &value); - void to_string(std::ostream &os) const; + std::string to_string() const; int compare(const Value &other) const; diff --git a/src/observer/sql/parser/yacc_sql.cpp b/src/observer/sql/parser/yacc_sql.cpp index a30cef6..3bfce51 100644 --- a/src/observer/sql/parser/yacc_sql.cpp +++ b/src/observer/sql/parser/yacc_sql.cpp @@ -208,7 +208,8 @@ enum yysymbol_kind_t YYSYMBOL_comp_op = 84, /* comp_op */ YYSYMBOL_load_data = 85, /* load_data */ YYSYMBOL_explain = 86, /* explain */ - YYSYMBOL_opt_semicolon = 87 /* opt_semicolon */ + YYSYMBOL_set_variable = 87, /* set_variable */ + YYSYMBOL_opt_semicolon = 88 /* opt_semicolon */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; @@ -519,18 +520,18 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 52 +#define YYFINAL 55 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 112 +#define YYLAST 127 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 52 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 36 +#define YYNNTS 37 /* YYNRULES -- Number of rules. */ -#define YYNRULES 76 +#define YYNRULES 78 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 138 +#define YYNSTATES 143 /* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 306 @@ -584,14 +585,14 @@ static const yytype_int8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 142, 142, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 171, 177, 182, 188, 194, 200, 206, 213, 219, - 227, 241, 251, 270, 273, 286, 294, 304, 307, 308, - 309, 312, 328, 331, 342, 345, 348, 356, 368, 383, - 406, 413, 425, 430, 441, 444, 458, 461, 474, 477, - 483, 486, 491, 498, 510, 522, 534, 549, 550, 551, - 552, 553, 554, 558, 568, 575, 576 + 0, 143, 143, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 173, 179, 184, 190, 196, 202, 208, 215, + 221, 229, 243, 253, 272, 275, 288, 296, 306, 309, + 310, 311, 314, 330, 333, 344, 347, 350, 358, 370, + 385, 408, 415, 427, 432, 443, 446, 460, 463, 476, + 479, 485, 488, 493, 500, 512, 524, 536, 551, 552, + 553, 554, 555, 556, 560, 570, 578, 588, 589 }; #endif @@ -620,7 +621,7 @@ static const char *const yytname[] = "type", "insert", "value_list", "value", "delete", "update", "select", "select_attr", "rel_attr", "attr_list", "rel_list", "where", "condition_list", "condition", "comp_op", "load_data", "explain", - "opt_semicolon", YY_NULLPTR + "set_variable", "opt_semicolon", YY_NULLPTR }; static const char * @@ -644,7 +645,7 @@ static const yytype_int16 yytoknum[] = }; #endif -#define YYPACT_NINF (-85) +#define YYPACT_NINF (-88) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) @@ -658,20 +659,21 @@ static const yytype_int16 yytoknum[] = STATE-NUM. */ static const yytype_int8 yypact[] = { - 10, 26, 46, -6, -37, 4, -85, -11, -12, -21, - -85, -85, -85, -85, -85, 7, 10, 47, 43, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, 6, 8, 9, - 12, 30, -85, 31, 42, -85, -85, 15, 16, 32, - 29, -85, -85, -85, -85, 48, 33, -85, 34, 22, - 23, 24, -85, 44, 41, 28, 25, 35, 36, 37, - -85, 58, 42, 61, -7, -85, 39, 51, 27, 62, - 65, -85, 38, 41, -85, -33, -85, -85, -85, -36, - -36, -85, 54, -33, 81, -85, -85, -85, 72, 35, - 73, 45, 58, -85, 71, -85, -85, -85, -85, -85, - -85, -7, -7, -7, 41, 49, 50, 62, -85, 74, - -85, -33, 76, -85, -85, -85, -85, -85, -85, -85, - -85, 77, -85, -85, 71, -85, -85, -85 + -2, 14, 29, -21, -42, 20, -88, -22, -9, -19, + -88, -88, -88, -88, -88, -13, 8, -2, 45, 43, + -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, -88, 0, + 6, 13, 15, 30, -88, 33, 46, -88, -88, 18, + 19, 34, 31, 32, -88, -88, -88, -88, 52, 37, + -88, 38, 26, 27, 28, -88, 47, 48, 35, 10, + 36, 39, 40, 41, -88, 59, 46, 62, 5, -88, + 42, -88, -88, -88, -88, 55, -8, 66, 64, -88, + 44, 48, -88, 10, -1, -1, -88, 57, 10, 84, + -88, -88, -88, 76, 39, 77, 49, 59, -88, 75, + -88, -88, -88, -88, -88, -88, 5, 5, 5, 48, + 50, 53, 66, -88, 78, -88, 10, 82, -88, -88, + -88, -88, -88, -88, -88, -88, 83, -88, -88, 75, + -88, -88, -88 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -679,38 +681,39 @@ static const yytype_int8 yypact[] = means the default is an error. */ static const yytype_int8 yydefact[] = { - 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, - 24, 25, 26, 22, 21, 0, 0, 0, 75, 20, - 19, 13, 14, 15, 16, 8, 9, 10, 11, 12, - 7, 4, 6, 5, 3, 17, 18, 0, 0, 0, - 0, 52, 50, 0, 54, 29, 28, 0, 0, 0, - 0, 74, 1, 76, 2, 0, 0, 27, 0, 0, - 0, 0, 51, 0, 58, 0, 0, 0, 0, 0, - 53, 56, 54, 0, 60, 47, 0, 0, 0, 33, - 0, 31, 0, 58, 55, 0, 44, 45, 46, 0, - 0, 59, 61, 0, 0, 38, 39, 40, 36, 0, - 0, 0, 56, 49, 42, 67, 68, 69, 70, 71, - 72, 0, 0, 60, 58, 0, 0, 33, 32, 0, - 57, 0, 0, 64, 66, 63, 65, 62, 48, 73, - 37, 0, 34, 30, 42, 41, 35, 43 + 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, + 25, 26, 27, 23, 22, 0, 0, 0, 0, 77, + 21, 20, 13, 14, 15, 16, 8, 9, 10, 11, + 12, 7, 4, 6, 5, 3, 17, 18, 19, 0, + 0, 0, 0, 53, 51, 0, 55, 30, 29, 0, + 0, 0, 0, 0, 75, 1, 78, 2, 0, 0, + 28, 0, 0, 0, 0, 52, 0, 59, 0, 0, + 0, 0, 0, 0, 54, 57, 55, 0, 61, 48, + 0, 45, 46, 47, 76, 0, 0, 34, 0, 32, + 0, 59, 56, 0, 0, 0, 60, 62, 0, 0, + 39, 40, 41, 37, 0, 0, 0, 57, 50, 43, + 68, 69, 70, 71, 72, 73, 0, 0, 61, 59, + 0, 0, 34, 33, 0, 58, 0, 0, 65, 67, + 64, 66, 63, 49, 74, 38, 0, 35, 31, 43, + 42, 36, 44 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -85, -85, 82, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -20, 0, -85, -85, -85, - -34, -84, -85, -85, -85, -85, -3, 40, -1, -81, - -10, -85, 14, -85, -85, -85 + -88, -88, 85, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -18, 1, -88, -88, -88, + -38, -68, -88, -88, -88, -88, -3, 51, -4, -87, + -12, -88, 12, -88, -88, -88, -88 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 100, 79, 131, 98, 31, - 122, 89, 32, 33, 34, 43, 90, 62, 83, 75, - 91, 92, 111, 35, 36, 54 + -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 105, 87, 136, 103, 32, + 127, 94, 33, 34, 35, 45, 95, 65, 91, 79, + 96, 97, 116, 36, 37, 38, 57 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -718,34 +721,36 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_uint8 yytable[] = { - 44, 104, 103, 105, 106, 107, 108, 109, 110, 114, - 45, 46, 86, 87, 1, 2, 88, 47, 48, 3, - 4, 5, 6, 7, 8, 9, 49, 123, 125, 10, - 11, 12, 37, 128, 38, 13, 14, 134, 86, 87, - 41, 41, 88, 50, 42, 15, 53, 52, 16, 95, - 96, 97, 39, 55, 40, 56, 57, 59, 72, 58, - 61, 60, 63, 64, 67, 65, 66, 68, 69, 70, - 71, 41, 74, 73, 77, 76, 82, 85, 93, 94, - 99, 101, 78, 80, 81, 102, 113, 115, 116, 121, - 118, 133, 119, 135, 136, 130, 129, 132, 51, 117, - 137, 120, 0, 127, 112, 0, 0, 0, 124, 126, - 0, 0, 84 + 46, 84, 1, 2, 108, 47, 49, 3, 4, 5, + 6, 7, 8, 9, 100, 101, 102, 10, 11, 12, + 39, 50, 40, 13, 14, 109, 43, 48, 51, 44, + 119, 15, 133, 16, 52, 41, 17, 42, 110, 111, + 112, 113, 114, 115, 53, 55, 56, 58, 128, 130, + 81, 82, 43, 59, 83, 81, 82, 62, 139, 83, + 60, 76, 61, 63, 64, 66, 67, 68, 71, 70, + 69, 72, 73, 74, 75, 43, 77, 90, 93, 78, + 106, 98, 80, 99, 104, 85, 86, 88, 89, 118, + 120, 107, 121, 126, 123, 138, 124, 134, 135, 140, + 141, 142, 54, 125, 137, 122, 132, 117, 0, 0, + 0, 0, 0, 129, 131, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 92 }; static const yytype_int16 yycheck[] = { - 3, 85, 83, 39, 40, 41, 42, 43, 44, 93, - 47, 7, 45, 46, 4, 5, 49, 28, 30, 9, - 10, 11, 12, 13, 14, 15, 47, 111, 112, 19, - 20, 21, 6, 114, 8, 25, 26, 121, 45, 46, - 47, 47, 49, 36, 50, 35, 3, 0, 38, 22, - 23, 24, 6, 47, 8, 47, 47, 27, 61, 47, - 18, 30, 47, 47, 16, 33, 37, 34, 34, 47, - 47, 47, 31, 29, 49, 47, 18, 16, 39, 28, - 18, 16, 47, 47, 47, 47, 32, 6, 16, 18, - 17, 17, 47, 17, 17, 45, 47, 117, 16, 99, - 134, 102, -1, 113, 90, -1, -1, -1, 111, 112, - -1, -1, 72 + 3, 69, 4, 5, 91, 47, 28, 9, 10, 11, + 12, 13, 14, 15, 22, 23, 24, 19, 20, 21, + 6, 30, 8, 25, 26, 93, 47, 7, 47, 50, + 98, 33, 119, 35, 47, 6, 38, 8, 39, 40, + 41, 42, 43, 44, 36, 0, 3, 47, 116, 117, + 45, 46, 47, 47, 49, 45, 46, 27, 126, 49, + 47, 64, 47, 30, 18, 47, 47, 33, 16, 37, + 39, 34, 34, 47, 47, 47, 29, 18, 16, 31, + 16, 39, 47, 28, 18, 49, 47, 47, 47, 32, + 6, 47, 16, 18, 17, 17, 47, 47, 45, 17, + 17, 139, 17, 107, 122, 104, 118, 95, -1, -1, + -1, -1, -1, 116, 117, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 76 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -753,19 +758,20 @@ static const yytype_int16 yycheck[] = static const yytype_int8 yystos[] = { 0, 4, 5, 9, 10, 11, 12, 13, 14, 15, - 19, 20, 21, 25, 26, 35, 38, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 71, 74, 75, 76, 85, 86, 6, 8, 6, - 8, 47, 50, 77, 78, 47, 7, 28, 30, 47, - 36, 54, 0, 3, 87, 47, 47, 47, 47, 27, - 30, 18, 79, 47, 47, 33, 37, 16, 34, 34, - 47, 47, 78, 29, 31, 81, 47, 49, 47, 68, - 47, 47, 18, 80, 79, 16, 45, 46, 49, 73, - 78, 82, 83, 39, 28, 22, 23, 24, 70, 18, - 67, 16, 47, 81, 73, 39, 40, 41, 42, 43, - 44, 84, 84, 32, 73, 6, 16, 68, 17, 47, - 80, 18, 72, 73, 78, 73, 78, 82, 81, 47, - 45, 69, 67, 17, 73, 17, 17, 72 + 19, 20, 21, 25, 26, 33, 35, 38, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 71, 74, 75, 76, 85, 86, 87, 6, + 8, 6, 8, 47, 50, 77, 78, 47, 7, 28, + 30, 47, 47, 36, 54, 0, 3, 88, 47, 47, + 47, 47, 27, 30, 18, 79, 47, 47, 33, 39, + 37, 16, 34, 34, 47, 47, 78, 29, 31, 81, + 47, 45, 46, 49, 73, 49, 47, 68, 47, 47, + 18, 80, 79, 16, 73, 78, 82, 83, 39, 28, + 22, 23, 24, 70, 18, 67, 16, 47, 81, 73, + 39, 40, 41, 42, 43, 44, 84, 84, 32, 73, + 6, 16, 68, 17, 47, 80, 18, 72, 73, 78, + 73, 78, 82, 81, 47, 45, 69, 67, 17, 73, + 17, 17, 72 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ @@ -773,12 +779,12 @@ static const yytype_int8 yyr1[] = { 0, 52, 53, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 67, 68, 68, 69, 70, 70, - 70, 71, 72, 72, 73, 73, 73, 74, 75, 76, - 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, - 82, 82, 82, 83, 83, 83, 83, 84, 84, 84, - 84, 84, 84, 85, 86, 87, 87 + 54, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 67, 68, 68, 69, 70, + 70, 70, 71, 72, 72, 73, 73, 73, 74, 75, + 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, + 81, 82, 82, 82, 83, 83, 83, 83, 84, 84, + 84, 84, 84, 84, 85, 86, 87, 88, 88 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -786,12 +792,12 @@ static const yytype_int8 yyr2[] = { 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, 2, 2, - 8, 5, 7, 0, 3, 5, 2, 1, 1, 1, - 1, 8, 0, 3, 1, 1, 1, 4, 7, 6, - 1, 2, 1, 3, 0, 3, 0, 3, 0, 2, - 0, 1, 3, 3, 3, 3, 3, 1, 1, 1, - 1, 1, 1, 7, 2, 0, 1 + 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, + 2, 8, 5, 7, 0, 3, 5, 2, 1, 1, + 1, 1, 8, 0, 3, 1, 1, 1, 4, 7, + 6, 1, 2, 1, 3, 0, 3, 0, 3, 0, + 2, 0, 1, 3, 3, 3, 3, 3, 1, 1, + 1, 1, 1, 1, 7, 2, 4, 0, 1 }; @@ -1637,93 +1643,93 @@ yyreduce: switch (yyn) { case 2: /* commands: command_wrapper opt_semicolon */ -#line 143 "yacc_sql.y" +#line 144 "yacc_sql.y" { std::unique_ptr sql_command = std::unique_ptr((yyvsp[-1].command)); sql_result->add_command(std::move(sql_command)); } -#line 1646 "yacc_sql.cpp" +#line 1652 "yacc_sql.cpp" break; - case 21: /* exit: EXIT */ -#line 171 "yacc_sql.y" + case 22: /* exit: EXIT */ +#line 173 "yacc_sql.y" { (void)yynerrs; // 这么写为了消除yynerrs未使用的告警。如果你有更好的方法欢迎提PR (yyval.command) = new Command(SCF_EXIT); } -#line 1655 "yacc_sql.cpp" +#line 1661 "yacc_sql.cpp" break; - case 22: /* help: HELP */ -#line 177 "yacc_sql.y" + case 23: /* help: HELP */ +#line 179 "yacc_sql.y" { (yyval.command) = new Command(SCF_HELP); } -#line 1663 "yacc_sql.cpp" +#line 1669 "yacc_sql.cpp" break; - case 23: /* sync: SYNC */ -#line 182 "yacc_sql.y" + case 24: /* sync: SYNC */ +#line 184 "yacc_sql.y" { (yyval.command) = new Command(SCF_SYNC); } -#line 1671 "yacc_sql.cpp" +#line 1677 "yacc_sql.cpp" break; - case 24: /* begin: TRX_BEGIN */ -#line 188 "yacc_sql.y" + case 25: /* begin: TRX_BEGIN */ +#line 190 "yacc_sql.y" { (yyval.command) = new Command(SCF_BEGIN); } -#line 1679 "yacc_sql.cpp" +#line 1685 "yacc_sql.cpp" break; - case 25: /* commit: TRX_COMMIT */ -#line 194 "yacc_sql.y" + case 26: /* commit: TRX_COMMIT */ +#line 196 "yacc_sql.y" { (yyval.command) = new Command(SCF_COMMIT); } -#line 1687 "yacc_sql.cpp" +#line 1693 "yacc_sql.cpp" break; - case 26: /* rollback: TRX_ROLLBACK */ -#line 200 "yacc_sql.y" + case 27: /* rollback: TRX_ROLLBACK */ +#line 202 "yacc_sql.y" { (yyval.command) = new Command(SCF_ROLLBACK); } -#line 1695 "yacc_sql.cpp" +#line 1701 "yacc_sql.cpp" break; - case 27: /* drop_table: DROP TABLE ID */ -#line 206 "yacc_sql.y" + case 28: /* drop_table: DROP TABLE ID */ +#line 208 "yacc_sql.y" { (yyval.command) = new Command(SCF_DROP_TABLE); (yyval.command)->drop_table.relation_name = (yyvsp[0].string); free((yyvsp[0].string)); } -#line 1705 "yacc_sql.cpp" +#line 1711 "yacc_sql.cpp" break; - case 28: /* show_tables: SHOW TABLES */ -#line 213 "yacc_sql.y" + case 29: /* show_tables: SHOW TABLES */ +#line 215 "yacc_sql.y" { (yyval.command) = new Command(SCF_SHOW_TABLES); } -#line 1713 "yacc_sql.cpp" +#line 1719 "yacc_sql.cpp" break; - case 29: /* desc_table: DESC ID */ -#line 219 "yacc_sql.y" + case 30: /* desc_table: DESC ID */ +#line 221 "yacc_sql.y" { (yyval.command) = new Command(SCF_DESC_TABLE); (yyval.command)->desc_table.relation_name = (yyvsp[0].string); free((yyvsp[0].string)); } -#line 1723 "yacc_sql.cpp" +#line 1729 "yacc_sql.cpp" break; - case 30: /* create_index: CREATE INDEX ID ON ID LBRACE ID RBRACE */ -#line 228 "yacc_sql.y" + case 31: /* create_index: CREATE INDEX ID ON ID LBRACE ID RBRACE */ +#line 230 "yacc_sql.y" { (yyval.command) = new Command(SCF_CREATE_INDEX); CreateIndex &create_index = (yyval.command)->create_index; @@ -1734,11 +1740,11 @@ yyreduce: free((yyvsp[-3].string)); free((yyvsp[-1].string)); } -#line 1738 "yacc_sql.cpp" +#line 1744 "yacc_sql.cpp" break; - case 31: /* drop_index: DROP INDEX ID ON ID */ -#line 242 "yacc_sql.y" + case 32: /* drop_index: DROP INDEX ID ON ID */ +#line 244 "yacc_sql.y" { (yyval.command) = new Command(SCF_DROP_INDEX); (yyval.command)->drop_index.index_name = (yyvsp[-2].string); @@ -1746,11 +1752,11 @@ yyreduce: free((yyvsp[-2].string)); free((yyvsp[0].string)); } -#line 1750 "yacc_sql.cpp" +#line 1756 "yacc_sql.cpp" break; - case 32: /* create_table: CREATE TABLE ID LBRACE attr_def attr_def_list RBRACE */ -#line 252 "yacc_sql.y" + case 33: /* create_table: CREATE TABLE ID LBRACE attr_def attr_def_list RBRACE */ +#line 254 "yacc_sql.y" { (yyval.command) = new Command(SCF_CREATE_TABLE); CreateTable &create_table = (yyval.command)->create_table; @@ -1766,19 +1772,19 @@ yyreduce: std::reverse(create_table.attr_infos.begin(), create_table.attr_infos.end()); delete (yyvsp[-2].attr_info); } -#line 1770 "yacc_sql.cpp" +#line 1776 "yacc_sql.cpp" break; - case 33: /* attr_def_list: %empty */ -#line 270 "yacc_sql.y" + case 34: /* attr_def_list: %empty */ +#line 272 "yacc_sql.y" { (yyval.attr_infos) = nullptr; } -#line 1778 "yacc_sql.cpp" +#line 1784 "yacc_sql.cpp" break; - case 34: /* attr_def_list: COMMA attr_def attr_def_list */ -#line 274 "yacc_sql.y" + case 35: /* attr_def_list: COMMA attr_def attr_def_list */ +#line 276 "yacc_sql.y" { if ((yyvsp[0].attr_infos) != nullptr) { (yyval.attr_infos) = (yyvsp[0].attr_infos); @@ -1788,11 +1794,11 @@ yyreduce: (yyval.attr_infos)->emplace_back(*(yyvsp[-1].attr_info)); delete (yyvsp[-1].attr_info); } -#line 1792 "yacc_sql.cpp" +#line 1798 "yacc_sql.cpp" break; - case 35: /* attr_def: ID type LBRACE number RBRACE */ -#line 287 "yacc_sql.y" + case 36: /* attr_def: ID type LBRACE number RBRACE */ +#line 289 "yacc_sql.y" { (yyval.attr_info) = new AttrInfo; (yyval.attr_info)->type = (AttrType)(yyvsp[-3].number); @@ -1800,11 +1806,11 @@ yyreduce: (yyval.attr_info)->length = (yyvsp[-1].number); free((yyvsp[-4].string)); } -#line 1804 "yacc_sql.cpp" +#line 1810 "yacc_sql.cpp" break; - case 36: /* attr_def: ID type */ -#line 295 "yacc_sql.y" + case 37: /* attr_def: ID type */ +#line 297 "yacc_sql.y" { (yyval.attr_info) = new AttrInfo; (yyval.attr_info)->type = (AttrType)(yyvsp[0].number); @@ -1812,35 +1818,35 @@ yyreduce: (yyval.attr_info)->length = 4; free((yyvsp[-1].string)); } -#line 1816 "yacc_sql.cpp" +#line 1822 "yacc_sql.cpp" break; - case 37: /* number: NUMBER */ -#line 304 "yacc_sql.y" + case 38: /* number: NUMBER */ +#line 306 "yacc_sql.y" {(yyval.number) = (yyvsp[0].number);} -#line 1822 "yacc_sql.cpp" +#line 1828 "yacc_sql.cpp" break; - case 38: /* type: INT_T */ -#line 307 "yacc_sql.y" + case 39: /* type: INT_T */ +#line 309 "yacc_sql.y" { (yyval.number)=INTS; } -#line 1828 "yacc_sql.cpp" +#line 1834 "yacc_sql.cpp" break; - case 39: /* type: STRING_T */ -#line 308 "yacc_sql.y" + case 40: /* type: STRING_T */ +#line 310 "yacc_sql.y" { (yyval.number)=CHARS; } -#line 1834 "yacc_sql.cpp" +#line 1840 "yacc_sql.cpp" break; - case 40: /* type: FLOAT_T */ -#line 309 "yacc_sql.y" + case 41: /* type: FLOAT_T */ +#line 311 "yacc_sql.y" { (yyval.number)=FLOATS; } -#line 1840 "yacc_sql.cpp" +#line 1846 "yacc_sql.cpp" break; - case 41: /* insert: INSERT INTO ID VALUES LBRACE value value_list RBRACE */ -#line 313 "yacc_sql.y" + case 42: /* insert: INSERT INTO ID VALUES LBRACE value value_list RBRACE */ +#line 315 "yacc_sql.y" { (yyval.command) = new Command(SCF_INSERT); (yyval.command)->insertion.relation_name = (yyvsp[-5].string); @@ -1852,19 +1858,19 @@ yyreduce: delete (yyvsp[-2].value); free((yyvsp[-5].string)); } -#line 1856 "yacc_sql.cpp" +#line 1862 "yacc_sql.cpp" break; - case 42: /* value_list: %empty */ -#line 328 "yacc_sql.y" + case 43: /* value_list: %empty */ +#line 330 "yacc_sql.y" { (yyval.value_list) = nullptr; } -#line 1864 "yacc_sql.cpp" +#line 1870 "yacc_sql.cpp" break; - case 43: /* value_list: COMMA value value_list */ -#line 331 "yacc_sql.y" + case 44: /* value_list: COMMA value value_list */ +#line 333 "yacc_sql.y" { if ((yyvsp[0].value_list) != nullptr) { (yyval.value_list) = (yyvsp[0].value_list); @@ -1874,37 +1880,37 @@ yyreduce: (yyval.value_list)->emplace_back(*(yyvsp[-1].value)); delete (yyvsp[-1].value); } -#line 1878 "yacc_sql.cpp" +#line 1884 "yacc_sql.cpp" break; - case 44: /* value: NUMBER */ -#line 342 "yacc_sql.y" + case 45: /* value: NUMBER */ +#line 344 "yacc_sql.y" { (yyval.value) = new Value((int)(yyvsp[0].number)); } -#line 1886 "yacc_sql.cpp" +#line 1892 "yacc_sql.cpp" break; - case 45: /* value: FLOAT */ -#line 345 "yacc_sql.y" + case 46: /* value: FLOAT */ +#line 347 "yacc_sql.y" { (yyval.value) = new Value((float)(yyvsp[0].floats)); } -#line 1894 "yacc_sql.cpp" +#line 1900 "yacc_sql.cpp" break; - case 46: /* value: SSS */ -#line 348 "yacc_sql.y" + case 47: /* value: SSS */ +#line 350 "yacc_sql.y" { char *tmp = common::substr((yyvsp[0].string),1,strlen((yyvsp[0].string))-2); (yyval.value) = new Value(tmp); free(tmp); } -#line 1904 "yacc_sql.cpp" +#line 1910 "yacc_sql.cpp" break; - case 47: /* delete: DELETE FROM ID where */ -#line 357 "yacc_sql.y" + case 48: /* delete: DELETE FROM ID where */ +#line 359 "yacc_sql.y" { (yyval.command) = new Command(SCF_DELETE); (yyval.command)->deletion.relation_name = (yyvsp[-1].string); @@ -1914,11 +1920,11 @@ yyreduce: } free((yyvsp[-1].string)); } -#line 1918 "yacc_sql.cpp" +#line 1924 "yacc_sql.cpp" break; - case 48: /* update: UPDATE ID SET ID EQ value where */ -#line 369 "yacc_sql.y" + case 49: /* update: UPDATE ID SET ID EQ value where */ +#line 371 "yacc_sql.y" { (yyval.command) = new Command(SCF_UPDATE); (yyval.command)->update.relation_name = (yyvsp[-5].string); @@ -1931,11 +1937,11 @@ yyreduce: free((yyvsp[-5].string)); free((yyvsp[-3].string)); } -#line 1935 "yacc_sql.cpp" +#line 1941 "yacc_sql.cpp" break; - case 49: /* select: SELECT select_attr FROM ID rel_list where */ -#line 384 "yacc_sql.y" + case 50: /* select: SELECT select_attr FROM ID rel_list where */ +#line 386 "yacc_sql.y" { (yyval.command) = new Command(SCF_SELECT); if ((yyvsp[-4].rel_attr_list) != nullptr) { @@ -1955,11 +1961,11 @@ yyreduce: } free((yyvsp[-2].string)); } -#line 1959 "yacc_sql.cpp" +#line 1965 "yacc_sql.cpp" break; - case 50: /* select_attr: STAR */ -#line 406 "yacc_sql.y" + case 51: /* select_attr: STAR */ +#line 408 "yacc_sql.y" { (yyval.rel_attr_list) = new std::vector; RelAttr attr; @@ -1967,11 +1973,11 @@ yyreduce: attr.attribute_name = "*"; (yyval.rel_attr_list)->emplace_back(attr); } -#line 1971 "yacc_sql.cpp" +#line 1977 "yacc_sql.cpp" break; - case 51: /* select_attr: rel_attr attr_list */ -#line 413 "yacc_sql.y" + case 52: /* select_attr: rel_attr attr_list */ +#line 415 "yacc_sql.y" { if ((yyvsp[0].rel_attr_list) != nullptr) { (yyval.rel_attr_list) = (yyvsp[0].rel_attr_list); @@ -1981,21 +1987,21 @@ yyreduce: (yyval.rel_attr_list)->emplace_back(*(yyvsp[-1].rel_attr)); delete (yyvsp[-1].rel_attr); } -#line 1985 "yacc_sql.cpp" +#line 1991 "yacc_sql.cpp" break; - case 52: /* rel_attr: ID */ -#line 425 "yacc_sql.y" + case 53: /* rel_attr: ID */ +#line 427 "yacc_sql.y" { (yyval.rel_attr) = new RelAttr; (yyval.rel_attr)->attribute_name = (yyvsp[0].string); free((yyvsp[0].string)); } -#line 1995 "yacc_sql.cpp" +#line 2001 "yacc_sql.cpp" break; - case 53: /* rel_attr: ID DOT ID */ -#line 430 "yacc_sql.y" + case 54: /* rel_attr: ID DOT ID */ +#line 432 "yacc_sql.y" { (yyval.rel_attr) = new RelAttr; (yyval.rel_attr)->relation_name = (yyvsp[-2].string); @@ -2003,19 +2009,19 @@ yyreduce: free((yyvsp[-2].string)); free((yyvsp[0].string)); } -#line 2007 "yacc_sql.cpp" +#line 2013 "yacc_sql.cpp" break; - case 54: /* attr_list: %empty */ -#line 441 "yacc_sql.y" + case 55: /* attr_list: %empty */ +#line 443 "yacc_sql.y" { (yyval.rel_attr_list) = nullptr; } -#line 2015 "yacc_sql.cpp" +#line 2021 "yacc_sql.cpp" break; - case 55: /* attr_list: COMMA rel_attr attr_list */ -#line 444 "yacc_sql.y" + case 56: /* attr_list: COMMA rel_attr attr_list */ +#line 446 "yacc_sql.y" { if ((yyvsp[0].rel_attr_list) != nullptr) { (yyval.rel_attr_list) = (yyvsp[0].rel_attr_list); @@ -2026,19 +2032,19 @@ yyreduce: (yyval.rel_attr_list)->emplace_back(*(yyvsp[-1].rel_attr)); delete (yyvsp[-1].rel_attr); } -#line 2030 "yacc_sql.cpp" +#line 2036 "yacc_sql.cpp" break; - case 56: /* rel_list: %empty */ -#line 458 "yacc_sql.y" + case 57: /* rel_list: %empty */ +#line 460 "yacc_sql.y" { (yyval.relation_list) = nullptr; } -#line 2038 "yacc_sql.cpp" +#line 2044 "yacc_sql.cpp" break; - case 57: /* rel_list: COMMA ID rel_list */ -#line 461 "yacc_sql.y" + case 58: /* rel_list: COMMA ID rel_list */ +#line 463 "yacc_sql.y" { if ((yyvsp[0].relation_list) != nullptr) { (yyval.relation_list) = (yyvsp[0].relation_list); @@ -2049,55 +2055,55 @@ yyreduce: (yyval.relation_list)->push_back((yyvsp[-1].string)); free((yyvsp[-1].string)); } -#line 2053 "yacc_sql.cpp" +#line 2059 "yacc_sql.cpp" break; - case 58: /* where: %empty */ -#line 474 "yacc_sql.y" + case 59: /* where: %empty */ +#line 476 "yacc_sql.y" { (yyval.condition_list) = nullptr; } -#line 2061 "yacc_sql.cpp" +#line 2067 "yacc_sql.cpp" break; - case 59: /* where: WHERE condition_list */ -#line 477 "yacc_sql.y" + case 60: /* where: WHERE condition_list */ +#line 479 "yacc_sql.y" { (yyval.condition_list) = (yyvsp[0].condition_list); } -#line 2069 "yacc_sql.cpp" +#line 2075 "yacc_sql.cpp" break; - case 60: /* condition_list: %empty */ -#line 483 "yacc_sql.y" + case 61: /* condition_list: %empty */ +#line 485 "yacc_sql.y" { (yyval.condition_list) = nullptr; } -#line 2077 "yacc_sql.cpp" +#line 2083 "yacc_sql.cpp" break; - case 61: /* condition_list: condition */ -#line 486 "yacc_sql.y" + case 62: /* condition_list: condition */ +#line 488 "yacc_sql.y" { (yyval.condition_list) = new std::vector; (yyval.condition_list)->emplace_back(*(yyvsp[0].condition)); delete (yyvsp[0].condition); } -#line 2087 "yacc_sql.cpp" +#line 2093 "yacc_sql.cpp" break; - case 62: /* condition_list: condition AND condition_list */ -#line 491 "yacc_sql.y" + case 63: /* condition_list: condition AND condition_list */ +#line 493 "yacc_sql.y" { (yyval.condition_list) = (yyvsp[0].condition_list); (yyval.condition_list)->emplace_back(*(yyvsp[-2].condition)); delete (yyvsp[-2].condition); } -#line 2097 "yacc_sql.cpp" +#line 2103 "yacc_sql.cpp" break; - case 63: /* condition: rel_attr comp_op value */ -#line 499 "yacc_sql.y" + case 64: /* condition: rel_attr comp_op value */ +#line 501 "yacc_sql.y" { (yyval.condition) = new Condition; (yyval.condition)->left_is_attr = 1; @@ -2109,11 +2115,11 @@ yyreduce: delete (yyvsp[-2].rel_attr); delete (yyvsp[0].value); } -#line 2113 "yacc_sql.cpp" +#line 2119 "yacc_sql.cpp" break; - case 64: /* condition: value comp_op value */ -#line 511 "yacc_sql.y" + case 65: /* condition: value comp_op value */ +#line 513 "yacc_sql.y" { (yyval.condition) = new Condition; (yyval.condition)->left_is_attr = 0; @@ -2125,11 +2131,11 @@ yyreduce: delete (yyvsp[-2].value); delete (yyvsp[0].value); } -#line 2129 "yacc_sql.cpp" +#line 2135 "yacc_sql.cpp" break; - case 65: /* condition: rel_attr comp_op rel_attr */ -#line 523 "yacc_sql.y" + case 66: /* condition: rel_attr comp_op rel_attr */ +#line 525 "yacc_sql.y" { (yyval.condition) = new Condition; (yyval.condition)->left_is_attr = 1; @@ -2141,11 +2147,11 @@ yyreduce: delete (yyvsp[-2].rel_attr); delete (yyvsp[0].rel_attr); } -#line 2145 "yacc_sql.cpp" +#line 2151 "yacc_sql.cpp" break; - case 66: /* condition: value comp_op rel_attr */ -#line 535 "yacc_sql.y" + case 67: /* condition: value comp_op rel_attr */ +#line 537 "yacc_sql.y" { (yyval.condition) = new Condition; (yyval.condition)->left_is_attr = 0; @@ -2157,67 +2163,79 @@ yyreduce: delete (yyvsp[-2].value); delete (yyvsp[0].rel_attr); } -#line 2161 "yacc_sql.cpp" +#line 2167 "yacc_sql.cpp" break; - case 67: /* comp_op: EQ */ -#line 549 "yacc_sql.y" + case 68: /* comp_op: EQ */ +#line 551 "yacc_sql.y" { (yyval.comp) = EQUAL_TO; } -#line 2167 "yacc_sql.cpp" +#line 2173 "yacc_sql.cpp" break; - case 68: /* comp_op: LT */ -#line 550 "yacc_sql.y" + case 69: /* comp_op: LT */ +#line 552 "yacc_sql.y" { (yyval.comp) = LESS_THAN; } -#line 2173 "yacc_sql.cpp" +#line 2179 "yacc_sql.cpp" break; - case 69: /* comp_op: GT */ -#line 551 "yacc_sql.y" + case 70: /* comp_op: GT */ +#line 553 "yacc_sql.y" { (yyval.comp) = GREAT_THAN; } -#line 2179 "yacc_sql.cpp" +#line 2185 "yacc_sql.cpp" break; - case 70: /* comp_op: LE */ -#line 552 "yacc_sql.y" + case 71: /* comp_op: LE */ +#line 554 "yacc_sql.y" { (yyval.comp) = LESS_EQUAL; } -#line 2185 "yacc_sql.cpp" +#line 2191 "yacc_sql.cpp" break; - case 71: /* comp_op: GE */ -#line 553 "yacc_sql.y" + case 72: /* comp_op: GE */ +#line 555 "yacc_sql.y" { (yyval.comp) = GREAT_EQUAL; } -#line 2191 "yacc_sql.cpp" +#line 2197 "yacc_sql.cpp" break; - case 72: /* comp_op: NE */ -#line 554 "yacc_sql.y" + case 73: /* comp_op: NE */ +#line 556 "yacc_sql.y" { (yyval.comp) = NOT_EQUAL; } -#line 2197 "yacc_sql.cpp" +#line 2203 "yacc_sql.cpp" break; - case 73: /* load_data: LOAD DATA INFILE SSS INTO TABLE ID */ -#line 559 "yacc_sql.y" + case 74: /* load_data: LOAD DATA INFILE SSS INTO TABLE ID */ +#line 561 "yacc_sql.y" { (yyval.command) = new Command(SCF_LOAD_DATA); (yyval.command)->load_data.relation_name = (yyvsp[0].string); (yyval.command)->load_data.file_name = (yyvsp[-3].string); free((yyvsp[0].string)); } -#line 2208 "yacc_sql.cpp" +#line 2214 "yacc_sql.cpp" break; - case 74: /* explain: EXPLAIN command_wrapper */ -#line 569 "yacc_sql.y" + case 75: /* explain: EXPLAIN command_wrapper */ +#line 571 "yacc_sql.y" { (yyval.command) = new Command(SCF_EXPLAIN); (yyval.command)->explain.cmd = std::unique_ptr((yyvsp[0].command)); } -#line 2217 "yacc_sql.cpp" +#line 2223 "yacc_sql.cpp" + break; + + case 76: /* set_variable: SET ID EQ value */ +#line 579 "yacc_sql.y" + { + (yyval.command) = new Command(SCF_SET_VARIABLE); + (yyval.command)->set_variable.name = (yyvsp[-2].string); + (yyval.command)->set_variable.value = *(yyvsp[0].value); + free((yyvsp[-2].string)); + delete (yyvsp[0].value); + } +#line 2235 "yacc_sql.cpp" break; -#line 2221 "yacc_sql.cpp" +#line 2239 "yacc_sql.cpp" default: break; } @@ -2447,7 +2465,7 @@ yyreturn: return yyresult; } -#line 578 "yacc_sql.y" +#line 591 "yacc_sql.y" //_____________________________________________________________________ extern void scan_string(const char *str, yyscan_t scanner); diff --git a/src/observer/sql/parser/yacc_sql.y b/src/observer/sql/parser/yacc_sql.y index cabd90e..f74479c 100644 --- a/src/observer/sql/parser/yacc_sql.y +++ b/src/observer/sql/parser/yacc_sql.y @@ -132,6 +132,7 @@ int yyerror(YYLTYPE *llocp, ParsedSqlResult *sql_result, yyscan_t scanner, const %type rollback %type load_data %type explain +%type set_variable %type help %type exit %type command_wrapper @@ -163,6 +164,7 @@ command_wrapper: | rollback | load_data | explain + | set_variable | help | exit ; @@ -572,6 +574,17 @@ explain: } ; +set_variable: + SET ID EQ value + { + $$ = new Command(SCF_SET_VARIABLE); + $$->set_variable.name = $2; + $$->set_variable.value = *$4; + free($2); + delete $4; + } + ; + opt_semicolon: /*empty*/ | SEMICOLON ; diff --git a/src/observer/sql/stmt/create_table_stmt.cpp b/src/observer/sql/stmt/create_table_stmt.cpp index 82d1073..69a8c45 100644 --- a/src/observer/sql/stmt/create_table_stmt.cpp +++ b/src/observer/sql/stmt/create_table_stmt.cpp @@ -13,9 +13,11 @@ See the Mulan PSL v2 for more details. */ // #include "sql/stmt/create_table_stmt.h" +#include "event/sql_debug.h" RC CreateTableStmt::create(Db *db, const CreateTable &create_table, Stmt *&stmt) { stmt = new CreateTableStmt(create_table.relation_name, create_table.attr_infos); + sql_debug("create table statement: table name %s", create_table.relation_name.c_str()); return RC::SUCCESS; } diff --git a/src/observer/sql/stmt/set_variable_stmt.h b/src/observer/sql/stmt/set_variable_stmt.h new file mode 100644 index 0000000..58cacaf --- /dev/null +++ b/src/observer/sql/stmt/set_variable_stmt.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. +miniob is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. */ + +// +// Created by Wangyunlai on 2023/6/29. +// + +#pragma once + +#include +#include + +#include "sql/stmt/stmt.h" + +/** + * @brief SetVairable 语句,设置变量,当前是会话变量,但是只有会话变量,没有全局变量 + * @ingroup Statement + */ +class SetVariableStmt : public Stmt +{ +public: + SetVariableStmt(const SetVariable &set_variable) : set_variable_(set_variable) + {} + virtual ~SetVariableStmt() = default; + + StmtType type() const override { return StmtType::SET_VARIABLE; } + + const char *var_name() const { return set_variable_.name.c_str(); } + const Value &var_value() const { return set_variable_.value; } + + static RC create(const SetVariable &set_variable, Stmt *&stmt) + { + /// 可以校验是否存在某个变量,但是这里忽略 + stmt = new SetVariableStmt(set_variable); + return RC::SUCCESS; + } + +private: + SetVariable set_variable_; +}; \ No newline at end of file diff --git a/src/observer/sql/stmt/stmt.cpp b/src/observer/sql/stmt/stmt.cpp index 8bb3d66..f5f5085 100644 --- a/src/observer/sql/stmt/stmt.cpp +++ b/src/observer/sql/stmt/stmt.cpp @@ -26,6 +26,7 @@ See the Mulan PSL v2 for more details. */ #include "sql/stmt/trx_begin_stmt.h" #include "sql/stmt/trx_end_stmt.h" #include "sql/stmt/exit_stmt.h" +#include "sql/stmt/set_variable_stmt.h" RC Stmt::create_stmt(Db *db, const Command &cmd, Stmt *&stmt) { @@ -79,6 +80,10 @@ RC Stmt::create_stmt(Db *db, const Command &cmd, Stmt *&stmt) return ExitStmt::create(stmt); } + case SCF_SET_VARIABLE: { + return SetVariableStmt::create(cmd.set_variable, stmt); + } + default: { LOG_INFO("Command::type %d doesn't need to create statement.", cmd.flag); } break; diff --git a/src/observer/sql/stmt/stmt.h b/src/observer/sql/stmt/stmt.h index bdfbf1c..5c50719 100644 --- a/src/observer/sql/stmt/stmt.h +++ b/src/observer/sql/stmt/stmt.h @@ -48,7 +48,8 @@ class Db; DEFINE_ENUM_ITEM(HELP) \ DEFINE_ENUM_ITEM(EXIT) \ DEFINE_ENUM_ITEM(EXPLAIN) \ - DEFINE_ENUM_ITEM(PREDICATE) + DEFINE_ENUM_ITEM(PREDICATE) \ + DEFINE_ENUM_ITEM(SET_VARIABLE) enum class StmtType { #define DEFINE_ENUM_ITEM(name) name, diff --git a/src/observer/storage/field/field.h b/src/observer/storage/field/field.h index c2bf15b..00a7053 100644 --- a/src/observer/storage/field/field.h +++ b/src/observer/storage/field/field.h @@ -17,6 +17,10 @@ See the Mulan PSL v2 for more details. */ #include "storage/table/table.h" #include "storage/field/field_meta.h" +/** + * @brief 字段 + * + */ class Field { public: diff --git a/src/observer/storage/field/field_meta.h b/src/observer/storage/field/field_meta.h index 968d94e..e0aec4b 100644 --- a/src/observer/storage/field/field_meta.h +++ b/src/observer/storage/field/field_meta.h @@ -23,7 +23,10 @@ namespace Json { class Value; } // namespace Json -// Take care of shallow copy +/** + * @brief 字段元数据 + * + */ class FieldMeta { public: diff --git a/src/observer/storage/index/bplus_tree.h b/src/observer/storage/index/bplus_tree.h index 345111e..7594ce7 100644 --- a/src/observer/storage/index/bplus_tree.h +++ b/src/observer/storage/index/bplus_tree.h @@ -34,9 +34,6 @@ See the Mulan PSL v2 for more details. */ * @defgroup BPlusTree */ -#define EMPTY_RID_PAGE_NUM -1 // TODO remove me -#define EMPTY_RID_SLOT_NUM -1 - /** * @brief B+树的操作类型 * @ingroup BPlusTree @@ -49,7 +46,7 @@ enum class BplusTreeOperationType }; /** - * @brief 属性比较 + * @brief 属性比较(BplusTree) * @ingroup BPlusTree */ class AttrComparator @@ -91,7 +88,8 @@ private: }; /** - * @brief 键值比较 + * @brief 键值比较(BplusTree) + * @details BplusTree的键值除了字段属性,还有RID,是为了避免属性值重复而增加的。 * @ingroup BPlusTree */ class KeyComparator @@ -124,7 +122,7 @@ private: }; /** - * @brief 属性打印,调试使用 + * @brief 属性打印,调试使用(BplusTree) * @ingroup BPlusTree */ class AttrPrinter @@ -173,7 +171,7 @@ private: }; /** - * @brief 键值打印,调试使用 + * @brief 键值打印,调试使用(BplusTree) * @ingroup BPlusTree */ class KeyPrinter @@ -358,8 +356,7 @@ public: /** * 查找指定key的插入位置(注意不是key本身) - * 如果key已经存在,会设置found的值 - * NOTE: 当前lookup的实现效率非常低,你是否可以优化它? + * 如果key已经存在,会设置found的值。 */ int lookup(const KeyComparator &comparator, const char *key, bool *found = nullptr) const; @@ -418,11 +415,10 @@ public: /** * 与Leaf节点不同,lookup返回指定key应该属于哪个子节点,返回这个子节点在当前节点中的索引 * 如果想要返回插入位置,就提供 `insert_position` 参数 - * @param comparator 用于键值比较的函数 - * @param key 查找的键值 - * @param found 如果是有效指针,将会返回当前是否存在指定的键值 - * @param insert_position 如果是有效指针,将会返回可以插入指定键值的位置 - * NOTE: 查找效率不高,你可以优化它吗? + * @param[in] comparator 用于键值比较的函数 + * @param[in] key 查找的键值 + * @param[out] found 如果是有效指针,将会返回当前是否存在指定的键值 + * @param[out] insert_position 如果是有效指针,将会返回可以插入指定键值的位置 */ int lookup(const KeyComparator &comparator, const char *key, diff --git a/src/observer/storage/table/table.h b/src/observer/storage/table/table.h index caadb94..741e48f 100644 --- a/src/observer/storage/table/table.h +++ b/src/observer/storage/table/table.h @@ -29,7 +29,10 @@ class IndexScanner; class RecordDeleter; class Trx; -// TODO remove the routines with condition +/** + * @brief 表 + * + */ class Table { public: diff --git a/src/observer/storage/table/table_meta.h b/src/observer/storage/table/table_meta.h index 73e20b6..0108e95 100644 --- a/src/observer/storage/table/table_meta.h +++ b/src/observer/storage/table/table_meta.h @@ -22,6 +22,10 @@ See the Mulan PSL v2 for more details. */ #include "storage/index/index_meta.h" #include "common/lang/serializable.h" +/** + * @brief 表元数据 + * + */ class TableMeta : public common::Serializable { public: diff --git a/src/observer/storage/trx/mvcc_trx.h b/src/observer/storage/trx/mvcc_trx.h index f4dd3af..47c40fd 100644 --- a/src/observer/storage/trx/mvcc_trx.h +++ b/src/observer/storage/trx/mvcc_trx.h @@ -55,8 +55,9 @@ private: }; /** + * @brief 多版本并发事务 + * @ingroup Transaction * TODO 没有垃圾回收 - * */ class MvccTrx : public Trx { -- GitLab