* WinSetMarkPosition * Set the "mark" position for the window object, which is the oldest row * number (counting from 0) it is allowed to fetch during all subsequent * operations within the current partition. * * Window functions do not have to call this, but are encouraged to move the * mark forward when possible to keep the tuplestore size down and prevent * having to spill rows to dis
| 3475 | * having to spill rows to disk. |
| 3476 | */ |
| 3477 | void |
| 3478 | WinSetMarkPosition(WindowObject winobj, int64 markpos) |
| 3479 | { |
| 3480 | WindowAggState *winstate; |
| 3481 | |
| 3482 | Assert(WindowObjectIsValid(winobj)); |
| 3483 | winstate = winobj->winstate; |
| 3484 | |
| 3485 | /* |
| 3486 | * In GPDB, unlike in PostgreSQL, the start and end offsets are not |
| 3487 | * necessarily constant throughout the execution. In that case, don't |
| 3488 | * believe it when the window function tells that it's won't need the |
| 3489 | * old rows anymore, in case the window frame needs to enlarge later. |
| 3490 | * In principle, it would perhaps be nicer if each window function |
| 3491 | * would take this into account and not call WinSetMarkPosition in |
| 3492 | * that case, but changing all the window function implementations |
| 3493 | * is not very appealing. It woudl be make merging harder, and there |
| 3494 | * would be the risk for bugs of omission. 3rd party extenstion, |
| 3495 | * written for PostgreSQL, would also not know about it. So all in all, |
| 3496 | * let's just keep the all the rows, if the start/end offsets contain |
| 3497 | * variables. That is hopefully not very common in practice. |
| 3498 | */ |
| 3499 | if (!winstate->start_offset_var_free || !winstate->end_offset_var_free) |
| 3500 | return; |
| 3501 | |
| 3502 | if (markpos < winobj->markpos) |
| 3503 | elog(ERROR, "cannot move WindowObject's mark position backward"); |
| 3504 | tuplestore_select_read_pointer(winstate->buffer, winobj->markptr); |
| 3505 | if (markpos > winobj->markpos) |
| 3506 | { |
| 3507 | tuplestore_skiptuples(winstate->buffer, |
| 3508 | markpos - winobj->markpos, |
| 3509 | true); |
| 3510 | winobj->markpos = markpos; |
| 3511 | } |
| 3512 | tuplestore_select_read_pointer(winstate->buffer, winobj->readptr); |
| 3513 | if (markpos > winobj->seekpos) |
| 3514 | { |
| 3515 | tuplestore_skiptuples(winstate->buffer, |
| 3516 | markpos - winobj->seekpos, |
| 3517 | true); |
| 3518 | winobj->seekpos = markpos; |
| 3519 | } |
| 3520 | } |
| 3521 | |
| 3522 | /* |
| 3523 | * WinRowsArePeers |
no test coverage detected