| 782 | } |
| 783 | |
| 784 | Status AnalyticEvalNode::GetNext(RuntimeState* state, RowBatch* row_batch, bool* eos) { |
| 785 | SCOPED_TIMER(runtime_profile_->total_time_counter()); |
| 786 | ScopedGetNextEventAdder ea(this, eos); |
| 787 | RETURN_IF_ERROR(ExecDebugAction(TExecNodePhase::GETNEXT, state)); |
| 788 | RETURN_IF_CANCELLED(state); |
| 789 | RETURN_IF_ERROR(QueryMaintenance(state)); |
| 790 | VLOG_FILE << id() << " GetNext: " << DebugStateString(); |
| 791 | DCHECK(!input_stream_->is_closed()); // input_stream_ is closed if we already hit eos. |
| 792 | |
| 793 | if (ReachedLimit()) { |
| 794 | // TODO: This transfer is simple and correct, but not necessarily efficient. We |
| 795 | // should optimize the use/transfer of memory to better amortize allocations |
| 796 | // over multiple Reset()/Open()/GetNext()* cycles. |
| 797 | row_batch->tuple_data_pool()->AcquireData(prev_tuple_pool_.get(), false); |
| 798 | row_batch->tuple_data_pool()->AcquireData(curr_tuple_pool_.get(), false); |
| 799 | DCHECK(!input_stream_->is_closed()); |
| 800 | // Flush resources in case we are in a subplan and need to allocate more blocks |
| 801 | // when the node is reopened. |
| 802 | input_stream_->Close(row_batch, RowBatch::FlushMode::FLUSH_RESOURCES); |
| 803 | *eos = true; |
| 804 | return Status::OK(); |
| 805 | } else { |
| 806 | *eos = false; |
| 807 | } |
| 808 | |
| 809 | RETURN_IF_ERROR(ProcessChildBatches(state)); |
| 810 | |
| 811 | bool output_eos = false; |
| 812 | RETURN_IF_ERROR(GetNextOutputBatch(state, row_batch, &output_eos)); |
| 813 | if (input_eos_ && output_eos) { |
| 814 | // Transfer the ownership of all row-backing resources on eos for simplicity. |
| 815 | // TODO: This transfer is simple and correct, but not necessarily efficient. We |
| 816 | // should optimize the use/transfer of memory to better amortize allocations |
| 817 | // over multiple Reset()/Open()/GetNext()* cycles. |
| 818 | row_batch->tuple_data_pool()->AcquireData(prev_tuple_pool_.get(), false); |
| 819 | row_batch->tuple_data_pool()->AcquireData(curr_tuple_pool_.get(), false); |
| 820 | // Flush resources in case we are in a subplan and need to allocate more blocks |
| 821 | // when the node is reopened. |
| 822 | input_stream_->Close(row_batch, RowBatch::FlushMode::FLUSH_RESOURCES); |
| 823 | *eos = true; |
| 824 | } else if (prev_pool_last_result_idx_ != -1 && |
| 825 | prev_pool_last_result_idx_ < input_stream_->rows_returned() && |
| 826 | prev_pool_last_window_idx_ < window_tuples_.front().first) { |
| 827 | // Transfer resources to the output row batch if enough have accumulated and they're |
| 828 | // no longer needed by output rows to be returned later. |
| 829 | VLOG_FILE << id() << " Transfer prev pool to output batch, " |
| 830 | << " pool size: " << prev_tuple_pool_->total_allocated_bytes() |
| 831 | << " last result idx: " << prev_pool_last_result_idx_ |
| 832 | << " last window idx: " << prev_pool_last_window_idx_; |
| 833 | row_batch->tuple_data_pool()->AcquireData(prev_tuple_pool_.get(), !*eos); |
| 834 | prev_pool_last_result_idx_ = -1; |
| 835 | prev_pool_last_window_idx_ = -1; |
| 836 | } |
| 837 | |
| 838 | COUNTER_SET(rows_returned_counter_, rows_returned()); |
| 839 | return Status::OK(); |
| 840 | } |
| 841 |
no test coverage detected