Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support truncate table statement #3542

Merged
merged 11 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions cases/plan/cmd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,22 @@ cases:
+-cmd_type: drop function
+-if_exists: true
+-args: [func1]
- id: truncate_stmt
desc: truncate
sql: TRUNCATE TABLE t1;
expect:
node_tree_str: |
+-node[CMD]
+-cmd_type: truncate table
+-args: [t1]
- id: truncate_stmt_db
desc: truncate
sql: TRUNCATE TABLE db1.t1;
expect:
node_tree_str: |
+-node[CMD]
+-cmd_type: truncate table
+-args: [db1, t1]
- id: exit_stmt
desc: exit statement
sql: EXIT;
Expand Down
16 changes: 16 additions & 0 deletions docs/en/reference/sql/ddl/TRUNCATE_TABLE_STATEMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# TRUNCATE TABLE

```
TRUNCATE TABLE table_name
```

`TRUNCATE TABLE` statement is used to clear the specified table.

## Example: clear t1

```sql
TRUNCATE TABLE t1;
-- Truncate table t1? yes/no
-- yes
-- SUCCEED
```
1 change: 1 addition & 0 deletions docs/en/reference/sql/ddl/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ Data Definition Statement (DDL)
SHOW_FUNCTIONS
DROP_FUNCTION
SHOW_CREATE_TABLE_STATEMENT
TRUNCATE_TABLE_STATEMENT
16 changes: 16 additions & 0 deletions docs/zh/openmldb_sql/ddl/TRUNCATE_TABLE_STATEMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# TRUNCATE TABLE

```
TRUNCATE TABLE table_name
```

`TRUNCATE TABLE`语句用清空指定的表。

## Example: 清空t1表

