Skip to content

Commit

Permalink
fix issue 4056 (#4063)
Browse files Browse the repository at this point in the history
  • Loading branch information
ray6080 committed Aug 12, 2024
1 parent 93a3cd3 commit 9f2fc90
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/include/main/client_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class KUZU_API ClientContext {
const std::unordered_map<std::string, std::unique_ptr<common::Value>>& inputParams);

std::unique_ptr<QueryResult> executeAndAutoCommitIfNecessaryNoLock(
PreparedStatement* preparedStatement, uint32_t planIdx = 0u, bool requiredNexTx = true,
PreparedStatement* preparedStatement, uint32_t planIdx = 0u,
std::optional<uint64_t> queryID = std::nullopt);

bool canExecuteWriteQuery();
Expand Down
13 changes: 6 additions & 7 deletions src/main/client_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,8 @@ std::unique_ptr<QueryResult> ClientContext::query(std::string_view query,
for (auto& statement : parsedStatements) {
auto preparedStatement = prepareNoLock(statement,
enumerateAllPlans /* enumerate all plans */, encodedJoin, false /*requireNewTx*/);
auto currentQueryResult = executeAndAutoCommitIfNecessaryNoLock(preparedStatement.get(), 0u,
false /*requiredNexTx*/, queryID);
auto currentQueryResult =
executeAndAutoCommitIfNecessaryNoLock(preparedStatement.get(), 0u, queryID);
if (!lastResult) {
// first result of the query
queryResult = std::move(currentQueryResult);
Expand Down Expand Up @@ -442,7 +442,7 @@ std::unique_ptr<QueryResult> ClientContext::executeWithParams(PreparedStatement*
KU_ASSERT(preparedStatement->parsedStatement != nullptr);
auto rebindPreparedStatement = prepareNoLock(preparedStatement->parsedStatement, false, "",
false, preparedStatement->parameterMap);
return executeAndAutoCommitIfNecessaryNoLock(rebindPreparedStatement.get(), 0u, false, queryID);
return executeAndAutoCommitIfNecessaryNoLock(rebindPreparedStatement.get(), 0u, queryID);
}

void ClientContext::bindParametersNoLock(PreparedStatement* preparedStatement,
Expand All @@ -461,12 +461,11 @@ void ClientContext::bindParametersNoLock(PreparedStatement* preparedStatement,
}

std::unique_ptr<QueryResult> ClientContext::executeAndAutoCommitIfNecessaryNoLock(
PreparedStatement* preparedStatement, uint32_t planIdx, bool requiredNexTx,
std::optional<uint64_t> queryID) {
PreparedStatement* preparedStatement, uint32_t planIdx, std::optional<uint64_t> queryID) {
if (!preparedStatement->isSuccess()) {
return queryResultWithError(preparedStatement->errMsg);
}
if (preparedStatement->parsedStatement->requireTx() && requiredNexTx && getTx() == nullptr) {
if (preparedStatement->parsedStatement->requireTx() && getTx() == nullptr) {
this->transactionContext->beginAutoTransaction(preparedStatement->isReadOnly());
}
this->resetActiveQuery();
Expand Down Expand Up @@ -586,7 +585,7 @@ void ClientContext::runQuery(std::string query) {
for (auto& statement : parsedStatements) {
auto preparedStatement = prepareNoLock(statement, false, "", false);
auto currentQueryResult =
executeAndAutoCommitIfNecessaryNoLock(preparedStatement.get(), 0u, false);
executeAndAutoCommitIfNecessaryNoLock(preparedStatement.get(), 0u);
if (!currentQueryResult->isSuccess()) {
throw ConnectionException(currentQueryResult->errMsg);
}
Expand Down
2 changes: 1 addition & 1 deletion src/storage/store/update_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ VectorUpdateInfo& UpdateInfo::getOrCreateVectorInfo(const Transaction* transacti
// Same transaction.
KU_ASSERT(current->version >= Transaction::START_TRANSACTION_ID);
info = current;
} else if (current->version >= transaction->getStartTS()) {
} else if (current->version > transaction->getStartTS()) {
// Potentially there can be conflicts. `current` can be uncommitted transaction (version
// is transaction ID) or committed transaction started after this transaction.
for (auto i = 0u; i < current->numRowsUpdated; i++) {
Expand Down
1 change: 1 addition & 0 deletions test/storage/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ add_kuzu_test(compression_test compression_test.cpp)
add_kuzu_test(local_hash_index_test local_hash_index_test.cpp)
add_kuzu_test(buffer_manager_test buffer_manager_test.cpp)
add_kuzu_test(rel_scan_test rel_scan_test.cpp)
add_kuzu_test(node_update_test node_update_test.cpp)
31 changes: 31 additions & 0 deletions test/storage/node_update_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "graph_test/graph_test.h"

namespace kuzu {
namespace testing {

class NodeUpdateTest : public EmptyDBTest {
protected:
void SetUp() override {
EmptyDBTest::SetUp();
createDBAndConn();
}

void TearDown() override { EmptyDBTest::TearDown(); }
};

TEST_F(NodeUpdateTest, UpdateSameRow) {
ASSERT_TRUE(conn->query("CREATE NODE TABLE IF NOT EXISTS Product (item STRING, price INT64, "
"PRIMARY KEY (item))")
->isSuccess());
ASSERT_TRUE(conn->query("CREATE (n:Product {item: 'watch'}) SET n.price = 100")->isSuccess());
ASSERT_TRUE(
conn->query("MATCH (n:Product) WHERE n.item = 'watch' SET n.price = 200")->isSuccess());
ASSERT_TRUE(
conn->query("MATCH (n:Product) WHERE n.item = 'watch' SET n.price = 300")->isSuccess());
const auto res = conn->query("MATCH (n:Product) RETURN n.price");
ASSERT_TRUE(res->isSuccess() && res->hasNext());
ASSERT_EQ(res->getNext()->getValue(0)->val.int64Val, 300);
}

} // namespace testing
} // namespace kuzu

0 comments on commit 9f2fc90

Please sign in to comment.