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

3169 {
3170  Assert(WindowObjectIsValid(winobj));
3171  return winobj->winstate->currentpos;
3172 }
Assert(fmt[strlen(fmt) - 1] !='\n')
int64 currentpos
Definition: execnodes.h:2440
WindowAggState * winstate
Definition: nodeWindowAgg.c:64
#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 3576 of file nodeWindowAgg.c.

3577 {
3578  WindowAggState *winstate;
3579  ExprContext *econtext;
3580 
3581  Assert(WindowObjectIsValid(winobj));
3582  winstate = winobj->winstate;
3583 
3584  econtext = winstate->ss.ps.ps_ExprContext;
3585 
3586  econtext->ecxt_outertuple = winstate->ss.ss_ScanTupleSlot;
3587  return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
3588  econtext, isnull);
3589 }
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:320
static void * list_nth(const List *list, int n)
Definition: pg_list.h:278
TupleTableSlot * ecxt_outertuple
Definition: execnodes.h:236
ExprContext * ps_ExprContext
Definition: execnodes.h:1037
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1426
PlanState ps
Definition: execnodes.h:1423
ScanState ss
Definition: execnodes.h:2423

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

3384 {
3385  WindowAggState *winstate;
3386  ExprContext *econtext;
3387  TupleTableSlot *slot;
3388  int64 abs_pos;
3389  int64 mark_pos;
3390 
3391  Assert(WindowObjectIsValid(winobj));
3392  winstate = winobj->winstate;
3393  econtext = winstate->ss.ps.ps_ExprContext;
3394  slot = winstate->temp_slot_1;
3395 
3396  switch (seektype)
3397  {
3398  case WINDOW_SEEK_CURRENT:
3399  elog(ERROR, "WINDOW_SEEK_CURRENT is not supported for WinGetFuncArgInFrame");
3400  abs_pos = mark_pos = 0; /* keep compiler quiet */
3401  break;
3402  case WINDOW_SEEK_HEAD:
3403  /* rejecting relpos < 0 is easy and simplifies code below */
3404  if (relpos < 0)
3405  goto out_of_frame;
3406  update_frameheadpos(winstate);
3407  abs_pos = winstate->frameheadpos + relpos;
3408  mark_pos = abs_pos;
3409 
3410  /*
3411  * Account for exclusion option if one is active, but advance only
3412  * abs_pos not mark_pos. This prevents changes of the current
3413  * row's peer group from resulting in trying to fetch a row before
3414  * some previous mark position.
3415  *
3416  * Note that in some corner cases such as current row being
3417  * outside frame, these calculations are theoretically too simple,
3418  * but it doesn't matter because we'll end up deciding the row is
3419  * out of frame. We do not attempt to avoid fetching rows past
3420  * end of frame; that would happen in some cases anyway.
3421  */
3422  switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION)
3423  {
3424  case 0:
3425  /* no adjustment needed */
3426  break;
3428  if (abs_pos >= winstate->currentpos &&
3429  winstate->currentpos >= winstate->frameheadpos)
3430  abs_pos++;
3431  break;
3433  update_grouptailpos(winstate);
3434  if (abs_pos >= winstate->groupheadpos &&
3435  winstate->grouptailpos > winstate->frameheadpos)
3436  {
3437  int64 overlapstart = Max(winstate->groupheadpos,
3438  winstate->frameheadpos);
3439 
3440  abs_pos += winstate->grouptailpos - overlapstart;
3441  }
3442  break;
3444  update_grouptailpos(winstate);
3445  if (abs_pos >= winstate->groupheadpos &&
3446  winstate->grouptailpos > winstate->frameheadpos)
3447  {
3448  int64 overlapstart = Max(winstate->groupheadpos,
3449  winstate->frameheadpos);
3450 
3451  if (abs_pos == overlapstart)
3452  abs_pos = winstate->currentpos;
3453  else
3454  abs_pos += winstate->grouptailpos - overlapstart - 1;
3455  }
3456  break;
3457  default:
3458  elog(ERROR, "unrecognized frame option state: 0x%x",
3459  winstate->frameOptions);
3460  break;
3461  }
3462  break;
3463  case WINDOW_SEEK_TAIL:
3464  /* rejecting relpos > 0 is easy and simplifies code below */
3465  if (relpos > 0)
3466  goto out_of_frame;
3467  update_frametailpos(winstate);
3468  abs_pos = winstate->frametailpos - 1 + relpos;
3469 
3470  /*
3471  * Account for exclusion option if one is active. If there is no
3472  * exclusion, we can safely set the mark at the accessed row. But
3473  * if there is, we can only mark the frame start, because we can't
3474  * be sure how far back in the frame the exclusion might cause us
3475  * to fetch in future. Furthermore, we have to actually check
3476  * against frameheadpos here, since it's unsafe to try to fetch a
3477  * row before frame start if the mark might be there already.
3478  */
3479  switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION)
3480  {
3481  case 0:
3482  /* no adjustment needed */
3483  mark_pos = abs_pos;
3484  break;
3486  if (abs_pos <= winstate->currentpos &&
3487  winstate->currentpos < winstate->frametailpos)
3488  abs_pos--;
3489  update_frameheadpos(winstate);
3490  if (abs_pos < winstate->frameheadpos)
3491  goto out_of_frame;
3492  mark_pos = winstate->frameheadpos;
3493  break;
3495  update_grouptailpos(winstate);
3496  if (abs_pos < winstate->grouptailpos &&
3497  winstate->groupheadpos < winstate->frametailpos)
3498  {
3499  int64 overlapend = Min(winstate->grouptailpos,
3500  winstate->frametailpos);
3501 
3502  abs_pos -= overlapend - winstate->groupheadpos;
3503  }
3504  update_frameheadpos(winstate);
3505  if (abs_pos < winstate->frameheadpos)
3506  goto out_of_frame;
3507  mark_pos = winstate->frameheadpos;
3508  break;
3510  update_grouptailpos(winstate);
3511  if (abs_pos < winstate->grouptailpos &&
3512  winstate->groupheadpos < winstate->frametailpos)
3513  {
3514  int64 overlapend = Min(winstate->grouptailpos,
3515  winstate->frametailpos);
3516 
3517  if (abs_pos == overlapend - 1)
3518  abs_pos = winstate->currentpos;
3519  else
3520  abs_pos -= overlapend - 1 - winstate->groupheadpos;
3521  }
3522  update_frameheadpos(winstate);
3523  if (abs_pos < winstate->frameheadpos)
3524  goto out_of_frame;
3525  mark_pos = winstate->frameheadpos;
3526  break;
3527  default:
3528  elog(ERROR, "unrecognized frame option state: 0x%x",
3529  winstate->frameOptions);
3530  mark_pos = 0; /* keep compiler quiet */
3531  break;
3532  }
3533  break;
3534  default:
3535  elog(ERROR, "unrecognized window seek type: %d", seektype);
3536  abs_pos = mark_pos = 0; /* keep compiler quiet */
3537  break;
3538  }
3539 
3540  if (!window_gettupleslot(winobj, abs_pos, slot))
3541  goto out_of_frame;
3542 
3543  /* The code above does not detect all out-of-frame cases, so check */
3544  if (row_is_in_frame(winstate, abs_pos, slot) <= 0)
3545  goto out_of_frame;
3546 
3547  if (isout)
3548  *isout = false;
3549  if (set_mark)
3550  WinSetMarkPosition(winobj, mark_pos);
3551  econtext->ecxt_outertuple = slot;
3552  return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
3553  econtext, isnull);
3554 
3555 out_of_frame:
3556  if (isout)
3557  *isout = true;
3558  *isnull = true;
3559  return (Datum) 0;
3560 }
#define Min(x, y)
Definition: c.h:997
#define Max(x, y)
Definition: c.h:991
#define ERROR
Definition: elog.h:33
#define elog(elevel,...)
Definition: elog.h:218
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:551
#define FRAMEOPTION_EXCLUDE_TIES
Definition: parsenodes.h:553
#define FRAMEOPTION_EXCLUDE_GROUP
Definition: parsenodes.h:552
#define FRAMEOPTION_EXCLUSION
Definition: parsenodes.h:559
uintptr_t Datum
Definition: postgres.h:411
int64 frameheadpos
Definition: execnodes.h:2441
int64 grouptailpos
Definition: execnodes.h:2467
int64 groupheadpos
Definition: execnodes.h:2466
int64 frametailpos
Definition: execnodes.h:2442
TupleTableSlot * temp_slot_1
Definition: execnodes.h:2503
#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 3293 of file nodeWindowAgg.c.

