Skip to content

Commit

Permalink
feat: Add overloaded version for Insert() & Delete() in common_checke…
Browse files Browse the repository at this point in the history
…r.h (#578)

* feat: Add overloaded version for Insert() & Delete() in common_checker.h

* feat: Add ExecuteSqlTxn result check logic && improve printed messages

* fix: Ensure format consistency
  • Loading branch information
xzhseh authored Jul 1, 2023
1 parent 3531cf1 commit 9553f1c
Showing 1 changed file with 95 additions and 0 deletions.
95 changes: 95 additions & 0 deletions test/concurrency/common_checker.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,71 @@ auto Insert(Transaction *txn, BustubInstance &instance, int v1) -> void {
ASSERT_EQ(ss.str(), "3,\n");
}

/// @brief Use this to write your own test cases, if needed
/// @param v1_vec Elements to be insert into `t1:v1`, the size of which can either be 1, or same as @v2_vec
/// @param v2_vec Elements to be insert into `t1:v2`, must not be empty
/// @param flag When set to `true`, the size of @v1_vec should be exactly one, the default value is `false`
/// Usage: Insert(txn, instance, {1, 2, 3}, {4, 5, 6}, flag = false);
/// This overloaded function will then bound each pair from @v1_vec & @v2_vec as a insert value
/// If flag is set to `true`, v1_vec should contain exactly one element,
/// The insert pair will be {v1_vec[0], v2_vec[0]}, {v1_vec[0], v2_vec[1]} ...
auto Insert(Transaction *txn, BustubInstance &instance, const std::vector<int> &v1_vec, const std::vector<int> &v2_vec,
bool flag = false) -> void {
// Check if the input vectors have the same size.
if (!flag) {
if (v1_vec.size() != v2_vec.size()) {
fmt::print(stderr, "Vectors @v1_vec and @v2_vec must have the same size\n");
return;
}
if (v1_vec.empty()) {
fmt::print(stderr, "Input vectors must not be empty\n");
return;
}
} else {
if (v1_vec.size() != 1) {
fmt::print(stderr, "Size of @v1_vec should be exactly 1 if flag is set to `true`\n");
return;
}
if (v2_vec.empty()) {
fmt::print(stderr, "Input vectors must not be empty\n");
return;
}
}

std::stringstream ss;
auto writer = bustub::SimpleStreamWriter(ss, true, ",");

assert(v1_vec.size() == 1);
std::string val_str{};
if (!flag) {
for (size_t i = 0; i < v1_vec.size(); ++i) {
val_str += fmt::format("({}, {}), ", v1_vec[i], v2_vec[i]);
}
} else {
for (const auto &v2 : v2_vec) {
val_str += fmt::format("({}, {}), ", v1_vec[0], v2);
}
}

// Remove the last comma and space
assert(!val_str.empty() && val_str.size() >= 2);
val_str.pop_back();
val_str.pop_back();

fmt::print(stderr, "insert data with @v1_vec = {} and @v2_vec = {} in txn {} {}\n", v1_vec, v2_vec,
txn->GetTransactionId(), txn->GetIsolationLevel());

std::string sql = "INSERT INTO t1 VALUES " + val_str;

bool res = instance.ExecuteSqlTxn(sql, writer, txn);
if (!res) {
fmt::print(stderr, "Failed to insert data with @v1_vec = {} and @v2_vec = {} in txn {} {}\n", v1_vec, v2_vec);
}

// The final number of inserted elements should be the size of @v2_vec
ASSERT_EQ(ss.str(), fmt::format("{},\n", v2_vec.size()));
}

auto Delete(Transaction *txn, BustubInstance &instance, int v1) -> void {
std::stringstream ss;
auto writer = bustub::SimpleStreamWriter(ss, true, ",");
Expand All @@ -39,6 +104,36 @@ auto Delete(Transaction *txn, BustubInstance &instance, int v1) -> void {
ASSERT_EQ(ss.str(), "3,\n");
}

/// @brief Use this to write your own test cases, if needed
/// @param d_vec Elements to be deleted from t1, represents the value of `t1:v1`
/// @param d_size The size you expect to be deleted from t1, will be used as sanity check, default value is 3
/// This overloaded function performs a vectorized self-constructed deletion to better test the implementation
/// You should calculate the number of elements that logically should be deleted, and pass it in as @d_size.
auto Delete(Transaction *txn, BustubInstance &instance, const std::vector<int> &d_vec, int d_size = 3) -> void {
if (d_vec.empty()) {
fmt::print(stderr, "Input vec must not be empty\n");
return;
}

assert(!d_vec.empty());

std::stringstream ss;
auto writer = bustub::SimpleStreamWriter(ss, true, ",");

for (const auto &v1 : d_vec) {
fmt::print(stderr, "delete data with v1 = {} in txn {} {}\n", v1, txn->GetTransactionId(),
txn->GetIsolationLevel());
std::string sql = fmt::format("DELETE FROM t1 WHERE v1 = {}", v1);
bool res = instance.ExecuteSqlTxn(sql, writer, txn);
if (!res) {
fmt::print(stderr, "Failed to delete data with v1 = {} in txn {} {}\n", v1, txn->GetTransactionId(),
txn->GetIsolationLevel());
}
}

ASSERT_EQ(ss.str(), fmt::format("{},\n", d_size));
}

auto ExpectResult(const std::string &actual_result, const std::string &expected_result) -> bool {
auto actual_result_rows = bustub::StringUtil::Split(actual_result, '\n');
auto expected_result_rows = bustub::StringUtil::Split(expected_result, '\n');
Expand Down

0 comments on commit 9553f1c

Please sign in to comment.