1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

The sqlite3_value object now carries an sqlite3* pointer to use for

recording malloc failures.  This eliminates the need to pass sqlite3*
pointers into many internal interfaces.  Also added more mutexing. (CVS 4263)

FossilOrigin-Name: 9287276191a582c1cf7cf6b71d8399727d8e534d
This commit is contained in:
drh
2007-08-21 19:33:56 +00:00
parent e30f442622
commit b21c8cd4f6
26 changed files with 397 additions and 307 deletions

View File

@@ -1,5 +1,5 @@
C Adding\smore\sthread\slocking\scode.\s\sThis\sis\san\sincremental\scheck-in.\s(CVS\s4262) C The\ssqlite3_value\sobject\snow\scarries\san\ssqlite3*\spointer\sto\suse\sfor\nrecording\smalloc\sfailures.\s\sThis\seliminates\sthe\sneed\sto\spass\ssqlite3*\npointers\sinto\smany\sinternal\sinterfaces.\s\sAlso\sadded\smore\smutexing.\s(CVS\s4263)
D 2007-08-21T16:15:56 D 2007-08-21T19:33:56
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -79,26 +79,26 @@ F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
F src/alter.c f0aac0060ae8102e58f210b44d35b53438d53173 F src/alter.c f0aac0060ae8102e58f210b44d35b53438d53173
F src/analyze.c a14237d869c6bea0846493b59317e4097e81a0b6 F src/analyze.c a14237d869c6bea0846493b59317e4097e81a0b6
F src/attach.c a52225c75b107be8c5bc144a2b6d20201be3f8f8 F src/attach.c a52225c75b107be8c5bc144a2b6d20201be3f8f8
F src/auth.c 5ea90bc93dfea46e9fe4bf531e14c7cd98219ecb F src/auth.c 083c1205b45e3f52291ec539d396b4fc557856b3
F src/btree.c 8e529f390d8d1d83acbaf13cb1c09da8361cf5b1 F src/btree.c 4cfe2fe8d61dd906662833732919dc27116ffce7
F src/btree.h 525105564c87111922412368f2e4301c36e74ac1 F src/btree.h aeb85d6a48573785666fb97566bf5802d5f9b7ca
F src/btreeInt.h e93edf57832278138b98cf60cbc54241103c6988 F src/btreeInt.h e93edf57832278138b98cf60cbc54241103c6988
F src/build.c add67be992307b4b11849a6611bfd3352aacde92 F src/build.c 2159551184160e2cf17ff945e9a05fbe6f331c3d
F src/callback.c 143436453bb93e831c9574fea0b9b9eb90e40ff3 F src/callback.c fdd527372162a974094103eae82119fcfcf11260
F src/complete.c ea63834e798a0ab14159bdc6e6cabc3df21aa346 F src/complete.c b6dea59fb6d7b3201fa1e0e552cda8c2258a4f50
F src/date.c 70a5af1944c0b76bed917cab3c1ca47e5f97d359 F src/date.c a80b33f6e70d619978622547d2c78ab8b036b31a
F src/delete.c 849846d06d29851dde0d9f424a5de5817eb140d1 F src/delete.c 849846d06d29851dde0d9f424a5de5817eb140d1
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
F src/expr.c 3ea108a9e409f58b8203e29c54442da5085be5bf F src/expr.c 3ea108a9e409f58b8203e29c54442da5085be5bf
F src/func.c 8516d5f97ddc1004537490fbaffa9a8b0da5c4bb F src/func.c 36440cb02589fd4697cbbf0b351eeedc160d1f4b
F src/hash.c 2f322979071dd2bdba7503b5276d66f028744382 F src/hash.c 2f322979071dd2bdba7503b5276d66f028744382
F src/hash.h 3ad3da76bfb954978d227bf495568b0e6da2c19e F src/hash.h 3ad3da76bfb954978d227bf495568b0e6da2c19e
F src/insert.c 633322aef1799f6604fa805e12488bc628570b0c F src/insert.c 633322aef1799f6604fa805e12488bc628570b0c
F src/legacy.c a83519a8fbb488c3155fca577b010d590ec479e9 F src/legacy.c a83519a8fbb488c3155fca577b010d590ec479e9
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35 F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
F src/loadext.c 780748f3f55a3b5af6ed0adfd58035f728cde4ca F src/loadext.c dd803303fd06ef0b13913faaa4a7fc7d8c8c4e77
F src/main.c 1f6f46975182c589c4942c708c9821db7c5d5772 F src/main.c 7cec512d2c83afea2b83977b384633b9edb1ae1d
F src/malloc.c c2f5da620d8e030c6974a0ddcaeb7b408c9bdb3d F src/malloc.c c291b07b6b03ba1a1db0c24f630b745071679ed0
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217 F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
F src/mem1.c 30bf8be3846f92fdf88c490c5e5378512383bcbe F src/mem1.c 30bf8be3846f92fdf88c490c5e5378512383bcbe
F src/mem2.c 482f0aaf14e8ef1db64cb8c5b9a9bfe708297c92 F src/mem2.c 482f0aaf14e8ef1db64cb8c5b9a9bfe708297c92
@@ -118,23 +118,23 @@ F src/pager.c df16604a2a8c6808cd9b309a7e1bdb556d868c8e
F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8 F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8
F src/parse.y 2d2ce439dc6184621fb0b86f4fc5aca7f391a590 F src/parse.y 2d2ce439dc6184621fb0b86f4fc5aca7f391a590
F src/pragma.c 9b989506a1b7c8aecd6befb8235e2f57a4aba7e5 F src/pragma.c 9b989506a1b7c8aecd6befb8235e2f57a4aba7e5
F src/prepare.c 5bc8c7a943215302943fec831f8c646f6dfdf76a F src/prepare.c d30764fabc3eb704c0d18bdeb9f38df028f19567
F src/printf.c a8f46e0ed360c18d40e89aa636533be300b406c2 F src/printf.c a8f46e0ed360c18d40e89aa636533be300b406c2
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2 F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
F src/sqlite.h.in c691ae04f7c064d853710a1eff4707549a54e1f8 F src/sqlite.h.in 95e159919060f9c6e060ff420ce17490f7b6a0f3
F src/sqlite3ext.h 647a6b8a8f76ff6c9611e4a071531d8e63ff2d6b F src/sqlite3ext.h 647a6b8a8f76ff6c9611e4a071531d8e63ff2d6b
F src/sqliteInt.h c9ba3861d1e8835caeb0c89fca7cddd12779e1ac F src/sqliteInt.h 23eb6a5b1f10d5d3d34c3c7846b7c3b93acf1276
F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
F src/table.c c725e47f6f3092b9a7b569fc58e408e2173ee008 F src/table.c c725e47f6f3092b9a7b569fc58e408e2173ee008
F src/tclsqlite.c 299fb45c5cf983b49b2c984b87b936b8132fbfe2 F src/tclsqlite.c 299fb45c5cf983b49b2c984b87b936b8132fbfe2
F src/test1.c 9e9651b0b9f85654b4bf28dfad787bc21a33aae5 F src/test1.c 70b96fc5ef8d013e2da0f936a62fe76e387faf83
F src/test2.c 4f742e99ed1bea5c14692f627bdb59a146f30504 F src/test2.c 4f742e99ed1bea5c14692f627bdb59a146f30504
F src/test3.c 2e4da0fe90a0aa8cf9276ea34cbe92e91dc1db07 F src/test3.c 2e4da0fe90a0aa8cf9276ea34cbe92e91dc1db07
F src/test4.c d97b87919dc3db1cc5fccc04a33f030d5940e1a9 F src/test4.c d97b87919dc3db1cc5fccc04a33f030d5940e1a9
F src/test5.c 81353afad5d795ae7155bffce1e4deef10ee8e22 F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4
F src/test6.c da83a0e49c03e8a25f4ce6e25c537c6617c14fc0 F src/test6.c da83a0e49c03e8a25f4ce6e25c537c6617c14fc0
F src/test7.c 50f5aa04fd751528ad5ee50e9be9ecee6f0b574a F src/test7.c 50f5aa04fd751528ad5ee50e9be9ecee6f0b574a
F src/test8.c 4bf571b82e502094846ae06e30fe028f190aaaae F src/test8.c 4bf571b82e502094846ae06e30fe028f190aaaae
@@ -153,17 +153,17 @@ F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59
F src/tokenize.c e39527c9c867774a92716c669a48ad8fbc3cdc63 F src/tokenize.c e39527c9c867774a92716c669a48ad8fbc3cdc63
F src/trigger.c dccc6fbf37d12193c90ede5b026bbd195d505ff4 F src/trigger.c dccc6fbf37d12193c90ede5b026bbd195d505ff4
F src/update.c e89b980b443d44b68bfc0b1746cdb6308e049ac9 F src/update.c e89b980b443d44b68bfc0b1746cdb6308e049ac9
F src/utf.c 853f97ce0d3cff8dbaef517a6dc475f7001a67c5 F src/utf.c 4af6259d5906b5a1bf3035cc387c4d7907bdd56e
F src/util.c 23251cee7867dfdcc80b05d278dbca71586d95cf F src/util.c 3f9c0387b54f977726790f52ab92cd3d9379b367
F src/vacuum.c 318ccae7c4e3ddf241aeaee4d2611bfe1949a373 F src/vacuum.c 318ccae7c4e3ddf241aeaee4d2611bfe1949a373
F src/vdbe.c f1a9a29da48ccfa49042df478abb478520589f37 F src/vdbe.c 9d4d00589c174aad9a616f1615464ddddebba0ec
F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3 F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3
F src/vdbeInt.h 8e360d326328e7a66100f468697edf9cfb4567dc F src/vdbeInt.h 39fb069ce04137545ca0bc790f80ddc64a8c99d9
F src/vdbeapi.c b4a1f4d56906a43f40c2bc47d7b142db3759c14e F src/vdbeapi.c 09eb4fe5ce6e8e4558ca3fa1e22241f2d3895bf0
F src/vdbeaux.c 14b48bfc6334682e5e5858a0835f8b00d8751953 F src/vdbeaux.c b0aeed4ff33352904b392ee6c7408bae5b141b9b
F src/vdbeblob.c ac223e6d3acaa3321ce09c11c47bf0d05b37372f F src/vdbeblob.c d12ed95dac0992e1e372d079d76af047cc42f7c7
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6 F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
F src/vdbemem.c 2843e6f91e8f19cfd72cfc7b24a03f1647db3c28 F src/vdbemem.c 3de25d78e7b1d0af7a05199de905cea8c43aed5d
F src/vtab.c ee29237ecc9b310dc43c0c2ac5caa6c6a20787be F src/vtab.c ee29237ecc9b310dc43c0c2ac5caa6c6a20787be
F src/where.c 2776a0caf8cbbfd6ec79cfb1cd9bc25074055e5e F src/where.c 2776a0caf8cbbfd6ec79cfb1cd9bc25074055e5e
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617 F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
@@ -558,7 +558,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
P 3787563e90d7210d349ee36484c3f008c955552e P 7428732b1fa04b83eda0a3539834693ef351313e
R 059b95f5c37a602e37abf433f570fd9a R 913d5d6bd631d176ac289a9e0cf82ff0
U drh U drh
Z da09ba003aea60219dd1a004da17c3aa Z c581f4a42a4b4dc59e9659821c9fdece

View File

@@ -1 +1 @@
7428732b1fa04b83eda0a3539834693ef351313e 9287276191a582c1cf7cf6b71d8399727d8e534d

View File

@@ -14,7 +14,7 @@
** systems that do not need this facility may omit it by recompiling ** systems that do not need this facility may omit it by recompiling
** the library with -DSQLITE_OMIT_AUTHORIZATION=1 ** the library with -DSQLITE_OMIT_AUTHORIZATION=1
** **
** $Id: auth.c,v 1.26 2007/05/14 11:34:47 drh Exp $ ** $Id: auth.c,v 1.27 2007/08/21 19:33:56 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -74,9 +74,11 @@ int sqlite3_set_authorizer(
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pArg void *pArg
){ ){
sqlite3_mutex_enter(db->mutex);
db->xAuth = xAuth; db->xAuth = xAuth;
db->pAuthArg = pArg; db->pAuthArg = pArg;
sqlite3ExpirePreparedStatements(db); sqlite3ExpirePreparedStatements(db);
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK; return SQLITE_OK;
} }

View File

@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give. ** May you share freely, never taking more than you give.
** **
************************************************************************* *************************************************************************
** $Id: btree.c,v 1.405 2007/08/21 13:11:01 danielk1977 Exp $ ** $Id: btree.c,v 1.406 2007/08/21 19:33:56 drh Exp $
** **
** This file implements a external (disk-based) database using BTrees. ** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information. ** See the header comment on "btreeInt.h" for additional information.
@@ -3706,6 +3706,13 @@ int sqlite3BtreeEof(BtCursor *pCur){
return (CURSOR_VALID!=pCur->eState); return (CURSOR_VALID!=pCur->eState);
} }
/*
** Return the database connection handle for a cursor.
*/
sqlite3 *sqlite3BtreeCursorDb(const BtCursor *pCur){
return pCur->pBtree->pSqlite;
}
/* /*
** Advance the cursor to the next entry in the database. If ** Advance the cursor to the next entry in the database. If
** successful then set *pRes=0. If the cursor ** successful then set *pRes=0. If the cursor

View File

@@ -13,7 +13,7 @@
** subsystem. See comments in the source code for a detailed description ** subsystem. See comments in the source code for a detailed description
** of what each interface routine does. ** of what each interface routine does.
** **
** @(#) $Id: btree.h,v 1.84 2007/08/20 22:48:42 drh Exp $ ** @(#) $Id: btree.h,v 1.85 2007/08/21 19:33:56 drh Exp $
*/ */
#ifndef _BTREE_H_ #ifndef _BTREE_H_
#define _BTREE_H_ #define _BTREE_H_
@@ -150,6 +150,7 @@ int sqlite3BtreeFlags(BtCursor*);
int sqlite3BtreePrevious(BtCursor*, int *pRes); int sqlite3BtreePrevious(BtCursor*, int *pRes);
int sqlite3BtreeKeySize(BtCursor*, i64 *pSize); int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*); int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
sqlite3 *sqlite3BtreeCursorDb(const BtCursor*);
const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt); const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt); const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
int sqlite3BtreeDataSize(BtCursor*, u32 *pSize); int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);

View File

