PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
windowapi.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define WINDOW_SEEK_CURRENT   0
 
#define WINDOW_SEEK_HEAD   1
 
#define WINDOW_SEEK_TAIL   2
 
#define PG_WINDOW_OBJECT()   ((WindowObject) fcinfo->context)
 
#define WindowObjectIsValid(winobj)    ((winobj) != NULL && IsA(winobj, WindowObjectData))
 

Typedefs

typedef struct WindowObjectDataWindowObject
 

Functions

void * WinGetPartitionLocalMemory (WindowObject winobj, Size sz)
 
int64 WinGetCurrentPosition (WindowObject winobj)
 
int64 WinGetPartitionRowCount (WindowObject winobj)
 
void WinSetMarkPosition (WindowObject winobj, int64 markpos)
 
bool WinRowsArePeers (WindowObject winobj, int64 pos1, int64 pos2)
 
Datum WinGetFuncArgInPartition (WindowObject winobj, int argno, int relpos, int seektype, bool set_mark, bool *isnull, bool *isout)
 
Datum WinGetFuncArgInFrame (WindowObject winobj, int argno, int relpos, int seektype, bool set_mark, bool *isnull, bool *isout)
 
Datum WinGetFuncArgCurrent (WindowObject winobj, int argno, bool *isnull)
 

Macro Definition Documentation

◆ PG_WINDOW_OBJECT

#define PG_WINDOW_OBJECT ( )    ((WindowObject) fcinfo->context)

Definition at line 39 of file windowapi.h.

◆ WINDOW_SEEK_CURRENT

#define WINDOW_SEEK_CURRENT   0

Definition at line 32 of file windowapi.h.

◆ WINDOW_SEEK_HEAD

#define WINDOW_SEEK_HEAD   1

Definition at line 33 of file windowapi.h.

◆ WINDOW_SEEK_TAIL

#define WINDOW_SEEK_TAIL   2

Definition at line 34 of file windowapi.h.

◆ WindowObjectIsValid

#define WindowObjectIsValid (   winobj)     ((winobj) != NULL && IsA(winobj, WindowObjectData))

Definition at line 41 of file windowapi.h.

Typedef Documentation

◆ WindowObject

typedef struct WindowObjectData* WindowObject

Definition at line 37 of file windowapi.h.

Function Documentation

◆ WinGetCurrentPosition()

int64 WinGetCurrentPosition ( WindowObject  winobj)

Definition at line 3251 of file nodeWindowAgg.c.

3252{
3253 Assert(WindowObjectIsValid(winobj));
3254 return winobj->winstate->currentpos;
3255}
#define Assert(condition)
Definition: c.h:812
int64 currentpos
Definition: execnodes.h:2607
WindowAggState * winstate
Definition: nodeWindowAgg.c:65
#define WindowObjectIsValid(winobj)
Definition: windowapi.h:41

References Assert, WindowAggState::currentpos, WindowObjectIsValid, and WindowObjectData::winstate.

Referenced by rank_up(), window_cume_dist(), window_percent_rank(), window_rank(), and window_row_number().

◆ WinGetFuncArgCurrent()

Datum WinGetFuncArgCurrent ( WindowObject  winobj,
int  argno,
bool *  isnull 
)

Definition at line 3659 of file nodeWindowAgg.c.

3660{
3661 WindowAggState *winstate;
3662 ExprContext *econtext;
3663
3664 Assert(WindowObjectIsValid(winobj));
3665 winstate = winobj->winstate;
3666
3667 econtext = winstate->ss.ps.ps_ExprContext;
3668
3669 econtext->ecxt_outertuple = winstate->ss.ss_ScanTupleSlot;
3670 return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
3671 econtext, isnull);
3672}
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:346
static void * list_nth(const List *list, int n)
Definition: pg_list.h:299
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:262
ExprContext * ps_ExprContext
Definition: execnodes.h:1165
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1576
PlanState ps
Definition: execnodes.h:1573
ScanState ss
Definition: execnodes.h:2590

References WindowObjectData::argstates, Assert, ExprContext::ecxt_outertuple, ExecEvalExpr(), list_nth(), ScanState::ps, PlanState::ps_ExprContext, WindowAggState::ss, ScanState::ss_ScanTupleSlot, WindowObjectIsValid, and WindowObjectData::winstate.

Referenced by leadlag_common(), window_nth_value(), and window_ntile().

