]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix problem in the code generator were incorrect code was being created if
authordrh <drh@noemail.net>
Tue, 6 Jan 2004 01:13:46 +0000 (01:13 +0000)
committerdrh <drh@noemail.net>
Tue, 6 Jan 2004 01:13:46 +0000 (01:13 +0000)
the SQL source contained a negative integer that was too large to fit in
a 32-bit signed integer variable.  Ticket #552. (CVS 1157)

FossilOrigin-Name: b8381d9fe99273507e8626638110646801afef06

manifest
manifest.uuid
src/expr.c
src/sqliteInt.h
src/util.c
test/misc3.test

index 3e1d3c953ac25246ea9611c4fa52d44f64baf30c..cc5987b05d0140b6f37e2e070a2ca00da4f792a1 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sthe\ssqlite_current_time\svariable\sfor\stesting\spurposes.\s(CVS\s1156)
-D 2004-01-06T00:44:25
+C Fix\sproblem\sin\sthe\scode\sgenerator\swere\sincorrect\scode\swas\sbeing\screated\sif\r\nthe\sSQL\ssource\scontained\sa\snegative\sinteger\sthat\swas\stoo\slarge\sto\sfit\sin\r\na\s32-bit\ssigned\sinteger\svariable.\s\sTicket\s#552.\s(CVS\s1157)
+D 2004-01-06T01:13:46
 F Makefile.in 0515ff9218ad8d5a8f6220f0494b8ef94c67013b
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -31,7 +31,7 @@ F src/copy.c 9e47975ea96751c658bcf1a0c4f0bb7c6ee61e73
 F src/date.c 13775c2dedfc805ebf3f6507bad676f7c974a241
 F src/delete.c 0f81e6799c089487615d38e042a2de4d2d6192bc
 F src/encode.c 25ea901a9cefb3d93774afa4a06b57cb58acf544
-F src/expr.c a14401a54e5923f3e52b6d04a83813d150f43f33
+F src/expr.c abb40922fa9995aca06f999ed35d2061d44650d6
 F src/func.c 62cf8fae8147c0301d1c6a4a94fe0a78f7aa5b33
 F src/hash.c 058f077c1f36f266581aa16f907a3903abf64aa3
 F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
@@ -50,7 +50,7 @@ F src/select.c d79ac60ba1595ff3c94b12892e87098329776482
 F src/shell.c 3b067edc098c45caca164bcad1fa79192c3ec5ae
 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
 F src/sqlite.h.in e6cfff01fafc8a82ce82cd8c932af421dc9adb54
-F src/sqliteInt.h a70744a84caec6d48017143ea5b9f945867e539e
+F src/sqliteInt.h 88ab55200183355e35f8f13a6b4c27b4b48288b2
 F src/table.c d845cb101b5afc1f7fea083c99e3d2fa7998d895
 F src/tclsqlite.c dcd18d1f0d51ac4863d1f9059f614f903bc1fffe
 F src/test1.c 1d297ca6c01601ee38d723ff08343dc01f351985
@@ -61,7 +61,7 @@ F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
 F src/tokenize.c 5597df1fd76d6947e7da824856ac1910e2055729
 F src/trigger.c ce83e017b407d046e909d05373d7f8ee70f9f7f9
 F src/update.c 24260b4fda00c9726d27699a0561d53c0dccc397
-F src/util.c 48631b7f7b2f3874fb3aa60396e18619933e9386
+F src/util.c 0e3bf40dafe75805495454ff5283b552f14b5d4d
 F src/vacuum.c 77485a64a6e4e358170f150fff681c1624a092b0
 F src/vdbe.c a16a084ca40edeec3a2e490d6f672fc84f851dd9
 F src/vdbe.h 3957844e46fea71fd030e78f6a3bd2f7e320fb43
@@ -106,7 +106,7 @@ F test/memleak.test a18e6810cae96d2f6f5136920267adbefc8e1e90
 F test/minmax.test 6d9b6d6ee34f42e2a58dffece1f76d35f446b3af
 F test/misc1.test 0b98d493b0cf55cb5f53e1f3df8107c166eecb5a
 F test/misc2.test 10c2ce26407d37411b96273e552d5095393732be
