* update_grouptailpos * make grouptailpos valid for the current row * * May clobber winstate->temp_slot_2. */
| 2257 | * May clobber winstate->temp_slot_2. |
| 2258 | */ |
| 2259 | static void |
| 2260 | update_grouptailpos(WindowAggState *winstate) |
| 2261 | { |
| 2262 | WindowAgg *node = (WindowAgg *) winstate->ss.ps.plan; |
| 2263 | MemoryContext oldcontext; |
| 2264 | |
| 2265 | if (winstate->grouptail_valid) |
| 2266 | return; /* already known for current row */ |
| 2267 | |
| 2268 | /* We may be called in a short-lived context */ |
| 2269 | oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory); |
| 2270 | |
| 2271 | /* If no ORDER BY, all rows are peers with each other */ |
| 2272 | if (node->ordNumCols == 0) |
| 2273 | { |
| 2274 | spool_tuples(winstate, -1); |
| 2275 | winstate->grouptailpos = winstate->spooled_rows; |
| 2276 | winstate->grouptail_valid = true; |
| 2277 | MemoryContextSwitchTo(oldcontext); |
| 2278 | return; |
| 2279 | } |
| 2280 | |
| 2281 | /* |
| 2282 | * Because grouptail_valid is reset only when current row advances into a |
| 2283 | * new peer group, we always reach here knowing that grouptailpos needs to |
| 2284 | * be advanced by at least one row. Hence, unlike the otherwise similar |
| 2285 | * case for frame tail tracking, we do not need persistent storage of the |
| 2286 | * group tail row. |
| 2287 | */ |
| 2288 | Assert(winstate->grouptailpos <= winstate->currentpos); |
| 2289 | tuplestore_select_read_pointer(winstate->buffer, |
| 2290 | winstate->grouptail_ptr); |
| 2291 | for (;;) |
| 2292 | { |
| 2293 | /* Note we advance grouptailpos even if the fetch fails */ |
| 2294 | winstate->grouptailpos++; |
| 2295 | spool_tuples(winstate, winstate->grouptailpos); |
| 2296 | if (!tuplestore_gettupleslot(winstate->buffer, true, true, |
| 2297 | winstate->temp_slot_2)) |
| 2298 | break; /* end of partition */ |
| 2299 | if (winstate->grouptailpos > winstate->currentpos && |
| 2300 | !are_peers(winstate, winstate->temp_slot_2, |
| 2301 | winstate->ss.ss_ScanTupleSlot)) |
| 2302 | break; /* this row is the group tail */ |
| 2303 | } |
| 2304 | ExecClearTuple(winstate->temp_slot_2); |
| 2305 | winstate->grouptail_valid = true; |
| 2306 | |
| 2307 | MemoryContextSwitchTo(oldcontext); |
| 2308 | } |
| 2309 | |
| 2310 | static void |
| 2311 | compute_start_end_offsets(WindowAggState *winstate) |
no test coverage detected