* Call transition function for a DISTINCT-qualified aggregate. * * All the input values have been loaded into the tuplesort. Perform the sort, * deduplicate, and call the transition function for each unique value. */
| 675 | * deduplicate, and call the transition function for each unique value. |
| 676 | */ |
| 677 | static void |
| 678 | perform_distinct_windowaggregate(WindowAggState *winstate, |
| 679 | WindowStatePerFunc perfuncstate, |
| 680 | WindowStatePerAgg peraggstate) |
| 681 | { |
| 682 | LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS); |
| 683 | Datum prevDatum = (Datum) 0; |
| 684 | bool prevNull = true; |
| 685 | MemoryContext oldcontext; |
| 686 | |
| 687 | oldcontext = MemoryContextSwitchTo(winstate->tmpcontext->ecxt_per_tuple_memory); |
| 688 | |
| 689 | tuplesort_performsort(peraggstate->distinctSortState); |
| 690 | |
| 691 | #ifdef FAULT_INJECTOR |
| 692 | /* |
| 693 | * This routine is used for tracing whether the sort operation of DISTINCT-qualified |
| 694 | * WindowAgg spills to disk. |
| 695 | */ |
| 696 | if (SIMPLE_FAULT_INJECTOR("distinct_winagg_perform_sort") == FaultInjectorTypeSkip) |
| 697 | { |
| 698 | TuplesortInstrumentation sortstats; |
| 699 | tuplesort_get_stats(peraggstate->distinctSortState, &sortstats); |
| 700 | if (sortstats.spaceType == SORT_SPACE_TYPE_MEMORY) |
| 701 | ereport(NOTICE, |
| 702 | (errmsg("distinct winagg sortstats: sort operation fitted in memory"))); |
| 703 | else |
| 704 | ereport(NOTICE, |
| 705 | (errmsg("distinct winagg sortstats: sort operation spilled to disk"))); |
| 706 | } |
| 707 | #endif |
| 708 | |
| 709 | /* load the first tuple from spool */ |
| 710 | if (tuplesort_getdatum(peraggstate->distinctSortState, true, |
| 711 | &fcinfo->args[1].value, &fcinfo->args[1].isnull, NULL)) |
| 712 | { |
| 713 | call_transfunc(winstate, perfuncstate, peraggstate, fcinfo); |
| 714 | prevDatum = fcinfo->args[1].value; |
| 715 | prevNull = fcinfo->args[1].isnull; |
| 716 | |
| 717 | /* continue loading more tuples */ |
| 718 | while (tuplesort_getdatum(peraggstate->distinctSortState, true, |
| 719 | &fcinfo->args[1].value, &fcinfo->args[1].isnull, NULL)) |
| 720 | { |
| 721 | int cmp; |
| 722 | |
| 723 | cmp = ApplySortComparator(prevDatum, prevNull, |
| 724 | fcinfo->args[1].value, fcinfo->args[1].isnull, |
| 725 | &peraggstate->distinctComparator); |
| 726 | if (cmp < 0) |
| 727 | { |
| 728 | call_transfunc(winstate, perfuncstate, peraggstate, fcinfo); |
| 729 | } |
| 730 | else if (cmp == 0) |
| 731 | { |
| 732 | /* Equal, skip it */ |
| 733 | } |
| 734 | else |
no test coverage detected