This is an automated email from the ASF dual-hosted git repository. panxiaolei pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 30ccc7e028e [Chore](descriptors) remove unused codes for descriptors (#33408) 30ccc7e028e is described below commit 30ccc7e028e303c0cd967d51f39cefbeac0028be Author: Pxl <pxl...@qq.com> AuthorDate: Wed Apr 10 15:04:54 2024 +0800 [Chore](descriptors) remove unused codes for descriptors (#33408) remove unused codes for descriptors --- be/src/pipeline/exec/scan_operator.cpp | 5 +- be/src/pipeline/exec/scan_operator.h | 8 +- be/src/runtime/descriptor_helper.h | 10 +- be/src/runtime/descriptors.cpp | 132 ++++------------- be/src/runtime/descriptors.h | 161 ++++----------------- be/src/vec/exec/scan/vscan_node.cpp | 43 +++--- be/test/testutil/desc_tbl_builder.cpp | 7 +- be/test/vec/exec/parquet/parquet_thrift_test.cpp | 2 +- be/test/vec/exprs/vexpr_test.cpp | 2 +- .../org/apache/doris/analysis/SlotDescriptor.java | 2 +- .../org/apache/doris/analysis/TupleDescriptor.java | 33 +---- .../doris/planner/TableFunctionPlanTest.java | 16 +- gensrc/proto/descriptors.proto | 8 +- gensrc/thrift/Descriptors.thrift | 8 +- 14 files changed, 116 insertions(+), 321 deletions(-) diff --git a/be/src/pipeline/exec/scan_operator.cpp b/be/src/pipeline/exec/scan_operator.cpp index 0107f57bd20..baff3df2d37 100644 --- a/be/src/pipeline/exec/scan_operator.cpp +++ b/be/src/pipeline/exec/scan_operator.cpp @@ -748,9 +748,8 @@ Status ScanLocalState<Derived>::_should_push_down_binary_predicate( } else { std::shared_ptr<ColumnPtrWrapper> const_col_wrapper; RETURN_IF_ERROR(children[1 - i]->get_const_col(expr_ctx, &const_col_wrapper)); - if (const vectorized::ColumnConst* const_column = - check_and_get_column<vectorized::ColumnConst>( - const_col_wrapper->column_ptr)) { + if (const auto* const_column = check_and_get_column<vectorized::ColumnConst>( + const_col_wrapper->column_ptr)) { *slot_ref_child = i; *constant_val = const_column->get_data_at(0); } else { diff --git a/be/src/pipeline/exec/scan_operator.h b/be/src/pipeline/exec/scan_operator.h index a741893a747..35a5d0c722a 100644 --- a/be/src/pipeline/exec/scan_operator.h +++ b/be/src/pipeline/exec/scan_operator.h @@ -63,7 +63,7 @@ public: : PipelineXLocalState<>(state, parent), vectorized::RuntimeFilterConsumer(parent->node_id(), parent->runtime_filter_descs(), parent->row_descriptor(), _conjuncts) {} - virtual ~ScanLocalStateBase() = default; + ~ScanLocalStateBase() override = default; virtual bool ready_to_read() = 0; @@ -159,8 +159,8 @@ class ScanLocalState : public ScanLocalStateBase { } Status clone_conjunct_ctxs(vectorized::VExprContextSPtrs& conjuncts) override; - virtual void set_scan_ranges(RuntimeState* state, - const std::vector<TScanRangeParams>& scan_ranges) override {} + void set_scan_ranges(RuntimeState* state, + const std::vector<TScanRangeParams>& scan_ranges) override {} TPushAggOp::type get_push_down_agg_type() override; @@ -186,7 +186,7 @@ protected: friend class vectorized::ScannerContext; friend class vectorized::VScanner; - virtual Status _init_profile() override; + Status _init_profile() override; virtual Status _process_conjuncts() { RETURN_IF_ERROR(_normalize_conjuncts()); return Status::OK(); diff --git a/be/src/runtime/descriptor_helper.h b/be/src/runtime/descriptor_helper.h index 15c0d68599c..049947478d3 100644 --- a/be/src/runtime/descriptor_helper.h +++ b/be/src/runtime/descriptor_helper.h @@ -110,14 +110,6 @@ public: void build(TDescriptorTableBuilder* tb) { // build slot desc _tuple_id = tb->next_tuple_id(); - int num_nullables = 0; - for (int i = 0; i < _slot_descs.size(); ++i) { - auto& slot_desc = _slot_descs[i]; - if (slot_desc.nullIndicatorByte >= 0) { - num_nullables++; - } - } - int null_bytes = (num_nullables + 7) / 8; int null_offset = 0; for (int i = 0; i < _slot_descs.size(); ++i) { auto& slot_desc = _slot_descs[i]; @@ -137,7 +129,7 @@ public: _tuple_desc.id = _tuple_id; // Useless not set it. _tuple_desc.byteSize = 0; - _tuple_desc.numNullBytes = null_bytes; + _tuple_desc.numNullBytes = 0; _tuple_desc.numNullSlots = _slot_descs.size(); tb->add_slots(_slot_descs); diff --git a/be/src/runtime/descriptors.cpp b/be/src/runtime/descriptors.cpp index 0fb43631916..4c72a445054 100644 --- a/be/src/runtime/descriptors.cpp +++ b/be/src/runtime/descriptors.cpp @@ -39,24 +39,13 @@ namespace doris { const int RowDescriptor::INVALID_IDX = -1; -std::string NullIndicatorOffset::debug_string() const { - std::stringstream out; - out << "(offset=" << byte_offset << " mask=" << std::hex << static_cast<int>(bit_mask) - << std::dec << ")"; - return out.str(); -} - -std::ostream& operator<<(std::ostream& os, const NullIndicatorOffset& null_indicator) { - os << null_indicator.debug_string(); - return os; -} SlotDescriptor::SlotDescriptor(const TSlotDescriptor& tdesc) : _id(tdesc.id), _type(TypeDescriptor::from_thrift(tdesc.slotType)), _parent(tdesc.parent), _col_pos(tdesc.columnPos), - _null_indicator_offset(tdesc.nullIndicatorByte, tdesc.nullIndicatorBit), + _is_nullable(tdesc.nullIndicatorBit != -1), _col_name(tdesc.colName), _col_name_lower_case(to_lower(tdesc.colName)), _col_unique_id(tdesc.col_unique_id), @@ -75,7 +64,7 @@ SlotDescriptor::SlotDescriptor(const PSlotDescriptor& pdesc) _type(TypeDescriptor::from_protobuf(pdesc.slot_type())), _parent(pdesc.parent()), _col_pos(pdesc.column_pos()), - _null_indicator_offset(pdesc.null_indicator_byte(), pdesc.null_indicator_bit()), + _is_nullable(pdesc.null_indicator_bit() != -1), _col_name(pdesc.col_name()), _col_name_lower_case(to_lower(pdesc.col_name())), _col_unique_id(pdesc.col_unique_id()), @@ -94,9 +83,8 @@ void SlotDescriptor::to_protobuf(PSlotDescriptor* pslot) const { _type.to_protobuf(pslot->mutable_slot_type()); pslot->set_column_pos(_col_pos); pslot->set_byte_offset(0); - pslot->set_null_indicator_byte(_null_indicator_offset.byte_offset); - pslot->set_null_indicator_bit(_null_indicator_offset.bit_offset); - DCHECK_LE(_null_indicator_offset.bit_offset, 8); + pslot->set_null_indicator_byte(0); + pslot->set_null_indicator_bit(_is_nullable ? 0 : -1); pslot->set_col_name(_col_name); pslot->set_slot_idx(_slot_idx); pslot->set_is_materialized(_is_materialized); @@ -305,33 +293,15 @@ std::string JdbcTableDescriptor::debug_string() const { TupleDescriptor::TupleDescriptor(const TTupleDescriptor& tdesc, bool own_slots) : _id(tdesc.id), - _table_desc(nullptr), - _num_null_bytes(tdesc.numNullBytes), _num_materialized_slots(0), _has_varlen_slots(false), - _own_slots(own_slots) { - if (false == tdesc.__isset.numNullSlots) { - //be compatible for existing tables with no nullptr value - _num_null_slots = 0; - } else { - _num_null_slots = tdesc.numNullSlots; - } -} + _own_slots(own_slots) {} TupleDescriptor::TupleDescriptor(const PTupleDescriptor& pdesc, bool own_slots) : _id(pdesc.id()), - _table_desc(nullptr), - _num_null_bytes(pdesc.num_null_bytes()), _num_materialized_slots(0), _has_varlen_slots(false), - _own_slots(own_slots) { - if (!pdesc.has_num_null_slots()) { - //be compatible for existing tables with no nullptr value - _num_null_slots = 0; - } else { - _num_null_slots = pdesc.num_null_slots(); - } -} + _own_slots(own_slots) {} void TupleDescriptor::add_slot(SlotDescriptor* slot) { _slots.push_back(slot); @@ -339,34 +309,19 @@ void TupleDescriptor::add_slot(SlotDescriptor* slot) { if (slot->is_materialized()) { ++_num_materialized_slots; - if (slot->type().is_string_type()) { - _string_slots.push_back(slot); - _has_varlen_slots = true; - } else if (slot->type().is_collection_type()) { - _collection_slots.push_back(slot); + if (slot->type().is_string_type() || slot->type().is_collection_type()) { _has_varlen_slots = true; - } else { - _no_string_slots.push_back(slot); } } } -std::vector<SlotDescriptor*> TupleDescriptor::slots_ordered_by_idx() const { - std::vector<SlotDescriptor*> sorted_slots(slots().size()); - for (SlotDescriptor* slot : slots()) { - sorted_slots[slot->_slot_idx] = slot; - } - return sorted_slots; -} - void TupleDescriptor::to_protobuf(PTupleDescriptor* ptuple) const { ptuple->Clear(); ptuple->set_id(_id); // Useless not set ptuple->set_byte_size(0); - ptuple->set_num_null_bytes(_num_null_bytes); ptuple->set_table_id(-1); - ptuple->set_num_null_slots(_num_null_slots); + ptuple->set_num_null_bytes(0); } std::string TupleDescriptor::debug_string() const { @@ -398,16 +353,13 @@ RowDescriptor::RowDescriptor(const DescriptorTbl& desc_tbl, const std::vector<TT << row_tuples.size(); DCHECK_GT(row_tuples.size(), 0); _num_materialized_slots = 0; - _num_null_slots = 0; - for (int i = 0; i < row_tuples.size(); ++i) { - TupleDescriptor* tupleDesc = desc_tbl.get_tuple_descriptor(row_tuples[i]); + for (int row_tuple : row_tuples) { + TupleDescriptor* tupleDesc = desc_tbl.get_tuple_descriptor(row_tuple); _num_materialized_slots += tupleDesc->num_materialized_slots(); - _num_null_slots += tupleDesc->num_null_slots(); _tuple_desc_map.push_back(tupleDesc); DCHECK(_tuple_desc_map.back() != nullptr); } - _num_null_bytes = (_num_null_slots + 7) / 8; init_tuple_idx_map(); init_has_varlen_slots(); @@ -437,8 +389,8 @@ RowDescriptor::RowDescriptor(const RowDescriptor& lhs_row_desc, const RowDescrip void RowDescriptor::init_tuple_idx_map() { // find max id TupleId max_id = 0; - for (int i = 0; i < _tuple_desc_map.size(); ++i) { - max_id = std::max(_tuple_desc_map[i]->id(), max_id); + for (auto& i : _tuple_desc_map) { + max_id = std::max(i->id(), max_id); } _tuple_idx_map.resize(max_id + 1, INVALID_IDX); @@ -449,24 +401,14 @@ void RowDescriptor::init_tuple_idx_map() { void RowDescriptor::init_has_varlen_slots() { _has_varlen_slots = false; - for (int i = 0; i < _tuple_desc_map.size(); ++i) { - if (_tuple_desc_map[i]->has_varlen_slots()) { + for (auto& i : _tuple_desc_map) { + if (i->has_varlen_slots()) { _has_varlen_slots = true; break; } } } -int RowDescriptor::get_row_size() const { - int size = 0; - - for (int i = 0; i < _tuple_desc_map.size(); ++i) { - size += _tuple_desc_map[i]->byte_size(); - } - - return size; -} - int RowDescriptor::get_tuple_idx(TupleId id) const { // comment CHECK temporarily to make fuzzy test run smoothly // DCHECK_LT(id, _tuple_idx_map.size()) << "RowDescriptor: " << debug_string(); @@ -476,32 +418,18 @@ int RowDescriptor::get_tuple_idx(TupleId id) const { return _tuple_idx_map[id]; } -bool RowDescriptor::tuple_is_nullable(int tuple_idx) const { - DCHECK_LT(tuple_idx, _tuple_idx_nullable_map.size()) << "RowDescriptor: " << debug_string(); - return _tuple_idx_nullable_map[tuple_idx]; -} - -bool RowDescriptor::is_any_tuple_nullable() const { - for (int i = 0; i < _tuple_idx_nullable_map.size(); ++i) { - if (_tuple_idx_nullable_map[i]) { - return true; - } - } - return false; -} - void RowDescriptor::to_thrift(std::vector<TTupleId>* row_tuple_ids) { row_tuple_ids->clear(); - for (int i = 0; i < _tuple_desc_map.size(); ++i) { - row_tuple_ids->push_back(_tuple_desc_map[i]->id()); + for (auto& i : _tuple_desc_map) { + row_tuple_ids->push_back(i->id()); } } void RowDescriptor::to_protobuf( google::protobuf::RepeatedField<google::protobuf::int32>* row_tuple_ids) const { row_tuple_ids->Clear(); - for (auto desc : _tuple_desc_map) { + for (auto* desc : _tuple_desc_map) { row_tuple_ids->Add(desc->id()); } } @@ -571,8 +499,8 @@ std::string RowDescriptor::debug_string() const { int RowDescriptor::get_column_id(int slot_id, bool force_materialize_slot) const { int column_id_counter = 0; - for (const auto tuple_desc : _tuple_desc_map) { - for (const auto slot : tuple_desc->slots()) { + for (auto* const tuple_desc : _tuple_desc_map) { + for (auto* const slot : tuple_desc->slots()) { if (!force_materialize_slot && !slot->need_materialize()) { continue; } @@ -590,8 +518,7 @@ Status DescriptorTbl::create(ObjectPool* pool, const TDescriptorTable& thrift_tb *tbl = pool->add(new DescriptorTbl()); // deserialize table descriptors first, they are being referenced by tuple descriptors - for (size_t i = 0; i < thrift_tbl.tableDescriptors.size(); ++i) { - const TTableDescriptor& tdesc = thrift_tbl.tableDescriptors[i]; + for (const auto& tdesc : thrift_tbl.tableDescriptors) { TableDescriptor* desc = nullptr; switch (tdesc.tableType) { @@ -638,8 +565,7 @@ Status DescriptorTbl::create(ObjectPool* pool, const TDescriptorTable& thrift_tb (*tbl)->_tbl_desc_map[tdesc.id] = desc; } - for (size_t i = 0; i < thrift_tbl.tupleDescriptors.size(); ++i) { - const TTupleDescriptor& tdesc = thrift_tbl.tupleDescriptors[i]; + for (const auto& tdesc : thrift_tbl.tupleDescriptors) { TupleDescriptor* desc = pool->add(new TupleDescriptor(tdesc)); // fix up table pointer @@ -652,13 +578,12 @@ Status DescriptorTbl::create(ObjectPool* pool, const TDescriptorTable& thrift_tb (*tbl)->_row_tuples.emplace_back(tdesc.id); } - for (size_t i = 0; i < thrift_tbl.slotDescriptors.size(); ++i) { - const TSlotDescriptor& tdesc = thrift_tbl.slotDescriptors[i]; + for (const auto& tdesc : thrift_tbl.slotDescriptors) { SlotDescriptor* slot_d = pool->add(new SlotDescriptor(tdesc)); (*tbl)->_slot_desc_map[tdesc.id] = slot_d; // link to parent - TupleDescriptorMap::iterator entry = (*tbl)->_tuple_desc_map.find(tdesc.parent); + auto entry = (*tbl)->_tuple_desc_map.find(tdesc.parent); if (entry == (*tbl)->_tuple_desc_map.end()) { return Status::InternalError("unknown tid in slot descriptor msg"); @@ -671,7 +596,7 @@ Status DescriptorTbl::create(ObjectPool* pool, const TDescriptorTable& thrift_tb TableDescriptor* DescriptorTbl::get_table_descriptor(TableId id) const { // TODO: is there some boost function to do exactly this? - TableDescriptorMap::const_iterator i = _tbl_desc_map.find(id); + auto i = _tbl_desc_map.find(id); if (i == _tbl_desc_map.end()) { return nullptr; @@ -682,7 +607,7 @@ TableDescriptor* DescriptorTbl::get_table_descriptor(TableId id) const { TupleDescriptor* DescriptorTbl::get_tuple_descriptor(TupleId id) const { // TODO: is there some boost function to do exactly this? - TupleDescriptorMap::const_iterator i = _tuple_desc_map.find(id); + auto i = _tuple_desc_map.find(id); if (i == _tuple_desc_map.end()) { return nullptr; @@ -693,7 +618,7 @@ TupleDescriptor* DescriptorTbl::get_tuple_descriptor(TupleId id) const { SlotDescriptor* DescriptorTbl::get_slot_descriptor(SlotId id) const { // TODO: is there some boost function to do exactly this? - SlotDescriptorMap::const_iterator i = _slot_desc_map.find(id); + auto i = _slot_desc_map.find(id); if (i == _slot_desc_map.end()) { return nullptr; @@ -706,9 +631,8 @@ std::string DescriptorTbl::debug_string() const { std::stringstream out; out << "tuples:\n"; - for (TupleDescriptorMap::const_iterator i = _tuple_desc_map.begin(); i != _tuple_desc_map.end(); - ++i) { - out << i->second->debug_string() << '\n'; + for (auto i : _tuple_desc_map) { + out << i.second->debug_string() << '\n'; } return out.str(); diff --git a/be/src/runtime/descriptors.h b/be/src/runtime/descriptors.h index 2d43fd03e4f..d3d92cf5cf6 100644 --- a/be/src/runtime/descriptors.h +++ b/be/src/runtime/descriptors.h @@ -39,12 +39,10 @@ #include "runtime/types.h" #include "vec/data_types/data_type.h" -namespace google { -namespace protobuf { +namespace google::protobuf { template <typename Element> class RepeatedField; -} // namespace protobuf -} // namespace google +} // namespace google::protobuf namespace doris { @@ -52,33 +50,6 @@ class ObjectPool; class PTupleDescriptor; class PSlotDescriptor; -// Location information for null indicator bit for particular slot. -// For non-nullable slots, the byte_offset will be 0 and the bit_mask will be 0. -// This allows us to do the NullIndicatorOffset operations (tuple + byte_offset &/| -// bit_mask) regardless of whether the slot is nullable or not. -// This is more efficient than branching to check if the slot is non-nullable. -struct NullIndicatorOffset { - int byte_offset; - uint8_t bit_mask; // to extract null indicator - int8_t bit_offset; // only used to serialize, from 1 to 8, invalid null value - // bit_offset is -1. - - NullIndicatorOffset(int byte_offset, int bit_offset_) - : byte_offset(byte_offset), - bit_mask(bit_offset_ == -1 ? 0 : 1 << (7 - bit_offset_)), - bit_offset(bit_offset_) { - DCHECK_LE(bit_offset_, 8); - } - - bool equals(const NullIndicatorOffset& o) const { - return this->byte_offset == o.byte_offset && this->bit_mask == o.bit_mask; - } - - std::string debug_string() const; -}; - -std::ostream& operator<<(std::ostream& os, const NullIndicatorOffset& null_indicator); - class SlotDescriptor { public: // virtual ~SlotDescriptor() {}; @@ -91,7 +62,7 @@ public: // Returns the field index in the generated llvm struct for this slot's tuple int field_idx() const { return _field_idx; } bool is_materialized() const { return _is_materialized; } - bool is_nullable() const { return _null_indicator_offset.bit_mask != 0; } + bool is_nullable() const { return _is_nullable; } const std::string& col_name() const { return _col_name; } const std::string& col_name_lower_case() const { return _col_name_lower_case; } @@ -129,7 +100,7 @@ private: const TypeDescriptor _type; const TupleId _parent; const int _col_pos; - const NullIndicatorOffset _null_indicator_offset; + bool _is_nullable; const std::string _col_name; const std::string _col_name_lower_case; @@ -236,14 +207,14 @@ public: MaxComputeTableDescriptor(const TTableDescriptor& tdesc); ~MaxComputeTableDescriptor() override; std::string debug_string() const override; - const std::string region() const { return _region; } - const std::string project() const { return _project; } - const std::string table() const { return _table; } - const std::string odps_url() const { return _odps_url; } - const std::string tunnel_url() const { return _tunnel_url; } - const std::string access_key() const { return _access_key; } - const std::string secret_key() const { return _secret_key; } - const std::string public_access() const { return _public_access; } + std::string region() const { return _region; } + std::string project() const { return _project; } + std::string table() const { return _table; } + std::string odps_url() const { return _odps_url; } + std::string tunnel_url() const { return _tunnel_url; } + std::string access_key() const { return _access_key; } + std::string secret_key() const { return _secret_key; } + std::string public_access() const { return _public_access; } private: std::string _region; @@ -278,13 +249,13 @@ class MySQLTableDescriptor : public TableDescriptor { public: MySQLTableDescriptor(const TTableDescriptor& tdesc); std::string debug_string() const override; - const std::string mysql_db() const { return _mysql_db; } - const std::string mysql_table() const { return _mysql_table; } - const std::string host() const { return _host; } - const std::string port() const { return _port; } - const std::string user() const { return _user; } - const std::string passwd() const { return _passwd; } - const std::string charset() const { return _charset; } + std::string mysql_db() const { return _mysql_db; } + std::string mysql_table() const { return _mysql_table; } + std::string host() const { return _host; } + std::string port() const { return _port; } + std::string user() const { return _user; } + std::string passwd() const { return _passwd; } + std::string charset() const { return _charset; } private: std::string _mysql_db; @@ -300,13 +271,13 @@ class ODBCTableDescriptor : public TableDescriptor { public: ODBCTableDescriptor(const TTableDescriptor& tdesc); std::string debug_string() const override; - const std::string db() const { return _db; } - const std::string table() const { return _table; } - const std::string host() const { return _host; } - const std::string port() const { return _port; } - const std::string user() const { return _user; } - const std::string passwd() const { return _passwd; } - const std::string driver() const { return _driver; } + std::string db() const { return _db; } + std::string table() const { return _table; } + std::string host() const { return _host; } + std::string port() const { return _port; } + std::string user() const { return _user; } + std::string passwd() const { return _passwd; } + std::string driver() const { return _driver; } TOdbcTableType::type type() const { return _type; } private: @@ -358,6 +329,9 @@ private: class TupleDescriptor { public: + TupleDescriptor(TupleDescriptor&&) = delete; + void operator=(const TupleDescriptor&) = delete; + ~TupleDescriptor() { if (_own_slots) { for (SlotDescriptor* slot : _slots) { @@ -365,50 +339,12 @@ public: } } } - int64_t byte_size() const { return _byte_size; } int num_materialized_slots() const { return _num_materialized_slots; } - int num_null_slots() const { return _num_null_slots; } - int num_null_bytes() const { return _num_null_bytes; } const std::vector<SlotDescriptor*>& slots() const { return _slots; } - const std::vector<SlotDescriptor*>& string_slots() const { return _string_slots; } - const std::vector<SlotDescriptor*>& no_string_slots() const { return _no_string_slots; } - const std::vector<SlotDescriptor*>& collection_slots() const { return _collection_slots; } - bool has_varlen_slots() const { - { return _has_varlen_slots; } - } + bool has_varlen_slots() const { return _has_varlen_slots; } const TableDescriptor* table_desc() const { return _table_desc; } - static bool is_var_length(const std::vector<TupleDescriptor*>& descs) { - for (auto desc : descs) { - if (desc->string_slots().size() > 0) { - return true; - } - if (desc->collection_slots().size() > 0) { - return true; - } - } - return false; - } - - bool has_hll_slot() const { - for (auto slot : _slots) { - if (slot->type().is_hll_type()) { - return true; - } - } - return false; - } - - bool has_bitmap_slot() const { - for (auto slot : _slots) { - if (slot->type().is_bitmap_type()) { - return true; - } - } - return false; - } - TupleId id() const { return _id; } std::string debug_string() const; @@ -425,16 +361,8 @@ private: const TupleId _id; TableDescriptor* _table_desc = nullptr; - int64_t _byte_size; - int _num_null_slots; - int _num_null_bytes; int _num_materialized_slots; - std::vector<SlotDescriptor*> _slots; // contains all slots - std::vector<SlotDescriptor*> _string_slots; // contains only materialized string slots - // contains only materialized slots except string slots - std::vector<SlotDescriptor*> _no_string_slots; - // _collection_slots - std::vector<SlotDescriptor*> _collection_slots; + std::vector<SlotDescriptor*> _slots; // contains all slots // Provide quick way to check if there are variable length slots. // True if _string_slots or _collection_slots have entries. @@ -443,13 +371,8 @@ private: TupleDescriptor(const TTupleDescriptor& tdesc, bool own_slot = false); TupleDescriptor(const PTupleDescriptor& tdesc, bool own_slot = false); - TupleDescriptor(TupleDescriptor&&) = delete; - void operator=(const TupleDescriptor&) = delete; void add_slot(SlotDescriptor* slot); - - /// Returns slots in their physical order. - std::vector<SlotDescriptor*> slots_ordered_by_idx() const; }; class DescriptorTbl { @@ -515,15 +438,12 @@ public: _tuple_idx_map(desc._tuple_idx_map), _has_varlen_slots(desc._has_varlen_slots) { _num_materialized_slots = 0; - _num_null_slots = 0; _num_slots = 0; - std::vector<TupleDescriptor*>::const_iterator it = desc._tuple_desc_map.begin(); + auto it = desc._tuple_desc_map.begin(); for (; it != desc._tuple_desc_map.end(); ++it) { _num_materialized_slots += (*it)->num_materialized_slots(); - _num_null_slots += (*it)->num_null_slots(); _num_slots += (*it)->slots().size(); } - _num_null_bytes = (_num_null_slots + 7) / 8; } RowDescriptor(TupleDescriptor* tuple_desc, bool is_nullable); @@ -533,17 +453,8 @@ public: // dummy descriptor, needed for the JNI EvalPredicate() function RowDescriptor() = default; - // Returns total size in bytes. - // TODO: also take avg string lengths into account, ie, change this - // to GetAvgRowSize() - int get_row_size() const; - int num_materialized_slots() const { return _num_materialized_slots; } - int num_null_slots() const { return _num_null_slots; } - - int num_null_bytes() const { return _num_null_bytes; } - int num_slots() const { return _num_slots; } static const int INVALID_IDX; @@ -551,12 +462,6 @@ public: // Returns INVALID_IDX if id not part of this row. int get_tuple_idx(TupleId id) const; - // Return true if the Tuple of the given Tuple index is nullable. - bool tuple_is_nullable(int tuple_idx) const; - - // Return true if any Tuple of the row is nullable. - bool is_any_tuple_nullable() const; - // Return true if any Tuple has variable length slots. bool has_varlen_slots() const { return _has_varlen_slots; } @@ -598,8 +503,6 @@ private: bool _has_varlen_slots; int _num_materialized_slots; - int _num_null_slots; - int _num_null_bytes; int _num_slots; }; diff --git a/be/src/vec/exec/scan/vscan_node.cpp b/be/src/vec/exec/scan/vscan_node.cpp index 744b68c0966..b3aeebb4e5b 100644 --- a/be/src/vec/exec/scan/vscan_node.cpp +++ b/be/src/vec/exec/scan/vscan_node.cpp @@ -380,18 +380,18 @@ Status VScanNode::_normalize_conjuncts() { } }; - for (int slot_idx = 0; slot_idx < slots.size(); ++slot_idx) { - _colname_to_slot_id[slots[slot_idx]->col_name()] = slots[slot_idx]->id(); - _slot_id_to_slot_desc[slots[slot_idx]->id()] = slots[slot_idx]; + for (auto& slot : slots) { + _colname_to_slot_id[slot->col_name()] = slot->id(); + _slot_id_to_slot_desc[slot->id()] = slot; - auto type = slots[slot_idx]->type().type; - if (slots[slot_idx]->type().type == TYPE_ARRAY) { - type = slots[slot_idx]->type().children[0].type; + auto type = slot->type().type; + if (slot->type().type == TYPE_ARRAY) { + type = slot->type().children[0].type; if (type == TYPE_ARRAY) { continue; } } - init_value_range(slots[slot_idx], slots[slot_idx]->type().type); + init_value_range(slot, slot->type().type); } get_cast_types_for_variants(); @@ -471,7 +471,7 @@ Status VScanNode::_normalize_predicate(const VExprSPtr& conjunct_expr_root, VExp if (is_leaf(conjunct_expr_root)) { auto impl = conjunct_expr_root->get_impl(); // If impl is not null, which means this a conjuncts from runtime filter. - auto cur_expr = impl ? impl.get() : conjunct_expr_root.get(); + auto* cur_expr = impl ? impl.get() : conjunct_expr_root.get(); bool _is_runtime_filter_predicate = _rf_vexpr_set.contains(conjunct_expr_root); SlotDescriptor* slot = nullptr; ColumnValueRangeType* range = nullptr; @@ -642,8 +642,8 @@ Status VScanNode::_normalize_function_filters(VExpr* expr, VExprContext* expr_ct doris::FunctionContext* fn_ctx = nullptr; StringRef val; PushDownType temp_pdt; - RETURN_IF_ERROR(_should_push_down_function_filter( - reinterpret_cast<VectorizedFnCall*>(fn_expr), expr_ctx, &val, &fn_ctx, temp_pdt)); + RETURN_IF_ERROR(_should_push_down_function_filter(assert_cast<VectorizedFnCall*>(fn_expr), + expr_ctx, &val, &fn_ctx, temp_pdt)); if (temp_pdt != PushDownType::UNACCEPTABLE) { std::string col = slot->col_name(); _push_down_functions.emplace_back(opposite, col, fn_ctx, val); @@ -699,16 +699,15 @@ Status VScanNode::_eval_const_conjuncts(VExpr* vexpr, VExprContext* expr_ctx, Pu if (vexpr->is_constant()) { std::shared_ptr<ColumnPtrWrapper> const_col_wrapper; RETURN_IF_ERROR(vexpr->get_const_col(expr_ctx, &const_col_wrapper)); - if (const ColumnConst* const_column = + if (const auto* const_column = check_and_get_column<ColumnConst>(const_col_wrapper->column_ptr)) { constant_val = const_cast<char*>(const_column->get_data_at(0).data); if (constant_val == nullptr || !*reinterpret_cast<bool*>(constant_val)) { *pdt = PushDownType::ACCEPTABLE; _eos = true; } - } else if (const ColumnVector<UInt8>* bool_column = - check_and_get_column<ColumnVector<UInt8>>( - const_col_wrapper->column_ptr)) { + } else if (const auto* bool_column = check_and_get_column<ColumnVector<UInt8>>( + const_col_wrapper->column_ptr)) { // TODO: If `vexpr->is_constant()` is true, a const column is expected here. // But now we still don't cover all predicates for const expression. // For example, for query `SELECT col FROM tbl WHERE 'PROMOTION' LIKE 'AAA%'`, @@ -759,14 +758,14 @@ Status VScanNode::_normalize_in_and_eq_predicate(VExpr* expr, VExprContext* expr } } else { // normal in predicate - VInPredicate* pred = static_cast<VInPredicate*>(expr); + auto* pred = static_cast<VInPredicate*>(expr); PushDownType temp_pdt = _should_push_down_in_predicate(pred, expr_ctx, false); if (temp_pdt == PushDownType::UNACCEPTABLE) { return Status::OK(); } // begin to push InPredicate value into ColumnValueRange - InState* state = reinterpret_cast<InState*>( + auto* state = reinterpret_cast<InState*>( expr_ctx->fn_context(pred->fn_context_index()) ->get_function_state(FunctionContext::FRAGMENT_LOCAL)); @@ -785,7 +784,7 @@ Status VScanNode::_normalize_in_and_eq_predicate(VExpr* expr, VExprContext* expr iter->next(); continue; } - auto value = const_cast<void*>(iter->get_value()); + auto* value = const_cast<void*>(iter->get_value()); RETURN_IF_ERROR(_change_value_range<true>( temp_range, value, ColumnValueRange<T>::add_fixed_value_range, "")); iter->next(); @@ -846,14 +845,14 @@ Status VScanNode::_normalize_not_in_and_not_eq_predicate(VExpr* expr, VExprConte PushDownType temp_pdt = PushDownType::UNACCEPTABLE; // 1. Normalize in conjuncts like 'where col in (v1, v2, v3)' if (TExprNodeType::IN_PRED == expr->node_type()) { - VInPredicate* pred = static_cast<VInPredicate*>(expr); + auto* pred = static_cast<VInPredicate*>(expr); if ((temp_pdt = _should_push_down_in_predicate(pred, expr_ctx, true)) == PushDownType::UNACCEPTABLE) { return Status::OK(); } // begin to push InPredicate value into ColumnValueRange - InState* state = reinterpret_cast<InState*>( + auto* state = reinterpret_cast<InState*>( expr_ctx->fn_context(pred->fn_context_index()) ->get_function_state(FunctionContext::FRAGMENT_LOCAL)); @@ -872,7 +871,7 @@ Status VScanNode::_normalize_not_in_and_not_eq_predicate(VExpr* expr, VExprConte if (nullptr == iter->get_value()) { continue; } - auto value = const_cast<void*>(iter->get_value()); + auto* value = const_cast<void*>(iter->get_value()); if (is_fixed_range) { RETURN_IF_ERROR(_change_value_range<true>( range, value, ColumnValueRange<T>::remove_fixed_value_range, fn_name)); @@ -1017,7 +1016,7 @@ Status VScanNode::_normalize_compound_predicate( auto compound_fn_name = expr->fn().name.function_name; auto children_num = expr->children().size(); for (auto i = 0; i < children_num; ++i) { - auto child_expr = expr->children()[i].get(); + auto* child_expr = expr->children()[i].get(); if (TExprNodeType::BINARY_PRED == child_expr->node_type()) { SlotDescriptor* slot = nullptr; ColumnValueRangeType* range_on_slot = nullptr; @@ -1276,7 +1275,7 @@ Status VScanNode::_should_push_down_binary_predicate( } else { std::shared_ptr<ColumnPtrWrapper> const_col_wrapper; RETURN_IF_ERROR(children[1 - i]->get_const_col(expr_ctx, &const_col_wrapper)); - if (const ColumnConst* const_column = + if (const auto* const_column = check_and_get_column<ColumnConst>(const_col_wrapper->column_ptr)) { *slot_ref_child = i; *constant_val = const_column->get_data_at(0); diff --git a/be/test/testutil/desc_tbl_builder.cpp b/be/test/testutil/desc_tbl_builder.cpp index cee9f562262..4cba9a44a4b 100644 --- a/be/test/testutil/desc_tbl_builder.cpp +++ b/be/test/testutil/desc_tbl_builder.cpp @@ -64,11 +64,11 @@ static TSlotDescriptor make_slot_descriptor(int id, int parent_id, const TypeDes return slot_desc; } -static TTupleDescriptor make_tuple_descriptor(int id, int num_null_bytes) { +static TTupleDescriptor make_tuple_descriptor(int id) { TTupleDescriptor tuple_desc; tuple_desc.__set_id(id); tuple_desc.__set_byteSize(0); - tuple_desc.__set_numNullBytes(num_null_bytes); + tuple_desc.__set_numNullBytes(0); return tuple_desc; } @@ -98,7 +98,6 @@ TTupleDescriptor DescriptorTblBuilder::build_tuple(const vector<TypeDescriptor>& return build_tuple(slot_types[0].children, thrift_desc_tbl, next_tuple_id, slot_id); } - int num_null_bytes = BitUtil::ceil(slot_types.size(), 8); int tuple_id = *next_tuple_id; ++(*next_tuple_id); @@ -117,7 +116,7 @@ TTupleDescriptor DescriptorTblBuilder::build_tuple(const vector<TypeDescriptor>& ++(*slot_id); } - TTupleDescriptor result = make_tuple_descriptor(tuple_id, num_null_bytes); + TTupleDescriptor result = make_tuple_descriptor(tuple_id); thrift_desc_tbl->tupleDescriptors.push_back(result); return result; } diff --git a/be/test/vec/exec/parquet/parquet_thrift_test.cpp b/be/test/vec/exec/parquet/parquet_thrift_test.cpp index 61cb740a1a2..75898f6acd0 100644 --- a/be/test/vec/exec/parquet/parquet_thrift_test.cpp +++ b/be/test/vec/exec/parquet/parquet_thrift_test.cpp @@ -332,7 +332,7 @@ static doris::TupleDescriptor* create_tuple_desc( TTupleDescriptor t_tuple_desc; t_tuple_desc.__set_byteSize(offset); - t_tuple_desc.__set_numNullBytes((null_byte * 8 + null_bit + 7) / 8); + t_tuple_desc.__set_numNullBytes(0); doris::TupleDescriptor* tuple_desc = pool->add(new (std::nothrow) doris::TupleDescriptor(t_tuple_desc)); diff --git a/be/test/vec/exprs/vexpr_test.cpp b/be/test/vec/exprs/vexpr_test.cpp index 079fbe5f377..efe737262f0 100644 --- a/be/test/vec/exprs/vexpr_test.cpp +++ b/be/test/vec/exprs/vexpr_test.cpp @@ -128,7 +128,7 @@ static doris::TupleDescriptor* create_tuple_desc( TTupleDescriptor t_tuple_desc; t_tuple_desc.__set_byteSize(offset); - t_tuple_desc.__set_numNullBytes((null_byte * 8 + null_bit + 7) / 8); + t_tuple_desc.__set_numNullBytes(0); doris::TupleDescriptor* tuple_desc = pool->add(new (std::nothrow) doris::TupleDescriptor(t_tuple_desc)); diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotDescriptor.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotDescriptor.java index 4615fcbd82a..80076670746 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotDescriptor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SlotDescriptor.java @@ -64,7 +64,7 @@ public class SlotDescriptor { // physical layout parameters private int byteSize; - private int byteOffset; // within tuple + private int byteOffset = 0; // within tuple private int slotIdx; // index within tuple struct private int slotOffset; // index within slot array list diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/TupleDescriptor.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/TupleDescriptor.java index f6b74abfd72..980cf3c4cfa 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/TupleDescriptor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/TupleDescriptor.java @@ -63,8 +63,6 @@ public class TupleDescriptor { private boolean isMaterialized = true; private int byteSize; // of all slots plus null indicators - private int numNullBytes; - private int numNullableSlots; // This cardinality is only used to mock slot ndv. // Only tuple of olap scan node has this value. @@ -232,8 +230,7 @@ public class TupleDescriptor { } public TTupleDescriptor toThrift() { - TTupleDescriptor ttupleDesc = new TTupleDescriptor(id.asInt(), byteSize, numNullBytes); - ttupleDesc.setNumNullSlots(numNullableSlots); + TTupleDescriptor ttupleDesc = new TTupleDescriptor(id.asInt(), 0, 0); if (table != null && table.getId() >= 0) { ttupleDesc.setTableId((int) table.getId()); } @@ -302,22 +299,14 @@ public class TupleDescriptor { } // populate slotsBySize; also compute avgSerializedSize - numNullableSlots = 0; for (SlotDescriptor d : slots) { if (d.isMaterialized()) { slotsBySize.get(d.getType().getSlotSize()).add(d); - if (d.getIsNullable()) { - ++numNullableSlots; - } } } // we shouldn't have anything of size 0 Preconditions.checkState(slotsBySize.get(0).isEmpty()); - // assign offsets to slots in order of ascending size - numNullBytes = (numNullableSlots + 7) / 8; - int offset = numNullBytes; - // slotIdx is the index into the resulting tuple struct. The first (smallest) field // is 0, next is 1, etc. int slotIdx = 0; @@ -325,21 +314,13 @@ public class TupleDescriptor { if (slotsBySize.get(slotSize).isEmpty()) { continue; } - if (slotSize > 1) { - // insert padding - int alignTo = slotSize; - offset = (offset + alignTo - 1) / alignTo * alignTo; - } for (SlotDescriptor d : slotsBySize.get(slotSize)) { d.setByteSize(slotSize); - d.setByteOffset(offset); d.setSlotIdx(slotIdx++); - offset += slotSize; + byteSize += slotSize; } } - - this.byteSize = offset; } /** @@ -409,9 +390,9 @@ public class TupleDescriptor { for (SlotDescriptor slot : slots) { slotStrings.add(slot.debugString()); } - return MoreObjects.toStringHelper(this).add("id", id.asInt()).add("tbl", tblStr).add("byte_size", byteSize) - .add("is_materialized", isMaterialized).add("slots", "[" + Joiner.on(", ").join(slotStrings) + "]") - .toString(); + return MoreObjects.toStringHelper(this).add("id", id.asInt()).add("tbl", tblStr) + .add("is_materialized", isMaterialized).add("slots", "[" + Joiner.on(", ").join(slotStrings) + "]") + .toString(); } public String debugString() { @@ -426,7 +407,6 @@ public class TupleDescriptor { .add("id", id.asInt()) .add("name", debugName) .add("tbl", tblStr) - .add("byte_size", byteSize) .add("is_materialized", isMaterialized) .add("slots", "[" + Joiner.on(", ").join(slotStrings) + "]") .toString(); @@ -439,8 +419,7 @@ public class TupleDescriptor { builder.append(MoreObjects.toStringHelper(this) .add("id", id.asInt()) - .add("tbl", tblStr) - .add("byteSize", byteSize)); + .add("tbl", tblStr)); builder.append("\n"); for (SlotDescriptor slot : slots) { if (slot.isMaterialized()) { diff --git a/fe/fe-core/src/test/java/org/apache/doris/planner/TableFunctionPlanTest.java b/fe/fe-core/src/test/java/org/apache/doris/planner/TableFunctionPlanTest.java index c22744cfe5d..df6d4032055 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/planner/TableFunctionPlanTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/planner/TableFunctionPlanTest.java @@ -78,7 +78,7 @@ public class TableFunctionPlanTest { Assert.assertTrue( explainString.contains("table function: explode_split(`db1`.`tbl1`.`k2`, ',')")); Assert.assertTrue(explainString.contains("tuple ids: 0 1")); - Assert.assertTrue(explainString.contains("TupleDescriptor{id=1, tbl=tmp, byteSize=32}")); + Assert.assertTrue(explainString.contains("TupleDescriptor{id=1, tbl=tmp")); Assert.assertTrue(explainString.contains("SlotDescriptor{id=1, col=e1, colUniqueId=-1, type=VARCHAR")); } @@ -94,7 +94,7 @@ public class TableFunctionPlanTest { Assert.assertTrue( explainString.contains("table function: explode_split(`db1`.`tbl1`.`k2`, ',')")); Assert.assertTrue(explainString.contains("tuple ids: 0 1")); - Assert.assertTrue(explainString.contains("TupleDescriptor{id=1, tbl=tmp, byteSize=32}")); + Assert.assertTrue(explainString.contains("TupleDescriptor{id=1, tbl=tmp")); Assert.assertTrue(explainString.contains("SlotDescriptor{id=1, col=e1, colUniqueId=-1, type=VARCHAR")); } @@ -115,10 +115,10 @@ public class TableFunctionPlanTest { Assert.assertTrue( explainString.contains("table function: explode_split(`db1`.`tbl1`.`k2`, ',')")); Assert.assertTrue(explainString.contains("tuple ids: 0 1")); - Assert.assertTrue(explainString.contains("TupleDescriptor{id=1, tbl=tmp, byteSize=32}")); + Assert.assertTrue(explainString.contains("TupleDescriptor{id=1, tbl=tmp")); Assert.assertTrue(explainString.contains("SlotDescriptor{id=1, col=e1, colUniqueId=-1, type=VARCHAR")); // group by tuple - Assert.assertTrue(explainString.contains("TupleDescriptor{id=2, tbl=null, byteSize=32}")); + Assert.assertTrue(explainString.contains("TupleDescriptor{id=2, tbl=null")); } /* Case4 where explode column @@ -134,7 +134,7 @@ public class TableFunctionPlanTest { explainString.contains("table function: explode_split(`db1`.`tbl1`.`k2`, ',')")); Assert.assertTrue(explainString.contains("`e1` = '1'")); Assert.assertTrue(explainString.contains("tuple ids: 0 1")); - Assert.assertTrue(explainString.contains("TupleDescriptor{id=1, tbl=tmp, byteSize=32}")); + Assert.assertTrue(explainString.contains("TupleDescriptor{id=1, tbl=tmp")); Assert.assertTrue(explainString.contains("SlotDescriptor{id=1, col=e1, colUniqueId=-1, type=VARCHAR")); } @@ -150,7 +150,7 @@ public class TableFunctionPlanTest { Assert.assertTrue( explainString.contains("table function: explode_split(`db1`.`tbl1`.`k2`, ',')")); Assert.assertTrue(explainString.contains("tuple ids: 0 1")); - Assert.assertTrue(explainString.contains("TupleDescriptor{id=1, tbl=tmp, byteSize=32}")); + Assert.assertTrue(explainString.contains("TupleDescriptor{id=1, tbl=tmp")); Assert.assertTrue(explainString.contains("SlotDescriptor{id=1, col=e1, colUniqueId=-1, type=VARCHAR")); Assert.assertTrue(UtFrameUtils.checkPlanResultContainsNode(explainString, 0, "OlapScanNode")); Assert.assertTrue(explainString.contains("`k1` = 1")); @@ -170,10 +170,10 @@ public class TableFunctionPlanTest { "table function: explode_split(`db1`.`tbl1`.`k2`, ',') explode_split(`db1`.`tbl1`.`k2`, ',')")); Assert.assertTrue(explainString.contains("lateral view tuple id: 1 2")); // lateral view 2 tuple - Assert.assertTrue(explainString.contains("TupleDescriptor{id=1, tbl=tmp2, byteSize=32}")); + Assert.assertTrue(explainString.contains("TupleDescriptor{id=1, tbl=tmp2")); Assert.assertTrue(explainString.contains("SlotDescriptor{id=1, col=e2, colUniqueId=-1, type=VARCHAR")); // lateral view 1 tuple - Assert.assertTrue(explainString.contains("TupleDescriptor{id=2, tbl=tmp1, byteSize=32}")); + Assert.assertTrue(explainString.contains("TupleDescriptor{id=2, tbl=tmp1")); Assert.assertTrue(explainString.contains("SlotDescriptor{id=2, col=e1, colUniqueId=-1, type=VARCHAR")); } diff --git a/gensrc/proto/descriptors.proto b/gensrc/proto/descriptors.proto index e7acedbcbb6..9d6945becc0 100644 --- a/gensrc/proto/descriptors.proto +++ b/gensrc/proto/descriptors.proto @@ -28,7 +28,7 @@ message PSlotDescriptor { required int32 parent = 2; // tuple id which this slot is belong to required PTypeDesc slot_type = 3; required int32 column_pos = 4; // in originating table - required int32 byte_offset = 5; // into tuple, not used any more + required int32 byte_offset = 5; // // deprecated required int32 null_indicator_byte = 6; required int32 null_indicator_bit = 7; required string col_name = 8; @@ -43,10 +43,10 @@ message PSlotDescriptor { message PTupleDescriptor { required int32 id = 1; - required int32 byte_size = 2; - required int32 num_null_bytes = 3; + required int32 byte_size = 2; // deprecated + required int32 num_null_bytes = 3; // deprecated optional int64 table_id = 4; - optional int32 num_null_slots = 5; + optional int32 num_null_slots = 5; // deprecated }; message POlapTableIndexSchema { diff --git a/gensrc/thrift/Descriptors.thrift b/gensrc/thrift/Descriptors.thrift index fca91b1c8af..cbb73959a0a 100644 --- a/gensrc/thrift/Descriptors.thrift +++ b/gensrc/thrift/Descriptors.thrift @@ -49,7 +49,7 @@ struct TSlotDescriptor { 2: required Types.TTupleId parent 3: required Types.TTypeDesc slotType 4: required i32 columnPos // in originating table - 5: required i32 byteOffset // into tuple + 5: required i32 byteOffset // deprecated 6: required i32 nullIndicatorByte 7: required i32 nullIndicatorBit 8: required string colName; @@ -69,10 +69,10 @@ struct TSlotDescriptor { struct TTupleDescriptor { 1: required Types.TTupleId id - 2: required i32 byteSize - 3: required i32 numNullBytes + 2: required i32 byteSize // deprecated + 3: required i32 numNullBytes // deprecated 4: optional Types.TTableId tableId - 5: optional i32 numNullSlots + 5: optional i32 numNullSlots // deprecated } enum THdfsFileFormat { --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org