提交 118ffa6d 编写于 作者: W wangyunlai.wyl

first step

上级 2e5fe7fa
./deps/libevent/*
./deps/googletest/*
./deps/jsoncpp/*
./deps/libevent
./deps/googletest
./deps/jsoncpp
build/*
cmake-build-*/*
.vscode/*
......@@ -12,3 +12,6 @@ compile_commands.json
./vcs.xml
./workspace.xml
./modules.xml
GRTAGS
GPATH
GTAGS
......@@ -29,17 +29,20 @@ RUN wget http://yum-test.obvos.alibaba-inc.com/oceanbase/development-kit/el/7/x8
RUN git clone https://github.com/libevent/libevent -b release-2.1.12-stable \
&& mkdir -p ${HOME_DIR}/deps/libevent/build \
&& cmake -DEVENT__DISABLE_OPENSSL=ON -B ${HOME_DIR}/deps/libevent/build ${HOME_DIR}/deps/libevent && make -C ${HOME_DIR}/deps/libevent/build -j install \
&& cmake -DEVENT__DISABLE_OPENSSL=ON -B ${HOME_DIR}/deps/libevent/build ${HOME_DIR}/deps/libevent \
&& make -C ${HOME_DIR}/deps/libevent/build -j install \
&& rm -rf ${HOME_DIR}/deps/*
RUN git clone https://github.com/open-source-parsers/jsoncpp.git \
&& mkdir -p ${HOME_DIR}/deps/jsoncpp/build \
&& cmake -DJSONCPP_WITH_TESTS=OFF -DJSONCPP_WITH_POST_BUILD_UNITTEST=OFF -B ${HOME_DIR}/deps/jsoncpp/build ${HOME_DIR}/deps/jsoncpp/ && make -C ${HOME_DIR}/deps/jsoncpp/build -j install \
&& cmake -DJSONCPP_WITH_TESTS=OFF -DJSONCPP_WITH_POST_BUILD_UNITTEST=OFF -B ${HOME_DIR}/deps/jsoncpp/build ${HOME_DIR}/deps/jsoncpp/ \
&& make -C ${HOME_DIR}/deps/jsoncpp/build -j install \
&& rm -rf ${HOME_DIR}/deps/*
RUN git clone https://github.com/google/googletest \
&& mkdir -p ${HOME_DIR}/deps/googletest/build \
&& cmake -B ${HOME_DIR}/deps/googletest/build ${HOME_DIR}/deps/googletest && make -C ${HOME_DIR}/deps/googletest/build -j install \
&& cmake -B ${HOME_DIR}/deps/googletest/build ${HOME_DIR}/deps/googletest \
&& make -C ${HOME_DIR}/deps/googletest/build -j install \
&& rm -rf ${HOME_DIR}/deps/*
RUN wget http://ftp.gnu.org/gnu/bison/bison-3.7.tar.gz \
......
googletest @ b1f84bf1
Subproject commit b1f84bf1763b1010597bff13c79b5388eebdf205
jsoncpp @ 42e892d9
Subproject commit 42e892d96e47b1f6e29844cc705e148ec4856448
libevent @ 5df3037d
Subproject commit 5df3037d10556bfcb675bc73e516978b75fc7bc7
......@@ -57,21 +57,22 @@ count=3
[SessionStage]
ThreadId=SQLThreads
NextStages=ResolveStage
NextStages=PlanCacheStage
[ResolveStage]
[PlanCacheStage]
ThreadId=SQLThreads
NextStages=QueryCacheStage
#NextStages=OptimizeStage
NextStages=ParseStage
[QueryCacheStage]
[ParseStage]
ThreadId=SQLThreads
NextStages=PlanCacheStage
NextStages=ResolveStage
[PlanCacheStage]
[ResolveStage]
ThreadId=SQLThreads
NextStages=ExecuteStage,ParseStage
NextStages=QueryCacheStage
[ParseStage]
[QueryCacheStage]
ThreadId=SQLThreads
NextStages=OptimizeStage
......
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Longda on 2021/4/14.
//
#include "event/sql_event.h"
#include "event/session_event.h"
SQLStageEvent::SQLStageEvent(SessionEvent *event, const std::string &sql) : session_event_(event), sql_(sql)
{}
SQLStageEvent::~SQLStageEvent() noexcept
{
if (session_event_ != nullptr) {
session_event_ = nullptr;
// SessionEvent *session_event = session_event_;
// session_event_ = nullptr;
// session_event->doneImmediate();
}
}
......@@ -12,32 +12,32 @@ See the Mulan PSL v2 for more details. */
// Created by Wangyunlai on 2021/5/11.
//
#ifndef __OBSERVER_EVENT_EXECUTION_PLAN_EVENT_H__
#define __OBSERVER_EVENT_EXECUTION_PLAN_EVENT_H__
#pragma once
#include "common/seda/stage_event.h"
#include "sql/parser/parse.h"
class SQLStageEvent;
class ExecutionPlanEvent : public common::StageEvent {
class ExecutePlanEvent : public common::StageEvent {
public:
ExecutionPlanEvent(SQLStageEvent *sql_event, Query *sqls);
virtual ~ExecutionPlanEvent();
ExecutePlanEvent(SQLStageEvent *sql_event, common::StageEvent *parent_event)
: sql_event_(sql_event), parent_event_(parent_event)
{}
Query *sqls() const
{
return sqls_;
}
virtual ~ExecutePlanEvent() = default;
SQLStageEvent *sql_event() const
{
return sql_event_;
}
common::StageEvent *parent_event() const {
return parent_event_;
}
private:
SQLStageEvent *sql_event_;
Query *sqls_;
SQLStageEvent *sql_event_ = nullptr;
common::StageEvent *parent_event_ = nullptr;
};
#endif // __OBSERVER_EVENT_EXECUTION_PLAN_EVENT_H__
\ No newline at end of file
#endif // __OBSERVER_EVENT_EXECUTION_PLAN_EVENT_H__
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/6/7.
//
#pragma once
#include "common/seda/stage_event.h"
class SQLStageEvent;
class Stmt;
class OptimizeEvent : public common::StageEvent {
public:
OptimizeEvent(SQLStageEvent *sql_event, common::StageEvent *parent_event)
: sql_event_(sql_event), parent_event_(parent_event)
{}
virtual ~OptimizeEvent() noexcept = default;
SQLStageEvent *sql_event() const {
return sql_event_;
}
common::StageEvent *parent_event() const {
return parent_event_;
}
private:
SQLStageEvent *sql_event_ = nullptr;
common::StageEvent *parent_event_ = nullptr;
};
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/23.
//
#pragma once
#include "common/seda/stage_event.h"
class SQLStageEvent;
class Stmt;
class QueryCacheEvent : public common::StageEvent {
public:
QueryCacheEvent(SQLStageEvent *sql_event, common::StageEvent *parent_event)
: sql_event_(sql_event), parent_event_(parent_event)
{}
virtual ~QueryCacheEvent() noexcept = default;
SQLStageEvent *sql_event() const {
return sql_event_;
}
common::StageEvent *parent_event() const {
return parent_event_;
}
private:
SQLStageEvent *sql_event_ = nullptr;
common::StageEvent *parent_event_ = nullptr;
};
......@@ -9,20 +9,15 @@ MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Longda on 2021/4/14.
// Created by Wangyunlai on 2022/5/23.
//
#include "event/storage_event.h"
#include "event/execution_plan_event.h"
#include "event/resolve_event.h"
#include "event/session_event.h"
StorageEvent::StorageEvent(ExecutionPlanEvent *exe_event) : exe_event_(exe_event)
ResolveStageEvent(SessionEvent *event) : session_event_(event)
{}
StorageEvent::~StorageEvent()
ResolveStageEvent::~ResolveStageEvent() noexcept
{
exe_event_ = nullptr;
// if (exe_event_ != nullptr) {
// ExecutionPlanEvent *exe_event = exe_event_;
// exe_event->doneImmediate();
// }
}
\ No newline at end of file
}
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/23.
//
#pragma once
#include "common/seda/stage_event.h"
class SessionEvent;
class Stmt;
class ResolveStageEvent : public BaseEvent {
public:
ResolveStageEvent(SessionEvent *event);
virtual ~ResolveStageEvent() noexcept;
SessionEvent *session_event() const
{
return session_event_;
}
private:
SessionEvent *session_event_ = nullptr;
};
......@@ -15,16 +15,23 @@ See the Mulan PSL v2 for more details. */
#include "session_event.h"
SessionEvent::SessionEvent(ConnectionContext *client) : client_(client)
{}
{
}
SessionEvent::~SessionEvent()
{}
{
}
ConnectionContext *SessionEvent::get_client() const
{
return client_;
}
Session *SessionEvent::session() const
{
return client_->session;
}
const char *SessionEvent::get_response() const
{
return response_.c_str();
......@@ -58,4 +65,4 @@ char *SessionEvent::get_request_buf()
int SessionEvent::get_request_buf_len()
{
return SOCKET_BUFFER_SIZE;
}
\ No newline at end of file
}
......@@ -21,12 +21,15 @@ See the Mulan PSL v2 for more details. */
#include "common/seda/stage_event.h"
#include "net/connection_context.h"
class Session;
class SessionEvent : public common::StageEvent {
public:
SessionEvent(ConnectionContext *client);
virtual ~SessionEvent();
ConnectionContext *get_client() const;
Session *session() const;
const char *get_response() const;
void set_response(const char *response);
......
......@@ -15,7 +15,7 @@ See the Mulan PSL v2 for more details. */
#include "event/sql_event.h"
#include "event/session_event.h"
SQLStageEvent::SQLStageEvent(SessionEvent *event, std::string &sql) : session_event_(event), sql_(sql)
SQLStageEvent::SQLStageEvent(SessionEvent *event, const std::string &sql) : session_event_(event), sql_(sql)
{}
SQLStageEvent::~SQLStageEvent() noexcept
......@@ -26,4 +26,4 @@ SQLStageEvent::~SQLStageEvent() noexcept
// session_event_ = nullptr;
// session_event->doneImmediate();
}
}
\ No newline at end of file
}
......@@ -15,30 +15,37 @@ See the Mulan PSL v2 for more details. */
#ifndef __OBSERVER_SQL_EVENT_SQLEVENT_H__
#define __OBSERVER_SQL_EVENT_SQLEVENT_H__
#include "common/seda/stage_event.h"
#include <string>
#include "common/seda/stage_event.h"
class SessionEvent;
class Stmt;
struct Query;
class SQLStageEvent : public common::StageEvent {
class SQLStageEvent : public common::StageEvent
{
public:
SQLStageEvent(SessionEvent *event, std::string &sql);
SQLStageEvent(SessionEvent *event, const std::string &sql);
virtual ~SQLStageEvent() noexcept;
const std::string &get_sql() const
{
return sql_;
}
SessionEvent *session_event() const
{
return session_event_;
}
const std::string &sql() const { return sql_; }
Query *query() const { return query_; }
Stmt *stmt() const { return stmt_; }
void set_sql(const char *sql) { sql_ = sql; }
void set_query(Query *query) { query_ = query; }
void set_stmt(Stmt *stmt) { stmt_ = stmt; }
private:
SessionEvent *session_event_;
std::string &sql_;
// void *context_;
SessionEvent *session_event_ = nullptr;
std::string sql_;
Query *query_ = nullptr;
Stmt *stmt_ = nullptr;
};
#endif //__SRC_OBSERVER_SQL_EVENT_SQLEVENT_H__
......@@ -17,20 +17,22 @@ See the Mulan PSL v2 for more details. */
#include "common/seda/stage_event.h"
class ExecutionPlanEvent;
class SQLStageEvent;
class StorageEvent : public common::StageEvent {
public:
StorageEvent(ExecutionPlanEvent *exe_event);
StorageEvent(SQLStageEvent *sql_event) : sql_event_(sql_event)
{}
virtual ~StorageEvent();
ExecutionPlanEvent *exe_event() const
SQLStageEvent *sql_event() const
{
return exe_event_;
return sql_event_;
}
private:
ExecutionPlanEvent *exe_event_;
SQLStageEvent *sql_event_;
};
#endif //__OBSERVER_SQL_EVENT_STORAGEEVENT_H__
......@@ -24,6 +24,7 @@ const char *strrc(RC rc)
RC_CASE_STRING(SUCCESS);
RC_CASE_STRING(GENERIC_ERROR);
RC_CASE_STRING(INVALID_ARGUMENT);
RC_CASE_STRING(UNIMPLENMENT);
RC_CASE_STRING(SQL_SYNTAX);
RC_CASE_STRING(BUFFERPOOL);
RC_CASE_STRING(RECORD);
......@@ -179,4 +180,4 @@ const char *strrc(RC rc)
return "UNKNOWN";
}
}
}
\ No newline at end of file
}
......@@ -172,10 +172,11 @@ enum RC {
/* beginning-of-error-codes */
GENERIC_ERROR, /* Generic error */
INVALID_ARGUMENT, /* Invalid argument */
UNIMPLENMENT, /* not implenment yet */
SQL_SYNTAX, /* SQL Syntax error */
BUFFERPOOL, /* Buffer pool error*/
RECORD, /* Record error */
INTERNAL, /* Internal logic error in SQLite */
INTERNAL, /* Internal logic error in SQL */
PERM, /* Access permission denied */
ABORT, /* Callback routine requested an abort */
BUSY, /* The database file is locked */
......
......@@ -14,6 +14,8 @@ See the Mulan PSL v2 for more details. */
#include "session/session.h"
#include "storage/trx/trx.h"
#include "storage/common/db.h"
#include "storage/default/default_handler.h"
Session &Session::default_session()
{
......@@ -21,7 +23,7 @@ Session &Session::default_session()
return session;
}
Session::Session(const Session &other) : current_db_(other.current_db_)
Session::Session(const Session &other) : db_(other.db_)
{}
Session::~Session()
......@@ -30,13 +32,30 @@ Session::~Session()
trx_ = nullptr;
}
const std::string &Session::get_current_db() const
const char *Session::get_current_db_name() const
{
return current_db_;
if (db_ != nullptr)
return db_->name();
else
return "";
}
Db *Session::get_current_db() const
{
return db_;
}
void Session::set_current_db(const std::string &dbname)
{
current_db_ = dbname;
DefaultHandler &handler = DefaultHandler::get_default();
Db *db = handler.find_db(dbname.c_str());
if (db == nullptr) {
LOG_WARN("no such database: %s", dbname.c_str());
return;
}
LOG_TRACE("change db to %s", dbname.c_str());
db_ = db;
}
void Session::set_trx_multi_operation_mode(bool multi_operation_mode)
......
......@@ -12,12 +12,12 @@ See the Mulan PSL v2 for more details. */
// Created by Wangyunlai on 2021/5/12.
//
#ifndef __OBSERVER_SESSION_SESSION_H__
#define __OBSERVER_SESSION_SESSION_H__
#pragma once
#include <string>
class Trx;
class Db;
class Session {
public:
......@@ -31,7 +31,9 @@ public:
Session(const Session &other);
void operator=(Session &) = delete;
const std::string &get_current_db() const;
const char *get_current_db_name() const;
Db *get_current_db() const;
void set_current_db(const std::string &dbname);
void set_trx_multi_operation_mode(bool multi_operation_mode);
......@@ -40,9 +42,7 @@ public:
Trx *current_trx();
private:
std::string current_db_;
Db *db_ = nullptr;
Trx *trx_ = nullptr;
bool trx_multi_operation_mode_ = false; // 当前事务的模式,是否多语句模式. 单语句模式自动提交
};
#endif // __OBSERVER_SESSION_SESSION_H__
\ No newline at end of file
......@@ -34,7 +34,7 @@ using namespace common;
const std::string SessionStage::SQL_METRIC_TAG = "SessionStage.sql";
// Constructor
SessionStage::SessionStage(const char *tag) : Stage(tag), resolve_stage_(nullptr), sql_metric_(nullptr)
SessionStage::SessionStage(const char *tag) : Stage(tag), plan_cache_stage_(nullptr), sql_metric_(nullptr)
{}
// Destructor
......@@ -73,7 +73,7 @@ bool SessionStage::initialize()
LOG_TRACE("Enter");
std::list<Stage *>::iterator stgp = next_stage_list_.begin();
resolve_stage_ = *(stgp++);
plan_cache_stage_ = *(stgp++);
MetricsRegistry &metricsRegistry = get_metrics_registry();
sql_metric_ = new SimpleTimer();
......@@ -138,7 +138,6 @@ void SessionStage::callback_event(StageEvent *event, CallbackContext *context)
void SessionStage::handle_request(StageEvent *event)
{
SessionEvent *sev = dynamic_cast<SessionEvent *>(event);
if (nullptr == sev) {
LOG_ERROR("Cannot cat event to sessionEvent");
......@@ -169,5 +168,5 @@ void SessionStage::handle_request(StageEvent *event)
sev->push_callback(cb);
SQLStageEvent *sql_event = new SQLStageEvent(sev, sql);
resolve_stage_->handle_event(sql_event);
plan_cache_stage_->handle_event(sql_event);
}
......@@ -47,8 +47,8 @@ protected:
void handle_request(common::StageEvent *event);
private:
Stage *resolve_stage_;
common::SimpleTimer *sql_metric_;
Stage *plan_cache_stage_ = nullptr;
common::SimpleTimer *sql_metric_ = nullptr;
static const std::string SQL_METRIC_TAG;
};
......
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by WangYunlai on 2021/6/9.
//
#pragma once
#include "sql/parser/parse.h"
#include "rc.h"
class DeleteStmt;
class DeleteOperator : public Operator
{
public:
DeleteOperator(DeleteStmt *delete_stmt)
: delete_stmt_(delete_stmt)
{}
virtual ~InsertOperator() = default;
RC open() override;
RC next() override;
RC close() override;
private:
InsertStmt *insert_stmt_ = nullptr;
};
......@@ -25,9 +25,14 @@ See the Mulan PSL v2 for more details. */
#include "event/storage_event.h"
#include "event/sql_event.h"
#include "event/session_event.h"
#include "event/execution_plan_event.h"
#include "sql/executor/execution_node.h"
#include "sql/executor/tuple.h"
#include "sql/executor/table_scan_operator.h"
#include "sql/stmt/stmt.h"
#include "sql/stmt/select_stmt.h"
#include "sql/stmt/update_stmt.h"
#include "sql/stmt/delete_stmt.h"
#include "sql/stmt/insert_stmt.h"
#include "storage/common/table.h"
#include "storage/default/default_handler.h"
#include "storage/common/condition_filter.h"
......@@ -108,9 +113,6 @@ void ExecuteStage::callback_event(StageEvent *event, CallbackContext *context)
LOG_TRACE("Enter\n");
// here finish read all data from disk or network, but do nothing here.
ExecutionPlanEvent *exe_event = static_cast<ExecutionPlanEvent *>(event);
SQLStageEvent *sql_event = exe_event->sql_event();
sql_event->done_immediate();
LOG_TRACE("Exit\n");
return;
......@@ -118,88 +120,83 @@ void ExecuteStage::callback_event(StageEvent *event, CallbackContext *context)
void ExecuteStage::handle_request(common::StageEvent *event)
{
ExecutionPlanEvent *exe_event = static_cast<ExecutionPlanEvent *>(event);
SessionEvent *session_event = exe_event->sql_event()->session_event();
Query *sql = exe_event->sqls();
const char *current_db = session_event->get_client()->session->get_current_db().c_str();
CompletionCallback *cb = new (std::nothrow) CompletionCallback(this, nullptr);
if (cb == nullptr) {
LOG_ERROR("Failed to new callback for ExecutionPlanEvent");
exe_event->done_immediate();
return;
SQLStageEvent *sql_event = static_cast<SQLStageEvent *>(event);
SessionEvent *session_event = sql_event->session_event();
Stmt *stmt = sql_event->stmt();
Session *session = session_event->session();
Db *current_db = session->get_current_db();
Query *sql = sql_event->query();
if (stmt != nullptr) {
switch (stmt->type()) {
case StmtType::SELECT: {
do_select((SelectStmt *)stmt, session_event);
} break;
case StmtType::UPDATE: {
//do_update((UpdateStmt *)stmt, session_event);
} break;
case StmtType::DELETE: {
//do_delete((DeleteStmt *)stmt, session_event);
} break;
}
} else {
switch (sql->flag) {
case SCF_HELP: {
do_help(sql_event);
} break;
case SCF_CREATE_TABLE: {
do_create_table(sql_event);
} break;
case SCF_CREATE_INDEX: {
do_create_index(sql_event);
} break;
case SCF_SHOW_TABLES: {
do_show_tables(sql_event);
} break;
case SCF_DESC_TABLE: {
do_desc_table(sql_event);
} break;
}
}
exe_event->push_callback(cb);
switch (sql->flag) {
case SCF_SELECT: { // select
do_select(current_db, sql, exe_event->sql_event()->session_event());
exe_event->done_immediate();
} break;
//case SCF_SELECT: { // select
// do_select(current_db, sql, exe_event->sql_event()->session_event());
// exe_event->done_immediate();
//} bre
case SCF_INSERT:
case SCF_UPDATE:
case SCF_DELETE:
case SCF_CREATE_TABLE:
case SCF_SHOW_TABLES:
case SCF_DESC_TABLE:
case SCF_DROP_TABLE:
case SCF_CREATE_INDEX:
case SCF_DROP_INDEX:
case SCF_LOAD_DATA: {
StorageEvent *storage_event = new (std::nothrow) StorageEvent(exe_event);
if (storage_event == nullptr) {
LOG_ERROR("Failed to new StorageEvent");
event->done_immediate();
return;
}
default_storage_stage_->handle_event(storage_event);
default_storage_stage_->handle_event(event);
} break;
case SCF_SYNC: {
RC rc = DefaultHandler::get_default().sync();
session_event->set_response(strrc(rc));
exe_event->done_immediate();
} break;
case SCF_BEGIN: {
session_event->get_client()->session->set_trx_multi_operation_mode(true);
session->set_trx_multi_operation_mode(true);
session_event->set_response(strrc(RC::SUCCESS));
exe_event->done_immediate();
} break;
case SCF_COMMIT: {
Trx *trx = session_event->get_client()->session->current_trx();
Trx *trx = session->current_trx();
RC rc = trx->commit();
session_event->get_client()->session->set_trx_multi_operation_mode(false);
session->set_trx_multi_operation_mode(false);
session_event->set_response(strrc(rc));
exe_event->done_immediate();
} break;
case SCF_ROLLBACK: {
Trx *trx = session_event->get_client()->session->current_trx();
RC rc = trx->rollback();
session_event->get_client()->session->set_trx_multi_operation_mode(false);
session->set_trx_multi_operation_mode(false);
session_event->set_response(strrc(rc));
exe_event->done_immediate();
} break;
case SCF_HELP: {
const char *response = "show tables;\n"
"desc `table name`;\n"
"create table `table name` (`column name` `column type`, ...);\n"
"create index `index name` on `table` (`column`);\n"
"insert into `table` values(`value1`,`value2`);\n"
"update `table` set column=value [where `column`=`value`];\n"
"delete from `table` [where `column`=`value`];\n"
"select [ * | `columns` ] from `table`;\n";
session_event->set_response(response);
exe_event->done_immediate();
} break;
case SCF_EXIT: {
// do nothing
const char *response = "Unsupported\n";
session_event->set_response(response);
exe_event->done_immediate();
} break;
default: {
exe_event->done_immediate();
LOG_ERROR("Unsupported command=%d\n", sql->flag);
}
}
......@@ -216,6 +213,37 @@ void end_trx_if_need(Session *session, Trx *trx, bool all_right)
}
}
RC ExecuteStage::do_select(SelectStmt *select_stmt, SessionEvent *session_event)
{
RC rc = RC::SUCCESS;
if (select_stmt->tables().size() != 1) {
LOG_WARN("select more than 1 tables is not supported");
rc = RC::UNIMPLENMENT;
return rc;
}
Table *table = select_stmt->tables().front();
TableScanOperator table_scan_operator(table);
rc = table_scan_operator.open();
if (rc != RC::SUCCESS) {
LOG_WARN("failed to open operator");
return rc;
}
while ((rc = table_scan_operator.next()) == RC::SUCCESS) {
// get current record
// write to response
}
if (rc != RC::RECORD_EOF) {
LOG_WARN("something wrong while iterate operator. rc=%s", strrc(rc));
table_scan_operator.close();
} else {
rc = table_scan_operator.close();
}
return rc;
}
#if 0
// 这里没有对输入的某些信息做合法性校验,比如查询的列名、where条件中的列名等,没有做必要的合法性校验
// 需要补充上这一部分. 校验部分也可以放在resolve,不过跟execution放一起也没有关系
RC ExecuteStage::do_select(const char *db, Query *sql, SessionEvent *session_event)
......@@ -357,3 +385,83 @@ RC create_selection_executor(
return select_node.init(trx, table, std::move(schema), std::move(condition_filters));
}
#endif
RC ExecuteStage::do_help(SQLStageEvent *sql_event)
{
SessionEvent *session_event = sql_event->session_event();
const char *response = "show tables;\n"
"desc `table name`;\n"
"create table `table name` (`column name` `column type`, ...);\n"
"create index `index name` on `table` (`column`);\n"
"insert into `table` values(`value1`,`value2`);\n"
"update `table` set column=value [where `column`=`value`];\n"
"delete from `table` [where `column`=`value`];\n"
"select [ * | `columns` ] from `table`;\n";
session_event->set_response(response);
return RC::SUCCESS;
}
RC ExecuteStage::do_create_table(SQLStageEvent *sql_event)
{
const CreateTable &create_table = sql_event->query()->sstr.create_table;
SessionEvent *session_event = sql_event->session_event();
Db *db = session_event->session()->get_current_db();
RC rc = db->create_table(create_table.relation_name,
create_table.attribute_count, create_table.attributes);
if (rc == RC::SUCCESS) {
session_event->set_response("SUCCESS");
} else {
session_event->set_response("FAILURE");
}
return rc;
}
RC ExecuteStage::do_create_index(SQLStageEvent *sql_event)
{
SessionEvent *session_event = sql_event->session_event();
Db *db = session_event->session()->get_current_db();
const CreateIndex &create_index = sql_event->query()->sstr.create_index;
Table *table = db->find_table(create_index.relation_name);
if (nullptr == table) {
session_event->set_response("FAILURE");
return RC::SCHEMA_TABLE_NOT_EXIST;
}
RC rc = table->create_index(nullptr, create_index.index_name, create_index.attribute_name);
sql_event->session_event()->set_response(rc == RC::SUCCESS ? "SUCCESS" : "FAILURE");
return rc;
}
RC ExecuteStage::do_show_tables(SQLStageEvent *sql_event)
{
SessionEvent *session_event = sql_event->session_event();
Db *db = session_event->session()->get_current_db();
std::vector<std::string> all_tables;
db->all_tables(all_tables);
if (all_tables.empty()) {
session_event->set_response("No table\n");
} else {
std::stringstream ss;
for (const auto &table : all_tables) {
ss << table << std::endl;
}
session_event->set_response(ss.str().c_str());
}
return RC::SUCCESS;
}
RC ExecuteStage::do_desc_table(SQLStageEvent *sql_event)
{
Query *query = sql_event->query();
Db *db = sql_event->session_event()->session()->get_current_db();
const char *table_name = query->sstr.desc_table.relation_name;
Table *table = db->find_table(table_name);
std::stringstream ss;
if (table != nullptr) {
table->table_meta().desc(ss);
} else {
ss << "No such table: " << table_name << std::endl;
}
sql_event->session_event()->set_response(ss.str().c_str());
return RC::SUCCESS;
}
......@@ -19,7 +19,9 @@ See the Mulan PSL v2 for more details. */
#include "sql/parser/parse.h"
#include "rc.h"
class SQLStageEvent;
class SessionEvent;
class SelectStmt;
class ExecuteStage : public common::Stage {
public:
......@@ -37,7 +39,12 @@ protected:
void callback_event(common::StageEvent *event, common::CallbackContext *context) override;
void handle_request(common::StageEvent *event);
RC do_select(const char *db, Query *sql, SessionEvent *session_event);
RC do_help(SQLStageEvent *session_event);
RC do_create_table(SQLStageEvent *sql_event);
RC do_create_index(SQLStageEvent *sql_event);
RC do_show_tables(SQLStageEvent *sql_event);
RC do_desc_table(SQLStageEvent *sql_event);
RC do_select(SelectStmt *select_stmt, SessionEvent *session_event);
protected:
private:
......
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by WangYunlai on 2021/6/9.
//
#include "sql/executor/insert_operator.h"
#include "sql/stmt/insert_stmt.h"
#include "storage/common/table.h"
#include "rc.h"
RC InsertOperator::open()
{
Table *table = insert_stmt_->table();
const Value *values = insert_stmt_->values();
int value_amount = insert_stmt_->value_amount();
return table->insert_record(nullptr, value_amount, values); // TODO trx
}
RC InsertOperator::next()
{
return RC::RECORD_EOF;
}
RC InsertOperator::close()
{
return RC::SUCCESS;
}
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by WangYunlai on 2021/6/7.
//
#pragma once
#include "common/seda/stage.h"
#include "sql/executor/operator.h"
#include "sql/parser/parse.h"
#include "rc.h"
class InsertStmt;
class InsertOperator : public Operator
{
public:
InsertOperator(InsertStmt *insert_stmt)
: insert_stmt_(insert_stmt)
{}
virtual ~InsertOperator() = default;
RC open() override;
RC next() override;
RC close() override;
private:
InsertStmt *insert_stmt_ = nullptr;
};
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by WangYunlai on 2021/6/10.
//
#include "sql/executor/join_operator.h"
RC JoinOperator::open()
{
RC rc = left_->open();
if (rc != RC::SUCCESS) {
LOG_WARN("failed to open left operator. rc=%d:%s", rc, strrc(rc));
return rc;
}
rc = right_->open();
if (rc != RC::SUCCESS) {
LOG_WARN("failed to open right operator. rc=%d:%s", rc, strrc(rc));
return rc;
}
return rc;
}
RC JoinOperator::step_right()
{
rc = right_->next();
while (rc == RC::SUCCESS) {
if (predicate_->filter()) {
return rc;
}
rc = right_->next();
}
return rc;
}
RC JoinOperator::next()
{
RC rc = RC::SUCCESS;
while (true) {
if (round_done_) {
rc = left_->next();
if (rc != RC::SUCCESS) {
return rc;
}
round_done_ = false;
right_->close();
right_->open(); // TODO
}
rc = step_right();
if (rc == RC::SUCCESS) {
return rc;
}
if (rc == RC::RECORD_EOF) {
round_done_ = true;
} else {
return rc;
}
}
return RC::RECORD_EOF;
}
RC JoinOperator::close()
{
left_->close();
right_->close();
return RC::SUCCESS;
}
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by WangYunlai on 2021/6/10.
//
#pragma once
#include "sql/parser/parse.h"
#include "sql/executor/operator.h"
#include "rc.h"
class JoinPredicate;
class JoinOperator : public Operator
{
public:
JoinOperator(Operator *left, Operator *right)
{}
virtual ~JoinOperator() = default;
RC open() override;
RC next() override;
RC close() override;
private:
Operator *left_ = nullptr;
Operator *right_ = nullptr;
JoinPredicate *predicate_ = nullptr;
bool round_done_ = true;
};
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by WangYunlai on 2021/6/7.
//
#pragma once
#include "common/seda/stage.h"
#include "sql/parser/parse.h"
#include "rc.h"
class Operator
{
public:
Operator()
{}
virtual ~Operator() = default;
virtual RC open() = 0;
virtual RC next() = 0;
virtual RC close() = 0;
private:
};
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by WangYunlai on 2021/6/9.
//
#include "sql/executor/predicate.h"
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by WangYunlai on 2021/6/10.
//
#pragma once
class Predicate
{
public:
Predicate()
{}
virtual ~Predicate() = default;
private:
};
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by WangYunlai on 2021/6/9.
//
#include "sql/executor/table_scan_operator.h"
#include "storage/common/table.h"
#include "rc.h"
RC TableScanOperator::open()
{
return table_->get_record_scanner(record_scanner_);
}
RC TableScanOperator::next()
{
if (!record_scanner_.has_next()) {
return RC::RECORD_EOF;
}
RC rc = record_scanner_.next(current_record_);
while (rc == RC::SUCCESS) {
//if (predicate_ != nullptr && predicate_->filter(current_record_)) {
// return rc;
//}
if (record_scanner_.has_next()) {
rc = record_scanner_.next(current_record_);
}
}
return rc;
}
RC TableScanOperator::close()
{
return record_scanner_.close_scan();
}
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by WangYunlai on 2021/6/7.
//
#pragma once
#include "sql/executor/predicate.h"
#include "sql/executor/operator.h"
#include "storage/common/record_manager.h"
#include "rc.h"
class Table;
class Predicate;
class TableScanOperator : public Operator
{
public:
TableScanOperator(Table *table)
: table_(table), predicate_(nullptr)
{}
TableScanOperator(Table *table, Predicate *pred)
: table_(table), predicate_(pred)
{}
virtual ~TableScanOperator() = default;
RC open() override;
RC next() override;
RC close() override;
private:
Table *table_ = nullptr;
RecordFileScanner record_scanner_;
Predicate *predicate_ = nullptr;
Record current_record_;
};
......@@ -65,7 +65,7 @@ bool OptimizeStage::initialize()
LOG_TRACE("Enter");
std::list<Stage *>::iterator stgp = next_stage_list_.begin();
execute_stage = *(stgp++);
execute_stage_ = *(stgp++);
LOG_TRACE("Exit");
return true;
......@@ -84,7 +84,7 @@ void OptimizeStage::handle_event(StageEvent *event)
LOG_TRACE("Enter\n");
// optimize sql plan, here just pass the event to the next stage
execute_stage->handle_event(event);
execute_stage_->handle_event(event);
LOG_TRACE("Exit\n");
return;
......@@ -93,7 +93,6 @@ void OptimizeStage::handle_event(StageEvent *event)
void OptimizeStage::callback_event(StageEvent *event, CallbackContext *context)
{
LOG_TRACE("Enter\n");
LOG_TRACE("Exit\n");
return;
}
......@@ -34,7 +34,7 @@ protected:
protected:
private:
Stage *execute_stage = nullptr;
Stage *execute_stage_ = nullptr;
};
#endif //__OBSERVER_SQL_OPTIMIZE_STAGE_H__
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Longda on 2021/4/13.
//
#ifndef __OBSERVER_SQL_PARSE_STAGE_H__
#define __OBSERVER_SQL_PARSE_STAGE_H__
#include "common/seda/stage.h"
class ParseStage : public common::Stage {
public:
~ParseStage();
static Stage *make_stage(const std::string &tag);
protected:
// common function
ParseStage(const char *tag);
bool set_properties();
bool initialize();
void cleanup();
void handle_event(common::StageEvent *event);
void callback_event(common::StageEvent *event, common::CallbackContext *context);
protected:
common::StageEvent *handle_request(common::StageEvent *event);
private:
Stage *resolve_stage_ = nullptr;
};
#endif //__OBSERVER_SQL_PARSE_STAGE_H__
......@@ -238,4 +238,4 @@ void query_destroy(Query *query); // reset and delete
}
#endif // __cplusplus
#endif // __OBSERVER_SQL_PARSER_PARSE_DEFS_H__
\ No newline at end of file
#endif // __OBSERVER_SQL_PARSER_PARSE_DEFS_H__
......@@ -25,7 +25,6 @@ See the Mulan PSL v2 for more details. */
#include "event/session_event.h"
#include "event/sql_event.h"
#include "sql/parser/parse.h"
#include "event/execution_plan_event.h"
using namespace common;
......@@ -69,7 +68,8 @@ bool ParseStage::initialize()
LOG_TRACE("Enter");
std::list<Stage *>::iterator stgp = next_stage_list_.begin();
optimize_stage_ = *(stgp++);
// optimize_stage_ = *(stgp++);
resolve_stage_ = *(stgp++);
LOG_TRACE("Exit");
return true;
......@@ -87,9 +87,8 @@ void ParseStage::handle_event(StageEvent *event)
{
LOG_TRACE("Enter\n");
StageEvent *new_event = handle_request(event);
if (nullptr == new_event) {
callback_event(event, nullptr);
RC rc = handle_request(event);
if (RC::SUCCESS != rc) {
event->done_immediate();
return;
}
......@@ -97,12 +96,13 @@ void ParseStage::handle_event(StageEvent *event)
CompletionCallback *cb = new (std::nothrow) CompletionCallback(this, nullptr);
if (cb == nullptr) {
LOG_ERROR("Failed to new callback for SQLStageEvent");
callback_event(event, nullptr);
event->done_immediate();
return;
}
event->push_callback(cb);
optimize_stage_->handle_event(new_event);
resolve_stage_->handle_event(event);
event->done_immediate();
LOG_TRACE("Exit\n");
return;
......@@ -113,31 +113,30 @@ void ParseStage::callback_event(StageEvent *event, CallbackContext *context)
LOG_TRACE("Enter\n");
SQLStageEvent *sql_event = static_cast<SQLStageEvent *>(event);
sql_event->session_event()->done_immediate();
sql_event->done_immediate();
LOG_TRACE("Exit\n");
return;
}
StageEvent *ParseStage::handle_request(StageEvent *event)
RC ParseStage::handle_request(StageEvent *event)
{
SQLStageEvent *sql_event = static_cast<SQLStageEvent *>(event);
const std::string &sql = sql_event->get_sql();
const std::string &sql = sql_event->sql();
Query *result = query_create();
if (nullptr == result) {
Query *query_result = query_create();
if (nullptr == query_result) {
LOG_ERROR("Failed to create query.");
return nullptr;
return RC::INTERNAL;
}
RC ret = parse(sql.c_str(), result);
RC ret = parse(sql.c_str(), query_result);
if (ret != RC::SUCCESS) {
// set error information to event
const char *error = result->sstr.errors != nullptr ? result->sstr.errors : "Unknown error";
char response[256];
snprintf(response, sizeof(response), "Failed to parse sql: %s, error msg: %s\n", sql.c_str(), error);
sql_event->session_event()->set_response(response);
query_destroy(result);
return nullptr;
sql_event->session_event()->set_response("Failed to parse sql");
query_destroy(query_result);
return RC::INTERNAL;
}
return new ExecutionPlanEvent(sql_event, result);
sql_event->set_query(query_result);
return RC::SUCCESS;
}
......@@ -16,6 +16,7 @@ See the Mulan PSL v2 for more details. */
#define __OBSERVER_SQL_PARSE_STAGE_H__
#include "common/seda/stage.h"
#include "rc.h"
class ParseStage : public common::Stage {
public:
......@@ -33,10 +34,11 @@ protected:
void callback_event(common::StageEvent *event, common::CallbackContext *context);
protected:
common::StageEvent *handle_request(common::StageEvent *event);
RC handle_request(common::StageEvent *event);
private:
Stage *optimize_stage_ = nullptr;
Stage *resolve_stage_ = nullptr;
};
#endif //__OBSERVER_SQL_PARSE_STAGE_H__
......@@ -23,6 +23,10 @@ See the Mulan PSL v2 for more details. */
#include "common/log/log.h"
#include "common/seda/timer_stage.h"
#include "event/sql_event.h"
#include "event/session_event.h"
#include "session/session.h"
#include "sql/stmt/stmt.h"
#include "storage/default/default_handler.h"
using namespace common;
......@@ -66,7 +70,7 @@ bool ResolveStage::initialize()
LOG_TRACE("Enter");
std::list<Stage *>::iterator stgp = next_stage_list_.begin();
query_cache_stage = *(stgp++);
query_cache_stage_ = *(stgp++);
LOG_TRACE("Exit");
return true;
......@@ -85,9 +89,31 @@ void ResolveStage::handle_event(StageEvent *event)
LOG_TRACE("Enter\n");
SQLStageEvent *sql_event = static_cast<SQLStageEvent *>(event);
if (nullptr == sql_event) {
LOG_WARN("failed to get sql stage event");
return;
}
SessionEvent *session_event = sql_event->session_event();
DefaultHandler &handler = DefaultHandler::get_default();
Db *db = session_event->session()->get_current_db();
if (nullptr == db) {
LOG_ERROR("cannot current db");
return ;
}
Query *query = sql_event->query();
Stmt *stmt = nullptr;
RC rc = Stmt::create_stmt(db, *query, stmt);
if (rc != RC::SUCCESS && rc != RC::UNIMPLENMENT) {
LOG_WARN("failed to create stmt. rc=%d:%s", rc, strrc(rc));
return;
}
sql_event->set_stmt(stmt);
// do nothing here
query_cache_stage->handle_event(sql_event);
query_cache_stage_->handle_event(sql_event);
LOG_TRACE("Exit\n");
return;
......
......@@ -34,7 +34,7 @@ protected:
protected:
private:
Stage *query_cache_stage = nullptr;
Stage *query_cache_stage_ = nullptr;
};
#endif //__OBSERVER_SQL_RESOLVE_STAGE_H__
......@@ -65,8 +65,8 @@ bool PlanCacheStage::initialize()
LOG_TRACE("Enter");
std::list<Stage *>::iterator stgp = next_stage_list_.begin();
execute_stage = *(stgp++);
parse_stage = *(stgp++);
// execute_stage = *(stgp++);
parse_stage_ = *(stgp++);
LOG_TRACE("Exit");
return true;
......@@ -96,7 +96,7 @@ void PlanCacheStage::handle_event(StageEvent *event)
event->push_callback(cb);
*/
// do nothing here, pass the event to the next stage
parse_stage->handle_event(event);
parse_stage_->handle_event(event);
LOG_TRACE("Exit\n");
return;
......
......@@ -34,8 +34,7 @@ protected:
protected:
private:
Stage *parse_stage = nullptr;
Stage *execute_stage = nullptr;
Stage *parse_stage_ = nullptr;
};
#endif //__OBSERVER_SQL_PLAN_CACHE_STAGE_H__
......@@ -65,7 +65,7 @@ bool QueryCacheStage::initialize()
LOG_TRACE("Enter");
std::list<Stage *>::iterator stgp = next_stage_list_.begin();
plan_cache_stage = *(stgp++);
optimize_stage_ = *(stgp++);
LOG_TRACE("Exit");
return true;
......@@ -83,19 +83,7 @@ void QueryCacheStage::handle_event(StageEvent *event)
{
LOG_TRACE("Enter\n");
// Add callback to update query cache
/*
CompletionCallback *cb = new (std::nothrow) CompletionCallback(this, nullptr);
if (cb == nullptr) {
LOG_ERROR("Failed to new callback for SQLStageEvent");
event->done_immediate();
return;
}
event->push_callback(cb);
*/
// do nothing here, pass the event to the next stage
plan_cache_stage->handle_event(event);
optimize_stage_->handle_event(event);
LOG_TRACE("Exit\n");
return;
......@@ -104,10 +92,6 @@ void QueryCacheStage::handle_event(StageEvent *event)
void QueryCacheStage::callback_event(StageEvent *event, CallbackContext *context)
{
LOG_TRACE("Enter\n");
// update data to query cache here
// event->done_immediate();
LOG_TRACE("Exit\n");
return;
}
......@@ -34,7 +34,7 @@ protected:
protected:
private:
Stage *plan_cache_stage = nullptr;
Stage *optimize_stage_ = nullptr;
};
#endif //__OBSERVER_SQL_QUERY_CACHE_STAGE_H__
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/22.
//
#include "common/log/log.h"
#include "sql/stmt/delete_stmt.h"
#include "sql/stmt/filter_stmt.h"
#include "storage/common/db.h"
#include "storage/common/table.h"
DeleteStmt::DeleteStmt(Table *table, FilterStmt *filter_stmt)
: table_ (table), filter_stmt_(filter_stmt)
{}
DeleteStmt::~DeleteStmt()
{
if (nullptr != filter_stmt_) {
delete filter_stmt_;
filter_stmt_ = nullptr;
}
}
RC DeleteStmt::create(Db *db, const Deletes &delete_sql, Stmt *&stmt)
{
const char *table_name = delete_sql.relation_name;
if (nullptr == db || nullptr == table_name) {
LOG_WARN("invalid argument. db=%p, table_name=%p",
db, table_name);
return RC::INVALID_ARGUMENT;
}
// check whether the table exists
Table *table = db->find_table(table_name);
if (nullptr == table) {
LOG_WARN("no such table. db=%s, table_name=%s", db->name(), table_name);
return RC::SCHEMA_TABLE_NOT_EXIST;
}
FilterStmt *filter_stmt = nullptr;
RC rc = FilterStmt::create(db, table, delete_sql.conditions, delete_sql.condition_num, filter_stmt);
if (rc != RC::SUCCESS) {
LOG_WARN("failed to create filter statement. rc=%d:%s", rc, strrc(rc));
return rc;
}
stmt = new DeleteStmt(table, filter_stmt);
return rc;
}
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/27.
//
#pragma once
#include "rc.h"
#include "sql/stmt/stmt.h"
#include "sql/parser/parse_defs.h"
class Table;
class FilterStmt;
class DeleteStmt : public Stmt
{
public:
DeleteStmt(Table *table, FilterStmt *filter_stmt);
~DeleteStmt() override;
Table *table() const { return table_; }
FilterStmt *filter_stmt() const { return filter_stmt_; }
StmtType type() const override { return StmtType::DELETE; }
public:
static RC create(Db *db, const Deletes &delete_sql, Stmt *&stmt);
private:
Table *table_ = nullptr;
FilterStmt *filter_stmt_ = nullptr;
};
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/22.
//
#include "rc.h"
#include "common/log/log.h"
#include "common/lang/string.h"
#include "sql/stmt/filter_stmt.h"
#include "storage/common/db.h"
#include "storage/common/table.h"
RC FilterStmt::create(Db *db, Table *default_table,
const Condition *conditions, int condition_num,
FilterStmt *&stmt)
{
RC rc = RC::SUCCESS;
stmt = nullptr;
FilterStmt *tmp_stmt = new FilterStmt();
for (int i = 0; i < condition_num; i++) {
FilterUnit filter_unit;
rc = create_filter_unit(db, default_table, conditions[i], filter_unit);
if (rc != RC::SUCCESS) {
delete tmp_stmt;
LOG_WARN("failed to create filter unit. condition index=%d", i);
return rc;
}
tmp_stmt->filter_units_.push_back(filter_unit);
}
stmt = tmp_stmt;
return rc;
}
RC get_table_and_field(Db *db, Table *default_table, const RelAttr &attr, Table *&table, const FieldMeta *&field)
{
if (common::is_blank(attr.relation_name)) {
table = default_table;
} else {
table = db->find_table(attr.relation_name);
}
if (nullptr == table) {
LOG_WARN("No such table: attr.relation_name: %s", attr.relation_name);
return RC::SCHEMA_TABLE_NOT_EXIST;
}
field = table->table_meta().field(attr.attribute_name);
if (nullptr == field) {
LOG_WARN("no such field in table: table %s, field %s", table->name(), attr.attribute_name);
table = nullptr;
return RC::SCHEMA_FIELD_NOT_EXIST;
}
return RC::SUCCESS;
}
RC FilterStmt::create_filter_unit(Db *db, Table *default_table,
const Condition &condition, FilterUnit &filter_unit)
{
RC rc = RC::SUCCESS;
CompOp comp = condition.comp;
FilterItem &left_item = filter_unit.left();
FilterItem &right_item = filter_unit.right();
if (condition.left_is_attr) {
Table *table = nullptr;
const FieldMeta *field = nullptr;
rc = get_table_and_field(db, default_table, condition.left_attr, table, field);
if (rc != RC::SUCCESS) {
LOG_WARN("cannot find attr");
return rc;
}
left_item.set_field(table, field);
} else {
left_item.set_value(condition.left_value);
}
if (condition.right_is_attr) {
Table *table = nullptr;
const FieldMeta *field = nullptr;
rc = get_table_and_field(db, default_table, condition.right_attr, table, field);
if (rc != RC::SUCCESS) {
LOG_WARN("cannot find attr");
return rc;
}
right_item.set_field(table, field);
} else {
right_item.set_value(condition.right_value);
}
// 检查两个类型是否能够比较
return rc;
}
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/22.
//
#pragma once
#include <vector>
#include "rc.h"
#include "sql/parser/parse_defs.h"
#include "sql/stmt/stmt.h"
class Db;
class Table;
class FieldMeta;
class FilterField
{
public:
FilterField() = default;
FilterField(Table *table, FieldMeta *field) : table_(table), field_(field)
{}
Table *table() const {
return table_;
}
const FieldMeta *field() const {
return field_;
}
void set_table(Table *table) {
table_ = table;
}
void set_field(const FieldMeta *field) {
field_ = field;
}
private:
Table *table_ = nullptr;
const FieldMeta *field_ = nullptr;
};
class FilterItem
{
public:
FilterItem() = default;
void set_field(Table *table, const FieldMeta *field) {
is_attr_ = true;
field_.set_table(table);
field_.set_field(field);
}
void set_value(const Value &value) {
is_attr_ = false;
value_ = value;
}
bool is_attr() const {
return is_attr_;
}
const FilterField &field() const {
return field_;
}
const Value &value() const {
return value_;
}
private:
bool is_attr_ = false; // is an attribute or a value
FilterField field_;
Value value_;
};
class FilterUnit
{
public:
FilterUnit() = default;
void set_comp(CompOp comp) {
comp_ = comp;
}
FilterItem &left() {
return left_;
}
FilterItem &right() {
return right_;
}
const FilterItem &left() const {
return left_;
}
const FilterItem &right() const {
return right_;
}
private:
CompOp comp_;
FilterItem left_;
FilterItem right_;
};
class FilterStmt
{
public:
FilterStmt() = default;
public:
const std::vector<FilterUnit> &filter_units() const
{
return filter_units_;
}
public:
static RC create(Db *db, Table *default_table,
const Condition *conditions, int condition_num,
FilterStmt *&stmt);
static RC create_filter_unit(Db *db, Table *default_table, const Condition &condition, FilterUnit &filter_unit);
private:
std::vector<FilterUnit> filter_units_; // 默认当前都是AND关系
};
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/22.
//
#include "sql/stmt/insert_stmt.h"
#include "common/log/log.h"
#include "storage/common/db.h"
#include "storage/common/table.h"
InsertStmt::InsertStmt(Table *table, const Value *values, int value_amount)
: table_ (table), values_(values), value_amount_(value_amount)
{}
RC InsertStmt::create(Db *db, const Inserts &inserts, Stmt *&stmt)
{
const char *table_name = inserts.relation_name;
if (nullptr == db || nullptr == table_name || inserts.value_num <= 0) {
LOG_WARN("invalid argument. db=%p, table_name=%p, value_num=%d",
db, table_name, inserts.value_num);
return RC::INVALID_ARGUMENT;
}
// check whether the table exists
Table *table = db->find_table(table_name);
if (nullptr == table) {
LOG_WARN("no such table. db=%s, table_name=%s", db->name(), table_name);
return RC::SCHEMA_TABLE_NOT_EXIST;
}
// check the fields number
const Value *values = inserts.values;
const int value_num = inserts.value_num;
const TableMeta &table_meta = table->table_meta();
const int field_num = table_meta.field_num() - table_meta.sys_field_num();
if (field_num != value_num) {
LOG_WARN("schema mismatch. value num=%d, field num in schema=%d", value_num, field_num);
return RC::SCHEMA_FIELD_MISSING;
}
// check fields type
for (int i = table_meta.sys_field_num(); i < table_meta.field_num(); i++) {
const FieldMeta *field_meta = table_meta.field(i);
const AttrType field_type = field_meta->type();
const AttrType value_type = values[i].type;
if (field_type != value_type) { // TODO try to convert the value type to field type
LOG_WARN("field type mismatch. table=%s, field=%s, field type=%d, value_type=%d",
table_name, field_meta->name(), field_type, value_type);
return RC::SCHEMA_FIELD_TYPE_MISMATCH;
}
}
// everything alright
stmt = new InsertStmt(table, values, value_num);
return RC::SUCCESS;
}
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/22.
//
#pragma once
#include "rc.h"
#include "sql/stmt/stmt.h"
class Table;
class Db;
class InsertStmt : public Stmt
{
public:
InsertStmt() = default;
InsertStmt(Table *table, const Value *values, int value_amount);
StmtType type() const override {
return StmtType::INSERT;
}
public:
static RC create(Db *db, const Inserts &insert_sql, Stmt *&stmt);
public:
Table *table() const {return table_;}
const Value *values() const { return values_; }
int value_amount() const { return value_amount_; }
private:
Table *table_ = nullptr;
const Value *values_ = nullptr;
int value_amount_ = 0;
};
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/6/6.
//
#include "sql/stmt/select_stmt.h"
#include "sql/stmt/filter_stmt.h"
#include "common/log/log.h"
#include "common/lang/string.h"
#include "storage/common/db.h"
#include "storage/common/table.h"
SelectStmt::~SelectStmt()
{
if (nullptr != filter_stmt_) {
delete filter_stmt_;
filter_stmt_ = nullptr;
}
}
static void wildcard_fields(Table *table, std::vector<FieldDesc> &field_metas)
{
const TableMeta &table_meta = table->table_meta();
const int field_num = table_meta.field_num();
for (int i = table_meta.sys_field_num(); i < field_num; i++) {
field_metas.push_back(FieldDesc(table, table_meta.field(i)));
}
}
RC SelectStmt::create(Db *db, const Selects &select_sql, Stmt *&stmt)
{
if (nullptr == db) {
LOG_WARN("invalid argument. db is null");
return RC::INVALID_ARGUMENT;
}
std::vector<Table *> tables;
std::map<std::string, Table *> table_map;
for (int i = 0; i < select_sql.relation_num; i++) {
const char *table_name = select_sql.relations[i];
if (nullptr == table_name) {
LOG_WARN("invalid argument. relation name is null. index=%d", i);
return RC::INVALID_ARGUMENT;
}
Table *table = db->find_table(table_name);
if (nullptr == table) {
LOG_WARN("no such table. db=%s, table_name=%s", db->name(), table_name);
return RC::SCHEMA_TABLE_NOT_EXIST;
}
tables.push_back(table);
table_map.insert(std::pair<std::string, Table*>(table_name, table));
}
std::vector<FieldDesc> query_fields;
for (int i = 0; i < select_sql.attr_num; i++) {
const RelAttr &relation_attr = select_sql.attributes[i];
if (common::is_blank(relation_attr.relation_name) && 0 == strcmp(relation_attr.attribute_name, "*")) {
for (Table *table : tables) {
wildcard_fields(table, query_fields);
}
} else if (!common::is_blank(relation_attr.relation_name)) { // TODO
const char *table_name = relation_attr.relation_name;
const char *field_name = relation_attr.attribute_name;
if (0 == strcmp(table_name, "*")) {
if (0 != strcmp(field_name, "*")) {
LOG_WARN("invalid field name while table is *. attr=%s", field_name);
return RC::SCHEMA_FIELD_MISSING;
}
for (Table *table : tables) {
wildcard_fields(table, query_fields);
}
} else {
auto iter = table_map.find(table_name);
if (iter == table_map.end()) {
LOG_WARN("no such table in from list: %s", table_name);
return RC::SCHEMA_FIELD_MISSING;
}
Table *table = iter->second;
if (field_name == "*") {
wildcard_fields(table, query_fields);
} else {
const FieldMeta *field_meta = table->table_meta().field(field_name);
if (nullptr == field_meta) {
LOG_WARN("no such field. field=%s.%s.%s", db->name(), table->name(), field_name);
return RC::SCHEMA_FIELD_MISSING;
}
query_fields.push_back(FieldDesc(table, field_meta));
}
}
} else {
if (tables.size() != 1) {
LOG_WARN("invalid. I do not know the attr's table. attr=%s", relation_attr.attribute_name);
return RC::SCHEMA_FIELD_MISSING;
}
Table *table = tables[0];
const FieldMeta *field_meta = table->table_meta().field(relation_attr.attribute_name);
if (nullptr == field_meta) {
LOG_WARN("no such field. field=%s.%s.%s", db->name(), table->name(), relation_attr.attribute_name);
return RC::SCHEMA_FIELD_MISSING;
}
query_fields.push_back(FieldDesc(table, field_meta));
}
}
LOG_INFO("got %d tables in from stmt and %d fields in query stmt", tables.size(), query_fields.size());
Table *default_table = nullptr;
if (tables.size() == 1) {
default_table = tables[0];
}
FilterStmt *filter_stmt = nullptr;
RC rc = FilterStmt::create(db, default_table, select_sql.conditions, select_sql.condition_num, filter_stmt);
if (rc != RC::SUCCESS) {
LOG_WARN("cannot construct filter stmt");
return rc;
}
// make sure all tables in predicate are exists in from stmt
const std::vector<FilterUnit> &filter_units = filter_stmt->filter_units();
for (const FilterUnit &filter_unit : filter_units) {
const FilterItem &left = filter_unit.left();
const FilterItem &right = filter_unit.right();
if (left.is_attr()) {
Table *table = left.field().table();
if (table_map.find(table->name()) == table_map.end()) {
LOG_WARN("the table in predicate is not in from stmt: %s", table->name());
return RC::SCHEMA_TABLE_NOT_EXIST;
}
}
if (right.is_attr()) {
Table *table = right.field().table();
if (table_map.find(table->name()) == table_map.end()) {
LOG_WARN("the table in predicate is not in from stmt: %s", table->name());
return RC::SCHEMA_TABLE_NOT_EXIST;
}
}
}
// everything alright
SelectStmt *select_stmt = new SelectStmt();
select_stmt->tables_.swap(tables);
select_stmt->query_fields_.swap(query_fields);
select_stmt->filter_stmt_ = filter_stmt;
stmt = select_stmt;
return RC::SUCCESS;
}
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/6/5.
//
#pragma once
#include <vector>
#include "rc.h"
#include "sql/stmt/stmt.h"
class FieldMeta;
class FilterStmt;
class Db;
class Table;
// better to create a field class
struct FieldDesc
{
Table *table_ = nullptr;
const FieldMeta *field_meta_ = nullptr;
FieldDesc() = default;
FieldDesc(Table *table, const FieldMeta *field_meta) : table_(table), field_meta_(field_meta) {}
};
class SelectStmt : public Stmt
{
public:
SelectStmt() = default;
~SelectStmt() override;
StmtType type() const override { return StmtType::SELECT; }
public:
static RC create(Db *db, const Selects &select_sql, Stmt *&stmt);
public:
const std::vector<Table *> &tables() const { return tables_; }
FilterStmt *filter_stmt() const { return filter_stmt_; }
private:
std::vector<FieldDesc> query_fields_;
std::vector<Table *> tables_;
FilterStmt *filter_stmt_ = nullptr;
};
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/22.
//
#include "rc.h"
#include "common/log/log.h"
#include "sql/stmt/insert_stmt.h"
#include "sql/stmt/delete_stmt.h"
#include "sql/stmt/select_stmt.h"
RC Stmt::create_stmt(Db *db, const Query &query, Stmt *&stmt)
{
stmt = nullptr;
switch (query.flag) {
case SCF_INSERT: {
return InsertStmt::create(db, query.sstr.insertion, stmt);
}
break;
case SCF_DELETE: {
return DeleteStmt::create(db, query.sstr.deletion, stmt);
}
case SCF_SELECT: {
return SelectStmt::create(db, query.sstr.selection, stmt);
}
default: {
LOG_WARN("unknown query command");
}
break;
}
return RC::UNIMPLENMENT;
}
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/22.
//
#pragma once
#include "rc.h"
#include "sql/parser/parse_defs.h"
class Db;
enum class StmtType
{
SELECT,
INSERT,
UPDATE,
DELETE,
CREATE_TABLE,
DROP_TABLE,
CREATE_INDEX,
DROP_INDEX,
SYNC,
SHOW_TABLES,
DESC_TABLE,
BEGIN,
COMMIT,
ROLLBACK,
LOAD_DATA,
HELP,
EXIT,
PREDICATE,
};
class Stmt
{
public:
Stmt() = default;
virtual ~Stmt() = default;
virtual StmtType type() const = 0;
public:
static RC create_stmt(Db *db, const Query &query, Stmt *&stmt);
private:
};
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/22.
//
#include "sql/stmt/update_stmt.h"
UpdateStmt::UpdateStmt(Table *table, Value *values, int value_amount)
: table_ (table), values_(values), value_amount_(value_amount)
{}
RC UpdateStmt::create(Db *db, const Updates &update, Stmt *&stmt)
{
// TODO
#if 0
const char *table_name = update.relation_name;
if (nullptr == db || nullptr == table_name || update.value_num <= 0) {
LOG_WARN("invalid argument. db=%p, table_name=%p, value_num=%d",
db, table_name, inserts.value_num);
return RC::INVALID_ARGUMENT;
}
// check whether the table exists
Table *table = db->find_table(table_name);
if (nullptr == table) {
LOG_WARN("no such table. db=%s, table_name=%s", db->name(), table_name);
return RC::SCHEMA_TABLE_NOT_EXIST;
}
// check the fields number
const Value *values = inserts.values;
const int value_num = inserts.value_num;
const TableMeta &table_meta = table->table_meta();
const int field_num = table_meta.field_num() - table_meta.sys_field_num();
if (field_num != value_num) {
LOG_WARN("schema mismatch. value num=%d, field num in schema=%d", value_num, field_num);
return RC::SCHEMA_FIELD_MISSING;
}
// check fields type
for (int i = table_meta.sys_field_num(); i < table_meta.field_num(); i++) {
const FieldMeta *field_meta = table_meta.field(i);
const AttrType field_type = field_meta->type();
const AttrType value_type = values[i].type;
if (field_type != value_type) { // TODO try to convert the value type to field type
LOG_WARN("field type mismatch. table=%s, field=%s, field type=%d, value_type=%d",
table_name, field_meta->name(), field_type, value_type);
return RC::SCHEMA_FIELD_TYPE_MISMATCH;
}
}
// everything alright
stmt = new InsertStmt(table, values, value_num);
#endif
return RC::INTERNAL;
}
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/22.
//
#pragma once
#include "rc.h"
#include "sql/stmt/stmt.h"
class Table;
class UpdateStmt : public Stmt
{
public:
UpdateStmt() = default;
UpdateStmt(Table *table, Value *values, int value_amount);
public:
static RC create(Db *db, const Updates &update_sql, Stmt *&stmt);
public:
Table *table() const {return table_;}
Value *values() const { return values_; }
int value_amount() const { return value_amount_; }
private:
Table *table_ = nullptr;
Value *values_ = nullptr;
int value_amount_ = 0;
};
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/4.
//
#pragma once
#include <stddef.h>
#include <vector>
#include "rc.h"
#include "storage/common/index_meta.h"
#include "storage/common/field_meta.h"
#include "storage/common/record_manager.h"
class Record
{
public:
Record() = default;
~Record() = default;
void set_data(char *data);
char *data();
const char *data() const;
void set_rid(const RID &rid);
RID & rid();
const RID &rid() const;
RC set_field_value(const Value &value, int index);
RC set_field_values(const Value *values, int value_num, int start_index);
private:
std::vector<FieldMeta> * fields_ = nullptr;
RID rid_;
// the data buffer
// record will not release the memory
char * data_ = nullptr;
};
......@@ -357,6 +357,15 @@ RC Table::init_record_handler(const char *base_dir)
return rc;
}
RC Table::get_record_scanner(RecordFileScanner &scanner)
{
RC rc = scanner.open_scan(*data_buffer_pool_, nullptr);
if (rc != RC::SUCCESS) {
LOG_ERROR("failed to open scanner. rc=%d:%s", rc, strrc(rc));
}
return rc;
}
/**
* 为了不把Record暴露出去,封装一下
*/
......
......@@ -17,12 +17,13 @@ See the Mulan PSL v2 for more details. */
#include "storage/common/table_meta.h"
struct Record;
struct RID;
class DiskBufferPool;
class RecordFileHandler;
class RecordFileScanner;
class ConditionFilter;
class DefaultConditionFilter;
struct Record;
struct RID;
class Index;
class IndexScanner;
class RecordDeleter;
......@@ -60,6 +61,8 @@ public:
RC create_index(Trx *trx, const char *index_name, const char *attribute_name);
RC get_record_scanner(RecordFileScanner &scanner);
public:
const char *name() const;
......
......@@ -42,7 +42,7 @@ public:
const FieldMeta *field(int index) const;
const FieldMeta *field(const char *name) const;
const FieldMeta *find_field_by_offset(int offset) const;
int field_num() const;
int field_num() const; // sys field included
int sys_field_num() const;
const IndexMeta *index(const char *name) const;
......@@ -73,4 +73,4 @@ protected:
static std::vector<FieldMeta> sys_fields_;
};
#endif // __OBSERVER_STORAGE_COMMON_TABLE_META_H__
\ No newline at end of file
#endif // __OBSERVER_STORAGE_COMMON_TABLE_META_H__
......@@ -97,9 +97,6 @@ public:
* 否则,创建该索引。
* 创建索引的工作包括:①创建并打开索引文件;
* ②逐个扫描被索引的记录,并向索引文件中插入索引项;③关闭索引
* @param indexName
* @param relName
* @param attrName
* @return
*/
RC create_index(
......@@ -118,9 +115,6 @@ public:
* nValues为属性值个数,values为对应的属性值数组。
* 函数根据给定的属性值构建元组,调用记录管理模块的函数插入该元组,
* 然后在该表的每个索引中为该元组创建合适的索引项
* @param relName
* @param nValues
* @param values
* @return
*/
RC insert_record(Trx *trx, const char *dbname, const char *relation_name, int value_num, const Value *values);
......@@ -142,11 +136,6 @@ public:
* 在每一个更新的元组中将属性attrName的值设置为一个新的值。
* 如果没有指定条件,则此方法更新relName中所有元组。
* 如果要更新一个被索引的属性,应当先删除每个被更新元组对应的索引条目,然后插入一个新的索引条目
* @param relName
* @param attrName
* @param value
* @param nConditions
* @param conditions
* @return
*/
RC update_record(Trx *trx, const char *dbname, const char *relation_name, const char *attribute_name,
......
......@@ -29,7 +29,6 @@ See the Mulan PSL v2 for more details. */
#include "storage/common/table.h"
#include "storage/common/table_meta.h"
#include "storage/trx/trx.h"
#include "event/execution_plan_event.h"
#include "event/session_event.h"
#include "event/sql_event.h"
#include "event/storage_event.h"
......@@ -143,21 +142,15 @@ void DefaultStorageStage::handle_event(StageEvent *event)
LOG_TRACE("Enter\n");
TimerStat timerStat(*query_metric_);
StorageEvent *storage_event = static_cast<StorageEvent *>(event);
CompletionCallback *cb = new (std::nothrow) CompletionCallback(this, nullptr);
if (cb == nullptr) {
LOG_ERROR("Failed to new callback for SessionEvent");
storage_event->done_immediate();
return;
}
storage_event->push_callback(cb);
SQLStageEvent *sql_event = static_cast<SQLStageEvent *>(event);
Query *sql = storage_event->exe_event()->sqls();
Query *sql = sql_event->query();
SessionEvent *session_event = storage_event->exe_event()->sql_event()->session_event();
SessionEvent *session_event = sql_event->session_event();
Session *session = session_event->get_client()->session;
const char *current_db = session->get_current_db().c_str();
Db *db = session->get_current_db();
const char *dbname = db->name();
Trx *current_trx = session->current_trx();
......@@ -168,7 +161,7 @@ void DefaultStorageStage::handle_event(StageEvent *event)
case SCF_INSERT: { // insert into
const Inserts &inserts = sql->sstr.insertion;
const char *table_name = inserts.relation_name;
rc = handler_->insert_record(current_trx, current_db, table_name, inserts.value_num, inserts.values);
//rc = handler_->insert_record(current_trx, current_db, table_name, inserts.value_num, inserts.values);
snprintf(response, sizeof(response), "%s\n", rc == RC::SUCCESS ? "SUCCESS" : "FAILURE");
} break;
case SCF_UPDATE: {
......@@ -176,6 +169,7 @@ void DefaultStorageStage::handle_event(StageEvent *event)
const char *table_name = updates.relation_name;
const char *field_name = updates.attribute_name;
int updated_count = 0;
#if 0
rc = handler_->update_record(current_trx,
current_db,
table_name,
......@@ -184,58 +178,19 @@ void DefaultStorageStage::handle_event(StageEvent *event)
updates.condition_num,
updates.conditions,
&updated_count);
#endif
snprintf(response, sizeof(response), "%s\n", rc == RC::SUCCESS ? "SUCCESS" : "FAILURE");
} break;
case SCF_DELETE: {
const Deletes &deletes = sql->sstr.deletion;
const char *table_name = deletes.relation_name;
int deleted_count = 0;
#if 0
rc = handler_->delete_record(
current_trx, current_db, table_name, deletes.condition_num, deletes.conditions, &deleted_count);
#endif
snprintf(response, sizeof(response), "%s\n", rc == RC::SUCCESS ? "SUCCESS" : "FAILURE");
} break;
case SCF_CREATE_TABLE: { // create table
const CreateTable &create_table = sql->sstr.create_table;
rc = handler_->create_table(
current_db, create_table.relation_name, create_table.attribute_count, create_table.attributes);
snprintf(response, sizeof(response), "%s\n", rc == RC::SUCCESS ? "SUCCESS" : "FAILURE");
} break;
case SCF_CREATE_INDEX: {
const CreateIndex &create_index = sql->sstr.create_index;
rc = handler_->create_index(
current_trx, current_db, create_index.relation_name, create_index.index_name, create_index.attribute_name);
snprintf(response, sizeof(response), "%s\n", rc == RC::SUCCESS ? "SUCCESS" : "FAILURE");
} break;
case SCF_SHOW_TABLES: {
Db *db = handler_->find_db(current_db);
if (nullptr == db) {
snprintf(response, sizeof(response), "No such database: %s\n", current_db);
} else {
std::vector<std::string> all_tables;
db->all_tables(all_tables);
if (all_tables.empty()) {
snprintf(response, sizeof(response), "No table\n");
} else {
std::stringstream ss;
for (const auto &table : all_tables) {
ss << table << std::endl;
}
snprintf(response, sizeof(response), "%s\n", ss.str().c_str());
}
}
} break;
case SCF_DESC_TABLE: {
const char *table_name = sql->sstr.desc_table.relation_name;
Table *table = handler_->find_table(current_db, table_name);
std::stringstream ss;
if (table != nullptr) {
table->table_meta().desc(ss);
} else {
ss << "No such table: " << table_name << std::endl;
}
snprintf(response, sizeof(response), "%s", ss.str().c_str());
} break;
case SCF_LOAD_DATA: {
/*
......@@ -244,7 +199,7 @@ void DefaultStorageStage::handle_event(StageEvent *event)
*/
const char *table_name = sql->sstr.load_data.relation_name;
const char *file_name = sql->sstr.load_data.file_name;
std::string result = load_data(current_db, table_name, file_name);
std::string result = load_data(dbname, table_name, file_name);
snprintf(response, sizeof(response), "%s", result.c_str());
} break;
default:
......@@ -269,7 +224,7 @@ void DefaultStorageStage::callback_event(StageEvent *event, CallbackContext *con
{
LOG_TRACE("Enter\n");
StorageEvent *storage_event = static_cast<StorageEvent *>(event);
storage_event->exe_event()->done_immediate();
storage_event->sql_event()->done_immediate();
LOG_TRACE("Exit\n");
return;
}
......@@ -411,4 +366,4 @@ std::string DefaultStorageStage::load_data(const char *db_name, const char *tabl
<< " record(s) loaded, total cost " << cost_nano / 1000000000.0 << " second(s)" << std::endl;
}
return result_string.str();
}
\ No newline at end of file
}
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Wangyunlai on 2022/5/3.
//
#ifndef __OBSERVER_STORAGE_ROW_ROW_H_
#define __OBSERVER_STORAGE_ROW_ROW_H_
#include <stddef.h>
#include <vector>
#include "rc.h"
#include "storage/common/index_meta.h"
#include "storage/common/field_meta.h"
#include "storage/common/record_manager.h"
class Row {
public:
Row() = default;
~Row() = default;
RC init(const FieldMeta *fields_, int num);
RC set_projector();
private:
std::vector<FieldMeta *> fields_;
std::vector<int> projector_;
char *data_;
};
#endif // __OBSERVER_STORAGE_ROW_ROW_H_
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by wangyunlai on 2021/6/11.
//
#include <string.h>
const double epsilon = 1E-6;
int compare_int(void *arg1, void *arg2)
{
int v1 = *(int *)arg1;
int v2 = *(int *)arg2;
return v1 - v2;
}
int compare_float(void *arg1, void *arg2)
{
float v1 = *(float *)arg1;
float v2 = *(float *)arg2;
float cmp = v1 - v2;
if (cmp > epsilon) {
return 1;
}
if (cmp < -epsilon) {
return -1;
}
return 0;
}
int compare_string(void *arg1, void *arg2, int maxlen)
{
const char *s1 = (const char *)arg1;
const char *s2 = (const char *)arg2;
return strncmp(s1, s2, maxlen);
}
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by wangyunlai on 2021/6/11
//
#pragma once
int compare_int(void *arg1, void *arg2);
int compare_float(void *arg1, void *arg2);
int compare_string(void *arg1, void *arg2);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册