diff options
author | drh <drh@noemail.net> | 2003-07-06 17:22:25 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2003-07-06 17:22:25 +0000 |
commit | 1dd59e0f9447ca2d38504b38b42f72efb8313b6f (patch) | |
tree | 00a4b07ca510ac528739c75d4801a4a4004a646a /src | |
parent | 3c8bf55a040f0b8e25824f204a461d8e465d045d (diff) | |
download | sqlite-1dd59e0f9447ca2d38504b38b42f72efb8313b6f.tar.gz sqlite-1dd59e0f9447ca2d38504b38b42f72efb8313b6f.zip |
Correctly handle comparing an INTEGER PRIMARY KEY against a floating point
number. Ticket #377. (CVS 1045)
FossilOrigin-Name: 982aa3356bcc217003cd9e6a829619219c334797
Diffstat (limited to 'src')
-rw-r--r-- | src/vdbe.c | 42 | ||||
-rw-r--r-- | src/where.c | 6 |
2 files changed, 41 insertions, 7 deletions
diff --git a/src/vdbe.c b/src/vdbe.c index ee69bc2ca..ee5b6b0ea 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -36,7 +36,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.231 2003/06/29 20:25:08 drh Exp $ +** $Id: vdbe.c,v 1.232 2003/07/06 17:22:25 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -2268,6 +2268,30 @@ case OP_AddImm: { break; } +/* Opcode: IsNumeric 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. +*/ +case OP_IsNumeric: { + int tos = p->tos; + int r; + 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 ){ + POPSTACK; + pc = pOp->p2 - 1; + } + break; +} + /* Opcode: MustBeInt P1 P2 * ** ** Force the top of the stack to be an integer. If the top of the @@ -2294,14 +2318,24 @@ case OP_MustBeInt: { }else if( aStack[tos].flags & STK_Str ){ int v; if( !toInt(zStack[tos], &v) ){ - goto mismatch; + double r; + if( !sqliteIsNumber(zStack[tos]) ){ + goto mismatch; + } + Realify(p, tos); + assert( (aStack[tos].flags & STK_Real)!=0 ); + v = aStack[tos].r; + r = (double)v; + if( r!=aStack[tos].r ){ + goto mismatch; + } } - p->aStack[tos].i = v; + aStack[tos].i = v; }else{ goto mismatch; } Release(p, tos); - p->aStack[tos].flags = STK_Int; + aStack[tos].flags = STK_Int; break; mismatch: diff --git a/src/where.c b/src/where.c index 1400c6285..a0504ec6d 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.79 2003/05/17 17:35:13 drh Exp $ +** $Id: where.c,v 1.80 2003/07/06 17:22:25 drh Exp $ */ #include "sqliteInt.h" @@ -853,7 +853,7 @@ WhereInfo *sqliteWhereBegin( }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); } - sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk); + 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); } @@ -872,7 +872,7 @@ WhereInfo *sqliteWhereBegin( }else{ sqliteExprCode(pParse, aExpr[k].p->pLeft); } - sqliteVdbeAddOp(v, OP_MustBeInt, 1, sqliteVdbeCurrentAddr(v)+1); + /* sqliteVdbeAddOp(v, OP_MustBeInt, 0, sqliteVdbeCurrentAddr(v)+1); */ pLevel->iMem = pParse->nMem++; sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 0); if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ){ |