@@ -22,7 +22,7 @@
** COMMIT ** COMMIT
** ROLLBACK ** ROLLBACK
** **
** $Id: build.c,v 1.436 2007/08/17 01:14:38 drh Exp $ ** $Id: build.c,v 1.437 2007/08/21 19:33:56 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -3369,6 +3369,7 @@ KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(pParse->db, nBytes); KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(pParse->db, nBytes);
if( pKey ){ if( pKey ){
pKey->db = pParse->db;
pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]); pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) ); assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
for(i=0; i<nCol; i++){ for(i=0; i<nCol; i++){

View File

@@ -13,7 +13,7 @@
** This file contains functions used to access the internal hash tables ** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences. ** of user defined functions and collation sequences.
** **
** $Id: callback.c,v 1.20 2007/08/16 10:09:02 danielk1977 Exp $ ** $Id: callback.c,v 1.21 2007/08/21 19:33:56 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -36,8 +36,8 @@ static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
if( db->xCollNeeded16 ){ if( db->xCollNeeded16 ){
char const *zExternal; char const *zExternal;
sqlite3_value *pTmp = sqlite3ValueNew(db); sqlite3_value *pTmp = sqlite3ValueNew(db);
sqlite3ValueSetStr(db, pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC); sqlite3ValueSetStr(pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC);
zExternal = sqlite3ValueText(db, pTmp, SQLITE_UTF16NATIVE); zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
if( zExternal ){ if( zExternal ){
db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal); db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
} }

View File

@@ -16,7 +16,7 @@
** separating it out, the code will be automatically omitted from ** separating it out, the code will be automatically omitted from
** static links that do not use it. ** static links that do not use it.
** **
** $Id: complete.c,v 1.4 2007/08/16 10:09:02 danielk1977 Exp $ ** $Id: complete.c,v 1.5 2007/08/21 19:33:56 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#ifndef SQLITE_OMIT_COMPLETE #ifndef SQLITE_OMIT_COMPLETE
@@ -251,8 +251,8 @@ int sqlite3_complete16(const void *zSql){
int rc = SQLITE_NOMEM; int rc = SQLITE_NOMEM;
pVal = sqlite3ValueNew(0); pVal = sqlite3ValueNew(0);
sqlite3ValueSetStr(0, pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
zSql8 = sqlite3ValueText(0, pVal, SQLITE_UTF8); zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
if( zSql8 ){ if( zSql8 ){
rc = sqlite3_complete(zSql8); rc = sqlite3_complete(zSql8);
} }

View File

@@ -16,7 +16,7 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope. ** All other code has file scope.
** **
** $Id: date.c,v 1.70 2007/08/21 10:44:16 drh Exp $ ** $Id: date.c,v 1.71 2007/08/21 19:33:56 drh Exp $
** **
** SQLite processes all times and dates as Julian Day numbers. The ** SQLite processes all times and dates as Julian Day numbers. The
** dates and times are stored as the number of days since noon ** dates and times are stored as the number of days since noon
@@ -905,7 +905,7 @@ static void ctimeFunc(
){ ){
sqlite3_value *pVal = sqlite3ValueNew(0); sqlite3_value *pVal = sqlite3ValueNew(0);
if( pVal ){ if( pVal ){
sqlite3ValueSetStr(0, pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC); sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
timeFunc(context, 1, &pVal); timeFunc(context, 1, &pVal);
sqlite3ValueFree(pVal); sqlite3ValueFree(pVal);
} }
@@ -923,7 +923,7 @@ static void cdateFunc(
){ ){
sqlite3_value *pVal = sqlite3ValueNew(0); sqlite3_value *pVal = sqlite3ValueNew(0);
if( pVal ){ if( pVal ){
sqlite3ValueSetStr(0, pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC); sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
dateFunc(context, 1, &pVal); dateFunc(context, 1, &pVal);
sqlite3ValueFree(pVal); sqlite3ValueFree(pVal);
} }
@@ -941,7 +941,7 @@ static void ctimestampFunc(
){ ){
sqlite3_value *pVal = sqlite3ValueNew(0); sqlite3_value *pVal = sqlite3ValueNew(0);
if( pVal ){ if( pVal ){
sqlite3ValueSetStr(0, pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC); sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
datetimeFunc(context, 1, &pVal); datetimeFunc(context, 1, &pVal);
sqlite3ValueFree(pVal); sqlite3ValueFree(pVal);
} }

View File

@@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope. ** All other code has file scope.
** **
** $Id: func.c,v 1.167 2007/08/21 10:44:16 drh Exp $ ** $Id: func.c,v 1.168 2007/08/21 19:33:56 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -1062,13 +1062,13 @@ static void test_destructor(
test_destructor_count_var++; test_destructor_count_var++;
assert( nArg==1 ); assert( nArg==1 );
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
len = sqlite3ValueBytes(0, argv[0], ENC(db)); len = sqlite3ValueBytes(argv[0], ENC(db));
zVal = sqlite3MallocZero(len+3); zVal = sqlite3MallocZero(len+3);
zVal[len] = 0; zVal[len] = 0;
zVal[len-1] = 0; zVal[len-1] = 0;
assert( zVal ); assert( zVal );
zVal++; zVal++;
memcpy(zVal, sqlite3ValueText(0, argv[0], ENC(db)), len); memcpy(zVal, sqlite3ValueText(argv[0], ENC(db)), len);
if( ENC(db)==SQLITE_UTF8 ){ if( ENC(db)==SQLITE_UTF8 ){
sqlite3_result_text(pCtx, zVal, -1, destructor); sqlite3_result_text(pCtx, zVal, -1, destructor);
#ifndef SQLITE_OMIT_UTF16 #ifndef SQLITE_OMIT_UTF16
@@ -1271,10 +1271,10 @@ static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv)
max = sqlite3_user_data(context)!=0; max = sqlite3_user_data(context)!=0;
cmp = sqlite3MemCompare(pBest, pArg, pColl); cmp = sqlite3MemCompare(pBest, pArg, pColl);
if( (max && cmp<0) || (!max && cmp>0) ){ if( (max && cmp<0) || (!max && cmp>0) ){
sqlite3VdbeMemCopy(0, pBest, pArg); sqlite3VdbeMemCopy(pBest, pArg);
} }
}else{ }else{
sqlite3VdbeMemCopy(0, pBest, pArg); sqlite3VdbeMemCopy(pBest, pArg);
} }
} }
static void minMaxFinalize(sqlite3_context *context){ static void minMaxFinalize(sqlite3_context *context){

View File

@@ -260,7 +260,7 @@ const sqlite3_api_routines sqlite3_apis = {
** error message text. The calling function should free this memory ** error message text. The calling function should free this memory
** by calling sqlite3_free(). ** by calling sqlite3_free().
*/ */
int sqlite3_load_extension( static int sqlite3LoadExtension(
sqlite3 *db, /* Load the extension into this database connection */ sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */ const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
@@ -329,6 +329,18 @@ int sqlite3_load_extension(
db->aExtension[db->nExtension-1] = handle; db->aExtension[db->nExtension-1] = handle;
return SQLITE_OK; return SQLITE_OK;
} }
int sqlite3_load_extension(
sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
char **pzErrMsg /* Put error message here if not 0 */
){
int rc;
sqlite3_mutex_enter(db->mutex);
rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg);
sqlite3_mutex_leave(db->mutex);
return rc;
}
/* /*
** Call this routine when the database connection is closing in order ** Call this routine when the database connection is closing in order
@@ -336,6 +348,7 @@ int sqlite3_load_extension(
*/ */
void sqlite3CloseExtensions(sqlite3 *db){ void sqlite3CloseExtensions(sqlite3 *db){
int i; int i;
assert( sqlite3_mutex_held(db->mutex) );
for(i=0; i<db->nExtension; i++){ for(i=0; i<db->nExtension; i++){
sqlite3OsDlClose(db->pVfs, db->aExtension[i]); sqlite3OsDlClose(db->pVfs, db->aExtension[i]);
} }
@@ -347,11 +360,13 @@ void sqlite3CloseExtensions(sqlite3 *db){
** default so as not to open security holes in older applications. ** default so as not to open security holes in older applications.
*/ */
int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
sqlite3_mutex_enter(db->mutex);
if( onoff ){ if( onoff ){
db->flags |= SQLITE_LoadExtension; db->flags |= SQLITE_LoadExtension;
}else{ }else{
db->flags &= ~SQLITE_LoadExtension; db->flags &= ~SQLITE_LoadExtension;
} }
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK; return SQLITE_OK;
} }

View File

@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be ** other files are for internal use by SQLite and should not be
** accessed by users of the library. ** accessed by users of the library.
** **
** $Id: main.c,v 1.392 2007/08/21 16:15:56 drh Exp $ ** $Id: main.c,v 1.393 2007/08/21 19:33:56 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -819,7 +819,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){
assert( !db->mallocFailed ); assert( !db->mallocFailed );
z = sqlite3_value_text16(db->pErr); z = sqlite3_value_text16(db->pErr);
if( z==0 ){ if( z==0 ){
sqlite3ValueSetStr(db, db->pErr, -1, sqlite3ErrStr(db->errCode), sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
SQLITE_UTF8, SQLITE_STATIC); SQLITE_UTF8, SQLITE_STATIC);
z = sqlite3_value_text16(db->pErr); z = sqlite3_value_text16(db->pErr);
} }
@@ -1116,8 +1116,8 @@ int sqlite3_open16(
assert( ppDb ); assert( ppDb );
*ppDb = 0; *ppDb = 0;
pVal = sqlite3ValueNew(0); pVal = sqlite3ValueNew(0);
sqlite3ValueSetStr(0, pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC); sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
zFilename8 = sqlite3ValueText(0, pVal, SQLITE_UTF8); zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
if( zFilename8 ){ if( zFilename8 ){
rc = openDatabase(zFilename8, ppDb, rc = openDatabase(zFilename8, ppDb,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);

View File

@@ -12,24 +12,46 @@
** Memory allocation functions used throughout sqlite. ** Memory allocation functions used throughout sqlite.
** **
** **
** $Id: malloc.c,v 1.7 2007/08/21 10:44:16 drh Exp $ ** $Id: malloc.c,v 1.8 2007/08/21 19:33:56 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <stdarg.h> #include <stdarg.h>
#include <ctype.h> #include <ctype.h>
/* /*
** Set the soft heap-size limit for the current thread. Passing a negative ** This routine runs when the memory allocator sees that the
** value indicates no limit. ** total memory allocation is about to exceed the soft heap
** limit.
*/
static void softHeapLimitEnforcer(
void *NotUsed,
sqlite3_uint64 inUse,
unsigned int allocSize
){
sqlite3_release_memory(allocSize);
}
/*
** Set the soft heap-size limit for the current thread. Passing a
** zero or negative value indicates no limit.
*/ */
void sqlite3_soft_heap_limit(int n){ void sqlite3_soft_heap_limit(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT sqlite3_uint64 iLimit;
ThreadData *pTd = sqlite3ThreadData(); int overage;
if( pTd ){ if( n<0 ){
pTd->nSoftHeapLimit = n; iLimit = 0;
}else{
iLimit = n;
}
if( iLimit>0 ){
sqlite3_memory_alarm(softHeapLimitEnforcer, 0, iLimit);
}else{
sqlite3_memory_alarm(0, 0, 0);
}
overage = sqlite3_memory_used() - n;
if( overage>0 ){
sqlite3_release_memory(overage);
} }
sqlite3ReleaseThreadData();
#endif
} }
/* /*
@@ -63,7 +85,7 @@ void *sqlite3DbMallocZero(sqlite3 *db, unsigned n){
void *p = sqlite3_malloc(n); void *p = sqlite3_malloc(n);
if( p ){ if( p ){
memset(p, 0, n); memset(p, 0, n);
}else{ }else if( db ){
db->mallocFailed = 1; db->mallocFailed = 1;
} }
return p; return p;
@@ -196,29 +218,3 @@ int sqlite3ApiExit(sqlite3* db, int rc){
} }
return rc & (db ? db->errMask : 0xff); return rc & (db ? db->errMask : 0xff);
} }
#ifdef SQLITE_MEMDEBUG
/*
** This function sets a flag in the thread-specific-data structure that will
** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called.
*/
#if 0
void sqlite3MallocDisallow(){
#if 0
assert( sqlite3_mallocDisallowed>=0 );
sqlite3_mallocDisallowed++;
#endif
}
/*
** This function clears the flag set in the thread-specific-data structure set
** by sqlite3MallocDisallow().
*/
void sqlite3MallocAllow(){
#if 0
assert( sqlite3_mallocDisallowed>0 );
sqlite3_mallocDisallowed--;
#endif
}
#endif
#endif

View File

@@ -13,7 +13,7 @@
** interface, and routines that contribute to loading the database schema ** interface, and routines that contribute to loading the database schema
** from disk. ** from disk.
** **
** $Id: prepare.c,v 1.55 2007/08/21 10:44:16 drh Exp $ ** $Id: prepare.c,v 1.56 2007/08/21 19:33:56 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -470,6 +470,7 @@ int sqlite3Prepare(
if( sqlite3SafetyOn(db) ){ if( sqlite3SafetyOn(db) ){
return SQLITE_MISUSE; return SQLITE_MISUSE;
} }
assert( sqlite3_mutex_held(db->mutex) );
/* If any attached database schemas are locked, do not proceed with /* If any attached database schemas are locked, do not proceed with
** compilation. Instead return SQLITE_LOCKED immediately. ** compilation. Instead return SQLITE_LOCKED immediately.
@@ -563,6 +564,20 @@ int sqlite3Prepare(
assert( (rc&db->errMask)==rc ); assert( (rc&db->errMask)==rc );
return rc; return rc;
} }
static int sqlite3LockAndPrepare(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
){
int rc;
sqlite3_mutex_enter(db->mutex);
rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail);
sqlite3_mutex_leave(db->mutex);
return rc;
}
/* /*
** Rerun the compilation of a statement after a schema change. ** Rerun the compilation of a statement after a schema change.
@@ -580,6 +595,7 @@ int sqlite3Reprepare(Vdbe *p){
return 0; return 0;
} }
db = sqlite3VdbeDb(p); db = sqlite3VdbeDb(p);
assert( sqlite3_mutex_held(db->mutex) );
rc = sqlite3Prepare(db, zSql, -1, 0, &pNew, 0); rc = sqlite3Prepare(db, zSql, -1, 0, &pNew, 0);
if( rc ){ if( rc ){
assert( pNew==0 ); assert( pNew==0 );
@@ -610,7 +626,7 @@ int sqlite3_prepare(
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */ const char **pzTail /* OUT: End of parsed string */
){ ){
return sqlite3Prepare(db,zSql,nBytes,0,ppStmt,pzTail); return sqlite3LockAndPrepare(db,zSql,nBytes,0,ppStmt,pzTail);
} }
int sqlite3_prepare_v2( int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle. */ sqlite3 *db, /* Database handle. */
@@ -619,7 +635,7 @@ int sqlite3_prepare_v2(
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */ const char **pzTail /* OUT: End of parsed string */
){ ){
return sqlite3Prepare(db,zSql,nBytes,1,ppStmt,pzTail); return sqlite3LockAndPrepare(db,zSql,nBytes,1,ppStmt,pzTail);
} }
@@ -646,6 +662,7 @@ static int sqlite3Prepare16(
if( sqlite3SafetyCheck(db) ){ if( sqlite3SafetyCheck(db) ){
return SQLITE_MISUSE; return SQLITE_MISUSE;
} }
sqlite3_mutex_enter(db->mutex);
zSql8 = sqlite3Utf16to8(db, zSql, nBytes); zSql8 = sqlite3Utf16to8(db, zSql, nBytes);
if( zSql8 ){ if( zSql8 ){
rc = sqlite3Prepare(db, zSql8, -1, saveSqlFlag, ppStmt, &zTail8); rc = sqlite3Prepare(db, zSql8, -1, saveSqlFlag, ppStmt, &zTail8);
@@ -661,7 +678,9 @@ static int sqlite3Prepare16(
*pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed);
} }
sqlite3_free(zSql8); sqlite3_free(zSql8);
return sqlite3ApiExit(db, rc); rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
} }
/* /*

View File

@@ -30,7 +30,7 @@
** the version number) and changes its name to "sqlite3.h" as ** the version number) and changes its name to "sqlite3.h" as
** part of the build process. ** part of the build process.
** **
** @(#) $Id: sqlite.h.in,v 1.233 2007/08/21 16:15:56 drh Exp $ ** @(#) $Id: sqlite.h.in,v 1.234 2007/08/21 19:33:56 drh Exp $
*/ */
#ifndef _SQLITE3_H_ #ifndef _SQLITE3_H_
#define _SQLITE3_H_ #define _SQLITE3_H_
@@ -2257,7 +2257,7 @@ void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
** the implementation of the function using this call. ** the implementation of the function using this call.
** **
** This routine must be called from the same thread in which ** This routine must be called from the same thread in which
** the SQL function was originally invoked. ** the SQL function is running.
*/ */
void *sqlite3_user_data(sqlite3_context*); void *sqlite3_user_data(sqlite3_context*);
@@ -2291,8 +2291,8 @@ void *sqlite3_user_data(sqlite3_context*);
** expressions that are constant at compile time. This includes literal ** expressions that are constant at compile time. This includes literal
** values and SQL variables. ** values and SQL variables.
** **
** These routine must be called from the same thread in which ** These routines must be called from the same thread in which
** the SQL function was originally invoked. ** the SQL function is running.
*/ */
void *sqlite3_get_auxdata(sqlite3_context*, int); void *sqlite3_get_auxdata(sqlite3_context*, int);
void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*)); void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*));
@@ -2658,6 +2658,12 @@ int sqlite3_release_memory(int);
** continue without error or notification. This is why the limit is ** continue without error or notification. This is why the limit is
** called a "soft" limit. It is advisory only. ** called a "soft" limit. It is advisory only.
** **
** The soft heap limit is implemented using the [sqlite3_memory_alarm()]
** interface. Only a single memory alarm is available in the default
** implementation. This means that if the application also uses the
** memory alarm interface it will interfere with the operation of the
** soft heap limit and undefined behavior will result.
**
** Prior to SQLite version 3.5.0, this routine only constrained the memory ** Prior to SQLite version 3.5.0, this routine only constrained the memory
** allocated by a single thread - the same thread in which this routine ** allocated by a single thread - the same thread in which this routine
** runs. Beginning with SQLite version 3.5.0, the soft heap limit is ** runs. Beginning with SQLite version 3.5.0, the soft heap limit is

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.594 2007/08/21 13:51:23 drh Exp $ ** @(#) $Id: sqliteInt.h,v 1.595 2007/08/21 19:33:56 drh Exp $
*/ */
#ifndef _SQLITEINT_H_ #ifndef _SQLITEINT_H_
#define _SQLITEINT_H_ #define _SQLITEINT_H_
@@ -793,6 +793,7 @@ struct FKey {
** were larger. ** were larger.
*/ */
struct KeyInfo { struct KeyInfo {
sqlite3 *db; /* The database connection */
u8 enc; /* Text encoding - one of the TEXT_Utf* values */ u8 enc; /* Text encoding - one of the TEXT_Utf* values */
u8 incrKey; /* Increase 2nd key by epsilon before comparison */ u8 incrKey; /* Increase 2nd key by epsilon before comparison */
int nField; /* Number of entries in aColl[] */ int nField; /* Number of entries in aColl[] */
@@ -1744,15 +1745,15 @@ int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckObjectName(Parse *, const char *); int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int); void sqlite3VdbeSetChanges(sqlite3 *, int);
const void *sqlite3ValueText(sqlite3 *db, sqlite3_value*, u8); const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueBytes(sqlite3 *db, sqlite3_value*, u8); int sqlite3ValueBytes(sqlite3_value*, u8);
void sqlite3ValueSetStr(sqlite3 *,sqlite3_value*, int, const void *,u8, void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
void(*)(void*)); void(*)(void*));
void sqlite3ValueFree(sqlite3_value*); void sqlite3ValueFree(sqlite3_value*);
sqlite3_value *sqlite3ValueNew(sqlite3 *); sqlite3_value *sqlite3ValueNew(sqlite3 *);
char *sqlite3Utf16to8(sqlite3 *, const void*, int); char *sqlite3Utf16to8(sqlite3 *, const void*, int);
int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
void sqlite3ValueApplyAffinity(sqlite3 *, sqlite3_value *, u8, u8); void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
extern const unsigned char sqlite3UpperToLower[]; extern const unsigned char sqlite3UpperToLower[];
void sqlite3RootPageMoved(Db*, int, int); void sqlite3RootPageMoved(Db*, int, int);
void sqlite3Reindex(Parse*, Token*, Token*); void sqlite3Reindex(Parse*, Token*, Token*);

View File

@@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated ** is not included in the SQLite library. It is used for automated
** testing of the SQLite library. ** testing of the SQLite library.
** **
** $Id: test1.c,v 1.266 2007/08/21 10:44:16 drh Exp $ ** $Id: test1.c,v 1.267 2007/08/21 19:33:57 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "tcl.h" #include "tcl.h"
@@ -921,10 +921,10 @@ static int test_create_function(
sqlite3_iMallocFail++; sqlite3_iMallocFail++;
} }
#endif #endif
pVal = sqlite3ValueNew(0); pVal = sqlite3ValueNew(db);
sqlite3ValueSetStr(0,pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC); sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
rc = sqlite3_create_function16(db, rc = sqlite3_create_function16(db,
sqlite3ValueText(0, pVal, SQLITE_UTF16NATIVE), sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0); 1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
sqlite3ValueFree(pVal); sqlite3ValueFree(pVal);
} }
@@ -2056,11 +2056,11 @@ static int test_collate_func(
} }
pVal = sqlite3ValueNew(0); pVal = sqlite3ValueNew(0);
sqlite3ValueSetStr(0, pVal, nA, zA, encin, SQLITE_STATIC); sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC);
n = sqlite3_value_bytes(pVal); n = sqlite3_value_bytes(pVal);
Tcl_ListObjAppendElement(i,pX, Tcl_ListObjAppendElement(i,pX,
Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n)); Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n));
sqlite3ValueSetStr(0, pVal, nB, zB, encin, SQLITE_STATIC); sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC);
n = sqlite3_value_bytes(pVal); n = sqlite3_value_bytes(pVal);
Tcl_ListObjAppendElement(i,pX, Tcl_ListObjAppendElement(i,pX,
Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n)); Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n));
@@ -2101,9 +2101,9 @@ static int test_collate(
} }
#endif #endif
pVal = sqlite3ValueNew(0); pVal = sqlite3ValueNew(0);
sqlite3ValueSetStr(0, pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC); sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
rc = sqlite3_create_collation16(db, rc = sqlite3_create_collation16(db,
sqlite3ValueText(0, pVal, SQLITE_UTF16NATIVE), SQLITE_UTF16BE, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), SQLITE_UTF16BE,
(void *)SQLITE_UTF16BE, val?test_collate_func:0); (void *)SQLITE_UTF16BE, val?test_collate_func:0);
sqlite3ValueFree(pVal); sqlite3ValueFree(pVal);
} }
@@ -2270,7 +2270,7 @@ static void test_function_utf8(
Tcl_DecrRefCount(pX); Tcl_DecrRefCount(pX);
sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT); sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT);
pVal = sqlite3ValueNew(0); pVal = sqlite3ValueNew(0);
sqlite3ValueSetStr(0, pVal, -1, Tcl_GetStringResult(interp), sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
SQLITE_UTF8, SQLITE_STATIC); SQLITE_UTF8, SQLITE_STATIC);
sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal), sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal),
-1, SQLITE_TRANSIENT); -1, SQLITE_TRANSIENT);
@@ -2293,7 +2293,7 @@ static void test_function_utf16le(
Tcl_EvalObjEx(interp, pX, 0); Tcl_EvalObjEx(interp, pX, 0);
Tcl_DecrRefCount(pX); Tcl_DecrRefCount(pX);
pVal = sqlite3ValueNew(0); pVal = sqlite3ValueNew(0);
sqlite3ValueSetStr(0, pVal, -1, Tcl_GetStringResult(interp), sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
SQLITE_UTF8, SQLITE_STATIC); SQLITE_UTF8, SQLITE_STATIC);
sqlite3_result_text(pCtx,(char*)sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT); sqlite3_result_text(pCtx,(char*)sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT);
sqlite3ValueFree(pVal); sqlite3ValueFree(pVal);
@@ -2315,7 +2315,7 @@ static void test_function_utf16be(
Tcl_EvalObjEx(interp, pX, 0); Tcl_EvalObjEx(interp, pX, 0);
Tcl_DecrRefCount(pX); Tcl_DecrRefCount(pX);
pVal = sqlite3ValueNew(0); pVal = sqlite3ValueNew(0);
sqlite3ValueSetStr(0, pVal, -1, Tcl_GetStringResult(interp), sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
SQLITE_UTF8, SQLITE_STATIC); SQLITE_UTF8, SQLITE_STATIC);
sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal), sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal),
-1, SQLITE_TRANSIENT); -1, SQLITE_TRANSIENT);

