PostgreSQL Source Code  git master
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 3196 of file nodeWindowAgg.c.

3197 {
3198  Assert(WindowObjectIsValid(winobj));
3199  return winobj->winstate->currentpos;
3200 }
Assert(fmt[strlen(fmt) - 1] !='\n')
int64 currentpos
Definition: execnodes.h:2479
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 3604 of file nodeWindowAgg.c.

3605 {
3606  WindowAggState *winstate;
3607  ExprContext *econtext;
3608 
3609  Assert(WindowObjectIsValid(winobj));
3610  winstate = winobj->winstate;
3611 
3612  econtext = winstate->ss.ps.ps_ExprContext;
3613 
3614  econtext->ecxt_outertuple = winstate->ss.ss_ScanTupleSlot;
3615  return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
3616  econtext, isnull);
3617 }
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:331
static void * list_nth(const List *list, int n)
Definition: pg_list.h:299
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:253
ExprContext * ps_ExprContext
Definition: execnodes.h:1074
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1464
PlanState ps
Definition: execnodes.h:1461
ScanState ss
Definition: execnodes.h:2462

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 3409 of file nodeWindowAgg.c.

3412 {
3413  WindowAggState *winstate;
3414  ExprContext *econtext;
3415  TupleTableSlot *slot;
3416  int64 abs_pos;
3417  int64 mark_pos;
3418 
3419  Assert(WindowObjectIsValid(winobj));
3420  winstate = winobj->winstate;
3421  econtext = winstate->ss.ps.ps_ExprContext;
3422  slot = winstate->temp_slot_1;
3423 
3424  switch (seektype)
3425  {
3426  case WINDOW_SEEK_CURRENT:
3427  elog(ERROR, "WINDOW_SEEK_CURRENT is not supported for WinGetFuncArgInFrame");
3428  abs_pos = mark_pos = 0; /* keep compiler quiet */
3429  break;
3430  case WINDOW_SEEK_HEAD:
3431  /* rejecting relpos < 0 is easy and simplifies code below */
3432  if (relpos < 0)
3433  goto out_of_frame;
3434  update_frameheadpos(winstate);
3435  abs_pos = winstate->frameheadpos + relpos;
3436  mark_pos = abs_pos;
3437 
3438  /*
3439  * Account for exclusion option if one is active, but advance only
3440  * abs_pos not mark_pos. This prevents changes of the current
3441  * row's peer group from resulting in trying to fetch a row before
3442  * some previous mark position.
3443  *
3444  * Note that in some corner cases such as current row being
3445  * outside frame, these calculations are theoretically too simple,
3446  * but it doesn't matter because we'll end up deciding the row is
3447  * out of frame. We do not attempt to avoid fetching rows past
3448  * end of frame; that would happen in some cases anyway.
3449  */
3450  switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION)
3451  {
3452  case 0:
3453  /* no adjustment needed */
3454  break;
3456  if (abs_pos >= winstate->currentpos &&
3457  winstate->currentpos >= winstate->frameheadpos)
3458  abs_pos++;
3459  break;
3461  update_grouptailpos(winstate);
3462  if (abs_pos >= winstate->groupheadpos &&
3463  winstate->grouptailpos > winstate->frameheadpos)
3464  {
3465  int64 overlapstart = Max(winstate->groupheadpos,
3466  winstate->frameheadpos);
3467 
3468  abs_pos += winstate->grouptailpos - overlapstart;
3469  }
3470  break;
3472  update_grouptailpos(winstate);
3473  if (abs_pos >= winstate->groupheadpos &&
3474  winstate->grouptailpos > winstate->frameheadpos)
3475  {
3476  int64 overlapstart = Max(winstate->groupheadpos,
3477  winstate->frameheadpos);
3478 
3479  if (abs_pos == overlapstart)
3480  abs_pos = winstate->currentpos;
3481  else
3482  abs_pos += winstate->grouptailpos - overlapstart - 1;
3483  }
3484  break;
3485  default:
3486  elog(ERROR, "unrecognized frame option state: 0x%x",
3487  winstate->frameOptions);
3488  break;
3489  }
3490  break;
3491  case WINDOW_SEEK_TAIL:
3492  /* rejecting relpos > 0 is easy and simplifies code below */
3493  if (relpos > 0)
3494  goto out_of_frame;
3495  update_frametailpos(winstate);
3496  abs_pos = winstate->frametailpos - 1 + relpos;
3497 
3498  /*
3499  * Account for exclusion option if one is active. If there is no
3500  * exclusion, we can safely set the mark at the accessed row. But
3501  * if there is, we can only mark the frame start, because we can't
3502  * be sure how far back in the frame the exclusion might cause us
3503  * to fetch in future. Furthermore, we have to actually check
3504  * against frameheadpos here, since it's unsafe to try to fetch a
3505  * row before frame start if the mark might be there already.
3506  */
3507  switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION)
3508  {
3509  case 0:
3510  /* no adjustment needed */
3511  mark_pos = abs_pos;
3512  break;
3514  if (abs_pos <= winstate->currentpos &&
3515  winstate->currentpos < winstate->frametailpos)
3516  abs_pos--;
3517  update_frameheadpos(winstate);
3518  if (abs_pos < winstate->frameheadpos)
3519  goto out_of_frame;
3520  mark_pos = winstate->frameheadpos;
3521  break;
3523  update_grouptailpos(winstate);
3524  if (abs_pos < winstate->grouptailpos &&
3525  winstate->groupheadpos < winstate->frametailpos)
3526  {
3527  int64 overlapend = Min(winstate->grouptailpos,
3528  winstate->frametailpos);
3529 
3530  abs_pos -= overlapend - winstate->groupheadpos;
3531  }
3532  update_frameheadpos(winstate);
3533  if (abs_pos < winstate->frameheadpos)
3534  goto out_of_frame;
3535  mark_pos = winstate->frameheadpos;
3536  break;
3538  update_grouptailpos(winstate);
3539  if (abs_pos < winstate->grouptailpos &&
3540  winstate->groupheadpos < winstate->frametailpos)
3541  {
3542  int64 overlapend = Min(winstate->grouptailpos,
3543  winstate->frametailpos);
3544 
3545  if (abs_pos == overlapend - 1)
3546  abs_pos = winstate->currentpos;
3547  else
3548  abs_pos -= overlapend - 1 - winstate->groupheadpos;
3549  }
3550  update_frameheadpos(winstate);
3551  if (abs_pos < winstate->frameheadpos)
3552  goto out_of_frame;
3553  mark_pos = winstate->frameheadpos;
3554  break;
3555  default:
3556  elog(ERROR, "unrecognized frame option state: 0x%x",
3557  winstate->frameOptions);
3558  mark_pos = 0; /* keep compiler quiet */
3559  break;
3560  }
3561  break;
3562  default:
3563  elog(ERROR, "unrecognized window seek type: %d", seektype);
3564  abs_pos = mark_pos = 0; /* keep compiler quiet */
3565  break;
3566  }
3567 
3568  if (!window_gettupleslot(winobj, abs_pos, slot))
3569  goto out_of_frame;
3570 
3571  /* The code above does not detect all out-of-frame cases, so check */
3572  if (row_is_in_frame(winstate, abs_pos, slot) <= 0)
3573  goto out_of_frame;
3574 
3575  if (isout)
3576  *isout = false;
3577  if (set_mark)
3578  WinSetMarkPosition(winobj, mark_pos);
3579  econtext->ecxt_outertuple = slot;
3580  return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
3581  econtext, isnull);
3582 
3583 out_of_frame:
3584  if (isout)
3585  *isout = true;
3586  *isnull = true;
3587  return (Datum) 0;
3588 }
#define Min(x, y)
Definition: c.h:988
#define Max(x, y)
Definition: c.h:982
#define ERROR
Definition: elog.h:39
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:594
#define FRAMEOPTION_EXCLUDE_TIES
Definition: parsenodes.h:596
#define FRAMEOPTION_EXCLUDE_GROUP
Definition: parsenodes.h:595
#define FRAMEOPTION_EXCLUSION
Definition: parsenodes.h:602
uintptr_t Datum
Definition: postgres.h:64
int64 frameheadpos
Definition: execnodes.h:2480
int64 grouptailpos
Definition: execnodes.h:2506
int64 groupheadpos
Definition: execnodes.h:2505
int64 frametailpos
Definition: execnodes.h:2481
TupleTableSlot * temp_slot_1
Definition: execnodes.h:2542
#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 3321 of file nodeWindowAgg.c.

