1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Correctly handle comparing an INTEGER PRIMARY KEY against a floating point

number.  Ticket #377. (CVS 1045)

FossilOrigin-Name: 982aa3356bcc217003cd9e6a829619219c334797
This commit is contained in:
drh
2003-07-06 17:22:25 +00:00
parent 3c8bf55a04
commit 1dd59e0f94
5 changed files with 105 additions and 17 deletions

View File

@ -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:

View File

@ -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 ){