3296 {
3297  WindowAggState *winstate;
3298  ExprContext *econtext;
3299  TupleTableSlot *slot;
3300  bool gottuple;
3301  int64 abs_pos;
3302 
3303  Assert(WindowObjectIsValid(winobj));
3304  winstate = winobj->winstate;
3305  econtext = winstate->ss.ps.ps_ExprContext;
3306  slot = winstate->temp_slot_1;
3307 
3308  switch (seektype)
3309  {
3310  case WINDOW_SEEK_CURRENT:
3311  abs_pos = winstate->currentpos + relpos;
3312  break;
3313  case WINDOW_SEEK_HEAD:
3314  abs_pos = relpos;
3315  break;
3316  case WINDOW_SEEK_TAIL:
3317  spool_tuples(winstate, -1);
3318  abs_pos = winstate->spooled_rows - 1 + relpos;
3319  break;
3320  default:
3321  elog(ERROR, "unrecognized window seek type: %d", seektype);
3322  abs_pos = 0; /* keep compiler quiet */
3323  break;
3324  }
3325 
3326  gottuple = window_gettupleslot(winobj, abs_pos, slot);
3327 
3328  if (!gottuple)
3329  {
3330  if (isout)
3331  *isout = true;
3332  *isnull = true;
3333  return (Datum) 0;
3334  }
3335  else
3336  {
3337  if (isout)
3338  *isout = false;
3339  if (set_mark)
3340  WinSetMarkPosition(winobj, abs_pos);
3341  econtext->ecxt_outertuple = slot;
3342  return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno),
3343  econtext, isnull);
3344  }
3345 }
static void spool_tuples(WindowAggState *winstate, int64 pos)
int64 spooled_rows
Definition: execnodes.h:2439

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