◆ WinGetFuncArgInFrame()

Datum WinGetFuncArgInFrame ( WindowObject  winobj,
int  argno,
int  relpos,
int  seektype,
bool  set_mark,
bool *  isnull,
bool *  isout 
)

Definition at line 3464 of file nodeWindowAgg.c.

3467{
3468 WindowAggState *winstate;
3469 ExprContext *econtext;
3470 TupleTableSlot *slot;
3471 int64 abs_pos;
3472 int64 mark_pos;
3473
3474 Assert(WindowObjectIsValid(winobj));
3475 winstate = winobj->winstate;
3476 econtext = winstate->ss.ps.ps_ExprContext;
3477 slot = winstate->temp_slot_1;
3478
3479 switch (seektype)
3480 {
3482 elog(ERROR, "WINDOW_SEEK_CURRENT is not supported for WinGetFuncArgInFrame");
3483 abs_pos = mark_pos = 0; /* keep compiler quiet */
3484 break;
3485 case WINDOW_SEEK_HEAD:
3486 /* rejecting relpos < 0 is easy and simplifies code below */
3487 if (relpos < 0)
3488 goto out_of_frame;
3489 update_frameheadpos(winstate);
3490 abs_pos = winstate->frameheadpos + relpos;
3491 mark_pos = abs_pos;
3492
3493 /*
3494 * Account for exclusion option if one is active, but advance only
3495 * abs_pos not mark_pos. This prevents changes of the current
3496 * row's peer group from resulting in trying to fetch a row before
3497 * some previous mark position.
3498 *
3499 * Note that in some corner cases such as current row being
3500 * outside frame, these calculations are theoretically too simple,
3501 * but it doesn't matter because we'll end up deciding the row is
3502 * out of frame. We do not attempt to avoid fetching rows past
3503 * end of frame; that would happen in some cases anyway.
3504 */
3505 switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION)
3506 {
3507 case 0:
3508 /* no adjustment needed */
3509 break;
3511 if (abs_pos >= winstate->currentpos &&
3512 winstate->currentpos >= winstate->frameheadpos)
3513 abs_pos++;
3514 break;
3516 update_grouptailpos(winstate);
3517 if (abs_pos >= winstate->groupheadpos &&
3518 winstate->grouptailpos > winstate->frameheadpos)
3519 {
3520 int64 overlapstart = Max(winstate->groupheadpos,
3521 winstate->frameheadpos);
3522
3523 abs_pos += winstate->grouptailpos - overlapstart;
3524 }
3525 break;
3527 update_grouptailpos(winstate);
3528 if (abs_pos >= winstate->groupheadpos &&
3529 winstate->grouptailpos > winstate->frameheadpos)
3530 {
3531 int64 overlapstart = Max(winstate->groupheadpos,
3532 winstate->frameheadpos);
3533
3534 if (abs_pos == overlapstart)
3535 abs_pos = winstate->currentpos;
3536 else
3537 abs_pos += winstate->grouptailpos - overlapstart - 1;
3538 }
3539 break;
3540 default:
3541 elog(ERROR, "unrecognized frame option state: 0x%x",
3542 winstate->frameOptions);
3543 break;
3544 }
3545 break;
3546 case WINDOW_SEEK_TAIL:
3547 /* rejecting relpos > 0 is easy and simplifies code below */
3548 if (relpos > 0)
3549 goto out_of_frame;
3550 update_frametailpos(winstate);
3551 abs_pos = winstate->frametailpos - 1 + relpos;
3552
3553 /*
3554 * Account for exclusion option if one is active. If there is no
3555 * exclusion, we can safely set the mark at the accessed row. But
3556 * if there is, we can only mark the frame start, because we can't
3557 * be sure how far back in the frame the exclusion might cause us
3558 * to fetch in future. Furthermore, we have to actually check
3559 * against frameheadpos here, since it's unsafe to try to fetch a
3560 * row before frame start if the mark might be there already.
3561 */
3562 switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION)
3563 {
3564 case 0:
3565 /* no adjustment needed */
3566 mark_pos = abs_pos;
3567 break;
3569 if (abs_pos <= winstate->currentpos &&
3570 winstate->currentpos < winstate->frametailpos)
3571 abs_pos--;
3572 update_frameheadpos(winstate);
3573 if (abs_pos < winstate->frameheadpos)
3574 goto out_of_frame;
3575 mark_pos = winstate->frameheadpos;
3576 break;
3578 update_grouptailpos(winstate);
3579 if (abs_pos < winstate->grouptailpos &&
3580 winstate->groupheadpos < winstate->frametailpos)
3581 {
3582 int64 overlapend = Min(winstate->grouptailpos,
3583 winstate->frametailpos);
3584
3585 abs_pos -= overlapend - winstate->groupheadpos;
3586 }
3587 update_frameheadpos(winstate);
3588 if (abs_pos < winstate->frameheadpos)
3589 goto out_of_frame;
3590 mark_pos = winstate->frameheadpos;
3591 break;
3593 update_grouptailpos(winstate);
3594 if (abs_pos < winstate->grouptailpos &&
3595 winstate->groupheadpos < winstate->frametailpos)
3596 {
3597 int64 overlapend = Min(winstate->grouptailpos,
3598 winstate->frametailpos);
3599
3600 if (abs_pos == overlapend - 1)
3601 abs_pos = winstate->currentpos;
3602 else
3603 abs_pos -= overlapend - 1 - winstate->groupheadpos;
3604 }
3605 update_frameheadpos(winstate);
3606 if (abs_pos < winstate->frameheadpos)
3607 goto out_of_frame;
3608 mark_pos = winstate->frameheadpos;
3609 break;
3610 default:
3611 elog(ERROR, "unrecognized frame option state: 0x%x",
3612 winstate->frameOptions);
3613 mark_pos = 0; /* keep compiler quiet */
3614 break;
3615 }
3616 break;
3617 default:
3618 elog(ERROR, "unrecognized window seek type: %d", seektype);
3619 abs_pos = mark_pos = 0; /* keep compiler quiet */
3620 break;
3621 }
3622
3623 if (!window_gettupleslot(winobj, abs_pos, slot))
3624 goto out_of_frame;
3625
3626 /* The code above does not detect all out-of-frame cases, so check */
3627 if (row_is_in_frame(winstate, abs_pos, slot) <= 0)
3628 goto out_of_frame;
3629
3630 if (isout)
3631 *isout = false;
3632 if (set_mark)
3633 WinSetMarkPosition(winobj, mark_pos);
3634 econtext->ecxt_outertuple = slot;
3635 return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
3636 econtext, isnull);
3637
3638out_of_frame:
3639 if (isout)
3640 *isout = true;
3641 *isnull = true;
3642 return (Datum) 0;
3643}
#define Min(x, y)
Definition: c.h:958
#define Max(x, y)
Definition: c.h:952
int64_t int64
Definition: c.h:482
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
static void update_grouptailpos(WindowAggState *winstate)
static int row_is_in_frame(WindowAggState *winstate, int64 pos, TupleTableSlot *slot)
static bool window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot)
void WinSetMarkPosition(WindowObject winobj, int64 markpos)
static void update_frametailpos(WindowAggState *winstate)
static void update_frameheadpos(WindowAggState *winstate)
#define FRAMEOPTION_EXCLUDE_CURRENT_ROW
Definition: parsenodes.h:598
#define FRAMEOPTION_EXCLUDE_TIES
Definition: parsenodes.h:600
#define FRAMEOPTION_EXCLUDE_GROUP
Definition: parsenodes.h:599
#define FRAMEOPTION_EXCLUSION
Definition: parsenodes.h:606
uintptr_t Datum
Definition: postgres.h:64
int64 frameheadpos
Definition: execnodes.h:2608
int64 grouptailpos
Definition: execnodes.h:2645
int64 groupheadpos
Definition: execnodes.h:2644
int64 frametailpos
Definition: execnodes.h:2609
TupleTableSlot * temp_slot_1
Definition: execnodes.h:2672
#define WINDOW_SEEK_TAIL
Definition: windowapi.h:34
#define WINDOW_SEEK_HEAD
Definition: windowapi.h:33
#define WINDOW_SEEK_CURRENT
Definition: windowapi.h:32