View File

@@ -15,7 +15,7 @@
** is used for testing the SQLite routines for converting between ** is used for testing the SQLite routines for converting between
** the various supported unicode encodings. ** the various supported unicode encodings.
** **
** $Id: test5.c,v 1.19 2007/08/21 10:44:16 drh Exp $ ** $Id: test5.c,v 1.20 2007/08/21 19:33:57 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "vdbeInt.h" #include "vdbeInt.h"
@@ -156,7 +156,7 @@ static int test_translate(
if( objc==5 ){ if( objc==5 ){
z = sqlite3StrDup(z); z = sqlite3StrDup(z);
} }
sqlite3ValueSetStr(0, pVal, -1, z, enc_from, xDel); sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel);
}else{ }else{
z = (char*)Tcl_GetByteArrayFromObj(objv[1], &len); z = (char*)Tcl_GetByteArrayFromObj(objv[1], &len);
if( objc==5 ){ if( objc==5 ){
@@ -164,11 +164,11 @@ static int test_translate(
z = sqlite3_malloc(len); z = sqlite3_malloc(len);
memcpy(z, zTmp, len); memcpy(z, zTmp, len);
} }
sqlite3ValueSetStr(0, pVal, -1, z, enc_from, xDel); sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel);
} }
z = (char *)sqlite3ValueText(0, pVal, enc_to); z = (char *)sqlite3ValueText(pVal, enc_to);
len = sqlite3ValueBytes(0, pVal, enc_to) + (enc_to==SQLITE_UTF8?1:2); len = sqlite3ValueBytes(pVal, enc_to) + (enc_to==SQLITE_UTF8?1:2);
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj((u8*)z, len)); Tcl_SetObjResult(interp, Tcl_NewByteArrayObj((u8*)z, len));
sqlite3ValueFree(pVal); sqlite3ValueFree(pVal);

View File

@@ -12,7 +12,7 @@
** This file contains routines used to translate between UTF-8, ** This file contains routines used to translate between UTF-8,
** UTF-16, UTF-16BE, and UTF-16LE. ** UTF-16, UTF-16BE, and UTF-16LE.
** **
** $Id: utf.c,v 1.55 2007/08/16 10:09:03 danielk1977 Exp $ ** $Id: utf.c,v 1.56 2007/08/21 19:33:57 drh Exp $
** **
** Notes on UTF-8: ** Notes on UTF-8:
** **
@@ -187,7 +187,7 @@ int sqlite3Utf8Read(
** desiredEnc. It is an error if the string is already of the desired ** desiredEnc. It is an error if the string is already of the desired
** encoding, or if *pMem does not contain a string value. ** encoding, or if *pMem does not contain a string value.
*/ */
int sqlite3VdbeMemTranslate(sqlite3 *db, Mem *pMem, u8 desiredEnc){ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
unsigned char zShort[NBFS]; /* Temporary short output buffer */ unsigned char zShort[NBFS]; /* Temporary short output buffer */
int len; /* Maximum length of output string in bytes */ int len; /* Maximum length of output string in bytes */
unsigned char *zOut; /* Output buffer */ unsigned char *zOut; /* Output buffer */
@@ -196,6 +196,7 @@ int sqlite3VdbeMemTranslate(sqlite3 *db, Mem *pMem, u8 desiredEnc){
unsigned char *z; /* Output iterator */ unsigned char *z; /* Output iterator */
unsigned int c; unsigned int c;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( pMem->flags&MEM_Str ); assert( pMem->flags&MEM_Str );
assert( pMem->enc!=desiredEnc ); assert( pMem->enc!=desiredEnc );
assert( pMem->enc!=0 ); assert( pMem->enc!=0 );
@@ -216,7 +217,7 @@ int sqlite3VdbeMemTranslate(sqlite3 *db, Mem *pMem, u8 desiredEnc){
if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){ if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){
u8 temp; u8 temp;
int rc; int rc;
rc = sqlite3VdbeMemMakeWriteable(db, pMem); rc = sqlite3VdbeMemMakeWriteable(pMem);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
assert( rc==SQLITE_NOMEM ); assert( rc==SQLITE_NOMEM );
return SQLITE_NOMEM; return SQLITE_NOMEM;
@@ -260,8 +261,10 @@ int sqlite3VdbeMemTranslate(sqlite3 *db, Mem *pMem, u8 desiredEnc){
zIn = (u8*)pMem->z; zIn = (u8*)pMem->z;
zTerm = &zIn[pMem->n]; zTerm = &zIn[pMem->n];
if( len>NBFS ){ if( len>NBFS ){
zOut = sqlite3DbMallocRaw(db, len); zOut = sqlite3DbMallocRaw(pMem->db, len);
if( !zOut ) return SQLITE_NOMEM; if( !zOut ){
return SQLITE_NOMEM;
}
}else{ }else{
zOut = zShort; zOut = zShort;
} }
@@ -336,7 +339,7 @@ translate_out:
** The allocation (static, dynamic etc.) and encoding of the Mem may be ** The allocation (static, dynamic etc.) and encoding of the Mem may be
** changed by this function. ** changed by this function.
*/ */
int sqlite3VdbeMemHandleBom(sqlite3 *db, Mem *pMem){ int sqlite3VdbeMemHandleBom(Mem *pMem){
int rc = SQLITE_OK; int rc = SQLITE_OK;
u8 bom = 0; u8 bom = 0;
@@ -364,11 +367,11 @@ int sqlite3VdbeMemHandleBom(sqlite3 *db, Mem *pMem){
char *z = pMem->z; char *z = pMem->z;
pMem->z = 0; pMem->z = 0;
pMem->xDel = 0; pMem->xDel = 0;
rc = sqlite3VdbeMemSetStr(db, pMem, &z[2], pMem->n-2, bom, rc = sqlite3VdbeMemSetStr(pMem, &z[2], pMem->n-2, bom,
SQLITE_TRANSIENT); SQLITE_TRANSIENT);
xDel(z); xDel(z);
}else{ }else{
rc = sqlite3VdbeMemSetStr(db, pMem, &pMem->z[2], pMem->n-2, bom, rc = sqlite3VdbeMemSetStr(pMem, &pMem->z[2], pMem->n-2, bom,
SQLITE_TRANSIENT); SQLITE_TRANSIENT);
} }
} }
@@ -411,8 +414,9 @@ int sqlite3Utf8CharLen(const char *zIn, int nByte){
char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte){ char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte){
Mem m; Mem m;
memset(&m, 0, sizeof(m)); memset(&m, 0, sizeof(m));
sqlite3VdbeMemSetStr(db, &m, z, nByte, SQLITE_UTF16NATIVE, SQLITE_STATIC); m.db = db;
sqlite3VdbeChangeEncoding(db, &m, SQLITE_UTF8); sqlite3VdbeMemSetStr(&m, z, nByte, SQLITE_UTF16NATIVE, SQLITE_STATIC);
sqlite3VdbeChangeEncoding(&m, SQLITE_UTF8);
assert( (m.flags & MEM_Term)!=0 || db->mallocFailed ); assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
assert( (m.flags & MEM_Str)!=0 || db->mallocFailed ); assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
return (m.flags & MEM_Dyn)!=0 ? m.z : sqlite3DbStrDup(db, m.z); return (m.flags & MEM_Dyn)!=0 ? m.z : sqlite3DbStrDup(db, m.z);

View File

@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing ** This file contains functions for allocating memory, comparing
** strings, and stuff like that. ** strings, and stuff like that.
** **
** $Id: util.c,v 1.210 2007/08/21 10:44:16 drh Exp $ ** $Id: util.c,v 1.211 2007/08/21 19:33:57 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <stdarg.h> #include <stdarg.h>
@@ -51,9 +51,9 @@ void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
va_start(ap, zFormat); va_start(ap, zFormat);
z = sqlite3VMPrintf(db, zFormat, ap); z = sqlite3VMPrintf(db, zFormat, ap);
va_end(ap); va_end(ap);
sqlite3ValueSetStr(db, db->pErr, -1, z, SQLITE_UTF8, sqlite3_free); sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, sqlite3_free);
}else{ }else{
sqlite3ValueSetStr(db, db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC); sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
} }
} }
} }

