* advance_windowaggregate * parallel to advance_aggregates in nodeAgg.c */
| 282 | * parallel to advance_aggregates in nodeAgg.c |
| 283 | */ |
| 284 | static void |
| 285 | advance_windowaggregate(WindowAggState *winstate, |
| 286 | WindowStatePerFunc perfuncstate, |
| 287 | WindowStatePerAgg peraggstate) |
| 288 | { |
| 289 | LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS); |
| 290 | WindowFuncExprState *wfuncstate = perfuncstate->wfuncstate; |
| 291 | ListCell *arg; |
| 292 | int i; |
| 293 | MemoryContext oldContext; |
| 294 | ExprContext *econtext = winstate->tmpcontext; |
| 295 | ExprState *filter = wfuncstate->aggfilter; |
| 296 | |
| 297 | oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory); |
| 298 | |
| 299 | /* Skip anything FILTERed out */ |
| 300 | if (filter) |
| 301 | { |
| 302 | bool isnull; |
| 303 | Datum res = ExecEvalExpr(filter, econtext, &isnull); |
| 304 | |
| 305 | if (isnull || !DatumGetBool(res)) |
| 306 | { |
| 307 | MemoryContextSwitchTo(oldContext); |
| 308 | return; |
| 309 | } |
| 310 | } |
| 311 | |
| 312 | /* We start from 1, since the 0th arg will be the transition value */ |
| 313 | i = 1; |
| 314 | foreach(arg, wfuncstate->args) |
| 315 | { |
| 316 | ExprState *argstate = (ExprState *) lfirst(arg); |
| 317 | |
| 318 | fcinfo->args[i].value = ExecEvalExpr(argstate, econtext, |
| 319 | &fcinfo->args[i].isnull); |
| 320 | i++; |
| 321 | } |
| 322 | |
| 323 | /* |
| 324 | * If this is a DISTINCT-qualified aggregate, we cannot call the |
| 325 | * transition function yet. Instead, we spool the input into a tuplesort. |
| 326 | * We will perform the sort, deduplicate, and call the transition |
| 327 | * function later, after we have spooled all the input values in this |
| 328 | * partition. |
| 329 | */ |
| 330 | if (peraggstate->isDistinct) |
| 331 | { |
| 332 | Assert(list_length(wfuncstate->args) == 1); |
| 333 | |
| 334 | /* |
| 335 | * For a strict transfn, nothing happens when there's a NULL input; we |
| 336 | * just keep the prior transValue. |
| 337 | */ |
| 338 | if (peraggstate->transfn.fn_strict && fcinfo->args[1].isnull) |
| 339 | { |
| 340 | /* skip it */ |
| 341 | } |
no test coverage detected