MCPcopy Create free account
hub / github.com/apache/cloudberry / eval_windowaggregates

Function eval_windowaggregates

src/backend/executor/nodeWindowAgg.c:856–1276  ·  view source on GitHub ↗

* eval_windowaggregates * evaluate plain aggregates being used as window functions * * This differs from nodeAgg.c in two ways. First, if the window's frame * start position moves, we use the inverse transition function (if it exists) * to remove rows from the transition value. And second, we expect to be * able to call aggregate final functions repeatedly after aggregating more * data on

Source from the content-addressed store, hash-verified

854 * nodeAgg.c.
855 */
856static void
857eval_windowaggregates(WindowAggState *winstate)
858{
859 WindowStatePerAgg peraggstate;
860 int wfuncno,
861 numaggs,
862 numaggs_restart,
863 i;
864 int64 aggregatedupto_nonrestarted;
865 MemoryContext oldContext;
866 ExprContext *econtext;
867 WindowObject agg_winobj;
868 TupleTableSlot *agg_row_slot;
869 TupleTableSlot *temp_slot;
870 bool frame_head_moved_backwards;
871 bool frame_tail_moved_backwards;
872
873 numaggs = winstate->numaggs;
874 if (numaggs == 0)
875 return; /* nothing to do */
876
877 /* final output execution is in ps_ExprContext */
878 econtext = winstate->ss.ps.ps_ExprContext;
879 agg_winobj = winstate->agg_winobj;
880 agg_row_slot = winstate->agg_row_slot;
881 temp_slot = winstate->temp_slot_1;
882
883 /*
884 * If the window's frame start clause is UNBOUNDED_PRECEDING and no
885 * exclusion clause is specified, then the window frame consists of a
886 * contiguous group of rows extending forward from the start of the
887 * partition, and rows only enter the frame, never exit it, as the current
888 * row advances forward. This makes it possible to use an incremental
889 * strategy for evaluating aggregates: we run the transition function for
890 * each row added to the frame, and run the final function whenever we
891 * need the current aggregate value. This is considerably more efficient
892 * than the naive approach of re-running the entire aggregate calculation
893 * for each current row. It does assume that the final function doesn't
894 * damage the running transition value, but we have the same assumption in
895 * nodeAgg.c too (when it rescans an existing hash table).
896 *
897 * If the frame start does sometimes move, we can still optimize as above
898 * whenever successive rows share the same frame head, but if the frame
899 * head moves beyond the previous head we try to remove those rows using
900 * the aggregate's inverse transition function. This function restores
901 * the aggregate's current state to what it would be if the removed row
902 * had never been aggregated in the first place. Inverse transition
903 * functions may optionally return NULL, indicating that the function was
904 * unable to remove the tuple from aggregation. If this happens, or if
905 * the aggregate doesn't have an inverse transition function at all, we
906 * must perform the aggregation all over again for all tuples within the
907 * new frame boundaries.
908 *
909 * If there's any exclusion clause, then we may have to aggregate over a
910 * non-contiguous set of rows, so we punt and recalculate for every row.
911 * (For some frame end choices, it might be that the frame is always
912 * contiguous anyway, but that's an optimization to investigate later.)
913 *

Callers 1

ExecWindowAggFunction · 0.85

Calls 12

update_frameheadposFunction · 0.85
ExecClearTupleFunction · 0.85
window_gettupleslotFunction · 0.85
row_is_in_frameFunction · 0.85
WinSetMarkPositionFunction · 0.85
advance_windowaggregateFunction · 0.85
finalize_windowaggregateFunction · 0.85
MemoryContextSwitchToFunction · 0.85
datumCopyFunction · 0.85
pfreeFunction · 0.50

Tested by

no test coverage detected