diff --git a/src/storage/catalog/meta/meta_tree.cpp b/src/storage/catalog/meta/meta_tree.cpp index 9e9e166346..1924927b76 100644 --- a/src/storage/catalog/meta/meta_tree.cpp +++ b/src/storage/catalog/meta/meta_tree.cpp @@ -43,13 +43,12 @@ import new_txn_manager; namespace infinity { -SharedPtr MetaTree::MakeMetaTree(const Vector> &meta_keys) { +SharedPtr MetaTree::MakeMetaTree(Vector> &meta_keys) { SharedPtr meta_tree = MakeShared(); - SizeT meta_count = meta_keys.size(); + auto new_end = meta_keys.end(); // Get all dbs HashSet db_names, db_ids; - for (SizeT idx = 0; idx < meta_count; ++idx) { - const SharedPtr &meta_key = meta_keys[idx]; + new_end = std::remove_if(meta_keys.begin(), new_end, [&](auto &meta_key) mutable { switch (meta_key->type_) { case MetaType::kDB: { auto db_key = static_cast(meta_key.get()); @@ -58,33 +57,33 @@ SharedPtr MetaTree::MakeMetaTree(const Vector> &met // Check if duplicated if (db_names.contains(db_key->db_name_)) { - String error_message = fmt::format("Duplicate db name: {}, idx: {}", db_key->ToString(), idx); + String error_message = fmt::format("Duplicate db name: {}", db_key->ToString()); UnrecoverableError(error_message); } else { db_names.emplace(db_key->db_name_); } if (db_ids.contains(db_key->db_id_str_)) { - String error_message = fmt::format("Duplicate db id: {}, idx: {}", db_key->ToString(), idx); + String error_message = fmt::format("Duplicate db id: {}", db_key->ToString()); UnrecoverableError(error_message); } else { db_ids.emplace(db_key->db_id_str_); } - break; + return true; } case MetaType::kSystemTag: { auto system_tag_key = static_cast(meta_key.get()); meta_tree->system_tag_map_.emplace(system_tag_key->tag_name_, system_tag_key->value_); - break; + return true; } default: break; } - } + return false; + }); // Get all tables and attach to the db - for (SizeT idx = 0; idx < meta_count; ++idx) { - const SharedPtr &meta_key = meta_keys[idx]; + new_end = std::remove_if(meta_keys.begin(), new_end, [&](auto &meta_key) mutable{ switch (meta_key->type_) { case MetaType::kTable: { auto table_key = static_cast(meta_key.get()); @@ -92,259 +91,259 @@ SharedPtr MetaTree::MakeMetaTree(const Vector> &met auto iter = meta_tree->db_map_.find(table_key->db_id_str_); if (iter == meta_tree->db_map_.end()) { - String error_message = fmt::format("DB not found for table: {}, idx: {}", table_key->ToString(), idx); + String error_message = fmt::format("DB not found for table: {}", table_key->ToString()); LOG_WARN(error_message); // DB is dropped - continue; + return true; } auto &table_map = iter->second->table_map_; if (table_map.contains(table_key->table_id_str_)) { - String error_message = fmt::format("Duplicate table id: {}, idx: {}", table_key->ToString(), idx); + String error_message = fmt::format("Duplicate table id: {}", table_key->ToString()); UnrecoverableError(error_message); } table_map.emplace(table_key->table_id_str_, table_object); - break; + return true; } case MetaType::kDBTag: { auto db_tag_key = static_cast(meta_key.get()); auto db_iter = meta_tree->db_map_.find(db_tag_key->db_id_str_); if (db_iter == meta_tree->db_map_.end()) { - String error_message = fmt::format("DB not found for tag: {}, idx: {}", db_tag_key->ToString(), idx); + String error_message = fmt::format("DB not found for tag: {}", db_tag_key->ToString()); LOG_WARN(error_message); // DB is dropped - continue; + return true; } auto &db_object = db_iter->second; auto &tag_map = db_object->tag_map_; if (tag_map.contains(db_tag_key->tag_name_)) { - String error_message = fmt::format("Duplicate db tag: {}, idx: {}", db_tag_key->ToString(), idx); + String error_message = fmt::format("Duplicate db tag: {}", db_tag_key->ToString()); UnrecoverableError(error_message); } tag_map.emplace(db_tag_key->tag_name_, meta_key); - break; + return true; } default: break; } - } + return false; + }); // Get all table segments / table tag / table index / table column and attach them to the table - for (SizeT idx = 0; idx < meta_count; ++idx) { - const SharedPtr &meta_key = meta_keys[idx]; + new_end = std::remove_if(meta_keys.begin(), new_end, [&](auto &meta_key) mutable { switch (meta_key->type_) { case MetaType::kSegment: { auto segment_key = static_cast(meta_key.get()); auto db_iter = meta_tree->db_map_.find(segment_key->db_id_str_); if (db_iter == meta_tree->db_map_.end()) { - String error_message = fmt::format("DB not found: {}, idx: {}", segment_key->ToString(), idx); + String error_message = fmt::format("DB not found: {}", segment_key->ToString()); LOG_WARN(error_message); // DB is dropped - continue; + return true; } auto &table_map = db_iter->second->table_map_; auto table_iter = table_map.find(segment_key->table_id_str_); if (table_iter == table_map.end()) { - String error_message = fmt::format("Table not found: {}, idx: {}", segment_key->ToString(), idx); + String error_message = fmt::format("Table not found: {}", segment_key->ToString()); LOG_WARN(error_message); // The Table is dropped - continue; + return true; } MetaTableObject *table_object = static_cast(table_iter->second.get()); auto &segment_map = table_object->segment_map_; if (segment_map.contains(segment_key->segment_id_)) { - String error_message = fmt::format("Duplicate segment id: {}, idx: {}", segment_key->ToString(), idx); + String error_message = fmt::format("Duplicate segment id: {}", segment_key->ToString()); UnrecoverableError(error_message); } auto segment_object = MakeShared(meta_key); segment_map.emplace(segment_key->segment_id_, segment_object); - break; + return true; } case MetaType::kTableTag: { auto table_tag_key = static_cast(meta_key.get()); auto db_iter = meta_tree->db_map_.find(table_tag_key->db_id_str_); if (db_iter == meta_tree->db_map_.end()) { - String error_message = fmt::format("DB not found: {}, idx: {}", table_tag_key->ToString(), idx); + String error_message = fmt::format("DB not found: {}", table_tag_key->ToString()); LOG_WARN(error_message); // DB is dropped - continue; + return true; } auto &table_map = db_iter->second->table_map_; auto table_iter = table_map.find(table_tag_key->table_id_str_); if (table_iter == table_map.end()) { - String error_message = fmt::format("Table not found: {}, idx: {}", table_tag_key->ToString(), idx); + String error_message = fmt::format("Table not found: {}", table_tag_key->ToString()); LOG_WARN(error_message); // The Table is dropped - continue; + return true; } MetaTableObject *table_object = static_cast(table_iter->second.get()); auto &tag_map = table_object->tag_map_; tag_map.emplace(table_tag_key->tag_name_, meta_key); - break; + return true; } case MetaType::kTableIndex: { auto table_index_meta_key = static_cast(meta_key.get()); auto db_iter = meta_tree->db_map_.find(table_index_meta_key->db_id_str_); if (db_iter == meta_tree->db_map_.end()) { - String error_message = fmt::format("DB not found: {}, idx: {}", table_index_meta_key->ToString(), idx); + String error_message = fmt::format("DB not found: {}", table_index_meta_key->ToString()); LOG_WARN(error_message); // DB is dropped - continue; + return true; } auto &table_map = db_iter->second->table_map_; auto table_iter = table_map.find(table_index_meta_key->table_id_str_); if (table_iter == table_map.end()) { - String error_message = fmt::format("Table not found: {}, idx: {}", table_index_meta_key->ToString(), idx); + String error_message = fmt::format("Table not found: {}", table_index_meta_key->ToString()); LOG_WARN(error_message); // The Table is dropped - continue; + return true; } auto table_index_object = MakeShared(meta_key); MetaTableObject *table_object = static_cast(table_iter->second.get()); auto &index_map = table_object->index_map_; index_map.emplace(table_index_meta_key->index_id_str_, table_index_object); - break; + return true; } case MetaType::kTableColumn: { auto table_column_meta_key = static_cast(meta_key.get()); auto db_iter = meta_tree->db_map_.find(table_column_meta_key->db_id_str_); if (db_iter == meta_tree->db_map_.end()) { - String error_message = fmt::format("DB not found: {}, idx: {}", table_column_meta_key->ToString(), idx); + String error_message = fmt::format("DB not found: {}", table_column_meta_key->ToString()); LOG_WARN(error_message); // DB is dropped - continue; + return true; } auto &table_map = db_iter->second->table_map_; auto table_iter = table_map.find(table_column_meta_key->table_id_str_); if (table_iter == table_map.end()) { - String error_message = fmt::format("Table not found: {}, idx: {}", table_column_meta_key->ToString(), idx); + String error_message = fmt::format("Table not found: {}", table_column_meta_key->ToString()); LOG_WARN(error_message); // The Table is dropped - continue; + return true; } MetaTableObject *table_object = static_cast(table_iter->second.get()); auto &column_map = table_object->column_map_; column_map.emplace(table_column_meta_key->column_name_, meta_key); - break; + return true; } default: break; } - } + return false; + }); // Get all blocks and attach to segment - for (SizeT idx = 0; idx < meta_count; ++idx) { - const SharedPtr &meta_key = meta_keys[idx]; + new_end = std::remove_if(meta_keys.begin(), new_end, [&](auto &meta_key) mutable { switch (meta_key->type_) { case MetaType::kBlock: { auto block_key = static_cast(meta_key.get()); auto db_iter = meta_tree->db_map_.find(block_key->db_id_str_); if (db_iter == meta_tree->db_map_.end()) { - String error_message = fmt::format("DB not found: {}, idx: {}", block_key->ToString(), idx); + String error_message = fmt::format("DB not found: {}", block_key->ToString()); LOG_WARN(error_message); // DB is dropped - continue; + return true; } auto &table_map = db_iter->second->table_map_; auto table_iter = table_map.find(block_key->table_id_str_); if (table_iter == table_map.end()) { - String error_message = fmt::format("Table not found: {}, idx: {}", block_key->ToString(), idx); + String error_message = fmt::format("Table not found: {}", block_key->ToString()); LOG_WARN(error_message); // The Table is dropped - continue; + return true; } MetaTableObject *table_object = static_cast(table_iter->second.get()); auto &segment_map = table_object->segment_map_; auto segment_iter = segment_map.find(block_key->segment_id_); if (segment_iter == segment_map.end()) { - String error_message = fmt::format("Segment not found: {}, idx: {}", block_key->ToString(), idx); + String error_message = fmt::format("Segment not found: {}", block_key->ToString()); LOG_WARN(error_message); - continue; + return true; } MetaSegmentObject *segment_object = static_cast(segment_iter->second.get()); auto block_object = MakeShared(meta_key); auto &block_map = segment_object->block_map_; block_map.emplace(block_key->block_id_, block_object); - break; + return true; } case MetaType::kSegmentTag: { auto segment_tag = static_cast(meta_key.get()); auto db_iter = meta_tree->db_map_.find(segment_tag->db_id_str_); if (db_iter == meta_tree->db_map_.end()) { - String error_message = fmt::format("DB not found: {}, idx: {}", segment_tag->ToString(), idx); + String error_message = fmt::format("DB not found: {}", segment_tag->ToString()); LOG_WARN(error_message); // DB is dropped - continue; + return true; } auto &table_map = db_iter->second->table_map_; auto table_iter = table_map.find(segment_tag->table_id_str_); if (table_iter == table_map.end()) { - String error_message = fmt::format("Table not found: {}, idx: {}", segment_tag->ToString(), idx); + String error_message = fmt::format("Table not found: {}", segment_tag->ToString()); LOG_WARN(error_message); // The Table is dropped - continue; + return true; } MetaTableObject *table_object = static_cast(table_iter->second.get()); auto &segment_map = table_object->segment_map_; auto segment_iter = segment_map.find(segment_tag->segment_id_); if (segment_iter == segment_map.end()) { - String error_message = fmt::format("Segment not found: {}, idx: {}", segment_tag->ToString(), idx); + String error_message = fmt::format("Segment not found: {}", segment_tag->ToString()); LOG_WARN(error_message); - continue; + return true; } MetaSegmentObject *segment_object = static_cast(segment_iter->second.get()); auto &tag_map = segment_object->tag_map_; tag_map.emplace(segment_tag->tag_name_, meta_key); - break; + return true; } default: break; } - } + return false; + }); // Get all block column / block tag and attach to blocks - for (SizeT idx = 0; idx < meta_count; ++idx) { - const SharedPtr &meta_key = meta_keys[idx]; + new_end = std::remove_if(meta_keys.begin(), new_end, [&](auto &meta_key) mutable { switch (meta_key->type_) { case MetaType::kBlockColumn: { auto block_key = static_cast(meta_key.get()); auto db_iter = meta_tree->db_map_.find(block_key->db_id_str_); if (db_iter == meta_tree->db_map_.end()) { - String error_message = fmt::format("DB not found: {}, idx: {}", block_key->ToString(), idx); + String error_message = fmt::format("DB not found: {}", block_key->ToString()); LOG_WARN(error_message); // DB is dropped - continue; + return true; } auto &table_map = db_iter->second->table_map_; auto table_iter = table_map.find(block_key->table_id_str_); if (table_iter == table_map.end()) { - String error_message = fmt::format("Table not found: {}, idx: {}", block_key->ToString(), idx); + String error_message = fmt::format("Table not found: {}", block_key->ToString()); LOG_WARN(error_message); // The Table is dropped - continue; + return true; } MetaTableObject *table_object = static_cast(table_iter->second.get()); auto &segment_map = table_object->segment_map_; auto segment_iter = segment_map.find(block_key->segment_id_); if (segment_iter == segment_map.end()) { - String error_message = fmt::format("Segment not found: {}, idx: {}", block_key->ToString(), idx); + String error_message = fmt::format("Segment not found: {}", block_key->ToString()); UnrecoverableError(error_message); } @@ -352,25 +351,25 @@ SharedPtr MetaTree::MakeMetaTree(const Vector> &met auto block_object = MakeShared(meta_key); auto &block_map = segment_object->block_map_; block_map.emplace(block_key->block_id_, block_object); - break; + return true; } case MetaType::kBlockTag: { auto block_tag = static_cast(meta_key.get()); auto db_iter = meta_tree->db_map_.find(block_tag->db_id_str_); if (db_iter == meta_tree->db_map_.end()) { - String error_message = fmt::format("DB not found: {}, idx: {}", block_tag->ToString(), idx); + String error_message = fmt::format("DB not found: {}", block_tag->ToString()); LOG_WARN(error_message); // DB is dropped - continue; + return true; } auto &table_map = db_iter->second->table_map_; auto table_iter = table_map.find(block_tag->table_id_str_); if (table_iter == table_map.end()) { - String error_message = fmt::format("Table not found: {}, idx: {}", block_tag->ToString(), idx); + String error_message = fmt::format("Table not found: {}", block_tag->ToString()); LOG_WARN(error_message); // The Table is dropped - continue; + return true; } MetaTableObject *table_object = static_cast(table_iter->second.get()); @@ -378,203 +377,204 @@ SharedPtr MetaTree::MakeMetaTree(const Vector> &met auto segment_iter = segment_map.find(block_tag->segment_id_); if (segment_iter == segment_map.end()) { // Segment is compacted - String error_message = fmt::format("Segment not found, maybe is compacted: {}, idx: {}", block_tag->ToString(), idx); + String error_message = fmt::format("Segment not found: {}", block_tag->ToString()); LOG_WARN(error_message); - continue; + return true; } MetaSegmentObject *segment_object = static_cast(segment_iter->second.get()); auto &block_map = segment_object->block_map_; auto block_iter = block_map.find(block_tag->block_id_); if (block_iter == block_map.end()) { - String error_message = fmt::format("Block not found: {}, idx: {}", block_tag->ToString(), idx); + String error_message = fmt::format("Block not found: {}", block_tag->ToString()); UnrecoverableError(error_message); } MetaBlockObject *block_object = static_cast(block_iter->second.get()); auto &tag_map = block_object->tag_map_; tag_map.emplace(block_tag->tag_name_, meta_key); - break; + return true; } default: break; } - } + return false; + }); // Get all segment indexes and attach to table index - for (SizeT idx = 0; idx < meta_count; ++idx) { - const SharedPtr &meta_key = meta_keys[idx]; + new_end = std::remove_if(meta_keys.begin(), new_end, [&](auto &meta_key) mutable { switch (meta_key->type_) { case MetaType::kSegmentIndex: { auto segment_index_key = static_cast(meta_key.get()); auto db_iter = meta_tree->db_map_.find(segment_index_key->db_id_str_); if (db_iter == meta_tree->db_map_.end()) { - String error_message = fmt::format("DB not found: {}, idx: {}", segment_index_key->ToString(), idx); + String error_message = fmt::format("DB not found: {}", segment_index_key->ToString()); LOG_WARN(error_message); // DB is dropped - continue; + return true; } auto &table_map = db_iter->second->table_map_; auto table_iter = table_map.find(segment_index_key->table_id_str_); if (table_iter == table_map.end()) { - String error_message = fmt::format("Table not found: {}, idx: {}", segment_index_key->ToString(), idx); + String error_message = fmt::format("Table not found: {}", segment_index_key->ToString()); LOG_WARN(error_message); - // The Table is dropped - continue; + // Table is dropped + return true; } MetaTableObject *table_object = static_cast(table_iter->second.get()); auto &index_map = table_object->index_map_; auto table_index_iter = index_map.find(segment_index_key->index_id_str_); if (table_index_iter == index_map.end()) { - String error_message = fmt::format("Table index not found: {}, idx: {}", segment_index_key->ToString(), idx); + String error_message = fmt::format("Table index not found: {}", segment_index_key->ToString()); LOG_WARN(error_message); // Table index is dropped - continue; + return true; } MetaTableIndexObject *table_index_object = static_cast(table_index_iter->second.get()); auto segment_index_object = MakeShared(meta_key); table_index_object->segment_map_.emplace(segment_index_key->segment_id_, segment_index_object); - break; + return true; } case MetaType::kTableIndexTag: { auto table_index_tag_key = static_cast(meta_key.get()); auto db_iter = meta_tree->db_map_.find(table_index_tag_key->db_id_str_); if (db_iter == meta_tree->db_map_.end()) { - String error_message = fmt::format("DB not found: {}, idx: {}", table_index_tag_key->ToString(), idx); + String error_message = fmt::format("DB not found: {}", table_index_tag_key->ToString()); LOG_WARN(error_message); // DB is dropped - continue; + return true; } auto &table_map = db_iter->second->table_map_; auto table_iter = table_map.find(table_index_tag_key->table_id_str_); if (table_iter == table_map.end()) { - String error_message = fmt::format("Table not found: {}, idx: {}", table_index_tag_key->ToString(), idx); + String error_message = fmt::format("Table not found: {}", table_index_tag_key->ToString()); LOG_WARN(error_message); // The Table is dropped - continue; + return true; } MetaTableObject *table_object = static_cast(table_iter->second.get()); auto &index_map = table_object->index_map_; auto table_index_iter = index_map.find(table_index_tag_key->index_id_str_); if (table_index_iter == index_map.end()) { - String error_message = fmt::format("Table index not found: {}, idx: {}", table_index_tag_key->ToString(), idx); + String error_message = fmt::format("Table index not found: {}", table_index_tag_key->ToString()); LOG_WARN(error_message); // Table index is dropped. - continue; + return true; } MetaTableIndexObject *table_index_object = static_cast(table_index_iter->second.get()); auto &tag_map = table_index_object->tag_map_; tag_map.emplace(table_index_tag_key->tag_name_, meta_key); - break; + return true; } default: break; } - } + return false; + }); // Get all chunk indexes and attach to segment index - for (SizeT idx = 0; idx < meta_count; ++idx) { - const SharedPtr &meta_key = meta_keys[idx]; + new_end = std::remove_if(meta_keys.begin(), new_end, [&](auto &meta_key) mutable { switch (meta_key->type_) { case MetaType::kChunkIndex: { auto chunk_index_key = static_cast(meta_key.get()); auto db_iter = meta_tree->db_map_.find(chunk_index_key->db_id_str_); if (db_iter == meta_tree->db_map_.end()) { - String error_message = fmt::format("DB not found: {}, idx: {}", chunk_index_key->ToString(), idx); + String error_message = fmt::format("DB not found: {}", chunk_index_key->ToString()); LOG_WARN(error_message); // DB is dropped - continue; + return true; } auto &table_map = db_iter->second->table_map_; auto table_iter = table_map.find(chunk_index_key->table_id_str_); if (table_iter == table_map.end()) { - String error_message = fmt::format("Table not found: {}, idx: {}", chunk_index_key->ToString(), idx); + String error_message = fmt::format("Table not found: {}", chunk_index_key->ToString()); LOG_WARN(error_message); // The Table is dropped - continue; + return true; } MetaTableObject *table_object = static_cast(table_iter->second.get()); auto &index_map = table_object->index_map_; auto table_index_iter = index_map.find(chunk_index_key->index_id_str_); if (table_index_iter == index_map.end()) { - String error_message = fmt::format("Table index not found: {}, idx: {}", chunk_index_key->ToString(), idx); + String error_message = fmt::format("Table index not found: {}", chunk_index_key->ToString()); LOG_WARN(error_message); // The Table is dropped - continue; + return true; } MetaTableIndexObject *table_index_object = static_cast(table_index_iter->second.get()); auto &segment_map = table_index_object->segment_map_; auto segment_index_iter = segment_map.find(chunk_index_key->segment_id_); if (segment_index_iter == segment_map.end()) { - String error_message = fmt::format("Segment index not found: {}, idx: {}", chunk_index_key->ToString(), idx); + String error_message = fmt::format("Segment index not found: {}", chunk_index_key->ToString()); LOG_WARN(error_message); - continue; + return true; } MetaSegmentIndexObject *segment_index_object = static_cast(segment_index_iter->second.get()); auto &chunk_map = segment_index_object->chunk_map_; chunk_map.emplace(chunk_index_key->chunk_id_, meta_key); - break; + return true; } default: break; } - } + return false; + }); // Get all pm object stat - for (SizeT idx = 0; idx < meta_count; ++idx) { - const SharedPtr &meta_key = meta_keys[idx]; + new_end = std::remove_if(meta_keys.begin(), new_end, [&](auto &meta_key) mutable { switch (meta_key->type_) { case MetaType::kPmObject: { auto pm_obj_key = static_cast(meta_key.get()); auto pm_obj_iter = meta_tree->pm_object_map_.find(pm_obj_key->object_key_); if (pm_obj_iter != meta_tree->pm_object_map_.end()) { - String error_message = fmt::format("Duplicate pm object key: {}, idx: {}", pm_obj_key->ToString(), idx); + String error_message = fmt::format("Duplicate pm object key: {}", pm_obj_key->ToString()); UnrecoverableError(error_message); } auto pm_object = MakeShared(meta_key); meta_tree->pm_object_map_.emplace(pm_obj_key->object_key_, pm_object); - break; + return true; } default: break; } - } + return false; + }); // Get pm object - for (SizeT idx = 0; idx < meta_count; ++idx) { - const SharedPtr &meta_key = meta_keys[idx]; + new_end = std::remove_if(meta_keys.begin(), new_end, [&](auto &meta_key) mutable { switch (meta_key->type_) { case MetaType::kPmPath: { auto pm_path_key = static_cast(meta_key.get()); nlohmann::json pm_path_json = nlohmann::json::parse(pm_path_key->value_); String object_key = pm_path_json["obj_key"]; if (object_key == "KEY_EMPTY") { - continue; + return true; } auto pm_obj_iter = meta_tree->pm_object_map_.find(object_key); if (pm_obj_iter == meta_tree->pm_object_map_.end()) { - String error_message = fmt::format("PM object not found: {}, idx: {}", pm_path_key->ToString(), idx); + String error_message = fmt::format("PM object not found: {}", pm_path_key->ToString()); UnrecoverableError(error_message); } pm_obj_iter->second->path_map_.emplace(pm_path_key->path_key_, meta_key); - break; + return true; } default: break; } - } + return false; + }); return meta_tree; } diff --git a/src/storage/catalog/meta/meta_tree.cppm b/src/storage/catalog/meta/meta_tree.cppm index 6d9299d48f..eb43680e5d 100644 --- a/src/storage/catalog/meta/meta_tree.cppm +++ b/src/storage/catalog/meta/meta_tree.cppm @@ -124,7 +124,7 @@ export struct MetaPmObject final : public MetaObject { }; export struct MetaTree { - static SharedPtr MakeMetaTree(const Vector> &meta_keys); + static SharedPtr MakeMetaTree(Vector> &meta_keys); public: static bool PathFilter(std::string_view path, CheckStmtType tag, Optional db_table_str);