This is an automated email from the ASF dual-hosted git repository. alexey pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/kudu.git
The following commit(s) were added to refs/heads/master by this push: new a6e8aa2fd [tool] Add partitions show with tablet id a6e8aa2fd is described below commit a6e8aa2fd5063abb2cc5c8944c9d19fdb38b8aa0 Author: kedeng <kdeng...@gmail.com> AuthorDate: Tue Jun 14 15:43:05 2022 +0800 [tool] Add partitions show with tablet id With this commit help, we can get the corresponding relationship between partitions and tablet id. Which will help us to observe the partitions more easily. The command looks like: `kudu table list --list_tablets --show_tablet_partition_info <table_name> <master_addresses> [-negotiation_timeout_ms=<ms>] [-timeout_ms=<ms>]` The output of the command looks like: ` TestTableListPartition T e72c529ad1a8481390683fd0fe3fb917 : HASH (key_hash0) PARTITION 0, HASH (key_hash1, key_hash2) PARTITION 0, RANGE (key_range) PARTITION 0 <= VALUES < 1 L 8afe7243874943058e849fecebb84d98 127.28.231.1:11503 T 674c732628b74fbab0a03a11f357b432 : HASH (key_hash0) PARTITION 0, HASH (key_hash1, key_hash2) PARTITION 0, RANGE (key_range) PARTITION 2 <= VALUES < 3 L 8afe7243874943058e849fecebb84d98 127.28.231.1:11503 T 1c9a5a6f62d1402aba04dc84f32b6b04 : HASH (key_hash0) PARTITION 0, HASH (key_hash1, key_hash2) PARTITION 1, RANGE (key_range) PARTITION 0 <= VALUES < 1 L 8afe7243874943058e849fecebb84d98 127.28.231.1:11503 T 44046ee1b43a43f4b59dad75f611ac0a : HASH (key_hash0) PARTITION 0, HASH (key_hash1, key_hash2) PARTITION 1, RANGE (key_range) PARTITION 2 <= VALUES < 3 L 8afe7243874943058e849fecebb84d98 127.28.231.1:11503 T 12ca618464074d8a9ae3f9581701bcf0 : HASH (key_hash0) PARTITION 0, HASH (key_hash1, key_hash2) PARTITION 2, RANGE (key_range) PARTITION 0 <= VALUES < 1 L 8afe7243874943058e849fecebb84d98 127.28.231.1:11503 T edc1cbdae0934df9a48866fe65cfbec8 : HASH (key_hash0) PARTITION 0, HASH (key_hash1, key_hash2) PARTITION 2, RANGE (key_range) PARTITION 2 <= VALUES < 3 L 8afe7243874943058e849fecebb84d98 127.28.231.1:11503 T 91ebccd823634878a6e0a8a4e941aa4f : HASH (key_hash0) PARTITION 1, HASH (key_hash1, key_hash2) PARTITION 0, RANGE (key_range) PARTITION 0 <= VALUES < 1 L 8afe7243874943058e849fecebb84d98 127.28.231.1:11503 T 0057ad8aea0d4ad3a626b6417f14bcac : HASH (key_hash0) PARTITION 1, HASH (key_hash1, key_hash2) PARTITION 0, RANGE (key_range) PARTITION 2 <= VALUES < 3 L 8afe7243874943058e849fecebb84d98 127.28.231.1:11503 T de3f9629a97148069aae9e598cb0d3fa : HASH (key_hash0) PARTITION 1, HASH (key_hash1, key_hash2) PARTITION 1, RANGE (key_range) PARTITION 0 <= VALUES < 1 L 8afe7243874943058e849fecebb84d98 127.28.231.1:11503 T d7f9c9103f1943ef9b5131f03e9f8738 : HASH (key_hash0) PARTITION 1, HASH (key_hash1, key_hash2) PARTITION 1, RANGE (key_range) PARTITION 2 <= VALUES < 3 L 8afe7243874943058e849fecebb84d98 127.28.231.1:11503 T 63777094ede14232a5822a3ac50925fd : HASH (key_hash0) PARTITION 1, HASH (key_hash1, key_hash2) PARTITION 2, RANGE (key_range) PARTITION 0 <= VALUES < 1 L 8afe7243874943058e849fecebb84d98 127.28.231.1:11503 T 87f91f80595140fd9c9582a186a3f52b : HASH (key_hash0) PARTITION 1, HASH (key_hash1, key_hash2) PARTITION 2, RANGE (key_range) PARTITION 2 <= VALUES < 3 L 8afe7243874943058e849fecebb84d98 127.28.231.1:11503 ` Change-Id: Ia9c3b62111c7f302ea934324d1636f79731f18f1 Reviewed-on: http://gerrit.cloudera.org:8080/18617 Tested-by: Kudu Jenkins Reviewed-by: Alexey Serbin <ale...@apache.org> --- src/kudu/client/client-internal.cc | 23 +++++- src/kudu/client/client-internal.h | 12 ++- src/kudu/common/partition.h | 2 - src/kudu/integration-tests/cluster_itest_util.cc | 18 ++++ src/kudu/integration-tests/cluster_itest_util.h | 7 ++ src/kudu/master/catalog_manager.cc | 39 ++++++--- src/kudu/master/catalog_manager.h | 7 ++ src/kudu/master/master.proto | 10 +++ src/kudu/tools/kudu-admin-test.cc | 100 +++++++++++++++++++++++ src/kudu/tools/tool_action_table.cc | 50 +++++++++++- 10 files changed, 248 insertions(+), 20 deletions(-) diff --git a/src/kudu/client/client-internal.cc b/src/kudu/client/client-internal.cc index 5c650599f..9095ae9c2 100644 --- a/src/kudu/client/client-internal.cc +++ b/src/kudu/client/client-internal.cc @@ -444,12 +444,15 @@ Status KuduClient::Data::WaitForAlterTableToFinish( Status KuduClient::Data::ListTablesWithInfo(KuduClient* client, vector<TableInfo>* tables_info, - const string& filter) { + const string& filter, + bool list_tablet_with_partition) { ListTablesRequestPB req; if (!filter.empty()) { req.set_name_filter(filter); } + req.set_list_tablet_with_partition(list_tablet_with_partition); + auto deadline = MonoTime::Now() + client->default_admin_operation_timeout(); Synchronizer sync; ListTablesResponsePB resp; @@ -468,8 +471,26 @@ Status KuduClient::Data::ListTablesWithInfo(KuduClient* client, info.live_row_count = table.has_live_row_count() ? table.live_row_count() : 0; info.num_tablets = table.has_num_tablets() ? table.num_tablets() : 0; info.num_replicas = table.has_num_replicas() ? table.num_replicas() : 0; + if (list_tablet_with_partition) { + for (const auto& pt : table.tablet_with_partition()) { + Partition partition; + Partition::FromPB(pt.partition(), &partition); + PartitionWithTabletId partition_with_tablet_id = {pt.tablet_id(), std::move(partition)}; + info.partition_with_tablet_info.emplace_back(std::move(partition_with_tablet_id)); + } + } + + // sort by range key + // Different range partitions of the same table do not intersect. + // So we just compare the start/begin key of two ranges. + std::sort(info.partition_with_tablet_info.begin(), info.partition_with_tablet_info.end(), + [] (const PartitionWithTabletId& lhs, const PartitionWithTabletId& rhs) { + return lhs.partition.begin().range_key() < rhs.partition.begin().range_key(); + }); + tables_info->emplace_back(std::move(info)); } + return Status::OK(); } diff --git a/src/kudu/client/client-internal.h b/src/kudu/client/client-internal.h index 61661f73b..8a062b2c8 100644 --- a/src/kudu/client/client-internal.h +++ b/src/kudu/client/client-internal.h @@ -28,6 +28,7 @@ #include "kudu/client/authz_token_cache.h" #include "kudu/client/client.h" +#include "kudu/common/partition.h" #include "kudu/gutil/macros.h" #include "kudu/gutil/ref_counted.h" #include "kudu/rpc/rpc_controller.h" @@ -42,7 +43,6 @@ namespace kudu { class DnsResolver; -class PartitionSchema; class Sockaddr; namespace security { @@ -138,15 +138,23 @@ class KuduClient::Data { master::TableIdentifierPB table, const MonoTime& deadline); + struct PartitionWithTabletId { + std::string tablet_id; + Partition partition; + }; + struct TableInfo { std::string table_name; uint64_t live_row_count; int num_tablets; int num_replicas; + std::vector<PartitionWithTabletId> partition_with_tablet_info; }; + static Status ListTablesWithInfo(KuduClient* client, std::vector<TableInfo>* tables_info, - const std::string& filter); + const std::string& filter, + bool list_tablet_with_partition = false); // Open the table identified by 'table_identifier'. Status OpenTable(KuduClient* client, diff --git a/src/kudu/common/partition.h b/src/kudu/common/partition.h index 7b0878b15..90e67ef6b 100644 --- a/src/kudu/common/partition.h +++ b/src/kudu/common/partition.h @@ -24,8 +24,6 @@ #include <utility> #include <vector> -#include <gtest/gtest_prod.h> - #include "kudu/common/schema.h" #include "kudu/gutil/port.h" #include "kudu/util/slice.h" diff --git a/src/kudu/integration-tests/cluster_itest_util.cc b/src/kudu/integration-tests/cluster_itest_util.cc index dfdacd804..10a5a68a4 100644 --- a/src/kudu/integration-tests/cluster_itest_util.cc +++ b/src/kudu/integration-tests/cluster_itest_util.cc @@ -972,6 +972,24 @@ Status GetTabletLocations(const shared_ptr<MasterServiceProxy>& master_proxy, return Status::OK(); } +Status ListTablesWithInfo(const shared_ptr<MasterServiceProxy>& master_proxy, + const string& filter, + const MonoDelta& timeout, + master::ListTablesResponsePB* tables_info) { + master::ListTablesRequestPB req; + if (!filter.empty()) { + req.set_name_filter(filter); + } + req.set_list_tablet_with_partition(true); + rpc::RpcController rpc; + rpc.set_timeout(timeout); + RETURN_NOT_OK(master_proxy->ListTables(req, tables_info, &rpc)); + if (tables_info->has_error()) { + return StatusFromPB(tables_info->error().status()); + } + return Status::OK(); +} + Status GetTableLocations(const shared_ptr<MasterServiceProxy>& master_proxy, const string& table_name, const MonoDelta& timeout, diff --git a/src/kudu/integration-tests/cluster_itest_util.h b/src/kudu/integration-tests/cluster_itest_util.h index c716cef63..e1d635cd7 100644 --- a/src/kudu/integration-tests/cluster_itest_util.h +++ b/src/kudu/integration-tests/cluster_itest_util.h @@ -342,6 +342,13 @@ Status GetTabletLocations(const std::shared_ptr<master::MasterServiceProxy>& mas master::ReplicaTypeFilter filter, master::GetTabletLocationsResponsePB* tablet_locations); +// Get information on the specified tables from master. +// When @filter is not empty, only returns tables that satisfy a substring match on filter. +Status ListTablesWithInfo(const std::shared_ptr<master::MasterServiceProxy>& master_proxy, + const std::string& filter, + const MonoDelta& timeout, + master::ListTablesResponsePB* tables_info); + // Get the list of tablet locations for all tablets in the specified table via the given // table name (and table ID if provided) from the Master. Status GetTableLocations(const std::shared_ptr<master::MasterServiceProxy>& master_proxy, diff --git a/src/kudu/master/catalog_manager.cc b/src/kudu/master/catalog_manager.cc index 3048abcad..7476df1a9 100644 --- a/src/kudu/master/catalog_manager.cc +++ b/src/kudu/master/catalog_manager.cc @@ -3641,12 +3641,8 @@ Status CatalogManager::ListTables(const ListTablesRequestPB* req, if (table_name != ltm.data().name()) { continue; } - ListTablesResponsePB::TableInfo* table = resp->add_tables(); - table->set_id(table_info->id()); - table->set_name(table_name); - table->set_live_row_count(table_info->GetMetrics()->live_row_count->value()); - table->set_num_tablets(table_info->num_tablets()); - table->set_num_replicas(ltm.data().pb.num_replicas()); + FillListTablesResponse(table_name, table_info, ltm.data().pb.num_replicas(), + req->list_tablet_with_partition(), resp); } } else { // Otherwise, pass all tables through. @@ -3654,17 +3650,36 @@ Status CatalogManager::ListTables(const ListTablesRequestPB* req, const auto& table_name = name_and_table_info.first; const auto& table_info = name_and_table_info.second; TableMetadataLock ltm(table_info.get(), LockMode::READ); - ListTablesResponsePB::TableInfo* table = resp->add_tables(); - table->set_id(table_info->id()); - table->set_name(table_name); - table->set_live_row_count(table_info->GetMetrics()->live_row_count->value()); - table->set_num_tablets(table_info->num_tablets()); - table->set_num_replicas(ltm.data().pb.num_replicas()); + FillListTablesResponse(table_name, table_info, ltm.data().pb.num_replicas(), + req->list_tablet_with_partition(), resp); } } return Status::OK(); } +void CatalogManager::FillListTablesResponse(const string& table_name, + const scoped_refptr<TableInfo>& table_info, + int replica_num, + bool list_tablet_with_partition, + ListTablesResponsePB* resp) { + ListTablesResponsePB::TableInfo* table = resp->add_tables(); + table->set_id(table_info->id()); + table->set_name(table_name); + table->set_live_row_count(table_info->GetMetrics()->live_row_count->value()); + table->set_num_tablets(table_info->num_tablets()); + table->set_num_replicas(replica_num); + if (list_tablet_with_partition) { + const auto& tablet_map = table_info->tablet_map(); + for (const auto& tablet : tablet_map) { + ListTablesResponsePB::TabletWithPartition* tablet_with_partition = + table->add_tablet_with_partition(); + TabletMetadataLock t(tablet.second.get(), LockMode::READ); + tablet_with_partition->set_tablet_id(tablet.second->id()); + tablet_with_partition->mutable_partition()->CopyFrom( + tablet.second->metadata().state().pb.partition()); + } + } +} Status CatalogManager::GetTableStatistics(const GetTableStatisticsRequestPB* req, GetTableStatisticsResponsePB* resp, const optional<string>& user) { diff --git a/src/kudu/master/catalog_manager.h b/src/kudu/master/catalog_manager.h index 9de7ba230..9282fa28b 100644 --- a/src/kudu/master/catalog_manager.h +++ b/src/kudu/master/catalog_manager.h @@ -1146,6 +1146,13 @@ class CatalogManager : public tserver::TabletReplicaLookupIf { void ResetTableLocationsCache(); + // Fill in the reply of ListTables request. + static void FillListTablesResponse(const std::string& table_name, + const scoped_refptr<TableInfo>& table_info, + int replica_num, + bool list_tablet_with_partition, + ListTablesResponsePB* resp); + // Task that takes care of deleted tables, is called in a backgroud thread. // Clean up the metadata of tables if the time since they were deleted has passed // 'FLAGS_metadata_for_deleted_table_and_tablet_reserved_secs'. diff --git a/src/kudu/master/master.proto b/src/kudu/master/master.proto index e660a74df..d556245fa 100644 --- a/src/kudu/master/master.proto +++ b/src/kudu/master/master.proto @@ -591,18 +591,28 @@ message ListTablesRequestPB { // interpreted as if it were set to [TableTypePB::DEFAULT_TABLE], meaning // to include only user-defined tables. repeated TableTypePB type_filter = 2; + + // Set this field 'true' to include information on the partition backed by + // each tablet in the result list. + optional bool list_tablet_with_partition = 3 [default = false]; } message ListTablesResponsePB { // The error, if an error occurred with this request. optional MasterErrorPB error = 1; + message TabletWithPartition { + optional string tablet_id = 1; + optional PartitionPB partition = 2; + } + message TableInfo { required bytes id = 1; required string name = 2; optional uint64 live_row_count = 3; optional int32 num_tablets = 4; optional int32 num_replicas = 5; + repeated TabletWithPartition tablet_with_partition = 6; } repeated TableInfo tables = 2; diff --git a/src/kudu/tools/kudu-admin-test.cc b/src/kudu/tools/kudu-admin-test.cc index 9482afb09..45e66b292 100644 --- a/src/kudu/tools/kudu-admin-test.cc +++ b/src/kudu/tools/kudu-admin-test.cc @@ -44,6 +44,8 @@ #include "kudu/client/write_op.h" #include "kudu/common/common.pb.h" #include "kudu/common/partial_row.h" +#include "kudu/common/partition.h" +#include "kudu/common/schema.h" #include "kudu/common/wire_protocol.pb.h" #include "kudu/consensus/consensus.pb.h" #include "kudu/consensus/metadata.pb.h" @@ -112,6 +114,7 @@ using kudu::consensus::OpId; using kudu::itest::FindTabletFollowers; using kudu::itest::FindTabletLeader; using kudu::itest::GetConsensusState; +using kudu::itest::ListTablesWithInfo; using kudu::itest::StartElection; using kudu::itest::WaitUntilLeader; using kudu::itest::TabletServerMap; @@ -2083,6 +2086,103 @@ TEST_F(AdminCliTest, TestDescribeTableNoOwner) { ASSERT_STR_CONTAINS(stdout, "OWNER \n"); } +TEST_F(AdminCliTest, TestListTabletWithPartition) { + FLAGS_num_tablet_servers = 1; + FLAGS_num_replicas = 1; + + NO_FATALS(BuildAndStart()); + + vector<TServerDetails*> tservers; + vector<string> base_tablet_ids; + AppendValuesFromMap(tablet_servers_, &tservers); + ListRunningTabletIds(tservers.front(), + MonoDelta::FromSeconds(30), &base_tablet_ids); + + // Test a table with all types in its schema, multiple hash partitioning + // levels, multiple range partitions, and non-covered ranges. + const string kTableId = "TestTableListPartition"; + KuduSchema schema; + + // Build the schema. + { + KuduSchemaBuilder builder; + builder.AddColumn("key_hash0")->Type(KuduColumnSchema::INT32)->NotNull(); + builder.AddColumn("key_hash1")->Type(KuduColumnSchema::INT32)->NotNull(); + builder.AddColumn("key_hash2")->Type(KuduColumnSchema::INT32)->NotNull(); + builder.AddColumn("key_range")->Type(KuduColumnSchema::INT32)->NotNull(); + builder.SetPrimaryKey({ "key_hash0", "key_hash1", "key_hash2", "key_range" }); + ASSERT_OK(builder.Build(&schema)); + } + + // Set up partitioning and create the table. + { + unique_ptr<KuduPartialRow> lower_bound0(schema.NewRow()); + ASSERT_OK(lower_bound0->SetInt32("key_range", 0)); + unique_ptr<KuduPartialRow> upper_bound0(schema.NewRow()); + ASSERT_OK(upper_bound0->SetInt32("key_range", 1)); + unique_ptr<KuduPartialRow> lower_bound1(schema.NewRow()); + ASSERT_OK(lower_bound1->SetInt32("key_range", 2)); + unique_ptr<KuduPartialRow> upper_bound1(schema.NewRow()); + ASSERT_OK(upper_bound1->SetInt32("key_range", 3)); + unique_ptr<KuduTableCreator> table_creator(client_->NewTableCreator()); + ASSERT_OK(table_creator->table_name(kTableId) + .schema(&schema) + .add_hash_partitions({"key_hash0"}, 2) + .add_hash_partitions({"key_hash1", "key_hash2"}, 3) + .set_range_partition_columns({"key_range"}) + .add_range_partition(lower_bound0.release(), upper_bound0.release()) + .add_range_partition(lower_bound1.release(), upper_bound1.release()) + .num_replicas(FLAGS_num_replicas) + .Create()); + } + + vector<string> new_tablet_ids; + ListRunningTabletIds(tservers.front(), + MonoDelta::FromSeconds(30), &new_tablet_ids); + vector<string> delta_tablet_ids; + for (auto& tablet_id : base_tablet_ids) { + if (std::find(new_tablet_ids.begin(), new_tablet_ids.end(), tablet_id) == + new_tablet_ids.end()) { + delta_tablet_ids.push_back(tablet_id); + } + } + + // Test the list tablet with partition output. + string stdout; + string stderr; + Status s = RunKuduTool({ + "table", + "list", + "--list_tablets", + "--show_tablet_partition_info", + "--tables", + kTableId, + cluster_->master()->bound_rpc_addr().ToString(), + }, &stdout, &stderr); + ASSERT_TRUE(s.ok()) << ToolRunInfo(s, stdout, stderr); + + client::sp::shared_ptr<KuduTable> table; + ASSERT_OK(client_->OpenTable(kTableId, &table)); + const auto& partition_schema = table->partition_schema(); + const auto& schema_internal = KuduSchema::ToSchema(table->schema()); + + // make sure table name correct + ASSERT_STR_CONTAINS(stdout, kTableId); + + master::ListTablesResponsePB tables_info; + ASSERT_OK(ListTablesWithInfo(cluster_->master_proxy(), kTableId, + MonoDelta::FromSeconds(30), &tables_info)); + for (const auto& table : tables_info.tables()) { + for (const auto& pt : table.tablet_with_partition()) { + Partition partition; + Partition::FromPB(pt.partition(), &partition); + string partition_str = partition_schema.PartitionDebugString(partition, schema_internal); + string tablet_with_partition = pt.tablet_id() + " : " + partition_str; + ASSERT_STR_CONTAINS(stdout, tablet_with_partition); + } + } +} + TEST_F(AdminCliTest, TestLocateRow) { FLAGS_num_tablet_servers = 1; FLAGS_num_replicas = 1; diff --git a/src/kudu/tools/tool_action_table.cc b/src/kudu/tools/tool_action_table.cc index e68c6f1f7..f6f82bbaa 100644 --- a/src/kudu/tools/tool_action_table.cc +++ b/src/kudu/tools/tool_action_table.cc @@ -109,6 +109,20 @@ DEFINE_bool(list_tablets, false, DEFINE_bool(show_table_info, false, "Include extra information such as number of tablets, replicas, " "and live row count for a table in the output"); +DEFINE_bool(show_tablet_partition_info, false, + "Include partition keys information corresponding to tablet in the output."); + +bool ValidateShowTabletPartitionInfo() { + if (!FLAGS_list_tablets && FLAGS_show_tablet_partition_info) { + LOG(ERROR) << Substitute("--show_tablet_partition_info is meaningless " + "when --list_tablets=false"); + return false; + } + return true; +} + +GROUP_FLAG_VALIDATOR(show_tablet_partition_info, ValidateShowTabletPartitionInfo); + DEFINE_bool(modify_external_catalogs, true, "Whether to modify external catalogs, such as the Hive Metastore, " "when renaming or dropping a table."); @@ -167,14 +181,35 @@ namespace tools { // KuduReplica, KuduReplica::Data, and KuduClientBuilder. class TableLister { public: + static string SearchPartitionInfo(const KuduClient::Data::TableInfo& table_info, + const client::sp::shared_ptr<KuduTable>& table, + const string& tablet_id) { + string pinfo; + const auto& partition_with_tablet_info = table_info.partition_with_tablet_info; + for (const auto& pt : partition_with_tablet_info) { + if (tablet_id != pt.tablet_id) { + continue; + } + + const auto& schema_internal = KuduSchema::ToSchema(table->schema()); + const auto& partition_schema = table->partition_schema(); + pinfo = partition_schema.PartitionDebugString(pt.partition, schema_internal); + break; + } + return pinfo; + } + static Status ListTablets(const vector<string>& master_addresses) { client::sp::shared_ptr<KuduClient> client; RETURN_NOT_OK(CreateKuduClient(master_addresses, &client, - true /* can_see_all_replicas */)); + true/* can_see_all_replicas */)); vector<kudu::client::KuduClient::Data::TableInfo> tables_info; RETURN_NOT_OK(client->data_->ListTablesWithInfo( - client.get(), &tables_info, "" /* filter */)); + client.get(), + &tables_info, + "" /* filter */, + FLAGS_show_tablet_partition_info)); vector<string> table_filters = Split(FLAGS_tables, ",", strings::SkipEmpty()); for (const auto& tinfo : tables_info) { @@ -187,9 +222,11 @@ class TableLister { } else { cout << tname << endl; } + if (!FLAGS_list_tablets) { continue; } + client::sp::shared_ptr<KuduTable> client_table; RETURN_NOT_OK(client->OpenTable(tname, &client_table)); vector<KuduScanToken*> tokens; @@ -198,7 +235,12 @@ class TableLister { RETURN_NOT_OK(builder.Build(&tokens)); for (const auto* token : tokens) { - cout << " T " << token->tablet().id() << endl; + string partition_info; + string tablet_id = token->tablet().id(); + if (FLAGS_show_tablet_partition_info) { + partition_info = " : " + SearchPartitionInfo(tinfo, client_table, tablet_id); + } + cout << " T " << tablet_id << partition_info << endl; for (const auto* replica : token->tablet().replicas()) { const bool is_voter = ReplicaController::is_voter(*replica); const bool is_leader = replica->is_leader(); @@ -210,6 +252,7 @@ class TableLister { } cout << endl; } + return Status::OK(); } }; @@ -1504,6 +1547,7 @@ unique_ptr<Mode> BuildTableMode() { .Description("List tables") .AddOptionalParameter("tables") .AddOptionalParameter("list_tablets") + .AddOptionalParameter("show_tablet_partition_info") .AddOptionalParameter("show_table_info") .Build();