3324 {
3325  WindowAggState *winstate;
3326  ExprContext *econtext;
3327  TupleTableSlot *slot;
3328  bool gottuple;
3329  int64 abs_pos;
3330 
3331  Assert(WindowObjectIsValid(winobj));
3332  winstate = winobj->winstate;
3333  econtext = winstate->ss.ps.ps_ExprContext;
3334  slot = winstate->temp_slot_1;
3335 
3336  switch (seektype)
3337  {
3338  case WINDOW_SEEK_CURRENT:
3339  abs_pos = winstate->currentpos + relpos;
3340  break;
3341  case WINDOW_SEEK_HEAD:
3342  abs_pos = relpos;
3343  break;
3344  case WINDOW_SEEK_TAIL:
3345  spool_tuples(winstate, -1);
3346  abs_pos = winstate->spooled_rows - 1 + relpos;
3347  break;
3348  default:
3349  elog(ERROR, "unrecognized window seek type: %d", seektype);
3350  abs_pos = 0; /* keep compiler quiet */
3351  break;
3352  }
3353 
3354  gottuple = window_gettupleslot(winobj, abs_pos, slot);
3355 
3356  if (!gottuple)
3357  {
3358  if (isout)
3359  *isout = true;
3360  *isnull = true;
3361  return (Datum) 0;
3362  }
3363  else
3364  {
3365  if (isout)
3366  *isout = false;
3367  if (set_mark)
3368  WinSetMarkPosition(winobj, abs_pos);
3369  econtext->ecxt_outertuple = slot;
3370  return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
3371  econtext, isnull);
3372  }
3373 }
static void spool_tuples(WindowAggState *winstate, int64 pos)
int64 spooled_rows
Definition: execnodes.h:2478

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 3181 of file nodeWindowAgg.c.

