| 144 | } |
| 145 | |
| 146 | Status SortNode::GetNext(RuntimeState* state, RowBatch* row_batch, bool* eos) { |
| 147 | SCOPED_TIMER(runtime_profile_->total_time_counter()); |
| 148 | ScopedGetNextEventAdder ea(this, eos); |
| 149 | RETURN_IF_ERROR(ExecDebugAction(TExecNodePhase::GETNEXT, state)); |
| 150 | RETURN_IF_CANCELLED(state); |
| 151 | RETURN_IF_ERROR(QueryMaintenance(state)); |
| 152 | |
| 153 | if (ReachedLimit()) { |
| 154 | *eos = true; |
| 155 | return Status::OK(); |
| 156 | } else { |
| 157 | *eos = false; |
| 158 | } |
| 159 | |
| 160 | if (returned_buffer_) { |
| 161 | // If the Sorter returned a buffer on the last call to GetNext(), we might have an |
| 162 | // opportunity to release memory. Release reservation, unless it might be needed |
| 163 | // for the next subplan iteration or merging spilled runs. |
| 164 | returned_buffer_ = false; |
| 165 | if (!IsInSubplan() && !sorter_->HasSpilledRuns()) { |
| 166 | DCHECK(!buffer_pool_client()->has_unpinned_pages()); |
| 167 | Status status = ReleaseUnusedReservation(); |
| 168 | DCHECK(status.ok()) << "Should not fail - no runs were spilled so no pages are " |
| 169 | << "unpinned. " << status.GetDetail(); |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | DCHECK_EQ(row_batch->num_rows(), 0); |
| 174 | RETURN_IF_ERROR(sorter_->GetNext(row_batch, eos)); |
| 175 | while ((num_rows_skipped_ < offset_)) { |
| 176 | num_rows_skipped_ += row_batch->num_rows(); |
| 177 | // Throw away rows in the output batch until the offset is skipped. |
| 178 | int rows_to_keep = num_rows_skipped_ - offset_; |
| 179 | if (rows_to_keep > 0) { |
| 180 | row_batch->CopyRows(0, row_batch->num_rows() - rows_to_keep, rows_to_keep); |
| 181 | row_batch->set_num_rows(rows_to_keep); |
| 182 | } else { |
| 183 | row_batch->set_num_rows(0); |
| 184 | } |
| 185 | if (rows_to_keep > 0 || *eos) break; |
| 186 | RETURN_IF_ERROR(sorter_->GetNext(row_batch, eos)); |
| 187 | } |
| 188 | |
| 189 | returned_buffer_ = row_batch->num_buffers() > 0; |
| 190 | CheckLimitAndTruncateRowBatchIfNeeded(row_batch, eos); |
| 191 | |
| 192 | COUNTER_SET(rows_returned_counter_, rows_returned()); |
| 193 | |
| 194 | return Status::OK(); |
| 195 | } |
| 196 | |
| 197 | Status SortNode::Reset(RuntimeState* state, RowBatch* row_batch) { |
| 198 | num_rows_skipped_ = 0; |
no test coverage detected