diff options
author | dan <dan@noemail.net> | 2019-03-18 16:51:24 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2019-03-18 16:51:24 +0000 |
commit | bdabe742da30a22aff881fc89773cf0ec1eaec60 (patch) | |
tree | 53a9106e6271362882c47dafd42fa8b09e33b570 /src | |
parent | 1e7cb19be3f06951fcbafdb6055df04a4ca7924d (diff) | |
download | sqlite-bdabe742da30a22aff881fc89773cf0ec1eaec60.tar.gz sqlite-bdabe742da30a22aff881fc89773cf0ec1eaec60.zip |
Fixes for RANGE windows and NULL values.
FossilOrigin-Name: 723c84be3ec5ae941b7abd2442cdb76ca3bd76a5ce2d830b0e648c6e1424885a
Diffstat (limited to 'src')
-rw-r--r-- | src/vdbe.c | 3 | ||||
-rw-r--r-- | src/window.c | 29 |
2 files changed, 14 insertions, 18 deletions
diff --git a/src/vdbe.c b/src/vdbe.c index 00792b144..095021eb6 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1924,7 +1924,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ ** OP_Eq or OP_Ne) then take the jump or not depending on whether ** or not both operands are null. */ - assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); assert( (flags1 & MEM_Cleared)==0 ); assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB ); testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 ); @@ -1933,7 +1932,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ ){ res = 0; /* Operands are equal */ }else{ - res = 1; /* Operands are not equal */ + res = ((flags3 & MEM_Null) ? -1 : +1); /* Operands are not equal */ } }else{ /* SQLITE_NULLEQ is clear and at least one operand is NULL, diff --git a/src/window.c b/src/window.c index d3088c0c8..28562c8f7 100644 --- a/src/window.c +++ b/src/window.c @@ -1783,21 +1783,14 @@ static void windowCodeRangeTest( windowReadPeerValues(p, csr2, reg2); /* Check if the peer value for csr1 value is a text or blob by comparing - ** it to the smallest possible string - ''. */ + ** it to the smallest possible string - ''. If it is, jump over the + ** OP_Add or OP_Subtract operation and proceed directly to the comparison. */ sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC); addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1); - - if( op==OP_Le ){ - sqlite3VdbeAddOp2(v, OP_IsNull, reg1, lbl); - } - if( op==OP_Ge ){ - sqlite3VdbeAddOp2(v, OP_NotNull, reg1, sqlite3VdbeCurrentAddr(v)+2); - sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); - } - sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1); sqlite3VdbeJumpHere(v, addrGe); sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); sqlite3ReleaseTempReg(pParse, reg1); sqlite3ReleaseTempReg(pParse, reg2); @@ -2367,13 +2360,15 @@ void sqlite3WindowCodeStep( ** be deleted after they enter the frame (WINDOW_AGGSTEP). */ switch( pMWin->eStart ){ case TK_FOLLOWING: { - 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; + 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); } - sqlite3ValueFree(pVal); break; } case TK_UNBOUNDED: @@ -2390,6 +2385,8 @@ void sqlite3WindowCodeStep( break; } + s.eDelete = 0; + /* Allocate registers for the array of values from the sub-query, the ** samve values in record form, and the rowid used to insert said record ** into the ephemeral table. */ |