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

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


The following commit(s) were added to refs/heads/develop by this push:
     new a5424d37 Same name (case insensitive) in tablet / table. (#490)
a5424d37 is described below

commit a5424d3718154ac02b4710cc0daaf244c2bacf63
Author: Colin Lee <[email protected]>
AuthorDate: Wed Jun 4 16:27:59 2025 +0800

    Same name (case insensitive) in tablet / table. (#490)
    
    * tmp code.
    
    * add duplicate column name check.
    
    * fix memory leak.
    
    * fix memory leak.
    
    * fix memory leak.
---
 cpp/src/common/schema.h                            |  4 +++
 cpp/src/common/tablet.cc                           | 16 +++++++--
 cpp/src/common/tablet.h                            | 13 ++++----
 cpp/src/cwrapper/tsfile_cwrapper.cc                |  7 ++--
 cpp/src/writer/tsfile_table_writer.cc              |  4 +++
 cpp/src/writer/tsfile_table_writer.h               |  6 +++-
 cpp/src/writer/tsfile_writer.cc                    | 25 ++++++++++++--
 .../writer/table_view/tsfile_writer_table_test.cc  | 38 ++++++++++++++++++++++
 8 files changed, 97 insertions(+), 16 deletions(-)

diff --git a/cpp/src/common/schema.h b/cpp/src/common/schema.h
index 5deffad9..0227aa50 100644
--- a/cpp/src/common/schema.h
+++ b/cpp/src/common/schema.h
@@ -331,6 +331,10 @@ class TableSchema {
         }
     }
 
+    size_t get_column_pos_index_num() const {
+        return column_pos_index_.size();
+    }
+
     void update(ChunkGroupMeta *chunk_group_meta) {
         for (auto iter = chunk_group_meta->chunk_meta_list_.begin();
              iter != chunk_group_meta->chunk_meta_list_.end(); iter++) {
diff --git a/cpp/src/common/tablet.cc b/cpp/src/common/tablet.cc
index ac4a2708..8bc801cf 100644
--- a/cpp/src/common/tablet.cc
+++ b/cpp/src/common/tablet.cc
@@ -36,9 +36,8 @@ int Tablet::init() {
     std::pair<std::map<std::string, int>::iterator, bool> ins_res;
     for (size_t c = 0; c < schema_count; c++) {
         ins_res = schema_map_.insert(
-            std::make_pair(schema_vec_->at(c).measurement_name_, c));
+            std::make_pair(to_lower(schema_vec_->at(c).measurement_name_), c));
         if (!ins_res.second) {
-            ASSERT(false);
             // maybe dup measurement_name
             return E_INVALID_ARG;
         }
@@ -131,6 +130,9 @@ void Tablet::destroy() {
 }
 
 int Tablet::add_timestamp(uint32_t row_index, int64_t timestamp) {
+    if (err_code_ != E_OK) {
+        return err_code_;
+    }
     ASSERT(timestamps_ != NULL);
     if (UNLIKELY(row_index >= static_cast<uint32_t>(max_row_num_))) {
         ASSERT(false);
@@ -223,6 +225,9 @@ void Tablet::process_val(uint32_t row_index, uint32_t 
schema_index, T val) {
 
 template <typename T>
 int Tablet::add_value(uint32_t row_index, uint32_t schema_index, T val) {
+    if (err_code_ != E_OK) {
+        return err_code_;
+    }
     int ret = common::E_OK;
     if (UNLIKELY(schema_index >= schema_vec_->size())) {
         ASSERT(false);
@@ -250,6 +255,9 @@ int Tablet::add_value(uint32_t row_index, uint32_t 
schema_index, T val) {
 template <>
 int Tablet::add_value(uint32_t row_index, uint32_t schema_index,
                       common::String val) {
+    if (err_code_ != E_OK) {
+        return err_code_;
+    }
     int ret = common::E_OK;
     if (UNLIKELY(schema_index >= schema_vec_->size())) {
         ASSERT(false);
@@ -269,9 +277,11 @@ template <typename T>
 int Tablet::add_value(uint32_t row_index, const std::string &measurement_name,
                       T val) {
     int ret = common::E_OK;
+    if (err_code_ != E_OK) {
+        return err_code_;
+    }
     SchemaMapIterator find_iter = schema_map_.find(measurement_name);
     if (LIKELY(find_iter == schema_map_.end())) {
-        ASSERT(false);
         ret = E_INVALID_ARG;
     } else {
         ret = add_value(row_index, find_iter->second, val);
diff --git a/cpp/src/common/tablet.h b/cpp/src/common/tablet.h
index e69d477e..b036cca9 100644
--- a/cpp/src/common/tablet.h
+++ b/cpp/src/common/tablet.h
@@ -57,6 +57,7 @@ class Tablet {
 
    public:
     static const uint32_t DEFAULT_MAX_ROWS = 1024;
+    int err_code_ = common::E_OK;
 
    public:
     Tablet(const std::string &device_id,
@@ -75,7 +76,7 @@ class Tablet {
             ASSERT(false);
             max_row_num_ = DEFAULT_MAX_ROWS;
         }
-        init();
+        err_code_ = init();
     }
 
     Tablet(const std::string &device_id,
@@ -106,7 +107,7 @@ class Tablet {
                            return MeasurementSchema(name, type);
                        });
         schema_vec_ = 
std::make_shared<std::vector<MeasurementSchema>>(measurement_vec);
-        init();
+        err_code_ = init();
     }
 
     Tablet(const std::string &insert_target_name,
@@ -127,7 +128,7 @@ class Tablet {
                                   common::get_default_compressor()));
         }
         set_column_categories(column_categories);
-        init();
+        err_code_ = init();
     }
 
     /**
@@ -150,10 +151,10 @@ class Tablet {
         schema_vec_ = std::make_shared<std::vector<MeasurementSchema>>();
         for (size_t i = 0; i < column_names.size(); i++) {
             schema_vec_->emplace_back(
-                MeasurementSchema(column_names[i], data_types[i], 
common::get_value_encoder(data_types[i]),
-                                  common::get_default_compressor()));
+                column_names[i], data_types[i], 
common::get_value_encoder(data_types[i]),
+                                  common::get_default_compressor());
         }
-        init();
+        err_code_ = init();
     }
 
     ~Tablet() { destroy(); }
diff --git a/cpp/src/cwrapper/tsfile_cwrapper.cc 
b/cpp/src/cwrapper/tsfile_cwrapper.cc
index 0997dc42..656737df 100644
--- a/cpp/src/cwrapper/tsfile_cwrapper.cc
+++ b/cpp/src/cwrapper/tsfile_cwrapper.cc
@@ -174,7 +174,7 @@ Tablet tablet_new(char **column_name_list, TSDataType 
*data_types,
     std::vector<std::string> measurement_list;
     std::vector<common::TSDataType> data_type_list;
     for (uint32_t i = 0; i < column_num; i++) {
-        measurement_list.emplace_back(column_name_list[i]);
+        measurement_list.emplace_back(storage::to_lower(column_name_list[i]));
         data_type_list.push_back(
             static_cast<common::TSDataType>(*(data_types + i)));
     }
@@ -196,7 +196,7 @@ ERRNO tablet_add_timestamp(Tablet tablet, uint32_t 
row_index,
                                           const char *column_name,           \
                                           const type value) {                \
         return static_cast<storage::Tablet *>(tablet)->add_value(            \
-            row_index, column_name, value);                                  \
+            row_index, storage::to_lower(column_name), value);               \
     }
 TABLET_ADD_VALUE_BY_NAME_DEF(int32_t);
 TABLET_ADD_VALUE_BY_NAME_DEF(int64_t);
@@ -208,7 +208,7 @@ ERRNO tablet_add_value_by_name_string(Tablet tablet, 
uint32_t row_index,
                                       const char *column_name,
                                       const char *value) {
     return static_cast<storage::Tablet *>(tablet)->add_value(
-        row_index, column_name, common::String(value));
+        row_index, storage::to_lower(column_name), common::String(value));
 }
 
 #define TABLE_ADD_VALUE_BY_INDEX_DEF(type)                                    \
@@ -688,7 +688,6 @@ ERRNO _tsfile_writer_flush(TsFileWriter writer) {
     return w->flush();
 }
 
-
 ResultSet _tsfile_reader_query_device(TsFileReader reader,
                                       const char *device_name,
                                       char **sensor_name, uint32_t sensor_num,
diff --git a/cpp/src/writer/tsfile_table_writer.cc 
b/cpp/src/writer/tsfile_table_writer.cc
index 6cbb0c9b..942b15b5 100644
--- a/cpp/src/writer/tsfile_table_writer.cc
+++ b/cpp/src/writer/tsfile_table_writer.cc
@@ -29,6 +29,10 @@ int storage::TsFileTableWriter::register_table(const 
std::shared_ptr<TableSchema
 }
 
 int storage::TsFileTableWriter::write_table(storage::Tablet& tablet) const {
+    // DIRTY CODE...
+    if (common::E_OK != error_number) {
+        return error_number;
+    }
     if (tablet.get_table_name().empty()) {
         tablet.set_table_name(exclusive_table_name_);
     } else if (!exclusive_table_name_.empty() && tablet.get_table_name() != 
exclusive_table_name_) {
diff --git a/cpp/src/writer/tsfile_table_writer.h 
b/cpp/src/writer/tsfile_table_writer.h
index 72d2833e..d3fc918b 100644
--- a/cpp/src/writer/tsfile_table_writer.h
+++ b/cpp/src/writer/tsfile_table_writer.h
@@ -61,7 +61,7 @@ class TsFileTableWriter {
         // Perform a deep copy. The source TableSchema object may be
         // stack/heap-allocated.
         auto table_schema_ptr = std::make_shared<TableSchema>(*table_schema);
-        tsfile_writer_->register_table(table_schema_ptr);
+        error_number = tsfile_writer_->register_table(table_schema_ptr);
         exclusive_table_name_ = table_schema->get_table_name();
         common::g_config_value_.chunk_group_size_threshold_ = memory_threshold;
     }
@@ -106,6 +106,10 @@ class TsFileTableWriter {
     // if this TsFile only contains one table, this will be its name, 
otherwise,
     // it will be an empty string
     std::string exclusive_table_name_;
+
+    // Some errors may not be conveyed during the construction phase, so it's
+    // necessary to maintain an internal error code.
+    int error_number = common::E_OK;
 };
 
 }  // namespace storage
diff --git a/cpp/src/writer/tsfile_writer.cc b/cpp/src/writer/tsfile_writer.cc
index a570fc54..0f47756d 100644
--- a/cpp/src/writer/tsfile_writer.cc
+++ b/cpp/src/writer/tsfile_writer.cc
@@ -117,6 +117,27 @@ void TsFileWriter::set_generate_table_schema(bool 
generate_table_schema) {
 int TsFileWriter::register_table(
     const std::shared_ptr<TableSchema> &table_schema) {
     if (!table_schema) return E_INVALID_ARG;
+
+    // Empty table name or column name is not allowed.
+    if (table_schema->get_table_name().empty()) {
+        return E_INVALID_ARG;
+    }
+    for (const auto &name : table_schema->get_measurement_names()) {
+        if (name.empty()) {
+            return E_INVALID_ARG;
+        }
+    }
+
+    // Because it is not possible to return an error code for duplicate name
+    // checks during the construction phase of TabletSchema, the duplicate name
+    // check has been moved to the table registration stage.
+
+    // TODO: Add Debug INFO if ErrorCode is not enough to describe problems.
+    if (table_schema->get_column_pos_index_num() !=
+        table_schema->get_measurement_names().size()) {
+        return E_INVALID_ARG;
+    }
+
     if (io_writer_->get_schema()->table_schema_map_.find(
             table_schema->get_table_name()) !=
         io_writer_->get_schema()->table_schema_map_.end()) {
@@ -671,7 +692,7 @@ int TsFileWriter::write_tablet_aligned(const Tablet 
&tablet) {
             continue;
         }
         if (RET_FAIL(value_write_column(value_chunk_writer, tablet, c, 0,
-                           tablet.get_cur_row_size()))) {
+                                        tablet.get_cur_row_size()))) {
             return ret;
         }
     }
@@ -764,7 +785,7 @@ int TsFileWriter::write_table(Tablet &tablet) {
                     continue;
                 }
                 if (RET_FAIL(write_column(chunk_writer, tablet, c, start_idx,
-                             device_id_end_index_pair.second))) {
+                                          device_id_end_index_pair.second))) {
                     return ret;
                 }
             }
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 85ddcbce..a13c20be 100644
--- a/cpp/test/writer/table_view/tsfile_writer_table_test.cc
+++ b/cpp/test/writer/table_view/tsfile_writer_table_test.cc
@@ -351,4 +351,42 @@ TEST_F(TsFileWriterTableTest, WriteAndReadSimple) {
 
     reader.close();
     delete table_schema;
+}
+
+TEST_F(TsFileWriterTableTest, DuplicateColumnName) {
+    std::vector<MeasurementSchema*> measurement_schemas;
+    std::vector<ColumnCategory> column_categories;
+    measurement_schemas.resize(3);
+    measurement_schemas[0] = new MeasurementSchema("device", STRING);
+    column_categories.emplace_back(ColumnCategory::TAG);
+    measurement_schemas[1] = new MeasurementSchema("Device", STRING);
+    column_categories.emplace_back(ColumnCategory::TAG);
+    measurement_schemas[2] = new MeasurementSchema("value", DOUBLE);
+    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");
+    ASSERT_EQ(E_INVALID_ARG, tablet.add_timestamp(0, 10));
+    ASSERT_EQ(E_INVALID_ARG, tablet.add_value(1, 1, 10));
+    ASSERT_EQ(E_INVALID_ARG, tablet.add_value(1, "test", 10));
+    std::vector<MeasurementSchema> measurement_schemas2;
+    for (int i = 0; i < 2; i++) {
+        measurement_schemas2.push_back(*measurement_schemas[i]);
+    }
+    Tablet tablet1 = Tablet(
+        "test_table",
+        
std::make_shared<std::vector<MeasurementSchema>>(measurement_schemas2));
+    tablet1.set_table_name("test_table");
+    ASSERT_EQ(E_INVALID_ARG, tablet1.add_timestamp(0, 10));
+    ASSERT_EQ(E_INVALID_ARG, tablet1.add_value(1, 1, 10));
+    ASSERT_EQ(E_INVALID_ARG, tablet1.add_value(1, "test", 10));
+
+    ASSERT_EQ(E_INVALID_ARG, tsfile_table_writer->write_table(tablet));
+    ASSERT_EQ(E_INVALID_ARG, tsfile_table_writer->register_table(
+                                 
std::make_shared<TableSchema>(*table_schema)));
+    delete table_schema;
 }
\ No newline at end of file

Reply via email to