This is an automated email from the ASF dual-hosted git repository.
alexey pushed a commit to branch branch-1.17.x
in repository https://gitbox.apache.org/repos/asf/kudu.git
The following commit(s) were added to refs/heads/branch-1.17.x by this push:
new 3f10f3e25 KUDU-3495 Initialize the bitmap while decoding insert/upsert
3f10f3e25 is described below
commit 3f10f3e251ff80e35978ea98b61f31cb52308705
Author: 宋家成 <[email protected]>
AuthorDate: Tue Aug 8 18:33:25 2023 +0800
KUDU-3495 Initialize the bitmap while decoding insert/upsert
The upsert request with an old client schema might lead to
unexpected result eventually.
If client A opens a table first and then client B add a column
to the table, the upsert request of client A might set the
newly added column to default value.
The reason is that we did not initialize the tablet_isset_bitmap
while decoding the insert or upsert requests.
A user does not want to change the column which he did not request
to even if the client schema is not correct, so initialize the bitmap.
Change-Id: I38a33cb58a085bc83854c5145e904c8ed51092a8
Reviewed-on: http://gerrit.cloudera.org:8080/20327
Tested-by: Kudu Jenkins
Reviewed-by: Alexey Serbin <[email protected]>
(cherry picked from commit f1f3c907fc6f012b6d7a72f0103e1db4f56f0e7d)
Reviewed-on: http://gerrit.cloudera.org:8080/21296
Reviewed-by: Yingchun Lai <[email protected]>
Tested-by: Alexey Serbin <[email protected]>
---
src/kudu/common/row_operations-test.cc | 27 +++++++++++++++++++++++++++
src/kudu/common/row_operations.cc | 4 ++++
2 files changed, 31 insertions(+)
diff --git a/src/kudu/common/row_operations-test.cc
b/src/kudu/common/row_operations-test.cc
index 17c336dda..137d6f4f3 100644
--- a/src/kudu/common/row_operations-test.cc
+++ b/src/kudu/common/row_operations-test.cc
@@ -1005,4 +1005,31 @@ TEST_F(RowOperationsTest, ExceedCellLimit) {
}
}
+TEST_F(RowOperationsTest, SchemasDoNotMatch) {
+ Schema client_schema({ ColumnSchema("key", INT32),
+ ColumnSchema("int_val", INT32) },
+ 1);
+ SchemaBuilder server_schema_builder;
+ ASSERT_OK(server_schema_builder.AddKeyColumn("key", INT32));
+ ASSERT_OK(server_schema_builder.AddColumn("int_val", INT32));
+ ASSERT_OK(server_schema_builder.AddNullableColumn("string_val", STRING));
+ Schema server_schema = server_schema_builder.Build();
+
+ KuduPartialRow row(&client_schema);
+ ASSERT_OK(row.SetInt32("key", 1));
+ ASSERT_OK(row.SetInt32("int_val", 2));
+ RowOperationsPB pb;
+ RowOperationsPBEncoder(&pb).Add(RowOperationsPB::UPSERT, row);
+
+ arena_.Reset();
+ RowOperationsPBDecoder decoder(&pb, &client_schema, &server_schema, &arena_);
+ vector<DecodedRowOperation> ops;
+ ASSERT_OK(decoder.DecodeOperations<DecoderMode::WRITE_OPS>(&ops));
+ // The correct bitmap should be {1, 1, 0}.
+ ASSERT_EQ(1, ops.size());
+ ASSERT_TRUE(BitmapTest(ops[0].isset_bitmap, 0));
+ ASSERT_TRUE(BitmapTest(ops[0].isset_bitmap, 1));
+ ASSERT_FALSE(BitmapTest(ops[0].isset_bitmap, 2));
+}
+
} // namespace kudu
diff --git a/src/kudu/common/row_operations.cc
b/src/kudu/common/row_operations.cc
index 5e8d560ec..b1cf61362 100644
--- a/src/kudu/common/row_operations.cc
+++ b/src/kudu/common/row_operations.cc
@@ -439,6 +439,10 @@ Status RowOperationsPBDecoder::DecodeInsertOrUpsert(const
uint8_t* prototype_row
if (PREDICT_FALSE(!tablet_row_storage || !tablet_isset_bitmap)) {
return Status::RuntimeError("Out of memory");
}
+ // Initialize the bitmap since some columns might be lost in the client
schema,
+ // in which case the original value of the lost columns might be set to
default
+ // value by upsert request.
+ memset(tablet_isset_bitmap, 0, BitmapSize(tablet_schema_->num_columns()));
// Initialize the new row from the 'prototype' row which has been set
// with all of the server-side default values. This copy may be entirely