References WindowObjectData::argstates, Assert, WindowAggState::currentpos, ExprContext::ecxt_outertuple, elog, ERROR, ExecEvalExpr(), WindowAggState::frameheadpos, FRAMEOPTION_EXCLUDE_CURRENT_ROW, FRAMEOPTION_EXCLUDE_GROUP, FRAMEOPTION_EXCLUDE_TIES, FRAMEOPTION_EXCLUSION, WindowAggState::frameOptions, WindowAggState::frametailpos, WindowAggState::groupheadpos, WindowAggState::grouptailpos, list_nth(), Max, Min, ScanState::ps, PlanState::ps_ExprContext, row_is_in_frame(), WindowAggState::ss, WindowAggState::temp_slot_1, update_frameheadpos(), update_frametailpos(), update_grouptailpos(), window_gettupleslot(), WINDOW_SEEK_CURRENT, WINDOW_SEEK_HEAD, WINDOW_SEEK_TAIL, WindowObjectIsValid, WinSetMarkPosition(), and WindowObjectData::winstate.

Referenced by window_first_value(), window_last_value(), and window_nth_value().

◆ WinGetFuncArgInPartition()

Datum WinGetFuncArgInPartition ( WindowObject  winobj,
int  argno,
int  relpos,
int  seektype,
bool  set_mark,
bool *  isnull,
bool *  isout 
)

