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:
42
src/vdbe.c
42
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:
|
||||
|
@ -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 ){
|
||||
|
Reference in New Issue
Block a user