Hello!

See the test:

========================
$ cat /tmp/test
package require sqlite3
sqlite3 db :memory:

db eval {create table test(a int);insert into test values (1);}
proc test {label sql result} {
    global i j
    puts -nonewline $label\t
    set _result [db eval $sql]
    if { $_result eq $result} {
        puts OK
    } else {
        puts ERROR\t$result!=$_result
    }
}
set i 1

test 1.0 {select typeof($i)} integer ;# it doesn't work in orig sqlite
test 1.1 {select * from test where a=$i} 1
test 1.2 {select * from test where 1=$i} 1 ;# it doesn't work in orig sqlite
test 1.3 {select a from test where a IN (cast($i AS INT), 160)} 1
test 1.4 {select a from test where 1 IN (cast($i AS INT), 160)} 1


$ tclsh8.5 /tmp/test
1.0     ERROR   integer!=text
1.1     OK
1.2     ERROR   1!=
1.3     OK
1.4     OK


But in the tclsh shell these tests work fine:
========================
$ tclsh8.5
% package require sqlite3
sqlite3 db :memory:

db eval {create table test(a int);insert into test values (1);}
proc test {label sql result} {
    global i j
    puts -nonewline $label\t
    set _result [db eval $sql]
    if { $_result eq $result} {
        puts OK
    } else {
        puts ERROR\t$result!=$_result
    }
}
set i 1

test 1.0 {select typeof($i)} integer ;# it doesn't work in orig sqlite
test 1.1 {select * from test where a=$i} 1
test 1.2 {select * from test where 1=$i} 1 ;# it doesn't work in orig sqlite
test 1.3 {select a from test where a IN (cast($i AS INT), 160)} 1
test 1.4 {select a from test where 1 IN (cast($i AS INT), 160)} 1

3.6.18
% % % % % % % 1
% 1
% % 1.0 OK
% 1.1   OK
% 1.2   OK
% 1.3   OK
% 1.4   OK
% %



============== the patch ====================
--- tclsqlite.c.old     2009-09-05 00:37:43.000000000 +0400                     
                      
+++ tclsqlite.c 2009-10-09 02:50:39.000000000 +0400                             
                      
@@ -754,26 +754,18 @@                                                           
                      
   }else{                                                                       
                      
     Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);                               
                      
     int n;                                                                     
                      
+    Tcl_WideInt v;                                                             
                      
+    double r;                                                                  
                      
     u8 *data;                                                                  
                      
-    char *zType = pVar->typePtr ? pVar->typePtr->name : "";                    
                      
-    char c = zType[0];                                                         
                      
-    if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){            
                      
+    if( pVar->typePtr && pVar->typePtr->name[0]=='b' && 
strcmp(pVar->typePtr->name,"bytearray")==0 && pVar->bytes==0 ){
       /* Only return a BLOB type if the Tcl variable is a bytearray and        
                                        
       ** has no string representation. */                                      
                                        
       data = Tcl_GetByteArrayFromObj(pVar, &n);                                
                                        
       sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);                 
                                        
-    }else if( c=='b' && strcmp(zType,"boolean")==0 ){                          
                                        
-      Tcl_GetIntFromObj(0, pVar, &n);                                          
                                        
-      sqlite3_result_int(context, n);                                          
                                        
-    }else if( c=='d' && strcmp(zType,"double")==0 ){                           
                                        
-      double r;                                                                
                                        
-      Tcl_GetDoubleFromObj(0, pVar, &r);                                       
                                        
-      sqlite3_result_double(context, r);                                       
                                        
-    }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||                        
                                        
-          (c=='i' && strcmp(zType,"int")==0) ){                                
                                        
-      Tcl_WideInt v;                                                           
                                        
-      Tcl_GetWideIntFromObj(0, pVar, &v);                                      
                                        
+    }else if( TCL_OK == Tcl_GetWideIntFromObj(0, pVar, &v)){                   
                                        
       sqlite3_result_int64(context, v);                                        
                                        
+    }else if( TCL_OK == Tcl_GetDoubleFromObj(0, pVar, &r)){                    
                                        
+      sqlite3_result_double(context, r);                                       
                                        
     }else{                                                                     
                                        
       data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);                  
                                        
       sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);         
                                        
@@ -1629,6 +1621,9 @@                                                           
                                        
     SqlPreparedStmt *pPreStmt;  /* Pointer to a prepared statement */          
                                        
     int rc2;                                                                   
                                        
                                                                                
                                                                                
                             
+    Tcl_ObjType *tclWideIntType = Tcl_GetObjType("wideint");                   
                                                                                
                             
+    Tcl_ObjType *tclDoubleType = Tcl_GetObjType("double");                     
                                                                                
                             
+                                                                               
                                                                                
                             
     if( choice==DB_EVAL ){                                                     
                                                                                
                             
       if( objc<3 || objc>5 ){                                                  
                                                                                
                             
         Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");        
                                                                                
                             
@@ -1728,7 +1723,7 @@                                                           
                                                                                
                             
         assert( pPreStmt==0 );
       }

-      /* Bind values to parameters that begin with $ or :
+      /* Bind values to parameters that begin with $ or : or @
       */
       nVar = sqlite3_bind_parameter_count(pStmt);
       nParm = 0;
@@ -1744,10 +1739,10 @@
           if( pVar ){
             int n;
             u8 *data;
-            char *zType = pVar->typePtr ? pVar->typePtr->name : "";
-            char c = zType[0];
+            double r;
+            Tcl_WideInt v;
             if( zVar[0]=='@' ||
-               (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
+               ( pVar->typePtr && pVar->typePtr->name[0]=='b' && 
strcmp(pVar->typePtr->name,"bytearray")==0 && pVar->bytes==0) ){
               /* Load a BLOB type if the Tcl variable is a bytearray and
               ** it has no string representation or the host
               ** parameter name begins with "@". */
@@ -1755,18 +1750,10 @@
               sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
               Tcl_IncrRefCount(pVar);
               apParm[nParm++] = pVar;
-            }else if( c=='b' && strcmp(zType,"boolean")==0 ){
-              Tcl_GetIntFromObj(interp, pVar, &n);
-              sqlite3_bind_int(pStmt, i, n);
-            }else if( c=='d' && strcmp(zType,"double")==0 ){
-              double r;
-              Tcl_GetDoubleFromObj(interp, pVar, &r);
-              sqlite3_bind_double(pStmt, i, r);
-            }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
-                  (c=='i' && strcmp(zType,"int")==0) ){
-              Tcl_WideInt v;
-              Tcl_GetWideIntFromObj(interp, pVar, &v);
+            }else if( TCL_OK == Tcl_GetWideIntFromObj(interp, pVar, &v)) {
               sqlite3_bind_int64(pStmt, i, v);
+            }else if( TCL_OK == Tcl_GetDoubleFromObj(interp, pVar, &r)) {
+              sqlite3_bind_double(pStmt, i, r);
             }else{
               data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
               sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);
=======================================

Best regards, Alexey Pechnikov.
http://pechnikov.tel/
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to