You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by mg...@apache.org on 2024/09/09 11:04:14 UTC
(kudu) 01/02: Table copy supports creating a table with no range partition
This is an automated email from the ASF dual-hosted git repository.
mgreber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git
commit 43a7cf5358304aa17b47967540e713e4d6140c0a
Author: xinghuayu007 <14...@qq.com>
AuthorDate: Fri Aug 2 15:44:59 2024 +0800
Table copy supports creating a table with no range partition
Currently, using CLI 'table copy' to create a destination table
when the source table doesn't have any range partition, it creates
a table with an unbounded range partition. That makes the source
table's schema different from the destination table's. That
also causes the tablet schema to be different in the same partition.
The following is an example:
The source table schema:
TABLE test1 (
key INT32 NOT NULL,
int_val INT32 NOT NULL,
string_val STRING NULLABLE,
PRIMARY KEY (key)
)
OWNER root
REPLICAS 1
COMMENT
CLI command:
'kudu table copy $ma test1 $ma --create_table=true'
The destination table schema:
TABLE test1 (
key INT32 NOT NULL,
int_val INT32 NOT NULL,
string_val STRING NULLABLE,
PRIMARY KEY (key)
)
RANGE (key) (
PARTITION UNBOUNDED
)
OWNER root
REPLICAS 1
COMMENT
Semantically it is right, but is better to keep the source table
schema the same with the destination schema.
Change-Id: I94f99f845393ff2460761cc7bd82ecb3f3ead79b
Reviewed-on: http://gerrit.cloudera.org:8080/21634
Reviewed-by: Yingchun Lai <la...@apache.org>
Tested-by: Marton Greber <gr...@gmail.com>
Reviewed-by: Marton Greber <gr...@gmail.com>
---
src/kudu/tools/kudu-tool-test.cc | 97 ++++++++++++++++++++++++++++++++++++++++
src/kudu/tools/table_scanner.cc | 3 +-
2 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/src/kudu/tools/kudu-tool-test.cc b/src/kudu/tools/kudu-tool-test.cc
index 6112f31d9..9dc36d6fc 100644
--- a/src/kudu/tools/kudu-tool-test.cc
+++ b/src/kudu/tools/kudu-tool-test.cc
@@ -1781,6 +1781,103 @@ TEST_P(CreateEmptyPartitionTableTest, TestCreateEmptyPartitionTable) {
}
}
+
+enum class PartitionCombinationMode {
+ kOnlyHashPartition,
+ kOnlyRangePartition,
+ kNoAnyPartition
+};
+
+class CreateNoRangePartitionTable :
+ public ToolTest,
+ public ::testing::WithParamInterface<PartitionCombinationMode> {
+};
+
+INSTANTIATE_TEST_SUITE_P(, CreateNoRangePartitionTable,
+ ::testing::Values(PartitionCombinationMode::kOnlyHashPartition,
+ PartitionCombinationMode::kOnlyRangePartition,
+ PartitionCombinationMode::kNoAnyPartition));
+
+TEST_P(CreateNoRangePartitionTable, TestCreateNoRangePartitionTable) {
+ PartitionCombinationMode create_table_mode = GetParam();
+ const string& kSrcTableName = "test1";
+ const string& kDstTableName = "test2";
+ NO_FATALS(StartExternalMiniCluster());
+ shared_ptr<KuduClient> client;
+ ASSERT_OK(cluster_->CreateClient(nullptr, &client));
+ unique_ptr<KuduTableCreator> table_creator(client->NewTableCreator());
+ KuduSchema schema = KuduSchema::FromSchema(GetSimpleTestSchema());
+ // Create a table in different modes.
+ switch (create_table_mode) {
+ case PartitionCombinationMode::kOnlyHashPartition:
+ ASSERT_OK(table_creator->table_name(kSrcTableName)
+ .schema(&schema)
+ .num_replicas(1)
+ .add_hash_partitions({"key"}, 2)
+ .set_range_partition_columns({})
+ .Create());
+ break;
+ case PartitionCombinationMode::kOnlyRangePartition:
+ ASSERT_OK(table_creator->table_name(kSrcTableName)
+ .schema(&schema)
+ .num_replicas(1)
+ .set_range_partition_columns({"key"})
+ .Create());
+ break;
+ case PartitionCombinationMode::kNoAnyPartition:
+ ASSERT_OK(table_creator->table_name(kSrcTableName)
+ .schema(&schema)
+ .num_replicas(1)
+ .set_range_partition_columns({})
+ .Create());
+ break;
+ default:
+ ASSERT_TRUE(false);
+ }
+
+ // Describe the source table and check the partition schema.
+ const string& master_addr = cluster_->master()->bound_rpc_addr().ToString();
+ vector<string> stdout_before;
+ NO_FATALS(RunActionStdoutLines(Substitute("table describe $0 $1",
+ master_addr,
+ kSrcTableName), &stdout_before));
+ const string& src_table_schema = JoinStrings(stdout_before, "\\");
+ switch (create_table_mode) {
+ case PartitionCombinationMode::kOnlyHashPartition:
+ ASSERT_STR_CONTAINS(src_table_schema, "HASH (key) PARTITIONS");
+ ASSERT_STR_NOT_CONTAINS(src_table_schema, "RANG");
+ break;
+ case PartitionCombinationMode::kOnlyRangePartition:
+ ASSERT_STR_CONTAINS(src_table_schema, "RANGE (key)");
+ ASSERT_STR_NOT_CONTAINS(src_table_schema, "HASH");
+ break;
+ case PartitionCombinationMode::kNoAnyPartition:
+ ASSERT_STR_NOT_CONTAINS(src_table_schema, "HASH");
+ ASSERT_STR_NOT_CONTAINS(src_table_schema, "RANG");
+ break;
+ default:
+ ASSERT_TRUE(false);
+ }
+
+ // Table copy the source table and create the destination table.
+ NO_FATALS(RunTool(
+ Substitute("table copy $0 $1 $2 --dst_table=$3 --create_table=true ",
+ master_addr, kSrcTableName,
+ master_addr, kDstTableName
+ ), nullptr, nullptr));
+ // Describe the destination table and check the partition schema.
+ vector<string> stdout_after;
+ NO_FATALS(RunActionStdoutLines(Substitute("table describe $0 $1",
+ master_addr,
+ kDstTableName), &stdout_after));
+ ASSERT_EQ(stdout_before.size(), stdout_after.size());
+ // Other than the table names, the schemas are the same.
+ // Therefore, compare the content from the second line.
+ for (int i = 1; i < stdout_after.size(); i++) {
+ ASSERT_EQ(stdout_before[i], stdout_after[i]);
+ }
+}
+
TEST_F(ToolTest, TestFsCheck) {
const string kTestDir = GetTestPath("test");
const string kTabletId = "ffffffffffffffffffffffffffffffff";
diff --git a/src/kudu/tools/table_scanner.cc b/src/kudu/tools/table_scanner.cc
index 34e74daec..8fb4fd932 100644
--- a/src/kudu/tools/table_scanner.cc
+++ b/src/kudu/tools/table_scanner.cc
@@ -547,8 +547,7 @@ Status CreateDstTableIfNeeded(const client::sp::shared_ptr<KuduTable>& src_table
table_creator->add_range_partition(lower.release(), upper.release());
}
- if (partition_schema.hash_schema().empty() &&
- partition_schema.range_schema().column_ids.empty()) {
+ if (partition_schema.range_schema().column_ids.empty()) {
// This src table is unpartitioned, just create a table range partitioned on no columns.
table_creator->set_range_partition_columns({});
}