aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2004-01-14 21:59:22 +0000
committerdrh <drh@noemail.net>2004-01-14 21:59:22 +0000
commit751f41217e0047b940aa102a069a59830b80ba9c (patch)
tree3adbe221083715ebddc9d9ac3f5cd5eddfffe6d3 /src
parentd43ce86fa7d2a1126932f8594a60c82471b46560 (diff)
downloadsqlite-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.c8
-rw-r--r--src/vdbe.c41
-rw-r--r--src/where.c8
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{