----------------- * ExecWindowAgg * * ExecWindowAgg receives tuples from its outer subplan and * stores them into a tuplestore, then processes window functions. * This node doesn't reduce nor qualify any row so the number of * returned rows is exactly the same as its outer subplan's result. * ----------------- */
| 2392 | * ----------------- |
| 2393 | */ |
| 2394 | static TupleTableSlot * |
| 2395 | ExecWindowAgg(PlanState *pstate) |
| 2396 | { |
| 2397 | WindowAggState *winstate = castNode(WindowAggState, pstate); |
| 2398 | ExprContext *econtext; |
| 2399 | int i; |
| 2400 | int numfuncs; |
| 2401 | |
| 2402 | CHECK_FOR_INTERRUPTS(); |
| 2403 | |
| 2404 | if (winstate->all_done) |
| 2405 | return NULL; |
| 2406 | |
| 2407 | /* |
| 2408 | * Compute frame offset values, if any, during first call (or after a |
| 2409 | * rescan). These are assumed to hold constant throughout the scan; if |
| 2410 | * user gives us a volatile expression, we'll only use its initial value. |
| 2411 | * |
| 2412 | * GPDB: We accept non-constant frame offsets, too. If they're not |
| 2413 | * constants, we'll compute them later. |
| 2414 | */ |
| 2415 | if (winstate->all_first && |
| 2416 | winstate->start_offset_var_free && |
| 2417 | winstate->end_offset_var_free) |
| 2418 | { |
| 2419 | compute_start_end_offsets(winstate); |
| 2420 | |
| 2421 | winstate->all_first = false; |
| 2422 | } |
| 2423 | |
| 2424 | if (winstate->buffer == NULL) |
| 2425 | { |
| 2426 | /* Initialize for first partition and set current row = 0 */ |
| 2427 | begin_partition(winstate); |
| 2428 | /* If there are no input rows, we'll detect that and exit below */ |
| 2429 | } |
| 2430 | else |
| 2431 | { |
| 2432 | /* Advance current row within partition */ |
| 2433 | winstate->currentpos++; |
| 2434 | /* This might mean that the frame moves, too */ |
| 2435 | winstate->framehead_valid = false; |
| 2436 | winstate->frametail_valid = false; |
| 2437 | /* we don't need to invalidate grouptail here; see below */ |
| 2438 | |
| 2439 | if (!winstate->start_offset_var_free) |
| 2440 | winstate->start_offset_valid = false; |
| 2441 | if (!winstate->end_offset_var_free) |
| 2442 | winstate->end_offset_valid = false; |
| 2443 | } |
| 2444 | |
| 2445 | /* |
| 2446 | * Spool all tuples up to and including the current row, if we haven't |
| 2447 | * already |
| 2448 | */ |
| 2449 | spool_tuples(winstate, winstate->currentpos); |
| 2450 | |
| 2451 | #ifdef FAULT_INJECTOR |
nothing calls this directly
no test coverage detected