* finalize_windowaggregate * parallel to finalize_aggregate in nodeAgg.c */
| 754 | * parallel to finalize_aggregate in nodeAgg.c |
| 755 | */ |
| 756 | static void |
| 757 | finalize_windowaggregate(WindowAggState *winstate, |
| 758 | WindowStatePerFunc perfuncstate, |
| 759 | WindowStatePerAgg peraggstate, |
| 760 | Datum *result, bool *isnull) |
| 761 | { |
| 762 | MemoryContext oldContext; |
| 763 | |
| 764 | /* |
| 765 | * If this is a distinct-qualified aggregate, then we have only spooled the |
| 766 | * inputs into the sorter so far. We haven't run the transition function over |
| 767 | * the input yet. Perform the sort now, and call the transition function on the |
| 768 | * unique values. |
| 769 | */ |
| 770 | if (peraggstate->isDistinct) |
| 771 | { |
| 772 | perform_distinct_windowaggregate(winstate, |
| 773 | perfuncstate, |
| 774 | peraggstate); |
| 775 | /* |
| 776 | * Now we have the final transition value in peraggstate->transValue, like |
| 777 | * in the normal, non-DISTINCT, case. |
| 778 | */ |
| 779 | } |
| 780 | |
| 781 | oldContext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_tuple_memory); |
| 782 | |
| 783 | /* |
| 784 | * Apply the agg's finalfn if one is provided, else return transValue. |
| 785 | */ |
| 786 | if (OidIsValid(peraggstate->finalfn_oid)) |
| 787 | { |
| 788 | LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS); |
| 789 | int numFinalArgs = peraggstate->numFinalArgs; |
| 790 | bool anynull; |
| 791 | int i; |
| 792 | |
| 793 | InitFunctionCallInfoData(fcinfodata.fcinfo, &(peraggstate->finalfn), |
| 794 | numFinalArgs, |
| 795 | perfuncstate->winCollation, |
| 796 | (void *) winstate, NULL); |
| 797 | fcinfo->args[0].value = |
| 798 | MakeExpandedObjectReadOnly(peraggstate->transValue, |
| 799 | peraggstate->transValueIsNull, |
| 800 | peraggstate->transtypeLen); |
| 801 | fcinfo->args[0].isnull = peraggstate->transValueIsNull; |
| 802 | anynull = peraggstate->transValueIsNull; |
| 803 | |
| 804 | /* Fill any remaining argument positions with nulls */ |
| 805 | for (i = 1; i < numFinalArgs; i++) |
| 806 | { |
| 807 | fcinfo->args[i].value = (Datum) 0; |
| 808 | fcinfo->args[i].isnull = true; |
| 809 | anynull = true; |
| 810 | } |
| 811 | |
| 812 | if (fcinfo->flinfo->fn_strict && anynull) |
| 813 | { |
no test coverage detected