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
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users