This is an automated email from the ASF dual-hosted git repository.
laiyingchun 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 958248a KUDU-3339 [tool] CLI to add a column
958248a is described below
commit 958248adf3ea70f12ab033e0041bfc5c922956af
Author: shenxingwuying <[email protected]>
AuthorDate: Mon Aug 23 17:18:36 2021 +0800
KUDU-3339 [tool] CLI to add a column
usage:
kudu table add_column <master_addresses> <table_name> \
<column_name> <data_type> [-encoding_type=<type>] \
[-compression_type=<type>] [-default_value=<value>] \
[-comment=<comment>]
Change-Id: I93e6c2af07e9fa5aa909b4a09b79b7c54401d4e3
Reviewed-on: http://gerrit.cloudera.org:8080/17851
Tested-by: Kudu Jenkins
Reviewed-by: Yingchun Lai <[email protected]>
---
src/kudu/client/schema.cc | 14 ++++++++
src/kudu/client/schema.h | 3 ++
src/kudu/tools/kudu-tool-test.cc | 69 +++++++++++++++++++++++++++++++++++++
src/kudu/tools/tool_action_table.cc | 69 +++++++++++++++++++++++++++++++++++++
4 files changed, 155 insertions(+)
diff --git a/src/kudu/client/schema.cc b/src/kudu/client/schema.cc
index e5a1bba..8c97e55 100644
--- a/src/kudu/client/schema.cc
+++ b/src/kudu/client/schema.cc
@@ -808,6 +808,20 @@ KuduColumnTypeAttributes
KuduColumnSchema::type_attributes() const {
type_attributes.length);
}
+KuduColumnStorageAttributes KuduColumnSchema::storage_attributes() const {
+ ColumnStorageAttributes storage_attributes =
DCHECK_NOTNULL(col_)->attributes();
+ KuduColumnStorageAttributes::EncodingType encoding_type;
+ KuduColumnStorageAttributes::StringToEncodingType(
+ kudu::EncodingType_Name(storage_attributes.encoding),
+ &encoding_type);
+ KuduColumnStorageAttributes::CompressionType compression_type;
+ KuduColumnStorageAttributes::StringToCompressionType(
+ kudu::CompressionType_Name(storage_attributes.compression),
+ &compression_type);
+ return KuduColumnStorageAttributes(encoding_type, compression_type,
+ storage_attributes.cfile_block_size);
+}
+
const string& KuduColumnSchema::comment() const {
return DCHECK_NOTNULL(col_)->comment();
}
diff --git a/src/kudu/client/schema.h b/src/kudu/client/schema.h
index 086e7d9..6791e56 100644
--- a/src/kudu/client/schema.h
+++ b/src/kudu/client/schema.h
@@ -307,6 +307,9 @@ class KUDU_EXPORT KuduColumnSchema {
/// @return Type attributes of the column schema.
KuduColumnTypeAttributes type_attributes() const;
+ /// @return Storage attributes of the column schema.
+ KuduColumnStorageAttributes storage_attributes() const;
+
/// @return comment of the column schema.
///
/// @note An empty string will be returned if there is no comment.
diff --git a/src/kudu/tools/kudu-tool-test.cc b/src/kudu/tools/kudu-tool-test.cc
index df435a6..67c0193 100644
--- a/src/kudu/tools/kudu-tool-test.cc
+++ b/src/kudu/tools/kudu-tool-test.cc
@@ -1188,6 +1188,7 @@ TEST_F(ToolTest, TestModeHelp) {
"column_set_comment.*Set comment for a column",
"copy.*Copy table data to another table",
"create.*Create a new table",
+ "add_column.*Add a column",
"delete_column.*Delete a column",
"delete.*Delete a table",
"describe.*Describe a table",
@@ -4717,6 +4718,73 @@ TEST_F(ToolTest, TestColumnSetDefault) {
"DECIMAL columns are not supported for setting default value by this
tool"));
}
+TEST_F(ToolTest, TestAddColumn) {
+ NO_FATALS(StartExternalMiniCluster());
+ const string& kTableName = "kudu.table.add.column";
+ const string& kColumnName0 = "col.0";
+ const string& kColumnName1 = "col.1";
+ KuduSchemaBuilder schema_builder;
+ schema_builder.AddColumn("key")
+ ->Type(client::KuduColumnSchema::INT32)
+ ->NotNull()
+ ->PrimaryKey();
+ schema_builder.AddColumn(kColumnName0)
+ ->Type(client::KuduColumnSchema::INT32)
+ ->NotNull();
+ KuduSchema schema;
+ ASSERT_OK(schema_builder.Build(&schema));
+
+ // Create the table
+ TestWorkload workload(cluster_.get());
+ workload.set_table_name(kTableName);
+ workload.set_schema(schema);
+ workload.set_num_replicas(1);
+ workload.Setup();
+
+ string master_addr = cluster_->master()->bound_rpc_addr().ToString();
+ shared_ptr<KuduClient> client;
+ ASSERT_OK(KuduClientBuilder()
+ .add_master_server_addr(master_addr)
+ .Build(&client));
+ shared_ptr<KuduTable> table;
+ ASSERT_OK(client->OpenTable(kTableName, &table));
+ ASSERT_STR_CONTAINS(table->schema().ToString(), kColumnName0);
+ ASSERT_STR_NOT_CONTAINS(table->schema().ToString(), kColumnName1);
+ NO_FATALS(RunActionStdoutNone(Substitute("table add_column $0 $1 $2 STRING "
+ "-encoding_type=DICT_ENCODING "
+ "-compression_type=LZ4 "
+ "-default_value=[\"abcd\"] "
+ "-comment=helloworld",
+ master_addr, kTableName,
kColumnName1)));
+
+ ASSERT_OK(client->OpenTable(kTableName, &table));
+ ASSERT_STR_CONTAINS(table->schema().ToString(), kColumnName1);
+
+ KuduSchemaBuilder expected_schema_builder;
+ expected_schema_builder.AddColumn("key")
+ ->Type(kudu::client::KuduColumnSchema::INT32)
+ ->NotNull()
+ ->PrimaryKey();
+ expected_schema_builder.AddColumn(kColumnName1)
+ ->Type(client::KuduColumnSchema::STRING)
+ ->Compression(client::KuduColumnStorageAttributes::CompressionType::LZ4)
+
->Encoding(client::KuduColumnStorageAttributes::EncodingType::DICT_ENCODING)
+ ->Default(client::KuduValue::CopyString(Slice("abcd")))
+ ->Comment("helloworld");
+ KuduSchema expected_schema;
+ ASSERT_OK(expected_schema_builder.Build(&expected_schema));
+
+ ASSERT_EQ(table->schema().Column(2).name(),
expected_schema.Column(1).name());
+ ASSERT_EQ(table->schema().Column(2).is_nullable(),
expected_schema.Column(1).is_nullable());
+ ASSERT_EQ(table->schema().Column(2).type(),
expected_schema.Column(1).type());
+ ASSERT_EQ(table->schema().Column(2).storage_attributes().encoding(),
+ expected_schema.Column(1).storage_attributes().encoding());
+ ASSERT_EQ(table->schema().Column(2).storage_attributes().compression(),
+ expected_schema.Column(1).storage_attributes().compression());
+ ASSERT_EQ(table->schema().Column(2).comment(),
expected_schema.Column(1).comment());
+ ASSERT_EQ(table->schema().Column(2), expected_schema.Column(1));
+}
+
TEST_F(ToolTest, TestDeleteColumn) {
NO_FATALS(StartExternalMiniCluster());
constexpr const char* const kTableName = "kudu.table.delete.column";
@@ -4916,6 +4984,7 @@ TEST_F(ToolTest, TestSetReplicationFactor) {
schema_builder.AddColumn("value")
->Type(client::KuduColumnSchema::INT32)
->NotNull();
+
KuduSchema schema;
ASSERT_OK(schema_builder.Build(&schema));
diff --git a/src/kudu/tools/tool_action_table.cc
b/src/kudu/tools/tool_action_table.cc
index f85ff67..91614f9 100644
--- a/src/kudu/tools/tool_action_table.cc
+++ b/src/kudu/tools/tool_action_table.cc
@@ -127,6 +127,16 @@ DEFINE_int32(scan_batch_size, -1,
DECLARE_bool(row_count_only);
DECLARE_bool(show_scanner_stats);
+
+DEFINE_string(encoding_type, "AUTO_ENCODING",
+ "Type of encoding for the column including AUTO_ENCODING,
PLAIN_ENCODING, "
+ "PREFIX_ENCODING, RLE, DICT_ENCODING, BIT_SHUFFLE,
GROUP_VARINT");
+DEFINE_string(compression_type, "DEFAULT_COMPRESSION",
+ "Type of compression for the column including
DEFAULT_COMPRESSION, "
+ "NO_COMPRESSION, SNAPPY, LZ4, ZLIB");
+DEFINE_string(default_value, "", "Default value for this column.");
+DEFINE_string(comment, "", "Comment for this column.");
+
DECLARE_bool(show_values);
DECLARE_string(replica_selection);
DECLARE_string(tables);
@@ -217,6 +227,7 @@ const char* const kBlockSizeArg = "block_size";
const char* const kColumnCommentArg = "column_comment";
const char* const kCreateTableJSONArg = "create_table_json";
const char* const kReplicationFactorArg = "replication_factor";
+const char* const kDataTypeArg = "data_type";
enum PartitionAction {
ADD,
@@ -975,6 +986,47 @@ Status ColumnSetComment(const RunnerContext& context) {
return alterer->Alter();
}
+Status AddColumn(const RunnerContext& context) {
+ const string& table_name = FindOrDie(context.required_args, kTableNameArg);
+ const string& column_name = FindOrDie(context.required_args, kColumnNameArg);
+ const string& data_type_name = FindOrDie(context.required_args,
kDataTypeArg);
+
+ client::sp::shared_ptr<KuduClient> client;
+ RETURN_NOT_OK(CreateKuduClient(context, &client));
+ unique_ptr<KuduTableAlterer> alterer(client->NewTableAlterer(table_name));
+ KuduColumnSpec* column_spec = alterer->AddColumn(column_name);
+
+ KuduColumnSchema::DataType data_type;
+ RETURN_NOT_OK(KuduColumnSchema::StringToDataType(data_type_name,
&data_type));
+ column_spec->Type(data_type);
+
+ if (!FLAGS_default_value.empty()) {
+ KuduValue* value = nullptr;
+ RETURN_NOT_OK(ParseValueOfType(FLAGS_default_value, data_type, &value));
+ column_spec->Default(value);
+ }
+
+ if (!FLAGS_encoding_type.empty()) {
+ KuduColumnStorageAttributes::EncodingType encoding_type;
+
RETURN_NOT_OK(KuduColumnStorageAttributes::StringToEncodingType(FLAGS_encoding_type,
+
&encoding_type));
+ column_spec->Encoding(encoding_type);
+ }
+
+ if (!FLAGS_compression_type.empty()) {
+ KuduColumnStorageAttributes::CompressionType compress_type;
+
RETURN_NOT_OK(KuduColumnStorageAttributes::StringToCompressionType(FLAGS_compression_type,
+
&compress_type));
+ column_spec->Compression(compress_type);
+ }
+
+ if (!FLAGS_comment.empty()) {
+ column_spec->Comment(FLAGS_comment);
+ }
+
+ return alterer->Alter();
+}
+
Status DeleteColumn(const RunnerContext& context) {
const string& table_name = FindOrDie(context.required_args, kTableNameArg);
const string& column_name = FindOrDie(context.required_args, kColumnNameArg);
@@ -1496,6 +1548,22 @@ unique_ptr<Mode> BuildTableMode() {
.AddRequiredParameter({ kColumnCommentArg, "Comment of the column" })
.Build();
+ unique_ptr<Action> add_column =
+ ActionBuilder("add_column", &AddColumn)
+ .Description("Add a column")
+ .AddRequiredParameter({ kMasterAddressesArg, kMasterAddressesArgDesc })
+ .AddRequiredParameter({ kTableNameArg, "Name of the table to alter" })
+ .AddRequiredParameter({ kColumnNameArg, "Name of the table column to
add" })
+ .AddRequiredParameter({ kDataTypeArg, "Data Type, eg: INT8, INT16,
INT32, INT64, STRING,"
+ " BOOL, FLOAT, DOUBLE, BINARY, UNIXTIME_MICROS,
DECIMAL, VARCHAR,"
+ " TIMESTAMP, DATE"})
+ .AddOptionalParameter(kEncodingTypeArg)
+ .AddOptionalParameter(kCompressionTypeArg)
+ .AddOptionalParameter(kDefaultValueArg)
+ .AddOptionalParameter("comment")
+ .Build();
+
+
unique_ptr<Action> delete_column =
ClusterActionBuilder("delete_column", &DeleteColumn)
.Description("Delete a column")
@@ -1552,6 +1620,7 @@ unique_ptr<Mode> BuildTableMode() {
return ModeBuilder("table")
.Description("Operate on Kudu tables")
.AddMode(BuildSetTableLimitMode())
+ .AddAction(std::move(add_column))
.AddAction(std::move(add_range_partition))
.AddAction(std::move(clear_comment))
.AddAction(std::move(column_remove_default))