Definition at line 3376 of file nodeWindowAgg.c.

3379{
3380 WindowAggState *winstate;
3381 ExprContext *econtext;
3382 TupleTableSlot *slot;
3383 bool gottuple;
3384 int64 abs_pos;
3385
3386 Assert(WindowObjectIsValid(winobj));
3387 winstate = winobj->winstate;
3388 econtext = winstate->ss.ps.ps_ExprContext;
3389 slot = winstate->temp_slot_1;
3390
3391 switch (seektype)
3392 {
3394 abs_pos = winstate->currentpos + relpos;
3395 break;
3396 case WINDOW_SEEK_HEAD:
3397 abs_pos = relpos;
3398 break;
3399 case WINDOW_SEEK_TAIL:
3400 spool_tuples(winstate, -1);
3401 abs_pos = winstate->spooled_rows - 1 + relpos;
3402 break;
3403 default:
3404 elog(ERROR, "unrecognized window seek type: %d", seektype);
3405 abs_pos = 0; /* keep compiler quiet */
3406 break;
3407 }
3408
3409 gottuple = window_gettupleslot(winobj, abs_pos, slot);
3410
3411 if (!gottuple)
3412 {
3413 if (isout)
3414 *isout = true;
3415 *isnull = true;
3416 return (Datum) 0;
3417 }
3418 else
3419 {
3420 if (isout)
3421 *isout = false;
3422 if (set_mark)
3423 WinSetMarkPosition(winobj, abs_pos);
3424 econtext->ecxt_outertuple = slot;
3425 return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
3426 econtext, isnull);
3427 }
3428}
static void spool_tuples(WindowAggState *winstate, int64 pos)
int64 spooled_rows
Definition: execnodes.h:2606

References WindowObjectData::argstates, Assert, WindowAggState::currentpos, ExprContext::ecxt_outertuple, elog, ERROR, ExecEvalExpr(), list_nth(), ScanState::ps, PlanState::ps_ExprContext, spool_tuples(), WindowAggState::spooled_rows, WindowAggState::ss, WindowAggState::temp_slot_1, window_gettupleslot(), WINDOW_SEEK_CURRENT, WINDOW_SEEK_HEAD, WINDOW_SEEK_TAIL, WindowObjectIsValid, WinSetMarkPosition(), and WindowObjectData::winstate.

Referenced by leadlag_common().

◆ WinGetPartitionLocalMemory()

void * WinGetPartitionLocalMemory ( WindowObject  winobj,
Size  sz 
)

Definition at line 3236 of file nodeWindowAgg.c.

3237{
3238 Assert(WindowObjectIsValid(winobj));
3239 if (winobj->localmem == NULL)
3240 winobj->localmem =
3242 return winobj->localmem;
3243}
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1215
MemoryContext partcontext
Definition: execnodes.h:2647

References Assert, WindowObjectData::localmem, MemoryContextAllocZero(), WindowAggState::partcontext, WindowObjectIsValid, and WindowObjectData::winstate.

Referenced by rank_up(), window_cume_dist(), window_dense_rank(), window_ntile(), window_percent_rank(), and window_rank().

◆ WinGetPartitionRowCount()

int64 WinGetPartitionRowCount ( WindowObject  winobj)

Definition at line 3266 of file nodeWindowAgg.c.

3267{
3268 Assert(WindowObjectIsValid(winobj));
3269 spool_tuples(winobj->winstate, -1);
3270 return winobj->winstate->spooled_rows;
3271}

