From 54975cdff9d5e7e4490fbf6012d82143136b1e0b Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 7 Mar 2019 20:47:46 +0000 Subject: [PATCH] Fix other "ROWS BETWEEN" cases on this branch. FossilOrigin-Name: a5f68f66472610b5beb4fe28669fbbfe83a32742be73cecad9b2ae28f8a17b30 --- manifest | 12 +- manifest.uuid | 2 +- src/window.c | 402 ++++++++------------------------------------------ 3 files changed, 67 insertions(+), 349 deletions(-) diff --git a/manifest b/manifest index 20f066a065..2d96c2ceb1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\snew\swindow\sfunctions\sfunction\sso\sthat\scursors\sare\sstepped\simmediately\safter\seach\soperation,\sinstead\sof\simmediately\sbefore. -D 2019-03-07T19:26:17.600 +C Fix\sother\s"ROWS\sBETWEEN"\scases\son\sthis\sbranch. +D 2019-03-07T20:47:46.020 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 1ad7263f38329c0ecea543c80f30af839ee714ea77fc391bf1a3fbb919a5b6b5 @@ -604,7 +604,7 @@ F src/where.c 8a207cb2ca6b99e1edb1e4bbff9b0504385a759cbf66180d1deb34d80ca4b799 F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88 F src/wherecode.c ce7b21e1be2b981d62683fc59c4ca73a04a7ff2f1ebec23d41baf2da2349afd6 F src/whereexpr.c 36b47f7261d6b6f1a72d774c113b74beddf6745aba1018e64b196e29db233442 -F src/window.c 00962a6b3434fd44a1c6e0446faaa27a0715b9234d9467e2b2f0516cc22d3ced +F src/window.c fd7eae2b523f47c114f689f213407c218b737b45a29ed0a5b8ad6e3377f49594 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1809,7 +1809,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 45cbd3b4498cea8856f189e9d0a192556d4f15212055b8328a1beca6083fc47a -R 8a700321d1f21bd34463dfe3468362b4 +P 093d2b25f1b656bba57d665aac68109436861b157a5769432b612176dae3f6eb +R bc65bb166c813f4264e0cac9b9ddcfde U dan -Z 66270c88444ad4957a492203232c2b1a +Z 787ed5434e794ce48cb312b7f3a2a9d5 diff --git a/manifest.uuid b/manifest.uuid index 9b064598e1..eac4a67e39 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -093d2b25f1b656bba57d665aac68109436861b157a5769432b612176dae3f6eb \ No newline at end of file +a5f68f66472610b5beb4fe28669fbbfe83a32742be73cecad9b2ae28f8a17b30 \ No newline at end of file diff --git a/src/window.c b/src/window.c index 24f7451548..6faa464d2a 100644 --- a/src/window.c +++ b/src/window.c @@ -1542,307 +1542,6 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){ return regArg; } - -/* -** 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 PRECEDING AND FOLLOWING -** -** ... -** if( new partition ){ -** Gosub flush_partition -** } -** Insert (record in eph-table) -** sqlite3WhereEnd() -** Gosub flush_partition -** -** flush_partition: -** Once { -** OpenDup (iEphCsr -> csrStart) -** OpenDup (iEphCsr -> csrEnd) -** } -** regStart = // PRECEDING expression -** regEnd = // FOLLOWING expression -** if( regStart<0 || regEnd<0 ){ error! } -** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done -** Next(csrEnd) // if EOF skip Aggstep -** Aggstep (csrEnd) -** if( (regEnd--)<=0 ){ -** AggFinal (xValue) -** Gosub addrGosub -** Next(csr) // if EOF goto flush_partition_done -** if( (regStart--)<=0 ){ -** AggInverse (csrStart) -** Next(csrStart) -** } -** } -** flush_partition_done: -** ResetSorter (csr) -** Return -** -** ROWS BETWEEN PRECEDING AND CURRENT ROW -** ROWS BETWEEN CURRENT ROW AND FOLLOWING -** ROWS BETWEEN UNBOUNDED PRECEDING AND FOLLOWING -** -** These are similar to the above. For "CURRENT ROW", intialize the -** register to 0. For "UNBOUNDED PRECEDING" to infinity. -** -** ROWS BETWEEN PRECEDING AND UNBOUNDED FOLLOWING -** ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING -** -** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done -** while( 1 ){ -** Next(csrEnd) // Exit while(1) at EOF -** Aggstep (csrEnd) -** } -** while( 1 ){ -** AggFinal (xValue) -** Gosub addrGosub -** Next(csr) // if EOF goto flush_partition_done -** if( (regStart--)<=0 ){ -** AggInverse (csrStart) -** Next(csrStart) -** } -** } -** -** For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if() -** condition is always true (as if regStart were initialized to 0). -** -** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING -** -** This is the only RANGE case handled by this routine. It modifies the -** second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to -** be: -** -** while( 1 ){ -** AggFinal (xValue) -** while( 1 ){ -** regPeer++ -** Gosub addrGosub -** Next(csr) // if EOF goto flush_partition_done -** if( new peer ) break; -** } -** while( (regPeer--)>0 ){ -** AggInverse (csrStart) -** Next(csrStart) -** } -** } -** -** ROWS BETWEEN FOLLOWING AND FOLLOWING -** -** regEnd = regEnd - regStart -** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done -** Aggstep (csrEnd) -** Next(csrEnd) // if EOF fall-through -** if( (regEnd--)<=0 ){ -** if( (regStart--)<=0 ){ -** AggFinal (xValue) -** Gosub addrGosub -** Next(csr) // if EOF goto flush_partition_done -** } -** AggInverse (csrStart) -** Next (csrStart) -** } -** -** ROWS BETWEEN PRECEDING AND PRECEDING -** -** Replace the bit after "Rewind" in the above with: -** -** if( (regEnd--)<=0 ){ -** AggStep (csrEnd) -** Next (csrEnd) -** } -** AggFinal (xValue) -** Gosub addrGosub -** Next(csr) // if EOF goto flush_partition_done -** if( (regStart--)<=0 ){ -** AggInverse (csr2) -** Next (csr2) -** } -** -*/ -static void windowCodeRowExprStep( - Parse *pParse, - Select *p, - WhereInfo *pWInfo, - int regGosub, - int addrGosub -){ - Window *pMWin = p->pWin; - Vdbe *v = sqlite3GetVdbe(pParse); - int regFlushPart; /* Register for "Gosub flush_partition" */ - int lblFlushPart; /* Label for "Gosub flush_partition" */ - int lblFlushDone; /* Label for "Gosub flush_partition_done" */ - - int regArg; - int addr; - int csrStart = pParse->nTab++; - int csrEnd = pParse->nTab++; - int regStart; /* Value of PRECEDING */ - int regEnd; /* Value of FOLLOWING */ - int addrGoto; - int addrTop; - int addrIfPos1 = 0; - int addrIfPos2 = 0; - int regSize = 0; - - assert( pMWin->eStart==TK_PRECEDING - || pMWin->eStart==TK_CURRENT - || pMWin->eStart==TK_FOLLOWING - || pMWin->eStart==TK_UNBOUNDED - ); - assert( pMWin->eEnd==TK_FOLLOWING - || pMWin->eEnd==TK_CURRENT - || pMWin->eEnd==TK_UNBOUNDED - || pMWin->eEnd==TK_PRECEDING - ); - - /* Allocate register and label for the "flush_partition" sub-routine. */ - regFlushPart = ++pParse->nMem; - lblFlushPart = sqlite3VdbeMakeLabel(pParse); - lblFlushDone = sqlite3VdbeMakeLabel(pParse); - - regStart = ++pParse->nMem; - regEnd = ++pParse->nMem; - - windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, ®Size); - - addrGoto = sqlite3VdbeAddOp0(v, OP_Goto); - - /* Start of "flush_partition" */ - sqlite3VdbeResolveLabel(v, lblFlushPart); - sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3); - VdbeCoverage(v); - VdbeComment((v, "Flush_partition subroutine")); - sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr); - sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr); - - /* If either regStart or regEnd are not non-negative integers, throw - ** an exception. */ - if( pMWin->pStart ){ - sqlite3ExprCode(pParse, pMWin->pStart, regStart); - windowCheckIntValue(pParse, regStart, 0); - } - if( pMWin->pEnd ){ - sqlite3ExprCode(pParse, pMWin->pEnd, regEnd); - windowCheckIntValue(pParse, regEnd, 1); - } - - /* If this is "ROWS FOLLOWING AND ROWS FOLLOWING", do: - ** - ** if( regEndpEnd && pMWin->eStart==TK_FOLLOWING ){ - assert( pMWin->pStart!=0 ); - assert( pMWin->eEnd==TK_FOLLOWING ); - sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd); - VdbeCoverageNeverNull(v); - sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart); - sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd); - } - - if( pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){ - assert( pMWin->pEnd!=0 ); - assert( pMWin->eStart==TK_PRECEDING ); - sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd); - VdbeCoverageNeverNull(v); - sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart); - sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd); - } - - /* Initialize the accumulator register for each window function to NULL */ - regArg = windowInitAccum(pParse, pMWin); - - sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone); - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone); - VdbeCoverageNeverTaken(v); - sqlite3VdbeChangeP5(v, 1); - sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone); - VdbeCoverageNeverTaken(v); - sqlite3VdbeChangeP5(v, 1); - - /* Invoke AggStep function for each window function using the row that - ** csrEnd currently points to. Or, if csrEnd is already at EOF, - ** do nothing. */ - addrTop = sqlite3VdbeCurrentAddr(v); - if( pMWin->eEnd==TK_PRECEDING ){ - addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1); - VdbeCoverage(v); - } - sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2); - VdbeCoverage(v); - addr = sqlite3VdbeAddOp0(v, OP_Goto); - windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize); - if( pMWin->eEnd==TK_UNBOUNDED ){ - sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); - sqlite3VdbeJumpHere(v, addr); - addrTop = sqlite3VdbeCurrentAddr(v); - }else{ - sqlite3VdbeJumpHere(v, addr); - if( pMWin->eEnd==TK_PRECEDING ){ - sqlite3VdbeJumpHere(v, addrIfPos1); - } - } - - if( pMWin->eEnd==TK_FOLLOWING ){ - addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1); - VdbeCoverage(v); - } - if( pMWin->eStart==TK_FOLLOWING ){ - addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1); - VdbeCoverage(v); - } - windowAggFinal(pParse, pMWin, 0); - windowReturnOneRow(pParse, pMWin, regGosub, addrGosub); - sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2); - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone); - if( pMWin->eStart==TK_FOLLOWING ){ - sqlite3VdbeJumpHere(v, addrIfPos2); - } - - if( pMWin->eStart==TK_CURRENT - || pMWin->eStart==TK_PRECEDING - || pMWin->eStart==TK_FOLLOWING - ){ - int lblSkipInverse = sqlite3VdbeMakeLabel(pParse);; - if( pMWin->eStart==TK_PRECEDING ){ - sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1); - VdbeCoverage(v); - } - if( pMWin->eStart==TK_FOLLOWING ){ - sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2); - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Goto, 0, lblSkipInverse); - }else{ - sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1); - VdbeCoverageAlwaysTaken(v); - } - windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize); - sqlite3VdbeResolveLabel(v, lblSkipInverse); - } - if( pMWin->eEnd==TK_FOLLOWING ){ - sqlite3VdbeJumpHere(v, addrIfPos1); - } - sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); - - /* flush_partition_done: */ - sqlite3VdbeResolveLabel(v, lblFlushDone); - sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr); - sqlite3VdbeAddOp1(v, OP_Return, regFlushPart); - VdbeComment((v, "end flush_partition subroutine")); - - /* Jump to here to skip over flush_partition */ - sqlite3VdbeJumpHere(v, addrGoto); -} - /* ** Return true if the entire partition should be cached in the ephemeral ** table before processing any rows. @@ -1884,26 +1583,34 @@ static int windowCodeOp( int regCountdown, int jumpOnEof ){ + Window *pMWin = p->pMWin; int ret = 0; Vdbe *v = p->pVdbe; int addrIf = 0; + /* Special case - WINDOW_AGGINVERSE is always a no-op if the frame + ** starts with UNBOUNDED PRECEDING. */ + if( op==WINDOW_AGGINVERSE && pMWin->eStart==TK_UNBOUNDED ){ + assert( regCountdown==0 && jumpOnEof==0 ); + return 0; + } + if( regCountdown>0 ){ addrIf = sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, 0, 1); } switch( op ){ case WINDOW_RETURN_ROW: - windowAggFinal(p->pParse, p->pMWin, 0); - windowReturnOneRow(p->pParse, p->pMWin, p->regGosub, p->addrGosub); + windowAggFinal(p->pParse, pMWin, 0); + windowReturnOneRow(p->pParse, pMWin, p->regGosub, p->addrGosub); break; case WINDOW_AGGINVERSE: - windowAggStep(p->pParse, p->pMWin, csr, 1, p->regArg, p->pMWin->regSize); + windowAggStep(p->pParse, pMWin, csr, 1, p->regArg, pMWin->regSize); break; case WINDOW_AGGSTEP: - windowAggStep(p->pParse, p->pMWin, csr, 0, p->regArg, p->pMWin->regSize); + windowAggStep(p->pParse, pMWin, csr, 0, p->regArg, pMWin->regSize); break; } @@ -2006,8 +1713,6 @@ static void windowCodeStep( int csrStart = csrCurrent+2; int csrEnd = csrCurrent+3; - int regStart; /* Value of PRECEDING */ - int regEnd; /* Value of FOLLOWING */ int iSubCsr = p->pSrc->a[0].iCursor; /* Cursor of sub-select */ int nSub = p->pSrc->a[0].pTab->nCol; /* Number of cols returned by sub */ @@ -2025,6 +1730,9 @@ static void windowCodeStep( int bCache = windowCachePartition(pMWin); + int regStart = 0; /* Value of PRECEDING */ + int regEnd = 0; /* Value of FOLLOWING */ + int reg = pParse->nMem+1; int regRecord = reg+nSub; int regRowid = regRecord+1; @@ -2040,8 +1748,13 @@ static void windowCodeStep( pParse->nMem += 1 + nSub + 1; regFlushPart = ++pParse->nMem; - regStart = ++pParse->nMem; - regEnd = ++pParse->nMem; + + if( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ){ + regStart = ++pParse->nMem; + } + if( pMWin->eEnd==TK_PRECEDING || pMWin->eEnd==TK_FOLLOWING ){ + regEnd = ++pParse->nMem; + } assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT @@ -2107,14 +1820,16 @@ static void windowCodeStep( /* This block is run for the first row of each partition */ s.regArg = regArg = windowInitAccum(pParse, pMWin); - sqlite3ExprCode(pParse, pMWin->pStart, regStart); - windowCheckIntValue(pParse, regStart, 0); - sqlite3ExprCode(pParse, pMWin->pEnd, regEnd); - windowCheckIntValue(pParse, regEnd, 1); + if( regStart ){ + sqlite3ExprCode(pParse, pMWin->pStart, regStart); + windowCheckIntValue(pParse, regStart, 0); + } + if( regEnd ){ + sqlite3ExprCode(pParse, pMWin->pEnd, regEnd); + windowCheckIntValue(pParse, regEnd, 1); + } - if( pMWin->eStart==pMWin->eEnd - && pMWin->eStart!=TK_CURRENT && pMWin->eStart!=TK_UNBOUNDED - ){ + if( pMWin->eStart==pMWin->eEnd && regStart && regEnd ){ int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le); int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd); windowAggFinal(pParse, pMWin, 0); @@ -2131,11 +1846,14 @@ static void windowCodeStep( addrShortcut = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, addrGe); } - if( pMWin->eStart==TK_FOLLOWING ){ + if( pMWin->eStart==TK_FOLLOWING && regEnd ){ + assert( pMWin->eEnd==TK_FOLLOWING ); sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart); } - sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, 1); + if( pMWin->eStart!=TK_UNBOUNDED ){ + sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, 1); + } sqlite3VdbeAddOp2(v, OP_Rewind, csrCurrent, 1); sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, 1); @@ -2151,8 +1869,10 @@ static void windowCodeStep( } if( pMWin->eStart==TK_FOLLOWING ){ windowCodeOp(&s, WINDOW_AGGSTEP, csrEnd, 0, 0); - windowCodeOp(&s, WINDOW_RETURN_ROW, csrCurrent, regEnd, 0); - windowCodeOp(&s, WINDOW_AGGINVERSE, csrStart, regStart, 0); + if( pMWin->eEnd!=TK_UNBOUNDED ){ + windowCodeOp(&s, WINDOW_RETURN_ROW, csrCurrent, regEnd, 0); + windowCodeOp(&s, WINDOW_AGGINVERSE, csrStart, regStart, 0); + } }else if( pMWin->eEnd==TK_PRECEDING ){ windowCodeOp(&s, WINDOW_AGGSTEP, csrEnd, regEnd, 0); @@ -2161,10 +1881,12 @@ static void windowCodeStep( }else{ int addr; windowCodeOp(&s, WINDOW_AGGSTEP, csrEnd, 0, 0); - addr = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0, 1); - windowCodeOp(&s, WINDOW_RETURN_ROW, csrCurrent, 0, 0); - windowCodeOp(&s, WINDOW_AGGINVERSE, csrStart, regStart, 0); - sqlite3VdbeJumpHere(v, addr); + if( pMWin->eEnd!=TK_UNBOUNDED ){ + if( regEnd ) addr = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0, 1); + windowCodeOp(&s, WINDOW_RETURN_ROW, csrCurrent, 0, 0); + windowCodeOp(&s, WINDOW_AGGINVERSE, csrStart, regStart, 0); + if( regEnd ) sqlite3VdbeJumpHere(v, addr); + } } VdbeModuleComment((pParse->pVdbe, "End windowCodeStep.SECOND_ROW_CODE")); @@ -2195,9 +1917,16 @@ static void windowCodeStep( int addrBreak2; int addrBreak3; windowCodeOp(&s, WINDOW_AGGSTEP, csrEnd, 0, 0); - addrStart = sqlite3VdbeCurrentAddr(v); - addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, csrCurrent, regEnd, 1); - addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, csrStart, regStart, 1); + if( pMWin->eEnd==TK_UNBOUNDED ){ + addrStart = sqlite3VdbeCurrentAddr(v); + addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, csrCurrent, regStart, 1); + addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, csrStart, 0, 1); + }else{ + assert( pMWin->eEnd==TK_FOLLOWING ); + addrStart = sqlite3VdbeCurrentAddr(v); + addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, csrCurrent, regEnd, 1); + addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, csrStart, regStart, 1); + } sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart); sqlite3VdbeJumpHere(v, addrBreak2); addrStart = sqlite3VdbeCurrentAddr(v); @@ -2688,21 +2417,10 @@ void sqlite3WindowCodeStep( ** 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||!pMWin->pOrderBy) - ){ - int bCache = windowCachePartition(pMWin); - if( (pMWin->eEnd!=TK_FOLLOWING && pMWin->eEnd!=TK_PRECEDING) - || (pMWin->eStart!=TK_FOLLOWING && pMWin->eStart!=TK_PRECEDING) - ){ - VdbeModuleComment((pParse->pVdbe, "Begin RowExprStep()")); - windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub); - VdbeModuleComment((pParse->pVdbe, "End RowExprStep()")); - }else{ - VdbeModuleComment((pParse->pVdbe, "Begin windowCodeStep()")); - windowCodeStep(pParse, p, pWInfo, regGosub, addrGosub); - VdbeModuleComment((pParse->pVdbe, "End windowCodeStep()")); - } + if( pMWin->eType==TK_ROWS ){ + VdbeModuleComment((pParse->pVdbe, "Begin windowCodeStep()")); + windowCodeStep(pParse, p, pWInfo, regGosub, addrGosub); + VdbeModuleComment((pParse->pVdbe, "End windowCodeStep()")); }else{ Window *pWin; int bCache = 0; /* True to use CacheStep() */ -- 2.47.2