diff options
author | dan <dan@noemail.net> | 2018-07-02 12:07:32 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2018-07-02 12:07:32 +0000 |
commit | 7262ca94cb4308c74a504e949cdb6e3e5cc61610 (patch) | |
tree | 19fd1e9b5ceafeb0b29fba7517cc751d9b87763c /src/func.c | |
parent | 9f607e9c231dafcd64602fd9deee48a37ff27c07 (diff) | |
download | sqlite-7262ca94cb4308c74a504e949cdb6e3e5cc61610.tar.gz sqlite-7262ca94cb4308c74a504e949cdb6e3e5cc61610.zip |
Fix a segfault caused by invoking a regular aggregate as a window-function.
And some problems with count(*) when used as a window-function.
FossilOrigin-Name: 4f3c8a82fd1c5b14d84f2301e34cfc8d52fe4b3a60840c39e895c11f2da529d9
Diffstat (limited to 'src/func.c')
-rw-r--r-- | src/func.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/src/func.c b/src/func.c index c5dd6a58e..ff7c3049f 100644 --- a/src/func.c +++ b/src/func.c @@ -1572,6 +1572,9 @@ static void totalFinalize(sqlite3_context *context){ typedef struct CountCtx CountCtx; struct CountCtx { i64 n; +#ifdef SQLITE_DEBUG + int bInverse; /* True if xInverse() ever called */ +#endif }; /* @@ -1589,7 +1592,7 @@ static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ ** sure it still operates correctly, verify that its count agrees with our ** internal count when using count(*) and when the total count can be ** expressed as a 32-bit integer. */ - assert( argc==1 || p==0 || p->n>0x7fffffff + assert( argc==1 || p==0 || p->n>0x7fffffff || p->bInverse || p->n==sqlite3_aggregate_count(context) ); #endif } @@ -1598,6 +1601,18 @@ static void countFinalize(sqlite3_context *context){ p = sqlite3_aggregate_context(context, 0); sqlite3_result_int64(context, p ? p->n : 0); } +#ifndef SQLITE_OMIT_WINDOWFUNC +static void countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv){ + CountCtx *p; + p = sqlite3_aggregate_context(ctx, sizeof(*p)); + if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){ + p->n--; +#ifdef SQLITE_DEBUG + p->bInverse = 1; +#endif + } +} +#endif /* ** Routines to implement min() and max() aggregate functions. @@ -1943,8 +1958,10 @@ void sqlite3RegisterBuiltinFunctions(void){ WAGGREGATE(sum, 1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0), WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0), WAGGREGATE(avg, 1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0), - AGGREGATE2(count, 0,0,0, countStep, countFinalize, SQLITE_FUNC_COUNT ), - WAGGREGATE(count, 1,0,0, countStep, countFinalize, 0, 0, 0 ), + WAGGREGATE(count, 0,0,0, countStep, + countFinalize, countFinalize, countInverse, SQLITE_FUNC_COUNT ), + WAGGREGATE(count, 1,0,0, countStep, + countFinalize, countFinalize, countInverse, 0 ), WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, |