| 172 | } |
| 173 | |
| 174 | Status UnnestNode::GetNext(RuntimeState* state, RowBatch* row_batch, bool* eos) { |
| 175 | SCOPED_TIMER(runtime_profile_->total_time_counter()); |
| 176 | // Avoid expensive query maintenance overhead for small collections. |
| 177 | if (item_idx_ > 0) { |
| 178 | RETURN_IF_CANCELLED(state); |
| 179 | RETURN_IF_ERROR(QueryMaintenance(state)); |
| 180 | } |
| 181 | *eos = false; |
| 182 | |
| 183 | // Populate the output row_batch with tuples from the collections. |
| 184 | while (item_idx_ < longest_collection_size_) { |
| 185 | int row_idx = row_batch->AddRow(); |
| 186 | TupleRow* row = row_batch->GetRow(row_idx); |
| 187 | for (int i = 0; i < coll_values_.size(); ++i) { |
| 188 | const CollectionValue* coll_value = coll_values_[i]; |
| 189 | DCHECK(coll_value != nullptr); |
| 190 | DCHECK_GE(coll_value->num_tuples, 0); |
| 191 | Tuple* input_tuple; |
| 192 | if (coll_value->num_tuples <= item_idx_) { |
| 193 | input_tuple = CreateNullTuple(i, row_batch); |
| 194 | } else { |
| 195 | input_tuple = |
| 196 | reinterpret_cast<Tuple*>(coll_value->ptr + item_idx_ * item_byte_sizes_[i]); |
| 197 | } |
| 198 | row->SetTuple(output_coll_tuple_idxs_[i], input_tuple); |
| 199 | } |
| 200 | ++item_idx_; |
| 201 | DCHECK_EQ(conjuncts_.size(), conjunct_evals_.size()); |
| 202 | if (EvalConjuncts(conjunct_evals_.data(), conjuncts_.size(), row)) { |
| 203 | row_batch->CommitLastRow(); |
| 204 | // The limit is handled outside of this loop. |
| 205 | if (row_batch->AtCapacity()) break; |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | // Checking the limit here is simpler/cheaper than doing it in the loop above. |
| 210 | const bool reached_limit = CheckLimitAndTruncateRowBatchIfNeeded(row_batch, eos); |
| 211 | if (!reached_limit && item_idx_ == longest_collection_size_) *eos = true; |
| 212 | COUNTER_SET(rows_returned_counter_, rows_returned()); |
| 213 | return Status::OK(); |
| 214 | } |
| 215 | |
| 216 | int UnnestNode::GetCollTupleIdx(const SlotDescriptor* slot_desc) const { |
| 217 | DCHECK(slot_desc != nullptr); |
nothing calls this directly
no test coverage detected