-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
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
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
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
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
-6c8ad2790eaede90b3f1ef62614e667178b2a8c4
\ No newline at end of file
+cf2dd45b58380de7f3e167b5357848d12872caa3
\ No newline at end of file
** 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 <ctype.h>
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;
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 ){
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 ){
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().
*/
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.
}
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);
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; i<n; i++, pBlob++){
int i, j; /* Loop counters */
assert( argc==3 );
- nStr = sqlite3_value_bytes(argv[0]);
zStr = sqlite3_value_text(argv[0]);
if( zStr==0 ) return;
- nPattern = sqlite3_value_bytes(argv[1]);
+ nStr = sqlite3_value_bytes(argv[0]);
+ assert( zStr==sqlite3_value_text(argv[0]) ); /* No encoding change */
zPattern = sqlite3_value_text(argv[1]);
if( zPattern==0 || zPattern[0]==0 ) return;
- nRep = sqlite3_value_bytes(argv[2]);
+ nPattern = sqlite3_value_bytes(argv[1]);
+ assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */
zRep = sqlite3_value_text(argv[2]);
if( zRep==0 ) return;
+ nRep = sqlite3_value_bytes(argv[2]);
+ assert( zRep==sqlite3_value_text(argv[2]) );
nOut = nStr + 1;
assert( nOut<SQLITE_MAX_LENGTH );
zOut = sqlite3_malloc((int)nOut);
if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
return;
}
- nIn = sqlite3_value_bytes(argv[0]);
zIn = sqlite3_value_text(argv[0]);
if( zIn==0 ) return;
+ nIn = sqlite3_value_bytes(argv[0]);
+ assert( zIn==sqlite3_value_text(argv[0]) );
if( argc==1 ){
static const unsigned char lenOne[] = { 1 };
static const unsigned char *azOne[] = { (u8*)" " };
Mem *p = (Mem*)pVal;
if( p->flags & (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);
-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 {
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:
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
- <ul>
- <li>sqlite3_column_blob(),</li>
- <li>sqlite3_column_text(), or</li>
- <li>sqlite3_column_text16()</li>
- </ul>
- is invalided by subsequent calls to
+ The safest and easiest to remember policy is to invoke these routines
+ in one of the following ways:
+
<ul>
- <li>sqlite3_column_bytes(),</li>
- <li>sqlite3_column_bytes16(),</li>
- <li>sqlite3_column_text(), or</li>
- <li>sqlite3_column_text16().</li>
+ <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
+ <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
+ <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li>
</ul>
- This means that you should always call sqlite3_column_bytes() or
- sqlite3_column_bytes16() <u>before</u> calling sqlite3_column_blob(),
- sqlite3_column_text(), or sqlite3_column_text16().
+ 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 {} {