diff --git a/src/common/sys/rc.h b/src/common/sys/rc.h index d465c7cfb..c73cc9c2f 100644 --- a/src/common/sys/rc.h +++ b/src/common/sys/rc.h @@ -76,7 +76,8 @@ See the Mulan PSL v2 for more details. */ DEFINE_RC(LOGBUF_FULL) \ DEFINE_RC(LOG_FILE_FULL) \ DEFINE_RC(LOG_ENTRY_INVALID) \ - DEFINE_RC(UNSUPPORTED) + DEFINE_RC(UNSUPPORTED) \ + DEFINE_RC(DELETE_FILE_ERROR) enum class RC { diff --git a/src/observer/sql/executor/command_executor.cpp b/src/observer/sql/executor/command_executor.cpp index 0da5c4e0f..4556479f4 100644 --- a/src/observer/sql/executor/command_executor.cpp +++ b/src/observer/sql/executor/command_executor.cpp @@ -17,6 +17,7 @@ See the Mulan PSL v2 for more details. */ #include "event/sql_event.h" #include "sql/executor/create_index_executor.h" #include "sql/executor/create_table_executor.h" +#include "sql/executor/drop_table_executor.h" #include "sql/executor/desc_table_executor.h" #include "sql/executor/help_executor.h" #include "sql/executor/load_data_executor.h" @@ -82,6 +83,11 @@ RC CommandExecutor::execute(SQLStageEvent *sql_event) rc = RC::SUCCESS; } break; + case StmtType::DROP_TABLE: { + DropTableExecutor executor; + rc = executor.execute(sql_event); + } break; + default: { LOG_ERROR("unknown command: %d", static_cast(stmt->type())); rc = RC::UNIMPLEMENTED; diff --git a/src/observer/sql/executor/drop_table_executor.cpp b/src/observer/sql/executor/drop_table_executor.cpp new file mode 100644 index 000000000..b2d0891fc --- /dev/null +++ b/src/observer/sql/executor/drop_table_executor.cpp @@ -0,0 +1,19 @@ +#include "sql/executor/drop_table_executor.h" +#include "session/session.h" +#include "common/log/log.h" +#include "storage/table/table.h" +#include "sql/stmt/drop_table_stmt.h" +#include "event/sql_event.h" +#include "event/session_event.h" +#include "storage/db/db.h" +RC DropTableExecutor::execute(SQLStageEvent *sql_event) +{ + Stmt *stmt = sql_event->stmt(); + Session *session = sql_event->session_event()->session(); + ASSERT(stmt->type() == StmtType::DROP_TABLE, + "drop table executor can not run this command: %d", static_cast(stmt->type())); + DropTableStmt *drop_table_stmt = static_cast(stmt); + const char *table_name = drop_table_stmt->table_name().c_str(); + RC rc = session->get_current_db()->drop_table(table_name); + return rc; +} \ No newline at end of file diff --git a/src/observer/sql/executor/drop_table_executor.h b/src/observer/sql/executor/drop_table_executor.h new file mode 100644 index 000000000..5f0afdf68 --- /dev/null +++ b/src/observer/sql/executor/drop_table_executor.h @@ -0,0 +1,14 @@ +#pragma once +#include "common/sys/rc.h" +class SQLStageEvent; +/** + * @brief 删除表的执行器 + * @ingroup Executor + */ +class DropTableExecutor +{ +public: + DropTableExecutor() = default; + virtual ~DropTableExecutor() = default; + RC execute(SQLStageEvent *sql_event); +}; \ No newline at end of file diff --git a/src/observer/sql/stmt/drop_table_stmt.cpp b/src/observer/sql/stmt/drop_table_stmt.cpp new file mode 100644 index 000000000..c8da17d22 --- /dev/null +++ b/src/observer/sql/stmt/drop_table_stmt.cpp @@ -0,0 +1,8 @@ +#include "sql/stmt/drop_table_stmt.h" +#include "event/sql_debug.h" +RC DropTableStmt::create(Db *db, const DropTableSqlNode &drop_table, Stmt *&stmt) +{ + stmt = new DropTableStmt(drop_table.relation_name); + sql_debug("drop table statement: table name %s", drop_table.relation_name.c_str()); + return RC::SUCCESS; +} \ No newline at end of file diff --git a/src/observer/sql/stmt/drop_table_stmt.h b/src/observer/sql/stmt/drop_table_stmt.h new file mode 100644 index 000000000..070b93e2e --- /dev/null +++ b/src/observer/sql/stmt/drop_table_stmt.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include +#include "sql/stmt/stmt.h" +class Db; +/** + * @brief 表示删除表的语句 + * @ingroup Statement + * @details 虽然解析成了stmt,但是与原始的SQL解析后的数据也差不多 + */ +class DropTableStmt : public Stmt +{ +public: + DropTableStmt(const std::string &table_name) + : table_name_(table_name) + {} + virtual ~DropTableStmt() = default; + StmtType type() const override { return StmtType::DROP_TABLE; } + const std::string &table_name() const { return table_name_; } + static RC create(Db *db, const DropTableSqlNode &create_table, Stmt *&stmt); +private: + std::string table_name_; +}; \ No newline at end of file diff --git a/src/observer/sql/stmt/stmt.cpp b/src/observer/sql/stmt/stmt.cpp index 61be9c1b6..f6233cf73 100644 --- a/src/observer/sql/stmt/stmt.cpp +++ b/src/observer/sql/stmt/stmt.cpp @@ -17,6 +17,7 @@ See the Mulan PSL v2 for more details. */ #include "sql/stmt/calc_stmt.h" #include "sql/stmt/create_index_stmt.h" #include "sql/stmt/create_table_stmt.h" +#include "sql/stmt/drop_table_stmt.h" #include "sql/stmt/delete_stmt.h" #include "sql/stmt/desc_table_stmt.h" #include "sql/stmt/exit_stmt.h" @@ -71,6 +72,10 @@ RC Stmt::create_stmt(Db *db, ParsedSqlNode &sql_node, Stmt *&stmt) return CreateTableStmt::create(db, sql_node.create_table, stmt); } + case SCF_DROP_TABLE: { + return DropTableStmt::create(db, sql_node.drop_table, stmt); + } + case SCF_DESC_TABLE: { return DescTableStmt::create(db, sql_node.desc_table, stmt); } diff --git a/src/observer/storage/buffer/disk_buffer_pool.cpp b/src/observer/storage/buffer/disk_buffer_pool.cpp index df656d76c..6c23e0e02 100644 --- a/src/observer/storage/buffer/disk_buffer_pool.cpp +++ b/src/observer/storage/buffer/disk_buffer_pool.cpp @@ -921,3 +921,21 @@ RC BufferPoolManager::get_buffer_pool(int32_t id, DiskBufferPool *&bp) return RC::SUCCESS; } +//将相关数据移出bufferpool +RC BufferPoolManager::remove_file(const char *file_name) +{ + RC ret = RC::SUCCESS; + if((ret = close_file(file_name)) != RC::SUCCESS) + { + LOG_WARN("close file fail. file name=%s", file_name); + } + else + { + if( 0 != ::remove(file_name)) + { + LOG_WARN("remove file fail. file name=%s, errno = %s", file_name,strerror(errno)); + ret = RC::FILE_REMOVE; + } + } + return ret; +} diff --git a/src/observer/storage/buffer/disk_buffer_pool.h b/src/observer/storage/buffer/disk_buffer_pool.h index 715f66a83..b4e93b5cb 100644 --- a/src/observer/storage/buffer/disk_buffer_pool.h +++ b/src/observer/storage/buffer/disk_buffer_pool.h @@ -332,6 +332,8 @@ class BufferPoolManager final RC flush_page(Frame &frame); + RC remove_file(const char *file_name); + BPFrameManager &get_frame_manager() { return frame_manager_; } DoubleWriteBuffer *get_dblwr_buffer() { return dblwr_buffer_.get(); } diff --git a/src/observer/storage/db/db.cpp b/src/observer/storage/db/db.cpp index 1c6b9ff61..db70728a7 100644 --- a/src/observer/storage/db/db.cpp +++ b/src/observer/storage/db/db.cpp @@ -395,6 +395,33 @@ RC Db::init_dblwr_buffer() return RC::SUCCESS; } +RC Db::drop_table(const char *table_name) +{ + RC rc = RC::SUCCESS; + Table * table = nullptr; + auto it = opened_tables_.find(table_name); + if(it == opened_tables_.end()) + { + LOG_WARN("table : %s not exist", table_name); + rc = RC::SCHEMA_TABLE_NOT_EXIST; + } + else if( (table = it->second) == nullptr) + { + LOG_WARN("table : %s not exist", table_name); + rc = RC::SCHEMA_TABLE_NOT_EXIST; + } + else if((rc = table->drop(path_.c_str())) != RC::SUCCESS) + { + LOG_WARN("table drop file,errno: %s", strrc(rc)); + } + else + { + opened_tables_.erase(it); + delete table; + } + return rc; +} + LogHandler &Db::log_handler() { return *log_handler_; } BufferPoolManager &Db::buffer_pool_manager() { return *buffer_pool_manager_; } TrxKit &Db::trx_kit() { return *trx_kit_; } diff --git a/src/observer/storage/db/db.h b/src/observer/storage/db/db.h index ca68d41cb..89a1743b8 100644 --- a/src/observer/storage/db/db.h +++ b/src/observer/storage/db/db.h @@ -87,6 +87,8 @@ class Db */ RC sync(); + RC drop_table(const char *table_name); + /// @brief 获取当前数据库的日志处理器 LogHandler &log_handler(); diff --git a/src/observer/storage/table/table.cpp b/src/observer/storage/table/table.cpp index 5396c9f1b..fcb1faea4 100644 --- a/src/observer/storage/table/table.cpp +++ b/src/observer/storage/table/table.cpp @@ -540,3 +540,44 @@ RC Table::sync() LOG_INFO("Sync table over. table=%s", name()); return rc; } + +RC Table::drop(const char *dir) +{ + // 1.drop index first + RC rc = RC::SUCCESS; + if ((rc = sync()) != RC::SUCCESS) { + LOG_WARN("Failed to sync table %s to disk.", name()); + } else { + std::string meta_file = ::table_meta_file(dir, name()); + // 1.drop meta file and index file + if (0 != ::unlink(meta_file.c_str())) { + LOG_WARN("unable to delete %s meta file", name()); + rc = RC::DELETE_FILE_ERROR; + } else { + const int index_num = table_meta_.index_num(); + for (int i = 0; i < index_num; i++) { + ((BplusTreeIndex *)indexes_[i])->close(); + const IndexMeta *index_meta = table_meta_.index(i); + if (index_meta != nullptr) { + std::string index_file = ::table_index_file(dir, name(), index_meta->name()); + if (0 != ::unlink(index_file.c_str())) { + LOG_WARN("unable to delete %s meta file", name()); + rc = RC::DELETE_FILE_ERROR; + break; + } + } + } + } + } + if (RC::SUCCESS == rc) { + // 2.destroy record handler + record_handler_->close(); + delete record_handler_; + record_handler_ = nullptr; + // 3.destroy buffer pool and remove data file + std::string data_file = table_data_file(dir, name()); + BufferPoolManager &bpm = db_->buffer_pool_manager(); + rc = bpm.remove_file(data_file.c_str()); + } + return rc; +} diff --git a/src/observer/storage/table/table.h b/src/observer/storage/table/table.h index 089e13ae4..bd1307370 100644 --- a/src/observer/storage/table/table.h +++ b/src/observer/storage/table/table.h @@ -110,6 +110,8 @@ class Table RC sync(); + RC drop(const char *dir); + private: RC insert_entry_of_indexes(const char *record, const RID &rid); RC delete_entry_of_indexes(const char *record, const RID &rid, bool error_on_not_exists);