3182 {
3183  Assert(WindowObjectIsValid(winobj));
3184  if (winobj->localmem == NULL)
3185  winobj->localmem =
3187  return winobj->localmem;
3188 }
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1048
MemoryContext partcontext
Definition: execnodes.h:2508

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 3211 of file nodeWindowAgg.c.

3212 {
3213  Assert(WindowObjectIsValid(winobj));
3214  spool_tuples(winobj->winstate, -1);
3215  return winobj->winstate->spooled_rows;
3216 }

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 3264 of file nodeWindowAgg.c.

3265 {
3266  WindowAggState *winstate;
3267  WindowAgg *node;
3268  TupleTableSlot *slot1;
3269  TupleTableSlot *slot2;
3270  bool res;
3271 
3272  Assert(WindowObjectIsValid(winobj));
3273  winstate = winobj->winstate;
3274  node = (WindowAgg *) winstate->ss.ps.plan;
3275 
3276  /* If no ORDER BY, all rows are peers; don't bother to fetch them */
3277  if (node->ordNumCols == 0)
3278  return true;
3279 
3280  /*
3281  * Note: OK to use temp_slot_2 here because we aren't calling any
3282  * frame-related functions (those tend to clobber temp_slot_2).
3283  */
3284  slot1 = winstate->temp_slot_1;
3285  slot2 = winstate->temp_slot_2;
3286 
3287  if (!window_gettupleslot(winobj, pos1, slot1))
3288  elog(ERROR, "specified position is out of window: " INT64_FORMAT,
3289  pos1);
3290  if (!window_gettupleslot(winobj, pos2, slot2))
3291  elog(ERROR, "specified position is out of window: " INT64_FORMAT,
3292  pos2);
3293 
3294  res = are_peers(winstate, slot1, slot2);
3295 
3296  ExecClearTuple(slot1);
3297  ExecClearTuple(slot2);
3298 
3299  return res;
3300 }
#define INT64_FORMAT
Definition: c.h:532
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1, TupleTableSlot *slot2)
Plan * plan
Definition: execnodes.h:1035
TupleTableSlot * temp_slot_2
Definition: execnodes.h:2543
int ordNumCols
Definition: plannodes.h:1059
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:471

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 3229 of file nodeWindowAgg.c.

3230 {
3231  WindowAggState *winstate;
3232 
3233  Assert(WindowObjectIsValid(winobj));
3234  winstate = winobj->winstate;
3235 
3236  if (markpos < winobj->markpos)
3237  elog(ERROR, "cannot move WindowObject's mark position backward");
3238  tuplestore_select_read_pointer(winstate->buffer, winobj->markptr);
3239  if (markpos > winobj->markpos)
3240  {
3241  tuplestore_skiptuples(winstate->buffer,
3242  markpos - winobj->markpos,
3243  true);
3244  winobj->markpos = markpos;
3245  }
3246  tuplestore_select_read_pointer(winstate->buffer, winobj->readptr);
3247  if (markpos > winobj->seekpos)
3248  {
3249  tuplestore_skiptuples(winstate->buffer,
3250  markpos - winobj->seekpos,
3251  true);
3252  winobj->seekpos = markpos;
3253  }
3254 }
Tuplestorestate * buffer
Definition: execnodes.h:2473
void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr)
Definition: tuplestore.c:473
bool tuplestore_skiptuples(Tuplestorestate *state, int64 ntuples, bool forward)
Definition: tuplestore.c:1135

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().