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