diff options
author | dan <dan@noemail.net> | 2019-03-26 16:47:17 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2019-03-26 16:47:17 +0000 |
commit | 725b1cfc53d19b4de268df83f3d83c0d96a51810 (patch) | |
tree | 347dbed1fafc71393aa7ccc79852f2470945a30b /src/window.c | |
parent | d4a591dd6beaa33223b153abe092c8e61d6bde0a (diff) | |
download | sqlite-725b1cfc53d19b4de268df83f3d83c0d96a51810.tar.gz sqlite-725b1cfc53d19b4de268df83f3d83c0d96a51810.zip |
Fix a problem with window frames that use "BETWEEN <start> AND 0 PRECEDING".
FossilOrigin-Name: 7927b6b023502e990d23f30251b5b0918b547726b863bfb6747dcd7f1f71d19a
Diffstat (limited to 'src/window.c')
-rw-r--r-- | src/window.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/src/window.c b/src/window.c index aab06c461..ded26f81c 100644 --- a/src/window.c +++ b/src/window.c @@ -2014,6 +2014,26 @@ Window *sqlite3WindowListDup(sqlite3 *db, Window *p){ } /* +** Return true if it can be determined at compile time that expression +** pExpr evaluates to a value that, when cast to an integer, is greater +** than zero. False otherwise. +** +** If an OOM error occurs, this function sets the Parse.db.mallocFailed +** flag and returns zero. +*/ +static int windowExprGtZero(Parse *pParse, Expr *pExpr){ + int ret = 0; + sqlite3 *db = pParse->db; + sqlite3_value *pVal = 0; + sqlite3ValueFromExpr(db, pExpr, db->enc, SQLITE_AFF_NUMERIC, &pVal); + if( pVal && sqlite3_value_int(pVal)>0 ){ + ret = 1; + } + sqlite3ValueFree(pVal); + return ret; +} + +/* ** sqlite3WhereBegin() has already been called for the SELECT statement ** passed as the second argument when this function is invoked. It generates ** code to populate the Window.regResult register for each window function @@ -2406,22 +2426,17 @@ void sqlite3WindowCodeStep( ** has been returned to the caller (WINDOW_RETURN_ROW), or they may ** be deleted after they enter the frame (WINDOW_AGGSTEP). */ switch( pMWin->eStart ){ - case TK_FOLLOWING: { - if( pMWin->eType!=TK_RANGE ){ - sqlite3 *db = pParse->db; - sqlite3_value *pVal = 0; - sqlite3ValueFromExpr(db,pMWin->pStart,db->enc,SQLITE_AFF_NUMERIC,&pVal); - if( pVal && sqlite3_value_int(pVal)>0 ){ - s.eDelete = WINDOW_RETURN_ROW; - } - sqlite3ValueFree(pVal); + case TK_FOLLOWING: + if( pMWin->eType!=TK_RANGE && windowExprGtZero(pParse, pMWin->pStart) ){ + s.eDelete = WINDOW_RETURN_ROW; } break; - } case TK_UNBOUNDED: if( windowCacheFrame(pMWin)==0 ){ if( pMWin->eEnd==TK_PRECEDING ){ - s.eDelete = WINDOW_AGGSTEP; + if( pMWin->eType!=TK_RANGE && windowExprGtZero(pParse, pMWin->pEnd) ){ + s.eDelete = WINDOW_AGGSTEP; + } }else{ s.eDelete = WINDOW_RETURN_ROW; } |