From 234d166e5c674e19ecbbb3d3cc1d9202f3a24a9a Mon Sep 17 00:00:00 2001
From: yonchicy <1079279184@qq.com>
Date: Sat, 19 Aug 2023 14:47:55 +0800
Subject: [PATCH] =?UTF-8?q?=E5=86=99=E5=AE=8C=20load?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/analyze/analyze.cpp             | 41 ++-------------------------
 src/analyze/analyze.h               |  6 +---
 src/common/CMakeLists.txt           |  3 --
 src/common/common.h                 | 43 ++++++++++++++++++++++++++++-
 src/execution/execution_manager.cpp |  1 +
 src/optimizer/optimizer.h           |  2 +-
 src/optimizer/plan.h                |  5 +---
 src/parser/lex.l                    |  5 ++++
 src/record/rm_file_handle.cpp       | 31 +++++++++++----------
 src/system/sm_manager.cpp           |  5 +++-
 src/unit_test.cpp                   |  2 +-
 11 files changed, 74 insertions(+), 70 deletions(-)

diff --git a/src/analyze/analyze.cpp b/src/analyze/analyze.cpp
index d13e8fa..0ab827b 100644
--- a/src/analyze/analyze.cpp
+++ b/src/analyze/analyze.cpp
@@ -19,10 +19,8 @@ See the Mulan PSL v2 for more details. */
 #include "defs.h"
 #include "errors.h"
 #include "parser/ast.h"
-template <typename type>
-inline bool no_overflow(const std::string &value);
-int compare_int_string(const std::string &val1, const std::string &val2);
-int compare_pos_int_string(const std::string &val1, const std::string &val2);
+// template <typename type>
+// inline bool no_overflow(const std::string &value);
 
 /**
  * @description:
@@ -415,38 +413,3 @@ CompOp Analyze::convert_sv_comp_op(ast::SvCompOp op) {
     return m.at(op);
 }
 
-// util functtion
-// 相等返回0,val1大于val2返回1,小于返回-1
-int compare_pos_int_string(const std::string &val1, const std::string &val2) {
-    int len1 = val1.size(), len2 = val2.size();
-    if (len1 > len2) {
-        return 1;
-    } else if (len1 < len2) {
-        return -1;
-    } else {
-        for (size_t i = 0; i < val1.size(); ++i) {
-            if (val1[i] > val2[i]) {
-                return 1;
-            } else if (val1[i] < val2[i]) {
-                return -1;
-            }
-        }
-        return 0;
-    }
-}
-
-// 相等返回0,val1大于val2返回1,小于返回-1
-int compare_int_string(const std::string &val1, const std::string &val2) {
-    assert(!val1.empty() && !val2.empty());
-
-    if (val2[0] == '-' && val1[0] != '-') {
-        return 1;
-    } else if (val1[0] == '-' && val2[0] != '-') {
-        return -1;
-    } else if (val1[0] == '-' && val2[0] == '-') {
-        return -compare_pos_int_string(val1.substr(1), val2.substr(1));
-    } else {
-        return compare_pos_int_string(val1[0] == '+' ? val1.substr(1) : val1, val2[0] == '+' ? val2.substr(1) : val2);
-    }
-}
-
diff --git a/src/analyze/analyze.h b/src/analyze/analyze.h
index 15029cf..863570d 100644
--- a/src/analyze/analyze.h
+++ b/src/analyze/analyze.h
@@ -20,11 +20,7 @@ See the Mulan PSL v2 for more details. */
 #include "parser/ast.h"
 #include "parser/parser.h"
 #include "system/sm.h"
