diff --git a/manifest b/manifest index 0bc3dd0a07..1779be3069 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\snew\sapproach\sfor\sUTF-8\stranslation.\s(CVS\s4004) -D 2007-05-15T11:55:09 +C Clarification\son\sthe\sbest\spractices\sfor\susing\sthe\s_bytes()\sAPIs.\nChange\ssqlite3_value_blob()\sto\sforce\sthe\srepresentation\sto\sbe\spurely\na\sBLOB\sand\snot\sa\sdual\sBLOB/String.\s\sTicket\s#2360.\s(CVS\s4005) +D 2007-05-15T13:27:07 F Makefile.in 87b200ad9970907f76df734d29dff3d294c10935 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -71,7 +71,7 @@ F src/date.c 6049db7d5a8fdf2c677ff7d58fa31d4f6593c988 F src/delete.c 5c0d89b3ef7d48fe1f5124bfe8341f982747fe29 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b F src/expr.c 436f1d3e5addf95c195016b518cd2f44a6f5f081 -F src/func.c fc1524fd6097b19c54cc4555e3ea724eec628e2c +F src/func.c 047c974d530ceca010293f4ae145e4ebc762e9d2 F src/hash.c 67b23e14f0257b69a3e8aa663e4eeadc1a2b6fd5 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564 F src/insert.c e595ca26805dfb3a9ebaabc28e7947c479f3b14d @@ -135,7 +135,7 @@ F src/vacuum.c 8bd895d29e7074e78d4e80f948e35ddc9cf2beef F src/vdbe.c 5deb4cdccd57065ccf8a2e5c704e8473c90d204b F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3 F src/vdbeInt.h bddb7931fc1216fda6f6720e18d2a9b1e0f8fc96 -F src/vdbeapi.c 3ca7808c67a10b5c20150108b431d520d141e93e +F src/vdbeapi.c 805147e4e6cd8218ded3dddf4e83ac6154b74a09 F src/vdbeaux.c 62011e2ccf5fa9b3dcc7fa6ff5f0e0638d324a70 F src/vdbeblob.c 96f3572fdc45eda5be06e6372b612bc30742d9f0 F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f @@ -447,7 +447,7 @@ F www/audit.tcl 90e09d580f79c7efec0c7d6f447b7ec5c2dce5c0 F www/autoinc.tcl b357f5ba954b046ee35392ce0f884a2fcfcdea06 F www/c_interface.tcl b51b08591554c16a0c3ef718364a508ac25abc7e F www/capi3.tcl 88884dd743039d1a95aa57f4a5eb369de7744716 -F www/capi3ref.tcl be09756d8b9aebd2d7b597fb910eed66fb4480e6 +F www/capi3ref.tcl 31da5635eb64ab0f47c71b93b131a6bcb1ddebc9 F www/changes.tcl 550300b0ff00fc1b872f7802b2d5a1e7587d3e58 F www/common.tcl 2b793e5c31486c8a01dd27dc0a631ad93704438e F www/compile.tcl 276546d7eb445add5a867193bbd80f6919a6b084 @@ -491,7 +491,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 252810424d8c4dcd19b369d62027094df7cf0bcc -R 8b16cbfea1aee4c8ac49aefcccb7ea15 +P 6c8ad2790eaede90b3f1ef62614e667178b2a8c4 +R 61699b7a12569d4bc746b73ba93dce41 U drh -Z 1d3ef6d9d156a8b50e6d1607d4475644 +Z 4386a51ac4f148f41d41e7eee93b8111 diff --git a/manifest.uuid b/manifest.uuid index 5da8c0d9aa..95eb9d1f72 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c8ad2790eaede90b3f1ef62614e667178b2a8c4 \ No newline at end of file +cf2dd45b58380de7f3e167b5357848d12872caa3 \ No newline at end of file diff --git a/src/func.c b/src/func.c index f33da23ebb..8a23cf34b2 100644 --- a/src/func.c +++ b/src/func.c @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.157 2007/05/15 11:55:09 drh Exp $ +** $Id: func.c,v 1.158 2007/05/15 13:27:07 drh Exp $ */ #include "sqliteInt.h" #include @@ -176,6 +176,7 @@ static void substrFunc( len = sqlite3_value_bytes(argv[0]); z = sqlite3_value_blob(argv[0]); if( z==0 ) return; + assert( len==sqlite3_value_bytes(argv[0]) ); }else{ z = sqlite3_value_text(argv[0]); if( z==0 ) return; @@ -242,8 +243,10 @@ static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ const char *z2; int i, n; if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return; - n = sqlite3_value_bytes(argv[0]); z2 = (char*)sqlite3_value_text(argv[0]); + n = sqlite3_value_bytes(argv[0]); + /* Verify that the call to _bytes() does not invalidate the _text() pointer */ + assert( z2==(char*)sqlite3_value_text(argv[0]) ); if( z2 ){ z1 = sqlite3_malloc(n+1); if( z1 ){ @@ -260,8 +263,10 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ const char *z2; int i, n; if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return; - n = sqlite3_value_bytes(argv[0]); z2 = (char*)sqlite3_value_text(argv[0]); + n = sqlite3_value_bytes(argv[0]); + /* Verify that the call to _bytes() does not invalidate the _text() pointer */ + assert( z2==(char*)sqlite3_value_text(argv[0]) ); if( z2 ){ z1 = sqlite3_malloc(n+1); if( z1 ){ @@ -562,6 +567,9 @@ static void likeFunc( const unsigned char *zA, *zB; int escape = 0; + zB = sqlite3_value_text(argv[0]); + zA = sqlite3_value_text(argv[1]); + /* Limit the length of the LIKE or GLOB pattern to avoid problems ** of deep recursion and N*N behavior in patternCompare(). */ @@ -569,9 +577,8 @@ static void likeFunc( sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); return; } + assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */ - zB = sqlite3_value_text(argv[0]); - zA = sqlite3_value_text(argv[1]); if( argc==3 ){ /* The escape character string must consist of a single UTF-8 character. ** Otherwise, return an error. @@ -655,8 +662,9 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ } case SQLITE_BLOB: { char *zText = 0; - int nBlob = sqlite3_value_bytes(argv[0]); char const *zBlob = sqlite3_value_blob(argv[0]); + int nBlob = sqlite3_value_bytes(argv[0]); + assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ if( 2*nBlob+4>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); @@ -722,12 +730,13 @@ static void hexFunc( const unsigned char *pBlob; char *zHex, *z; assert( argc==1 ); + pBlob = sqlite3_value_blob(argv[0]); n = sqlite3_value_bytes(argv[0]); if( n*2+1>SQLITE_MAX_LENGTH ){ sqlite3_result_error_toobig(context); return; } - pBlob = sqlite3_value_blob(argv[0]); + assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ z = zHex = sqlite3_malloc(n*2 + 1); if( zHex==0 ) return; for(i=0; iflags & (MEM_Blob|MEM_Str) ){ sqlite3VdbeMemExpandBlob(p); - if( (p->flags & MEM_Term)==0 ){ - p->flags &= ~MEM_Str; - } + p->flags &= ~MEM_Str; + p->flags |= MEM_Blob; + p->type = SQLITE_BLOB; return p->z; }else{ return sqlite3_value_text(pVal); diff --git a/www/capi3ref.tcl b/www/capi3ref.tcl index 07fca4c06a..7c5214e3e5 100644 --- a/www/capi3ref.tcl +++ b/www/capi3ref.tcl @@ -1,4 +1,4 @@ -set rcsid {$Id: capi3ref.tcl,v 1.57 2007/05/07 11:24:31 drh Exp $} +set rcsid {$Id: capi3ref.tcl,v 1.58 2007/05/15 13:27:08 drh Exp $} source common.tcl header {C/C++ Interface For SQLite Version 3} puts { @@ -391,20 +391,23 @@ int sqlite3_column_type(sqlite3_stmt*, int iCol); If the SQL statement is not currently point to a valid row, or if the the column index is out of range, the result is undefined. - If the result is a BLOB then the sqlite3_column_bytes() routine returns - the number of bytes in that BLOB. No type conversions occur. - If the result is a string (or a number since a number can be converted - into a string) then sqlite3_column_bytes() converts - the value into a UTF-8 string and returns - the number of bytes in the resulting string. The value returned does - not include the \\000 terminator at the end of the string. The - sqlite3_column_bytes16() routine converts the value into a UTF-16 - encoding and returns the number of bytes (not characters) in the - resulting string. The \\u0000 terminator is not included in this count. + If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() + routine returns the number of bytes in that BLOB or string. + If the result is a UTF-16 string, then sqlite3_column_bytes() converts + the string to UTF-8 and then returns the number of bytes. + If the result is a numeric value then sqlite3_column_bytes() uses + sqlite3_snprintf() to convert that value to a UTF-8 string and returns + the number of bytes in that string. + The value returned does + not include the \\000 terminator at the end of the string. + + The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes() + but leaves the result in UTF-16 instead of UTF-8. + The \\u0000 terminator is not included in this count. These routines attempt to convert the value where appropriate. For example, if the internal representation is FLOAT and a text result - is requested, sprintf() is used internally to do the conversion + is requested, sqlite3_snprintf() is used internally to do the conversion automatically. The following table details the conversions that are applied: @@ -459,24 +462,21 @@ int sqlite3_column_type(sqlite3_stmt*, int iCol); of conversion are done in place when it is possible, but sometime it is not possible and in those cases prior pointers are invalidated. - The safest and easiest to remember policy is this: assume that any - result from - - is invalided by subsequent calls to - - This means that you should always call sqlite3_column_bytes() or - sqlite3_column_bytes16() before calling sqlite3_column_blob(), - sqlite3_column_text(), or sqlite3_column_text16(). + The safest and easiest to remember policy is to invoke these routines + in one of the following ways: + + + In other words, you should call sqlite3_column_text(), sqlite3_column_blob(), + or sqlite3_column_text16() first to force the result into the desired + format, then invoke sqlite3_column_bytes() or sqlite3_column_bytes16() to + find the size of the result. Do not mix call to sqlite3_column_text() or + sqlite3_column_blob() with calls to sqlite3_column_bytes16(). And do not + mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes(). } api {} {