From: dan Date: Thu, 14 Jun 2018 14:27:05 +0000 (+0000) Subject: Improve comments and code legibility in new file window.c. X-Git-Tag: version-3.25.0~178^2~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=54a9ab3f131cf1b309b60d74ecfa2a0cc960321a;p=thirdparty%2Fsqlite.git Improve comments and code legibility in new file window.c. FossilOrigin-Name: bb915854d435bdd78f141d70e23527e97922ec176acd3ed8060c78dffc96bab8 --- diff --git a/manifest b/manifest index dadf035fa0..9c3a7a405a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblems\swith\s"RANGE\sBETWEEN\sCURRENT\sROW\sAND\sUNBOUNDED\sFOLLOWING"\swindow\nframes. -D 2018-06-13T20:29:38.362 +C Improve\scomments\sand\scode\slegibility\sin\snew\sfile\swindow.c. +D 2018-06-14T14:27:05.155 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 498b77b89a8cb42f2ee20fcd6317f279a45c0d6ff40d27825f94b69884c09bbe @@ -583,7 +583,7 @@ F src/where.c fe1a6f97c12cc9472ccce86166ba3f827cf61d6ae770c036a6396b63863baac4 F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4 F src/wherecode.c 3317f2b083a66d3e65a03edf316ade4ccb0a99c9956273282ebb579b95d4ba96 F src/whereexpr.c 6f022d6cc9daf56495f191b199352f783aff5cf268ba136b4d8cea3fb62d8c7d -F src/window.c 4a26ff629a2207fbb766b64eec5de56a642db2ee1a58ca7f3d9bf7241ca2265d +F src/window.c 0a6b366a3301c68172fcdbebd5b9ddf0466cdc6533ff92ad859b4acd06aaa29b F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1740,7 +1740,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6413e38a174044c28fa9b8b937e6c972d144547a246e6f2882e782538300d042 -R 30609a9614da284dabc36852804237fe +P c34f31dbd79891249ee9485e91f6ea558ee1db62e04fb0fff2c051612b8fa5e7 +R 250d0aa9c508f0b3712323b0e393b7d6 U dan -Z 71b05cd13cd6b1243eec19b7dd0b41c2 +Z 8f2ba813d9d3711cc22cf41096ce6e24 diff --git a/manifest.uuid b/manifest.uuid index 8d9afc357c..594644608c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c34f31dbd79891249ee9485e91f6ea558ee1db62e04fb0fff2c051612b8fa5e7 \ No newline at end of file +bb915854d435bdd78f141d70e23527e97922ec176acd3ed8060c78dffc96bab8 \ No newline at end of file diff --git a/src/window.c b/src/window.c index 395d6733be..459d05e29e 100644 --- a/src/window.c +++ b/src/window.c @@ -1236,6 +1236,12 @@ static void windowReturnRows( sqlite3VdbeJumpHere(v, addr+1); /* The OP_Goto */ } +/* +** Generate code to set the accumulator register for each window function +** in the linked list passed as the second argument to NULL. And perform +** any equivalent initialization required by any built-in window functions +** in the list. +*/ static int windowInitAccum(Parse *pParse, Window *pMWin){ Vdbe *v = sqlite3GetVdbe(pParse); int regArg; @@ -1258,15 +1264,11 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){ /* -** ROWS BETWEEN PRECEDING AND FOLLOWING -** ---------------------------------------------------- +** This function does the work of sqlite3WindowCodeStep() for all "ROWS" +** window frame types except for "BETWEEN UNBOUNDED PRECEDING AND CURRENT +** ROW". Pseudo-code for each follows. ** -** Pseudo-code for the implementation of this window frame type is as -** follows. sqlite3WhereBegin() has already been called to generate the -** top of the main loop when this function is called. -** -** Each time the sub-routine at addrGosub is invoked, a single output -** row is generated based on the current row indicated by Window.iEphCsr. +** ROWS BETWEEN PRECEDING AND FOLLOWING ** ** ... ** if( new partition ){ @@ -1551,6 +1553,16 @@ static void windowCodeRowExprStep( } /* +** This function does the work of sqlite3WindowCodeStep() for cases that +** would normally be handled by windowCodeDefaultStep() when there are +** one or more built-in window-functions that require the entire partition +** to be cached in a temp table before any rows can be returned. Additionally. +** "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" is always handled by +** this function. +** +** Pseudo-code corresponding to the VM code generated by this function +** for each type of window follows. +** ** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ** ** flush_partition: @@ -1581,8 +1593,64 @@ static void windowCodeRowExprStep( ** Return ** ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING +** +** As above, except that the "if( new peer )" branch is always taken. +** ** RANGE BETWEEN CURRENT ROW AND CURRENT ROW +** +** As above, except that each of the for() loops becomes: +** +** for(i=0; i csrLead) +** } +** foreach row (csrLead) { +** AggStep (csrLead) +** } +** foreach row (iEphCsr) { +** Gosub addrGosub +** } +** +** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +** +** flush_partition: +** Once { +** OpenDup (iEphCsr -> csrLead) +** } +** foreach row (csrLead){ +** AggStep (csrLead) +** } +** Rewind (csrLead) +** Integer ctr 0 +** foreach row (csrLead){ +** if( new peer ){ +** AggFinal (xValue) +** for(i=0; ipPartition; ExprList *pOrderBy = pMWin->pOrderBy; - int nPeer = pOrderBy->nExpr; + int nPeer = pOrderBy ? pOrderBy->nExpr : 0; int regNewPeer; int addrGoto; /* Address of Goto used to jump flush_par.. */ @@ -1610,8 +1678,9 @@ static void windowCodeCacheStep( int regArg; /* Register array to martial function args */ int regSize; int nArg; - int bReverse; int lblEmpty; + int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT + && pMWin->eEnd==TK_UNBOUNDED; assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) @@ -1620,7 +1689,6 @@ static void windowCodeCacheStep( ); lblEmpty = sqlite3VdbeMakeLabel(v); - bReverse = (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED); regNewPeer = pParse->nMem+1; pParse->nMem += nPeer; @@ -1878,34 +1946,60 @@ void sqlite3WindowCodeStep( int addrGosub /* OP_Gosub here to return each row */ ){ Window *pMWin = p->pWin; - ExprList *pOrderBy = pMWin->pOrderBy; - /* Call windowCodeRowExprStep() for all "ROWS" window modes except: + /* There are three different functions that may be used to do the work + ** of this one, depending on the window frame and the specific built-in + ** window functions used (if any). + ** + ** windowCodeRowExprStep() handles all "ROWS" window frames, except for: ** ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ** + ** The exception is because windowCodeRowExprStep() implements all window + ** frame types by caching the entire partition in a temp table, and + ** "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" is easy enough to + ** implement without such a cache. + ** + ** windowCodeCacheStep() is used for: + ** + ** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ** + ** It is also used for anything not handled by windowCodeRowExprStep() + ** that invokes a built-in window function that requires the entire + ** partition to be cached in a temp table before any rows are returned + ** (e.g. nth_value() or percent_rank()). + ** + ** Finally, assuming there is no built-in window function that requires + ** the partition to be cached, windowCodeDefaultStep() is used for: + ** + ** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ** RANGE BETWEEN CURRENT ROW AND CURRENT ROW + ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ** + ** windowCodeDefaultStep() is the only one of the three functions that + ** does not cache each partition in a temp table before beginning to + ** return rows. */ - if( (pMWin->eType==TK_ROWS - && (pMWin->eStart!=TK_UNBOUNDED || pMWin->eEnd!=TK_CURRENT || !pOrderBy)) + if( pMWin->eType==TK_ROWS + && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy) ){ windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub); }else{ Window *pWin; - int bCache = 0; + int bCache = 0; /* True to use CacheStep() */ - if( pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && pOrderBy ){ + if( pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED ){ bCache = 1; }else{ - /* Call windowCodeCacheStep() if there is a window function that requires - ** that the entire partition be cached in a temp table before any rows - ** are returned. */ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ FuncDef *pFunc = pWin->pFunc; if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE) - || (pFunc->xSFunc==nth_valueStepFunc) - || (pFunc->xSFunc==first_valueStepFunc) - || (pFunc->xSFunc==leadStepFunc) - || (pFunc->xSFunc==lagStepFunc) - ){ + || (pFunc->xSFunc==nth_valueStepFunc) + || (pFunc->xSFunc==first_valueStepFunc) + || (pFunc->xSFunc==leadStepFunc) + || (pFunc->xSFunc==lagStepFunc) + ){ bCache = 1; break; }