Untitled

mail@pastecode.io avatar
unknown
c_cpp
7 months ago
5.7 kB
2
Indexable
Never
//===----------------------------------------------------------------------===//
//
//                         BusTub
//
// delete_executor.cpp
//
// Identification: src/execution/delete_executor.cpp
//
// Copyright (c) 2015-2021, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

// #include <_types/_uint32_t.h>
#include "execution/executors/delete_executor.h"
#include <exception>
#include <memory>
#include "concurrency/transaction.h"
#include "concurrency/transaction_manager.h"
#include "storage/table/tuple.h"

namespace bustub {

DeleteExecutor::DeleteExecutor(ExecutorContext *exec_ctx, const DeletePlanNode *plan,
                               std::unique_ptr<AbstractExecutor> &&child_executor)
    : AbstractExecutor(exec_ctx) {
  child_executor_ = std::move(child_executor);
  plan_ = plan;
  table_info_ = exec_ctx_->GetCatalog()->GetTable(plan_->GetTableOid());
  first_call_ = false;
}

void DeleteExecutor::Init() {
  child_executor_->Init();
  first_call_ = true;
}

auto DeleteExecutor::Next([[maybe_unused]] Tuple *tuple, RID *rid) -> bool {
  if (!first_call_) {
    return false;
  }
  first_call_ = false;

  RID c_rid;
  Tuple c_tuple;
  std::vector<IndexInfo *> index_infos = exec_ctx_->GetCatalog()->GetTableIndexes(table_info_->name_);
  int32_t count = 0;

  // RID final_rid;

  while (child_executor_->Next(&c_tuple, &c_rid)) {
    count++;

    // check write-write conflict
    if (table_info_->table_->GetTupleMeta(c_rid).ts_ >= (1LL << 62) &&
        table_info_->table_->GetTupleMeta(c_rid).ts_ != exec_ctx_->GetTransaction()->GetTransactionTempTs()) {
      exec_ctx_->GetTransaction()->SetTainted();
      throw bustub::ExecutionException("ExecutionException");
    }

    if (table_info_->table_->GetTupleMeta(c_rid).ts_ < (1LL << 62) &&
        table_info_->table_->GetTupleMeta(c_rid).ts_ > exec_ctx_->GetTransaction()->GetReadTs()) {
      exec_ctx_->GetTransaction()->SetTainted();
      throw bustub::ExecutionException("ExecutionException");
    }

    // create undo log
    bool create_new = true;
    UndoLog new_undo;
    // int new_undo_index;
    UndoLink new_link;
    auto undo_link_optional = exec_ctx_->GetTransactionManager()->GetUndoLink(c_rid);
    if (undo_link_optional.has_value()) {
      auto undo_link = undo_link_optional.value();
      auto undo_log_optional = exec_ctx_->GetTransactionManager()->GetUndoLogOptional(undo_link);
      if (undo_log_optional.has_value()) {
        auto undo_log = undo_log_optional.value();
        if (undo_log.ts_ == exec_ctx_->GetTransaction()->GetTransactionTempTs()) {
          create_new = false;
          // new_undo_index = undo_link.prev_log_idx_;
          new_undo = undo_log;
          new_link = undo_link;
        }
      }
    }

    if (create_new) {
      new_undo.is_deleted_ = false;
      std::vector<bool> v(plan_->OutputSchema().GetColumnCount(), false);
      new_undo.modified_fields_ = v;
      new_undo.ts_ = table_info_->table_->GetTupleMeta(c_rid).ts_;
      new_undo.tuple_ = Tuple();
      if (undo_link_optional.has_value()) {
        new_undo.prev_version_ = undo_link_optional.value();
      }
      new_link = exec_ctx_->GetTransaction()->AppendUndoLog(new_undo);
    }

    new_undo.is_deleted_ = false;
    std::vector<bool> v(plan_->OutputSchema().GetColumnCount(), true);
    new_undo.modified_fields_ = v;
    new_undo.tuple_ = c_tuple;
    exec_ctx_->GetTransaction()->ModifyUndoLog(new_link.prev_log_idx_, new_undo);
    // exec_ctx_->UpdateUndoLink(record, std::nullopt, nullptr);
    exec_ctx_->GetTransactionManager()->UpdateUndoLink(c_rid, new_link);

    auto undo_link_optional_2 = exec_ctx_->GetTransactionManager()->GetUndoLink(c_rid);
    std::cout << "rid = " << c_rid << std::endl;
    if (undo_link_optional_2.has_value()) {
      // auto undo_link_2 = undo_link_optional_2.value();
      std::cout << "------------------------------ has value" << std::endl;
    }

    TupleMeta metadata;
    metadata.is_deleted_ = true;
    // metadata.ts_ = 0;
    metadata.ts_ = exec_ctx_->GetTransaction()->GetTransactionTempTs();

    // auto inserted_rid = table_info_->table_->InsertTuple(metadata, c_tuple, exec_ctx_->GetLockManager(),
    // exec_ctx_->GetTransaction(), plan_->GetTableOid());

    table_info_->table_->UpdateTupleMeta(metadata, c_rid);

    // delete probably does not need to update index (just need to set is_deleted_ to true)
    // but here I still deleted it (same for update)
    for (auto &index_info : index_infos) {
      auto metadatadelete = index_info->index_->GetMetadata();
      auto key_attr = metadatadelete->GetKeyAttrs();
      auto key_schema = index_info->index_->GetKeySchema();
      auto key = c_tuple.KeyFromTuple(table_info_->schema_, *key_schema, key_attr);

      index_info->index_->DeleteEntry(key, c_rid, exec_ctx_->GetTransaction());
      // index_info->index_->InsertEntry(key, inserted_rid.value(), exec_ctx_->GetTransaction());
    }

    exec_ctx_->GetTransaction()->AppendWriteSet(plan_->table_oid_, c_rid);

    // final_rid = inserted_rid.value();
    // final_rid = c_rid;
  }

  Value v(INTEGER, count);
  Tuple new_tuple({v}, &plan_->OutputSchema());
  *tuple = new_tuple;

  // auto transaction_id = exec_ctx_->GetTransaction()->GetTransactionId();
  // std::cout << "delete's transaction_id = " << transaction_id << std::endl;
  // exec_ctx_->GetTransaction()->AppendWriteSet(plan_->table_oid_, final_rid);  // add???
  // std::cout << "################ DELETE AppendWriteSet called for " << plan_->table_oid_ << ", deleted_rid = " <<
  // final_rid << std::endl;

  return true;
}

}  // namespace bustub
Leave a Comment