#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);
}
1.7.1