#include "postgres.h"
#include "utils/builtins.h"
#include "windowapi.h"
Go to the source code of this file.
Data Structures | |
struct | rank_context |
struct | ntile_context |
Typedefs | |
typedef struct rank_context | rank_context |
Functions | |
static bool | rank_up (WindowObject winobj) |
static Datum | leadlag_common (FunctionCallInfo fcinfo, bool forward, bool withoffset, bool withdefault) |
Datum | window_row_number (PG_FUNCTION_ARGS) |
Datum | window_rank (PG_FUNCTION_ARGS) |
Datum | window_dense_rank (PG_FUNCTION_ARGS) |
Datum | window_percent_rank (PG_FUNCTION_ARGS) |
Datum | window_cume_dist (PG_FUNCTION_ARGS) |
Datum | window_ntile (PG_FUNCTION_ARGS) |
Datum | window_lag (PG_FUNCTION_ARGS) |
Datum | window_lag_with_offset (PG_FUNCTION_ARGS) |
Datum | window_lag_with_offset_and_default (PG_FUNCTION_ARGS) |
Datum | window_lead (PG_FUNCTION_ARGS) |
Datum | window_lead_with_offset (PG_FUNCTION_ARGS) |
Datum | window_lead_with_offset_and_default (PG_FUNCTION_ARGS) |
Datum | window_first_value (PG_FUNCTION_ARGS) |
Datum | window_last_value (PG_FUNCTION_ARGS) |
Datum | window_nth_value (PG_FUNCTION_ARGS) |
typedef struct rank_context rank_context |
static Datum leadlag_common | ( | FunctionCallInfo | fcinfo, | |
bool | forward, | |||
bool | withoffset, | |||
bool | withdefault | |||
) | [static] |
Definition at line 286 of file windowfuncs.c.
References DatumGetInt32, FunctionCallInfoData::flinfo, get_fn_expr_arg_stable(), PG_RETURN_DATUM, PG_RETURN_NULL, PG_WINDOW_OBJECT, WINDOW_SEEK_CURRENT, WinGetFuncArgCurrent(), and WinGetFuncArgInPartition().
Referenced by window_lag(), window_lag_with_offset(), window_lag_with_offset_and_default(), window_lead(), window_lead_with_offset(), and window_lead_with_offset_and_default().
{ WindowObject winobj = PG_WINDOW_OBJECT(); int32 offset; bool const_offset; Datum result; bool isnull; bool isout; if (withoffset) { offset = DatumGetInt32(WinGetFuncArgCurrent(winobj, 1, &isnull)); if (isnull) PG_RETURN_NULL(); const_offset = get_fn_expr_arg_stable(fcinfo->flinfo, 1); } else { offset = 1; const_offset = true; } result = WinGetFuncArgInPartition(winobj, 0, (forward ? offset : -offset), WINDOW_SEEK_CURRENT, const_offset, &isnull, &isout); if (isout) { /* * target row is out of the partition; supply default value if * provided. otherwise it'll stay NULL */ if (withdefault) result = WinGetFuncArgCurrent(winobj, 2, &isnull); } if (isnull) PG_RETURN_NULL(); PG_RETURN_DATUM(result); }
static bool rank_up | ( | WindowObject | winobj | ) | [static] |
Definition at line 47 of file windowfuncs.c.
References Assert, rank_context::rank, WinGetCurrentPosition(), WinGetPartitionLocalMemory(), WinRowsArePeers(), and WinSetMarkPosition().
Referenced by window_cume_dist(), window_dense_rank(), window_percent_rank(), and window_rank().
{ bool up = false; /* should rank increase? */ int64 curpos = WinGetCurrentPosition(winobj); rank_context *context; context = (rank_context *) WinGetPartitionLocalMemory(winobj, sizeof(rank_context)); if (context->rank == 0) { /* first call: rank of first row is always 1 */ Assert(curpos == 0); context->rank = 1; } else { Assert(curpos > 0); /* do current and prior tuples match by ORDER BY clause? */ if (!WinRowsArePeers(winobj, curpos - 1, curpos)) up = true; } /* We can advance the mark, but only *after* acccess to prior row */ WinSetMarkPosition(winobj, curpos); return up; }
Datum window_cume_dist | ( | PG_FUNCTION_ARGS | ) |
Definition at line 169 of file windowfuncs.c.
References Assert, PG_RETURN_FLOAT8, PG_WINDOW_OBJECT, rank_context::rank, rank_up(), WinGetCurrentPosition(), WinGetPartitionLocalMemory(), WinGetPartitionRowCount(), and WinRowsArePeers().
{ WindowObject winobj = PG_WINDOW_OBJECT(); rank_context *context; bool up; int64 totalrows = WinGetPartitionRowCount(winobj); Assert(totalrows > 0); up = rank_up(winobj); context = (rank_context *) WinGetPartitionLocalMemory(winobj, sizeof(rank_context)); if (up || context->rank == 1) { /* * The current row is not peer to prior row or is just the first, so * count up the number of rows that are peer to the current. */ int64 row; context->rank = WinGetCurrentPosition(winobj) + 1; /* * start from current + 1 */ for (row = context->rank; row < totalrows; row++) { if (!WinRowsArePeers(winobj, row - 1, row)) break; context->rank++; } } PG_RETURN_FLOAT8((float8) context->rank / (float8) totalrows); }
Datum window_dense_rank | ( | PG_FUNCTION_ARGS | ) |
Definition at line 118 of file windowfuncs.c.
References PG_RETURN_INT64, PG_WINDOW_OBJECT, rank_context::rank, rank_up(), and WinGetPartitionLocalMemory().
{ WindowObject winobj = PG_WINDOW_OBJECT(); rank_context *context; bool up; up = rank_up(winobj); context = (rank_context *) WinGetPartitionLocalMemory(winobj, sizeof(rank_context)); if (up) context->rank++; PG_RETURN_INT64(context->rank); }
Datum window_first_value | ( | PG_FUNCTION_ARGS | ) |
Definition at line 407 of file windowfuncs.c.
References NULL, PG_RETURN_DATUM, PG_RETURN_NULL, PG_WINDOW_OBJECT, WINDOW_SEEK_HEAD, and WinGetFuncArgInFrame().
{ WindowObject winobj = PG_WINDOW_OBJECT(); Datum result; bool isnull; result = WinGetFuncArgInFrame(winobj, 0, 0, WINDOW_SEEK_HEAD, true, &isnull, NULL); if (isnull) PG_RETURN_NULL(); PG_RETURN_DATUM(result); }
Datum window_lag | ( | PG_FUNCTION_ARGS | ) |
Definition at line 338 of file windowfuncs.c.
References leadlag_common().
{ return leadlag_common(fcinfo, false, false, false); }
Datum window_lag_with_offset | ( | PG_FUNCTION_ARGS | ) |
Definition at line 350 of file windowfuncs.c.
References leadlag_common().
{ return leadlag_common(fcinfo, false, true, false); }
Datum window_lag_with_offset_and_default | ( | PG_FUNCTION_ARGS | ) |
Definition at line 361 of file windowfuncs.c.
References leadlag_common().
{ return leadlag_common(fcinfo, false, true, true); }
Datum window_last_value | ( | PG_FUNCTION_ARGS | ) |
Definition at line 428 of file windowfuncs.c.
References NULL, PG_RETURN_DATUM, PG_RETURN_NULL, PG_WINDOW_OBJECT, WINDOW_SEEK_TAIL, and WinGetFuncArgInFrame().
{ WindowObject winobj = PG_WINDOW_OBJECT(); Datum result; bool isnull; result = WinGetFuncArgInFrame(winobj, 0, 0, WINDOW_SEEK_TAIL, true, &isnull, NULL); if (isnull) PG_RETURN_NULL(); PG_RETURN_DATUM(result); }
Datum window_lead | ( | PG_FUNCTION_ARGS | ) |
Definition at line 373 of file windowfuncs.c.
References leadlag_common().
{ return leadlag_common(fcinfo, true, false, false); }
Datum window_lead_with_offset | ( | PG_FUNCTION_ARGS | ) |
Definition at line 385 of file windowfuncs.c.
References leadlag_common().
{ return leadlag_common(fcinfo, true, true, false); }
Datum window_lead_with_offset_and_default | ( | PG_FUNCTION_ARGS | ) |
Definition at line 396 of file windowfuncs.c.
References leadlag_common().
{ return leadlag_common(fcinfo, true, true, true); }
Datum window_nth_value | ( | PG_FUNCTION_ARGS | ) |
Definition at line 449 of file windowfuncs.c.
References DatumGetInt32, ereport, errcode(), errmsg(), ERROR, get_fn_expr_arg_stable(), NULL, PG_RETURN_DATUM, PG_RETURN_NULL, PG_WINDOW_OBJECT, WINDOW_SEEK_HEAD, WinGetFuncArgCurrent(), and WinGetFuncArgInFrame().
{ WindowObject winobj = PG_WINDOW_OBJECT(); bool const_offset; Datum result; bool isnull; int32 nth; nth = DatumGetInt32(WinGetFuncArgCurrent(winobj, 1, &isnull)); if (isnull) PG_RETURN_NULL(); const_offset = get_fn_expr_arg_stable(fcinfo->flinfo, 1); if (nth <= 0) ereport(ERROR, (errcode(ERRCODE_INVALID_ARGUMENT_FOR_NTH_VALUE), errmsg("argument of nth_value must be greater than zero"))); result = WinGetFuncArgInFrame(winobj, 0, nth - 1, WINDOW_SEEK_HEAD, const_offset, &isnull, NULL); if (isnull) PG_RETURN_NULL(); PG_RETURN_DATUM(result); }
Datum window_ntile | ( | PG_FUNCTION_ARGS | ) |
Definition at line 211 of file windowfuncs.c.
References ntile_context::boundary, DatumGetInt32, ereport, errcode(), errmsg(), ERROR, ntile_context::ntile, PG_RETURN_INT32, PG_RETURN_NULL, PG_WINDOW_OBJECT, ntile_context::remainder, ntile_context::rows_per_bucket, WinGetFuncArgCurrent(), WinGetPartitionLocalMemory(), and WinGetPartitionRowCount().
{ WindowObject winobj = PG_WINDOW_OBJECT(); ntile_context *context; context = (ntile_context *) WinGetPartitionLocalMemory(winobj, sizeof(ntile_context)); if (context->ntile == 0) { /* first call */ int64 total; int32 nbuckets; bool isnull; total = WinGetPartitionRowCount(winobj); nbuckets = DatumGetInt32(WinGetFuncArgCurrent(winobj, 0, &isnull)); /* * per spec: If NT is the null value, then the result is the null * value. */ if (isnull) PG_RETURN_NULL(); /* * per spec: If NT is less than or equal to 0 (zero), then an * exception condition is raised. */ if (nbuckets <= 0) ereport(ERROR, (errcode(ERRCODE_INVALID_ARGUMENT_FOR_NTILE), errmsg("argument of ntile must be greater than zero"))); context->ntile = 1; context->rows_per_bucket = 0; context->boundary = total / nbuckets; if (context->boundary <= 0) context->boundary = 1; else { /* * If the total number is not divisible, add 1 row to leading * buckets. */ context->remainder = total % nbuckets; if (context->remainder != 0) context->boundary++; } } context->rows_per_bucket++; if (context->boundary < context->rows_per_bucket) { /* ntile up */ if (context->remainder != 0 && context->ntile == context->remainder) { context->remainder = 0; context->boundary -= 1; } context->ntile += 1; context->rows_per_bucket = 1; } PG_RETURN_INT32(context->ntile); }
Datum window_percent_rank | ( | PG_FUNCTION_ARGS | ) |
Definition at line 140 of file windowfuncs.c.
References Assert, PG_RETURN_FLOAT8, PG_WINDOW_OBJECT, rank_context::rank, rank_up(), WinGetCurrentPosition(), WinGetPartitionLocalMemory(), and WinGetPartitionRowCount().
{ WindowObject winobj = PG_WINDOW_OBJECT(); rank_context *context; bool up; int64 totalrows = WinGetPartitionRowCount(winobj); Assert(totalrows > 0); up = rank_up(winobj); context = (rank_context *) WinGetPartitionLocalMemory(winobj, sizeof(rank_context)); if (up) context->rank = WinGetCurrentPosition(winobj) + 1; /* return zero if there's only one row, per spec */ if (totalrows <= 1) PG_RETURN_FLOAT8(0.0); PG_RETURN_FLOAT8((float8) (context->rank - 1) / (float8) (totalrows - 1)); }
Datum window_rank | ( | PG_FUNCTION_ARGS | ) |
Definition at line 98 of file windowfuncs.c.
References PG_RETURN_INT64, PG_WINDOW_OBJECT, rank_context::rank, rank_up(), WinGetCurrentPosition(), and WinGetPartitionLocalMemory().
{ WindowObject winobj = PG_WINDOW_OBJECT(); rank_context *context; bool up; up = rank_up(winobj); context = (rank_context *) WinGetPartitionLocalMemory(winobj, sizeof(rank_context)); if (up) context->rank = WinGetCurrentPosition(winobj) + 1; PG_RETURN_INT64(context->rank); }
Datum window_row_number | ( | PG_FUNCTION_ARGS | ) |
Definition at line 82 of file windowfuncs.c.
References PG_RETURN_INT64, PG_WINDOW_OBJECT, WinGetCurrentPosition(), and WinSetMarkPosition().
{ WindowObject winobj = PG_WINDOW_OBJECT(); int64 curpos = WinGetCurrentPosition(winobj); WinSetMarkPosition(winobj, curpos); PG_RETURN_INT64(curpos + 1); }