-template <typename type>
-inline bool no_overflow(const std::string &value) {
-    return (compare_int_string(value, std::to_string(std::numeric_limits<type>::max())) <= 0) &&
-           (compare_int_string(value, std::to_string(std::numeric_limits<type>::lowest())) >= 0);
-}
+
 
 class Query {
    public:
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index b28b04f..e69de29 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -1,3 +0,0 @@
-
-
-
diff --git a/src/common/common.h b/src/common/common.h
index c8ee6df..918c615 100644
--- a/src/common/common.h
+++ b/src/common/common.h
@@ -16,13 +16,54 @@ See the Mulan PSL v2 for more details. */
 #include <string>
 #include <vector>
 
-#include "analyze/analyze.h"
+
 #include "defs.h"
 #include "errors.h"
 #include "parser/ast.h"
 #include "record/rm_defs.h"
 #include "system/sm_meta.h"
 
+
+// util functtion
+// 相等返回0,val1大于val2返回1,小于返回-1
+static int compare_pos_int_string(const std::string &val1, const std::string &val2) {
+    int len1 = val1.size(), len2 = val2.size();
+    if (len1 > len2) {
+        return 1;
+    } else if (len1 < len2) {
+        return -1;
+    } else {
+        for (size_t i = 0; i < val1.size(); ++i) {
+            if (val1[i] > val2[i]) {
+                return 1;
+            } else if (val1[i] < val2[i]) {
+                return -1;
+            }
+        }
+        return 0;
+    }
+}
+
+// 相等返回0,val1大于val2返回1,小于返回-1
+static int compare_int_string(const std::string &val1, const std::string &val2) {
+    assert(!val1.empty() && !val2.empty());
+
+    if (val2[0] == '-' && val1[0] != '-') {
+        return 1;
+    } else if (val1[0] == '-' && val2[0] != '-') {
+        return -1;
+    } else if (val1[0] == '-' && val2[0] == '-') {
+        return -compare_pos_int_string(val1.substr(1), val2.substr(1));
+    } else {
+        return compare_pos_int_string(val1[0] == '+' ? val1.substr(1) : val1, val2[0] == '+' ? val2.substr(1) : val2);
+    }
+}
+
+template <typename type>
+bool no_overflow(const std::string &value) {
+    return (compare_int_string(value, std::to_string(std::numeric_limits<type>::max())) <= 0) &&
+           (compare_int_string(value, std::to_string(std::numeric_limits<type>::lowest())) >= 0);
+}
 enum AggType { COUNT, MAX, MIN, SUM };
 
 struct TabCol {
diff --git a/src/execution/execution_manager.cpp b/src/execution/execution_manager.cpp
index 7228d13..8e7428f 100644
--- a/src/execution/execution_manager.cpp
+++ b/src/execution/execution_manager.cpp
@@ -90,6 +90,7 @@ void QlManager::run_cmd_utility(std::shared_ptr<Plan> plan, txn_id_t *txn_id, Co
             case T_LOAD :{
                 auto plan = std::dynamic_pointer_cast<LoadPlan>(x);
                 sm_manager_->load_data(plan->file_path_,plan->tab_name_,context);
+                break;
             }
             case T_ShowTable: {
                 sm_manager_->show_tables(context);
diff --git a/src/optimizer/optimizer.h b/src/optimizer/optimizer.h
index b56c64b..3ea17c0 100644
--- a/src/optimizer/optimizer.h
+++ b/src/optimizer/optimizer.h
@@ -36,7 +36,7 @@ class Optimizer {
             return std::make_shared<OtherPlan>(T_Help, std::string());
         } else if (auto x = std::dynamic_pointer_cast<ast::LoadData>(query->parse)) {
             // load data
-            return std::make_shared<LoadPlan>(T_LOAD, std::string());
+            return std::make_shared<LoadPlan>(T_LOAD, x->file_path,x->tab_name);
         } else if (auto x = std::dynamic_pointer_cast<ast::ShowTables>(query->parse)) {
             // show tables;
             return std::make_shared<OtherPlan>(T_ShowTable, std::string());
diff --git a/src/optimizer/plan.h b/src/optimizer/plan.h
index 8707b92..980d989 100644
--- a/src/optimizer/plan.h
+++ b/src/optimizer/plan.h
@@ -183,10 +183,7 @@ class OtherPlan : public Plan {
 class LoadPlan  : public OtherPlan {
    public:
     std::string file_path_;
-    LoadPlan(PlanTag tag, std::string file_path,std::string tab_name) {
-        Plan::tag = tag;
-        tab_name_ = std::move(tab_name);
-        file_path_ = std::move(file_path);
+    LoadPlan(PlanTag tag, std::string file_path,std::string tab_name): OtherPlan(tag,tab_name),file_path_(std::move(file_path)){
     }
     ~LoadPlan() {}
 };
diff --git a/src/parser/lex.l b/src/parser/lex.l
index 8b52589..fd4c451 100644
--- a/src/parser/lex.l
+++ b/src/parser/lex.l
@@ -42,6 +42,7 @@ identifier {alpha}(_|{alpha}|{digit})*
 value_int_bigint {digit}+
 value_float {digit}+\.({digit}+)?
 value_string '[^']*'
+file_path ((\.)?(\.)?\/[^\/ ]*)+\/?
 single_op ";"|"("|")"|","|"*"|"="|">"|"<"|"."
 
 %x STATE_COMMENT
@@ -120,6 +121,10 @@ single_op ";"|"("|")"|","|"*"|"="|">"|"<"|"."
 {value_string} {
     yylval->sv_str = std::string(yytext + 1, strlen(yytext) - 2);
     return VALUE_STRING;
+}
+{file_path} {
+    yylval->sv_str = std::string(yytext , strlen(yytext));
+return VALUE_STRING;
 }
     /* EOF */
 <<EOF>> { return T_EOF; }
diff --git a/src/record/rm_file_handle.cpp b/src/record/rm_file_handle.cpp
index 5062f2f..f4df8fa 100644
--- a/src/record/rm_file_handle.cpp
+++ b/src/record/rm_file_handle.cpp
@@ -55,21 +55,22 @@ Rid RmFileHandle::insert_record(char *buf, Context *context) {
         if (!Bitmap::is_set(page_hdl.bitmap, i)) {
             auto &page_hdr = page_hdl.page_hdr;
             const PageId &page_id = page_hdl.page->get_page_id();
-            Rid rid{page_id.page_no, i};
-            if (context->txn_->get_state() == TransactionState::DEFAULT ||
-                context->txn_->get_state() == TransactionState::GROWING) {
-                auto rec = RmRecord(file_hdr_.record_size, buf);
-                auto table_name = disk_manager_->get_file_name(fd_);
-                auto insertRec = std::make_unique<WriteRecord>(WType::INSERT_TUPLE, table_name, rid, rec);
-                context->log_mgr_->gen_log_from_write_set(context->txn_, insertRec.get());
-                context->txn_->append_write_record(std::move(insertRec));
-            } else {
-                assert(false);
-            }
-            page_hdr->page_lsn = page_hdr->page_lsn > context->txn_->get_so_far_lsn() ? page_hdr->page_lsn
-                                                                                      : context->txn_->get_so_far_lsn();
-            if (!page_hdl.page->is_dirty()) {
-                page_hdl.page_hdr->rec_lsn = context->txn_->get_so_far_lsn();
+            Rid rid{page_id.page_no,i};
+            if(context!=nullptr){
+                if (context->txn_->get_state() == TransactionState::DEFAULT ||context->txn_->get_state() == TransactionState::GROWING ) {
+                    auto rec = RmRecord(file_hdr_.record_size,buf);
+                    auto table_name = disk_manager_->get_file_name(fd_);
+                    auto insertRec = std::make_unique < WriteRecord > (WType::INSERT_TUPLE,table_name , rid,rec);
+                    context->log_mgr_->gen_log_from_write_set(context->txn_,insertRec.get());
+                    context->txn_->append_write_record(std::move(insertRec));
+                }else {
+                    assert(false);
+                }
+                page_hdr->page_lsn =page_hdr->page_lsn > context->txn_->get_so_far_lsn()?page_hdr->page_lsn: context->txn_->get_so_far_lsn();
+                if(!page_hdl.page->is_dirty()){
+                    page_hdl.page_hdr->rec_lsn = context->txn_->get_so_far_lsn();
+                }
+
             }
 
             // insert data
diff --git a/src/system/sm_manager.cpp b/src/system/sm_manager.cpp
index bb01baf..95475f6 100644
--- a/src/system/sm_manager.cpp
+++ b/src/system/sm_manager.cpp
@@ -152,11 +152,14 @@ void SmManager::load_data(const std::string& file_path, const std::string& tab_n
                 }
             }
         }else {
+            RmRecord rec (fhs_[tab_name]->get_record_size());
             for (auto i = 0; i < tab_meta.cols.size(); i++) {
                 std::getline(ss, field, ',');
+                auto col = tab_meta.cols[i];
                 auto value = Value::convert_from_string(field,tab_meta.cols[i]);
+                memcpy(rec.data + col.offset, value.raw->data, col.len);
             }
-
+            fhs_[tab_name]->insert_record(rec.data,nullptr);
         }
     }
 
diff --git a/src/unit_test.cpp b/src/unit_test.cpp
index 2b3cbd4..6ee08e4 100644
--- a/src/unit_test.cpp
+++ b/src/unit_test.cpp
@@ -304,7 +304,7 @@ TEST_F(BufferPoolManagerTest, DISABLED_SampleTest) {
     const size_t buffer_pool_size = 10;
     auto disk_manager = BufferPoolManagerTest::disk_manager_.get();
     auto bpm =
-        std::make_unique<BufferPoolManager>(buffer_pool_size, disk_manager ,nullptr);
+        std::make_unique<BufferPoolManager>(buffer_pool_size, disk_manager,nullptr);
     // create tmp PageId
     int fd = BufferPoolManagerTest::fd_;
     PageId page_id_temp = {.fd = fd, .page_no = INVALID_PAGE_ID};
-- 
GitLab