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

Train debug (#203)

### 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
上级 99da0457
......@@ -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}/"
}
]
......
......@@ -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
}
......
......@@ -25,15 +25,13 @@ See the Mulan PSL v2 for more details. */
#include <map>
#include <set>
#include <string>
#include <functional>
#include <functional>
#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<intptr_t()> 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<intptr_t()> context_getter);
extern std::function<intptr_t()> g_context_getter;
} // namespace common
本篇文档介绍 MiniOB 中的事务模块是如何工作的。
# 背景
事务是数据库中非常基础的一个模块,也是非常核心的功能。事务有一些基本的概念,叫做ACID,分别是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。如果你对事务的基本概念不太清楚,建议先学习了解事务的基本概念,比如学习[事务处理](lectures/lecture-6.md)章节,或者在网上搜索更多资料。
事务是数据库中非常基础的一个模块,也是非常核心的功能。事务有一些基本的概念,叫做ACID,分别是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。如果你对事务的基本概念不太清楚,建议先学习了解事务的基本概念,比如学习[事务处理](../lectures/lecture-6.md)章节,或者在网上搜索更多资料。
# MiniOB 中的事务
## 实现简介
......
本篇文档介绍如何向[训练营](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
......@@ -21,6 +21,9 @@
训练营的使用方法比较简单,不过这里也有一个小手册:
[训练营使用手册](https://ask.oceanbase.com/t/topic/35600372)
为了方便大家使用训练营时获取调试信息,这里有一个小手册:
[训练营调试输出手册](./debug-output.md)
注意,在训练营开始前,需要注意自己的程序输出需要满足一定的要求,请参考:
[提交测试需要满足的输出要求](./miniob-output-convention.md)
......
......@@ -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
......
......@@ -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
......
......@@ -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语句
};
/* 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 <stdarg.h>
#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<string> &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;
}
/* 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 <list>
#include <string>
/**
* @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<std::string> &get_debug_infos() const;
private:
std::list<std::string> debug_infos_;
};
/**
* @brief 增加SQL的调试信息
* @details 可以在任何执行SQL语句时调用这个函数来增加调试信息。
* 如果当前上下文不在SQL执行过程中,那么不会生成调试信息。
* 在普通文本场景下,调试信息会直接输出到客户端,并增加 '#' 作为前缀。
*/
void sql_debug(const char *fmt, ...);
......@@ -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> command_;
Stmt *stmt_ = nullptr;
std::unique_ptr<PhysicalOperator> operator_;
std::string sql_; ///< 处理的SQL语句
std::unique_ptr<Command> command_; ///< 语法解析后的SQL命令
Stmt *stmt_ = nullptr; ///< Resolver之后生成的数据结构
std::unique_ptr<PhysicalOperator> operator_; ///< 生成的执行计划,也可能没有
};
......@@ -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;
......
......@@ -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<std::string> &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
......@@ -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<char> send_message_delimiter_; ///< 发送消息分隔符
std::vector<char> debug_message_prefix_; ///< 调试信息前缀
};
......@@ -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_;
}
......@@ -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 &current();
/**
* @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调试信息
};
......@@ -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);
}
......@@ -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;
}
......
......@@ -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
......@@ -26,7 +26,7 @@ class SelectStmt;
* @brief 执行SQL语句的Stage,包括DML和DDL
* @ingroup SQLStage
* @details 根据前面阶段生成的结果,有些语句会生成执行计划,有些不会。
* 整体上分为两类,带执行计划的,或者 @class CommandExecutor 可以直接执行的。
* 整体上分为两类,带执行计划的,或者 CommandExecutor 可以直接执行的。
*/
class ExecuteStage : public common::Stage
{
......
/* 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
......@@ -24,7 +24,8 @@ class Session;
/**
* @brief SQL执行结果
* @details 如果当前SQL生成了执行计划,那么在返回客户端时,调用执行计划返回结果。
* @details
* 如果当前SQL生成了执行计划,那么在返回客户端时,调用执行计划返回结果。
* 否则返回的结果就是当前SQL的执行结果,比如DDL语句,通过return_code和state_string来描述。
* 如果出现了一些错误,也可以通过return_code和state_string来获取信息。
*/
......
......@@ -16,6 +16,7 @@ See the Mulan PSL v2 for more details. */
#include <memory>
#include <vector>
#include <string>
#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<TupleCellSpec> 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<FieldExpr *> 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:
......
......@@ -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;
}
}
......
......@@ -19,6 +19,12 @@ See the Mulan PSL v2 for more details. */
class LogicalOperator;
/**
* @brief 简单比较的重写规则
* @ingroup Rewriter
* @details 如果有简单的比较运算,比如比较的两边都是常量,那我们就可以在运行执行计划之前就知道结果,
* 进而直接将表达式改成结果,这样就可以减少运行时的计算量。
*/
class ComparisonSimplificationRule : public ExpressionRewriteRule
{
public:
......
......@@ -19,8 +19,9 @@ See the Mulan PSL v2 for more details. */
class LogicalOperator;
/**
* 简化多个表达式联结的运算
* 比如只有一个表达式,或者表达式可以直接出来
* @brief 简化多个表达式联结的运算
* @ingroup Rewriter
* @details 比如只有一个表达式,或者表达式可以直接出来
*/
class ConjunctionSimplificationRule : public ExpressionRewriteRule
{
......
......@@ -28,7 +28,14 @@ class DeleteLogicalOperator;
class ExplainLogicalOperator;
class JoinLogicalOperator;
class PhysicalPlanGenerator {
/**
* @brief 物理计划生成器
* @ingroup PhysicalOperator
* @details 根据逻辑计划生成物理计划。
* 不会做任何优化,完全根据本意生成物理计划。
*/
class PhysicalPlanGenerator
{
public:
PhysicalPlanGenerator() = default;
virtual ~PhysicalPlanGenerator() = default;
......
......@@ -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
{
......
......@@ -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:
......
......@@ -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<LogicalOperator> &oper, bool &change_made) = 0;
};
/**
* @brief 表达式的重写规则
* @ingroup Rewriter
*/
class ExpressionRewriteRule
{
public:
......
......@@ -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<LogicalOperator> &oper, bool &change_made);
private:
......
......@@ -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<std::unique_ptr<Command>> sql_commands_; /// 这里记录SQL命令。虽然看起来支持多个,但是当前仅处理一个
std::vector<std::unique_ptr<Command>> sql_commands_; ///< 这里记录SQL命令。虽然看起来支持多个,但是当前仅处理一个
};
......@@ -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
......
......@@ -14,6 +14,8 @@ See the Mulan PSL v2 for more details. */
#pragma once
#include <string>
/**
* @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;
......
......@@ -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<Command> sql_command = std::unique_ptr<Command>((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>;
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<Condition>;
(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<Command>((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);
......
......@@ -132,6 +132,7 @@ int yyerror(YYLTYPE *llocp, ParsedSqlResult *sql_result, yyscan_t scanner, const
%type <command> rollback
%type <command> load_data
%type <command> explain
%type <command> set_variable
%type <command> help
%type <command> exit
%type <command> 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
;
......
......@@ -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;
}
......@@ -9,35 +9,39 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/6/7.
// Created by Wangyunlai on 2023/6/29.
//
#pragma once
#include "common/seda/stage_event.h"
#include <string>
#include <vector>
class SQLStageEvent;
class Stmt;
#include "sql/stmt/stmt.h"
class OptimizeEvent : public common::StageEvent {
/**
* @brief SetVairable 语句,设置变量,当前是会话变量,但是只有会话变量,没有全局变量
* @ingroup Statement
*/
class SetVariableStmt : public Stmt
{
public:
OptimizeEvent(SQLStageEvent *sql_event, common::StageEvent *parent_event)
: sql_event_(sql_event), parent_event_(parent_event)
SetVariableStmt(const SetVariable &set_variable) : set_variable_(set_variable)
{}
virtual ~SetVariableStmt() = default;
virtual ~OptimizeEvent() noexcept = default;
StmtType type() const override { return StmtType::SET_VARIABLE; }
SQLStageEvent *sql_event() const
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)
{
return sql_event_;
}
common::StageEvent *parent_event() const
{
return parent_event_;
/// 可以校验是否存在某个变量,但是这里忽略
stmt = new SetVariableStmt(set_variable);
return RC::SUCCESS;
}
private:
SQLStageEvent *sql_event_ = nullptr;
common::StageEvent *parent_event_ = nullptr;
};
SetVariable set_variable_;
};
\ No newline at end of file
......@@ -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;
......
......@@ -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,
......
......@@ -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:
......
......@@ -23,7 +23,10 @@ namespace Json {
class Value;
} // namespace Json
// Take care of shallow copy
/**
* @brief 字段元数据
*
*/
class FieldMeta
{
public:
......
......@@ -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,
......
......@@ -29,7 +29,10 @@ class IndexScanner;
class RecordDeleter;
class Trx;
// TODO remove the routines with condition
/**
* @brief 表
*
*/
class Table
{
public:
......
......@@ -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:
......
......@@ -55,8 +55,9 @@ private:
};
/**
* @brief 多版本并发事务
* @ingroup Transaction
* TODO 没有垃圾回收
*
*/
class MvccTrx : public Trx
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册