diff --git a/manifest b/manifest index 5d7e5a1e89..25690ed633 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\son\shomepage.\s(CVS\s1971) -D 2004-09-18T18:51:09 +C Merge\sthe\sListPush\sand\sListPop\sVDBE\sopcodes\sinto\sContextPush\sand\sContextPop.\s(CVS\s1972) +D 2004-09-19T00:50:21 F Makefile.in 76f8790c727cdbe2e1bef19c9c72b6e5da9cb9d8 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -33,7 +33,7 @@ F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029 F src/build.c c5ecf114af4ebc2963a03142b6bd6f2284ee35fc F src/date.c eb8d5fa1a6d5cfc09031c8852d10ff742a94b15b F src/delete.c e887f44aae1e33da1643df58abe86cd9cde45ad1 -F src/expr.c 9130794d8c86af2cbf2b8cdc66f2158167fd15b1 +F src/expr.c a6d95632ef9c6ad18fade504baa6d5a7225c9fee F src/func.c 1fbc5256639586573fd0e70814d6dcd8bc10afc1 F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84 @@ -69,16 +69,16 @@ F src/test3.c 5b5b0f3d11b097399c1054fff73d8f3711092301 F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df F src/test5.c b001fa7f1b9e2dc5c2331de62fc641b5ab2bd7a1 F src/tokenize.c 418ef7ba1149603a30dcf0057e04a3ea0e99edbe -F src/trigger.c 98dd620bebd9f3dadaacf0db3958b916cf1e7b7f +F src/trigger.c b42ae6ca49e3b935c37b6845fd2aadd2cab78c08 F src/update.c 0e00300763d2ce0dbd6a0598882a5039580b225e F src/utf.c 328890099db492dda5620ee5f924e244c6e57ff7 F src/util.c f9b661a3b80a1469777771776a59a5f0e2f193fc F src/vacuum.c 257de36230cb988842f66eb08dc6c0250b8e05f3 -F src/vdbe.c b19de04c57b4136a8e0203d5e3b76dd82bded1b5 +F src/vdbe.c 0542852785220807feb02b9dee1150ac2e592c8d F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181 -F src/vdbeInt.h e09362d6323a725de3c30b0cc381a691e86ed697 +F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b F src/vdbeapi.c c7208bb89fc4efc605e20328099a540175e2dae6 -F src/vdbeaux.c 0fbc50cf7aed1ea30c89839ad316446b839cc645 +F src/vdbeaux.c f312d91a594240831748a8949fdd446a6b2b3bb1 F src/vdbemem.c ef9ac7d32acfe4bce5c5b408b1294c8d9e0cdb56 F src/where.c 12e214870c84546858ddb9f121165a1fbfce6811 F test/all.test 929bfa932b55e75c96fe2203f7650ba451c1862c @@ -247,7 +247,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P d82ded9543fdd77f3613bac5e263f658dc3fd236 -R 99f6922d720aa23ffd86176b779c91ec +P 5d3b3a96bcc459a797bd723025f2d38efcfeb6fa +R 391c503e9b746bc6f666f540b502155a U drh -Z 8cc29533278c45147fd52457996f6601 +Z c87ee13fbd413eb4f4e5b30f3144edca diff --git a/manifest.uuid b/manifest.uuid index 7eec1714f2..453d17d957 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d3b3a96bcc459a797bd723025f2d38efcfeb6fa \ No newline at end of file +eb9b501ad8b0fa0fd63a67ece05fe142d6a19114 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 86cb54ad39..2e3e611006 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.161 2004/09/07 16:19:53 drh Exp $ +** $Id: expr.c,v 1.162 2004/09/19 00:50:21 drh Exp $ */ #include "sqliteInt.h" #include @@ -1480,6 +1480,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeDequoteP3(v, -1); } else { assert( pExpr->iColumn == OE_Ignore ); + sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0); sqlite3VdbeOp3(v, OP_Goto, 0, pParse->trigStack->ignoreJump, "(IGNORE jump)", 0); } diff --git a/src/trigger.c b/src/trigger.c index c387d03133..3e601346aa 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -645,7 +645,11 @@ static int codeTriggerProgram( ){ TriggerStep * pTriggerStep = pStepList; int orconf; + Vdbe *v = pParse->pVdbe; + assert( pTriggerStep!=0 ); + assert( v!=0 ); + sqlite3VdbeAddOp(v, OP_ContextPush, 0, 0); while( pTriggerStep ){ orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin; pParse->trigStack->orconf = orconf; @@ -661,34 +665,30 @@ static int codeTriggerProgram( case TK_UPDATE: { SrcList *pSrc; pSrc = targetSrcList(pParse, pTriggerStep); - sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 0, 0); - sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0); + sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0); sqlite3Update(pParse, pSrc, sqlite3ExprListDup(pTriggerStep->pExprList), sqlite3ExprDup(pTriggerStep->pWhere), orconf); - sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0); - sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 1, 0); + sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0); break; } case TK_INSERT: { SrcList *pSrc; pSrc = targetSrcList(pParse, pTriggerStep); - sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 0, 0); + sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0); sqlite3Insert(pParse, pSrc, sqlite3ExprListDup(pTriggerStep->pExprList), sqlite3SelectDup(pTriggerStep->pSelect), sqlite3IdListDup(pTriggerStep->pIdList), orconf); - sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 1, 0); + sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0); break; } case TK_DELETE: { SrcList *pSrc; - sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 0, 0); - sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0); + sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0); pSrc = targetSrcList(pParse, pTriggerStep); sqlite3DeleteFrom(pParse, pSrc, sqlite3ExprDup(pTriggerStep->pWhere)); - sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0); - sqlite3VdbeAddOp(pParse->pVdbe, OP_ResetCount, 1, 0); + sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0); break; } default: @@ -696,6 +696,7 @@ static int codeTriggerProgram( } pTriggerStep = pTriggerStep->pNext; } + sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0); return 0; } @@ -790,9 +791,7 @@ int sqlite3CodeRowTrigger( sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1); sqlite3ExprDelete(whenExpr); - sqlite3VdbeAddOp(pParse->pVdbe, OP_ContextPush, 0, 0); codeTriggerProgram(pParse, pTrigger->step_list, orconf); - sqlite3VdbeAddOp(pParse->pVdbe, OP_ContextPop, 0, 0); /* Pop the entry off the trigger stack */ pParse->trigStack = pParse->trigStack->pNext; diff --git a/src/vdbe.c b/src/vdbe.c index d4920a8a27..5ec829464f 100644 --- a/src/vdbe.c +++ b/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.414 2004/09/06 17:24:13 drh Exp $ +** $Id: vdbe.c,v 1.415 2004/09/19 00:50:21 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -3072,7 +3072,7 @@ case OP_Delete: { */ case OP_ResetCount: { if( pOp->p1 ){ - sqlite3VdbeSetChanges(p->db, p->nChange); + sqlite3VdbeSetChanges(db, p->nChange); } p->nChange = 0; break; @@ -3894,43 +3894,6 @@ case OP_ListReset: { break; } -/* Opcode: ListPush * * * -** -** Save the current Vdbe list such that it can be restored by a ListPop -** opcode. The list is empty after this is executed. -*/ -case OP_ListPush: { - p->keylistStackDepth++; - assert(p->keylistStackDepth > 0); - - /* FIX ME: This should be allocated at compile time. */ - p->keylistStack = sqliteRealloc(p->keylistStack, - sizeof(Keylist *) * p->keylistStackDepth); - if( p->keylistStack==0 ) goto no_mem; - - p->keylistStack[p->keylistStackDepth - 1] = p->pList; - p->pList = 0; - break; -} - -/* Opcode: ListPop * * * -** -** Restore the Vdbe list to the state it was in when ListPush was last -** executed. -*/ -case OP_ListPop: { - assert(p->keylistStackDepth > 0); - p->keylistStackDepth--; - sqlite3VdbeKeylistFree(p->pList); - p->pList = p->keylistStack[p->keylistStackDepth]; - p->keylistStack[p->keylistStackDepth] = 0; - if( p->keylistStackDepth == 0 ){ - sqliteFree(p->keylistStack); - p->keylistStack = 0; - } - break; -} - /* Opcode: ContextPush * * * ** ** Save the current Vdbe context such that it can be restored by a ContextPop @@ -3938,16 +3901,21 @@ case OP_ListPop: { ** count, and the current statement change count. */ case OP_ContextPush: { - p->contextStackDepth++; - assert( p->contextStackDepth>0 ); + int i = p->contextStackTop++; + Context *pContext; + assert( i>=0 ); /* FIX ME: This should be allocated as part of the vdbe at compile-time */ - p->contextStack = sqliteRealloc(p->contextStack, - sizeof(Context) * p->contextStackDepth); - if( p->contextStack==0 ) goto no_mem; - - p->contextStack[p->contextStackDepth - 1].lastRowid = p->db->lastRowid; - p->contextStack[p->contextStackDepth - 1].nChange = p->nChange; + if( i>=p->contextStackDepth ){ + p->contextStackDepth = i+1; + p->contextStack = sqliteRealloc(p->contextStack, sizeof(Context)*(i+1)); + if( p->contextStack==0 ) goto no_mem; + } + pContext = &p->contextStack[i]; + pContext->lastRowid = db->lastRowid; + pContext->nChange = p->nChange; + pContext->pList = p->pList; + p->pList = 0; break; } @@ -3958,14 +3926,12 @@ case OP_ContextPush: { ** change count, and the current statement change count. */ case OP_ContextPop: { - assert(p->contextStackDepth > 0); - p->contextStackDepth--; - p->db->lastRowid = p->contextStack[p->contextStackDepth].lastRowid; - p->nChange = p->contextStack[p->contextStackDepth].nChange; - if( p->contextStackDepth == 0 ){ - sqliteFree(p->contextStack); - p->contextStack = 0; - } + Context *pContext = &p->contextStack[--p->contextStackTop]; + assert( p->contextStackTop>=0 ); + db->lastRowid = pContext->lastRowid; + p->nChange = pContext->nChange; + sqlite3VdbeKeylistFree(p->pList); + p->pList = pContext->pList; break; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index ba6b591600..a929cb95e1 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -278,13 +278,17 @@ struct Keylist { /* ** A Context stores the last insert rowid, the last statement change count, ** and the current statement change count (i.e. changes since last statement). +** The current keylist is also stored in the context. ** Elements of Context structure type make up the ContextStack, which is -** updated by the ContextPush and ContextPop opcodes (used by triggers) +** updated by the ContextPush and ContextPop opcodes (used by triggers). +** The context is pushed before executing a trigger a popped when the +** trigger finishes. */ typedef struct Context Context; struct Context { int lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ int nChange; /* Statement changes (Vdbe.nChanges) */ + Keylist *pList; /* Records that will participate in a DELETE or UPDATE */ }; /* @@ -321,8 +325,7 @@ struct Vdbe { Agg agg; /* Aggregate information */ int nCallback; /* Number of callbacks invoked so far */ Keylist *pList; /* A list of ROWIDs */ - int keylistStackDepth; /* The size of the "keylist" stack */ - Keylist **keylistStack; /* The stack used by opcodes ListPush & ListPop */ + int contextStackTop; /* Index of top element in the context stack */ int contextStackDepth; /* The size of the "context" stack */ Context *contextStack; /* Stack used by opcodes ContextPush & ContextPop*/ int pc; /* The program counter */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index c04c966c36..64dddeb56b 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -846,19 +846,15 @@ static void Cleanup(Vdbe *p){ sqlite3VdbeKeylistFree(p->pList); p->pList = 0; } + for(i=0; icontextStackTop; i++){ + sqlite3VdbeKeylistFree(p->contextStack[i].pList); + } sqlite3VdbeSorterReset(p); sqlite3VdbeAggReset(0, &p->agg, 0); - if( p->keylistStack ){ - int ii; - for(ii = 0; ii < p->keylistStackDepth; ii++){ - sqlite3VdbeKeylistFree(p->keylistStack[ii]); - } - sqliteFree(p->keylistStack); - p->keylistStackDepth = 0; - p->keylistStack = 0; - } sqliteFree(p->contextStack); p->contextStack = 0; + p->contextStackDepth = 0; + p->contextStackTop = 0; sqliteFree(p->zErrMsg); p->zErrMsg = 0; }