mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Changes to the Mem structure to reduce the frequency of freeing and reallocating the dynamic buffer. (CVS 4928)
FossilOrigin-Name: d0bf73d81453da1d8e602e0445064d9f5e348063
This commit is contained in:
30
manifest
30
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Patch\sto\sthe\snew\smemory\stracing\slogic\sthat\sallows\sit\sto\sbuild\seven\sif\nmemory\sdebugging\sis\sturned\soff.\s(CVS\s4927)
|
C Changes\sto\sthe\sMem\sstructure\sto\sreduce\sthe\sfrequency\sof\sfreeing\sand\sreallocating\sthe\sdynamic\sbuffer.\s(CVS\s4928)
|
||||||
D 2008-03-28T12:53:38
|
D 2008-03-28T15:44:10
|
||||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||||
F Makefile.in cf434ce8ca902e69126ae0f94fc9f7dc7428a5fa
|
F Makefile.in cf434ce8ca902e69126ae0f94fc9f7dc7428a5fa
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -161,7 +161,7 @@ F src/test_devsym.c cee1aecaa90c895030399ca4ae38f84a08038f8a
|
|||||||
F src/test_func.c 9e9b33ff083b65da91c389cece903bc32de06f01
|
F src/test_func.c 9e9b33ff083b65da91c389cece903bc32de06f01
|
||||||
F src/test_hexio.c 1a1cd8324d57585ea86b922f609fa1fbaaf9662d
|
F src/test_hexio.c 1a1cd8324d57585ea86b922f609fa1fbaaf9662d
|
||||||
F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
|
F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
|
||||||
F src/test_malloc.c 3be391afbfccaeaeba8a5fdb349348d2740cc9cc
|
F src/test_malloc.c c92a65e8f9b31bb2b332448d92d2016c000a963d
|
||||||
F src/test_md5.c bca40b727c57462ddb415e57c5323445a1bb1a40
|
F src/test_md5.c bca40b727c57462ddb415e57c5323445a1bb1a40
|
||||||
F src/test_onefile.c 2fea6d22f13f5f286356c80c77ffd41f995f2b7a
|
F src/test_onefile.c 2fea6d22f13f5f286356c80c77ffd41f995f2b7a
|
||||||
F src/test_schema.c 12c9de7661d6294eec2d57afbb52e2af1128084f
|
F src/test_schema.c 12c9de7661d6294eec2d57afbb52e2af1128084f
|
||||||
@@ -171,17 +171,17 @@ F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
|
|||||||
F src/tokenize.c 13113f94bd1c15dea9e922f08b10f3eee6863474
|
F src/tokenize.c 13113f94bd1c15dea9e922f08b10f3eee6863474
|
||||||
F src/trigger.c 9bd3b6fa0beff4a02d262c96466f752ec15a7fc3
|
F src/trigger.c 9bd3b6fa0beff4a02d262c96466f752ec15a7fc3
|
||||||
F src/update.c 2aefd3c9277792e9fa2414dfe14202119fa49fe7
|
F src/update.c 2aefd3c9277792e9fa2414dfe14202119fa49fe7
|
||||||
F src/utf.c 32b00d6e19010025e58f2ecb2f921d5e126771b4
|
F src/utf.c 8c94fa10efc78c2568d08d436acc59df4df7191b
|
||||||
F src/util.c dba9e04121eb17ec4643d6ca231ff859452cf0e2
|
F src/util.c dba9e04121eb17ec4643d6ca231ff859452cf0e2
|
||||||
F src/vacuum.c 3524411bfb58aac0d87eadd3e5b7cd532772af30
|
F src/vacuum.c 3524411bfb58aac0d87eadd3e5b7cd532772af30
|
||||||
F src/vdbe.c ecad5d197fe9a0f91c348fd3e776fc149aec1ae7
|
F src/vdbe.c a1413f2dd70718cbea922ae58828426504b1184a
|
||||||
F src/vdbe.h f72201a0657d5f3d6cc008d1f8d9cc65768518c9
|
F src/vdbe.h f72201a0657d5f3d6cc008d1f8d9cc65768518c9
|
||||||
F src/vdbeInt.h 73a3162979585cc15d02e47cec2a1033df768246
|
F src/vdbeInt.h 0b96efdeecb0803e504bf1c16b198f87c91d6019
|
||||||
F src/vdbeapi.c f74189e4cae0d93b2744386b9ac57f5ab60c5133
|
F src/vdbeapi.c e03b846adf7fb938b3945019dc6c4c49ed86bb0e
|
||||||
F src/vdbeaux.c bb810c1c5450bd7887a39d5eb44f5902e01416f8
|
F src/vdbeaux.c 519ec819a8e549d087899f0c9a912afcdda762b4
|
||||||
F src/vdbeblob.c cc713c142c3d4952b380c98ee035f850830ddbdb
|
F src/vdbeblob.c cc713c142c3d4952b380c98ee035f850830ddbdb
|
||||||
F src/vdbefifo.c a30c237b2a3577e1415fb6e288cbb6b8ed1e5736
|
F src/vdbefifo.c a30c237b2a3577e1415fb6e288cbb6b8ed1e5736
|
||||||
F src/vdbemem.c d48a71d66a7afd564b6537ab7e7442f7729fa5af
|
F src/vdbemem.c 004c5e1eb8336b22b9abfc535976026ef324ab71
|
||||||
F src/vtab.c 00cd16317b29495c185ff40e4b227917d5a371b2
|
F src/vtab.c 00cd16317b29495c185ff40e4b227917d5a371b2
|
||||||
F src/where.c 7aeeec6731dc2f423e6a77ff2964bc3c38985625
|
F src/where.c 7aeeec6731dc2f423e6a77ff2964bc3c38985625
|
||||||
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
|
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
|
||||||
@@ -411,7 +411,7 @@ F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
|
|||||||
F test/printf.test c3405535b418d454e8a52196a0fc592ec9eec58d
|
F test/printf.test c3405535b418d454e8a52196a0fc592ec9eec58d
|
||||||
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x
|
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x
|
||||||
F test/ptrchng.test 83150cb7b513e33cce90fdc68f4b1817551857c0
|
F test/ptrchng.test 83150cb7b513e33cce90fdc68f4b1817551857c0
|
||||||
F test/quick.test 164584ef7c350b6c439d29f248fc582d5262e71c
|
F test/quick.test 1ab788b4ad66cc385d06d2dd1f0714ccfb52fb61
|
||||||
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
|
||||||
F test/rdonly.test b34db316525440d3b42c32e83942c02c37d28ef0
|
F test/rdonly.test b34db316525440d3b42c32e83942c02c37d28ef0
|
||||||
F test/reindex.test 38b138abe36bf9a08c791ed44d9f76cd6b97b78b
|
F test/reindex.test 38b138abe36bf9a08c791ed44d9f76cd6b97b78b
|
||||||
@@ -453,7 +453,7 @@ F test/table.test 13b1c2e2fb4727b35ee1fb7641fc469214fd2455
|
|||||||
F test/tableapi.test 791f7e3891d9b70bdb43b311694bf5e9befcbc34
|
F test/tableapi.test 791f7e3891d9b70bdb43b311694bf5e9befcbc34
|
||||||
F test/tclsqlite.test 3fac87cb1059c46b8fa8a60b553f4f1adb0fb6d9
|
F test/tclsqlite.test 3fac87cb1059c46b8fa8a60b553f4f1adb0fb6d9
|
||||||
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
|
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
|
||||||
F test/tester.tcl d967b34306776a7488c3cbaf22cc4410c144ccce
|
F test/tester.tcl bf793fcea043ba3c0c081224bdb808efccbc8fb3
|
||||||
F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7
|
F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7
|
||||||
F test/thread002.test 2c4ad2c386f60f6fe268cd91c769ee35b3c1fd0b
|
F test/thread002.test 2c4ad2c386f60f6fe268cd91c769ee35b3c1fd0b
|
||||||
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
|
F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
|
||||||
@@ -619,7 +619,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||||
P f1b97ed93183378ff56b4fe7ae8ea269c24092fc
|
P 0a9c63b227b9c6d2bd0e7b491245947ffc83c828
|
||||||
R f8436b96b881dc0b3a43307cb3273c3d
|
R 4bbd70b6d864c91be4417b22dd9d1d4c
|
||||||
U drh
|
U danielk1977
|
||||||
Z bd7953b885d6238223aab5e76018f9c2
|
Z 85774c3fc13d70f3eca1b91a57f3702c
|
||||||
|
@@ -1 +1 @@
|
|||||||
0a9c63b227b9c6d2bd0e7b491245947ffc83c828
|
d0bf73d81453da1d8e602e0445064d9f5e348063
|
@@ -13,7 +13,7 @@
|
|||||||
** This file contains code used to implement test interfaces to the
|
** This file contains code used to implement test interfaces to the
|
||||||
** memory allocation subsystem.
|
** memory allocation subsystem.
|
||||||
**
|
**
|
||||||
** $Id: test_malloc.c,v 1.21 2008/03/28 12:53:38 drh Exp $
|
** $Id: test_malloc.c,v 1.22 2008/03/28 15:44:10 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@@ -546,7 +546,7 @@ static void test_memdebug_callback(int nByte, int nFrame, void **aFrame){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int test_memdebug_log_clear(){
|
static void test_memdebug_log_clear(){
|
||||||
Tcl_HashSearch search;
|
Tcl_HashSearch search;
|
||||||
Tcl_HashEntry *pEntry;
|
Tcl_HashEntry *pEntry;
|
||||||
for(
|
for(
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
** This file contains routines used to translate between UTF-8,
|
** This file contains routines used to translate between UTF-8,
|
||||||
** UTF-16, UTF-16BE, and UTF-16LE.
|
** UTF-16, UTF-16BE, and UTF-16LE.
|
||||||
**
|
**
|
||||||
** $Id: utf.c,v 1.60 2008/02/13 18:25:27 danielk1977 Exp $
|
** $Id: utf.c,v 1.61 2008/03/28 15:44:10 danielk1977 Exp $
|
||||||
**
|
**
|
||||||
** Notes on UTF-8:
|
** Notes on UTF-8:
|
||||||
**
|
**
|
||||||
@@ -306,6 +306,7 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
|
|||||||
pMem->enc = desiredEnc;
|
pMem->enc = desiredEnc;
|
||||||
pMem->flags |= (MEM_Term|MEM_Dyn);
|
pMem->flags |= (MEM_Term|MEM_Dyn);
|
||||||
pMem->z = (char*)zOut;
|
pMem->z = (char*)zOut;
|
||||||
|
pMem->zMalloc = pMem->z;
|
||||||
|
|
||||||
translate_out:
|
translate_out:
|
||||||
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
|
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
|
||||||
|
35
src/vdbe.c
35
src/vdbe.c
@@ -43,7 +43,7 @@
|
|||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** commenting and indentation practices when changing or adding code.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.720 2008/03/27 22:42:52 drh Exp $
|
** $Id: vdbe.c,v 1.721 2008/03/28 15:44:10 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -235,6 +235,7 @@ static Cursor *allocateCursor(
|
|||||||
*/
|
*/
|
||||||
Mem *pMem = &p->aMem[p->nMem-iCur];
|
Mem *pMem = &p->aMem[p->nMem-iCur];
|
||||||
|
|
||||||
|
int nByte;
|
||||||
Cursor *pCx = 0;
|
Cursor *pCx = 0;
|
||||||
/* If the opcode of pOp is OP_SetNumColumns, then pOp->p2 contains
|
/* If the opcode of pOp is OP_SetNumColumns, then pOp->p2 contains
|
||||||
** the number of fields in the records contained in the table or
|
** the number of fields in the records contained in the table or
|
||||||
@@ -245,9 +246,7 @@ static Cursor *allocateCursor(
|
|||||||
if( pOp->opcode==OP_SetNumColumns || pOp->opcode==OP_OpenEphemeral ){
|
if( pOp->opcode==OP_SetNumColumns || pOp->opcode==OP_OpenEphemeral ){
|
||||||
nField = pOp->p2;
|
nField = pOp->p2;
|
||||||
}
|
}
|
||||||
|
nByte =
|
||||||
|
|
||||||
int nByte =
|
|
||||||
sizeof(Cursor) +
|
sizeof(Cursor) +
|
||||||
(isBtreeCursor?sqlite3BtreeCursorSize():0) +
|
(isBtreeCursor?sqlite3BtreeCursorSize():0) +
|
||||||
2*nField*sizeof(u32);
|
2*nField*sizeof(u32);
|
||||||
@@ -668,7 +667,7 @@ int sqlite3VdbeExec(
|
|||||||
assert( pOp->p2>0 );
|
assert( pOp->p2>0 );
|
||||||
assert( pOp->p2<=p->nMem );
|
assert( pOp->p2<=p->nMem );
|
||||||
pOut = &p->aMem[pOp->p2];
|
pOut = &p->aMem[pOp->p2];
|
||||||
sqlite3VdbeMemRelease(pOut);
|
sqlite3VdbeMemReleaseExternal(pOut);
|
||||||
pOut->flags = MEM_Null;
|
pOut->flags = MEM_Null;
|
||||||
}else
|
}else
|
||||||
|
|
||||||
@@ -880,7 +879,7 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */
|
|||||||
sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
|
sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
|
||||||
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
|
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
|
||||||
if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pOut) ) goto no_mem;
|
if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pOut) ) goto no_mem;
|
||||||
pOut->flags &= ~(MEM_Dyn);
|
pOut->zMalloc = 0;
|
||||||
pOut->flags |= MEM_Static;
|
pOut->flags |= MEM_Static;
|
||||||
if( pOp->p4type==P4_DYNAMIC ){
|
if( pOp->p4type==P4_DYNAMIC ){
|
||||||
sqlite3_free(pOp->p4.z);
|
sqlite3_free(pOp->p4.z);
|
||||||
@@ -1003,7 +1002,10 @@ case OP_SCopy: {
|
|||||||
pOut = &p->aMem[pOp->p2];
|
pOut = &p->aMem[pOp->p2];
|
||||||
assert( pOut!=pIn1 );
|
assert( pOut!=pIn1 );
|
||||||
if( pOp->opcode==OP_Move ){
|
if( pOp->opcode==OP_Move ){
|
||||||
|
char *zMalloc = pOut->zMalloc;
|
||||||
|
pOut->zMalloc = 0;
|
||||||
sqlite3VdbeMemMove(pOut, pIn1);
|
sqlite3VdbeMemMove(pOut, pIn1);
|
||||||
|
pIn1->zMalloc = zMalloc;
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
|
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
|
||||||
if( pOp->opcode==OP_Copy ){
|
if( pOp->opcode==OP_Copy ){
|
||||||
@@ -1269,6 +1271,8 @@ case OP_Function: {
|
|||||||
pOut = &p->aMem[pOp->p3];
|
pOut = &p->aMem[pOp->p3];
|
||||||
ctx.s.flags = MEM_Null;
|
ctx.s.flags = MEM_Null;
|
||||||
ctx.s.db = db;
|
ctx.s.db = db;
|
||||||
|
ctx.s.xDel = 0;
|
||||||
|
ctx.s.zMalloc = 0;
|
||||||
|
|
||||||
/* The output cell may already have a buffer allocated. Move
|
/* The output cell may already have a buffer allocated. Move
|
||||||
** the pointer to ctx.s so in case the user-function can use
|
** the pointer to ctx.s so in case the user-function can use
|
||||||
@@ -1884,6 +1888,7 @@ case OP_Column: {
|
|||||||
|
|
||||||
sMem.flags = 0;
|
sMem.flags = 0;
|
||||||
sMem.db = 0;
|
sMem.db = 0;
|
||||||
|
sMem.zMalloc = 0;
|
||||||
assert( p1<p->nCursor );
|
assert( p1<p->nCursor );
|
||||||
assert( pOp->p3>0 && pOp->p3<=p->nMem );
|
assert( pOp->p3>0 && pOp->p3<=p->nMem );
|
||||||
pDest = &p->aMem[pOp->p3];
|
pDest = &p->aMem[pOp->p3];
|
||||||
@@ -2029,7 +2034,7 @@ case OP_Column: {
|
|||||||
aOffset[i] = 0;
|
aOffset[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Release(&sMem);
|
sqlite3VdbeMemRelease(&sMem);
|
||||||
sMem.flags = MEM_Null;
|
sMem.flags = MEM_Null;
|
||||||
|
|
||||||
/* If we have read more header data than was contained in the header,
|
/* If we have read more header data than was contained in the header,
|
||||||
@@ -2054,8 +2059,11 @@ case OP_Column: {
|
|||||||
if( pDest->flags&MEM_Dyn ){
|
if( pDest->flags&MEM_Dyn ){
|
||||||
sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], &sMem);
|
sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], &sMem);
|
||||||
sMem.db = db;
|
sMem.db = db;
|
||||||
sqlite3VdbeMemCopy(pDest, &sMem);
|
rc = sqlite3VdbeMemCopy(pDest, &sMem);
|
||||||
assert( !(sMem.flags&MEM_Dyn) );
|
assert( !(sMem.flags&MEM_Dyn) );
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
goto op_column_out;
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest);
|
sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest);
|
||||||
}
|
}
|
||||||
@@ -2083,13 +2091,14 @@ case OP_Column: {
|
|||||||
** dynamically allocated space over to the pDest structure.
|
** dynamically allocated space over to the pDest structure.
|
||||||
** This prevents a memory copy.
|
** This prevents a memory copy.
|
||||||
*/
|
*/
|
||||||
if( (sMem.flags & MEM_Dyn)!=0 ){
|
if( sMem.zMalloc ){
|
||||||
assert( !sMem.xDel );
|
assert( sMem.z==sMem.zMalloc );
|
||||||
assert( !(pDest->flags & MEM_Dyn) );
|
assert( !(pDest->flags & MEM_Dyn) );
|
||||||
assert( !(pDest->flags & (MEM_Blob|MEM_Str)) || pDest->z==sMem.z );
|
assert( !(pDest->flags & (MEM_Blob|MEM_Str)) || pDest->z==sMem.z );
|
||||||
pDest->flags &= ~(MEM_Ephem|MEM_Static);
|
pDest->flags &= ~(MEM_Ephem|MEM_Static);
|
||||||
pDest->flags |= MEM_Dyn|MEM_Term;
|
pDest->flags |= MEM_Term;
|
||||||
pDest->z = sMem.z;
|
pDest->z = sMem.z;
|
||||||
|
pDest->zMalloc = sMem.zMalloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = sqlite3VdbeMemMakeWriteable(pDest);
|
rc = sqlite3VdbeMemMakeWriteable(pDest);
|
||||||
@@ -3295,11 +3304,12 @@ case OP_Insert: {
|
|||||||
}
|
}
|
||||||
pC->iKey = iKey;
|
pC->iKey = iKey;
|
||||||
pC->nData = pData->n;
|
pC->nData = pData->n;
|
||||||
if( pData->flags & MEM_Dyn ){
|
if( pData->z==pData->zMalloc || pC->ephemPseudoTable ){
|
||||||
pC->pData = pData->z;
|
pC->pData = pData->z;
|
||||||
if( !pC->ephemPseudoTable ){
|
if( !pC->ephemPseudoTable ){
|
||||||
pData->flags &= ~MEM_Dyn;
|
pData->flags &= ~MEM_Dyn;
|
||||||
pData->flags |= MEM_Ephem;
|
pData->flags |= MEM_Ephem;
|
||||||
|
pData->zMalloc = 0;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
pC->pData = sqlite3_malloc( pC->nData+2 );
|
pC->pData = sqlite3_malloc( pC->nData+2 );
|
||||||
@@ -4262,6 +4272,7 @@ case OP_AggStep: {
|
|||||||
pMem->n++;
|
pMem->n++;
|
||||||
ctx.s.flags = MEM_Null;
|
ctx.s.flags = MEM_Null;
|
||||||
ctx.s.z = 0;
|
ctx.s.z = 0;
|
||||||
|
ctx.s.zMalloc = 0;
|
||||||
ctx.s.xDel = 0;
|
ctx.s.xDel = 0;
|
||||||
ctx.s.db = db;
|
ctx.s.db = db;
|
||||||
ctx.isError = 0;
|
ctx.isError = 0;
|
||||||
|
@@ -124,6 +124,7 @@ struct Mem {
|
|||||||
u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
|
u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
|
||||||
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
|
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
|
||||||
void (*xDel)(void *); /* If not null, call this function to delete Mem.z */
|
void (*xDel)(void *); /* If not null, call this function to delete Mem.z */
|
||||||
|
char *zMalloc; /* Dynamic buffer allocated by sqlite3_malloc() */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* One or more of the following flags are set to indicate the validOK
|
/* One or more of the following flags are set to indicate the validOK
|
||||||
@@ -415,6 +416,7 @@ int sqlite3VdbeMemRealify(Mem*);
|
|||||||
int sqlite3VdbeMemNumerify(Mem*);
|
int sqlite3VdbeMemNumerify(Mem*);
|
||||||
int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
|
int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
|
||||||
void sqlite3VdbeMemRelease(Mem *p);
|
void sqlite3VdbeMemRelease(Mem *p);
|
||||||
|
void sqlite3VdbeMemReleaseExternal(Mem *p);
|
||||||
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
|
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
|
||||||
const char *sqlite3OpcodeName(int);
|
const char *sqlite3OpcodeName(int);
|
||||||
int sqlite3VdbeOpcodeHasProperty(int, int);
|
int sqlite3VdbeOpcodeHasProperty(int, int);
|
||||||
|
@@ -614,13 +614,16 @@ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
|
|||||||
pMem = p->pMem;
|
pMem = p->pMem;
|
||||||
if( (pMem->flags & MEM_Agg)==0 ){
|
if( (pMem->flags & MEM_Agg)==0 ){
|
||||||
if( nByte==0 ){
|
if( nByte==0 ){
|
||||||
assert( pMem->flags==MEM_Null );
|
sqlite3VdbeMemReleaseExternal(pMem);
|
||||||
|
pMem->flags = MEM_Null;
|
||||||
pMem->z = 0;
|
pMem->z = 0;
|
||||||
}else{
|
}else{
|
||||||
|
sqlite3VdbeMemGrow(pMem, nByte, 0);
|
||||||
pMem->flags = MEM_Agg;
|
pMem->flags = MEM_Agg;
|
||||||
pMem->xDel = sqlite3_free;
|
|
||||||
pMem->u.pDef = p->pFunc;
|
pMem->u.pDef = p->pFunc;
|
||||||
pMem->z = sqlite3DbMallocZero(p->s.db, nByte);
|
if( pMem->z ){
|
||||||
|
memset(pMem->z, 0, nByte);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (void*)pMem->z;
|
return (void*)pMem->z;
|
||||||
|
@@ -743,10 +743,12 @@ static void releaseMemArray(Mem *p, int N, int freebuffers){
|
|||||||
int malloc_failed = db->mallocFailed;
|
int malloc_failed = db->mallocFailed;
|
||||||
while( N-->0 ){
|
while( N-->0 ){
|
||||||
assert( N<2 || p[0].db==p[1].db );
|
assert( N<2 || p[0].db==p[1].db );
|
||||||
if( freebuffers || p->xDel ){
|
if( freebuffers ){
|
||||||
sqlite3VdbeMemRelease(p);
|
sqlite3VdbeMemRelease(p);
|
||||||
p->flags = MEM_Null;
|
}else{
|
||||||
|
sqlite3VdbeMemReleaseExternal(p);
|
||||||
}
|
}
|
||||||
|
p->flags = MEM_Null;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
db->mallocFailed = malloc_failed;
|
db->mallocFailed = malloc_failed;
|
||||||
@@ -1030,7 +1032,6 @@ void sqlite3VdbeMakeReady(
|
|||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
for(n=1; n<p->nMem; n++){
|
for(n=1; n<p->nMem; n++){
|
||||||
assert( p->aMem[n].db==db );
|
assert( p->aMem[n].db==db );
|
||||||
//assert( p->aMem[n].flags==MEM_Null );
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1182,8 +1183,8 @@ int sqlite3VdbeSetColName(Vdbe *p, int idx, int var, const char *zName, int N){
|
|||||||
rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
|
rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK && N==P4_DYNAMIC ){
|
if( rc==SQLITE_OK && N==P4_DYNAMIC ){
|
||||||
pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn;
|
pColName->flags &= (~MEM_Static);
|
||||||
pColName->xDel = 0;
|
pColName->zMalloc = pColName->z;
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -2220,6 +2221,7 @@ UnpackedRecord *sqlite3VdbeRecordUnpack(
|
|||||||
pMem->enc = pKeyInfo->enc;
|
pMem->enc = pKeyInfo->enc;
|
||||||
pMem->db = pKeyInfo->db;
|
pMem->db = pKeyInfo->db;
|
||||||
pMem->flags = 0;
|
pMem->flags = 0;
|
||||||
|
pMem->zMalloc = 0;
|
||||||
d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
|
d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
|
||||||
pMem++;
|
pMem++;
|
||||||
i++;
|
i++;
|
||||||
@@ -2237,7 +2239,7 @@ void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){
|
|||||||
int i;
|
int i;
|
||||||
Mem *pMem;
|
Mem *pMem;
|
||||||
for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){
|
for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){
|
||||||
if( pMem->flags & MEM_Dyn ){
|
if( pMem->zMalloc ){
|
||||||
sqlite3VdbeMemRelease(pMem);
|
sqlite3VdbeMemRelease(pMem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2285,6 +2287,7 @@ int sqlite3VdbeRecordCompare(
|
|||||||
mem1.enc = pKeyInfo->enc;
|
mem1.enc = pKeyInfo->enc;
|
||||||
mem1.db = pKeyInfo->db;
|
mem1.db = pKeyInfo->db;
|
||||||
mem1.flags = 0;
|
mem1.flags = 0;
|
||||||
|
mem1.zMalloc = 0;
|
||||||
|
|
||||||
idx1 = GetVarint(aKey1, szHdr1);
|
idx1 = GetVarint(aKey1, szHdr1);
|
||||||
d1 = szHdr1;
|
d1 = szHdr1;
|
||||||
@@ -2304,12 +2307,12 @@ int sqlite3VdbeRecordCompare(
|
|||||||
*/
|
*/
|
||||||
rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
|
rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
|
||||||
i<nField ? pKeyInfo->aColl[i] : 0);
|
i<nField ? pKeyInfo->aColl[i] : 0);
|
||||||
if( mem1.flags&MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
|
|
||||||
if( rc!=0 ){
|
if( rc!=0 ){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
if( mem1.zMalloc ) sqlite3VdbeMemRelease(&mem1);
|
||||||
|
|
||||||
/* One of the keys ran out of fields, but all the fields up to that point
|
/* One of the keys ran out of fields, but all the fields up to that point
|
||||||
** were equal. If the incrKey flag is true, then the second key is
|
** were equal. If the incrKey flag is true, then the second key is
|
||||||
@@ -2366,6 +2369,7 @@ int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){
|
|||||||
}
|
}
|
||||||
m.flags = 0;
|
m.flags = 0;
|
||||||
m.db = 0;
|
m.db = 0;
|
||||||
|
m.zMalloc = 0;
|
||||||
rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
|
rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
return rc;
|
return rc;
|
||||||
@@ -2409,6 +2413,7 @@ int sqlite3VdbeIdxKeyCompare(
|
|||||||
}
|
}
|
||||||
m.db = 0;
|
m.db = 0;
|
||||||
m.flags = 0;
|
m.flags = 0;
|
||||||
|
m.zMalloc = 0;
|
||||||
rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
|
rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
return rc;
|
return rc;
|
||||||
|
172
src/vdbemem.c
172
src/vdbemem.c
@@ -73,50 +73,35 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
|
|||||||
** not set, Mem.n is zeroed.
|
** not set, Mem.n is zeroed.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){
|
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){
|
||||||
int f = pMem->flags;
|
assert( 1 >=
|
||||||
|
((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
|
||||||
assert( (f & (MEM_Dyn|MEM_Static|MEM_Ephem))==0
|
(((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) +
|
||||||
|| (f & (MEM_Dyn|MEM_Static|MEM_Ephem))==MEM_Dyn
|
((pMem->flags&MEM_Ephem) ? 1 : 0) +
|
||||||
|| (f & (MEM_Dyn|MEM_Static|MEM_Ephem))==MEM_Ephem
|
((pMem->flags&MEM_Static) ? 1 : 0)
|
||||||
|| (f & (MEM_Dyn|MEM_Static|MEM_Ephem))==MEM_Static
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if( (f&MEM_Dyn)==0 || pMem->xDel || sqlite3MallocSize(pMem->z)<n ){
|
if( sqlite3MallocSize(pMem->zMalloc)<n ){
|
||||||
|
n = (n>32?n:32);
|
||||||
/* Allocate the new buffer. The minimum allocation size is 32 bytes. */
|
if( preserve && pMem->z==pMem->zMalloc ){
|
||||||
char *z = 0;
|
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
|
||||||
if( n>0 ){
|
preserve = 0;
|
||||||
if( preserve && (f&MEM_Dyn) && !pMem->xDel ){
|
}else{
|
||||||
z = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
|
sqlite3_free(pMem->zMalloc);
|
||||||
pMem->z = 0;
|
pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
|
||||||
preserve = 0;
|
|
||||||
}else{
|
|
||||||
z = sqlite3DbMallocRaw(pMem->db, (n>32?n:32));
|
|
||||||
}
|
|
||||||
if( !z ){
|
|
||||||
sqlite3VdbeMemRelease(pMem);
|
|
||||||
pMem->flags = MEM_Null;
|
|
||||||
return SQLITE_NOMEM;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the value is currently a string or blob and the preserve flag
|
|
||||||
** is true, copy the content to the new buffer.
|
|
||||||
*/
|
|
||||||
if( pMem->flags&(MEM_Blob|MEM_Str) && preserve ){
|
|
||||||
int nCopy = (pMem->n>n?n:pMem->n);
|
|
||||||
memcpy(z, pMem->z, nCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Release the old buffer. */
|
|
||||||
sqlite3VdbeMemRelease(pMem);
|
|
||||||
|
|
||||||
pMem->z = z;
|
|
||||||
pMem->flags |= MEM_Dyn;
|
|
||||||
pMem->flags &= ~(MEM_Ephem|MEM_Static);
|
|
||||||
pMem->xDel = 0;
|
|
||||||
}
|
}
|
||||||
return SQLITE_OK;
|
|
||||||
|
if( preserve && pMem->z && pMem->zMalloc && pMem->z!=pMem->zMalloc ){
|
||||||
|
memcpy(pMem->zMalloc, pMem->z, pMem->n);
|
||||||
|
}
|
||||||
|
if( pMem->xDel && pMem->flags&MEM_Dyn){
|
||||||
|
pMem->xDel((void *)(pMem->z));
|
||||||
|
}
|
||||||
|
|
||||||
|
pMem->z = pMem->zMalloc;
|
||||||
|
pMem->flags &= ~(MEM_Ephem|MEM_Static);
|
||||||
|
pMem->xDel = 0;
|
||||||
|
return (pMem->z ? SQLITE_OK : SQLITE_NOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -129,7 +114,7 @@ int sqlite3VdbeMemDynamicify(Mem *pMem){
|
|||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
expandBlob(pMem);
|
expandBlob(pMem);
|
||||||
f = pMem->flags;
|
f = pMem->flags;
|
||||||
if( (f&(MEM_Str|MEM_Blob)) && ((f&MEM_Dyn)==0 || pMem->xDel) ){
|
if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
|
||||||
if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
|
if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
|
||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
@@ -259,41 +244,47 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
|
|||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
ctx.s.flags = MEM_Null;
|
ctx.s.flags = MEM_Null;
|
||||||
ctx.s.db = pMem->db;
|
ctx.s.db = pMem->db;
|
||||||
|
ctx.s.zMalloc = 0;
|
||||||
ctx.pMem = pMem;
|
ctx.pMem = pMem;
|
||||||
ctx.pFunc = pFunc;
|
ctx.pFunc = pFunc;
|
||||||
ctx.isError = 0;
|
ctx.isError = 0;
|
||||||
pFunc->xFinalize(&ctx);
|
pFunc->xFinalize(&ctx);
|
||||||
if( pMem->z ){
|
assert( !pMem->xDel || 0==(pMem->flags&MEM_Dyn) );
|
||||||
sqlite3_free( pMem->z );
|
sqlite3_free(pMem->zMalloc);
|
||||||
}
|
|
||||||
*pMem = ctx.s;
|
*pMem = ctx.s;
|
||||||
rc = (ctx.isError?SQLITE_ERROR:SQLITE_OK);
|
rc = (ctx.isError?SQLITE_ERROR:SQLITE_OK);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** If the memory cell contains a string value that must be freed by
|
||||||
|
** invoking an external callback, free it now. Calling this function
|
||||||
|
** does not free any Mem.zMalloc buffer.
|
||||||
|
*/
|
||||||
|
void sqlite3VdbeMemReleaseExternal(Mem *p){
|
||||||
|
assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
|
||||||
|
if( p->flags&MEM_Agg ){
|
||||||
|
sqlite3VdbeMemFinalize(p, p->u.pDef);
|
||||||
|
assert( (p->flags & MEM_Agg)==0 );
|
||||||
|
sqlite3VdbeMemRelease(p);
|
||||||
|
}else if( p->xDel && p->flags&MEM_Dyn ){
|
||||||
|
p->xDel((void *)p->z);
|
||||||
|
p->xDel = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Release any memory held by the Mem. This may leave the Mem in an
|
** Release any memory held by the Mem. This may leave the Mem in an
|
||||||
** inconsistent state, for example with (Mem.z==0) and
|
** inconsistent state, for example with (Mem.z==0) and
|
||||||
** (Mem.type==SQLITE_TEXT).
|
** (Mem.type==SQLITE_TEXT).
|
||||||
*/
|
*/
|
||||||
void sqlite3VdbeMemRelease(Mem *p){
|
void sqlite3VdbeMemRelease(Mem *p){
|
||||||
assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
|
sqlite3VdbeMemReleaseExternal(p);
|
||||||
if( p->flags & (MEM_Dyn|MEM_Agg) ){
|
sqlite3_free(p->zMalloc);
|
||||||
if( p->xDel ){
|
p->z = 0;
|
||||||
if( p->flags & MEM_Agg ){
|
p->zMalloc = 0;
|
||||||
sqlite3VdbeMemFinalize(p, p->u.pDef);
|
p->xDel = 0;
|
||||||
assert( (p->flags & MEM_Agg)==0 );
|
|
||||||
sqlite3VdbeMemRelease(p);
|
|
||||||
}else{
|
|
||||||
p->xDel((void *)p->z);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
sqlite3_free(p->z);
|
|
||||||
}
|
|
||||||
p->z = 0;
|
|
||||||
p->xDel = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -514,6 +505,8 @@ int sqlite3VdbeMemTooBig(Mem *p){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MEMCELLSIZE (int)(&(((Mem *)0)->zMalloc))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Make an shallow copy of pFrom into pTo. Prior contents of
|
** Make an shallow copy of pFrom into pTo. Prior contents of
|
||||||
** pTo are freed. The pFrom->z field is not duplicated. If
|
** pTo are freed. The pFrom->z field is not duplicated. If
|
||||||
@@ -521,10 +514,10 @@ int sqlite3VdbeMemTooBig(Mem *p){
|
|||||||
** and flags gets srcType (either MEM_Ephem or MEM_Static).
|
** and flags gets srcType (either MEM_Ephem or MEM_Static).
|
||||||
*/
|
*/
|
||||||
void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
|
void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
|
||||||
sqlite3VdbeMemRelease(pTo);
|
sqlite3VdbeMemReleaseExternal(pTo);
|
||||||
memcpy(pTo, pFrom, sizeof(*pFrom));
|
memcpy(pTo, pFrom, MEMCELLSIZE);
|
||||||
pTo->xDel = 0;
|
pTo->xDel = 0;
|
||||||
if( pTo->flags&MEM_Dyn ){
|
if( pFrom->xDel || pFrom->z==pFrom->zMalloc ){
|
||||||
pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
|
pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
|
||||||
assert( srcType==MEM_Ephem || srcType==MEM_Static );
|
assert( srcType==MEM_Ephem || srcType==MEM_Static );
|
||||||
pTo->flags |= srcType;
|
pTo->flags |= srcType;
|
||||||
@@ -537,48 +530,18 @@ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
|
|||||||
*/
|
*/
|
||||||
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
|
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
char *zBuf = 0;
|
|
||||||
|
|
||||||
/* If cell pTo currently has a reusable buffer, save a pointer to it
|
sqlite3VdbeMemReleaseExternal(pTo);
|
||||||
** in local variable zBuf. This function attempts to avoid freeing
|
memcpy(pTo, pFrom, MEMCELLSIZE);
|
||||||
** this buffer.
|
pTo->flags &= ~MEM_Dyn;
|
||||||
*/
|
|
||||||
if( pTo->flags&MEM_Dyn ){
|
if( pTo->flags&(MEM_Str|MEM_Blob) ){
|
||||||
if( pTo->xDel ){
|
if( 0==(pFrom->flags&MEM_Static) ){
|
||||||
sqlite3VdbeMemRelease(pTo);
|
pTo->flags |= MEM_Ephem;
|
||||||
}else{
|
rc = sqlite3VdbeMemMakeWriteable(pTo);
|
||||||
zBuf = pTo->z;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the contents of *pFrom to *pTo */
|
|
||||||
memcpy(pTo, pFrom, sizeof(*pFrom));
|
|
||||||
|
|
||||||
if( pTo->flags&(MEM_Str|MEM_Blob) && pTo->flags&MEM_Static ){
|
|
||||||
/* pFrom contained a pointer to a static string. In this case,
|
|
||||||
** free any dynamically allocated buffer associated with pTo.
|
|
||||||
*/
|
|
||||||
sqlite3_free(zBuf);
|
|
||||||
}else{
|
|
||||||
char *zData = pTo->z;
|
|
||||||
|
|
||||||
pTo->z = zBuf;
|
|
||||||
pTo->flags &= ~(MEM_Static|MEM_Ephem);
|
|
||||||
pTo->flags |= MEM_Dyn;
|
|
||||||
pTo->xDel = 0;
|
|
||||||
|
|
||||||
if( pTo->flags&(MEM_Str|MEM_Blob) ){
|
|
||||||
if( sqlite3VdbeMemGrow(pTo, pTo->n+2, 0) ){
|
|
||||||
pTo->n = 0;
|
|
||||||
rc = SQLITE_NOMEM;
|
|
||||||
}else{
|
|
||||||
memcpy(pTo->z, zData, pTo->n);
|
|
||||||
pTo->z[pTo->n] = '\0';
|
|
||||||
pTo->z[pTo->n+1] = '\0';
|
|
||||||
pTo->flags |= MEM_Term;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,12 +555,12 @@ void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
|
|||||||
assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) );
|
assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) );
|
||||||
assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) );
|
assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) );
|
||||||
assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db );
|
assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db );
|
||||||
if( pTo->flags & MEM_Dyn ){
|
|
||||||
sqlite3VdbeMemRelease(pTo);
|
sqlite3VdbeMemRelease(pTo);
|
||||||
}
|
|
||||||
memcpy(pTo, pFrom, sizeof(Mem));
|
memcpy(pTo, pFrom, sizeof(Mem));
|
||||||
pFrom->flags = MEM_Null;
|
pFrom->flags = MEM_Null;
|
||||||
pFrom->xDel = 0;
|
pFrom->xDel = 0;
|
||||||
|
pFrom->zMalloc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -659,7 +622,6 @@ int sqlite3VdbeMemSetStr(
|
|||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
memcpy(pMem->z, z, nAlloc);
|
memcpy(pMem->z, z, nAlloc);
|
||||||
flags |= MEM_Dyn;
|
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeMemRelease(pMem);
|
sqlite3VdbeMemRelease(pMem);
|
||||||
pMem->z = (char *)z;
|
pMem->z = (char *)z;
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
#***********************************************************************
|
#***********************************************************************
|
||||||
# This file runs all tests.
|
# This file runs all tests.
|
||||||
#
|
#
|
||||||
# $Id: quick.test,v 1.74 2008/03/27 15:07:05 drh Exp $
|
# $Id: quick.test,v 1.75 2008/03/28 15:44:10 danielk1977 Exp $
|
||||||
|
|
||||||
proc lshift {lvar} {
|
proc lshift {lvar} {
|
||||||
upvar $lvar l
|
upvar $lvar l
|
||||||
@@ -22,6 +22,9 @@ while {[set arg [lshift argv]] != ""} {
|
|||||||
-soak {
|
-soak {
|
||||||
set SOAKTEST 1
|
set SOAKTEST 1
|
||||||
}
|
}
|
||||||
|
-start {
|
||||||
|
set STARTAT "[lshift argv]*"
|
||||||
|
}
|
||||||
default {
|
default {
|
||||||
set argv [linsert $argv 0 $arg]
|
set argv [linsert $argv 0 $arg]
|
||||||
break
|
break
|
||||||
@@ -97,6 +100,8 @@ foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
|
|||||||
set tail [file tail $testfile]
|
set tail [file tail $testfile]
|
||||||
if {[lsearch -exact $EXCLUDE $tail]>=0} continue
|
if {[lsearch -exact $EXCLUDE $tail]>=0} continue
|
||||||
if {[llength $INCLUDE]>0 && [lsearch -exact $INCLUDE $tail]<0} continue
|
if {[llength $INCLUDE]>0 && [lsearch -exact $INCLUDE $tail]<0} continue
|
||||||
|
if {[info exists STARTAT] && [string match $STARTAT $tail]} {unset STARTAT}
|
||||||
|
if {[info exists STARTAT]} continue
|
||||||
source $testfile
|
source $testfile
|
||||||
catch {db close}
|
catch {db close}
|
||||||
if {$sqlite_open_file_count>0} {
|
if {$sqlite_open_file_count>0} {
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
# This file implements some common TCL routines used for regression
|
# This file implements some common TCL routines used for regression
|
||||||
# testing the SQLite library
|
# testing the SQLite library
|
||||||
#
|
#
|
||||||
# $Id: tester.tcl,v 1.111 2008/03/28 07:42:54 danielk1977 Exp $
|
# $Id: tester.tcl,v 1.112 2008/03/28 15:44:10 danielk1977 Exp $
|
||||||
|
|
||||||
|
|
||||||
set tcl_precision 15
|
set tcl_precision 15
|
||||||
@@ -47,7 +47,7 @@ sqlite3_soft_heap_limit $soft_limit
|
|||||||
for {set i 0} {$i<[llength $argv]} {incr i} {
|
for {set i 0} {$i<[llength $argv]} {incr i} {
|
||||||
if {[lindex $argv $i] eq "--malloctrace"} {
|
if {[lindex $argv $i] eq "--malloctrace"} {
|
||||||
set argv [lreplace $argv $i $i]
|
set argv [lreplace $argv $i $i]
|
||||||
sqlite3_memdebug_backtrace 5
|
sqlite3_memdebug_backtrace 10
|
||||||
sqlite3_memdebug_log start
|
sqlite3_memdebug_log start
|
||||||
set argv [lreplace $argv $i $i]
|
set argv [lreplace $argv $i $i]
|
||||||
set tester_do_malloctrace 1
|
set tester_do_malloctrace 1
|
||||||
|
Reference in New Issue
Block a user