Personally I think this behavior is horrid. Is there some scenario where this wouldn't be a latent bug? Here's a patch against 3.7.14.1 which behaves the way it should IMHO Though I think it should actually throw an error when not parseable correctly. Why is this behavior allowed now?
Old: select cast('2' as integer); 2 select cast('2a' as integer); 2 select cast('2.1' as integer); 2 select cast('2.6' as integer); 2 select cast('2.6f' as integer); 2 select cast('2.6' as float); 2.6 Select cast('2.6f' as float); 2.6 New: select cast('2' as integer); 2 select cast('2a' as integer); 0 select cast('2.1' as integer); 0 select cast('2.6' as integer); 0 select cast('2.6f' as integer); 0 select cast('2.6' as float); 2.6 select cast('2.6f' as float); 0 *** sqlite3.old Thu Mar 07 07:06:32 2013 --- sqlite3.c Thu Mar 07 07:26:59 2013 *************** *** 21199,21205 **** int nDigits = 0; *pResult = 0.0; /* Default return value, in case of an error */ - if( enc==SQLITE_UTF16BE ) z++; /* skip leading spaces */ --- 21199,21204 ---- *************** *** 21239,21244 **** --- 21238,21249 ---- } /* skip non-significant digits */ while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++; + if (z < zEnd) { + return 0; + } + } + else { + return 0; } if( z>=zEnd ) goto do_atof_calc; *************** *** 21465,21470 **** --- 21470,21476 ---- sqlite_int64 v = 0; int i, c; int neg = 0; + printf("sqlite3GetInt32\n"); if( zNum[0]=='-' ){ neg = 1; zNum++; *************** *** 21474,21479 **** --- 21480,21488 ---- while( zNum[0]=='0' ) zNum++; for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ v = v*10 + c; + } + if (zNum[i] != 0) { + return 0; } /* The longest decimal representation of a 32 bit integer is 10 digits: -----Original Message----- From: sqlite-users-boun...@sqlite.org [mailto:sqlite-users-boun...@sqlite.org] On Behalf Of Petite Abeille Sent: Wednesday, March 06, 2013 4:21 PM To: General Discussion of SQLite Database Subject: Re: [sqlite] SQLite strong-typing [WAS: inner vs. outer join inconsistency] On Mar 6, 2013, at 10:49 PM, Nico Williams <n...@cryptonector.com> wrote: > Ah, your confusion comes from the fact that type conversion still > happens when the INSERT gets around to making the record. The CHECK > constraint happens before the record is made. See the vdbe that gets > generated. All good. Small sanity check though: select 2 = cast( '2' as integer ); > 1 Ok. '2' is can be casted to 2. great... select 2 = cast( 'a2' as integer ); > 0 Ok. 'a2' cannot really be casted to an integer. cool... select 2 = cast( '2.1' as integer ); > 1 Hmmm.. select 2 = cast( '2abc' as integer ); > 1 Whaaaaat?!? Oh. "When casting a TEXT value to INTEGER, the longest possible prefix of the value that can be interpreted as an integer number is extracted from the TEXT value and the remainder ignored. ". ah. ok. weird. So. select cast( 'abc' as integer ); > 0 o k i d o k i . . . _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users