Refactor the Vdbe.iVdbeMagic field into Vdbe.eVdbeState. Split the RUNNING
state into separate RUNNING and READY. This gives a size reduction and performance increase. FossilOrigin-Name: 5a50a42fde9477868fad31099f5fe976437825fac44f8b3a4cf6c739c7667bbb
This commit is contained in:
commit
17c4865b83
19
manifest
19
manifest
@ -1,5 +1,5 @@
|
||||
C Avoid\sa\sharmless\suninitialized\svariable\swarning\sin\sPRAGMA\sincremental_vacuum.
|
||||
D 2022-04-01T16:22:41.680
|
||||
C Refactor\sthe\sVdbe.iVdbeMagic\sfield\sinto\sVdbe.eVdbeState.\s\sSplit\sthe\sRUNNING\nstate\sinto\sseparate\sRUNNING\sand\sREADY.\s\sThis\sgives\sa\ssize\sreduction\sand\nperformance\sincrease.
|
||||
D 2022-04-01T17:01:57.201
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -624,11 +624,11 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
|
||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||
F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23
|
||||
F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3
|
||||
F src/vdbe.c 0245de62bdf0fb22605b8d093738890b3fa788604ee37b6cde3c36312c982dd5
|
||||
F src/vdbe.c aa8751fbca2aae36ea0a4753636d4e257363a39c67af6b52ebdaecea83de2859
|
||||
F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e
|
||||
F src/vdbeInt.h 75421e3c0f139b008c95f1e9c36815aa40f4d07d2bdd1e0499c2c5a1bcf43fd3
|
||||
F src/vdbeapi.c fe789d29ce9edab0f5413836ab535d4a1518aca3a6a75e2f8ff6cd1af8092384
|
||||
F src/vdbeaux.c 45a94316496a200a1d3a29b014fbbc7fc44860c026f768b2d0fcc108e92536d4
|
||||
F src/vdbeInt.h a2f535ae607e441104d22617a30cb6290264fa1820702a7956a10c6f795b1344
|
||||
F src/vdbeapi.c 17474f2122c1f54c93dcdb7b845e68e207bbebab6a040c65ed374c4aec049d34
|
||||
F src/vdbeaux.c 12fd47127081042706c318590f4dbc90233e22ca12742462f85703f4f4fc6658
|
||||
F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd
|
||||
F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206
|
||||
F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35
|
||||
@ -1945,8 +1945,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P d4e19314f564126e180e091f9135c7bc55a10442edb46fbd3a4cfad21201dfa6
|
||||
R 0ec367734a93a75663b3abea5e03bf19
|
||||
P 6d976f90dfe4886c3f4c062151af5c5ca7454d34b71172401b8c67acd2d663a0 d698826b08b88e227eb83f84b3cdb19f17306b532eccfa162090abccdf3c63d8
|
||||
R 97a4d2d9fb07a14d2a76d85d2d1743dd
|
||||
T +closed d698826b08b88e227eb83f84b3cdb19f17306b532eccfa162090abccdf3c63d8
|
||||
U drh
|
||||
Z 9dcfea7aa3dabdeb03cfb5d58440b56a
|
||||
Z b98f2a477a3e4e8aef60cc1790477902
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
6d976f90dfe4886c3f4c062151af5c5ca7454d34b71172401b8c67acd2d663a0
|
||||
5a50a42fde9477868fad31099f5fe976437825fac44f8b3a4cf6c739c7667bbb
|
@ -740,7 +740,7 @@ int sqlite3VdbeExec(
|
||||
#endif
|
||||
/*** INSERT STACK UNION HERE ***/
|
||||
|
||||
assert( p->iVdbeMagic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
|
||||
assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */
|
||||
sqlite3VdbeEnter(p);
|
||||
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
|
||||
if( db->xProgress ){
|
||||
|
@ -418,7 +418,6 @@ struct Vdbe {
|
||||
Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
|
||||
Parse *pParse; /* Parsing context used to create this Vdbe */
|
||||
ynVar nVar; /* Number of entries in aVar[] */
|
||||
u32 iVdbeMagic; /* Magic number defining state of the SQL statement */
|
||||
int nMem; /* Number of memory locations currently allocated */
|
||||
int nCursor; /* Number of slots in apCsr[] */
|
||||
u32 cacheCtr; /* VdbeCursor row cache generation counter */
|
||||
@ -457,6 +456,7 @@ struct Vdbe {
|
||||
u8 minWriteFileFormat; /* Minimum file format for writable database files */
|
||||
u8 prepFlags; /* SQLITE_PREPARE_* flags */
|
||||
u8 doingRerun; /* True if rerunning after an auto-reprepare */
|
||||
u8 eVdbeState; /* On of the VDBE_*_STATE values */
|
||||
bft expired:2; /* 1: recompile VM immediately 2: when convenient */
|
||||
bft explain:2; /* True if EXPLAIN present on SQL command */
|
||||
bft changeCntOn:1; /* True to update the change-counter */
|
||||
@ -487,13 +487,12 @@ struct Vdbe {
|
||||
};
|
||||
|
||||
/*
|
||||
** The following are allowed values for Vdbe.magic
|
||||
** The following are allowed values for Vdbe.eVdbeState
|
||||
*/
|
||||
#define VDBE_MAGIC_INIT 0x16bceaa5 /* Building a VDBE program */
|
||||
#define VDBE_MAGIC_RUN 0x2df20da3 /* VDBE is ready to execute */
|
||||
#define VDBE_MAGIC_HALT 0x319c2973 /* VDBE has completed execution */
|
||||
#define VDBE_MAGIC_RESET 0x48fa9f76 /* Reset and ready to run again */
|
||||
#define VDBE_MAGIC_DEAD 0x5606c3c8 /* The VDBE has been deallocated */
|
||||
#define VDBE_INIT_STATE 0 /* Prepared statement under construction */
|
||||
#define VDBE_READY_STATE 1 /* Ready to run but not yet started */
|
||||
#define VDBE_RUN_STATE 2 /* Run in progress */
|
||||
#define VDBE_HALT_STATE 3 /* Finished. Need reset() or finalize() */
|
||||
|
||||
/*
|
||||
** Structure used to store the context required by the
|
||||
|
137
src/vdbeapi.c
137
src/vdbeapi.c
@ -642,35 +642,6 @@ static int sqlite3Step(Vdbe *p){
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
|
||||
assert(p);
|
||||
if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){
|
||||
/* We used to require that sqlite3_reset() be called before retrying
|
||||
** sqlite3_step() after any error or after SQLITE_DONE. But beginning
|
||||
** with version 3.7.0, we changed this so that sqlite3_reset() would
|
||||
** be called automatically instead of throwing the SQLITE_MISUSE error.
|
||||
** This "automatic-reset" change is not technically an incompatibility,
|
||||
** since any application that receives an SQLITE_MISUSE is broken by
|
||||
** definition.
|
||||
**
|
||||
** Nevertheless, some published applications that were originally written
|
||||
** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE
|
||||
** returns, and those were broken by the automatic-reset change. As a
|
||||
** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
|
||||
** legacy behavior of returning SQLITE_MISUSE for cases where the
|
||||
** previous sqlite3_step() returned something other than a SQLITE_LOCKED
|
||||
** or SQLITE_BUSY error.
|
||||
*/
|
||||
#ifdef SQLITE_OMIT_AUTORESET
|
||||
if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){
|
||||
sqlite3_reset((sqlite3_stmt*)p);
|
||||
}else{
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#else
|
||||
sqlite3_reset((sqlite3_stmt*)p);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Check that malloc() has not failed. If it has, return early. */
|
||||
db = p->db;
|
||||
if( db->mallocFailed ){
|
||||
@ -678,45 +649,83 @@ static int sqlite3Step(Vdbe *p){
|
||||
return SQLITE_NOMEM_BKPT;
|
||||
}
|
||||
|
||||
if( p->pc<0 && p->expired ){
|
||||
p->rc = SQLITE_SCHEMA;
|
||||
rc = SQLITE_ERROR;
|
||||
if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){
|
||||
/* If this statement was prepared using saved SQL and an
|
||||
** error has occurred, then return the error code in p->rc to the
|
||||
** caller. Set the error code in the database handle to the same value.
|
||||
*/
|
||||
rc = sqlite3VdbeTransferError(p);
|
||||
}
|
||||
goto end_of_step;
|
||||
}
|
||||
if( p->pc<0 ){
|
||||
/* If there are no other statements currently running, then
|
||||
** reset the interrupt flag. This prevents a call to sqlite3_interrupt
|
||||
** from interrupting a statement that has not yet started.
|
||||
*/
|
||||
if( db->nVdbeActive==0 ){
|
||||
AtomicStore(&db->u1.isInterrupted, 0);
|
||||
}
|
||||
assert(p);
|
||||
if( p->eVdbeState!=VDBE_RUN_STATE ){
|
||||
restart_step:
|
||||
if( p->eVdbeState==VDBE_READY_STATE ){
|
||||
if( p->expired ){
|
||||
p->rc = SQLITE_SCHEMA;
|
||||
rc = SQLITE_ERROR;
|
||||
if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){
|
||||
/* If this statement was prepared using saved SQL and an
|
||||
** error has occurred, then return the error code in p->rc to the
|
||||
** caller. Set the error code in the database handle to the same
|
||||
** value.
|
||||
*/
|
||||
rc = sqlite3VdbeTransferError(p);
|
||||
}
|
||||
goto end_of_step;
|
||||
}
|
||||
|
||||
assert( db->nVdbeWrite>0 || db->autoCommit==0
|
||||
|| (db->nDeferredCons==0 && db->nDeferredImmCons==0)
|
||||
);
|
||||
/* If there are no other statements currently running, then
|
||||
** reset the interrupt flag. This prevents a call to sqlite3_interrupt
|
||||
** from interrupting a statement that has not yet started.
|
||||
*/
|
||||
if( db->nVdbeActive==0 ){
|
||||
AtomicStore(&db->u1.isInterrupted, 0);
|
||||
}
|
||||
|
||||
assert( db->nVdbeWrite>0 || db->autoCommit==0
|
||||
|| (db->nDeferredCons==0 && db->nDeferredImmCons==0)
|
||||
);
|
||||
|
||||
#ifndef SQLITE_OMIT_TRACE
|
||||
if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0
|
||||
&& !db->init.busy && p->zSql ){
|
||||
sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
|
||||
}else{
|
||||
assert( p->startTime==0 );
|
||||
}
|
||||
if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0
|
||||
&& !db->init.busy && p->zSql ){
|
||||
sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
|
||||
}else{
|
||||
assert( p->startTime==0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
db->nVdbeActive++;
|
||||
if( p->readOnly==0 ) db->nVdbeWrite++;
|
||||
if( p->bIsReader ) db->nVdbeRead++;
|
||||
p->pc = 0;
|
||||
db->nVdbeActive++;
|
||||
if( p->readOnly==0 ) db->nVdbeWrite++;
|
||||
if( p->bIsReader ) db->nVdbeRead++;
|
||||
p->pc = 0;
|
||||
p->eVdbeState = VDBE_RUN_STATE;
|
||||
}else
|
||||
|
||||
if( ALWAYS(p->eVdbeState==VDBE_HALT_STATE) ){
|
||||
/* We used to require that sqlite3_reset() be called before retrying
|
||||
** sqlite3_step() after any error or after SQLITE_DONE. But beginning
|
||||
** with version 3.7.0, we changed this so that sqlite3_reset() would
|
||||
** be called automatically instead of throwing the SQLITE_MISUSE error.
|
||||
** This "automatic-reset" change is not technically an incompatibility,
|
||||
** since any application that receives an SQLITE_MISUSE is broken by
|
||||
** definition.
|
||||
**
|
||||
** Nevertheless, some published applications that were originally written
|
||||
** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE
|
||||
** returns, and those were broken by the automatic-reset change. As a
|
||||
** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
|
||||
** legacy behavior of returning SQLITE_MISUSE for cases where the
|
||||
** previous sqlite3_step() returned something other than a SQLITE_LOCKED
|
||||
** or SQLITE_BUSY error.
|
||||
*/
|
||||
#ifdef SQLITE_OMIT_AUTORESET
|
||||
if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){
|
||||
sqlite3_reset((sqlite3_stmt*)p);
|
||||
}else{
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
#else
|
||||
sqlite3_reset((sqlite3_stmt*)p);
|
||||
#endif
|
||||
assert( p->eVdbeState==VDBE_READY_STATE );
|
||||
goto restart_step;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
p->rcApp = SQLITE_OK;
|
||||
#endif
|
||||
@ -1428,7 +1437,7 @@ static int vdbeUnbind(Vdbe *p, int i){
|
||||
return SQLITE_MISUSE_BKPT;
|
||||
}
|
||||
sqlite3_mutex_enter(p->db->mutex);
|
||||
if( p->iVdbeMagic!=VDBE_MAGIC_RUN || p->pc>=0 ){
|
||||
if( p->eVdbeState!=VDBE_READY_STATE ){
|
||||
sqlite3Error(p->db, SQLITE_MISUSE);
|
||||
sqlite3_mutex_leave(p->db->mutex);
|
||||
sqlite3_log(SQLITE_MISUSE,
|
||||
@ -1781,7 +1790,7 @@ int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){
|
||||
*/
|
||||
int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
|
||||
Vdbe *v = (Vdbe*)pStmt;
|
||||
return v!=0 && v->iVdbeMagic==VDBE_MAGIC_RUN && v->pc>=0;
|
||||
return v!=0 && v->eVdbeState==VDBE_RUN_STATE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -35,7 +35,7 @@ Vdbe *sqlite3VdbeCreate(Parse *pParse){
|
||||
p->pNext = db->pVdbe;
|
||||
p->pPrev = 0;
|
||||
db->pVdbe = p;
|
||||
p->iVdbeMagic = VDBE_MAGIC_INIT;
|
||||
assert( p->eVdbeState==VDBE_INIT_STATE );
|
||||
p->pParse = pParse;
|
||||
pParse->pVdbe = p;
|
||||
assert( pParse->aLabel==0 );
|
||||
@ -236,7 +236,7 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
|
||||
VdbeOp *pOp;
|
||||
|
||||
i = p->nOp;
|
||||
assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
|
||||
assert( p->eVdbeState==VDBE_INIT_STATE );
|
||||
assert( op>=0 && op<0xff );
|
||||
if( p->nOpAlloc<=i ){
|
||||
return growOp3(p, op, p1, p2, p3);
|
||||
@ -568,7 +568,7 @@ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){
|
||||
void sqlite3VdbeResolveLabel(Vdbe *v, int x){
|
||||
Parse *p = v->pParse;
|
||||
int j = ADDR(x);
|
||||
assert( v->iVdbeMagic==VDBE_MAGIC_INIT );
|
||||
assert( v->eVdbeState==VDBE_INIT_STATE );
|
||||
assert( j<-p->nLabel );
|
||||
assert( j>=0 );
|
||||
#ifdef SQLITE_DEBUG
|
||||
@ -878,7 +878,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
|
||||
** Return the address of the next instruction to be inserted.
|
||||
*/
|
||||
int sqlite3VdbeCurrentAddr(Vdbe *p){
|
||||
assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
|
||||
assert( p->eVdbeState==VDBE_INIT_STATE );
|
||||
return p->nOp;
|
||||
}
|
||||
|
||||
@ -963,7 +963,7 @@ VdbeOp *sqlite3VdbeAddOpList(
|
||||
int i;
|
||||
VdbeOp *pOut, *pFirst;
|
||||
assert( nOp>0 );
|
||||
assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
|
||||
assert( p->eVdbeState==VDBE_INIT_STATE );
|
||||
if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){
|
||||
return 0;
|
||||
}
|
||||
@ -1289,7 +1289,7 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
|
||||
sqlite3 *db;
|
||||
assert( p!=0 );
|
||||
db = p->db;
|
||||
assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
|
||||
assert( p->eVdbeState==VDBE_INIT_STATE );
|
||||
assert( p->aOp!=0 || db->mallocFailed );
|
||||
if( db->mallocFailed ){
|
||||
if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4);
|
||||
@ -1417,7 +1417,7 @@ VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
|
||||
/* C89 specifies that the constant "dummy" will be initialized to all
|
||||
** zeros, which is correct. MSVC generates a warning, nevertheless. */
|
||||
static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */
|
||||
assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
|
||||
assert( p->eVdbeState==VDBE_INIT_STATE );
|
||||
if( addr<0 ){
|
||||
addr = p->nOp - 1;
|
||||
}
|
||||
@ -2119,7 +2119,7 @@ int sqlite3VdbeList(
|
||||
Op *pOp; /* Current opcode */
|
||||
|
||||
assert( p->explain );
|
||||
assert( p->iVdbeMagic==VDBE_MAGIC_RUN );
|
||||
assert( p->eVdbeState==VDBE_RUN_STATE );
|
||||
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
|
||||
|
||||
/* Even though this opcode does not use dynamic strings for
|
||||
@ -2299,14 +2299,15 @@ void sqlite3VdbeRewind(Vdbe *p){
|
||||
int i;
|
||||
#endif
|
||||
assert( p!=0 );
|
||||
assert( p->iVdbeMagic==VDBE_MAGIC_INIT || p->iVdbeMagic==VDBE_MAGIC_RESET );
|
||||
assert( p->eVdbeState==VDBE_INIT_STATE
|
||||
|| p->eVdbeState==VDBE_READY_STATE
|
||||
|| p->eVdbeState==VDBE_HALT_STATE );
|
||||
|
||||
/* There should be at least one opcode.
|
||||
*/
|
||||
assert( p->nOp>0 );
|
||||
|
||||
/* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
|
||||
p->iVdbeMagic = VDBE_MAGIC_RUN;
|
||||
p->eVdbeState = VDBE_READY_STATE;
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
for(i=0; i<p->nMem; i++){
|
||||
@ -2362,7 +2363,7 @@ void sqlite3VdbeMakeReady(
|
||||
assert( p!=0 );
|
||||
assert( p->nOp>0 );
|
||||
assert( pParse!=0 );
|
||||
assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
|
||||
assert( p->eVdbeState==VDBE_INIT_STATE );
|
||||
assert( pParse==p->pParse );
|
||||
p->pVList = pParse->pVList;
|
||||
pParse->pVList = 0;
|
||||
@ -2503,14 +2504,12 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
|
||||
** Close all cursors in the current frame.
|
||||
*/
|
||||
static void closeCursorsInFrame(Vdbe *p){
|
||||
if( p->apCsr ){
|
||||
int i;
|
||||
for(i=0; i<p->nCursor; i++){
|
||||
VdbeCursor *pC = p->apCsr[i];
|
||||
if( pC ){
|
||||
sqlite3VdbeFreeCursor(p, pC);
|
||||
p->apCsr[i] = 0;
|
||||
}
|
||||
int i;
|
||||
for(i=0; i<p->nCursor; i++){
|
||||
VdbeCursor *pC = p->apCsr[i];
|
||||
if( pC ){
|
||||
sqlite3VdbeFreeCursor(p, pC);
|
||||
p->apCsr[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2559,9 +2558,7 @@ static void closeAllCursors(Vdbe *p){
|
||||
}
|
||||
assert( p->nFrame==0 );
|
||||
closeCursorsInFrame(p);
|
||||
if( p->aMem ){
|
||||
releaseMemArray(p->aMem, p->nMem);
|
||||
}
|
||||
releaseMemArray(p->aMem, p->nMem);
|
||||
while( p->pDelFrame ){
|
||||
VdbeFrame *pDel = p->pDelFrame;
|
||||
p->pDelFrame = pDel->pParent;
|
||||
@ -3041,7 +3038,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
** one, or the complete transaction if there is no statement transaction.
|
||||
*/
|
||||
|
||||
if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){
|
||||
if( p->eVdbeState!=VDBE_RUN_STATE ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
if( db->mallocFailed ){
|
||||
@ -3052,7 +3049,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
|
||||
/* No commit or rollback needed if the program never started or if the
|
||||
** SQL statement does not read or write a database file. */
|
||||
if( p->pc>=0 && p->bIsReader ){
|
||||
if( p->bIsReader ){
|
||||
int mrc; /* Primary error code from p->rc */
|
||||
int eStatementOp = 0;
|
||||
int isSpecialError; /* Set to true if a 'special' error */
|
||||
@ -3200,15 +3197,13 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
}
|
||||
|
||||
/* We have successfully halted and closed the VM. Record this fact. */
|
||||
if( p->pc>=0 ){
|
||||
db->nVdbeActive--;
|
||||
if( !p->readOnly ) db->nVdbeWrite--;
|
||||
if( p->bIsReader ) db->nVdbeRead--;
|
||||
assert( db->nVdbeActive>=db->nVdbeRead );
|
||||
assert( db->nVdbeRead>=db->nVdbeWrite );
|
||||
assert( db->nVdbeWrite>=0 );
|
||||
}
|
||||
p->iVdbeMagic = VDBE_MAGIC_HALT;
|
||||
db->nVdbeActive--;
|
||||
if( !p->readOnly ) db->nVdbeWrite--;
|
||||
if( p->bIsReader ) db->nVdbeRead--;
|
||||
assert( db->nVdbeActive>=db->nVdbeRead );
|
||||
assert( db->nVdbeRead>=db->nVdbeWrite );
|
||||
assert( db->nVdbeWrite>=0 );
|
||||
p->eVdbeState = VDBE_HALT_STATE;
|
||||
checkActiveVdbeCnt(db);
|
||||
if( db->mallocFailed ){
|
||||
p->rc = SQLITE_NOMEM_BKPT;
|
||||
@ -3290,8 +3285,8 @@ static void vdbeInvokeSqllog(Vdbe *v){
|
||||
** again.
|
||||
**
|
||||
** To look at it another way, this routine resets the state of the
|
||||
** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
|
||||
** VDBE_MAGIC_INIT.
|
||||
** virtual machine from VDBE_RUN_STATE or VDBE_HALT_STATE back to
|
||||
** VDBE_READY_STATE.
|
||||
*/
|
||||
int sqlite3VdbeReset(Vdbe *p){
|
||||
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
|
||||
@ -3382,7 +3377,6 @@ int sqlite3VdbeReset(Vdbe *p){
|
||||
}
|
||||
}
|
||||
#endif
|
||||
p->iVdbeMagic = VDBE_MAGIC_RESET;
|
||||
return p->rc & db->errMask;
|
||||
}
|
||||
|
||||
@ -3392,7 +3386,10 @@ int sqlite3VdbeReset(Vdbe *p){
|
||||
*/
|
||||
int sqlite3VdbeFinalize(Vdbe *p){
|
||||
int rc = SQLITE_OK;
|
||||
if( p->iVdbeMagic==VDBE_MAGIC_RUN || p->iVdbeMagic==VDBE_MAGIC_HALT ){
|
||||
assert( VDBE_RUN_STATE>VDBE_READY_STATE );
|
||||
assert( VDBE_HALT_STATE>VDBE_READY_STATE );
|
||||
assert( VDBE_INIT_STATE<VDBE_READY_STATE );
|
||||
if( p->eVdbeState>=VDBE_READY_STATE ){
|
||||
rc = sqlite3VdbeReset(p);
|
||||
assert( (rc & p->db->errMask)==rc );
|
||||
}
|
||||
@ -3456,7 +3453,7 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
|
||||
vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
|
||||
sqlite3DbFree(db, pSub);
|
||||
}
|
||||
if( p->iVdbeMagic!=VDBE_MAGIC_INIT ){
|
||||
if( p->eVdbeState!=VDBE_INIT_STATE ){
|
||||
releaseMemArray(p->aVar, p->nVar);
|
||||
if( p->pVList ) sqlite3DbFreeNN(db, p->pVList);
|
||||
if( p->pFree ) sqlite3DbFreeNN(db, p->pFree);
|
||||
@ -3503,8 +3500,6 @@ void sqlite3VdbeDelete(Vdbe *p){
|
||||
if( p->pNext ){
|
||||
p->pNext->pPrev = p->pPrev;
|
||||
}
|
||||
p->iVdbeMagic = VDBE_MAGIC_DEAD;
|
||||
p->db = 0;
|
||||
sqlite3DbFreeNN(db, p);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user