示例#1
0
/*
 * cume_dist
 * return fraction betweeen 0 and 1 inclusive,
 * which is described as NP / NR, where NP is the number of rows preceding or
 * peers to the current row, and NR is the total number of rows, per spec.
 */
datum_t window_cume_dist(PG_FUNC_ARGS)
{
	winobj_s* winobj = PG_WINOBJ();
	rank_context *context;
	bool up;
	int64 totalrows = win_get_row_count(winobj);

	ASSERT(totalrows > 0);

	up = rank_up(winobj);
	context = (rank_context *) win_get_partition(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 = win_get_current_position(winobj) + 1;

		/*
		 * start from current + 1
		 */
		for (row = context->rank; row < totalrows; row++) {
			if (!win_rows_are_peers(winobj, row - 1, row))
				break;

			context->rank++;
		}
	}

	RET_FLOAT8((float8) context->rank / (float8) totalrows);
}
示例#2
0
/*
 * dense_rank
 * Rank increases by 1 when key columns change.
 */
datum_t window_dense_rank(PG_FUNC_ARGS)
{
	winobj_s* winobj = PG_WINOBJ();
	rank_context *context;
	bool up;

	up = rank_up(winobj);
	context = (rank_context*) win_get_partition(winobj, sizeof(rank_context));
	if (up)
		context->rank++;

	RET_INT64(context->rank);
}
示例#3
0
/*
 * rank
 * Rank changes when key columns change.
 * The new rank number is the current row number.
 */
Datum
window_rank(PG_FUNCTION_ARGS)
{
	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);
}
示例#4
0
/*
 * percent_rank
 * return fraction between 0 and 1 inclusive,
 * which is described as (RK - 1) / (NR - 1), where RK is the current row's
 * rank and NR is the total number of rows, per spec.
 */
datum_t window_percent_rank(PG_FUNC_ARGS)
{
	winobj_s* winobj = PG_WINOBJ();
	rank_context *context;
	bool up;
	int64 totalrows = win_get_row_count(winobj);

	ASSERT(totalrows > 0);

	up = rank_up(winobj);
	context = (rank_context*) win_get_partition(winobj, sizeof(rank_context));
	if (up)
		context->rank = win_get_current_position(winobj) + 1;

	/* return zero if there's only one row, per spec */
	if (totalrows <= 1)
		RET_FLOAT8(0.0);

	RET_FLOAT8((float8) (context->rank - 1) / (float8) (totalrows - 1));
}
示例#5
0
/*
 * percent_rank
 * return fraction between 0 and 1 inclusive,
 * which is described as (RK - 1) / (NR - 1), where RK is the current row's
 * rank and NR is the total number of rows, per spec.
 */
Datum
window_percent_rank(PG_FUNCTION_ARGS)
{
	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));
}
示例#6
0
/*
 * cume_dist
 * return fraction betweeen 0 and 1 inclusive,
 * which is described as NP / NR, where NP is the number of rows preceding or
 * peers to the current row, and NR is the total number of rows, per spec.
 */
Datum
window_cume_dist(PG_FUNCTION_ARGS)
{
	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);
}