References Assert, spool_tuples(), WindowAggState::spooled_rows, WindowObjectIsValid, and WindowObjectData::winstate.

Referenced by window_cume_dist(), window_ntile(), and window_percent_rank().

◆ WinRowsArePeers()

bool WinRowsArePeers ( WindowObject  winobj,
int64  pos1,
int64  pos2 
)

Definition at line 3319 of file nodeWindowAgg.c.

3320{
3321 WindowAggState *winstate;
3322 WindowAgg *node;
3323 TupleTableSlot *slot1;
3324 TupleTableSlot *slot2;
3325 bool res;
3326
3327 Assert(WindowObjectIsValid(winobj));
3328 winstate = winobj->winstate;
3329 node = (WindowAgg *) winstate->ss.ps.plan;
3330
3331 /* If no ORDER BY, all rows are peers; don't bother to fetch them */
3332 if (node->ordNumCols == 0)
3333 return true;
3334
3335 /*
3336 * Note: OK to use temp_slot_2 here because we aren't calling any
3337 * frame-related functions (those tend to clobber temp_slot_2).
3338 */
3339 slot1 = winstate->temp_slot_1;
3340 slot2 = winstate->temp_slot_2;
3341
3342 if (!window_gettupleslot(winobj, pos1, slot1))
3343 elog(ERROR, "specified position is out of window: " INT64_FORMAT,
3344 pos1);
3345 if (!window_gettupleslot(winobj, pos2, slot2))
3346 elog(ERROR, "specified position is out of window: " INT64_FORMAT,
3347 pos2);
3348
3349 res = are_peers(winstate, slot1, slot2);
3350
3351 ExecClearTuple(slot1);
3352 ExecClearTuple(slot2);
3353
3354 return res;
3355}
#define INT64_FORMAT
Definition: c.h:503
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1, TupleTableSlot *slot2)
Plan * plan
Definition: execnodes.h:1126
TupleTableSlot * temp_slot_2
Definition: execnodes.h:2673
int ordNumCols
Definition: plannodes.h:1059
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:454

References are_peers(), Assert, elog, ERROR, ExecClearTuple(), if(), INT64_FORMAT, WindowAgg::ordNumCols, PlanState::plan, ScanState::ps, res, WindowAggState::ss, WindowAggState::temp_slot_1, WindowAggState::temp_slot_2, window_gettupleslot(), WindowObjectIsValid, and WindowObjectData::winstate.

Referenced by rank_up(), and window_cume_dist().

◆ WinSetMarkPosition()

void WinSetMarkPosition ( WindowObject  winobj,
int64  markpos 
)

Definition at line 3284 of file nodeWindowAgg.c.

3285{
3286 WindowAggState *winstate;
3287
3288 Assert(WindowObjectIsValid(winobj));
3289 winstate = winobj->winstate;
3290
3291 if (markpos < winobj->markpos)
3292 elog(ERROR, "cannot move WindowObject's mark position backward");
3293 tuplestore_select_read_pointer(winstate->buffer, winobj->markptr);
3294 if (markpos > winobj->markpos)
3295 {
3296 tuplestore_skiptuples(winstate->buffer,
3297 markpos - winobj->markpos,
3298 true);
3299 winobj->markpos = markpos;
3300 }
3301 tuplestore_select_read_pointer(winstate->buffer, winobj->readptr);
3302 if (markpos > winobj->seekpos)
3303 {
3304 tuplestore_skiptuples(winstate->buffer,
3305 markpos - winobj->seekpos,
3306 true);
3307 winobj->seekpos = markpos;
3308 }
3309}
Tuplestorestate * buffer
Definition: execnodes.h:2601
void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
Definition: tuplestore.c:507
bool tuplestore_skiptuples(Tuplestorestate *state, int64 ntuples, bool forward)
Definition: tuplestore.c:1187

References Assert, WindowAggState::buffer, elog, ERROR, WindowObjectData::markpos, WindowObjectData::markptr, WindowObjectData::readptr, WindowObjectData::seekpos, tuplestore_select_read_pointer(), tuplestore_skiptuples(), WindowObjectIsValid, and WindowObjectData::winstate.

Referenced by eval_windowaggregates(), rank_up(), window_row_number(), WinGetFuncArgInFrame(), and WinGetFuncArgInPartition().