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

Improve comments and code legibility in new file window.c.

FossilOrigin-Name: bb915854d435bdd78f141d70e23527e97922ec176acd3ed8060c78dffc96bab8
This commit is contained in:
dan
2018-06-14 14:27:05 +00:00
parent 13078caac4
commit 54a9ab3f13
3 changed files with 127 additions and 33 deletions

View File

@@ -1,5 +1,5 @@
C Fix\sproblems\swith\s"RANGE\sBETWEEN\sCURRENT\sROW\sAND\sUNBOUNDED\sFOLLOWING"\swindow\nframes. C Improve\scomments\sand\scode\slegibility\sin\snew\sfile\swindow.c.
D 2018-06-13T20:29:38.362 D 2018-06-14T14:27:05.155
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 498b77b89a8cb42f2ee20fcd6317f279a45c0d6ff40d27825f94b69884c09bbe F Makefile.in 498b77b89a8cb42f2ee20fcd6317f279a45c0d6ff40d27825f94b69884c09bbe
@@ -583,7 +583,7 @@ F src/where.c fe1a6f97c12cc9472ccce86166ba3f827cf61d6ae770c036a6396b63863baac4
F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4 F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4
F src/wherecode.c 3317f2b083a66d3e65a03edf316ade4ccb0a99c9956273282ebb579b95d4ba96 F src/wherecode.c 3317f2b083a66d3e65a03edf316ade4ccb0a99c9956273282ebb579b95d4ba96
F src/whereexpr.c 6f022d6cc9daf56495f191b199352f783aff5cf268ba136b4d8cea3fb62d8c7d F src/whereexpr.c 6f022d6cc9daf56495f191b199352f783aff5cf268ba136b4d8cea3fb62d8c7d
F src/window.c 4a26ff629a2207fbb766b64eec5de56a642db2ee1a58ca7f3d9bf7241ca2265d F src/window.c 0a6b366a3301c68172fcdbebd5b9ddf0466cdc6533ff92ad859b4acd06aaa29b
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1740,7 +1740,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 6413e38a174044c28fa9b8b937e6c972d144547a246e6f2882e782538300d042 P c34f31dbd79891249ee9485e91f6ea558ee1db62e04fb0fff2c051612b8fa5e7
R 30609a9614da284dabc36852804237fe R 250d0aa9c508f0b3712323b0e393b7d6
U dan U dan
Z 71b05cd13cd6b1243eec19b7dd0b41c2 Z 8f2ba813d9d3711cc22cf41096ce6e24

View File

@@ -1 +1 @@
c34f31dbd79891249ee9485e91f6ea558ee1db62e04fb0fff2c051612b8fa5e7 bb915854d435bdd78f141d70e23527e97922ec176acd3ed8060c78dffc96bab8

View File

@@ -1236,6 +1236,12 @@ static void windowReturnRows(
sqlite3VdbeJumpHere(v, addr+1); /* The OP_Goto */ 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){ static int windowInitAccum(Parse *pParse, Window *pMWin){
Vdbe *v = sqlite3GetVdbe(pParse); Vdbe *v = sqlite3GetVdbe(pParse);
int regArg; int regArg;
@@ -1258,15 +1264,11 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
/* /*
** 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.
**
** ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING ** ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
** ----------------------------------------------------
**
** 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.
** **
** ... ** ...
** if( new partition ){ ** 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 ** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
** **
** flush_partition: ** flush_partition:
@@ -1581,8 +1593,64 @@ static void windowCodeRowExprStep(
** Return ** Return
** **
** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ** 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 ** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
**
** As above, except that each of the for() loops becomes:
**
** for(i=0; i<ctr; i++){
** Gosub addrGosub
** AggStep (xInverse, iEphCsr)
** Next iEphCsr
** }
**
** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
**
** flush_partition:
** Once {
** OpenDup (iEphCsr -> 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; i<ctr; i++){
** Gosub addrGosub
** AggStep (xInverse, iEphCsr)
** Next iEphCsr
** }
** Integer ctr 0
** }
** Incr ctr
** }
**
** AggFinal (xFinalize)
** for(i=0; i<ctr; i++){
** Gosub addrGosub
** Next iEphCsr
** }
**
** ResetSorter (csr)
** Return
*/ */
static void windowCodeCacheStep( static void windowCodeCacheStep(
Parse *pParse, Parse *pParse,
@@ -1598,7 +1666,7 @@ static void windowCodeCacheStep(
int addr; int addr;
ExprList *pPart = pMWin->pPartition; ExprList *pPart = pMWin->pPartition;
ExprList *pOrderBy = pMWin->pOrderBy; ExprList *pOrderBy = pMWin->pOrderBy;
int nPeer = pOrderBy->nExpr; int nPeer = pOrderBy ? pOrderBy->nExpr : 0;
int regNewPeer; int regNewPeer;
int addrGoto; /* Address of Goto used to jump flush_par.. */ 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 regArg; /* Register array to martial function args */
int regSize; int regSize;
int nArg; int nArg;
int bReverse;
int lblEmpty; int lblEmpty;
int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT
&& pMWin->eEnd==TK_UNBOUNDED;
assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
|| (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
@@ -1620,7 +1689,6 @@ static void windowCodeCacheStep(
); );
lblEmpty = sqlite3VdbeMakeLabel(v); lblEmpty = sqlite3VdbeMakeLabel(v);
bReverse = (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED);
regNewPeer = pParse->nMem+1; regNewPeer = pParse->nMem+1;
pParse->nMem += nPeer; pParse->nMem += nPeer;
@@ -1878,34 +1946,60 @@ void sqlite3WindowCodeStep(
int addrGosub /* OP_Gosub here to return each row */ int addrGosub /* OP_Gosub here to return each row */
){ ){
Window *pMWin = p->pWin; 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 ** 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 if( pMWin->eType==TK_ROWS
&& (pMWin->eStart!=TK_UNBOUNDED || pMWin->eEnd!=TK_CURRENT || !pOrderBy)) && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy)
){ ){
windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub); windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub);
}else{ }else{
Window *pWin; 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; bCache = 1;
}else{ }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){ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
FuncDef *pFunc = pWin->pFunc; FuncDef *pFunc = pWin->pFunc;
if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE) if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
|| (pFunc->xSFunc==nth_valueStepFunc) || (pFunc->xSFunc==nth_valueStepFunc)
|| (pFunc->xSFunc==first_valueStepFunc) || (pFunc->xSFunc==first_valueStepFunc)
|| (pFunc->xSFunc==leadStepFunc) || (pFunc->xSFunc==leadStepFunc)
|| (pFunc->xSFunc==lagStepFunc) || (pFunc->xSFunc==lagStepFunc)
){ ){
bCache = 1; bCache = 1;
break; break;
} }