View File

@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing ** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code. ** commenting and indentation practices when changing or adding code.
** **
** $Id: vdbe.c,v 1.643 2007/08/21 10:44:16 drh Exp $ ** $Id: vdbe.c,v 1.644 2007/08/21 19:33:57 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -105,8 +105,8 @@ int sqlite3_max_blobsize = 0;
** Convert the given stack entity into a string if it isn't one ** Convert the given stack entity into a string if it isn't one
** already. Return non-zero if a malloc() fails. ** already. Return non-zero if a malloc() fails.
*/ */
#define Stringify(db, P, enc) \ #define Stringify(P, enc) \
if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(db,P,enc)) \ if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \
{ goto no_mem; } { goto no_mem; }
/* /*
@@ -137,15 +137,15 @@ int sqlite3_max_blobsize = 0;
** string that the stack entry itself controls. In other words, it ** string that the stack entry itself controls. In other words, it
** converts an MEM_Ephem string into an MEM_Dyn string. ** converts an MEM_Ephem string into an MEM_Dyn string.
*/ */
#define Deephemeralize(db,P) \ #define Deephemeralize(P) \
if( ((P)->flags&MEM_Ephem)!=0 \ if( ((P)->flags&MEM_Ephem)!=0 \
&& sqlite3VdbeMemMakeWriteable(db, P) ){ goto no_mem;} && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}
/* /*
** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*) ** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*)
** P if required. ** P if required.
*/ */
#define ExpandBlob(D,P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(D,P):0) #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0)
/* /*
** Argument pMem points at a memory cell that will be passed to a ** Argument pMem points at a memory cell that will be passed to a
@@ -209,14 +209,14 @@ static Cursor *allocateCursor(Vdbe *p, int iCur, int iDb){
** looks like a number, convert it into a number. If it does not ** looks like a number, convert it into a number. If it does not
** look like a number, leave it alone. ** look like a number, leave it alone.
*/ */
static void applyNumericAffinity(sqlite3 *db, Mem *pRec){ static void applyNumericAffinity(Mem *pRec){
if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){ if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){
int realnum; int realnum;
sqlite3VdbeMemNulTerminate(db, pRec); sqlite3VdbeMemNulTerminate(pRec);
if( (pRec->flags&MEM_Str) if( (pRec->flags&MEM_Str)
&& sqlite3IsNumber(pRec->z, &realnum, pRec->enc) ){ && sqlite3IsNumber(pRec->z, &realnum, pRec->enc) ){
i64 value; i64 value;
sqlite3VdbeChangeEncoding(db, pRec, SQLITE_UTF8); sqlite3VdbeChangeEncoding(pRec, SQLITE_UTF8);
if( !realnum && sqlite3Atoi64(pRec->z, &value) ){ if( !realnum && sqlite3Atoi64(pRec->z, &value) ){
sqlite3VdbeMemRelease(pRec); sqlite3VdbeMemRelease(pRec);
pRec->u.i = value; pRec->u.i = value;
@@ -247,7 +247,6 @@ static void applyNumericAffinity(sqlite3 *db, Mem *pRec){
** No-op. pRec is unchanged. ** No-op. pRec is unchanged.
*/ */
static void applyAffinity( static void applyAffinity(
sqlite3 *db, /* Report malloc() errors to this db connection */
Mem *pRec, /* The value to apply affinity to */ Mem *pRec, /* The value to apply affinity to */
char affinity, /* The affinity to be applied */ char affinity, /* The affinity to be applied */
u8 enc /* Use this text encoding */ u8 enc /* Use this text encoding */
@@ -258,13 +257,13 @@ static void applyAffinity(
** representation. ** representation.
*/ */
if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){ if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
sqlite3VdbeMemStringify(db, pRec, enc); sqlite3VdbeMemStringify(pRec, enc);
} }
pRec->flags &= ~(MEM_Real|MEM_Int); pRec->flags &= ~(MEM_Real|MEM_Int);
}else if( affinity!=SQLITE_AFF_NONE ){ }else if( affinity!=SQLITE_AFF_NONE ){
assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
|| affinity==SQLITE_AFF_NUMERIC ); || affinity==SQLITE_AFF_NUMERIC );
applyNumericAffinity(db, pRec); applyNumericAffinity(pRec);
if( pRec->flags & MEM_Real ){ if( pRec->flags & MEM_Real ){
sqlite3VdbeIntegerAffinity(pRec); sqlite3VdbeIntegerAffinity(pRec);
} }
@@ -281,7 +280,7 @@ static void applyAffinity(
*/ */
int sqlite3_value_numeric_type(sqlite3_value *pVal){ int sqlite3_value_numeric_type(sqlite3_value *pVal){
Mem *pMem = (Mem*)pVal; Mem *pMem = (Mem*)pVal;
applyNumericAffinity(0, pMem); applyNumericAffinity(pMem);
storeTypeInfo(pMem, 0); storeTypeInfo(pMem, 0);
return pMem->type; return pMem->type;
} }
@@ -291,12 +290,11 @@ int sqlite3_value_numeric_type(sqlite3_value *pVal){
** not the internal Mem* type. ** not the internal Mem* type.
*/ */
void sqlite3ValueApplyAffinity( void sqlite3ValueApplyAffinity(
sqlite3 *db,
sqlite3_value *pVal, sqlite3_value *pVal,
u8 affinity, u8 affinity,
u8 enc u8 enc
){ ){
applyAffinity(db, (Mem *)pVal, affinity, enc); applyAffinity((Mem *)pVal, affinity, enc);
} }
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
@@ -733,7 +731,7 @@ case OP_Real: { /* same as TK_FLOAT, */
pTos->enc = SQLITE_UTF8; pTos->enc = SQLITE_UTF8;
pTos->r = sqlite3VdbeRealValue(pTos); pTos->r = sqlite3VdbeRealValue(pTos);
pTos->flags |= MEM_Real; pTos->flags |= MEM_Real;
sqlite3VdbeChangeEncoding(db, pTos, encoding); sqlite3VdbeChangeEncoding(pTos, encoding);
break; break;
} }
@@ -752,9 +750,9 @@ case OP_String8: { /* same as TK_STRING */
#ifndef SQLITE_OMIT_UTF16 #ifndef SQLITE_OMIT_UTF16
if( encoding!=SQLITE_UTF8 ){ if( encoding!=SQLITE_UTF8 ){
pTos++; pTos++;
sqlite3VdbeMemSetStr(db, pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC); sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC);
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(db, pTos, encoding) ) goto no_mem; if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, encoding) ) goto no_mem;
if( SQLITE_OK!=sqlite3VdbeMemDynamicify(db, pTos) ) goto no_mem; if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pTos) ) goto no_mem;
pTos->flags &= ~(MEM_Dyn); pTos->flags &= ~(MEM_Dyn);
pTos->flags |= MEM_Static; pTos->flags |= MEM_Static;
if( pOp->p3type==P3_DYNAMIC ){ if( pOp->p3type==P3_DYNAMIC ){
@@ -842,7 +840,7 @@ case OP_HexBlob: { /* same as TK_BLOB */
case OP_Blob: { case OP_Blob: {
pTos++; pTos++;
assert( pOp->p1 < SQLITE_MAX_LENGTH ); /* Due to SQLITE_MAX_SQL_LENGTH */ assert( pOp->p1 < SQLITE_MAX_LENGTH ); /* Due to SQLITE_MAX_SQL_LENGTH */
sqlite3VdbeMemSetStr(db, pTos, pOp->p3, pOp->p1, 0, 0); sqlite3VdbeMemSetStr(pTos, pOp->p3, pOp->p1, 0, 0);
pTos->enc = encoding; pTos->enc = encoding;
break; break;
} }
@@ -903,7 +901,7 @@ case OP_Dup: {
pTos++; pTos++;
sqlite3VdbeMemShallowCopy(pTos, pFrom, MEM_Ephem); sqlite3VdbeMemShallowCopy(pTos, pFrom, MEM_Ephem);
if( pOp->p2 ){ if( pOp->p2 ){
Deephemeralize(db, pTos); Deephemeralize(pTos);
} }
break; break;
} }
@@ -924,9 +922,9 @@ case OP_Pull: { /* no-push */
Mem ts; Mem ts;
ts = *pFrom; ts = *pFrom;
Deephemeralize(db, pTos); Deephemeralize(pTos);
for(i=0; i<pOp->p1; i++, pFrom++){ for(i=0; i<pOp->p1; i++, pFrom++){
Deephemeralize(db, &pFrom[1]); Deephemeralize(&pFrom[1]);
assert( (pFrom[1].flags & MEM_Ephem)==0 ); assert( (pFrom[1].flags & MEM_Ephem)==0 );
*pFrom = pFrom[1]; *pFrom = pFrom[1];
if( pFrom->flags & MEM_Short ){ if( pFrom->flags & MEM_Short ){
@@ -954,7 +952,7 @@ case OP_Push: { /* no-push */
Mem *pTo = &pTos[-pOp->p1]; Mem *pTo = &pTos[-pOp->p1];
assert( pTo>=p->aStack ); assert( pTo>=p->aStack );
sqlite3VdbeMemMove(db, pTo, pTos); sqlite3VdbeMemMove(pTo, pTos);
pTos--; pTos--;
break; break;
} }
@@ -982,7 +980,7 @@ case OP_Callback: { /* no-push */
*/ */
pFirstColumn = &pTos[0-pOp->p1]; pFirstColumn = &pTos[0-pOp->p1];
for(pMem = p->aStack; pMem<pFirstColumn; pMem++){ for(pMem = p->aStack; pMem<pFirstColumn; pMem++){
Deephemeralize(db, pMem); Deephemeralize(pMem);
} }
/* Invalidate all ephemeral cursor row caches */ /* Invalidate all ephemeral cursor row caches */
@@ -993,7 +991,7 @@ case OP_Callback: { /* no-push */
** as side effect. ** as side effect.
*/ */
for(; pMem<=pTos; pMem++ ){ for(; pMem<=pTos; pMem++ ){
sqlite3VdbeMemNulTerminate(db, pMem); sqlite3VdbeMemNulTerminate(pMem);
storeTypeInfo(pMem, encoding); storeTypeInfo(pMem, encoding);
} }
@@ -1035,8 +1033,8 @@ case OP_Concat: { /* same as TK_CONCAT */
nByte = -1; nByte = -1;
break; break;
} }
ExpandBlob(db, pTerm); ExpandBlob(pTerm);
Stringify(db, pTerm, encoding); Stringify(pTerm, encoding);
nByte += pTerm->n; nByte += pTerm->n;
} }
@@ -1280,6 +1278,7 @@ case OP_Function: {
ctx.s.flags = MEM_Null; ctx.s.flags = MEM_Null;
ctx.s.z = 0; ctx.s.z = 0;
ctx.s.xDel = 0; ctx.s.xDel = 0;
ctx.s.db = db;
ctx.isError = 0; ctx.isError = 0;
if( ctx.pFunc->needCollSeq ){ if( ctx.pFunc->needCollSeq ){
assert( pOp>p->aOp ); assert( pOp>p->aOp );
@@ -1321,10 +1320,10 @@ case OP_Function: {
} }
/* Copy the result of the function to the top of the stack */ /* Copy the result of the function to the top of the stack */
sqlite3VdbeChangeEncoding(db, &ctx.s, encoding); sqlite3VdbeChangeEncoding(&ctx.s, encoding);
pTos++; pTos++;
pTos->flags = 0; pTos->flags = 0;
sqlite3VdbeMemMove(db, pTos, &ctx.s); sqlite3VdbeMemMove(pTos, &ctx.s);
if( sqlite3VdbeMemTooBig(pTos) ){ if( sqlite3VdbeMemTooBig(pTos) ){
goto too_big; goto too_big;
} }
@@ -1417,7 +1416,7 @@ case OP_AddImm: { /* no-push */
case OP_ForceInt: { /* no-push */ case OP_ForceInt: { /* no-push */
i64 v; i64 v;
assert( pTos>=p->aStack ); assert( pTos>=p->aStack );
applyAffinity(db, pTos, SQLITE_AFF_NUMERIC, encoding); applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);
if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){ if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){
Release(pTos); Release(pTos);
pTos--; pTos--;
@@ -1452,7 +1451,7 @@ case OP_ForceInt: { /* no-push */
*/ */
case OP_MustBeInt: { /* no-push */ case OP_MustBeInt: { /* no-push */
assert( pTos>=p->aStack ); assert( pTos>=p->aStack );
applyAffinity(db, pTos, SQLITE_AFF_NUMERIC, encoding); applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);
if( (pTos->flags & MEM_Int)==0 ){ if( (pTos->flags & MEM_Int)==0 ){
if( pOp->p2==0 ){ if( pOp->p2==0 ){
rc = SQLITE_MISMATCH; rc = SQLITE_MISMATCH;
@@ -1500,8 +1499,8 @@ case OP_ToText: { /* same as TK_TO_TEXT, no-push */
if( pTos->flags & MEM_Null ) break; if( pTos->flags & MEM_Null ) break;
assert( MEM_Str==(MEM_Blob>>3) ); assert( MEM_Str==(MEM_Blob>>3) );
pTos->flags |= (pTos->flags&MEM_Blob)>>3; pTos->flags |= (pTos->flags&MEM_Blob)>>3;
applyAffinity(db, pTos, SQLITE_AFF_TEXT, encoding); applyAffinity(pTos, SQLITE_AFF_TEXT, encoding);
rc = ExpandBlob(db, pTos); rc = ExpandBlob(pTos);
assert( pTos->flags & MEM_Str ); assert( pTos->flags & MEM_Str );
pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Blob); pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);
break; break;
@@ -1520,7 +1519,7 @@ case OP_ToBlob: { /* same as TK_TO_BLOB, no-push */
assert( pTos>=p->aStack ); assert( pTos>=p->aStack );
if( pTos->flags & MEM_Null ) break; if( pTos->flags & MEM_Null ) break;
if( (pTos->flags & MEM_Blob)==0 ){ if( (pTos->flags & MEM_Blob)==0 ){
applyAffinity(db, pTos, SQLITE_AFF_TEXT, encoding); applyAffinity(pTos, SQLITE_AFF_TEXT, encoding);
assert( pTos->flags & MEM_Str ); assert( pTos->flags & MEM_Str );
pTos->flags |= MEM_Blob; pTos->flags |= MEM_Blob;
} }
@@ -1701,13 +1700,13 @@ case OP_Ge: { /* same as TK_GE, no-push */
affinity = pOp->p1 & 0xFF; affinity = pOp->p1 & 0xFF;
if( affinity ){ if( affinity ){
applyAffinity(db, pNos, affinity, encoding); applyAffinity(pNos, affinity, encoding);
applyAffinity(db, pTos, affinity, encoding); applyAffinity(pTos, affinity, encoding);
} }
assert( pOp->p3type==P3_COLLSEQ || pOp->p3==0 ); assert( pOp->p3type==P3_COLLSEQ || pOp->p3==0 );
ExpandBlob(db, pNos); ExpandBlob(pNos);
ExpandBlob(db, pTos); ExpandBlob(pTos);
res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p3); res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p3);
switch( pOp->opcode ){ switch( pOp->opcode ){
case OP_Eq: res = res==0; break; case OP_Eq: res = res==0; break;
@@ -2118,7 +2117,7 @@ case OP_Column: {
** acquire the complete header text. ** acquire the complete header text.
*/ */
if( !zRec && avail<offset ){ if( !zRec && avail<offset ){
rc = sqlite3VdbeMemFromBtree(db, pCrsr, 0, offset, pC->isIndex, &sMem); rc = sqlite3VdbeMemFromBtree(pCrsr, 0, offset, pC->isIndex, &sMem);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
goto op_column_out; goto op_column_out;
} }
@@ -2172,8 +2171,7 @@ case OP_Column: {
zData = &zRec[aOffset[p2]]; zData = &zRec[aOffset[p2]];
}else{ }else{
len = sqlite3VdbeSerialTypeLen(aType[p2]); len = sqlite3VdbeSerialTypeLen(aType[p2]);
rc = sqlite3VdbeMemFromBtree( rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, &sMem);
db, pCrsr, aOffset[p2], len, pC->isIndex, &sMem);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
goto op_column_out; goto op_column_out;
} }
@@ -2205,7 +2203,7 @@ case OP_Column: {
/* pTos->z might be pointing to sMem.zShort[]. Fix that so that we /* pTos->z might be pointing to sMem.zShort[]. Fix that so that we
** can abandon sMem */ ** can abandon sMem */
rc = sqlite3VdbeMemMakeWriteable(db, pTos); rc = sqlite3VdbeMemMakeWriteable(pTos);
op_column_out: op_column_out:
break; break;
@@ -2301,13 +2299,13 @@ case OP_MakeRecord: {
for(pRec=pData0; pRec<=pTos; pRec++){ for(pRec=pData0; pRec<=pTos; pRec++){
int len; int len;
if( zAffinity ){ if( zAffinity ){
applyAffinity(db, pRec, zAffinity[pRec-pData0], encoding); applyAffinity(pRec, zAffinity[pRec-pData0], encoding);
} }
if( pRec->flags&MEM_Null ){ if( pRec->flags&MEM_Null ){
containsNull = 1; containsNull = 1;
} }
if( pRec->flags&MEM_Zero && pRec->n>0 ){ if( pRec->flags&MEM_Zero && pRec->n>0 ){
ExpandBlob(db, pRec); ExpandBlob(pRec);
} }
serial_type = sqlite3VdbeSerialType(pRec, file_format); serial_type = sqlite3VdbeSerialType(pRec, file_format);
len = sqlite3VdbeSerialTypeLen(serial_type); len = sqlite3VdbeSerialTypeLen(serial_type);
@@ -2973,7 +2971,7 @@ case OP_MoveGt: { /* no-push */
pC->rowidIsValid = res==0; pC->rowidIsValid = res==0;
}else{ }else{
assert( pTos->flags & MEM_Blob ); assert( pTos->flags & MEM_Blob );
ExpandBlob(db, pTos); ExpandBlob(pTos);
rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, 0, &res); rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, 0, &res);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
goto abort_due_to_error; goto abort_due_to_error;
@@ -3081,7 +3079,7 @@ case OP_Found: { /* no-push */
int res, rx; int res, rx;
assert( pC->isTable==0 ); assert( pC->isTable==0 );
assert( pTos->flags & MEM_Blob ); assert( pTos->flags & MEM_Blob );
Stringify(db, pTos, encoding); Stringify(pTos, encoding);
rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, 0, &res); rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, 0, &res);
alreadyExists = rx==SQLITE_OK && res==0; alreadyExists = rx==SQLITE_OK && res==0;
pC->deferredMoveto = 0; pC->deferredMoveto = 0;
@@ -3149,7 +3147,7 @@ case OP_IsUnique: { /* no-push */
/* Make sure K is a string and make zKey point to K /* Make sure K is a string and make zKey point to K
*/ */
assert( pNos->flags & MEM_Blob ); assert( pNos->flags & MEM_Blob );
Stringify(db, pNos, encoding); Stringify(pNos, encoding);
zKey = pNos->z; zKey = pNos->z;
nKey = pNos->n; nKey = pNos->n;
@@ -3172,7 +3170,7 @@ case OP_IsUnique: { /* no-push */
break; break;
} }
} }
rc = sqlite3VdbeIdxKeyCompare(db, pCx, len, (u8*)zKey, &res); rc = sqlite3VdbeIdxKeyCompare(pCx, len, (u8*)zKey, &res);
if( rc!=SQLITE_OK ) goto abort_due_to_error; if( rc!=SQLITE_OK ) goto abort_due_to_error;
if( res>0 ){ if( res>0 ){
pc = pOp->p2 - 1; pc = pOp->p2 - 1;
@@ -3184,7 +3182,7 @@ case OP_IsUnique: { /* no-push */
** final rowid column is different from R. If it equals R then jump ** final rowid column is different from R. If it equals R then jump
** immediately to P2. ** immediately to P2.
*/ */
rc = sqlite3VdbeIdxRowid(db, pCrsr, &v); rc = sqlite3VdbeIdxRowid(pCrsr, &v);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
goto abort_due_to_error; goto abort_due_to_error;
} }
@@ -3876,7 +3874,7 @@ case OP_IdxInsert: { /* no-push */
assert( pTos->flags & MEM_Blob ); assert( pTos->flags & MEM_Blob );
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
assert( pC->isTable==0 ); assert( pC->isTable==0 );
rc = ExpandBlob(db, pTos); rc = ExpandBlob(pTos);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
int nKey = pTos->n; int nKey = pTos->n;
const char *zKey = pTos->z; const char *zKey = pTos->z;
@@ -3943,7 +3941,7 @@ case OP_IdxRowid: {
if( pC->nullRow ){ if( pC->nullRow ){
pTos->flags = MEM_Null; pTos->flags = MEM_Null;
}else{ }else{
rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid); rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
goto abort_due_to_error; goto abort_due_to_error;
} }
@@ -4012,10 +4010,10 @@ case OP_IdxGE: { /* no-push */
assert( pTos->flags & MEM_Blob ); /* Created using OP_MakeRecord */ assert( pTos->flags & MEM_Blob ); /* Created using OP_MakeRecord */
assert( pC->deferredMoveto==0 ); assert( pC->deferredMoveto==0 );
ExpandBlob(db, pTos); ExpandBlob(pTos);
*pC->pIncrKey = pOp->p3!=0; *pC->pIncrKey = pOp->p3!=0;
assert( pOp->p3==0 || pOp->opcode!=OP_IdxGT ); assert( pOp->p3==0 || pOp->opcode!=OP_IdxGT );
rc = sqlite3VdbeIdxKeyCompare(db, pC, pTos->n, (u8*)pTos->z, &res); rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, (u8*)pTos->z, &res);
*pC->pIncrKey = 0; *pC->pIncrKey = 0;
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
break; break;
@@ -4337,7 +4335,7 @@ case OP_IntegrityCk: {
pTos->xDel = 0; pTos->xDel = 0;
} }
pTos->enc = SQLITE_UTF8; pTos->enc = SQLITE_UTF8;
sqlite3VdbeChangeEncoding(db, pTos, encoding); sqlite3VdbeChangeEncoding(pTos, encoding);
sqlite3_free(aRoot); sqlite3_free(aRoot);
break; break;
} }
@@ -4435,7 +4433,7 @@ case OP_ContextPop: { /* no-push */
case OP_MemStore: { /* no-push */ case OP_MemStore: { /* no-push */
assert( pTos>=p->aStack ); assert( pTos>=p->aStack );
assert( pOp->p1>=0 && pOp->p1<p->nMem ); assert( pOp->p1>=0 && pOp->p1<p->nMem );
rc = sqlite3VdbeMemMove(db, &p->aMem[pOp->p1], pTos); rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], pTos);
pTos--; pTos--;
/* If P2 is 0 then fall thru to the next opcode, OP_MemLoad, that will /* If P2 is 0 then fall thru to the next opcode, OP_MemLoad, that will
@@ -4589,7 +4587,7 @@ case OP_MemInt: {
case OP_MemMove: { case OP_MemMove: {
assert( pOp->p1>=0 && pOp->p1<p->nMem ); assert( pOp->p1>=0 && pOp->p1<p->nMem );
assert( pOp->p2>=0 && pOp->p2<p->nMem ); assert( pOp->p2>=0 && pOp->p2<p->nMem );
rc = sqlite3VdbeMemMove(db, &p->aMem[pOp->p1], &p->aMem[pOp->p2]); rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], &p->aMem[pOp->p2]);
break; break;
} }
@@ -4625,9 +4623,9 @@ case OP_AggStep: { /* no-push */
ctx.s.flags = MEM_Null; ctx.s.flags = MEM_Null;
ctx.s.z = 0; ctx.s.z = 0;
ctx.s.xDel = 0; ctx.s.xDel = 0;
ctx.s.db = db;
ctx.isError = 0; ctx.isError = 0;
ctx.pColl = 0; ctx.pColl = 0;
ctx.db = db;
if( ctx.pFunc->needCollSeq ){ if( ctx.pFunc->needCollSeq ){
assert( pOp>p->aOp ); assert( pOp>p->aOp );
assert( pOp[-1].p3type==P3_COLLSEQ ); assert( pOp[-1].p3type==P3_COLLSEQ );
@@ -4949,6 +4947,7 @@ case OP_VColumn: {
sqlite3_context sContext; sqlite3_context sContext;
memset(&sContext, 0, sizeof(sContext)); memset(&sContext, 0, sizeof(sContext));
sContext.s.flags = MEM_Null; sContext.s.flags = MEM_Null;
sContext.s.db = db;
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2); rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
@@ -4956,10 +4955,10 @@ case OP_VColumn: {
** do this regardless of whether or not an error occured to ensure any ** do this regardless of whether or not an error occured to ensure any
** dynamic allocation in sContext.s (a Mem struct) is released. ** dynamic allocation in sContext.s (a Mem struct) is released.
*/ */
sqlite3VdbeChangeEncoding(db, &sContext.s, encoding); sqlite3VdbeChangeEncoding(&sContext.s, encoding);
pTos++; pTos++;
pTos->flags = 0; pTos->flags = 0;
sqlite3VdbeMemMove(db, pTos, &sContext.s); sqlite3VdbeMemMove(pTos, &sContext.s);
if( sqlite3SafetyOn(db) ){ if( sqlite3SafetyOn(db) ){
goto abort_due_to_misuse; goto abort_due_to_misuse;
@@ -5028,7 +5027,7 @@ case OP_VRename: { /* no-push */
sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p3); sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p3);
assert( pVtab->pModule->xRename ); assert( pVtab->pModule->xRename );
Stringify(db, pTos, encoding); Stringify(pTos, encoding);
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
sqlite3VtabLock(pVtab); sqlite3VtabLock(pVtab);
@@ -5149,6 +5148,7 @@ default: {
** cell, so avoid calling MemSanity() in this case. ** cell, so avoid calling MemSanity() in this case.
*/ */
if( pTos>=p->aStack && pTos->flags ){ if( pTos>=p->aStack && pTos->flags ){
assert( pTos->db==db );
sqlite3VdbeMemSanity(pTos); sqlite3VdbeMemSanity(pTos);
assert( !sqlite3VdbeMemTooBig(pTos) ); assert( !sqlite3VdbeMemTooBig(pTos) );
} }

View File

@@ -130,6 +130,7 @@ struct Mem {
FuncDef *pDef; /* Used only when flags==MEM_Agg */ FuncDef *pDef; /* Used only when flags==MEM_Agg */
} u; } u;
double r; /* Real value */ double r; /* Real value */
sqlite3 *db; /* The associated database connection */
char *z; /* String or BLOB value */ char *z; /* String or BLOB value */
int n; /* Number of characters in string value, including '\0' */ int n; /* Number of characters in string value, including '\0' */
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
@@ -219,7 +220,6 @@ struct sqlite3_context {
Mem *pMem; /* Memory cell used to store aggregate context */ Mem *pMem; /* Memory cell used to store aggregate context */
u8 isError; /* Set to true for an error */ u8 isError; /* Set to true for an error */
CollSeq *pColl; /* Collating sequence */ CollSeq *pColl; /* Collating sequence */
sqlite3 *db; /* Database connection */
}; };
/* /*
@@ -375,56 +375,56 @@ int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
void sqlite3VdbeDeleteAuxData(VdbeFunc*, int); void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
int sqlite3VdbeIdxKeyCompare(sqlite3*,Cursor*,int,const unsigned char*,int*); int sqlite3VdbeIdxKeyCompare(Cursor*,int,const unsigned char*,int*);
int sqlite3VdbeIdxRowid(sqlite3 *, BtCursor *, i64 *); int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
int sqlite3VdbeRecordCompare(void*,int,const void*,int, const void*); int sqlite3VdbeRecordCompare(void*,int,const void*,int, const void*);
int sqlite3VdbeIdxRowidLen(const u8*); int sqlite3VdbeIdxRowidLen(const u8*);
int sqlite3VdbeExec(Vdbe*); int sqlite3VdbeExec(Vdbe*);
int sqlite3VdbeList(Vdbe*); int sqlite3VdbeList(Vdbe*);
int sqlite3VdbeHalt(Vdbe*); int sqlite3VdbeHalt(Vdbe*);
int sqlite3VdbeChangeEncoding(sqlite3 *, Mem *, int); int sqlite3VdbeChangeEncoding(Mem *, int);
int sqlite3VdbeMemTooBig(Mem*); int sqlite3VdbeMemTooBig(Mem*);
int sqlite3VdbeMemCopy(sqlite3*, Mem*, const Mem*); int sqlite3VdbeMemCopy(Mem*, const Mem*);
void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
int sqlite3VdbeMemMove(sqlite3*, Mem*, Mem*); int sqlite3VdbeMemMove(Mem*, Mem*);
int sqlite3VdbeMemNulTerminate(sqlite3 *, Mem*); int sqlite3VdbeMemNulTerminate(Mem*);
int sqlite3VdbeMemSetStr(sqlite3 *, Mem*, const char*, int, u8, void(*)(void*)); int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
void sqlite3VdbeMemSetInt64(Mem*, i64); void sqlite3VdbeMemSetInt64(Mem*, i64);
void sqlite3VdbeMemSetDouble(Mem*, double); void sqlite3VdbeMemSetDouble(Mem*, double);
void sqlite3VdbeMemSetNull(Mem*); void sqlite3VdbeMemSetNull(Mem*);
void sqlite3VdbeMemSetZeroBlob(Mem*,int); void sqlite3VdbeMemSetZeroBlob(Mem*,int);
int sqlite3VdbeMemMakeWriteable(sqlite3 *, Mem*); int sqlite3VdbeMemMakeWriteable(Mem*);
int sqlite3VdbeMemDynamicify(sqlite3 *, Mem*); int sqlite3VdbeMemDynamicify(Mem*);
int sqlite3VdbeMemStringify(sqlite3*, Mem*, int); int sqlite3VdbeMemStringify(Mem*, int);
i64 sqlite3VdbeIntValue(Mem*); i64 sqlite3VdbeIntValue(Mem*);
int sqlite3VdbeMemIntegerify(Mem*); int sqlite3VdbeMemIntegerify(Mem*);
double sqlite3VdbeRealValue(Mem*); double sqlite3VdbeRealValue(Mem*);
void sqlite3VdbeIntegerAffinity(Mem*); void sqlite3VdbeIntegerAffinity(Mem*);
int sqlite3VdbeMemRealify(Mem*); int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemNumerify(Mem*); int sqlite3VdbeMemNumerify(Mem*);
int sqlite3VdbeMemFromBtree(sqlite3*,BtCursor*,int,int,int,Mem*); int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p); void sqlite3VdbeMemRelease(Mem *p);
int sqlite3VdbeMemFinalize(Mem*, FuncDef*); int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
#ifndef NDEBUG #ifndef NDEBUG
void sqlite3VdbeMemSanity(Mem*); void sqlite3VdbeMemSanity(Mem*);
int sqlite3VdbeOpcodeNoPush(u8); int sqlite3VdbeOpcodeNoPush(u8);
#endif #endif
int sqlite3VdbeMemTranslate(sqlite3 *, Mem*, u8); int sqlite3VdbeMemTranslate(Mem*, u8);
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
void sqlite3VdbePrintSql(Vdbe*); void sqlite3VdbePrintSql(Vdbe*);
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf); void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
#endif #endif
int sqlite3VdbeMemHandleBom(sqlite3 *, Mem *pMem); int sqlite3VdbeMemHandleBom(Mem *pMem);
void sqlite3VdbeFifoInit(Fifo*); void sqlite3VdbeFifoInit(Fifo*);
int sqlite3VdbeFifoPush(Fifo*, i64); int sqlite3VdbeFifoPush(Fifo*, i64);
int sqlite3VdbeFifoPop(Fifo*, i64*); int sqlite3VdbeFifoPop(Fifo*, i64*);
void sqlite3VdbeFifoClear(Fifo*); void sqlite3VdbeFifoClear(Fifo*);
#ifndef SQLITE_OMIT_INCRBLOB #ifndef SQLITE_OMIT_INCRBLOB
int sqlite3VdbeMemExpandBlob(sqlite3 *, Mem *); int sqlite3VdbeMemExpandBlob(Mem *);
#else #else
#define sqlite3VdbeMemExpandBlob(d,x) SQLITE_OK #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK
#endif #endif
#endif /* !defined(_VDBEINT_H_) */ #endif /* !defined(_VDBEINT_H_) */

View File

@@ -97,7 +97,7 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
const void *sqlite3_value_blob(sqlite3_value *pVal){ const void *sqlite3_value_blob(sqlite3_value *pVal){
Mem *p = (Mem*)pVal; Mem *p = (Mem*)pVal;
if( p->flags & (MEM_Blob|MEM_Str) ){ if( p->flags & (MEM_Blob|MEM_Str) ){
sqlite3VdbeMemExpandBlob(0, p); sqlite3VdbeMemExpandBlob(p);
p->flags &= ~MEM_Str; p->flags &= ~MEM_Str;
p->flags |= MEM_Blob; p->flags |= MEM_Blob;
return p->z; return p->z;
@@ -106,10 +106,10 @@ const void *sqlite3_value_blob(sqlite3_value *pVal){
} }
} }
int sqlite3_value_bytes(sqlite3_value *pVal){ int sqlite3_value_bytes(sqlite3_value *pVal){
return sqlite3ValueBytes(0, pVal, SQLITE_UTF8); return sqlite3ValueBytes(pVal, SQLITE_UTF8);
} }
int sqlite3_value_bytes16(sqlite3_value *pVal){ int sqlite3_value_bytes16(sqlite3_value *pVal){
return sqlite3ValueBytes(0, pVal, SQLITE_UTF16NATIVE); return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
} }
double sqlite3_value_double(sqlite3_value *pVal){ double sqlite3_value_double(sqlite3_value *pVal){
return sqlite3VdbeRealValue((Mem*)pVal); return sqlite3VdbeRealValue((Mem*)pVal);
@@ -121,17 +121,17 @@ sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
return sqlite3VdbeIntValue((Mem*)pVal); return sqlite3VdbeIntValue((Mem*)pVal);
} }
const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
return (const unsigned char *)sqlite3ValueText(0, pVal, SQLITE_UTF8); return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
} }
#ifndef SQLITE_OMIT_UTF16 #ifndef SQLITE_OMIT_UTF16
const void *sqlite3_value_text16(sqlite3_value* pVal){ const void *sqlite3_value_text16(sqlite3_value* pVal){
return sqlite3ValueText(0, pVal, SQLITE_UTF16NATIVE); return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
} }
const void *sqlite3_value_text16be(sqlite3_value *pVal){ const void *sqlite3_value_text16be(sqlite3_value *pVal){
return sqlite3ValueText(0, pVal, SQLITE_UTF16BE); return sqlite3ValueText(pVal, SQLITE_UTF16BE);
} }
const void *sqlite3_value_text16le(sqlite3_value *pVal){ const void *sqlite3_value_text16le(sqlite3_value *pVal){
return sqlite3ValueText(0, pVal, SQLITE_UTF16LE); return sqlite3ValueText(pVal, SQLITE_UTF16LE);
} }
#endif /* SQLITE_OMIT_UTF16 */ #endif /* SQLITE_OMIT_UTF16 */
int sqlite3_value_type(sqlite3_value* pVal){ int sqlite3_value_type(sqlite3_value* pVal){
@@ -150,19 +150,19 @@ void sqlite3_result_blob(
void (*xDel)(void *) void (*xDel)(void *)
){ ){
assert( n>=0 ); assert( n>=0 );
sqlite3VdbeMemSetStr(0, &pCtx->s, z, n, 0, xDel); sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel);
} }
void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
sqlite3VdbeMemSetDouble(&pCtx->s, rVal); sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
} }
void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
pCtx->isError = 1; pCtx->isError = 1;
sqlite3VdbeMemSetStr(0, &pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
} }
#ifndef SQLITE_OMIT_UTF16 #ifndef SQLITE_OMIT_UTF16
void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
pCtx->isError = 1; pCtx->isError = 1;
sqlite3VdbeMemSetStr(0, &pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
} }
#endif #endif
void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
@@ -180,7 +180,7 @@ void sqlite3_result_text(
int n, int n,
void (*xDel)(void *) void (*xDel)(void *)
){ ){
sqlite3VdbeMemSetStr(0, &pCtx->s, z, n, SQLITE_UTF8, xDel); sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, xDel);
} }
#ifndef SQLITE_OMIT_UTF16 #ifndef SQLITE_OMIT_UTF16
void sqlite3_result_text16( void sqlite3_result_text16(
@@ -189,7 +189,7 @@ void sqlite3_result_text16(
int n, int n,
void (*xDel)(void *) void (*xDel)(void *)
){ ){
sqlite3VdbeMemSetStr(0, &pCtx->s, z, n, SQLITE_UTF16NATIVE, xDel); sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, xDel);
} }
void sqlite3_result_text16be( void sqlite3_result_text16be(
sqlite3_context *pCtx, sqlite3_context *pCtx,
@@ -197,7 +197,7 @@ void sqlite3_result_text16be(
int n, int n,
void (*xDel)(void *) void (*xDel)(void *)
){ ){
sqlite3VdbeMemSetStr(0, &pCtx->s, z, n, SQLITE_UTF16BE, xDel); sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16BE, xDel);
} }
void sqlite3_result_text16le( void sqlite3_result_text16le(
sqlite3_context *pCtx, sqlite3_context *pCtx,
@@ -205,11 +205,11 @@ void sqlite3_result_text16le(
int n, int n,
void (*xDel)(void *) void (*xDel)(void *)
){ ){
sqlite3VdbeMemSetStr(0, &pCtx->s, z, n, SQLITE_UTF16LE, xDel); sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16LE, xDel);
} }
#endif /* SQLITE_OMIT_UTF16 */ #endif /* SQLITE_OMIT_UTF16 */
void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
sqlite3VdbeMemCopy(0, &pCtx->s, pValue); sqlite3VdbeMemCopy(&pCtx->s, pValue);
} }
void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
sqlite3VdbeMemSetZeroBlob(&pCtx->s, n); sqlite3VdbeMemSetZeroBlob(&pCtx->s, n);
@@ -351,19 +351,27 @@ end_of_step:
*/ */
#ifdef SQLITE_OMIT_PARSER #ifdef SQLITE_OMIT_PARSER
int sqlite3_step(sqlite3_stmt *pStmt){ int sqlite3_step(sqlite3_stmt *pStmt){
return sqlite3Step((Vdbe*)pStmt); int rc;
Vdbe *v;
v = (Vdbe*)pStmt;
sqlite3_mutex_enter(v->db->mutex);
rc = sqlite3Step(v);
sqlite3_mutex_leave(v->db->mutex);
return rc;
} }
#else #else
int sqlite3_step(sqlite3_stmt *pStmt){ int sqlite3_step(sqlite3_stmt *pStmt){
int cnt = 0; int cnt = 0;
int rc; int rc;
Vdbe *v = (Vdbe*)pStmt; Vdbe *v = (Vdbe*)pStmt;
sqlite3_mutex_enter(v->db->mutex);
while( (rc = sqlite3Step(v))==SQLITE_SCHEMA while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
&& cnt++ < 5 && cnt++ < 5
&& sqlite3Reprepare(v) ){ && sqlite3Reprepare(v) ){
sqlite3_reset(pStmt); sqlite3_reset(pStmt);
v->expired = 0; v->expired = 0;
} }
sqlite3_mutex_leave(v->db->mutex);
return rc; return rc;
} }
#endif #endif
@@ -404,8 +412,10 @@ void sqlite3InvalidFunction(
** same context that was returned on prior calls. ** same context that was returned on prior calls.
*/ */
void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
Mem *pMem = p->pMem; Mem *pMem;
assert( p && p->pFunc && p->pFunc->xStep ); assert( p && p->pFunc && p->pFunc->xStep );
assert( sqlite3_mutex_held(p->s.db->mutex) );
pMem = p->pMem;
if( (pMem->flags & MEM_Agg)==0 ){ if( (pMem->flags & MEM_Agg)==0 ){
if( nByte==0 ){ if( nByte==0 ){
assert( pMem->flags==MEM_Null ); assert( pMem->flags==MEM_Null );
@@ -418,7 +428,7 @@ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
pMem->z = pMem->zShort; pMem->z = pMem->zShort;
memset(pMem->z, 0, nByte); memset(pMem->z, 0, nByte);
}else{ }else{
pMem->z = sqlite3DbMallocZero(p->db, nByte); pMem->z = sqlite3DbMallocZero(p->s.db, nByte);
} }
} }
} }
@@ -430,7 +440,10 @@ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
** the user-function defined by pCtx. ** the user-function defined by pCtx.
*/ */
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
VdbeFunc *pVdbeFunc = pCtx->pVdbeFunc; VdbeFunc *pVdbeFunc;
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
pVdbeFunc = pCtx->pVdbeFunc;
if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){ if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){
return 0; return 0;
} }
@@ -452,13 +465,14 @@ void sqlite3_set_auxdata(
VdbeFunc *pVdbeFunc; VdbeFunc *pVdbeFunc;
if( iArg<0 ) goto failed; if( iArg<0 ) goto failed;
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
pVdbeFunc = pCtx->pVdbeFunc; pVdbeFunc = pCtx->pVdbeFunc;
if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){ if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0); int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0);
int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg; int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
pVdbeFunc = sqlite3_realloc(pVdbeFunc, nMalloc); pVdbeFunc = sqlite3_realloc(pVdbeFunc, nMalloc);
if( !pVdbeFunc ){ if( !pVdbeFunc ){
pCtx->db->mallocFailed = 1; pCtx->s.db->mallocFailed = 1;
goto failed; goto failed;
} }
pCtx->pVdbeFunc = pVdbeFunc; pCtx->pVdbeFunc = pVdbeFunc;
@@ -524,7 +538,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
Vdbe *pVm = (Vdbe *)pStmt; Vdbe *pVm = (Vdbe *)pStmt;
int vals = sqlite3_data_count(pStmt); int vals = sqlite3_data_count(pStmt);
if( pVm==0 || pVm->resOnStack==0 || i>=pVm->nResColumn || i<0 ){ if( pVm==0 || pVm->resOnStack==0 || i>=pVm->nResColumn || i<0 ){
static const Mem nullMem = {{0}, 0.0, "", 0, MEM_Null, SQLITE_NULL }; static const Mem nullMem = {{0}, 0.0, 0, "", 0, MEM_Null, SQLITE_NULL };
sqlite3Error(pVm->db, SQLITE_RANGE, 0); sqlite3Error(pVm->db, SQLITE_RANGE, 0);
return (Mem*)&nullMem; return (Mem*)&nullMem;
} }
@@ -800,9 +814,9 @@ static int bindText(
return rc; return rc;
} }
pVar = &p->aVar[i-1]; pVar = &p->aVar[i-1];
rc = sqlite3VdbeMemSetStr(p->db, pVar, zData, nData, encoding, xDel); rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
if( rc==SQLITE_OK && encoding!=0 ){ if( rc==SQLITE_OK && encoding!=0 ){
rc = sqlite3VdbeChangeEncoding(p->db, pVar, ENC(p->db)); rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
} }
sqlite3Error(p->db, rc, 0); sqlite3Error(p->db, rc, 0);
rc = sqlite3ApiExit(p->db, rc); rc = sqlite3ApiExit(p->db, rc);
@@ -882,7 +896,7 @@ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
sqlite3_mutex_enter(p->db->mutex); sqlite3_mutex_enter(p->db->mutex);
rc = vdbeUnbind(p, i); rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = sqlite3VdbeMemCopy(0, &p->aVar[i-1], pValue); rc = sqlite3VdbeMemCopy(&p->aVar[i-1], pValue);
} }
sqlite3_mutex_leave(p->db->mutex); sqlite3_mutex_leave(p->db->mutex);
return rc; return rc;
@@ -987,7 +1001,7 @@ int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
} }
for(i=0; rc==SQLITE_OK && i<pFrom->nVar; i++){ for(i=0; rc==SQLITE_OK && i<pFrom->nVar; i++){
sqlite3MallocDisallow(); sqlite3MallocDisallow();
rc = sqlite3VdbeMemMove(0, &pTo->aVar[i], &pFrom->aVar[i]); rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
sqlite3MallocAllow(); sqlite3MallocAllow();
} }
assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );

View File

@@ -680,6 +680,7 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
static void releaseMemArray(Mem *p, int N){ static void releaseMemArray(Mem *p, int N){
if( p ){ if( p ){
while( N-->0 ){ while( N-->0 ){
assert( N<2 || p[0].db==p[1].db );
sqlite3VdbeMemRelease(p++); sqlite3VdbeMemRelease(p++);
} }
} }
@@ -887,11 +888,16 @@ void sqlite3VdbeMakeReady(
p->nCursor = nCursor; p->nCursor = nCursor;
for(n=0; n<nVar; n++){ for(n=0; n<nVar; n++){
p->aVar[n].flags = MEM_Null; p->aVar[n].flags = MEM_Null;
p->aVar[n].db = db;
}
for(n=0; n<nStack; n++){
p->aStack[n].db = db;
} }
} }
} }
for(n=0; n<p->nMem; n++){ for(n=0; n<p->nMem; n++){
p->aMem[n].flags = MEM_Null; p->aMem[n].flags = MEM_Null;
p->aMem[n].db = db;
} }
p->pTos = &p->aStack[-1]; p->pTos = &p->aStack[-1];
@@ -1032,11 +1038,9 @@ int sqlite3VdbeSetColName(Vdbe *p, int idx, int var, const char *zName, int N){
assert( p->aColName!=0 ); assert( p->aColName!=0 );
pColName = &(p->aColName[idx+var*p->nResColumn]); pColName = &(p->aColName[idx+var*p->nResColumn]);
if( N==P3_DYNAMIC || N==P3_STATIC ){ if( N==P3_DYNAMIC || N==P3_STATIC ){
rc = sqlite3VdbeMemSetStr(p->db, rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
}else{ }else{
rc = sqlite3VdbeMemSetStr(p->db, rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
pColName, zName, N, SQLITE_UTF8, SQLITE_TRANSIENT);
} }
if( rc==SQLITE_OK && N==P3_DYNAMIC ){ if( rc==SQLITE_OK && N==P3_DYNAMIC ){
pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn; pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn;
@@ -1550,7 +1554,7 @@ int sqlite3VdbeReset(Vdbe *p){
*/ */
if( p->pc>=0 ){ if( p->pc>=0 ){
if( p->zErrMsg ){ if( p->zErrMsg ){
sqlite3ValueSetStr(db,db->pErr,-1,p->zErrMsg,SQLITE_UTF8,sqlite3_free); sqlite3ValueSetStr(db->pErr,-1,p->zErrMsg,SQLITE_UTF8,sqlite3_free);
db->errCode = p->rc; db->errCode = p->rc;
p->zErrMsg = 0; p->zErrMsg = 0;
}else if( p->rc ){ }else if( p->rc ){
@@ -2032,7 +2036,9 @@ int sqlite3VdbeRecordCompare(
Mem mem1; Mem mem1;
Mem mem2; Mem mem2;
mem1.enc = pKeyInfo->enc; mem1.enc = pKeyInfo->enc;
mem1.db = pKeyInfo->db;
mem2.enc = pKeyInfo->enc; mem2.enc = pKeyInfo->enc;
mem2.db = pKeyInfo->db;
idx1 = GetVarint(aKey1, szHdr1); idx1 = GetVarint(aKey1, szHdr1);
d1 = szHdr1; d1 = szHdr1;
@@ -2106,7 +2112,7 @@ int sqlite3VdbeIdxRowidLen(const u8 *aKey){
** Read the rowid (the last field in the record) and store it in *rowid. ** Read the rowid (the last field in the record) and store it in *rowid.
** Return SQLITE_OK if everything works, or an error code otherwise. ** Return SQLITE_OK if everything works, or an error code otherwise.
*/ */
int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){
i64 nCellKey = 0; i64 nCellKey = 0;
int rc; int rc;
u32 szHdr; /* Size of the header */ u32 szHdr; /* Size of the header */
@@ -2118,7 +2124,7 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
if( nCellKey<=0 ){ if( nCellKey<=0 ){
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_BKPT;
} }
rc = sqlite3VdbeMemFromBtree(db, pCur, 0, nCellKey, 1, &m); rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
if( rc ){ if( rc ){
return rc; return rc;
} }
@@ -2142,7 +2148,6 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
** is ignored as well. ** is ignored as well.
*/ */
int sqlite3VdbeIdxKeyCompare( int sqlite3VdbeIdxKeyCompare(
sqlite3 *db,
Cursor *pC, /* The cursor to compare against */ Cursor *pC, /* The cursor to compare against */
int nKey, const u8 *pKey, /* The key to compare */ int nKey, const u8 *pKey, /* The key to compare */
int *res /* Write the comparison result here */ int *res /* Write the comparison result here */
@@ -2158,7 +2163,7 @@ int sqlite3VdbeIdxKeyCompare(
*res = 0; *res = 0;
return SQLITE_OK; return SQLITE_OK;
} }
rc = sqlite3VdbeMemFromBtree(db, pC->pCursor, 0, nCellKey, 1, &m); rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
if( rc ){ if( rc ){
return rc; return rc;
} }
@@ -2173,6 +2178,7 @@ int sqlite3VdbeIdxKeyCompare(
** sqlite3_changes() on the database handle 'db'. ** sqlite3_changes() on the database handle 'db'.
*/ */
void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){ void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){
assert( sqlite3_mutex_held(db->mutex) );
db->nChange = nChange; db->nChange = nChange;
db->nTotalChange += nChange; db->nTotalChange += nChange;
} }

View File

@@ -12,7 +12,7 @@
** **
** This file contains code used to implement incremental BLOB I/O. ** This file contains code used to implement incremental BLOB I/O.
** **
** $Id: vdbeblob.c,v 1.13 2007/08/21 15:13:19 drh Exp $ ** $Id: vdbeblob.c,v 1.14 2007/08/21 19:33:57 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -247,7 +247,6 @@ blob_open_out:
*/ */
int sqlite3_blob_close(sqlite3_blob *pBlob){ int sqlite3_blob_close(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob; Incrblob *p = (Incrblob *)pBlob;
sqlite3_stmt *pStmt;
sqlite3_mutex *mutex = p->db->mutex; sqlite3_mutex *mutex = p->db->mutex;
int rc; int rc;

View File

@@ -24,7 +24,7 @@
** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*) ** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*)
** P if required. ** P if required.
*/ */
#define expandBlob(D,P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(D,P):0) #define expandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0)
/* /*
** If pMem is an object with a valid string representation, this routine ** If pMem is an object with a valid string representation, this routine
@@ -39,11 +39,12 @@
** SQLITE_NOMEM may be returned if a malloc() fails during conversion ** SQLITE_NOMEM may be returned if a malloc() fails during conversion
** between formats. ** between formats.
*/ */
int sqlite3VdbeChangeEncoding(sqlite3 *db, Mem *pMem, int desiredEnc){ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
int rc; int rc;
if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
return SQLITE_OK; return SQLITE_OK;
} }
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
#ifdef SQLITE_OMIT_UTF16 #ifdef SQLITE_OMIT_UTF16
return SQLITE_ERROR; return SQLITE_ERROR;
#else #else
@@ -51,7 +52,7 @@ int sqlite3VdbeChangeEncoding(sqlite3 *db, Mem *pMem, int desiredEnc){
/* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned, /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned,
** then the encoding of the value may not have changed. ** then the encoding of the value may not have changed.
*/ */
rc = sqlite3VdbeMemTranslate(db, pMem, desiredEnc); rc = sqlite3VdbeMemTranslate(pMem, desiredEnc);
assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); assert(rc==SQLITE_OK || rc==SQLITE_NOMEM);
assert(rc==SQLITE_OK || pMem->enc!=desiredEnc); assert(rc==SQLITE_OK || pMem->enc!=desiredEnc);
assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc); assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc);
@@ -64,17 +65,18 @@ int sqlite3VdbeChangeEncoding(sqlite3 *db, Mem *pMem, int desiredEnc){
** **
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/ */
int sqlite3VdbeMemDynamicify(sqlite3 *db, Mem *pMem){ int sqlite3VdbeMemDynamicify(Mem *pMem){
int n; int n;
u8 *z; u8 *z;
expandBlob(db, pMem); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
expandBlob(pMem);
if( (pMem->flags & (MEM_Ephem|MEM_Static|MEM_Short))==0 ){ if( (pMem->flags & (MEM_Ephem|MEM_Static|MEM_Short))==0 ){
return SQLITE_OK; return SQLITE_OK;
} }
assert( (pMem->flags & MEM_Dyn)==0 ); assert( (pMem->flags & MEM_Dyn)==0 );
n = pMem->n; n = pMem->n;
assert( pMem->flags & (MEM_Str|MEM_Blob) ); assert( pMem->flags & (MEM_Str|MEM_Blob) );
z = sqlite3_malloc( n+2 ); z = sqlite3DbMallocRaw(pMem->db, n+2 );
if( z==0 ){ if( z==0 ){
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
@@ -93,16 +95,16 @@ int sqlite3VdbeMemDynamicify(sqlite3 *db, Mem *pMem){
** blob stored in dynamically allocated space. ** blob stored in dynamically allocated space.
*/ */
#ifndef SQLITE_OMIT_INCRBLOB #ifndef SQLITE_OMIT_INCRBLOB
int sqlite3VdbeMemExpandBlob(sqlite3 *db, Mem *pMem){ int sqlite3VdbeMemExpandBlob(Mem *pMem){
if( pMem->flags & MEM_Zero ){ if( pMem->flags & MEM_Zero ){
char *pNew; char *pNew;
int nByte; int nByte;
assert( (pMem->flags & MEM_Blob)!=0 ); assert( (pMem->flags & MEM_Blob)!=0 );
nByte = pMem->n + pMem->u.i; nByte = pMem->n + pMem->u.i;
if( nByte<=0 ) nByte = 1; if( nByte<=0 ) nByte = 1;
pNew = sqlite3_malloc(nByte); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
pNew = sqlite3DbMallocRaw(pMem->db, nByte);
if( pNew==0 ){ if( pNew==0 ){
if( db ) db->mallocFailed = 1;
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
memcpy(pNew, pMem->z, pMem->n); memcpy(pNew, pMem->z, pMem->n);
@@ -125,10 +127,11 @@ int sqlite3VdbeMemExpandBlob(sqlite3 *db, Mem *pMem){
** **
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/ */
int sqlite3VdbeMemMakeWriteable(sqlite3 *db, Mem *pMem){ int sqlite3VdbeMemMakeWriteable(Mem *pMem){
int n; int n;
u8 *z; u8 *z;
expandBlob(db, pMem); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
expandBlob(pMem);
if( (pMem->flags & (MEM_Ephem|MEM_Static))==0 ){ if( (pMem->flags & (MEM_Ephem|MEM_Static))==0 ){
return SQLITE_OK; return SQLITE_OK;
} }
@@ -138,9 +141,8 @@ int sqlite3VdbeMemMakeWriteable(sqlite3 *db, Mem *pMem){
z = (u8*)pMem->zShort; z = (u8*)pMem->zShort;
pMem->flags |= MEM_Short|MEM_Term; pMem->flags |= MEM_Short|MEM_Term;
}else{ }else{
z = sqlite3_malloc( n+2 ); z = sqlite3DbMallocRaw(pMem->db, n+2 );
if( z==0 ){ if( z==0 ){
db->mallocFailed = 1;
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
pMem->flags |= MEM_Dyn|MEM_Term; pMem->flags |= MEM_Dyn|MEM_Term;
@@ -158,18 +160,18 @@ int sqlite3VdbeMemMakeWriteable(sqlite3 *db, Mem *pMem){
/* /*
** Make sure the given Mem is \u0000 terminated. ** Make sure the given Mem is \u0000 terminated.
*/ */
int sqlite3VdbeMemNulTerminate(sqlite3 *db, Mem *pMem){ int sqlite3VdbeMemNulTerminate(Mem *pMem){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){ if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){
return SQLITE_OK; /* Nothing to do */ return SQLITE_OK; /* Nothing to do */
} }
if( pMem->flags & (MEM_Static|MEM_Ephem) ){ if( pMem->flags & (MEM_Static|MEM_Ephem) ){
return sqlite3VdbeMemMakeWriteable(db, pMem); return sqlite3VdbeMemMakeWriteable(pMem);
}else{ }else{
char *z; char *z;
sqlite3VdbeMemExpandBlob(db, pMem); sqlite3VdbeMemExpandBlob(pMem);
z = sqlite3_malloc(pMem->n+2); z = sqlite3DbMallocRaw(pMem->db, pMem->n+2);
if( !z ){ if( !z ){
db->mallocFailed = 1;
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
memcpy(z, pMem->z, pMem->n); memcpy(z, pMem->z, pMem->n);
@@ -200,11 +202,12 @@ int sqlite3VdbeMemNulTerminate(sqlite3 *db, Mem *pMem){
** keys are strings. In the former case a NULL pointer is returned the ** keys are strings. In the former case a NULL pointer is returned the
** user and the later is an internal programming error. ** user and the later is an internal programming error.
*/ */
int sqlite3VdbeMemStringify(sqlite3 *db, Mem *pMem, int enc){ int sqlite3VdbeMemStringify(Mem *pMem, int enc){
int rc = SQLITE_OK; int rc = SQLITE_OK;
int fg = pMem->flags; int fg = pMem->flags;
char *z = pMem->zShort; char *z = pMem->zShort;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( !(fg&MEM_Zero) ); assert( !(fg&MEM_Zero) );
assert( !(fg&(MEM_Str|MEM_Blob)) ); assert( !(fg&(MEM_Str|MEM_Blob)) );
assert( fg&(MEM_Int|MEM_Real) ); assert( fg&(MEM_Int|MEM_Real) );
@@ -225,7 +228,7 @@ int sqlite3VdbeMemStringify(sqlite3 *db, Mem *pMem, int enc){
pMem->z = z; pMem->z = z;
pMem->enc = SQLITE_UTF8; pMem->enc = SQLITE_UTF8;
pMem->flags |= MEM_Str | MEM_Short | MEM_Term; pMem->flags |= MEM_Str | MEM_Short | MEM_Term;
sqlite3VdbeChangeEncoding(db, pMem, enc); sqlite3VdbeChangeEncoding(pMem, enc);
return rc; return rc;
} }
@@ -242,8 +245,10 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
if( pFunc && pFunc->xFinalize ){ if( pFunc && pFunc->xFinalize ){
sqlite3_context ctx; sqlite3_context ctx;
assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
ctx.s.flags = MEM_Null; ctx.s.flags = MEM_Null;
ctx.s.z = pMem->zShort; ctx.s.z = pMem->zShort;
ctx.s.db = pMem->db;
ctx.pMem = pMem; ctx.pMem = pMem;
ctx.pFunc = pFunc; ctx.pFunc = pFunc;
ctx.isError = 0; ctx.isError = 0;
@@ -268,6 +273,7 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
** (Mem.type==SQLITE_TEXT). ** (Mem.type==SQLITE_TEXT).
*/ */
void sqlite3VdbeMemRelease(Mem *p){ void sqlite3VdbeMemRelease(Mem *p){
assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
if( p->flags & (MEM_Dyn|MEM_Agg) ){ if( p->flags & (MEM_Dyn|MEM_Agg) ){
if( p->xDel ){ if( p->xDel ){
if( p->flags & MEM_Agg ){ if( p->flags & MEM_Agg ){
@@ -296,7 +302,9 @@ void sqlite3VdbeMemRelease(Mem *p){
** If pMem is a string, its encoding might be changed. ** If pMem is a string, its encoding might be changed.
*/ */
i64 sqlite3VdbeIntValue(Mem *pMem){ i64 sqlite3VdbeIntValue(Mem *pMem){
int flags = pMem->flags; int flags;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
flags = pMem->flags;
if( flags & MEM_Int ){ if( flags & MEM_Int ){
return pMem->u.i; return pMem->u.i;
}else if( flags & MEM_Real ){ }else if( flags & MEM_Real ){
@@ -304,8 +312,8 @@ i64 sqlite3VdbeIntValue(Mem *pMem){
}else if( flags & (MEM_Str|MEM_Blob) ){ }else if( flags & (MEM_Str|MEM_Blob) ){
i64 value; i64 value;
pMem->flags |= MEM_Str; pMem->flags |= MEM_Str;
if( sqlite3VdbeChangeEncoding(0, pMem, SQLITE_UTF8) if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
|| sqlite3VdbeMemNulTerminate(0, pMem) ){ || sqlite3VdbeMemNulTerminate(pMem) ){
return 0; return 0;
} }
assert( pMem->z ); assert( pMem->z );
@@ -323,6 +331,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){
** If it is a NULL, return 0.0. ** If it is a NULL, return 0.0.
*/ */
double sqlite3VdbeRealValue(Mem *pMem){ double sqlite3VdbeRealValue(Mem *pMem){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
if( pMem->flags & MEM_Real ){ if( pMem->flags & MEM_Real ){
return pMem->r; return pMem->r;
}else if( pMem->flags & MEM_Int ){ }else if( pMem->flags & MEM_Int ){
@@ -330,8 +339,8 @@ double sqlite3VdbeRealValue(Mem *pMem){
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){ }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
double val = 0.0; double val = 0.0;
pMem->flags |= MEM_Str; pMem->flags |= MEM_Str;
if( sqlite3VdbeChangeEncoding(0, pMem, SQLITE_UTF8) if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
|| sqlite3VdbeMemNulTerminate(0, pMem) ){ || sqlite3VdbeMemNulTerminate(pMem) ){
return 0.0; return 0.0;
} }
assert( pMem->z ); assert( pMem->z );
@@ -348,6 +357,7 @@ double sqlite3VdbeRealValue(Mem *pMem){
*/ */
void sqlite3VdbeIntegerAffinity(Mem *pMem){ void sqlite3VdbeIntegerAffinity(Mem *pMem){
assert( pMem->flags & MEM_Real ); assert( pMem->flags & MEM_Real );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
pMem->u.i = pMem->r; pMem->u.i = pMem->r;
if( ((double)pMem->u.i)==pMem->r ){ if( ((double)pMem->u.i)==pMem->r ){
pMem->flags |= MEM_Int; pMem->flags |= MEM_Int;
@@ -358,6 +368,7 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){
** Convert pMem to type integer. Invalidate any prior representations. ** Convert pMem to type integer. Invalidate any prior representations.
*/ */
int sqlite3VdbeMemIntegerify(Mem *pMem){ int sqlite3VdbeMemIntegerify(Mem *pMem){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
pMem->u.i = sqlite3VdbeIntValue(pMem); pMem->u.i = sqlite3VdbeIntValue(pMem);
sqlite3VdbeMemRelease(pMem); sqlite3VdbeMemRelease(pMem);
pMem->flags = MEM_Int; pMem->flags = MEM_Int;
@@ -369,6 +380,7 @@ int sqlite3VdbeMemIntegerify(Mem *pMem){
** Invalidate any prior representations. ** Invalidate any prior representations.
*/ */
int sqlite3VdbeMemRealify(Mem *pMem){ int sqlite3VdbeMemRealify(Mem *pMem){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
pMem->r = sqlite3VdbeRealValue(pMem); pMem->r = sqlite3VdbeRealValue(pMem);
sqlite3VdbeMemRelease(pMem); sqlite3VdbeMemRelease(pMem);
pMem->flags = MEM_Real; pMem->flags = MEM_Real;
@@ -384,6 +396,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){
i64 i; i64 i;
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ); assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 );
assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
r1 = sqlite3VdbeRealValue(pMem); r1 = sqlite3VdbeRealValue(pMem);
i = (i64)r1; i = (i64)r1;
r2 = (double)i; r2 = (double)i;
@@ -483,14 +496,14 @@ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
** Make a full copy of pFrom into pTo. Prior contents of pTo are ** Make a full copy of pFrom into pTo. Prior contents of pTo are
** freed before the copy is made. ** freed before the copy is made.
*/ */
int sqlite3VdbeMemCopy(sqlite3 *db, Mem *pTo, const Mem *pFrom){ int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
int rc; int rc;
if( pTo->flags & MEM_Dyn ){ if( pTo->flags & MEM_Dyn ){
sqlite3VdbeMemRelease(pTo); sqlite3VdbeMemRelease(pTo);
} }
sqlite3VdbeMemShallowCopy(pTo, pFrom, MEM_Ephem); sqlite3VdbeMemShallowCopy(pTo, pFrom, MEM_Ephem);
if( pTo->flags & MEM_Ephem ){ if( pTo->flags & MEM_Ephem ){
rc = sqlite3VdbeMemMakeWriteable(db, pTo); rc = sqlite3VdbeMemMakeWriteable(pTo);
}else{ }else{
rc = SQLITE_OK; rc = SQLITE_OK;
} }
@@ -505,8 +518,11 @@ int sqlite3VdbeMemCopy(sqlite3 *db, Mem *pTo, const Mem *pFrom){
** might be returned if pFrom held ephemeral data and we were unable ** might be returned if pFrom held ephemeral data and we were unable
** to allocate enough space to make a copy. ** to allocate enough space to make a copy.
*/ */
int sqlite3VdbeMemMove(sqlite3 *db, Mem *pTo, Mem *pFrom){ int sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
int rc; int rc;
assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) );
assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) );
assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db );
if( pTo->flags & MEM_Dyn ){ if( pTo->flags & MEM_Dyn ){
sqlite3VdbeMemRelease(pTo); sqlite3VdbeMemRelease(pTo);
} }
@@ -517,7 +533,7 @@ int sqlite3VdbeMemMove(sqlite3 *db, Mem *pTo, Mem *pFrom){
pFrom->flags = MEM_Null; pFrom->flags = MEM_Null;
pFrom->xDel = 0; pFrom->xDel = 0;
if( pTo->flags & MEM_Ephem ){ if( pTo->flags & MEM_Ephem ){
rc = sqlite3VdbeMemMakeWriteable(db, pTo); rc = sqlite3VdbeMemMakeWriteable(pTo);
}else{ }else{
rc = SQLITE_OK; rc = SQLITE_OK;
} }
@@ -528,20 +544,19 @@ int sqlite3VdbeMemMove(sqlite3 *db, Mem *pTo, Mem *pFrom){
** Change the value of a Mem to be a string or a BLOB. ** Change the value of a Mem to be a string or a BLOB.
*/ */
int sqlite3VdbeMemSetStr( int sqlite3VdbeMemSetStr(
sqlite3 *db,
Mem *pMem, /* Memory cell to set to string value */ Mem *pMem, /* Memory cell to set to string value */
const char *z, /* String pointer */ const char *z, /* String pointer */
int n, /* Bytes in string, or negative */ int n, /* Bytes in string, or negative */
u8 enc, /* Encoding of z. 0 for BLOBs */ u8 enc, /* Encoding of z. 0 for BLOBs */
void (*xDel)(void*) /* Destructor function */ void (*xDel)(void*) /* Destructor function */
){ ){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
sqlite3VdbeMemRelease(pMem); sqlite3VdbeMemRelease(pMem);
if( !z ){ if( !z ){
pMem->flags = MEM_Null; pMem->flags = MEM_Null;
pMem->type = SQLITE_NULL; pMem->type = SQLITE_NULL;
return SQLITE_OK; return SQLITE_OK;
} }
pMem->z = (char *)z; pMem->z = (char *)z;
if( xDel==SQLITE_STATIC ){ if( xDel==SQLITE_STATIC ){
pMem->flags = MEM_Static; pMem->flags = MEM_Static;
@@ -580,13 +595,13 @@ int sqlite3VdbeMemSetStr(
pMem->n = sqlite3Utf16ByteLen(pMem->z,-1); pMem->n = sqlite3Utf16ByteLen(pMem->z,-1);
pMem->flags |= MEM_Term; pMem->flags |= MEM_Term;
} }
if( sqlite3VdbeMemHandleBom(db, pMem) ){ if( sqlite3VdbeMemHandleBom(pMem) ){
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
#endif /* SQLITE_OMIT_UTF16 */ #endif /* SQLITE_OMIT_UTF16 */
} }
if( pMem->flags&MEM_Ephem ){ if( pMem->flags&MEM_Ephem ){
return sqlite3VdbeMemMakeWriteable(db, pMem); return sqlite3VdbeMemMakeWriteable(pMem);
} }
return SQLITE_OK; return SQLITE_OK;
} }
@@ -686,17 +701,17 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
int n1, n2; int n1, n2;
/* Convert the strings into the encoding that the comparison /* Convert the strings into the encoding that the comparison
** function expects */ ** function expects */
v1 = sqlite3ValueText(0, (sqlite3_value*)pMem1, pColl->enc); v1 = sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc);
n1 = v1==0 ? 0 : pMem1->n; n1 = v1==0 ? 0 : pMem1->n;
assert( n1==sqlite3ValueBytes(0, (sqlite3_value*)pMem1, pColl->enc) ); assert( n1==sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc) );
v2 = sqlite3ValueText(0, (sqlite3_value*)pMem2, pColl->enc); v2 = sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc);
n2 = v2==0 ? 0 : pMem2->n; n2 = v2==0 ? 0 : pMem2->n;
assert( n2==sqlite3ValueBytes(0, (sqlite3_value*)pMem2, pColl->enc) ); assert( n2==sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc) );
/* Do the comparison */ /* Do the comparison */
rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2); rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
/* Convert the strings back into the database encoding */ /* Convert the strings back into the database encoding */
sqlite3ValueText(0, (sqlite3_value*)pMem1, origEnc); sqlite3ValueText((sqlite3_value*)pMem1, origEnc);
sqlite3ValueText(0, (sqlite3_value*)pMem2, origEnc); sqlite3ValueText((sqlite3_value*)pMem2, origEnc);
return rc; return rc;
} }
} }
@@ -726,7 +741,6 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
** to read from the disk) then the pMem is left in an inconsistent state. ** to read from the disk) then the pMem is left in an inconsistent state.
*/ */
int sqlite3VdbeMemFromBtree( int sqlite3VdbeMemFromBtree(
sqlite3 *db, /* Database connect to report malloc errors to */
BtCursor *pCur, /* Cursor pointing at record to retrieve. */ BtCursor *pCur, /* Cursor pointing at record to retrieve. */
int offset, /* Offset from the start of data to return bytes from. */ int offset, /* Offset from the start of data to return bytes from. */
int amt, /* Number of bytes to return. */ int amt, /* Number of bytes to return. */
@@ -735,7 +749,10 @@ int sqlite3VdbeMemFromBtree(
){ ){
char *zData; /* Data from the btree layer */ char *zData; /* Data from the btree layer */
int available = 0; /* Number of bytes available on the local btree page */ int available = 0; /* Number of bytes available on the local btree page */
sqlite3 *db; /* Database connection */
db = sqlite3BtreeCursorDb(pCur);
assert( sqlite3_mutex_held(db->mutex) );
if( key ){ if( key ){
zData = (char *)sqlite3BtreeKeyFetch(pCur, &available); zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
}else{ }else{
@@ -743,6 +760,7 @@ int sqlite3VdbeMemFromBtree(
} }
assert( zData!=0 ); assert( zData!=0 );
pMem->db = db;
pMem->n = amt; pMem->n = amt;
if( offset+amt<=available ){ if( offset+amt<=available ){
pMem->z = &zData[offset]; pMem->z = &zData[offset];
@@ -750,9 +768,8 @@ int sqlite3VdbeMemFromBtree(
}else{ }else{
int rc; int rc;
if( amt>NBFS-2 ){ if( amt>NBFS-2 ){
zData = (char *)sqlite3_malloc(amt+2); zData = (char *)sqlite3DbMallocRaw(db, amt+2);
if( !zData ){ if( !zData ){
db->mallocFailed = 1;
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term; pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
@@ -847,8 +864,10 @@ void sqlite3VdbeMemSanity(Mem *pMem){
** If that is the case, then the result must be aligned on an even byte ** If that is the case, then the result must be aligned on an even byte
** boundary. ** boundary.
*/ */
const void *sqlite3ValueText(sqlite3 *db, sqlite3_value* pVal, u8 enc){ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
if( !pVal ) return 0; if( !pVal ) return 0;
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
if( pVal->flags&MEM_Null ){ if( pVal->flags&MEM_Null ){
@@ -856,22 +875,23 @@ const void *sqlite3ValueText(sqlite3 *db, sqlite3_value* pVal, u8 enc){
} }
assert( (MEM_Blob>>3) == MEM_Str ); assert( (MEM_Blob>>3) == MEM_Str );
pVal->flags |= (pVal->flags & MEM_Blob)>>3; pVal->flags |= (pVal->flags & MEM_Blob)>>3;
expandBlob(db, pVal); expandBlob(pVal);
if( pVal->flags&MEM_Str ){ if( pVal->flags&MEM_Str ){
sqlite3VdbeChangeEncoding(db, pVal, enc & ~SQLITE_UTF16_ALIGNED); sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){ if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){
assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
if( sqlite3VdbeMemMakeWriteable(db, pVal)!=SQLITE_OK ){ if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
return 0; return 0;
} }
} }
sqlite3VdbeMemNulTerminate(db, pVal); sqlite3VdbeMemNulTerminate(pVal);
}else{ }else{
assert( (pVal->flags&MEM_Blob)==0 ); assert( (pVal->flags&MEM_Blob)==0 );
sqlite3VdbeMemStringify(db, pVal, enc); sqlite3VdbeMemStringify(pVal, enc);
assert( 0==(1&(int)pVal->z) ); assert( 0==(1&(int)pVal->z) );
} }
assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || db->mallocFailed ); assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
|| pVal->db->mallocFailed );
if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
return pVal->z; return pVal->z;
}else{ }else{
@@ -887,6 +907,7 @@ sqlite3_value *sqlite3ValueNew(sqlite3 *db){
if( p ){ if( p ){
p->flags = MEM_Null; p->flags = MEM_Null;
p->type = SQLITE_NULL; p->type = SQLITE_NULL;
p->db = db;
}else{ }else{
db->mallocFailed = 1; db->mallocFailed = 1;
} }
@@ -904,7 +925,7 @@ sqlite3_value *sqlite3ValueNew(sqlite3 *db){
** cannot be converted to a value, then *ppVal is set to NULL. ** cannot be converted to a value, then *ppVal is set to NULL.
*/ */
int sqlite3ValueFromExpr( int sqlite3ValueFromExpr(
sqlite3 *db, /* Report malloc() errors here */ sqlite3 *db, /* The database connection */
Expr *pExpr, /* The expression to evaluate */ Expr *pExpr, /* The expression to evaluate */
u8 enc, /* Encoding to use */ u8 enc, /* Encoding to use */
u8 affinity, /* Affinity to use */ u8 affinity, /* Affinity to use */
@@ -925,11 +946,11 @@ int sqlite3ValueFromExpr(
pVal = sqlite3ValueNew(db); pVal = sqlite3ValueNew(db);
if( !zVal || !pVal ) goto no_mem; if( !zVal || !pVal ) goto no_mem;
sqlite3Dequote(zVal); sqlite3Dequote(zVal);
sqlite3ValueSetStr(db, pVal, -1, zVal, SQLITE_UTF8, sqlite3_free); sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, sqlite3_free);
if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){ if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
sqlite3ValueApplyAffinity(db, pVal, SQLITE_AFF_NUMERIC, enc); sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, enc);
}else{ }else{
sqlite3ValueApplyAffinity(db, pVal, affinity, enc); sqlite3ValueApplyAffinity(pVal, affinity, enc);
} }
}else if( op==TK_UMINUS ) { }else if( op==TK_UMINUS ) {
if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){ if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){
@@ -945,8 +966,7 @@ int sqlite3ValueFromExpr(
if( !zVal || !pVal ) goto no_mem; if( !zVal || !pVal ) goto no_mem;
sqlite3Dequote(zVal); sqlite3Dequote(zVal);
nVal = strlen(zVal)/2; nVal = strlen(zVal)/2;
sqlite3VdbeMemSetStr( sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal), nVal,0,sqlite3_free);
db, pVal, sqlite3HexToBlob(db, zVal), nVal, 0, sqlite3_free);
sqlite3_free(zVal); sqlite3_free(zVal);
} }
#endif #endif
@@ -966,14 +986,13 @@ no_mem:
** Change the string value of an sqlite3_value object ** Change the string value of an sqlite3_value object
*/ */
void sqlite3ValueSetStr( void sqlite3ValueSetStr(
sqlite3 *db, /* Report malloc errors here */
sqlite3_value *v, /* Value to be set */ sqlite3_value *v, /* Value to be set */
int n, /* Length of string z */ int n, /* Length of string z */
const void *z, /* Text of the new string */ const void *z, /* Text of the new string */
u8 enc, /* Encoding to use */ u8 enc, /* Encoding to use */
void (*xDel)(void*) /* Destructor for the string */ void (*xDel)(void*) /* Destructor for the string */
){ ){
if( v ) sqlite3VdbeMemSetStr(db, (Mem *)v, z, n, enc, xDel); if( v ) sqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel);
} }
/* /*
@@ -981,7 +1000,7 @@ void sqlite3ValueSetStr(
*/ */
void sqlite3ValueFree(sqlite3_value *v){ void sqlite3ValueFree(sqlite3_value *v){
if( !v ) return; if( !v ) return;
sqlite3ValueSetStr(0, v, 0, 0, SQLITE_UTF8, SQLITE_STATIC); sqlite3ValueSetStr(v, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
sqlite3_free(v); sqlite3_free(v);
} }
@@ -989,9 +1008,9 @@ void sqlite3ValueFree(sqlite3_value *v){
** Return the number of bytes in the sqlite3_value object assuming ** Return the number of bytes in the sqlite3_value object assuming
** that it uses the encoding "enc" ** that it uses the encoding "enc"
*/ */
int sqlite3ValueBytes(sqlite3 *db, sqlite3_value *pVal, u8 enc){ int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
Mem *p = (Mem*)pVal; Mem *p = (Mem*)pVal;
if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(db, pVal, enc) ){ if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
if( p->flags & MEM_Zero ){ if( p->flags & MEM_Zero ){
return p->n+p->u.i; return p->n+p->u.i;
}else{ }else{