This is an automated email from the ASF dual-hosted git repository.

colinlee pushed a commit to branch colin_fix_tag_empty
in repository https://gitbox.apache.org/repos/asf/tsfile.git

commit 622528e420be671e513b78749e50ab3ec5bddd35
Author: ColinLee <[email protected]>
AuthorDate: Mon May 12 01:20:31 2025 +0800

    fix read error when tag is empty.
---
 .../reader/block/single_device_tsblock_reader.cc   | 12 +++-
 .../writer/table_view/tsfile_writer_table_test.cc  | 81 ++++++++++++++++++----
 cpp/test/writer/time_chunk_writer_test.cc          |  5 --
 3 files changed, 77 insertions(+), 21 deletions(-)

diff --git a/cpp/src/reader/block/single_device_tsblock_reader.cc 
b/cpp/src/reader/block/single_device_tsblock_reader.cc
index ec8059f9..64587a24 100644
--- a/cpp/src/reader/block/single_device_tsblock_reader.cc
+++ b/cpp/src/reader/block/single_device_tsblock_reader.cc
@@ -199,9 +199,15 @@ int SingleDeviceTsBlockReader::fill_ids() {
     for (const auto& entry : id_column_contexts_) {
         const auto& id_column_context = entry.second;
         for (int32_t pos : id_column_context.pos_in_result_) {
-            common::String device_id(
-                device_query_task_->get_device_id()->get_segments().at(
-                    id_column_context.pos_in_device_id_));
+            common::String device_id;
+            if (device_query_task_->get_device_id()->segment_num() <=
+                id_column_context.pos_in_device_id_) {
+                device_id = common::String("");
+            } else {
+                device_id = common::String(
+                    device_query_task_->get_device_id()->get_segments().at(
+                        id_column_context.pos_in_device_id_));
+            }
             if (RET_FAIL(col_appenders_[pos + 1]->fill(
                     (char*)&device_id, sizeof(device_id),
                     current_block_->get_row_count()))) {
diff --git a/cpp/test/writer/table_view/tsfile_writer_table_test.cc 
b/cpp/test/writer/table_view/tsfile_writer_table_test.cc
index 121e63a2..9897a82b 100644
--- a/cpp/test/writer/table_view/tsfile_writer_table_test.cc
+++ b/cpp/test/writer/table_view/tsfile_writer_table_test.cc
@@ -148,8 +148,8 @@ TEST_F(TsFileWriterTableTest, WriteDisorderTest) {
     int num_timestamp_per_device = 10;
     int offset = 0;
     storage::Tablet tablet(table_schema->get_measurement_names(),
-                       table_schema->get_data_types(),
-                       device_num * num_timestamp_per_device);
+                           table_schema->get_data_types(),
+                           device_num * num_timestamp_per_device);
 
     char* literal = new char[std::strlen("device_id") + 1];
     std::strcpy(literal, "device_id");
@@ -158,7 +158,9 @@ TEST_F(TsFileWriterTableTest, WriteDisorderTest) {
         for (int l = 0; l < num_timestamp_per_device; l++) {
             int row_index = i * num_timestamp_per_device + l;
             // disordered timestamp.
-            tablet.add_timestamp(row_index, l > num_timestamp_per_device / 2 ? 
l - num_timestamp_per_device : offset + l);
+            tablet.add_timestamp(row_index, l > num_timestamp_per_device / 2
+                                                ? l - num_timestamp_per_device
+                                                : offset + l);
             auto column_schemas = table_schema->get_measurement_schemas();
             for (const auto& column_schema : column_schemas) {
                 switch (column_schema->data_type_) {
@@ -166,12 +168,12 @@ TEST_F(TsFileWriterTableTest, WriteDisorderTest) {
                         tablet.add_value(row_index,
                                          column_schema->measurement_name_,
                                          static_cast<int64_t>(i));
-                    break;
+                        break;
                     case TSDataType::STRING:
                         tablet.add_value(row_index,
                                          column_schema->measurement_name_,
                                          literal_str);
-                    break;
+                        break;
                     default:
                         break;
                 }
@@ -180,7 +182,8 @@ TEST_F(TsFileWriterTableTest, WriteDisorderTest) {
     }
     delete[] literal;
 
-    ASSERT_EQ(tsfile_table_writer_->write_table(tablet), 
common::E_OUT_OF_ORDER);
+    ASSERT_EQ(tsfile_table_writer_->write_table(tablet),
+              common::E_OUT_OF_ORDER);
     ASSERT_EQ(tsfile_table_writer_->flush(), common::E_OK);
     ASSERT_EQ(tsfile_table_writer_->close(), common::E_OK);
     delete table_schema;
@@ -249,6 +252,62 @@ TEST_F(TsFileWriterTableTest, WriterWithMemoryThreshold) {
     delete table_schema;
 }
 
+TEST_F(TsFileWriterTableTest, EmptyTagWrite) {
+    std::vector<MeasurementSchema*> measurement_schemas;
+    std::vector<ColumnCategory> column_categories;
+    measurement_schemas.resize(3);
+    measurement_schemas[0] = new MeasurementSchema("device1", STRING);
+    measurement_schemas[1] = new MeasurementSchema("device2", STRING);
+    measurement_schemas[2] = new MeasurementSchema("value", DOUBLE);
+    column_categories.emplace_back(ColumnCategory::TAG);
+    column_categories.emplace_back(ColumnCategory::TAG);
+    column_categories.emplace_back(ColumnCategory::FIELD);
+    TableSchema* table_schema =
+        new TableSchema("test_table", measurement_schemas, column_categories);
+    auto tsfile_table_writer =
+        std::make_shared<TsFileTableWriter>(&write_file_, table_schema);
+    Tablet tablet = Tablet(table_schema->get_measurement_names(),
+                           table_schema->get_data_types());
+    tablet.set_table_name("test_table");
+    for (int i = 0; i < 100; i++) {
+        tablet.add_timestamp(i, static_cast<int64_t>(i));
+        tablet.add_value(i, "device1",
+                         std::string("device" + std::to_string(i)).c_str());
+        tablet.add_value(i, "device2", "");
+        tablet.add_value(i, "value", i * 1.1);
+    }
+    tsfile_table_writer->write_table(tablet);
+    tsfile_table_writer->flush();
+    tsfile_table_writer->close();
+
+    TsFileReader reader = TsFileReader();
+    reader.open(write_file_.get_file_path());
+    ResultSet* ret = nullptr;
+    int ret_value =
+        reader.query("test_table", {"device1", "device2", "value"}, 0, 50, 
ret);
+    ASSERT_EQ(common::E_OK, ret_value);
+
+    ASSERT_EQ(ret_value, 0);
+    auto* table_result_set = (TableResultSet*)ret;
+    bool has_next = false;
+    int cur_line = 0;
+    while (IS_SUCC(table_result_set->next(has_next)) && has_next) {
+        cur_line++;
+        int64_t timestamp = table_result_set->get_value<int64_t>("time");
+        ASSERT_EQ(table_result_set->get_value<common::String*>("device1")
+                      ->to_std_string(),
+                  "device" + to_string(timestamp));
+        ASSERT_EQ(table_result_set->get_value<double>("value"),
+                  timestamp * 1.1);
+    }
+    ASSERT_EQ(cur_line, 51);
+    table_result_set->close();
+    reader.destroy_query_data_set(table_result_set);
+
+    reader.close();
+    delete table_schema;
+}
+
 TEST_F(TsFileWriterTableTest, WritehDataTypeMisMatch) {
     auto table_schema = gen_table_schema(0);
     auto tsfile_table_writer_ = std::make_shared<TsFileTableWriter>(
@@ -262,9 +321,6 @@ TEST_F(TsFileWriterTableTest, WritehDataTypeMisMatch) {
     storage::Tablet tablet(table_schema->get_measurement_names(), datatypes,
                            device_num * num_timestamp_per_device);
 
-    char* literal = new char[std::strlen("device_id") + 1];
-    std::strcpy(literal, "device_id");
-    String literal_str(literal, std::strlen("device_id"));
     for (int i = 0; i < device_num; i++) {
         for (int l = 0; l < num_timestamp_per_device; l++) {
             int row_index = i * num_timestamp_per_device + l;
@@ -283,9 +339,9 @@ TEST_F(TsFileWriterTableTest, WritehDataTypeMisMatch) {
                                          static_cast<int32_t>(i));
                         break;
                     case TSDataType::STRING:
-                        tablet.add_value(row_index,
-                                         
column_schemas[idx]->measurement_name_,
-                                         literal_str);
+                        tablet.add_value(
+                            row_index, column_schemas[idx]->measurement_name_,
+                            std::string("device" + to_string(i)).c_str());
                         break;
                     default:
                         break;
@@ -293,7 +349,6 @@ TEST_F(TsFileWriterTableTest, WritehDataTypeMisMatch) {
             }
         }
     }
-    delete[] literal;
     delete table_schema;
 
     ASSERT_EQ(E_TYPE_NOT_MATCH, tsfile_table_writer_->write_table(tablet));
diff --git a/cpp/test/writer/time_chunk_writer_test.cc 
b/cpp/test/writer/time_chunk_writer_test.cc
index 1f1910c4..df79ab28 100644
--- a/cpp/test/writer/time_chunk_writer_test.cc
+++ b/cpp/test/writer/time_chunk_writer_test.cc
@@ -52,11 +52,6 @@ TEST_F(TimeChunkWriterTest, InitWithParameters) {
     writer.destroy();
 }
 
-TEST_F(TimeChunkWriterTest, WriteBoolean) {
-    EXPECT_EQ(time_chunk_writer.write(true), E_OK);
-    EXPECT_EQ(time_chunk_writer.write(false), E_OK);
-}
-
 TEST_F(TimeChunkWriterTest, WriteLargeDataSet) {
     for (int i = 0; i < 10000; ++i) {
         time_chunk_writer.write(i);

Reply via email to