diff options
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 59 |
1 files changed, 32 insertions, 27 deletions
diff --git a/src/expr.c b/src/expr.c index a0fff71d8..65821bd53 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 sqlite3ExprIsConstant(Expr *p){ 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 sqlite3ExprIsInteger(Expr *p, int *pValue){ 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 @@ int sqlite3ExprType(Expr *p){ } /* +** 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 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ 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 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ } 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 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ 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 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ /* 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 @@ FuncDef *sqlite3FindFunction( } return p; } - - - |