* If any data was spilled during hash aggregation, reset the hash table and * reprocess one batch of spilled data. After reprocessing a batch, the hash * table will again contain data, ready to be consumed by * agg_retrieve_hash_table_in_memory(). * * Should only be called after all in memory hash table entries have been * finalized and emitted. * * Return false when input is exhausted and
| 2796 | * otherwise return true. |
| 2797 | */ |
| 2798 | static bool |
| 2799 | agg_refill_hash_table(AggState *aggstate) |
| 2800 | { |
| 2801 | HashAggBatch *batch; |
| 2802 | AggStatePerHash perhash; |
| 2803 | HashAggSpill spill; |
| 2804 | HashTapeInfo *tapeinfo = aggstate->hash_tapeinfo; |
| 2805 | bool spill_initialized = false; |
| 2806 | |
| 2807 | if (aggstate->hash_batches == NIL) |
| 2808 | return false; |
| 2809 | |
| 2810 | /* hash_batches is a stack, with the top item at the end of the list */ |
| 2811 | batch = llast(aggstate->hash_batches); |
| 2812 | aggstate->hash_batches = list_delete_last(aggstate->hash_batches); |
| 2813 | |
| 2814 | hash_agg_set_limits(aggstate, aggstate->hashentrysize, batch->input_card, |
| 2815 | batch->used_bits, &aggstate->hash_mem_limit, |
| 2816 | &aggstate->hash_ngroups_limit, NULL); |
| 2817 | |
| 2818 | /* |
| 2819 | * Each batch only processes one grouping set; set the rest to NULL so |
| 2820 | * that advance_aggregates() knows to ignore them. We don't touch |
| 2821 | * pergroups for sorted grouping sets here, because they will be needed if |
| 2822 | * we rescan later. The expressions for sorted grouping sets will not be |
| 2823 | * evaluated after we recompile anyway. |
| 2824 | */ |
| 2825 | MemSet(aggstate->hash_pergroup, 0, |
| 2826 | sizeof(AggStatePerGroup) * aggstate->num_hashes); |
| 2827 | |
| 2828 | /* free memory and reset hash tables */ |
| 2829 | ReScanExprContext(aggstate->hashcontext); |
| 2830 | for (int setno = 0; setno < aggstate->num_hashes; setno++) |
| 2831 | ResetTupleHashTable(aggstate->perhash[setno].hashtable); |
| 2832 | |
| 2833 | aggstate->hash_ngroups_current = 0; |
| 2834 | |
| 2835 | /* |
| 2836 | * In AGG_MIXED mode, hash aggregation happens in phase 1 and the output |
| 2837 | * happens in phase 0. So, we switch to phase 1 when processing a batch, |
| 2838 | * and back to phase 0 after the batch is done. |
| 2839 | */ |
| 2840 | Assert(aggstate->current_phase == 0); |
| 2841 | if (aggstate->phase->aggstrategy == AGG_MIXED) |
| 2842 | { |
| 2843 | aggstate->current_phase = 1; |
| 2844 | aggstate->phase = &aggstate->phases[aggstate->current_phase]; |
| 2845 | } |
| 2846 | |
| 2847 | select_current_set(aggstate, batch->setno, true); |
| 2848 | |
| 2849 | perhash = &aggstate->perhash[aggstate->current_set]; |
| 2850 | |
| 2851 | /* |
| 2852 | * Spilled tuples are always read back as MinimalTuples, which may be |
| 2853 | * different from the outer plan, so recompile the aggregate expressions. |
| 2854 | * |
| 2855 | * We still need the NULL check, because we are only processing one |
no test coverage detected