-F test/misc3.test cfece884d4e552400bb630efb6deda973a97eda2
+F test/misc3.test 860233be672959b6d7df542adbeb0fc10103857c
 F test/misuse.test a3aa2b18a97e4c409a1fcaff5151a4dd804a0162
 F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
 F test/null.test c14d0f4739f21e929b8115b72bf0c765b6bb1721
@@ -179,7 +179,7 @@ F www/speed.tcl 2f6b1155b99d39adb185f900456d1d592c4832b3
 F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
-P 720b565e2d02344e4d38263f4995dfabc60c0860
-R f8de8a215a694e6aa8ad957d7bf6a945
+P 23fa407d50741bc0719259792398f28c1d0f12c2
+R 26f4e6dd4d46b029d5b74bd24795dcf2
 U drh
-Z 4f7ef24347116d6ebacdd3903fd02b08
+Z 323e2dfe44fbdbec4fff461f02b92003
index 742ca464f7de82ae8c8fb69196e70dd894a94d26..89f62c396de647448ff0df0b165b4515e269d6bb 100644 (file)
@@ -1 +1 @@
-23fa407d50741bc0719259792398f28c1d0f12c2
\ No newline at end of file
+b8381d9fe99273507e8626638110646801afef06
\ No newline at end of file
index 41cdaf949b941800a2abff194700bcc5cf78fab0..f706a5c22c38edbffb66d0d8af99a7a55a18dbb5 100644 (file)
@@ -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.102 2003/12/10 03:13:44 drh Exp $
+** $Id: expr.c,v 1.103 2004/01/06 01:13:46 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -328,22 +328,26 @@ int sqliteExprIsConstant(Expr *p){
 }
 
 /*
-** If the given expression codes a constant integer, return 1 and put
-** the value of the integer in *pValue.  If the expression is not an
-** integer, return 0 and leave *pValue unchanged.
+** If the given expression codes a constant integer that is small enough
+** to fit in a 32-bit integer, return 1 and put the value of the integer
+** in *pValue.  If the expression is not an integer or if it is too big
+** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
 */
 int sqliteExprIsInteger(Expr *p, int *pValue){
   switch( p->op ){
     case TK_INTEGER: {
-      *pValue = atoi(p->token.z);
-      return 1;
+      if( sqliteFitsIn32Bits(p->token.z) ){
+        *pValue = atoi(p->token.z);
+        return 1;
+      }
+      break;
     }
     case TK_STRING: {
       const char *z = p->token.z;
       int n = p->token.n;
       if( n>0 && z[0]=='-' ){ z++; n--; }
       while( n>0 && *z && isdigit(*z) ){ z++; n--; }
-      if( n==0 ){
+      if( n==0 && sqliteFitsIn32Bits(p->token.z) ){
         *pValue = atoi(p->token.z);
         return 1;
       }
@@ -969,6 +973,9 @@ int sqliteExprType(Expr *p){
   return SQLITE_SO_NUM;
 }
 
+/*
+** Run
+
 /*
 ** Generate code into the current Vdbe to evaluate the given
 ** expression and leave the result on the top of stack.
@@ -1014,16 +1021,10 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
       break;
     }
     case TK_INTEGER: {
-      int iVal = atoi(pExpr->token.z);
-      char zBuf[30];
-      sprintf(zBuf,"%d",iVal);
-      if( strlen(zBuf)!=pExpr->token.n 
-            || strncmp(pExpr->token.z,zBuf,pExpr->token.n)!=0 ){
-        /* If the integer value cannot be represented exactly in 32 bits,
-        ** then code it as a string instead. */
+      if( !sqliteFitsIn32Bits(pExpr->token.z) ){
         sqliteVdbeAddOp(v, OP_String, 0, 0);
       }else{
-        sqliteVdbeAddOp(v, OP_Integer, iVal, 0);
+        sqliteVdbeAddOp(v, OP_Integer, atoi(pExpr->token.z), 0);
       }
       sqliteVdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n);
       break;
@@ -1090,7 +1091,11 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
     case TK_UPLUS: {
       Expr *pLeft = pExpr->pLeft;
       if( pLeft && pLeft->op==TK_INTEGER ){
-        sqliteVdbeAddOp(v, OP_Integer, atoi(pLeft->token.z), 0);
+        if( sqliteFitsIn32Bits(pLeft->token.z) ){
+          sqliteVdbeAddOp(v, OP_Integer, atoi(pLeft->token.z), 0);
+        }else{
+          sqliteVdbeAddOp(v, OP_String, 0, 0);
+        }
         sqliteVdbeChangeP3(v, -1, pLeft->token.z, pLeft->token.n);
       }else if( pLeft && pLeft->op==TK_FLOAT ){
         sqliteVdbeAddOp(v, OP_String, 0, 0);
@@ -1106,7 +1111,7 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
         Token *p = &pExpr->pLeft->token;
         char *z = sqliteMalloc( p->n + 2 );
         sprintf(z, "-%.*s", p->n, p->z);
-        if( pExpr->pLeft->op==TK_INTEGER ){
+        if( pExpr->pLeft->op==TK_INTEGER && sqliteFitsIn32Bits(z) ){
           sqliteVdbeAddOp(v, OP_Integer, atoi(z), 0);
         }else{
           sqliteVdbeAddOp(v, OP_String, 0, 0);
index 7879b11237a170ccdc33080c0e20157e53e1b6a2..0cc8e3f9955d4487a988065e0435553e8eb3b0cd 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.205 2003/12/23 02:17:35 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.206 2004/01/06 01:13:47 drh Exp $
 */
 #include "config.h"
 #include "sqlite.h"
@@ -1205,3 +1205,4 @@ int sqliteFixExprList(DbFixer*, ExprList*);
 int sqliteFixTriggerStep(DbFixer*, TriggerStep*);
 double sqliteAtoF(const char *z);
 int sqlite_snprintf(int,char*,const char*,...);
+int sqliteFitsIn32Bits(const char *);
index d9d2f90c2c84df41e85ab1534b0e13d81760c9a9..af0f31cd1a73061f610b255cdb71b3092aaed0ca 100644 (file)
@@ -14,7 +14,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.69 2003/12/23 02:17:35 drh Exp $
+** $Id: util.c,v 1.70 2004/01/06 01:13:47 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -713,6 +713,24 @@ double sqliteAtoF(const char *z){
   return sign<0 ? -v1 : v1;
 }
 
+/*
+** The string zNum represents an integer.  There might be some other
+** information following the integer too, but that part is ignored.
+** If the integer that the prefix of zNum represents will fit in a
+** 32-bit signed integer, return TRUE.  Otherwise return FALSE.
+**
+** This routine returns FALSE for the string -2147483648 even that
+** that number will, in theory fit in a 32-bit integer.  But positive
+** 2147483648 will not fit in 32 bits.  So it seems safer to return
+** false.
+*/
+int sqliteFitsIn32Bits(const char *zNum){
+  int i, c;
+  if( *zNum=='-' || *zNum=='+' ) zNum++;
+  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
+  return i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0);
+}
+
 /* This comparison routine is what we use for comparison operations
 ** between numeric values in an SQL expression.  "Numeric" is a little
 ** bit misleading here.  What we mean is that the strings have a
index 7e8801eda4a58e98011fcab3ca52cf9a760bf5b3..256a72b14bcefdbd413405139550b35249637633 100644 (file)
@@ -13,7 +13,7 @@
 # This file implements tests for miscellanous features that were
 # left out of other test files.
 #
-# $Id: misc3.test,v 1.2 2003/12/23 02:17:35 drh Exp $
+# $Id: misc3.test,v 1.3 2004/01/06 01:13:47 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -98,5 +98,29 @@ do_test misc3-2.9 {
   execsql {SELECT 2.0e-27 * '+0.000005e+132'}
 } 1e+100
 
+# Ticket #522.  Make sure integer overflow is handled properly in
+# indices.
+#
+do_test misc3-3.1 {
+  execsql {PRAGMA integrity_check}
+} ok
+do_test misc3-3.2 {
+  execsql {
+    CREATE TABLE t2(a INT UNIQUE);
+    PRAGMA integrity_check;
+  }
+} ok
+do_test misc3-3.3 {
+  execsql {
+    INSERT INTO t2 VALUES(2147483648);
+    PRAGMA integrity_check;
+  }
+} ok
+do_test misc3-3.4 {
+  execsql {
+    INSERT INTO t2 VALUES(-2147483649);
+    PRAGMA integrity_check;
+  }
+} ok
 
 finish_test