1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Add implementation of last_value() window function.

FossilOrigin-Name: 2493ce1a402888f6a8f25e03052c25a4e9bca740639e98cb614f5e5160ac25d3
This commit is contained in:
dan
2018-06-05 16:16:17 +00:00
parent 6bc5c9e788
commit 1c5ed624a0
5 changed files with 496 additions and 10 deletions

View File

@@ -191,7 +191,6 @@ struct NtileCtx {
** been coerced to:
**
** ROWS UNBOUNDED PRECEDING AND CURRENT ROW
**
*/
static void ntileStepFunc(
sqlite3_context *pCtx,
@@ -243,6 +242,59 @@ static void ntileValueFunc(sqlite3_context *pCtx){
}
}
struct LastValueCtx {
sqlite3_value *pVal;
int nVal;
};
/*
** Implementation of last_value().
*/
static void last_valueStepFunc(
sqlite3_context *pCtx,
int nArg,
sqlite3_value **apArg
){
struct LastValueCtx *p;
p = (struct LastValueCtx *)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
sqlite3_value_free(p->pVal);
p->pVal = sqlite3_value_dup(apArg[0]);
p->nVal++;
}
}
static void last_valueInverseFunc(
sqlite3_context *pCtx,
int nArg,
sqlite3_value **apArg
){
struct LastValueCtx *p;
p = (struct LastValueCtx *)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
p->nVal--;
if( p->nVal==0 ){
sqlite3_value_free(p->pVal);
p->pVal = 0;
}
}
}
static void last_valueValueFunc(sqlite3_context *pCtx){
struct LastValueCtx *p;
p = (struct LastValueCtx *)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p && p->pVal ){
sqlite3_result_value(pCtx, p->pVal);
}
}
static void last_valueFinalizeFunc(sqlite3_context *pCtx){
struct LastValueCtx *p;
p = (struct LastValueCtx *)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p && p->pVal ){
sqlite3_result_value(pCtx, p->pVal);
sqlite3_value_free(p->pVal);
p->pVal = 0;
}
}
static void nth_valueStepFunc(
sqlite3_context *pCtx,
int nArg,
@@ -264,6 +316,12 @@ static void nth_valueValueFunc(sqlite3_context *pCtx){
name ## InverseFunc, #name \
}
#define WINDOWFUNCF(name,nArg,extra) { \
nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \
name ## InverseFunc, #name \
}
/*
** Register those built-in window functions that are not also aggregates.
*/
@@ -275,6 +333,7 @@ void sqlite3WindowFunctions(void){
WINDOWFUNC(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
WINDOWFUNC(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
WINDOWFUNC(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
WINDOWFUNCF(last_value, 1, 0),
WINDOWFUNC(nth_value, 2, 0),
};
sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));