diff options
author | dan <dan@noemail.net> | 2018-06-08 11:45:28 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2018-06-08 11:45:28 +0000 |
commit | 03854d2eccd79a5538da1ead29ed52dca85d5332 (patch) | |
tree | 4874a2b59dd43f892d1dba28dd6f037de316dbf3 /src/func.c | |
parent | 07509f8c1edce1378cb71e16b605ece614bd198d (diff) | |
download | sqlite-03854d2eccd79a5538da1ead29ed52dca85d5332.tar.gz sqlite-03854d2eccd79a5538da1ead29ed52dca85d5332.zip |
Fixes to allow group_concat() to be used as a window function.
FossilOrigin-Name: 89bbc9ba8f66853a7530453f146c9df1baacd8558468016cefa7602911f7578a
Diffstat (limited to 'src/func.c')
-rw-r--r-- | src/func.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/src/func.c b/src/func.c index e82652011..62a545e3d 100644 --- a/src/func.c +++ b/src/func.c @@ -1665,7 +1665,7 @@ static void groupConcatStep( if( pAccum ){ sqlite3 *db = sqlite3_context_db_handle(context); - int firstTerm = pAccum->mxAlloc==0; + int firstTerm = pAccum->nChar==0; pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; if( !firstTerm ){ if( argc==2 ){ @@ -1682,6 +1682,29 @@ static void groupConcatStep( if( zVal ) sqlite3_str_append(pAccum, zVal, nVal); } } +static void groupConcatInverse( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int n; + assert( argc==1 || argc==2 ); + StrAccum *pAccum; + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum)); + if( pAccum ){ + n = sqlite3_value_bytes(argv[0]); + if( argc==2 ){ + n += sqlite3_value_bytes(argv[1]); + } + if( n>=pAccum->nChar ){ + pAccum->nChar = 0; + }else{ + pAccum->nChar -= n; + memmove(pAccum->zText, &pAccum->zText[n], pAccum->nChar); + } + } +} static void groupConcatFinalize(sqlite3_context *context){ StrAccum *pAccum; pAccum = sqlite3_aggregate_context(context, 0); @@ -1894,16 +1917,15 @@ void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), FUNCTION(substr, 2, 0, 0, substrFunc ), FUNCTION(substr, 3, 0, 0, substrFunc ), - WAGGREGATE(sum, 1, 0, 0, sumStep, sumInverse, sumFinalize), - WAGGREGATE(total, 1, 0, 0, sumStep, sumInverse, totalFinalize ), - WAGGREGATE(avg, 1, 0, 0, sumStep, sumInverse, avgFinalize ), - AGGREGATE2(count, 0, 0, 0, countStep, countFinalize, - SQLITE_FUNC_COUNT ), - WAGGREGATE(count, 1, 0, 0, countStep, 0, countFinalize ), - AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize, - groupConcatValue), - AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize, - groupConcatValue), + WAGGREGATE(sum, 1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse), + WAGGREGATE(total, 1,0,0, sumStep, totalFinalize, totalFinalize, sumInverse), + WAGGREGATE(avg, 1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse), + AGGREGATE2(count, 0,0,0, countStep, countFinalize, SQLITE_FUNC_COUNT ), + WAGGREGATE(count, 1,0,0, countStep, countFinalize, 0, 0 ), + WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep, + groupConcatFinalize, groupConcatValue, groupConcatInverse), + WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, + groupConcatFinalize, groupConcatValue, groupConcatInverse), LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), #ifdef SQLITE_CASE_SENSITIVE_LIKE |