-C Extra\stests\sfor\sincremental\svacuum.\s(CVS\s3879)
-D 2007-04-27T07:55:38
+C Make\ssure\ssqlite3_value_bytes()\sdoes\snot\sreformat\sthe\scontent\safter\sa\ncall\sto\ssqlite3_value_blob().\s\sAdd\sdocumentation\sto\sexplain\sthis\shazard.\nAdd\smany\snew\stests.\s\sTicket\s#2321.\s(CVS\s3880)
+D 2007-04-27T17:16:20
F Makefile.in 8cab54f7c9f5af8f22fd97ddf1ecfd1e1860de62
F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F src/delete.c 5c0d89b3ef7d48fe1f5124bfe8341f982747fe29
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
F src/expr.c 2f0f9f89efe9170e5e6ca5d5e93a9d5896fff5ac
-F src/func.c b989aa0ecc66a6d48b46f297299d52f12d84bce9
+F src/func.c 89d8547a9cb1c5ad8e0b86b3d74de56e5254254b
F src/hash.c 67b23e14f0257b69a3e8aa663e4eeadc1a2b6fd5
F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
F src/insert.c 413cc06990cb3c401e64e596776c1e43934f8841
F src/sqliteInt.h 0b14d0eae083aafca0562d2261a404e5e5abc5f0
F src/table.c 6d0da66dde26ee75614ed8f584a1996467088d06
F src/tclsqlite.c ec69eb9ad56d03fbf7570ca1ca5ea947d1ec4b6f
-F src/test1.c 53b7eb5cba0012f592b5860f6ad3b5a3f887eb1e
+F src/test1.c f1271d41719d05348e6dc39722260e17b8d7ddc1
F src/test2.c 24458b17ab2f3c90cbc1c8446bd7ffe69be62f88
F src/test3.c 65f92247cf8592854e9bf5115b3fb711f8b33280
F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
F src/vdbe.c a3cf3792fdbd382f756eb7eb50006b2f3f8d4283
F src/vdbe.h 0025259af1939fb264a545816c69e4b5b8d52691
F src/vdbeInt.h 4b19fd8febad3fd14c4c97adaefc06754d323132
-F src/vdbeapi.c 245263aa2d70d87b1201753cddc881996f219843
+F src/vdbeapi.c 37fc2818bec64b361af73f3935699107bab0e625
F src/vdbeaux.c ef59545f53f90394283f2fd003375d3ebbf0bd6e
F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f
F src/vdbemem.c 981a113405bd9b80aeb71fe246a2f01708e8a8f7
F test/pragma.test fecb7085f58d9fb5172a5c0b63fd3b25c7bfb414
F test/printf.test 483b9fe75ffae1fb27328bdce5560b452ba83577
F test/progress.test 8b22b4974b0a95272566385f8cb8c341c7130df8 x
+F test/ptrchng.test 1c712dd6516e1377471744fa765e41c79a357da6
F test/quick.test 8e7ffe36a1c920cdcce5d641646abde2dafd764b
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
F test/rdonly.test b34db316525440d3b42c32e83942c02c37d28ef0
F www/audit.tcl 90e09d580f79c7efec0c7d6f447b7ec5c2dce5c0
F www/autoinc.tcl b357f5ba954b046ee35392ce0f884a2fcfcdea06
F www/c_interface.tcl b51b08591554c16a0c3ef718364a508ac25abc7e
-F www/capi3.tcl 7a7cc225fe02eb7ab861a6019b08baa0014409e1
-F www/capi3ref.tcl 80178d2697e97236c208a2a6a507e82d121acc71
+F www/capi3.tcl 88884dd743039d1a95aa57f4a5eb369de7744716
+F www/capi3ref.tcl 0d742d6bd59bc51bbb4be014e7ea47e97786d318
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 4d4180d6474d8d74460fb9333580b9b60c89f353
-R cb55629cd4ed6b5c3bd0582e6bc3a138
-U danielk1977
-Z f3e9134088bb4d98704fded975f43270
+P 40ba6493e9e8ba135552a2a0943ab499713ac001
+R ae6e82023418585801b4f01168703216
+U drh
+Z e4fdef4577a3571a48a38a52b01018a7
-40ba6493e9e8ba135552a2a0943ab499713ac001
\ No newline at end of file
+e92bd97a3726bbb7978489e2994747127c4aefcf
\ 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.141 2007/04/27 01:18:03 drh Exp $
+** $Id: func.c,v 1.142 2007/04/27 17:16:20 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
char *z1;
const char *z2;
- int i;
+ 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]);
if( z2 ){
- z1 = sqlite3_malloc(sqlite3_value_bytes(argv[0])+1);
+ z1 = sqlite3_malloc(n+1);
if( z1 ){
strcpy(z1, z2);
for(i=0; z1[i]; i++){
static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
char *z1;
const char *z2;
- int i;
+ 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]);
if( z2 ){
- z1 = sqlite3_malloc(sqlite3_value_bytes(argv[0])+1);
+ z1 = sqlite3_malloc(n+1);
if( z1 ){
strcpy(z1, z2);
for(i=0; z1[i]; i++){
int i, j; /* Loop counters */
assert( argc==3 );
+ nStr = sqlite3_value_bytes(argv[0]);
zStr = sqlite3_value_text(argv[0]);
if( zStr==0 ) return;
- nStr = sqlite3_value_bytes(argv[0]);
+ nPattern = sqlite3_value_bytes(argv[1]);
zPattern = sqlite3_value_text(argv[1]);
if( zPattern==0 || zPattern[0]==0 ) return;
- nPattern = sqlite3_value_bytes(argv[1]);
+ nRep = sqlite3_value_bytes(argv[2]);
zRep = sqlite3_value_text(argv[2]);
if( zRep==0 ) return;
- nRep = sqlite3_value_bytes(argv[2]);
if( nPattern>=nRep ){
nOut = nStr;
}else{
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]);
if( argc==1 ){
static const unsigned char zSpace[] = " ";
zCharSet = zSpace;
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
-** $Id: test1.c,v 1.239 2007/04/23 23:56:31 drh Exp $
+** $Id: test1.c,v 1.240 2007/04/27 17:16:20 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
int i;
for(i=0; i<argc; i++){
if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
+ int n = sqlite3_value_bytes(argv[i]);
sqlite3_result_text(context, (char*)sqlite3_value_text(argv[i]),
- sqlite3_value_bytes(argv[i]), SQLITE_TRANSIENT);
+ n, SQLITE_TRANSIENT);
break;
}
}
}
}
+/*
+** The following SQL function takes 4 arguments. The 2nd and
+** 4th argument must be one of these strings: 'text', 'text16',
+** or 'blob' corresponding to API functions
+**
+** sqlite3_value_text()
+** sqlite3_value_text16()
+** sqlite3_value_blob()
+**
+** The third argument is a string, either 'bytes' or 'bytes16' or 'noop',
+** corresponding to APIs:
+**
+** sqlite3_value_bytes()
+** sqlite3_value_bytes16()
+** noop
+**
+** The APIs designated by the 2nd through 4th arguments are applied
+** to the first argument in order. If the pointers returned by the
+** second and fourth are different, this routine returns 1. Otherwise,
+** this routine returns 0.
+**
+** This function is used to test to see when returned pointers from
+** the _text(), _text16() and _blob() APIs become invalidated.
+*/
+static void ptrChngFunction(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const void *p1, *p2;
+ const char *zCmd;
+ if( argc!=4 ) return;
+ zCmd = (const char*)sqlite3_value_text(argv[1]);
+ if( zCmd==0 ) return;
+ if( strcmp(zCmd,"text")==0 ){
+ p1 = (const void*)sqlite3_value_text(argv[0]);
+#ifndef SQLITE_OMIT_UTF16
+ }else if( strcmp(zCmd, "text16")==0 ){
+ p1 = (const void*)sqlite3_value_text16(argv[0]);
+#endif
+ }else if( strcmp(zCmd, "blob")==0 ){
+ p1 = (const void*)sqlite3_value_blob(argv[0]);
+ }else{
+ return;
+ }
+ zCmd = (const char*)sqlite3_value_text(argv[2]);
+ if( zCmd==0 ) return;
+ if( strcmp(zCmd,"bytes")==0 ){
+ sqlite3_value_bytes(argv[0]);
+#ifndef SQLITE_OMIT_UTF16
+ }else if( strcmp(zCmd, "bytes16")==0 ){
+ sqlite3_value_bytes16(argv[0]);
+#endif
+ }else if( strcmp(zCmd, "noop")==0 ){
+ /* do nothing */
+ }else{
+ return;
+ }
+ zCmd = (const char*)sqlite3_value_text(argv[3]);
+ if( zCmd==0 ) return;
+ if( strcmp(zCmd,"text")==0 ){
+ p2 = (const void*)sqlite3_value_text(argv[0]);
+#ifndef SQLITE_OMIT_UTF16
+ }else if( strcmp(zCmd, "text16")==0 ){
+ p2 = (const void*)sqlite3_value_text16(argv[0]);
+#endif
+ }else if( strcmp(zCmd, "blob")==0 ){
+ p2 = (const void*)sqlite3_value_blob(argv[0]);
+ }else{
+ return;
+ }
+ sqlite3_result_int(context, p1!=p2);
+}
+
+
/*
** Usage: sqlite_test_create_function DB
**
rc = sqlite3_create_function(db, "tkt2213func", 1, SQLITE_ANY, 0,
tkt2213Function, 0, 0);
}
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "pointer_change", 4, SQLITE_ANY, 0,
+ ptrChngFunction, 0, 0);
+ }
#ifndef SQLITE_OMIT_UTF16
/* Use the sqlite3_create_function16() API here. Mainly for fun, but also
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
- pBlob = sqlite3_column_blob(pStmt, col);
len = sqlite3_column_bytes(pStmt, col);
+ pBlob = sqlite3_column_blob(pStmt, col);
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len));
return TCL_OK;
}
const void *sqlite3_value_blob(sqlite3_value *pVal){
Mem *p = (Mem*)pVal;
if( p->flags & (MEM_Blob|MEM_Str) ){
+ if( (p->flags & MEM_Term)==0 ){
+ p->flags &= ~MEM_Str;
+ }
return p->z;
}else{
return sqlite3_value_text(pVal);
--- /dev/null
+# 2007 April 27
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.
+#
+# The focus of the tests in this file are to verify that the
+# underlying TEXT or BLOB representation of an sqlite3_value
+# changes appropriately when APIs from the following set are
+# called:
+#
+# sqlite3_value_text()
+# sqlite3_value_text16()
+# sqlite3_value_blob()
+# sqlite3_value_bytes()
+# sqlite3_value_bytes16()
+#
+# $Id: ptrchng.test,v 1.1 2007/04/27 17:16:22 drh Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# Register the "pointer_change" SQL function.
+#
+sqlite3_create_function db
+
+do_test ptrchng-1.1 {
+ execsql {
+ CREATE TABLE t1(x INTEGER PRIMARY KEY, y BLOB);
+ INSERT INTO t1 VALUES(1, 'abc');
+ INSERT INTO t1 VALUES(2,
+ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234356789');
+ INSERT INTO t1 VALUES(3, x'626c6f62');
+ INSERT INTO t1 VALUES(4,
+ x'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324'
+ );
+ SELECT count(*) FROM t1;
+ }
+} {4}
+
+# For the short entries that fit in the Mem.zBuf[], the pointer should
+# never change regardless of what type conversions occur.
+#
+do_test ptrchng-2.1 {
+ execsql {
+ SELECT pointer_change(y, 'text', 'noop', 'blob') FROM t1 WHERE x=1
+ }
+} {0}
+do_test ptrchng-2.2 {
+ execsql {
+ SELECT pointer_change(y, 'blob', 'noop', 'text') FROM t1 WHERE x=1
+ }
+} {0}
+ifcapable utf16 {
+ do_test ptrchng-2.3 {
+ execsql {
+ SELECT pointer_change(y, 'text', 'noop', 'text16') FROM t1 WHERE x=1
+ }
+ } {0}
+ do_test ptrchng-2.4 {
+ execsql {
+ SELECT pointer_change(y, 'blob', 'noop', 'text16') FROM t1 WHERE x=1
+ }
+ } {0}
+ do_test ptrchng-2.5 {
+ execsql {
+ SELECT pointer_change(y, 'text16', 'noop', 'blob') FROM t1 WHERE x=1
+ }
+ } {0}
+ do_test ptrchng-2.6 {
+ execsql {
+ SELECT pointer_change(y, 'text16', 'noop', 'text') FROM t1 WHERE x=1
+ }
+ } {0}
+}
+do_test ptrchng-2.11 {
+ execsql {
+ SELECT pointer_change(y, 'text', 'noop', 'blob') FROM t1 WHERE x=3
+ }
+} {0}
+do_test ptrchng-2.12 {
+ execsql {
+ SELECT pointer_change(y, 'blob', 'noop', 'text') FROM t1 WHERE x=3
+ }
+} {0}
+ifcapable utf16 {
+ do_test ptrchng-2.13 {
+ execsql {
+ SELECT pointer_change(y, 'text', 'noop', 'text16') FROM t1 WHERE x=3
+ }
+ } {0}
+ do_test ptrchng-2.14 {
+ execsql {
+ SELECT pointer_change(y, 'blob', 'noop', 'text16') FROM t1 WHERE x=3
+ }
+ } {0}
+ do_test ptrchng-2.15 {
+ execsql {
+ SELECT pointer_change(y, 'text16', 'noop', 'blob') FROM t1 WHERE x=3
+ }
+ } {0}
+ do_test ptrchng-2.16 {
+btree_breakpoint
+ execsql {
+ SELECT pointer_change(y, 'text16', 'noop', 'text') FROM t1 WHERE x=3
+ }
+ } {0}
+}
+
+# For the long entries that do not fit in the Mem.zBuf[], the pointer
+# should change sometimes.
+#
+do_test ptrchng-3.1 {
+ execsql {
+ SELECT pointer_change(y, 'text', 'noop', 'blob') FROM t1 WHERE x=2
+ }
+} {0}
+do_test ptrchng-3.2 {
+ execsql {
+ SELECT pointer_change(y, 'blob', 'noop', 'text') FROM t1 WHERE x=2
+ }
+} {0}
+ifcapable utf16 {
+ do_test ptrchng-3.3 {
+ execsql {
+ SELECT pointer_change(y, 'text', 'noop', 'text16') FROM t1 WHERE x=2
+ }
+ } {1}
+ do_test ptrchng-3.4 {
+ execsql {
+ SELECT pointer_change(y, 'blob', 'noop', 'text16') FROM t1 WHERE x=2
+ }
+ } {1}
+ do_test ptrchng-3.5 {
+ execsql {
+ SELECT pointer_change(y, 'text16', 'noop', 'blob') FROM t1 WHERE x=2
+ }
+ } {0}
+ do_test ptrchng-3.6 {
+ execsql {
+ SELECT pointer_change(y, 'text16', 'noop', 'text') FROM t1 WHERE x=2
+ }
+ } {1}
+}
+do_test ptrchng-3.11 {
+ execsql {
+ SELECT pointer_change(y, 'text', 'noop', 'blob') FROM t1 WHERE x=4
+ }
+} {0}
+do_test ptrchng-3.12 {
+ execsql {
+ SELECT pointer_change(y, 'blob', 'noop', 'text') FROM t1 WHERE x=4
+ }
+} {0}
+ifcapable utf16 {
+ do_test ptrchng-3.13 {
+ execsql {
+ SELECT pointer_change(y, 'text', 'noop', 'text16') FROM t1 WHERE x=4
+ }
+ } {1}
+ do_test ptrchng-3.14 {
+ execsql {
+ SELECT pointer_change(y, 'blob', 'noop', 'text16') FROM t1 WHERE x=4
+ }
+ } {1}
+ do_test ptrchng-3.15 {
+ execsql {
+ SELECT pointer_change(y, 'text16', 'noop', 'blob') FROM t1 WHERE x=4
+ }
+ } {0}
+ do_test ptrchng-3.16 {
+ execsql {
+ SELECT pointer_change(y, 'text16', 'noop', 'text') FROM t1 WHERE x=4
+ }
+ } {1}
+}
+
+# A call to _bytes() should never reformat a _text() or _blob().
+#
+do_test ptrchng-4.1 {
+ execsql {
+ SELECT pointer_change(y, 'text', 'bytes', 'text') FROM t1
+ }
+} {0 0 0 0}
+do_test ptrchng-4.2 {
+ execsql {
+ SELECT pointer_change(y, 'blob', 'bytes', 'blob') FROM t1
+ }
+} {0 0 0 0}
+
+# A call to _blob() should never trigger a reformat
+#
+do_test ptrchng-5.1 {
+ execsql {
+ SELECT pointer_change(y, 'text', 'bytes', 'blob') FROM t1
+ }
+} {0 0 0 0}
+ifcapable utf16 {
+ do_test ptrchng-5.2 {
+ execsql {
+ SELECT pointer_change(y, 'text16', 'noop', 'blob') FROM t1
+ }
+ } {0 0 0 0}
+ do_test ptrchng-5.3 {
+ execsql {
+ SELECT pointer_change(y, 'text16', 'bytes16', 'blob') FROM t1
+ }
+ } {0 0 0 0}
+}
+
+finish_test
-set rcsid {$Id: capi3.tcl,v 1.9 2005/03/11 04:39:58 drh Exp $}
+set rcsid {$Id: capi3.tcl,v 1.10 2007/04/27 17:16:22 drh Exp $}
source common.tcl
header {C/C++ Interface For SQLite Version 3}
is converted automatically.
</p>
+<p>
+Data format conversions can invalidate the pointer returned by
+prior calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
+sqlite3_column_text16(). Pointers might be invalided in the following
+cases:
+</p>
+<ul>
+<li><p>
+The initial content is a BLOB and sqlite3_column_text()
+or sqlite3_column_text16()
+is called. A zero-terminator might need to be added to the string.
+</p></li>
+<li><p>
+The initial content is UTF-8 text and sqlite3_column_bytes16() or
+sqlite3_column_text16() is called. The content must be converted to UTF-16.
+</p></li>
+<li><p>
+The initial content is UTF-16 text and sqlite3_column_bytes() or
+sqlite3_column_text() is called. The content must be converted to UTF-8.
+</p></li>
+</ul>
+<p>
+Note that conversions between UTF-16be and UTF-16le
+are always done in place and do
+not invalidate a prior pointer, though of course the content of the buffer
+that the prior pointer points to will have been modified. Other kinds
+of conversion are done in place when it is possible, but sometime it is
+not possible and in those cases prior pointers are invalidated.
+</p>
+
+<p>
+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
+<ul>
+<li>sqlite3_column_bytes(),</li>
+<li>sqlite3_column_bytes16(),</li>
+<li>sqlite3_column_text(), or</li>
+<li>sqlite3_column_text16().</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().
+</p>
+
<h4>2.3 User-defined functions</h4>
<p>
-set rcsid {$Id: capi3ref.tcl,v 1.55 2007/04/16 15:35:24 drh Exp $}
+set rcsid {$Id: capi3ref.tcl,v 1.56 2007/04/27 17:16:22 drh Exp $}
source common.tcl
header {C/C++ Interface For SQLite Version 3}
puts {
Note that when type conversions occur, pointers returned by prior
calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
- sqlite3_column_text16() may be invalidated. So, for example, if
- you initially call sqlite3_column_text() and get back a pointer to
- a UTF-8 string, then you call sqlite3_column_text16(), after the
- call to sqlite3_column_text16() the pointer returned by the prior
- call to sqlite3_column_text() will likely point to deallocated memory.
- Attempting to use the original pointer might lead to heap corruption
- or a segfault. Note also that calls to sqlite3_column_bytes()
- and sqlite3_column_bytes16() can also cause type conversion that
- and deallocate prior buffers. Use these routines carefully.
+ sqlite3_column_text16() may be invalidated.
+ Type conversions and pointer invalidations might occur
+ in the following cases:
+
+ <ul>
+ <li><p>
+ The initial content is a BLOB and sqlite3_column_text()
+ or sqlite3_column_text16()
+ is called. A zero-terminator might need to be added to the string.
+ </p></li>
+ <li><p>
+ The initial content is UTF-8 text and sqlite3_column_bytes16() or
+ sqlite3_column_text16() is called. The content must be converted to UTF-16.
+ </p></li>
+ <li><p>
+ The initial content is UTF-16 text and sqlite3_column_bytes() or
+ sqlite3_column_text() is called. The content must be converted to UTF-8.
+ </p></li>
+ </ul>
+
+ Conversions between UTF-16be and UTF-16le
+ are always done in place and do
+ not invalidate a prior pointer, though of course the content of the buffer
+ that the prior pointer points to will have been modified. Other kinds
+ 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
+ <ul>
+ <li>sqlite3_column_bytes(),</li>
+ <li>sqlite3_column_bytes16(),</li>
+ <li>sqlite3_column_text(), or</li>
+ <li>sqlite3_column_text16().</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().
+
}
api {} {
See the documentation under sqlite3_column_blob for additional
information.
+
+ Please pay particular attention to the fact that the pointer that
+ is returned from sqlite3_value_blob(), sqlite3_value_text(), or
+ sqlite3_value_text16() can be invalidated by a subsequent call to
+ sqlite3_value_bytes(), sqlite3_value_bytes16(), sqlite_value_text(),
+ or sqlite3_value_text16().
}
api {} {