```sql
TRUNCATE TABLE t1;
-- Truncate table t1? yes/no
-- yes
-- SUCCEED
```
1 change: 1 addition & 0 deletions docs/zh/openmldb_sql/ddl/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@
SHOW_FUNCTIONS
DROP_FUNCTION
SHOW_CREATE_TABLE_STATEMENT
TRUNCATE_TABLE_STATEMENT
1 change: 1 addition & 0 deletions hybridse/include/node/node_enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ enum CmdType {
kCmdDropFunction,
kCmdShowJobLog,
kCmdShowCreateTable,
kCmdTruncate,
kCmdFake, // not a real cmd, for testing purpose only
kLastCmd = kCmdFake,
};
Expand Down
1 change: 1 addition & 0 deletions hybridse/src/node/sql_node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ static absl::flat_hash_map<CmdType, absl::string_view> CreateCmdTypeNamesMap() {
{CmdType::kCmdDropFunction, "drop function"},
{CmdType::kCmdShowFunctions, "show functions"},
{CmdType::kCmdShowJobLog, "show joblog"},
{CmdType::kCmdTruncate, "truncate table"},
};
for (auto kind = 0; kind < CmdType::kLastCmd; ++kind) {
DCHECK(map.find(static_cast<CmdType>(kind)) != map.end());
Expand Down
10 changes: 10 additions & 0 deletions hybridse/src/planv2/ast_node_converter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,16 @@ base::Status ConvertStatement(const zetasql::ASTStatement* statement, node::Node
*output = node;
break;
}
case zetasql::AST_TRUNCATE_STATEMENT: {
const zetasql::ASTTruncateStatement* truncate_statement =
statement->GetAsOrNull<zetasql::ASTTruncateStatement>();
std::vector<std::string> names;
CHECK_STATUS(AstPathExpressionToStringList(truncate_statement->target_path(), names));
auto node =
dynamic_cast<node::CmdNode*>(node_manager->MakeCmdNode(node::CmdType::kCmdTruncate, names));
*output = node;
break;
}
case zetasql::AST_DROP_FUNCTION_STATEMENT: {
const zetasql::ASTDropFunctionStatement* drop_fun_statement =
statement->GetAsOrNull<zetasql::ASTDropFunctionStatement>();
Expand Down
6 changes: 5 additions & 1 deletion src/base/status.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ enum ReturnCode {
kExceedMaxMemory = 160,
kInvalidArgs = 161,
kCheckIndexFailed = 162,
kCatalogUpdateFailed = 163,
kNameserverIsNotLeader = 300,
kAutoFailoverIsEnabled = 301,
kEndpointIsNotExist = 302,
Expand Down Expand Up @@ -127,7 +128,10 @@ enum ReturnCode {
kCheckParameterFailed = 331,
kCreateProcedureFailedOnTablet = 332,
kCreateFunctionFailedOnTablet = 333,
kOPAlreadyExists = 317,
kOPAlreadyExists = 334,
kOffsetMismatch = 335,
kGetTabletFailed = 336,
kTruncateTableFailed = 337,
kReplicaClusterAliasDuplicate = 400,
kConnectRelicaClusterZkFailed = 401,
kNotSameReplicaName = 402,
Expand Down
2 changes: 1 addition & 1 deletion src/catalog/tablet_catalog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ void TabletTableHandler::AddTable(std::shared_ptr<::openmldb::storage::Table> ta
do {
old_tables = std::atomic_load_explicit(&tables_, std::memory_order_acquire);
new_tables = std::make_shared<Tables>(*old_tables);
new_tables->emplace(table->GetPid(), table);
new_tables->insert_or_assign(table->GetPid(), table);
} while (!atomic_compare_exchange_weak(&tables_, &old_tables, new_tables));
}

Expand Down
13 changes: 13 additions & 0 deletions src/client/ns_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,19 @@ bool NsClient::DropTable(const std::string& db, const std::string& name, std::st
return false;
}

base::Status NsClient::TruncateTable(const std::string& db, const std::string& name) {
::openmldb::nameserver::TruncateTableRequest request;
request.set_name(name);
request.set_db(db);
::openmldb::nameserver::TruncateTableResponse response;
bool ok = client_.SendRequest(&::openmldb::nameserver::NameServer_Stub::TruncateTable, &request, &response,
FLAGS_request_timeout_ms, 1);
if (ok && response.code() == 0) {
return {};
}
return {response.code(), response.msg()};
}

bool NsClient::SyncTable(const std::string& name, const std::string& cluster_alias, uint32_t pid, std::string& msg) {
::openmldb::nameserver::SyncTableRequest request;
request.set_name(name);
Expand Down
2 changes: 2 additions & 0 deletions src/client/ns_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ class NsClient : public Client {
bool DropTable(const std::string& db, const std::string& name,
std::string& msg); // NOLINT

base::Status TruncateTable(const std::string& db, const std::string& name);

bool SyncTable(const std::string& name, const std::string& cluster_alias, uint32_t pid,
std::string& msg); // NOLINT

Expand Down
14 changes: 14 additions & 0 deletions src/client/tablet_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,20 @@ bool TabletClient::SQLBatchRequestQuery(const std::string& db, const std::string
return true;
}

base::Status TabletClient::TruncateTable(uint32_t tid, uint32_t pid) {
::openmldb::api::TruncateTableRequest request;
::openmldb::api::TruncateTableResponse response;
request.set_tid(tid);
request.set_pid(pid);
if (!client_.SendRequest(&::openmldb::api::TabletServer_Stub::TruncateTable, &request, &response,
FLAGS_request_timeout_ms, 1)) {
return {base::ReturnCode::kRPCError, "send request failed!"};
} else if (response.code() == 0) {
return {};
}
return {response.code(), response.msg()};
}

base::Status TabletClient::CreateTable(const ::openmldb::api::TableMeta& table_meta) {
::openmldb::api::CreateTableRequest request;
::openmldb::api::TableMeta* table_meta_ptr = request.mutable_table_meta();
Expand Down
2 changes: 2 additions & 0 deletions src/client/tablet_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class TabletClient : public Client {

base::Status CreateTable(const ::openmldb::api::TableMeta& table_meta);

base::Status TruncateTable(uint32_t tid, uint32_t pid);

bool UpdateTableMetaForAddField(uint32_t tid, const std::vector<openmldb::common::ColumnDesc>& cols,
const openmldb::common::VersionPair& pair,
std::string& msg); // NOLINT
Expand Down
41 changes: 41 additions & 0 deletions src/cmd/sql_cmd_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,47 @@ TEST_P(DBSDKTest, DeployWithBias) {
ASSERT_TRUE(cs->GetNsClient()->DropDatabase(db, msg));
}

TEST_P(DBSDKTest, Truncate) {
auto cli = GetParam();
sr = cli->sr;
std::string db_name = "test2";
std::string table_name = "test1";
std::string ddl = "create table test1 (c1 string, c2 int, c3 bigint, INDEX(KEY=c1, ts=c3));";
ProcessSQLs(sr, {
"set @@execute_mode = 'online'",
absl::StrCat("create database ", db_name, ";"),
absl::StrCat("use ", db_name, ";"),
ddl,
});
hybridse::sdk::Status status;
sr->ExecuteSQL(absl::StrCat("truncate table ", table_name, ";"), &status);
ASSERT_TRUE(status.IsOK()) << status.ToString();
auto res = sr->ExecuteSQL(absl::StrCat("select * from ", table_name, ";"), &status);
ASSERT_EQ(res->Size(), 0);
for (int i = 0; i < 10; i++) {
std::string key = absl::StrCat("key", i);
for (int j = 0; j < 10; j++) {
uint64_t ts = 1000 + j;
sr->ExecuteSQL(absl::StrCat("insert into ", table_name, " values ('", key, "', 11, ", ts, ");"), &status);
}
}

res = sr->ExecuteSQL(absl::StrCat("select * from ", table_name, ";"), &status);
ASSERT_EQ(res->Size(), 100);
sr->ExecuteSQL(absl::StrCat("truncate table ", table_name, ";"), &status);
ASSERT_TRUE(status.IsOK()) << status.ToString();
res = sr->ExecuteSQL(absl::StrCat("select * from ", table_name, ";"), &status);
ASSERT_EQ(res->Size(), 0);
sr->ExecuteSQL(absl::StrCat("insert into ", table_name, " values ('aa', 11, 100);"), &status);
res = sr->ExecuteSQL(absl::StrCat("select * from ", table_name, ";"), &status);
ASSERT_EQ(res->Size(), 1);
ProcessSQLs(sr, {
absl::StrCat("use ", db_name, ";"),
absl::StrCat("drop table ", table_name),
absl::StrCat("drop database ", db_name),
});
}

TEST_P(DBSDKTest, DeletetRange) {
auto cli = GetParam();
sr = cli->sr;
Expand Down
84 changes: 84 additions & 0 deletions src/nameserver/name_server_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3713,6 +3713,69 @@ void NameServerImpl::CreateTable(RpcController* controller, const CreateTableReq
}
}

void NameServerImpl::TruncateTable(RpcController* controller, const TruncateTableRequest* request,
TruncateTableResponse* response, Closure* done) {
brpc::ClosureGuard done_guard(done);
const std::string& db = request->db();
const std::string& name = request->name();
std::shared_ptr<::openmldb::nameserver::TableInfo> table_info;
{
std::lock_guard<std::mutex> lock(mu_);
if (!GetTableInfoUnlock(request->name(), request->db(), &table_info)) {
PDLOG(WARNING, "table[%s] does not exist in db [%s]", name.c_str(), db.c_str());
response->set_code(::openmldb::base::ReturnCode::kTableIsNotExist);
response->set_msg("table does not exist");
return;
}
if (IsExistActiveOp(db, name)) {
PDLOG(WARNING, "there is active op. db [%s] name [%s]", db.c_str(), name.c_str());
response->set_code(::openmldb::base::ReturnCode::kOPAlreadyExists);
response->set_msg("there is active op");
return;
}
}
uint32_t tid = table_info->tid();
for (const auto& partition : table_info->table_partition()) {
uint32_t offset = 0;
for (const auto& partition_meta : partition.partition_meta()) {
if (partition_meta.offset() != offset) {
if (offset == 0) {
offset = partition_meta.offset();
} else {
PDLOG(WARNING, "table[%s] partition [%d] offset mismatch", name.c_str(), partition.pid());
response->set_code(::openmldb::base::ReturnCode::kOffsetMismatch);
response->set_msg("partition offset mismatch");
return;
}
}
}
}
for (const auto& partition : table_info->table_partition()) {
uint32_t pid = partition.pid();
for (const auto& partition_meta : partition.partition_meta()) {
const auto& endpoint = partition_meta.endpoint();
auto tablet_ptr = GetTablet(endpoint);
if (!tablet_ptr) {
PDLOG(WARNING, "endpoint[%s] can not find client", endpoint.c_str());
response->set_code(::openmldb::base::ReturnCode::kGetTabletFailed);
response->set_msg("fail to get client, endpint " + endpoint);
return;
}
auto status = tablet_ptr->client_->TruncateTable(tid, pid);
if (!status.OK()) {
PDLOG(WARNING, "truncate failed, tid[%u] pid[%u] endpoint[%s] msg [%s]",
tid, pid, endpoint.c_str(), status.GetMsg().c_str());
response->set_code(::openmldb::base::ReturnCode::kTruncateTableFailed);
response->set_msg(status.GetMsg());
return;
}
}
}
PDLOG(INFO, "truncate success, db[%s] name[%s]", db.c_str(), name.c_str());
response->set_code(::openmldb::base::ReturnCode::kOk);
response->set_msg("ok");
}

bool NameServerImpl::SaveTableInfo(std::shared_ptr<TableInfo> table_info) {
std::string table_value;
table_info->SerializeToString(&table_value);
Expand Down Expand Up @@ -10568,5 +10631,26 @@ bool NameServerImpl::IsExistActiveOp(const std::string& db, const std::string& n
return false;
}

bool NameServerImpl::IsExistActiveOp(const std::string& db, const std::string& name) {
for (const auto& op_list : task_vec_) {
if (op_list.empty()) {
continue;
}
for (const auto& op_data : op_list) {
if (!db.empty() && op_data->op_info_.db() != db) {
continue;
}
if (!name.empty() && op_data->op_info_.name() != name) {
continue;
}
if (op_data->op_info_.task_status() == api::TaskStatus::kInited ||
op_data->op_info_.task_status() == api::TaskStatus::kDoing) {
return true;
}
}
}
return false;
}

} // namespace nameserver
} // namespace openmldb
4 changes: 4 additions & 0 deletions src/nameserver/name_server_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ class NameServerImpl : public NameServer {
void DropTable(RpcController* controller, const DropTableRequest* request, GeneralResponse* response,
Closure* done);

void TruncateTable(RpcController* controller, const TruncateTableRequest* request,
TruncateTableResponse* response, Closure* done);

void AddTableField(RpcController* controller, const AddTableFieldRequest* request, GeneralResponse* response,
Closure* done);

Expand Down Expand Up @@ -683,6 +686,7 @@ class NameServerImpl : public NameServer {
bool IsExistDataBase(const std::string& db);

bool IsExistActiveOp(const std::string& db, const std::string& name, api::OPType op_type);
bool IsExistActiveOp(const std::string& db, const std::string& name);

private:
std::mutex mu_;
Expand Down
11 changes: 11 additions & 0 deletions src/proto/name_server.proto
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ message DropTableRequest {
optional string db = 4 [default = ""];
}

message TruncateTableRequest {
optional string name = 1;
optional string db = 2;
}

message TruncateTableResponse {
optional int32 code = 1;
optional string msg = 2;
}

message LoadTableRequest {
optional string name = 1;
optional string endpoint = 2;
Expand Down Expand Up @@ -529,6 +539,7 @@ message DeploySQLResponse {
service NameServer {
rpc CreateTable(CreateTableRequest) returns (GeneralResponse);
rpc DropTable(DropTableRequest) returns (GeneralResponse);
rpc TruncateTable(TruncateTableRequest) returns (TruncateTableResponse);
rpc ShowTablet(ShowTabletRequest) returns (ShowTabletResponse);
rpc ShowTable(ShowTableRequest) returns (ShowTableResponse);
rpc MakeSnapshotNS(MakeSnapshotNSRequest) returns (GeneralResponse);
Expand Down
Loading