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:
parent
e30f442622
commit
b21c8cd4f6
58
manifest
58
manifest
@ -1,5 +1,5 @@
|
||||
C Adding\smore\sthread\slocking\scode.\s\sThis\sis\san\sincremental\scheck-in.\s(CVS\s4262)
|
||||
D 2007-08-21T16:15:56
|
||||
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-21T19:33:56
|
||||
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
|
||||
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@ -79,26 +79,26 @@ F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
|
||||
F src/alter.c f0aac0060ae8102e58f210b44d35b53438d53173
|
||||
F src/analyze.c a14237d869c6bea0846493b59317e4097e81a0b6
|
||||
F src/attach.c a52225c75b107be8c5bc144a2b6d20201be3f8f8
|
||||
F src/auth.c 5ea90bc93dfea46e9fe4bf531e14c7cd98219ecb
|
||||
F src/btree.c 8e529f390d8d1d83acbaf13cb1c09da8361cf5b1
|
||||
F src/btree.h 525105564c87111922412368f2e4301c36e74ac1
|
||||
F src/auth.c 083c1205b45e3f52291ec539d396b4fc557856b3
|
||||
F src/btree.c 4cfe2fe8d61dd906662833732919dc27116ffce7
|
||||
F src/btree.h aeb85d6a48573785666fb97566bf5802d5f9b7ca
|
||||
F src/btreeInt.h e93edf57832278138b98cf60cbc54241103c6988
|
||||
F src/build.c add67be992307b4b11849a6611bfd3352aacde92
|
||||
F src/callback.c 143436453bb93e831c9574fea0b9b9eb90e40ff3
|
||||
F src/complete.c ea63834e798a0ab14159bdc6e6cabc3df21aa346
|
||||
F src/date.c 70a5af1944c0b76bed917cab3c1ca47e5f97d359
|
||||
F src/build.c 2159551184160e2cf17ff945e9a05fbe6f331c3d
|
||||
F src/callback.c fdd527372162a974094103eae82119fcfcf11260
|
||||
F src/complete.c b6dea59fb6d7b3201fa1e0e552cda8c2258a4f50
|
||||
F src/date.c a80b33f6e70d619978622547d2c78ab8b036b31a
|
||||
F src/delete.c 849846d06d29851dde0d9f424a5de5817eb140d1
|
||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||
F src/expr.c 3ea108a9e409f58b8203e29c54442da5085be5bf
|
||||
F src/func.c 8516d5f97ddc1004537490fbaffa9a8b0da5c4bb
|
||||
F src/func.c 36440cb02589fd4697cbbf0b351eeedc160d1f4b
|
||||
F src/hash.c 2f322979071dd2bdba7503b5276d66f028744382
|
||||
F src/hash.h 3ad3da76bfb954978d227bf495568b0e6da2c19e
|
||||
F src/insert.c 633322aef1799f6604fa805e12488bc628570b0c
|
||||
F src/legacy.c a83519a8fbb488c3155fca577b010d590ec479e9
|
||||
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
|
||||
F src/loadext.c 780748f3f55a3b5af6ed0adfd58035f728cde4ca
|
||||
F src/main.c 1f6f46975182c589c4942c708c9821db7c5d5772
|
||||
F src/malloc.c c2f5da620d8e030c6974a0ddcaeb7b408c9bdb3d
|
||||
F src/loadext.c dd803303fd06ef0b13913faaa4a7fc7d8c8c4e77
|
||||
F src/main.c 7cec512d2c83afea2b83977b384633b9edb1ae1d
|
||||
F src/malloc.c c291b07b6b03ba1a1db0c24f630b745071679ed0
|
||||
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
||||
F src/mem1.c 30bf8be3846f92fdf88c490c5e5378512383bcbe
|
||||
F src/mem2.c 482f0aaf14e8ef1db64cb8c5b9a9bfe708297c92
|
||||
@ -118,23 +118,23 @@ F src/pager.c df16604a2a8c6808cd9b309a7e1bdb556d868c8e
|
||||
F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8
|
||||
F src/parse.y 2d2ce439dc6184621fb0b86f4fc5aca7f391a590
|
||||
F src/pragma.c 9b989506a1b7c8aecd6befb8235e2f57a4aba7e5
|
||||
F src/prepare.c 5bc8c7a943215302943fec831f8c646f6dfdf76a
|
||||
F src/prepare.c d30764fabc3eb704c0d18bdeb9f38df028f19567
|
||||
F src/printf.c a8f46e0ed360c18d40e89aa636533be300b406c2
|
||||
F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
|
||||
F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2
|
||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
|
||||
F src/sqlite.h.in c691ae04f7c064d853710a1eff4707549a54e1f8
|
||||
F src/sqlite.h.in 95e159919060f9c6e060ff420ce17490f7b6a0f3
|
||||
F src/sqlite3ext.h 647a6b8a8f76ff6c9611e4a071531d8e63ff2d6b
|
||||
F src/sqliteInt.h c9ba3861d1e8835caeb0c89fca7cddd12779e1ac
|
||||
F src/sqliteInt.h 23eb6a5b1f10d5d3d34c3c7846b7c3b93acf1276
|
||||
F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
|
||||
F src/table.c c725e47f6f3092b9a7b569fc58e408e2173ee008
|
||||
F src/tclsqlite.c 299fb45c5cf983b49b2c984b87b936b8132fbfe2
|
||||
F src/test1.c 9e9651b0b9f85654b4bf28dfad787bc21a33aae5
|
||||
F src/test1.c 70b96fc5ef8d013e2da0f936a62fe76e387faf83
|
||||
F src/test2.c 4f742e99ed1bea5c14692f627bdb59a146f30504
|
||||
F src/test3.c 2e4da0fe90a0aa8cf9276ea34cbe92e91dc1db07
|
||||
F src/test4.c d97b87919dc3db1cc5fccc04a33f030d5940e1a9
|
||||
F src/test5.c 81353afad5d795ae7155bffce1e4deef10ee8e22
|
||||
F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4
|
||||
F src/test6.c da83a0e49c03e8a25f4ce6e25c537c6617c14fc0
|
||||
F src/test7.c 50f5aa04fd751528ad5ee50e9be9ecee6f0b574a
|
||||
F src/test8.c 4bf571b82e502094846ae06e30fe028f190aaaae
|
||||
@ -153,17 +153,17 @@ F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59
|
||||
F src/tokenize.c e39527c9c867774a92716c669a48ad8fbc3cdc63
|
||||
F src/trigger.c dccc6fbf37d12193c90ede5b026bbd195d505ff4
|
||||
F src/update.c e89b980b443d44b68bfc0b1746cdb6308e049ac9
|
||||
F src/utf.c 853f97ce0d3cff8dbaef517a6dc475f7001a67c5
|
||||
F src/util.c 23251cee7867dfdcc80b05d278dbca71586d95cf
|
||||
F src/utf.c 4af6259d5906b5a1bf3035cc387c4d7907bdd56e
|
||||
F src/util.c 3f9c0387b54f977726790f52ab92cd3d9379b367
|
||||
F src/vacuum.c 318ccae7c4e3ddf241aeaee4d2611bfe1949a373
|
||||
F src/vdbe.c f1a9a29da48ccfa49042df478abb478520589f37
|
||||
F src/vdbe.c 9d4d00589c174aad9a616f1615464ddddebba0ec
|
||||
F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3
|
||||
F src/vdbeInt.h 8e360d326328e7a66100f468697edf9cfb4567dc
|
||||
F src/vdbeapi.c b4a1f4d56906a43f40c2bc47d7b142db3759c14e
|
||||
F src/vdbeaux.c 14b48bfc6334682e5e5858a0835f8b00d8751953
|
||||
F src/vdbeblob.c ac223e6d3acaa3321ce09c11c47bf0d05b37372f
|
||||
F src/vdbeInt.h 39fb069ce04137545ca0bc790f80ddc64a8c99d9
|
||||
F src/vdbeapi.c 09eb4fe5ce6e8e4558ca3fa1e22241f2d3895bf0
|
||||
F src/vdbeaux.c b0aeed4ff33352904b392ee6c7408bae5b141b9b
|
||||
F src/vdbeblob.c d12ed95dac0992e1e372d079d76af047cc42f7c7
|
||||
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
|
||||
F src/vdbemem.c 2843e6f91e8f19cfd72cfc7b24a03f1647db3c28
|
||||
F src/vdbemem.c 3de25d78e7b1d0af7a05199de905cea8c43aed5d
|
||||
F src/vtab.c ee29237ecc9b310dc43c0c2ac5caa6c6a20787be
|
||||
F src/where.c 2776a0caf8cbbfd6ec79cfb1cd9bc25074055e5e
|
||||
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
|
||||
@ -558,7 +558,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P 3787563e90d7210d349ee36484c3f008c955552e
|
||||
R 059b95f5c37a602e37abf433f570fd9a
|
||||
P 7428732b1fa04b83eda0a3539834693ef351313e
|
||||
R 913d5d6bd631d176ac289a9e0cf82ff0
|
||||
U drh
|
||||
Z da09ba003aea60219dd1a004da17c3aa
|
||||
Z c581f4a42a4b4dc59e9659821c9fdece
|
||||
|
@ -1 +1 @@
|
||||
7428732b1fa04b83eda0a3539834693ef351313e
|
||||
9287276191a582c1cf7cf6b71d8399727d8e534d
|
@ -14,7 +14,7 @@
|
||||
** systems that do not need this facility may omit it by recompiling
|
||||
** 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"
|
||||
|
||||
@ -74,9 +74,11 @@ int sqlite3_set_authorizer(
|
||||
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
|
||||
void *pArg
|
||||
){
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->xAuth = xAuth;
|
||||
db->pAuthArg = pArg;
|
||||
sqlite3ExpirePreparedStatements(db);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
** 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.
|
||||
** See the header comment on "btreeInt.h" for additional information.
|
||||
@ -3706,6 +3706,13 @@ int sqlite3BtreeEof(BtCursor *pCur){
|
||||
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
|
||||
** successful then set *pRes=0. If the cursor
|
||||
|
@ -13,7 +13,7 @@
|
||||
** subsystem. See comments in the source code for a detailed description
|
||||
** 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_
|
||||
#define _BTREE_H_
|
||||
@ -150,6 +150,7 @@ int sqlite3BtreeFlags(BtCursor*);
|
||||
int sqlite3BtreePrevious(BtCursor*, int *pRes);
|
||||
int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
|
||||
int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
|
||||
sqlite3 *sqlite3BtreeCursorDb(const BtCursor*);
|
||||
const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
|
||||
const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
|
||||
int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
|
||||
|
@ -22,7 +22,7 @@
|
||||
** COMMIT
|
||||
** 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 <ctype.h>
|
||||
@ -3369,6 +3369,7 @@ KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
|
||||
KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(pParse->db, nBytes);
|
||||
|
||||
if( pKey ){
|
||||
pKey->db = pParse->db;
|
||||
pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
|
||||
assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
|
||||
for(i=0; i<nCol; i++){
|
||||
|
@ -13,7 +13,7 @@
|
||||
** This file contains functions used to access the internal hash tables
|
||||
** 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"
|
||||
@ -36,8 +36,8 @@ static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
|
||||
if( db->xCollNeeded16 ){
|
||||
char const *zExternal;
|
||||
sqlite3_value *pTmp = sqlite3ValueNew(db);
|
||||
sqlite3ValueSetStr(db, pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC);
|
||||
zExternal = sqlite3ValueText(db, pTmp, SQLITE_UTF16NATIVE);
|
||||
sqlite3ValueSetStr(pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC);
|
||||
zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
|
||||
if( zExternal ){
|
||||
db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
** separating it out, the code will be automatically omitted from
|
||||
** 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"
|
||||
#ifndef SQLITE_OMIT_COMPLETE
|
||||
@ -251,8 +251,8 @@ int sqlite3_complete16(const void *zSql){
|
||||
int rc = SQLITE_NOMEM;
|
||||
|
||||
pVal = sqlite3ValueNew(0);
|
||||
sqlite3ValueSetStr(0, pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
|
||||
zSql8 = sqlite3ValueText(0, pVal, SQLITE_UTF8);
|
||||
sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
|
||||
zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
|
||||
if( zSql8 ){
|
||||
rc = sqlite3_complete(zSql8);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
|
||||
** 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
|
||||
** dates and times are stored as the number of days since noon
|
||||
@ -905,7 +905,7 @@ static void ctimeFunc(
|
||||
){
|
||||
sqlite3_value *pVal = sqlite3ValueNew(0);
|
||||
if( pVal ){
|
||||
sqlite3ValueSetStr(0, pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
|
||||
sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
|
||||
timeFunc(context, 1, &pVal);
|
||||
sqlite3ValueFree(pVal);
|
||||
}
|
||||
@ -923,7 +923,7 @@ static void cdateFunc(
|
||||
){
|
||||
sqlite3_value *pVal = sqlite3ValueNew(0);
|
||||
if( pVal ){
|
||||
sqlite3ValueSetStr(0, pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
|
||||
sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
|
||||
dateFunc(context, 1, &pVal);
|
||||
sqlite3ValueFree(pVal);
|
||||
}
|
||||
@ -941,7 +941,7 @@ static void ctimestampFunc(
|
||||
){
|
||||
sqlite3_value *pVal = sqlite3ValueNew(0);
|
||||
if( pVal ){
|
||||
sqlite3ValueSetStr(0, pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
|
||||
sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC);
|
||||
datetimeFunc(context, 1, &pVal);
|
||||
sqlite3ValueFree(pVal);
|
||||
}
|
||||
|
10
src/func.c
10
src/func.c
@ -16,7 +16,7 @@
|
||||
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
|
||||
** All other code has file scope.
|
||||
**
|
||||
** $Id: func.c,v 1.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 <ctype.h>
|
||||
@ -1062,13 +1062,13 @@ static void test_destructor(
|
||||
test_destructor_count_var++;
|
||||
assert( nArg==1 );
|
||||
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[len] = 0;
|
||||
zVal[len-1] = 0;
|
||||
assert( zVal );
|
||||
zVal++;
|
||||
memcpy(zVal, sqlite3ValueText(0, argv[0], ENC(db)), len);
|
||||
memcpy(zVal, sqlite3ValueText(argv[0], ENC(db)), len);
|
||||
if( ENC(db)==SQLITE_UTF8 ){
|
||||
sqlite3_result_text(pCtx, zVal, -1, destructor);
|
||||
#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;
|
||||
cmp = sqlite3MemCompare(pBest, pArg, pColl);
|
||||
if( (max && cmp<0) || (!max && cmp>0) ){
|
||||
sqlite3VdbeMemCopy(0, pBest, pArg);
|
||||
sqlite3VdbeMemCopy(pBest, pArg);
|
||||
}
|
||||
}else{
|
||||
sqlite3VdbeMemCopy(0, pBest, pArg);
|
||||
sqlite3VdbeMemCopy(pBest, pArg);
|
||||
}
|
||||
}
|
||||
static void minMaxFinalize(sqlite3_context *context){
|
||||
|
@ -260,7 +260,7 @@ const sqlite3_api_routines sqlite3_apis = {
|
||||
** error message text. The calling function should free this memory
|
||||
** by calling sqlite3_free().
|
||||
*/
|
||||
int sqlite3_load_extension(
|
||||
static int sqlite3LoadExtension(
|
||||
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 */
|
||||
@ -329,6 +329,18 @@ int sqlite3_load_extension(
|
||||
db->aExtension[db->nExtension-1] = handle;
|
||||
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
|
||||
@ -336,6 +348,7 @@ int sqlite3_load_extension(
|
||||
*/
|
||||
void sqlite3CloseExtensions(sqlite3 *db){
|
||||
int i;
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
for(i=0; i<db->nExtension; 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.
|
||||
*/
|
||||
int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
if( onoff ){
|
||||
db->flags |= SQLITE_LoadExtension;
|
||||
}else{
|
||||
db->flags &= ~SQLITE_LoadExtension;
|
||||
}
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** 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 <ctype.h>
|
||||
@ -819,7 +819,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){
|
||||
assert( !db->mallocFailed );
|
||||
z = sqlite3_value_text16(db->pErr);
|
||||
if( z==0 ){
|
||||
sqlite3ValueSetStr(db, db->pErr, -1, sqlite3ErrStr(db->errCode),
|
||||
sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
|
||||
SQLITE_UTF8, SQLITE_STATIC);
|
||||
z = sqlite3_value_text16(db->pErr);
|
||||
}
|
||||
@ -1116,8 +1116,8 @@ int sqlite3_open16(
|
||||
assert( ppDb );
|
||||
*ppDb = 0;
|
||||
pVal = sqlite3ValueNew(0);
|
||||
sqlite3ValueSetStr(0, pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
|
||||
zFilename8 = sqlite3ValueText(0, pVal, SQLITE_UTF8);
|
||||
sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
|
||||
zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
|
||||
if( zFilename8 ){
|
||||
rc = openDatabase(zFilename8, ppDb,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
|
||||
|
68
src/malloc.c
68
src/malloc.c
@ -12,24 +12,46 @@
|
||||
** 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 <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
** Set the soft heap-size limit for the current thread. Passing a negative
|
||||
** value indicates no limit.
|
||||
** This routine runs when the memory allocator sees that the
|
||||
** 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){
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
ThreadData *pTd = sqlite3ThreadData();
|
||||
if( pTd ){
|
||||
pTd->nSoftHeapLimit = n;
|
||||
sqlite3_uint64 iLimit;
|
||||
int overage;
|
||||
if( n<0 ){
|
||||
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);
|
||||
if( p ){
|
||||
memset(p, 0, n);
|
||||
}else{
|
||||
}else if( db ){
|
||||
db->mallocFailed = 1;
|
||||
}
|
||||
return p;
|
||||
@ -196,29 +218,3 @@ int sqlite3ApiExit(sqlite3* db, int rc){
|
||||
}
|
||||
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
|
||||
|
@ -13,7 +13,7 @@
|
||||
** interface, and routines that contribute to loading the database schema
|
||||
** 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 <ctype.h>
|
||||
@ -470,6 +470,7 @@ int sqlite3Prepare(
|
||||
if( sqlite3SafetyOn(db) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
|
||||
/* If any attached database schemas are locked, do not proceed with
|
||||
** compilation. Instead return SQLITE_LOCKED immediately.
|
||||
@ -563,6 +564,20 @@ int sqlite3Prepare(
|
||||
assert( (rc&db->errMask)==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.
|
||||
@ -574,12 +589,13 @@ int sqlite3Reprepare(Vdbe *p){
|
||||
sqlite3_stmt *pNew;
|
||||
const char *zSql;
|
||||
sqlite3 *db;
|
||||
|
||||
|
||||
zSql = sqlite3VdbeGetSql(p);
|
||||
if( zSql==0 ){
|
||||
return 0;
|
||||
}
|
||||
db = sqlite3VdbeDb(p);
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
rc = sqlite3Prepare(db, zSql, -1, 0, &pNew, 0);
|
||||
if( rc ){
|
||||
assert( pNew==0 );
|
||||
@ -610,7 +626,7 @@ int sqlite3_prepare(
|
||||
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
|
||||
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(
|
||||
sqlite3 *db, /* Database handle. */
|
||||
@ -619,7 +635,7 @@ int sqlite3_prepare_v2(
|
||||
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
|
||||
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) ){
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
zSql8 = sqlite3Utf16to8(db, zSql, nBytes);
|
||||
if( zSql8 ){
|
||||
rc = sqlite3Prepare(db, zSql8, -1, saveSqlFlag, ppStmt, &zTail8);
|
||||
@ -661,7 +678,9 @@ static int sqlite3Prepare16(
|
||||
*pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed);
|
||||
}
|
||||
sqlite3_free(zSql8);
|
||||
return sqlite3ApiExit(db, rc);
|
||||
rc = sqlite3ApiExit(db, rc);
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -30,7 +30,7 @@
|
||||
** the version number) and changes its name to "sqlite3.h" as
|
||||
** 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_
|
||||
#define _SQLITE3_H_
|
||||
@ -2257,7 +2257,7 @@ void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
|
||||
** the implementation of the function using this call.
|
||||
**
|
||||
** 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*);
|
||||
|
||||
@ -2291,8 +2291,8 @@ void *sqlite3_user_data(sqlite3_context*);
|
||||
** expressions that are constant at compile time. This includes literal
|
||||
** values and SQL variables.
|
||||
**
|
||||
** These routine must be called from the same thread in which
|
||||
** the SQL function was originally invoked.
|
||||
** These routines must be called from the same thread in which
|
||||
** the SQL function is running.
|
||||
*/
|
||||
void *sqlite3_get_auxdata(sqlite3_context*, int);
|
||||
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
|
||||
** 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
|
||||
** 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
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** 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_
|
||||
#define _SQLITEINT_H_
|
||||
@ -793,6 +793,7 @@ struct FKey {
|
||||
** were larger.
|
||||
*/
|
||||
struct KeyInfo {
|
||||
sqlite3 *db; /* The database connection */
|
||||
u8 enc; /* Text encoding - one of the TEXT_Utf* values */
|
||||
u8 incrKey; /* Increase 2nd key by epsilon before comparison */
|
||||
int nField; /* Number of entries in aColl[] */
|
||||
@ -1744,15 +1745,15 @@ int sqlite3CheckCollSeq(Parse *, CollSeq *);
|
||||
int sqlite3CheckObjectName(Parse *, const char *);
|
||||
void sqlite3VdbeSetChanges(sqlite3 *, int);
|
||||
|
||||
const void *sqlite3ValueText(sqlite3 *db, sqlite3_value*, u8);
|
||||
int sqlite3ValueBytes(sqlite3 *db, sqlite3_value*, u8);
|
||||
void sqlite3ValueSetStr(sqlite3 *,sqlite3_value*, int, const void *,u8,
|
||||
const void *sqlite3ValueText(sqlite3_value*, u8);
|
||||
int sqlite3ValueBytes(sqlite3_value*, u8);
|
||||
void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
|
||||
void(*)(void*));
|
||||
void sqlite3ValueFree(sqlite3_value*);
|
||||
sqlite3_value *sqlite3ValueNew(sqlite3 *);
|
||||
char *sqlite3Utf16to8(sqlite3 *, const void*, int);
|
||||
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[];
|
||||
void sqlite3RootPageMoved(Db*, int, int);
|
||||
void sqlite3Reindex(Parse*, Token*, Token*);
|
||||
|
22
src/test1.c
22
src/test1.c
@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** 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 "tcl.h"
|
||||
@ -921,10 +921,10 @@ static int test_create_function(
|
||||
sqlite3_iMallocFail++;
|
||||
}
|
||||
#endif
|
||||
pVal = sqlite3ValueNew(0);
|
||||
sqlite3ValueSetStr(0,pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
|
||||
pVal = sqlite3ValueNew(db);
|
||||
sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
|
||||
rc = sqlite3_create_function16(db,
|
||||
sqlite3ValueText(0, pVal, SQLITE_UTF16NATIVE),
|
||||
sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
|
||||
1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
|
||||
sqlite3ValueFree(pVal);
|
||||
}
|
||||
@ -2056,11 +2056,11 @@ static int test_collate_func(
|
||||
}
|
||||
|
||||
pVal = sqlite3ValueNew(0);
|
||||
sqlite3ValueSetStr(0, pVal, nA, zA, encin, SQLITE_STATIC);
|
||||
sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC);
|
||||
n = sqlite3_value_bytes(pVal);
|
||||
Tcl_ListObjAppendElement(i,pX,
|
||||
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);
|
||||
Tcl_ListObjAppendElement(i,pX,
|
||||
Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n));
|
||||
@ -2101,9 +2101,9 @@ static int test_collate(
|
||||
}
|
||||
#endif
|
||||
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,
|
||||
sqlite3ValueText(0, pVal, SQLITE_UTF16NATIVE), SQLITE_UTF16BE,
|
||||
sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), SQLITE_UTF16BE,
|
||||
(void *)SQLITE_UTF16BE, val?test_collate_func:0);
|
||||
sqlite3ValueFree(pVal);
|
||||
}
|
||||
@ -2270,7 +2270,7 @@ static void test_function_utf8(
|
||||
Tcl_DecrRefCount(pX);
|
||||
sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT);
|
||||
pVal = sqlite3ValueNew(0);
|
||||
sqlite3ValueSetStr(0, pVal, -1, Tcl_GetStringResult(interp),
|
||||
sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
|
||||
SQLITE_UTF8, SQLITE_STATIC);
|
||||
sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal),
|
||||
-1, SQLITE_TRANSIENT);
|
||||
@ -2293,7 +2293,7 @@ static void test_function_utf16le(
|
||||
Tcl_EvalObjEx(interp, pX, 0);
|
||||
Tcl_DecrRefCount(pX);
|
||||
pVal = sqlite3ValueNew(0);
|
||||
sqlite3ValueSetStr(0, pVal, -1, Tcl_GetStringResult(interp),
|
||||
sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
|
||||
SQLITE_UTF8, SQLITE_STATIC);
|
||||
sqlite3_result_text(pCtx,(char*)sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT);
|
||||
sqlite3ValueFree(pVal);
|
||||
@ -2315,7 +2315,7 @@ static void test_function_utf16be(
|
||||
Tcl_EvalObjEx(interp, pX, 0);
|
||||
Tcl_DecrRefCount(pX);
|
||||
pVal = sqlite3ValueNew(0);
|
||||
sqlite3ValueSetStr(0, pVal, -1, Tcl_GetStringResult(interp),
|
||||
sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
|
||||
SQLITE_UTF8, SQLITE_STATIC);
|
||||
sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal),
|
||||
-1, SQLITE_TRANSIENT);
|
||||
|
10
src/test5.c
10
src/test5.c
@ -15,7 +15,7 @@
|
||||
** is used for testing the SQLite routines for converting between
|
||||
** 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 "vdbeInt.h"
|
||||
@ -156,7 +156,7 @@ static int test_translate(
|
||||
if( objc==5 ){
|
||||
z = sqlite3StrDup(z);
|
||||
}
|
||||
sqlite3ValueSetStr(0, pVal, -1, z, enc_from, xDel);
|
||||
sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel);
|
||||
}else{
|
||||
z = (char*)Tcl_GetByteArrayFromObj(objv[1], &len);
|
||||
if( objc==5 ){
|
||||
@ -164,11 +164,11 @@ static int test_translate(
|
||||
z = sqlite3_malloc(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);
|
||||
len = sqlite3ValueBytes(0, pVal, enc_to) + (enc_to==SQLITE_UTF8?1:2);
|
||||
z = (char *)sqlite3ValueText(pVal, enc_to);
|
||||
len = sqlite3ValueBytes(pVal, enc_to) + (enc_to==SQLITE_UTF8?1:2);
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj((u8*)z, len));
|
||||
|
||||
sqlite3ValueFree(pVal);
|
||||
|
24
src/utf.c
24
src/utf.c
@ -12,7 +12,7 @@
|
||||
** This file contains routines used to translate between UTF-8,
|
||||
** 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:
|
||||
**
|
||||
@ -187,7 +187,7 @@ int sqlite3Utf8Read(
|
||||
** desiredEnc. It is an error if the string is already of the desired
|
||||
** 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 */
|
||||
int len; /* Maximum length of output string in bytes */
|
||||
unsigned char *zOut; /* Output buffer */
|
||||
@ -196,6 +196,7 @@ int sqlite3VdbeMemTranslate(sqlite3 *db, Mem *pMem, u8 desiredEnc){
|
||||
unsigned char *z; /* Output iterator */
|
||||
unsigned int c;
|
||||
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
assert( pMem->flags&MEM_Str );
|
||||
assert( pMem->enc!=desiredEnc );
|
||||
assert( pMem->enc!=0 );
|
||||
@ -216,7 +217,7 @@ int sqlite3VdbeMemTranslate(sqlite3 *db, Mem *pMem, u8 desiredEnc){
|
||||
if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){
|
||||
u8 temp;
|
||||
int rc;
|
||||
rc = sqlite3VdbeMemMakeWriteable(db, pMem);
|
||||
rc = sqlite3VdbeMemMakeWriteable(pMem);
|
||||
if( rc!=SQLITE_OK ){
|
||||
assert( rc==SQLITE_NOMEM );
|
||||
return SQLITE_NOMEM;
|
||||
@ -260,8 +261,10 @@ int sqlite3VdbeMemTranslate(sqlite3 *db, Mem *pMem, u8 desiredEnc){
|
||||
zIn = (u8*)pMem->z;
|
||||
zTerm = &zIn[pMem->n];
|
||||
if( len>NBFS ){
|
||||
zOut = sqlite3DbMallocRaw(db, len);
|
||||
if( !zOut ) return SQLITE_NOMEM;
|
||||
zOut = sqlite3DbMallocRaw(pMem->db, len);
|
||||
if( !zOut ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
}else{
|
||||
zOut = zShort;
|
||||
}
|
||||
@ -336,7 +339,7 @@ translate_out:
|
||||
** The allocation (static, dynamic etc.) and encoding of the Mem may be
|
||||
** changed by this function.
|
||||
*/
|
||||
int sqlite3VdbeMemHandleBom(sqlite3 *db, Mem *pMem){
|
||||
int sqlite3VdbeMemHandleBom(Mem *pMem){
|
||||
int rc = SQLITE_OK;
|
||||
u8 bom = 0;
|
||||
|
||||
@ -364,11 +367,11 @@ int sqlite3VdbeMemHandleBom(sqlite3 *db, Mem *pMem){
|
||||
char *z = pMem->z;
|
||||
pMem->z = 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);
|
||||
xDel(z);
|
||||
}else{
|
||||
rc = sqlite3VdbeMemSetStr(db, pMem, &pMem->z[2], pMem->n-2, bom,
|
||||
rc = sqlite3VdbeMemSetStr(pMem, &pMem->z[2], pMem->n-2, bom,
|
||||
SQLITE_TRANSIENT);
|
||||
}
|
||||
}
|
||||
@ -411,8 +414,9 @@ int sqlite3Utf8CharLen(const char *zIn, int nByte){
|
||||
char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte){
|
||||
Mem m;
|
||||
memset(&m, 0, sizeof(m));
|
||||
sqlite3VdbeMemSetStr(db, &m, z, nByte, SQLITE_UTF16NATIVE, SQLITE_STATIC);
|
||||
sqlite3VdbeChangeEncoding(db, &m, SQLITE_UTF8);
|
||||
m.db = db;
|
||||
sqlite3VdbeMemSetStr(&m, z, nByte, SQLITE_UTF16NATIVE, SQLITE_STATIC);
|
||||
sqlite3VdbeChangeEncoding(&m, SQLITE_UTF8);
|
||||
assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
|
||||
assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
|
||||
return (m.flags & MEM_Dyn)!=0 ? m.z : sqlite3DbStrDup(db, m.z);
|
||||
|
@ -14,7 +14,7 @@
|
||||
** This file contains functions for allocating memory, comparing
|
||||
** 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 <stdarg.h>
|
||||
@ -51,9 +51,9 @@ void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
|
||||
va_start(ap, zFormat);
|
||||
z = sqlite3VMPrintf(db, zFormat, ap);
|
||||
va_end(ap);
|
||||
sqlite3ValueSetStr(db, db->pErr, -1, z, SQLITE_UTF8, sqlite3_free);
|
||||
sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, sqlite3_free);
|
||||
}else{
|
||||
sqlite3ValueSetStr(db, db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
|
||||
sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
122
src/vdbe.c
122
src/vdbe.c
@ -43,7 +43,7 @@
|
||||
** in this file for details. If in doubt, do not deviate from existing
|
||||
** 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 <ctype.h>
|
||||
@ -105,8 +105,8 @@ int sqlite3_max_blobsize = 0;
|
||||
** Convert the given stack entity into a string if it isn't one
|
||||
** already. Return non-zero if a malloc() fails.
|
||||
*/
|
||||
#define Stringify(db, P, enc) \
|
||||
if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(db,P,enc)) \
|
||||
#define Stringify(P, enc) \
|
||||
if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \
|
||||
{ goto no_mem; }
|
||||
|
||||
/*
|
||||
@ -137,15 +137,15 @@ int sqlite3_max_blobsize = 0;
|
||||
** string that the stack entry itself controls. In other words, it
|
||||
** converts an MEM_Ephem string into an MEM_Dyn string.
|
||||
*/
|
||||
#define Deephemeralize(db,P) \
|
||||
#define Deephemeralize(P) \
|
||||
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*)
|
||||
** 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
|
||||
@ -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
|
||||
** 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 ){
|
||||
int realnum;
|
||||
sqlite3VdbeMemNulTerminate(db, pRec);
|
||||
sqlite3VdbeMemNulTerminate(pRec);
|
||||
if( (pRec->flags&MEM_Str)
|
||||
&& sqlite3IsNumber(pRec->z, &realnum, pRec->enc) ){
|
||||
i64 value;
|
||||
sqlite3VdbeChangeEncoding(db, pRec, SQLITE_UTF8);
|
||||
sqlite3VdbeChangeEncoding(pRec, SQLITE_UTF8);
|
||||
if( !realnum && sqlite3Atoi64(pRec->z, &value) ){
|
||||
sqlite3VdbeMemRelease(pRec);
|
||||
pRec->u.i = value;
|
||||
@ -247,7 +247,6 @@ static void applyNumericAffinity(sqlite3 *db, Mem *pRec){
|
||||
** No-op. pRec is unchanged.
|
||||
*/
|
||||
static void applyAffinity(
|
||||
sqlite3 *db, /* Report malloc() errors to this db connection */
|
||||
Mem *pRec, /* The value to apply affinity to */
|
||||
char affinity, /* The affinity to be applied */
|
||||
u8 enc /* Use this text encoding */
|
||||
@ -258,13 +257,13 @@ static void applyAffinity(
|
||||
** representation.
|
||||
*/
|
||||
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);
|
||||
}else if( affinity!=SQLITE_AFF_NONE ){
|
||||
assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
|
||||
|| affinity==SQLITE_AFF_NUMERIC );
|
||||
applyNumericAffinity(db, pRec);
|
||||
applyNumericAffinity(pRec);
|
||||
if( pRec->flags & MEM_Real ){
|
||||
sqlite3VdbeIntegerAffinity(pRec);
|
||||
}
|
||||
@ -281,7 +280,7 @@ static void applyAffinity(
|
||||
*/
|
||||
int sqlite3_value_numeric_type(sqlite3_value *pVal){
|
||||
Mem *pMem = (Mem*)pVal;
|
||||
applyNumericAffinity(0, pMem);
|
||||
applyNumericAffinity(pMem);
|
||||
storeTypeInfo(pMem, 0);
|
||||
return pMem->type;
|
||||
}
|
||||
@ -291,12 +290,11 @@ int sqlite3_value_numeric_type(sqlite3_value *pVal){
|
||||
** not the internal Mem* type.
|
||||
*/
|
||||
void sqlite3ValueApplyAffinity(
|
||||
sqlite3 *db,
|
||||
sqlite3_value *pVal,
|
||||
u8 affinity,
|
||||
u8 enc
|
||||
){
|
||||
applyAffinity(db, (Mem *)pVal, affinity, enc);
|
||||
applyAffinity((Mem *)pVal, affinity, enc);
|
||||
}
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
@ -733,7 +731,7 @@ case OP_Real: { /* same as TK_FLOAT, */
|
||||
pTos->enc = SQLITE_UTF8;
|
||||
pTos->r = sqlite3VdbeRealValue(pTos);
|
||||
pTos->flags |= MEM_Real;
|
||||
sqlite3VdbeChangeEncoding(db, pTos, encoding);
|
||||
sqlite3VdbeChangeEncoding(pTos, encoding);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -752,9 +750,9 @@ case OP_String8: { /* same as TK_STRING */
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
if( encoding!=SQLITE_UTF8 ){
|
||||
pTos++;
|
||||
sqlite3VdbeMemSetStr(db, pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC);
|
||||
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(db, pTos, encoding) ) goto no_mem;
|
||||
if( SQLITE_OK!=sqlite3VdbeMemDynamicify(db, pTos) ) goto no_mem;
|
||||
sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC);
|
||||
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, encoding) ) goto no_mem;
|
||||
if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pTos) ) goto no_mem;
|
||||
pTos->flags &= ~(MEM_Dyn);
|
||||
pTos->flags |= MEM_Static;
|
||||
if( pOp->p3type==P3_DYNAMIC ){
|
||||
@ -842,7 +840,7 @@ case OP_HexBlob: { /* same as TK_BLOB */
|
||||
case OP_Blob: {
|
||||
pTos++;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
@ -903,7 +901,7 @@ case OP_Dup: {
|
||||
pTos++;
|
||||
sqlite3VdbeMemShallowCopy(pTos, pFrom, MEM_Ephem);
|
||||
if( pOp->p2 ){
|
||||
Deephemeralize(db, pTos);
|
||||
Deephemeralize(pTos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -924,9 +922,9 @@ case OP_Pull: { /* no-push */
|
||||
Mem ts;
|
||||
|
||||
ts = *pFrom;
|
||||
Deephemeralize(db, pTos);
|
||||
Deephemeralize(pTos);
|
||||
for(i=0; i<pOp->p1; i++, pFrom++){
|
||||
Deephemeralize(db, &pFrom[1]);
|
||||
Deephemeralize(&pFrom[1]);
|
||||
assert( (pFrom[1].flags & MEM_Ephem)==0 );
|
||||
*pFrom = pFrom[1];
|
||||
if( pFrom->flags & MEM_Short ){
|
||||
@ -954,7 +952,7 @@ case OP_Push: { /* no-push */
|
||||
Mem *pTo = &pTos[-pOp->p1];
|
||||
|
||||
assert( pTo>=p->aStack );
|
||||
sqlite3VdbeMemMove(db, pTo, pTos);
|
||||
sqlite3VdbeMemMove(pTo, pTos);
|
||||
pTos--;
|
||||
break;
|
||||
}
|
||||
@ -982,7 +980,7 @@ case OP_Callback: { /* no-push */
|
||||
*/
|
||||
pFirstColumn = &pTos[0-pOp->p1];
|
||||
for(pMem = p->aStack; pMem<pFirstColumn; pMem++){
|
||||
Deephemeralize(db, pMem);
|
||||
Deephemeralize(pMem);
|
||||
}
|
||||
|
||||
/* Invalidate all ephemeral cursor row caches */
|
||||
@ -993,7 +991,7 @@ case OP_Callback: { /* no-push */
|
||||
** as side effect.
|
||||
*/
|
||||
for(; pMem<=pTos; pMem++ ){
|
||||
sqlite3VdbeMemNulTerminate(db, pMem);
|
||||
sqlite3VdbeMemNulTerminate(pMem);
|
||||
storeTypeInfo(pMem, encoding);
|
||||
}
|
||||
|
||||
@ -1035,8 +1033,8 @@ case OP_Concat: { /* same as TK_CONCAT */
|
||||
nByte = -1;
|
||||
break;
|
||||
}
|
||||
ExpandBlob(db, pTerm);
|
||||
Stringify(db, pTerm, encoding);
|
||||
ExpandBlob(pTerm);
|
||||
Stringify(pTerm, encoding);
|
||||
nByte += pTerm->n;
|
||||
}
|
||||
|
||||
@ -1280,6 +1278,7 @@ case OP_Function: {
|
||||
ctx.s.flags = MEM_Null;
|
||||
ctx.s.z = 0;
|
||||
ctx.s.xDel = 0;
|
||||
ctx.s.db = db;
|
||||
ctx.isError = 0;
|
||||
if( ctx.pFunc->needCollSeq ){
|
||||
assert( pOp>p->aOp );
|
||||
@ -1321,10 +1320,10 @@ case OP_Function: {
|
||||
}
|
||||
|
||||
/* Copy the result of the function to the top of the stack */
|
||||
sqlite3VdbeChangeEncoding(db, &ctx.s, encoding);
|
||||
sqlite3VdbeChangeEncoding(&ctx.s, encoding);
|
||||
pTos++;
|
||||
pTos->flags = 0;
|
||||
sqlite3VdbeMemMove(db, pTos, &ctx.s);
|
||||
sqlite3VdbeMemMove(pTos, &ctx.s);
|
||||
if( sqlite3VdbeMemTooBig(pTos) ){
|
||||
goto too_big;
|
||||
}
|
||||
@ -1417,7 +1416,7 @@ case OP_AddImm: { /* no-push */
|
||||
case OP_ForceInt: { /* no-push */
|
||||
i64 v;
|
||||
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 ){
|
||||
Release(pTos);
|
||||
pTos--;
|
||||
@ -1452,7 +1451,7 @@ case OP_ForceInt: { /* no-push */
|
||||
*/
|
||||
case OP_MustBeInt: { /* no-push */
|
||||
assert( pTos>=p->aStack );
|
||||
applyAffinity(db, pTos, SQLITE_AFF_NUMERIC, encoding);
|
||||
applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);
|
||||
if( (pTos->flags & MEM_Int)==0 ){
|
||||
if( pOp->p2==0 ){
|
||||
rc = SQLITE_MISMATCH;
|
||||
@ -1500,8 +1499,8 @@ case OP_ToText: { /* same as TK_TO_TEXT, no-push */
|
||||
if( pTos->flags & MEM_Null ) break;
|
||||
assert( MEM_Str==(MEM_Blob>>3) );
|
||||
pTos->flags |= (pTos->flags&MEM_Blob)>>3;
|
||||
applyAffinity(db, pTos, SQLITE_AFF_TEXT, encoding);
|
||||
rc = ExpandBlob(db, pTos);
|
||||
applyAffinity(pTos, SQLITE_AFF_TEXT, encoding);
|
||||
rc = ExpandBlob(pTos);
|
||||
assert( pTos->flags & MEM_Str );
|
||||
pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);
|
||||
break;
|
||||
@ -1520,7 +1519,7 @@ case OP_ToBlob: { /* same as TK_TO_BLOB, no-push */
|
||||
assert( pTos>=p->aStack );
|
||||
if( pTos->flags & MEM_Null ) break;
|
||||
if( (pTos->flags & MEM_Blob)==0 ){
|
||||
applyAffinity(db, pTos, SQLITE_AFF_TEXT, encoding);
|
||||
applyAffinity(pTos, SQLITE_AFF_TEXT, encoding);
|
||||
assert( pTos->flags & MEM_Str );
|
||||
pTos->flags |= MEM_Blob;
|
||||
}
|
||||
@ -1701,13 +1700,13 @@ case OP_Ge: { /* same as TK_GE, no-push */
|
||||
|
||||
affinity = pOp->p1 & 0xFF;
|
||||
if( affinity ){
|
||||
applyAffinity(db, pNos, affinity, encoding);
|
||||
applyAffinity(db, pTos, affinity, encoding);
|
||||
applyAffinity(pNos, affinity, encoding);
|
||||
applyAffinity(pTos, affinity, encoding);
|
||||
}
|
||||
|
||||
assert( pOp->p3type==P3_COLLSEQ || pOp->p3==0 );
|
||||
ExpandBlob(db, pNos);
|
||||
ExpandBlob(db, pTos);
|
||||
ExpandBlob(pNos);
|
||||
ExpandBlob(pTos);
|
||||
res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p3);
|
||||
switch( pOp->opcode ){
|
||||
case OP_Eq: res = res==0; break;
|
||||
@ -2118,7 +2117,7 @@ case OP_Column: {
|
||||
** acquire the complete header text.
|
||||
*/
|
||||
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 ){
|
||||
goto op_column_out;
|
||||
}
|
||||
@ -2172,8 +2171,7 @@ case OP_Column: {
|
||||
zData = &zRec[aOffset[p2]];
|
||||
}else{
|
||||
len = sqlite3VdbeSerialTypeLen(aType[p2]);
|
||||
rc = sqlite3VdbeMemFromBtree(
|
||||
db, pCrsr, aOffset[p2], len, pC->isIndex, &sMem);
|
||||
rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, &sMem);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto op_column_out;
|
||||
}
|
||||
@ -2205,7 +2203,7 @@ case OP_Column: {
|
||||
|
||||
/* pTos->z might be pointing to sMem.zShort[]. Fix that so that we
|
||||
** can abandon sMem */
|
||||
rc = sqlite3VdbeMemMakeWriteable(db, pTos);
|
||||
rc = sqlite3VdbeMemMakeWriteable(pTos);
|
||||
|
||||
op_column_out:
|
||||
break;
|
||||
@ -2301,13 +2299,13 @@ case OP_MakeRecord: {
|
||||
for(pRec=pData0; pRec<=pTos; pRec++){
|
||||
int len;
|
||||
if( zAffinity ){
|
||||
applyAffinity(db, pRec, zAffinity[pRec-pData0], encoding);
|
||||
applyAffinity(pRec, zAffinity[pRec-pData0], encoding);
|
||||
}
|
||||
if( pRec->flags&MEM_Null ){
|
||||
containsNull = 1;
|
||||
}
|
||||
if( pRec->flags&MEM_Zero && pRec->n>0 ){
|
||||
ExpandBlob(db, pRec);
|
||||
ExpandBlob(pRec);
|
||||
}
|
||||
serial_type = sqlite3VdbeSerialType(pRec, file_format);
|
||||
len = sqlite3VdbeSerialTypeLen(serial_type);
|
||||
@ -2973,7 +2971,7 @@ case OP_MoveGt: { /* no-push */
|
||||
pC->rowidIsValid = res==0;
|
||||
}else{
|
||||
assert( pTos->flags & MEM_Blob );
|
||||
ExpandBlob(db, pTos);
|
||||
ExpandBlob(pTos);
|
||||
rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, 0, &res);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto abort_due_to_error;
|
||||
@ -3081,7 +3079,7 @@ case OP_Found: { /* no-push */
|
||||
int res, rx;
|
||||
assert( pC->isTable==0 );
|
||||
assert( pTos->flags & MEM_Blob );
|
||||
Stringify(db, pTos, encoding);
|
||||
Stringify(pTos, encoding);
|
||||
rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, 0, &res);
|
||||
alreadyExists = rx==SQLITE_OK && res==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
|
||||
*/
|
||||
assert( pNos->flags & MEM_Blob );
|
||||
Stringify(db, pNos, encoding);
|
||||
Stringify(pNos, encoding);
|
||||
zKey = pNos->z;
|
||||
nKey = pNos->n;
|
||||
|
||||
@ -3172,7 +3170,7 @@ case OP_IsUnique: { /* no-push */
|
||||
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( res>0 ){
|
||||
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
|
||||
** immediately to P2.
|
||||
*/
|
||||
rc = sqlite3VdbeIdxRowid(db, pCrsr, &v);
|
||||
rc = sqlite3VdbeIdxRowid(pCrsr, &v);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
@ -3876,7 +3874,7 @@ case OP_IdxInsert: { /* no-push */
|
||||
assert( pTos->flags & MEM_Blob );
|
||||
if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
|
||||
assert( pC->isTable==0 );
|
||||
rc = ExpandBlob(db, pTos);
|
||||
rc = ExpandBlob(pTos);
|
||||
if( rc==SQLITE_OK ){
|
||||
int nKey = pTos->n;
|
||||
const char *zKey = pTos->z;
|
||||
@ -3943,7 +3941,7 @@ case OP_IdxRowid: {
|
||||
if( pC->nullRow ){
|
||||
pTos->flags = MEM_Null;
|
||||
}else{
|
||||
rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
|
||||
rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
@ -4012,10 +4010,10 @@ case OP_IdxGE: { /* no-push */
|
||||
|
||||
assert( pTos->flags & MEM_Blob ); /* Created using OP_MakeRecord */
|
||||
assert( pC->deferredMoveto==0 );
|
||||
ExpandBlob(db, pTos);
|
||||
ExpandBlob(pTos);
|
||||
*pC->pIncrKey = pOp->p3!=0;
|
||||
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;
|
||||
if( rc!=SQLITE_OK ){
|
||||
break;
|
||||
@ -4337,7 +4335,7 @@ case OP_IntegrityCk: {
|
||||
pTos->xDel = 0;
|
||||
}
|
||||
pTos->enc = SQLITE_UTF8;
|
||||
sqlite3VdbeChangeEncoding(db, pTos, encoding);
|
||||
sqlite3VdbeChangeEncoding(pTos, encoding);
|
||||
sqlite3_free(aRoot);
|
||||
break;
|
||||
}
|
||||
@ -4435,7 +4433,7 @@ case OP_ContextPop: { /* no-push */
|
||||
case OP_MemStore: { /* no-push */
|
||||
assert( pTos>=p->aStack );
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nMem );
|
||||
rc = sqlite3VdbeMemMove(db, &p->aMem[pOp->p1], pTos);
|
||||
rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], pTos);
|
||||
pTos--;
|
||||
|
||||
/* 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: {
|
||||
assert( pOp->p1>=0 && pOp->p1<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;
|
||||
}
|
||||
|
||||
@ -4625,9 +4623,9 @@ case OP_AggStep: { /* no-push */
|
||||
ctx.s.flags = MEM_Null;
|
||||
ctx.s.z = 0;
|
||||
ctx.s.xDel = 0;
|
||||
ctx.s.db = db;
|
||||
ctx.isError = 0;
|
||||
ctx.pColl = 0;
|
||||
ctx.db = db;
|
||||
if( ctx.pFunc->needCollSeq ){
|
||||
assert( pOp>p->aOp );
|
||||
assert( pOp[-1].p3type==P3_COLLSEQ );
|
||||
@ -4949,6 +4947,7 @@ case OP_VColumn: {
|
||||
sqlite3_context sContext;
|
||||
memset(&sContext, 0, sizeof(sContext));
|
||||
sContext.s.flags = MEM_Null;
|
||||
sContext.s.db = db;
|
||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||
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
|
||||
** dynamic allocation in sContext.s (a Mem struct) is released.
|
||||
*/
|
||||
sqlite3VdbeChangeEncoding(db, &sContext.s, encoding);
|
||||
sqlite3VdbeChangeEncoding(&sContext.s, encoding);
|
||||
pTos++;
|
||||
pTos->flags = 0;
|
||||
sqlite3VdbeMemMove(db, pTos, &sContext.s);
|
||||
sqlite3VdbeMemMove(pTos, &sContext.s);
|
||||
|
||||
if( sqlite3SafetyOn(db) ){
|
||||
goto abort_due_to_misuse;
|
||||
@ -5028,7 +5027,7 @@ case OP_VRename: { /* no-push */
|
||||
sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p3);
|
||||
assert( pVtab->pModule->xRename );
|
||||
|
||||
Stringify(db, pTos, encoding);
|
||||
Stringify(pTos, encoding);
|
||||
|
||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||
sqlite3VtabLock(pVtab);
|
||||
@ -5149,6 +5148,7 @@ default: {
|
||||
** cell, so avoid calling MemSanity() in this case.
|
||||
*/
|
||||
if( pTos>=p->aStack && pTos->flags ){
|
||||
assert( pTos->db==db );
|
||||
sqlite3VdbeMemSanity(pTos);
|
||||
assert( !sqlite3VdbeMemTooBig(pTos) );
|
||||
}
|
||||
|
@ -130,6 +130,7 @@ struct Mem {
|
||||
FuncDef *pDef; /* Used only when flags==MEM_Agg */
|
||||
} u;
|
||||
double r; /* Real value */
|
||||
sqlite3 *db; /* The associated database connection */
|
||||
char *z; /* String or BLOB value */
|
||||
int n; /* Number of characters in string value, including '\0' */
|
||||
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 */
|
||||
u8 isError; /* Set to true for an error */
|
||||
CollSeq *pColl; /* Collating sequence */
|
||||
sqlite3 *db; /* Database connection */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -375,56 +375,56 @@ int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
|
||||
void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
|
||||
|
||||
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
|
||||
int sqlite3VdbeIdxKeyCompare(sqlite3*,Cursor*,int,const unsigned char*,int*);
|
||||
int sqlite3VdbeIdxRowid(sqlite3 *, BtCursor *, i64 *);
|
||||
int sqlite3VdbeIdxKeyCompare(Cursor*,int,const unsigned char*,int*);
|
||||
int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
|
||||
int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
|
||||
int sqlite3VdbeRecordCompare(void*,int,const void*,int, const void*);
|
||||
int sqlite3VdbeIdxRowidLen(const u8*);
|
||||
int sqlite3VdbeExec(Vdbe*);
|
||||
int sqlite3VdbeList(Vdbe*);
|
||||
int sqlite3VdbeHalt(Vdbe*);
|
||||
int sqlite3VdbeChangeEncoding(sqlite3 *, Mem *, int);
|
||||
int sqlite3VdbeChangeEncoding(Mem *, int);
|
||||
int sqlite3VdbeMemTooBig(Mem*);
|
||||
int sqlite3VdbeMemCopy(sqlite3*, Mem*, const Mem*);
|
||||
int sqlite3VdbeMemCopy(Mem*, const Mem*);
|
||||
void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
|
||||
int sqlite3VdbeMemMove(sqlite3*, Mem*, Mem*);
|
||||
int sqlite3VdbeMemNulTerminate(sqlite3 *, Mem*);
|
||||
int sqlite3VdbeMemSetStr(sqlite3 *, Mem*, const char*, int, u8, void(*)(void*));
|
||||
int sqlite3VdbeMemMove(Mem*, Mem*);
|
||||
int sqlite3VdbeMemNulTerminate(Mem*);
|
||||
int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
|
||||
void sqlite3VdbeMemSetInt64(Mem*, i64);
|
||||
void sqlite3VdbeMemSetDouble(Mem*, double);
|
||||
void sqlite3VdbeMemSetNull(Mem*);
|
||||
void sqlite3VdbeMemSetZeroBlob(Mem*,int);
|
||||
int sqlite3VdbeMemMakeWriteable(sqlite3 *, Mem*);
|
||||
int sqlite3VdbeMemDynamicify(sqlite3 *, Mem*);
|
||||
int sqlite3VdbeMemStringify(sqlite3*, Mem*, int);
|
||||
int sqlite3VdbeMemMakeWriteable(Mem*);
|
||||
int sqlite3VdbeMemDynamicify(Mem*);
|
||||
int sqlite3VdbeMemStringify(Mem*, int);
|
||||
i64 sqlite3VdbeIntValue(Mem*);
|
||||
int sqlite3VdbeMemIntegerify(Mem*);
|
||||
double sqlite3VdbeRealValue(Mem*);
|
||||
void sqlite3VdbeIntegerAffinity(Mem*);
|
||||
int sqlite3VdbeMemRealify(Mem*);
|
||||
int sqlite3VdbeMemNumerify(Mem*);
|
||||
int sqlite3VdbeMemFromBtree(sqlite3*,BtCursor*,int,int,int,Mem*);
|
||||
int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
|
||||
void sqlite3VdbeMemRelease(Mem *p);
|
||||
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
|
||||
#ifndef NDEBUG
|
||||
void sqlite3VdbeMemSanity(Mem*);
|
||||
int sqlite3VdbeOpcodeNoPush(u8);
|
||||
#endif
|
||||
int sqlite3VdbeMemTranslate(sqlite3 *, Mem*, u8);
|
||||
int sqlite3VdbeMemTranslate(Mem*, u8);
|
||||
#ifdef SQLITE_DEBUG
|
||||
void sqlite3VdbePrintSql(Vdbe*);
|
||||
void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
|
||||
#endif
|
||||
int sqlite3VdbeMemHandleBom(sqlite3 *, Mem *pMem);
|
||||
int sqlite3VdbeMemHandleBom(Mem *pMem);
|
||||
void sqlite3VdbeFifoInit(Fifo*);
|
||||
int sqlite3VdbeFifoPush(Fifo*, i64);
|
||||
int sqlite3VdbeFifoPop(Fifo*, i64*);
|
||||
void sqlite3VdbeFifoClear(Fifo*);
|
||||
|
||||
#ifndef SQLITE_OMIT_INCRBLOB
|
||||
int sqlite3VdbeMemExpandBlob(sqlite3 *, Mem *);
|
||||
int sqlite3VdbeMemExpandBlob(Mem *);
|
||||
#else
|
||||
#define sqlite3VdbeMemExpandBlob(d,x) SQLITE_OK
|
||||
#define sqlite3VdbeMemExpandBlob(x) SQLITE_OK
|
||||
#endif
|
||||
|
||||
#endif /* !defined(_VDBEINT_H_) */
|
||||
|
@ -97,7 +97,7 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
|
||||
const void *sqlite3_value_blob(sqlite3_value *pVal){
|
||||
Mem *p = (Mem*)pVal;
|
||||
if( p->flags & (MEM_Blob|MEM_Str) ){
|
||||
sqlite3VdbeMemExpandBlob(0, p);
|
||||
sqlite3VdbeMemExpandBlob(p);
|
||||
p->flags &= ~MEM_Str;
|
||||
p->flags |= MEM_Blob;
|
||||
return p->z;
|
||||
@ -106,10 +106,10 @@ const void *sqlite3_value_blob(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){
|
||||
return sqlite3ValueBytes(0, pVal, SQLITE_UTF16NATIVE);
|
||||
return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
|
||||
}
|
||||
double sqlite3_value_double(sqlite3_value *pVal){
|
||||
return sqlite3VdbeRealValue((Mem*)pVal);
|
||||
@ -121,17 +121,17 @@ sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
|
||||
return sqlite3VdbeIntValue((Mem*)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
|
||||
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){
|
||||
return sqlite3ValueText(0, pVal, SQLITE_UTF16BE);
|
||||
return sqlite3ValueText(pVal, SQLITE_UTF16BE);
|
||||
}
|
||||
const void *sqlite3_value_text16le(sqlite3_value *pVal){
|
||||
return sqlite3ValueText(0, pVal, SQLITE_UTF16LE);
|
||||
return sqlite3ValueText(pVal, SQLITE_UTF16LE);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_UTF16 */
|
||||
int sqlite3_value_type(sqlite3_value* pVal){
|
||||
@ -150,19 +150,19 @@ void sqlite3_result_blob(
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
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){
|
||||
sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
|
||||
}
|
||||
void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
|
||||
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
|
||||
void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
|
||||
pCtx->isError = 1;
|
||||
sqlite3VdbeMemSetStr(0, &pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
|
||||
}
|
||||
#endif
|
||||
void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
|
||||
@ -180,7 +180,7 @@ void sqlite3_result_text(
|
||||
int n,
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
sqlite3VdbeMemSetStr(0, &pCtx->s, z, n, SQLITE_UTF8, xDel);
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, xDel);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
void sqlite3_result_text16(
|
||||
@ -189,7 +189,7 @@ void sqlite3_result_text16(
|
||||
int n,
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
sqlite3VdbeMemSetStr(0, &pCtx->s, z, n, SQLITE_UTF16NATIVE, xDel);
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, xDel);
|
||||
}
|
||||
void sqlite3_result_text16be(
|
||||
sqlite3_context *pCtx,
|
||||
@ -197,7 +197,7 @@ void sqlite3_result_text16be(
|
||||
int n,
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
sqlite3VdbeMemSetStr(0, &pCtx->s, z, n, SQLITE_UTF16BE, xDel);
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16BE, xDel);
|
||||
}
|
||||
void sqlite3_result_text16le(
|
||||
sqlite3_context *pCtx,
|
||||
@ -205,11 +205,11 @@ void sqlite3_result_text16le(
|
||||
int n,
|
||||
void (*xDel)(void *)
|
||||
){
|
||||
sqlite3VdbeMemSetStr(0, &pCtx->s, z, n, SQLITE_UTF16LE, xDel);
|
||||
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16LE, xDel);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_UTF16 */
|
||||
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){
|
||||
sqlite3VdbeMemSetZeroBlob(&pCtx->s, n);
|
||||
@ -351,19 +351,27 @@ end_of_step:
|
||||
*/
|
||||
#ifdef SQLITE_OMIT_PARSER
|
||||
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
|
||||
int sqlite3_step(sqlite3_stmt *pStmt){
|
||||
int cnt = 0;
|
||||
int rc;
|
||||
Vdbe *v = (Vdbe*)pStmt;
|
||||
sqlite3_mutex_enter(v->db->mutex);
|
||||
while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
|
||||
&& cnt++ < 5
|
||||
&& sqlite3Reprepare(v) ){
|
||||
sqlite3_reset(pStmt);
|
||||
v->expired = 0;
|
||||
}
|
||||
sqlite3_mutex_leave(v->db->mutex);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
@ -404,8 +412,10 @@ void sqlite3InvalidFunction(
|
||||
** same context that was returned on prior calls.
|
||||
*/
|
||||
void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
|
||||
Mem *pMem = p->pMem;
|
||||
Mem *pMem;
|
||||
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( nByte==0 ){
|
||||
assert( pMem->flags==MEM_Null );
|
||||
@ -418,7 +428,7 @@ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
|
||||
pMem->z = pMem->zShort;
|
||||
memset(pMem->z, 0, nByte);
|
||||
}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.
|
||||
*/
|
||||
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 ){
|
||||
return 0;
|
||||
}
|
||||
@ -452,13 +465,14 @@ void sqlite3_set_auxdata(
|
||||
VdbeFunc *pVdbeFunc;
|
||||
if( iArg<0 ) goto failed;
|
||||
|
||||
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
|
||||
pVdbeFunc = pCtx->pVdbeFunc;
|
||||
if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
|
||||
int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0);
|
||||
int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
|
||||
pVdbeFunc = sqlite3_realloc(pVdbeFunc, nMalloc);
|
||||
if( !pVdbeFunc ){
|
||||
pCtx->db->mallocFailed = 1;
|
||||
pCtx->s.db->mallocFailed = 1;
|
||||
goto failed;
|
||||
}
|
||||
pCtx->pVdbeFunc = pVdbeFunc;
|
||||
@ -524,7 +538,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
|
||||
Vdbe *pVm = (Vdbe *)pStmt;
|
||||
int vals = sqlite3_data_count(pStmt);
|
||||
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);
|
||||
return (Mem*)&nullMem;
|
||||
}
|
||||
@ -800,9 +814,9 @@ static int bindText(
|
||||
return rc;
|
||||
}
|
||||
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 ){
|
||||
rc = sqlite3VdbeChangeEncoding(p->db, pVar, ENC(p->db));
|
||||
rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
|
||||
}
|
||||
sqlite3Error(p->db, rc, 0);
|
||||
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);
|
||||
rc = vdbeUnbind(p, i);
|
||||
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);
|
||||
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++){
|
||||
sqlite3MallocDisallow();
|
||||
rc = sqlite3VdbeMemMove(0, &pTo->aVar[i], &pFrom->aVar[i]);
|
||||
rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
|
||||
sqlite3MallocAllow();
|
||||
}
|
||||
assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
|
||||
|
@ -680,6 +680,7 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
|
||||
static void releaseMemArray(Mem *p, int N){
|
||||
if( p ){
|
||||
while( N-->0 ){
|
||||
assert( N<2 || p[0].db==p[1].db );
|
||||
sqlite3VdbeMemRelease(p++);
|
||||
}
|
||||
}
|
||||
@ -887,11 +888,16 @@ void sqlite3VdbeMakeReady(
|
||||
p->nCursor = nCursor;
|
||||
for(n=0; n<nVar; n++){
|
||||
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++){
|
||||
p->aMem[n].flags = MEM_Null;
|
||||
p->aMem[n].db = db;
|
||||
}
|
||||
|
||||
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 );
|
||||
pColName = &(p->aColName[idx+var*p->nResColumn]);
|
||||
if( N==P3_DYNAMIC || N==P3_STATIC ){
|
||||
rc = sqlite3VdbeMemSetStr(p->db,
|
||||
pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
|
||||
rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
|
||||
}else{
|
||||
rc = sqlite3VdbeMemSetStr(p->db,
|
||||
pColName, zName, N, SQLITE_UTF8, SQLITE_TRANSIENT);
|
||||
rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
|
||||
}
|
||||
if( rc==SQLITE_OK && N==P3_DYNAMIC ){
|
||||
pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn;
|
||||
@ -1550,7 +1554,7 @@ int sqlite3VdbeReset(Vdbe *p){
|
||||
*/
|
||||
if( p->pc>=0 ){
|
||||
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;
|
||||
p->zErrMsg = 0;
|
||||
}else if( p->rc ){
|
||||
@ -2032,7 +2036,9 @@ int sqlite3VdbeRecordCompare(
|
||||
Mem mem1;
|
||||
Mem mem2;
|
||||
mem1.enc = pKeyInfo->enc;
|
||||
mem1.db = pKeyInfo->db;
|
||||
mem2.enc = pKeyInfo->enc;
|
||||
mem2.db = pKeyInfo->db;
|
||||
|
||||
idx1 = GetVarint(aKey1, 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.
|
||||
** 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;
|
||||
int rc;
|
||||
u32 szHdr; /* Size of the header */
|
||||
@ -2118,7 +2124,7 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
|
||||
if( nCellKey<=0 ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
rc = sqlite3VdbeMemFromBtree(db, pCur, 0, nCellKey, 1, &m);
|
||||
rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
|
||||
if( rc ){
|
||||
return rc;
|
||||
}
|
||||
@ -2142,7 +2148,6 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
|
||||
** is ignored as well.
|
||||
*/
|
||||
int sqlite3VdbeIdxKeyCompare(
|
||||
sqlite3 *db,
|
||||
Cursor *pC, /* The cursor to compare against */
|
||||
int nKey, const u8 *pKey, /* The key to compare */
|
||||
int *res /* Write the comparison result here */
|
||||
@ -2158,7 +2163,7 @@ int sqlite3VdbeIdxKeyCompare(
|
||||
*res = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
rc = sqlite3VdbeMemFromBtree(db, pC->pCursor, 0, nCellKey, 1, &m);
|
||||
rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
|
||||
if( rc ){
|
||||
return rc;
|
||||
}
|
||||
@ -2173,6 +2178,7 @@ int sqlite3VdbeIdxKeyCompare(
|
||||
** sqlite3_changes() on the database handle 'db'.
|
||||
*/
|
||||
void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
db->nChange = nChange;
|
||||
db->nTotalChange += nChange;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
**
|
||||
** 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"
|
||||
@ -247,7 +247,6 @@ blob_open_out:
|
||||
*/
|
||||
int sqlite3_blob_close(sqlite3_blob *pBlob){
|
||||
Incrblob *p = (Incrblob *)pBlob;
|
||||
sqlite3_stmt *pStmt;
|
||||
sqlite3_mutex *mutex = p->db->mutex;
|
||||
int rc;
|
||||
|
||||
|
141
src/vdbemem.c
141
src/vdbemem.c
@ -24,7 +24,7 @@
|
||||
** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem*)
|
||||
** 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
|
||||
@ -39,11 +39,12 @@
|
||||
** SQLITE_NOMEM may be returned if a malloc() fails during conversion
|
||||
** between formats.
|
||||
*/
|
||||
int sqlite3VdbeChangeEncoding(sqlite3 *db, Mem *pMem, int desiredEnc){
|
||||
int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
|
||||
int rc;
|
||||
if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
#ifdef SQLITE_OMIT_UTF16
|
||||
return SQLITE_ERROR;
|
||||
#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,
|
||||
** 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 || 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.
|
||||
*/
|
||||
int sqlite3VdbeMemDynamicify(sqlite3 *db, Mem *pMem){
|
||||
int sqlite3VdbeMemDynamicify(Mem *pMem){
|
||||
int n;
|
||||
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 ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
assert( (pMem->flags & MEM_Dyn)==0 );
|
||||
n = pMem->n;
|
||||
assert( pMem->flags & (MEM_Str|MEM_Blob) );
|
||||
z = sqlite3_malloc( n+2 );
|
||||
z = sqlite3DbMallocRaw(pMem->db, n+2 );
|
||||
if( z==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
@ -93,16 +95,16 @@ int sqlite3VdbeMemDynamicify(sqlite3 *db, Mem *pMem){
|
||||
** blob stored in dynamically allocated space.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_INCRBLOB
|
||||
int sqlite3VdbeMemExpandBlob(sqlite3 *db, Mem *pMem){
|
||||
int sqlite3VdbeMemExpandBlob(Mem *pMem){
|
||||
if( pMem->flags & MEM_Zero ){
|
||||
char *pNew;
|
||||
int nByte;
|
||||
assert( (pMem->flags & MEM_Blob)!=0 );
|
||||
nByte = pMem->n + pMem->u.i;
|
||||
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( db ) db->mallocFailed = 1;
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
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.
|
||||
*/
|
||||
int sqlite3VdbeMemMakeWriteable(sqlite3 *db, Mem *pMem){
|
||||
int sqlite3VdbeMemMakeWriteable(Mem *pMem){
|
||||
int n;
|
||||
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 ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@ -138,9 +141,8 @@ int sqlite3VdbeMemMakeWriteable(sqlite3 *db, Mem *pMem){
|
||||
z = (u8*)pMem->zShort;
|
||||
pMem->flags |= MEM_Short|MEM_Term;
|
||||
}else{
|
||||
z = sqlite3_malloc( n+2 );
|
||||
z = sqlite3DbMallocRaw(pMem->db, n+2 );
|
||||
if( z==0 ){
|
||||
db->mallocFailed = 1;
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
pMem->flags |= MEM_Dyn|MEM_Term;
|
||||
@ -158,18 +160,18 @@ int sqlite3VdbeMemMakeWriteable(sqlite3 *db, Mem *pMem){
|
||||
/*
|
||||
** 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 ){
|
||||
return SQLITE_OK; /* Nothing to do */
|
||||
}
|
||||
if( pMem->flags & (MEM_Static|MEM_Ephem) ){
|
||||
return sqlite3VdbeMemMakeWriteable(db, pMem);
|
||||
return sqlite3VdbeMemMakeWriteable(pMem);
|
||||
}else{
|
||||
char *z;
|
||||
sqlite3VdbeMemExpandBlob(db, pMem);
|
||||
z = sqlite3_malloc(pMem->n+2);
|
||||
sqlite3VdbeMemExpandBlob(pMem);
|
||||
z = sqlite3DbMallocRaw(pMem->db, pMem->n+2);
|
||||
if( !z ){
|
||||
db->mallocFailed = 1;
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
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
|
||||
** 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 fg = pMem->flags;
|
||||
char *z = pMem->zShort;
|
||||
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
assert( !(fg&MEM_Zero) );
|
||||
assert( !(fg&(MEM_Str|MEM_Blob)) );
|
||||
assert( fg&(MEM_Int|MEM_Real) );
|
||||
@ -225,7 +228,7 @@ int sqlite3VdbeMemStringify(sqlite3 *db, Mem *pMem, int enc){
|
||||
pMem->z = z;
|
||||
pMem->enc = SQLITE_UTF8;
|
||||
pMem->flags |= MEM_Str | MEM_Short | MEM_Term;
|
||||
sqlite3VdbeChangeEncoding(db, pMem, enc);
|
||||
sqlite3VdbeChangeEncoding(pMem, enc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -242,8 +245,10 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
|
||||
if( pFunc && pFunc->xFinalize ){
|
||||
sqlite3_context ctx;
|
||||
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.z = pMem->zShort;
|
||||
ctx.s.db = pMem->db;
|
||||
ctx.pMem = pMem;
|
||||
ctx.pFunc = pFunc;
|
||||
ctx.isError = 0;
|
||||
@ -268,6 +273,7 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
|
||||
** (Mem.type==SQLITE_TEXT).
|
||||
*/
|
||||
void sqlite3VdbeMemRelease(Mem *p){
|
||||
assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
|
||||
if( p->flags & (MEM_Dyn|MEM_Agg) ){
|
||||
if( p->xDel ){
|
||||
if( p->flags & MEM_Agg ){
|
||||
@ -296,7 +302,9 @@ void sqlite3VdbeMemRelease(Mem *p){
|
||||
** If pMem is a string, its encoding might be changed.
|
||||
*/
|
||||
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 ){
|
||||
return pMem->u.i;
|
||||
}else if( flags & MEM_Real ){
|
||||
@ -304,8 +312,8 @@ i64 sqlite3VdbeIntValue(Mem *pMem){
|
||||
}else if( flags & (MEM_Str|MEM_Blob) ){
|
||||
i64 value;
|
||||
pMem->flags |= MEM_Str;
|
||||
if( sqlite3VdbeChangeEncoding(0, pMem, SQLITE_UTF8)
|
||||
|| sqlite3VdbeMemNulTerminate(0, pMem) ){
|
||||
if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
|
||||
|| sqlite3VdbeMemNulTerminate(pMem) ){
|
||||
return 0;
|
||||
}
|
||||
assert( pMem->z );
|
||||
@ -323,6 +331,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){
|
||||
** If it is a NULL, return 0.0.
|
||||
*/
|
||||
double sqlite3VdbeRealValue(Mem *pMem){
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
if( pMem->flags & MEM_Real ){
|
||||
return pMem->r;
|
||||
}else if( pMem->flags & MEM_Int ){
|
||||
@ -330,8 +339,8 @@ double sqlite3VdbeRealValue(Mem *pMem){
|
||||
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
|
||||
double val = 0.0;
|
||||
pMem->flags |= MEM_Str;
|
||||
if( sqlite3VdbeChangeEncoding(0, pMem, SQLITE_UTF8)
|
||||
|| sqlite3VdbeMemNulTerminate(0, pMem) ){
|
||||
if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
|
||||
|| sqlite3VdbeMemNulTerminate(pMem) ){
|
||||
return 0.0;
|
||||
}
|
||||
assert( pMem->z );
|
||||
@ -348,6 +357,7 @@ double sqlite3VdbeRealValue(Mem *pMem){
|
||||
*/
|
||||
void sqlite3VdbeIntegerAffinity(Mem *pMem){
|
||||
assert( pMem->flags & MEM_Real );
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
pMem->u.i = pMem->r;
|
||||
if( ((double)pMem->u.i)==pMem->r ){
|
||||
pMem->flags |= MEM_Int;
|
||||
@ -358,6 +368,7 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){
|
||||
** Convert pMem to type integer. Invalidate any prior representations.
|
||||
*/
|
||||
int sqlite3VdbeMemIntegerify(Mem *pMem){
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
pMem->u.i = sqlite3VdbeIntValue(pMem);
|
||||
sqlite3VdbeMemRelease(pMem);
|
||||
pMem->flags = MEM_Int;
|
||||
@ -369,6 +380,7 @@ int sqlite3VdbeMemIntegerify(Mem *pMem){
|
||||
** Invalidate any prior representations.
|
||||
*/
|
||||
int sqlite3VdbeMemRealify(Mem *pMem){
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
pMem->r = sqlite3VdbeRealValue(pMem);
|
||||
sqlite3VdbeMemRelease(pMem);
|
||||
pMem->flags = MEM_Real;
|
||||
@ -384,6 +396,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){
|
||||
i64 i;
|
||||
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 );
|
||||
assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
r1 = sqlite3VdbeRealValue(pMem);
|
||||
i = (i64)r1;
|
||||
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
|
||||
** freed before the copy is made.
|
||||
*/
|
||||
int sqlite3VdbeMemCopy(sqlite3 *db, Mem *pTo, const Mem *pFrom){
|
||||
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
|
||||
int rc;
|
||||
if( pTo->flags & MEM_Dyn ){
|
||||
sqlite3VdbeMemRelease(pTo);
|
||||
}
|
||||
sqlite3VdbeMemShallowCopy(pTo, pFrom, MEM_Ephem);
|
||||
if( pTo->flags & MEM_Ephem ){
|
||||
rc = sqlite3VdbeMemMakeWriteable(db, pTo);
|
||||
rc = sqlite3VdbeMemMakeWriteable(pTo);
|
||||
}else{
|
||||
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
|
||||
** to allocate enough space to make a copy.
|
||||
*/
|
||||
int sqlite3VdbeMemMove(sqlite3 *db, Mem *pTo, Mem *pFrom){
|
||||
int sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
|
||||
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 ){
|
||||
sqlite3VdbeMemRelease(pTo);
|
||||
}
|
||||
@ -517,7 +533,7 @@ int sqlite3VdbeMemMove(sqlite3 *db, Mem *pTo, Mem *pFrom){
|
||||
pFrom->flags = MEM_Null;
|
||||
pFrom->xDel = 0;
|
||||
if( pTo->flags & MEM_Ephem ){
|
||||
rc = sqlite3VdbeMemMakeWriteable(db, pTo);
|
||||
rc = sqlite3VdbeMemMakeWriteable(pTo);
|
||||
}else{
|
||||
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.
|
||||
*/
|
||||
int sqlite3VdbeMemSetStr(
|
||||
sqlite3 *db,
|
||||
Mem *pMem, /* Memory cell to set to string value */
|
||||
const char *z, /* String pointer */
|
||||
int n, /* Bytes in string, or negative */
|
||||
u8 enc, /* Encoding of z. 0 for BLOBs */
|
||||
void (*xDel)(void*) /* Destructor function */
|
||||
){
|
||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||
sqlite3VdbeMemRelease(pMem);
|
||||
if( !z ){
|
||||
pMem->flags = MEM_Null;
|
||||
pMem->type = SQLITE_NULL;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
pMem->z = (char *)z;
|
||||
if( xDel==SQLITE_STATIC ){
|
||||
pMem->flags = MEM_Static;
|
||||
@ -580,13 +595,13 @@ int sqlite3VdbeMemSetStr(
|
||||
pMem->n = sqlite3Utf16ByteLen(pMem->z,-1);
|
||||
pMem->flags |= MEM_Term;
|
||||
}
|
||||
if( sqlite3VdbeMemHandleBom(db, pMem) ){
|
||||
if( sqlite3VdbeMemHandleBom(pMem) ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_UTF16 */
|
||||
}
|
||||
if( pMem->flags&MEM_Ephem ){
|
||||
return sqlite3VdbeMemMakeWriteable(db, pMem);
|
||||
return sqlite3VdbeMemMakeWriteable(pMem);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@ -686,17 +701,17 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
|
||||
int n1, n2;
|
||||
/* Convert the strings into the encoding that the comparison
|
||||
** function expects */
|
||||
v1 = sqlite3ValueText(0, (sqlite3_value*)pMem1, pColl->enc);
|
||||
v1 = sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc);
|
||||
n1 = v1==0 ? 0 : pMem1->n;
|
||||
assert( n1==sqlite3ValueBytes(0, (sqlite3_value*)pMem1, pColl->enc) );
|
||||
v2 = sqlite3ValueText(0, (sqlite3_value*)pMem2, pColl->enc);
|
||||
assert( n1==sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc) );
|
||||
v2 = sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc);
|
||||
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 */
|
||||
rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
|
||||
/* Convert the strings back into the database encoding */
|
||||
sqlite3ValueText(0, (sqlite3_value*)pMem1, origEnc);
|
||||
sqlite3ValueText(0, (sqlite3_value*)pMem2, origEnc);
|
||||
sqlite3ValueText((sqlite3_value*)pMem1, origEnc);
|
||||
sqlite3ValueText((sqlite3_value*)pMem2, origEnc);
|
||||
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.
|
||||
*/
|
||||
int sqlite3VdbeMemFromBtree(
|
||||
sqlite3 *db, /* Database connect to report malloc errors to */
|
||||
BtCursor *pCur, /* Cursor pointing at record to retrieve. */
|
||||
int offset, /* Offset from the start of data to return bytes from. */
|
||||
int amt, /* Number of bytes to return. */
|
||||
@ -735,7 +749,10 @@ int sqlite3VdbeMemFromBtree(
|
||||
){
|
||||
char *zData; /* Data from the btree layer */
|
||||
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 ){
|
||||
zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
|
||||
}else{
|
||||
@ -743,6 +760,7 @@ int sqlite3VdbeMemFromBtree(
|
||||
}
|
||||
assert( zData!=0 );
|
||||
|
||||
pMem->db = db;
|
||||
pMem->n = amt;
|
||||
if( offset+amt<=available ){
|
||||
pMem->z = &zData[offset];
|
||||
@ -750,9 +768,8 @@ int sqlite3VdbeMemFromBtree(
|
||||
}else{
|
||||
int rc;
|
||||
if( amt>NBFS-2 ){
|
||||
zData = (char *)sqlite3_malloc(amt+2);
|
||||
zData = (char *)sqlite3DbMallocRaw(db, amt+2);
|
||||
if( !zData ){
|
||||
db->mallocFailed = 1;
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
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
|
||||
** boundary.
|
||||
*/
|
||||
const void *sqlite3ValueText(sqlite3 *db, sqlite3_value* pVal, u8 enc){
|
||||
const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
|
||||
if( !pVal ) return 0;
|
||||
|
||||
assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
|
||||
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
|
||||
|
||||
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 );
|
||||
pVal->flags |= (pVal->flags & MEM_Blob)>>3;
|
||||
expandBlob(db, pVal);
|
||||
expandBlob(pVal);
|
||||
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) ){
|
||||
assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
|
||||
if( sqlite3VdbeMemMakeWriteable(db, pVal)!=SQLITE_OK ){
|
||||
if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeMemNulTerminate(db, pVal);
|
||||
sqlite3VdbeMemNulTerminate(pVal);
|
||||
}else{
|
||||
assert( (pVal->flags&MEM_Blob)==0 );
|
||||
sqlite3VdbeMemStringify(db, pVal, enc);
|
||||
sqlite3VdbeMemStringify(pVal, enc);
|
||||
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) ){
|
||||
return pVal->z;
|
||||
}else{
|
||||
@ -887,6 +907,7 @@ sqlite3_value *sqlite3ValueNew(sqlite3 *db){
|
||||
if( p ){
|
||||
p->flags = MEM_Null;
|
||||
p->type = SQLITE_NULL;
|
||||
p->db = db;
|
||||
}else{
|
||||
db->mallocFailed = 1;
|
||||
}
|
||||
@ -904,7 +925,7 @@ sqlite3_value *sqlite3ValueNew(sqlite3 *db){
|
||||
** cannot be converted to a value, then *ppVal is set to NULL.
|
||||
*/
|
||||
int sqlite3ValueFromExpr(
|
||||
sqlite3 *db, /* Report malloc() errors here */
|
||||
sqlite3 *db, /* The database connection */
|
||||
Expr *pExpr, /* The expression to evaluate */
|
||||
u8 enc, /* Encoding to use */
|
||||
u8 affinity, /* Affinity to use */
|
||||
@ -925,14 +946,14 @@ int sqlite3ValueFromExpr(
|
||||
pVal = sqlite3ValueNew(db);
|
||||
if( !zVal || !pVal ) goto no_mem;
|
||||
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 ){
|
||||
sqlite3ValueApplyAffinity(db, pVal, SQLITE_AFF_NUMERIC, enc);
|
||||
sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, enc);
|
||||
}else{
|
||||
sqlite3ValueApplyAffinity(db, pVal, affinity, enc);
|
||||
sqlite3ValueApplyAffinity(pVal, affinity, enc);
|
||||
}
|
||||
}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) ){
|
||||
pVal->u.i = -1 * pVal->u.i;
|
||||
pVal->r = -1.0 * pVal->r;
|
||||
}
|
||||
@ -945,8 +966,7 @@ int sqlite3ValueFromExpr(
|
||||
if( !zVal || !pVal ) goto no_mem;
|
||||
sqlite3Dequote(zVal);
|
||||
nVal = strlen(zVal)/2;
|
||||
sqlite3VdbeMemSetStr(
|
||||
db, pVal, sqlite3HexToBlob(db, zVal), nVal, 0, sqlite3_free);
|
||||
sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal), nVal,0,sqlite3_free);
|
||||
sqlite3_free(zVal);
|
||||
}
|
||||
#endif
|
||||
@ -966,14 +986,13 @@ no_mem:
|
||||
** Change the string value of an sqlite3_value object
|
||||
*/
|
||||
void sqlite3ValueSetStr(
|
||||
sqlite3 *db, /* Report malloc errors here */
|
||||
sqlite3_value *v, /* Value to be set */
|
||||
int n, /* Length of string z */
|
||||
const void *z, /* Text of the new string */
|
||||
u8 enc, /* Encoding to use */
|
||||
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){
|
||||
if( !v ) return;
|
||||
sqlite3ValueSetStr(0, v, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
|
||||
sqlite3ValueSetStr(v, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
|
||||
sqlite3_free(v);
|
||||
}
|
||||
|
||||
@ -989,9 +1008,9 @@ void sqlite3ValueFree(sqlite3_value *v){
|
||||
** Return the number of bytes in the sqlite3_value object assuming
|
||||
** 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;
|
||||
if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(db, pVal, enc) ){
|
||||
if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
|
||||
if( p->flags & MEM_Zero ){
|
||||
return p->n+p->u.i;
|
||||
}else{
|
||||
|
Loading…
Reference in New Issue
Block a user