Correctly handle 64-bit integers in SQL statements. (CVS 1408)
FossilOrigin-Name: 34f03ba6a9d6e2144d0c6cbbbeb37b4c69705f1f
diff --git a/src/expr.c b/src/expr.c
index a0fff71..65821bd 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.122 2004/05/18 10:06:25 danielk1977 Exp $
+** $Id: expr.c,v 1.123 2004/05/19 20:41:03 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -442,8 +442,7 @@
int sqlite3ExprIsInteger(Expr *p, int *pValue){
switch( p->op ){
case TK_INTEGER: {
- if( sqlite3FitsIn32Bits(p->token.z) ){
- *pValue = atoi(p->token.z);
+ if( sqlite3GetInt32(p->token.z, pValue) ){
return 1;
}
break;
@@ -453,8 +452,7 @@
int n = p->token.n;
if( n>0 && z[0]=='-' ){ z++; n--; }
while( n>0 && *z && isdigit(*z) ){ z++; n--; }
- if( n==0 && sqlite3FitsIn32Bits(p->token.z) ){
- *pValue = atoi(p->token.z);
+ if( n==0 && sqlite3GetInt32(p->token.z, pValue) ){
return 1;
}
break;
@@ -1132,6 +1130,19 @@
}
/*
+** Generate an instruction that will put the integer describe by
+** text z[0..n-1] on the stack.
+*/
+static void codeInteger(Vdbe *v, const char *z, int n){
+ int i;
+ if( sqlite3GetInt32(z, &i) || (i=0, sqlite3FitsIn64Bits(z))!=0 ){
+ sqlite3VdbeOp3(v, OP_Integer, i, 0, z, n);
+ }else{
+ sqlite3VdbeOp3(v, OP_Real, 0, 0, z, n);
+ }
+}
+
+/*
** Generate code into the current Vdbe to evaluate the given
** expression and leave the result on the top of stack.
*/
@@ -1162,6 +1173,8 @@
case TK_LSHIFT: op = OP_ShiftLeft; break;
case TK_RSHIFT: op = OP_ShiftRight; break;
case TK_REM: op = OP_Remainder; break;
+ case TK_FLOAT: op = OP_Real; break;
+ case TK_STRING: op = OP_String; break;
default: break;
}
switch( pExpr->op ){
@@ -1175,18 +1188,13 @@
}
break;
}
- case TK_STRING:
- case TK_FLOAT:
case TK_INTEGER: {
- if( pExpr->op==TK_INTEGER && sqlite3FitsIn32Bits(pExpr->token.z) ){
- sqlite3VdbeAddOp(v, OP_Integer, atoi(pExpr->token.z), 0);
- }else if( pExpr->op==TK_FLOAT || pExpr->op==TK_INTEGER ){
- sqlite3VdbeAddOp(v, OP_Real, 0, 0);
- }else{
- sqlite3VdbeAddOp(v, OP_String, 0, 0);
- }
- assert( pExpr->token.z );
- sqlite3VdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n);
+ codeInteger(v, pExpr->token.z, pExpr->token.n);
+ break;
+ }
+ case TK_FLOAT:
+ case TK_STRING: {
+ sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z, pExpr->token.n);
sqlite3VdbeDequoteP3(v, -1);
break;
}
@@ -1238,17 +1246,17 @@
break;
}
case TK_UMINUS: {
- assert( pExpr->pLeft );
- if( pExpr->pLeft->op==TK_FLOAT || pExpr->pLeft->op==TK_INTEGER ){
- Token *p = &pExpr->pLeft->token;
+ Expr *pLeft = pExpr->pLeft;
+ assert( pLeft );
+ if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
+ Token *p = &pLeft->token;
char *z = sqliteMalloc( p->n + 2 );
sprintf(z, "-%.*s", p->n, p->z);
- if( pExpr->pLeft->op==TK_INTEGER && sqlite3FitsIn32Bits(z) ){
- sqlite3VdbeAddOp(v, OP_Integer, atoi(z), 0);
+ if( pLeft->op==TK_FLOAT ){
+ sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1);
}else{
- sqlite3VdbeAddOp(v, OP_Real, 0, 0);
+ codeInteger(v, z, p->n+1);
}
- sqlite3VdbeChangeP3(v, -1, z, p->n+1);
sqliteFree(z);
break;
}
@@ -1289,7 +1297,7 @@
/* FIX ME: The following is a temporary hack. */
if( 0==sqlite3StrNICmp(zId, "classof", nId) ){
assert( nExpr==1 );
- sqlite3VdbeOp3(v, OP_Class, nExpr, 0, 0, 0);
+ sqlite3VdbeAddOp(v, OP_Class, nExpr, 0);
}else{
sqlite3VdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_POINTER);
}
@@ -1800,6 +1808,3 @@
}
return p;
}
-
-
-