3154 {
3155  Assert(WindowObjectIsValid(winobj));
3156  if (winobj->localmem == NULL)
3157  winobj->localmem =
3159  return winobj->localmem;
3160 }
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:906
MemoryContext partcontext
Definition: execnodes.h:2469

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

3184 {
3185  Assert(WindowObjectIsValid(winobj));
3186  spool_tuples(winobj->winstate, -1);
3187  return winobj->winstate->spooled_rows;
3188 }

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

3237 {
3238  WindowAggState *winstate;
3239  WindowAgg *node;
3240  TupleTableSlot *slot1;
3241  TupleTableSlot *slot2;
3242  bool res;
3243 
3244  Assert(WindowObjectIsValid(winobj));
3245  winstate = winobj->winstate;
3246  node = (WindowAgg *) winstate->ss.ps.plan;
3247 
3248  /* If no ORDER BY, all rows are peers; don't bother to fetch them */
3249  if (node->ordNumCols == 0)
3250  return true;
3251 
3252  /*
3253  * Note: OK to use temp_slot_2 here because we aren't calling any
3254  * frame-related functions (those tend to clobber temp_slot_2).
3255  */
3256  slot1 = winstate->temp_slot_1;
3257  slot2 = winstate->temp_slot_2;
3258 
3259  if (!window_gettupleslot(winobj, pos1, slot1))
3260  elog(ERROR, "specified position is out of window: " INT64_FORMAT,
3261  pos1);
3262  if (!window_gettupleslot(winobj, pos2, slot2))
3263  elog(ERROR, "specified position is out of window: " INT64_FORMAT,
3264  pos2);
3265 
3266  res = are_peers(winstate, slot1, slot2);
3267 
3268  ExecClearTuple(slot1);
3269  ExecClearTuple(slot2);
3270 
3271  return res;
3272 }
#define INT64_FORMAT
Definition: c.h:494
static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1, TupleTableSlot *slot2)
Plan * plan
Definition: execnodes.h:998
TupleTableSlot * temp_slot_2
Definition: execnodes.h:2504
int ordNumCols
Definition: plannodes.h:1027
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:425

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

3202 {
3203  WindowAggState *winstate;
3204 
3205  Assert(WindowObjectIsValid(winobj));
3206  winstate = winobj->winstate;
3207 
3208  if (markpos < winobj->markpos)
3209  elog(ERROR, "cannot move WindowObject's mark position backward");
3210  tuplestore_select_read_pointer(winstate->buffer, winobj->markptr);
3211  if (markpos > winobj->markpos)
3212  {
3213  tuplestore_skiptuples(winstate->buffer,
3214  markpos - winobj->markpos,
3215  true);
3216  winobj->markpos = markpos;
3217  }
3218  tuplestore_select_read_pointer(winstate->buffer, winobj->readptr);
3219  if (markpos > winobj->seekpos)
3220  {
3221  tuplestore_skiptuples(winstate->buffer,
3222  markpos - winobj->seekpos,
3223  true);
3224  winobj->seekpos = markpos;
3225  }
3226 }
Tuplestorestate * buffer
Definition: execnodes.h:2434
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().