| 709 | } |
| 710 | |
| 711 | Status HdfsOrcScanner::SelectColumns(const TupleDescriptor& tuple_desc) { |
| 712 | list<const orc::Type*> selected_nodes; |
| 713 | stack<const SlotDescriptor*> pos_slots; |
| 714 | // Select columns for all non-position slots. |
| 715 | RETURN_IF_ERROR(ResolveColumns(tuple_desc, &selected_nodes, &pos_slots)); |
| 716 | |
| 717 | for (auto t : selected_nodes) selected_type_ids_.push_back(t->getColumnId()); |
| 718 | |
| 719 | // Select columns for array positions. Due to ORC-450 we can't materialize array |
| 720 | // offsets without materializing its items, so we should still select the item or any |
| 721 | // sub column of the item. To be simple, we choose the max column id in the subtree |
| 722 | // of the ARRAY node. |
| 723 | // We process the deeper position slots first since it may introduce an item column |
| 724 | // that can also serve the position slot of upper arrays. E.g. for 'array_col' as |
| 725 | // array<struct<c1:int,c2:int,c3:array<int>>>, if both 'array_col.pos' and |
| 726 | // 'array_col.item.c3.pos' are needed, we just need to select 'array_col.item.c3.item' |
| 727 | // in the ORC lib, then we get offsets(indices) of both the inner and outer arrays. |
| 728 | while (!pos_slots.empty()) { |
| 729 | const SlotDescriptor* pos_slot_desc = pos_slots.top(); |
| 730 | pos_slots.pop(); |
| 731 | const orc::Type* array_node = nullptr; |
| 732 | bool pos_field = false; |
| 733 | bool missing_field = false; |
| 734 | RETURN_IF_ERROR(schema_resolver_->ResolveColumn(pos_slot_desc->col_path(), |
| 735 | &array_node, &pos_field, &missing_field)); |
| 736 | if (HasChildrenSelected(*array_node, selected_type_ids_)) continue; |
| 737 | selected_type_ids_.push_back(array_node->getMaximumColumnId()); |
| 738 | VLOG(3) << "Add ORC column " << array_node->getMaximumColumnId() << " for " |
| 739 | << PrintColPath(*scan_node_->hdfs_table(), pos_slot_desc->col_path(), |
| 740 | schema_resolver_); |
| 741 | selected_nodes.push_back(array_node); |
| 742 | } |
| 743 | |
| 744 | // Select "CurrentTransaction" when we need to validate rows. |
| 745 | if (row_batches_need_validation_) { |
| 746 | // In case of zero-slot scans (e.g. count(*) over the table) we only select the |
| 747 | // 'currentTransaction' column. |
| 748 | if (scan_node_->IsZeroSlotTableScan()) selected_type_ids_.clear(); |
| 749 | if (std::find(selected_type_ids_.begin(), selected_type_ids_.end(), |
| 750 | CURRENT_TRANSCACTION_TYPE_ID) == selected_type_ids_.end()) { |
| 751 | selected_type_ids_.push_back(CURRENT_TRANSCACTION_TYPE_ID); |
| 752 | } |
| 753 | } |
| 754 | |
| 755 | COUNTER_SET(num_cols_counter_, static_cast<int64_t>(selected_type_ids_.size())); |
| 756 | row_reader_options_.includeTypes(selected_type_ids_); |
| 757 | return Status::OK(); |
| 758 | } |
| 759 | |
| 760 | Status HdfsOrcScanner::ProcessSplit() { |
| 761 | DCHECK(scan_node_->HasRowBatchQueue()); |
nothing calls this directly
no test coverage detected