1
0
mirror of https://github.com/sqlite/sqlite.git synced 2026-01-06 08:01:16 +03:00

Add tests to improve coverage of code in window.c. Fix a problem with "SELECT

row_number() OVER ()".

FossilOrigin-Name: f41b6b7317e2b5ac5721a3adff49f298ded29f9e0f887af98faeb0cb7e865ab6
This commit is contained in:
dan
2018-06-20 09:23:49 +00:00
parent 85b9a1c2fb
commit 9c27758eb4
8 changed files with 331 additions and 24 deletions

View File

@@ -172,7 +172,10 @@ struct CallCount {
};
/*
** Implementation of built-in window function dense_rank().
** Implementation of built-in window function dense_rank(). Assumes that
** the window frame has been set to:
**
** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
*/
static void dense_rankStepFunc(
sqlite3_context *pCtx,
@@ -202,7 +205,10 @@ static void dense_rankValueFunc(sqlite3_context *pCtx){
}
/*
** Implementation of built-in window function rank().
** Implementation of built-in window function rank(). Assumes that
** the window frame has been set to:
**
** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
*/
static void rankStepFunc(
sqlite3_context *pCtx,
@@ -234,7 +240,10 @@ static void rankValueFunc(sqlite3_context *pCtx){
}
/*
** Implementation of built-in window function percent_rank().
** Implementation of built-in window function percent_rank(). Assumes that
** the window frame has been set to:
**
** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
*/
static void percent_rankStepFunc(
sqlite3_context *pCtx,
@@ -244,8 +253,9 @@ static void percent_rankStepFunc(
struct CallCount *p;
assert( nArg==1 );
assert( sqlite3VdbeAssertAggContext(pCtx) );
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
if( ALWAYS(p) ){
if( p->nTotal==0 ){
p->nTotal = sqlite3_value_int64(apArg[0]);
}
@@ -275,6 +285,12 @@ static void percent_rankValueFunc(sqlite3_context *pCtx){
}
}
/*
** Implementation of built-in window function cume_dist(). Assumes that
** the window frame has been set to:
**
** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
*/
static void cume_distStepFunc(
sqlite3_context *pCtx,
int nArg,
@@ -283,8 +299,9 @@ static void cume_distStepFunc(
struct CallCount *p;
assert( nArg==1 );
assert( sqlite3VdbeAssertAggContext(pCtx) );
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
if( ALWAYS(p) ){
if( p->nTotal==0 ){
p->nTotal = sqlite3_value_int64(apArg[0]);
}
@@ -328,8 +345,9 @@ static void ntileStepFunc(
){
struct NtileCtx *p;
assert( nArg==2 );
assert( sqlite3VdbeAssertAggContext(pCtx) );
p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
if( ALWAYS(p) ){
if( p->nTotal==0 ){
p->nParam = sqlite3_value_int64(apArg[0]);
p->nTotal = sqlite3_value_int64(apArg[1]);
@@ -388,7 +406,7 @@ static void last_valueStepFunc(
sqlite3_value **apArg
){
struct LastValueCtx *p;
p = (struct LastValueCtx *)sqlite3_aggregate_context(pCtx, sizeof(*p));
p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
sqlite3_value_free(p->pVal);
p->pVal = sqlite3_value_dup(apArg[0]);
@@ -405,8 +423,8 @@ static void last_valueInvFunc(
sqlite3_value **apArg
){
struct LastValueCtx *p;
p = (struct LastValueCtx *)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( ALWAYS(p) ){
p->nVal--;
if( p->nVal==0 ){
sqlite3_value_free(p->pVal);
@@ -416,14 +434,14 @@ static void last_valueInvFunc(
}
static void last_valueValueFunc(sqlite3_context *pCtx){
struct LastValueCtx *p;
p = (struct LastValueCtx *)sqlite3_aggregate_context(pCtx, sizeof(*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));
p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p && p->pVal ){
sqlite3_result_value(pCtx, p->pVal);
sqlite3_value_free(p->pVal);
@@ -737,6 +755,18 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
}
/* If there is no ORDER BY or PARTITION BY clause, and the window
** function accepts zero arguments, and there are no other columns
** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible
** that pSublist is still NULL here. Add a constant expression here to
** keep everything legal in this case.
*/
if( pSublist==0 ){
pSublist = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0)
);
}
pSub = sqlite3SelectNew(
pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
);