diff options
author | drh <drh@noemail.net> | 2004-01-14 21:59:22 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2004-01-14 21:59:22 +0000 |
commit | 751f41217e0047b940aa102a069a59830b80ba9c (patch) | |
tree | 3adbe221083715ebddc9d9ac3f5cd5eddfffe6d3 /src | |
parent | d43ce86fa7d2a1126932f8594a60c82471b46560 (diff) | |
download | sqlite-751f41217e0047b940aa102a069a59830b80ba9c.tar.gz sqlite-751f41217e0047b940aa102a069a59830b80ba9c.zip |
Fix comparisons of ROWID against floating point numbers so that they work
correctly. Ticket #377 and #567. (CVS 1178)
FossilOrigin-Name: c9ac3db8e08403398ec344757385334601a59374
Diffstat (limited to 'src')
-rw-r--r-- | src/encode.c | 8 | ||||
-rw-r--r-- | src/vdbe.c | 41 | ||||
-rw-r--r-- | src/where.c | 8 |
3 files changed, 35 insertions, 22 deletions
diff --git a/src/encode.c b/src/encode.c index d5e5514c7..925995d19 100644 --- a/src/encode.c +++ b/src/encode.c @@ -15,7 +15,7 @@ ** data in an SQLite database. The code in this file is not used by any other ** part of the SQLite library. ** -** $Id: encode.c,v 1.9 2003/06/28 16:25:34 drh Exp $ +** $Id: encode.c,v 1.10 2004/01/14 21:59:23 drh Exp $ */ #include <string.h> @@ -190,16 +190,18 @@ int sqlite_decode_binary(const unsigned char *in, unsigned char *out){ } #ifdef ENCODER_TEST +#include <stdio.h> /* ** The subroutines above are not tested by the usual test suite. To test ** these routines, compile just this one file with a -DENCODER_TEST=1 option ** and run the result. */ int main(int argc, char **argv){ - int i, j, n, m, nOut; + int i, j, n, m, nOut, nByte; unsigned char in[30000]; unsigned char out[33000]; + nByte = 0; for(i=0; i<sizeof(in); i++){ printf("Test %d: ", i+1); n = rand() % (i+1); @@ -213,6 +215,7 @@ int main(int argc, char **argv){ }else{ for(j=0; j<n; j++) in[j] = rand() & 0xff; } + nByte += n; nOut = sqlite_encode_binary(in, n, out); if( nOut!=strlen(out) ){ printf(" ERROR return value is %d instead of %d\n", nOut, strlen(out)); @@ -241,5 +244,6 @@ int main(int argc, char **argv){ } printf(" OK\n"); } + fprintf(stderr, "Finished. Total encoding: %d bytes\n", nByte); } #endif /* ENCODER_TEST */ diff --git a/src/vdbe.c b/src/vdbe.c index 8e01614dd..505ff5fe3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.249 2004/01/07 20:37:52 drh Exp $ +** $Id: vdbe.c,v 1.250 2004/01/14 21:59:23 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -1217,27 +1217,38 @@ case OP_AddImm: { break; } -/* Opcode: IsNumeric P1 P2 * +/* Opcode: ForceInt P1 P2 * ** -** Check the top of the stack to see if it is a numeric value. A numeric -** value is an integer, a real number, or a string that looks like an -** integer or a real number. When P1==0, pop the stack and jump to P2 -** if the value is numeric. Otherwise fall through and leave the stack -** unchanged. The sense of the test is inverted when P1==1. +** Convert the top of the stack into an integer. If the current top of +** the stack is not numeric (meaning that is is a NULL or a string that +** does not look like an integer or floating point number) then pop the +** stack and jump to P2. If the top of the stack is numeric then +** convert it into the least integer that is greater than or equal to its +** current value if P1==0, or to the least integer that is strictly +** greater than its current value if P1==1. */ -case OP_IsNumeric: { +case OP_ForceInt: { int tos = p->tos; - int r; + int v; VERIFY( if( tos<0 ) goto not_enough_stack; ) - r = (aStack[tos].flags & (STK_Int|STK_Real))!=0 - || (zStack[tos] && sqliteIsNumber(zStack[tos])); - if( pOp->p1 ){ - r = !r; - } - if( r ){ + if( (aStack[tos].flags & (STK_Int|STK_Real))==0 + && (zStack[tos]==0 || sqliteIsNumber(zStack[tos])==0) ){ POPSTACK; pc = pOp->p2 - 1; + break; + } + if( aStack[tos].flags & STK_Int ){ + v = aStack[tos].i + (pOp->p1!=0); + }else{ + Realify(p, tos); + v = (int)aStack[tos].r; + if( aStack[tos].r>(double)v ) v++; + if( pOp->p1 && aStack[tos].r==(double)v ) v++; } + if( aStack[tos].flags & STK_Dyn ) sqliteFree(zStack[tos]); + zStack[tos] = 0; + aStack[tos].i = v; + aStack[tos].flags = STK_Int; break; } diff --git a/src/where.c b/src/where.c index b93e2ceb2..1cfaf63d2 100644 --- a/src/where.c +++ b/src/where.c @@ -12,7 +12,7 @@ ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** -** $Id: where.c,v 1.86 2004/01/07 20:37:52 drh Exp $ +** $Id: where.c,v 1.87 2004/01/14 21:59:24 drh Exp $ */ #include "sqliteInt.h" @@ -855,10 +855,8 @@ WhereInfo *sqliteWhereBegin( }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); } - sqliteVdbeAddOp(v, OP_IsNumeric, 1, brk); - if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ){ - sqliteVdbeAddOp(v, OP_AddImm, 1, 0); - } + sqliteVdbeAddOp(v, OP_ForceInt, + aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT, brk); sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk); aExpr[k].p = 0; }else{ |