| 242 | } |
| 243 | |
| 244 | Status ExchangeNode::GetNextMerging(RuntimeState* state, RowBatch* output_batch, |
| 245 | bool* eos) { |
| 246 | DCHECK_EQ(output_batch->num_rows(), 0); |
| 247 | RETURN_IF_CANCELLED(state); |
| 248 | RETURN_IF_ERROR(QueryMaintenance(state)); |
| 249 | // Clear any expr result allocations made by the merger. |
| 250 | expr_results_pool_->Clear(); |
| 251 | RETURN_IF_ERROR(stream_recvr_->GetNext(output_batch, eos)); |
| 252 | |
| 253 | while (num_rows_skipped_ < offset_) { |
| 254 | num_rows_skipped_ += output_batch->num_rows(); |
| 255 | // Throw away rows in the output batch until the offset is skipped. |
| 256 | int64_t rows_to_keep = num_rows_skipped_ - offset_; |
| 257 | if (rows_to_keep > 0) { |
| 258 | output_batch->CopyRows(0, output_batch->num_rows() - rows_to_keep, rows_to_keep); |
| 259 | output_batch->set_num_rows(rows_to_keep); |
| 260 | } else { |
| 261 | output_batch->set_num_rows(0); |
| 262 | } |
| 263 | if (rows_to_keep > 0 || *eos || output_batch->AtCapacity()) break; |
| 264 | RETURN_IF_ERROR(stream_recvr_->GetNext(output_batch, eos)); |
| 265 | } |
| 266 | |
| 267 | CheckLimitAndTruncateRowBatchIfNeeded(output_batch, eos); |
| 268 | |
| 269 | // On eos, transfer all remaining resources from the input batches maintained |
| 270 | // by the merger to the output batch. Also cancel the underlying receiver so |
| 271 | // the senders' fragments can exit early. |
| 272 | if (*eos) ReleaseRecvrResources(output_batch); |
| 273 | |
| 274 | COUNTER_SET(rows_returned_counter_, rows_returned()); |
| 275 | return Status::OK(); |
| 276 | } |
| 277 | |
| 278 | void ExchangeNode::DebugString(int indentation_level, stringstream* out) const { |
| 279 | *out << string(indentation_level * 2, ' '); |
nothing calls this directly
no test coverage detected