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 f1f3c907f KUDU-3495 Initialize the bitmap while decoding insert/upsert
f1f3c907f is described below

commit f1f3c907fc6f012b6d7a72f0103e1db4f56f0e7d
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]>
---
 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

Reply via email to