diff options
author | drh <drh@noemail.net> | 2008-01-05 04:06:03 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2008-01-05 04:06:03 +0000 |
commit | b1fdb2adea877989a87abb4e7426a34254e43b6c (patch) | |
tree | d83d76b1424e3f9f14762ed988348d95315d25cd /src | |
parent | 4c583128bd7c86d535a81af38665866213020164 (diff) | |
download | sqlite-b1fdb2adea877989a87abb4e7426a34254e43b6c.tar.gz sqlite-b1fdb2adea877989a87abb4e7426a34254e43b6c.zip |
Get rid of OP_Dup, OP_MemStore, OP_MemLoad, and OP_MemMove. Replace
with OP_Copy, OP_SCopy, and OP_Move. Add the infrastructure for
operation properties in1, in2, in3, out2, and out3 but do not yet
use any of these. (CVS 4682)
FossilOrigin-Name: cc149eb9ca3c672cc6fea3528353234ac2ed5745
Diffstat (limited to 'src')
-rw-r--r-- | src/analyze.c | 19 | ||||
-rw-r--r-- | src/build.c | 10 | ||||
-rw-r--r-- | src/delete.c | 12 | ||||
-rw-r--r-- | src/expr.c | 33 | ||||
-rw-r--r-- | src/insert.c | 53 | ||||
-rw-r--r-- | src/pragma.c | 10 | ||||
-rw-r--r-- | src/select.c | 28 | ||||
-rw-r--r-- | src/trigger.c | 8 | ||||
-rw-r--r-- | src/update.c | 4 | ||||
-rw-r--r-- | src/vdbe.c | 219 | ||||
-rw-r--r-- | src/where.c | 24 |
11 files changed, 240 insertions, 180 deletions
diff --git a/src/analyze.c b/src/analyze.c index 845f3080e..c44e30060 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code associated with the ANALYZE command. ** -** @(#) $Id: analyze.c,v 1.31 2008/01/04 22:01:03 drh Exp $ +** @(#) $Id: analyze.c,v 1.32 2008/01/05 04:06:04 drh Exp $ */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" @@ -158,15 +158,14 @@ static void analyzeOneTable( sqlite3VdbeAddOp2(v, OP_MemIncr, 1, iMem); for(i=0; i<nCol; i++){ sqlite3VdbeAddOp2(v, OP_Column, iIdxCur, i); - sqlite3VdbeAddOp1(v, OP_MemLoad, iMem+nCol+i+1); + sqlite3VdbeAddOp1(v, OP_SCopy, iMem+nCol+i+1); sqlite3VdbeAddOp1(v, OP_Ne, 0x100); } sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop); for(i=0; i<nCol; i++){ addr = sqlite3VdbeAddOp2(v, OP_MemIncr, 1, iMem+i+1); sqlite3VdbeChangeP2(v, topOfLoop + 3*i + 3, addr); - sqlite3VdbeAddOp2(v, OP_Column, iIdxCur, i); - sqlite3VdbeAddOp2(v, OP_MemStore, iMem+nCol+i+1, 1); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1); } sqlite3VdbeResolveLabel(v, endOfLoop); sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop); @@ -190,25 +189,25 @@ static void analyzeOneTable( ** If K>0 then it is always the case the D>0 so division by zero ** is never possible. */ - sqlite3VdbeAddOp1(v, OP_MemLoad, iMem); + sqlite3VdbeAddOp1(v, OP_SCopy, iMem); addr = sqlite3VdbeAddOp0(v, OP_IfNot); sqlite3VdbeAddOp1(v, OP_NewRowid, iStatCur); sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0); sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pIdx->zName, 0); - sqlite3VdbeAddOp1(v, OP_MemLoad, iMem); + sqlite3VdbeAddOp1(v, OP_SCopy, iMem); sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, " ", 0); for(i=0; i<nCol; i++){ - sqlite3VdbeAddOp1(v, OP_MemLoad, iMem); - sqlite3VdbeAddOp1(v, OP_MemLoad, iMem+i+1); + sqlite3VdbeAddOp1(v, OP_SCopy, iMem); + sqlite3VdbeAddOp1(v, OP_SCopy, iMem+i+1); sqlite3VdbeAddOp0(v, OP_Add); sqlite3VdbeAddOp1(v, OP_AddImm, -1); - sqlite3VdbeAddOp1(v, OP_MemLoad, iMem+i+1); + sqlite3VdbeAddOp1(v, OP_SCopy, iMem+i+1); sqlite3VdbeAddOp0(v, OP_Divide); sqlite3VdbeAddOp0(v, OP_ToInt); if( i==nCol-1 ){ sqlite3VdbeAddOp1(v, OP_Concat, nCol*2-1); }else{ - sqlite3VdbeAddOp1(v, OP_Dup, 1); + sqlite3VdbeAddOp1(v, OP_Copy, -1); } } sqlite3VdbeAddOp4(v, OP_MakeRecord, 3, 0, 0, "aaa", 0); diff --git a/src/build.c b/src/build.c index f125745c6..ab134d6a4 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.457 2008/01/04 22:01:03 drh Exp $ +** $Id: build.c,v 1.458 2008/01/05 04:06:04 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -881,7 +881,7 @@ void sqlite3StartTable( } sqlite3OpenMasterTable(pParse, iDb); sqlite3VdbeAddOp0(v, OP_NewRowid); - sqlite3VdbeAddOp0(v, OP_Dup); + sqlite3VdbeAddOp0(v, OP_Copy); sqlite3VdbeAddOp0(v, OP_Null); sqlite3CodeInsert(pParse, 0, OPFLAG_APPEND); sqlite3VdbeAddOp0(v, OP_Close); @@ -1493,7 +1493,7 @@ void sqlite3EndTable( if( pSelect ){ SelectDest dest = {SRT_Table, 1, 0}; Table *pSelTab; - sqlite3VdbeAddOp1(v, OP_Dup, 0); + sqlite3VdbeAddOp0(v, OP_Copy); sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, 0, iDb); pParse->nTab = 2; sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0); @@ -2235,7 +2235,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ v = sqlite3GetVdbe(pParse); if( v==0 ) return; if( memRootPage>=0 ){ - sqlite3VdbeAddOp1(v, OP_MemLoad, memRootPage); + sqlite3VdbeAddOp1(v, OP_SCopy, memRootPage); tnum = 0; }else{ tnum = pIndex->tnum; @@ -2638,7 +2638,7 @@ void sqlite3CreateIndex( */ sqlite3BeginWriteOperation(pParse, 1, iDb); sqlite3VdbeAddOp1(v, OP_CreateIndex, iDb); - sqlite3VdbeAddOp2(v, OP_MemStore, iMem, 0); + sqlite3VdbeAddOp2(v, OP_Copy, 0, iMem); /* Gather the complete text of the CREATE INDEX statement into ** the zStmt variable diff --git a/src/delete.c b/src/delete.c index 4a6a5d0ab..6ce8ad8f5 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** -** $Id: delete.c,v 1.148 2008/01/04 22:01:03 drh Exp $ +** $Id: delete.c,v 1.149 2008/01/05 04:06:04 drh Exp $ */ #include "sqliteInt.h" @@ -68,8 +68,8 @@ void sqlite3CodeInsert(Parse *p, int iCur, u8 flags){ int iData = ++p->nMem; int iKey = ++p->nMem; Vdbe *v = sqlite3GetVdbe(p); - sqlite3VdbeAddOp2(v, OP_MemStore, iData, 1); - sqlite3VdbeAddOp2(v, OP_MemStore, iKey, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, iData); + sqlite3VdbeAddOp2(v, OP_Move, 0, iKey); sqlite3VdbeAddOp3(v, OP_Insert, iCur, iData, iKey); sqlite3VdbeChangeP5(v, sqlite3VdbeCurrentAddr(v)-1, flags); } @@ -87,7 +87,7 @@ int sqlite3StackToReg(Parse *p, int nVal){ assert(v); p->nMem += nVal; for(i=nVal-1; i>=0; i--){ - sqlite3VdbeAddOp2(v, OP_MemStore, iRet+i, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, iRet+i); } return iRet; } @@ -96,7 +96,7 @@ void sqlite3RegToStack(Parse *p, int iReg, int nVal){ Vdbe *v = sqlite3GetVdbe(p); assert(v); for(i=0; i<nVal; i++){ - sqlite3VdbeAddOp2(v, OP_MemLoad, iReg+i, 0); + sqlite3VdbeAddOp2(v, OP_SCopy, iReg+i, 0); } } @@ -520,7 +520,7 @@ void sqlite3GenerateIndexKey( for(j=0; j<pIdx->nColumn; j++){ int idx = pIdx->aiColumn[j]; if( idx==pTab->iPKey ){ - sqlite3VdbeAddOp1(v, OP_Dup, j); + sqlite3VdbeAddOp1(v, OP_Copy, -j); }else{ sqlite3VdbeAddOp2(v, OP_Column, iCur, idx); sqlite3ColumnDefault(v, pTab, idx); diff --git a/src/expr.c b/src/expr.c index a6cb1e17b..2586885e0 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.330 2008/01/04 22:01:03 drh Exp $ +** $Id: expr.c,v 1.331 2008/01/05 04:06:04 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -308,8 +308,7 @@ Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){ } depth = atoi((char*)&pToken->z[1]); p->iTable = ++pParse->nMem; - sqlite3VdbeAddOp1(v, OP_Dup, depth); - sqlite3VdbeAddOp2(v, OP_MemStore, p->iTable, 1); + sqlite3VdbeAddOp2(v, OP_Copy, -depth, p->iTable); return p; } @@ -1606,7 +1605,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique){ int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3VdbeUsesBtree(v, iDb); - sqlite3VdbeAddOp1(v, OP_MemLoad, iMem); + sqlite3VdbeAddOp1(v, OP_SCopy, iMem); iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem); sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); @@ -1643,7 +1642,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique){ iDb = sqlite3SchemaToIndex(db, pIdx->pSchema); sqlite3VdbeUsesBtree(v, iDb); - sqlite3VdbeAddOp1(v, OP_MemLoad, iMem); + sqlite3VdbeAddOp1(v, OP_SCopy, iMem); iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem); sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); @@ -1700,7 +1699,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ */ if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){ int mem = ++pParse->nMem; - sqlite3VdbeAddOp1(v, OP_MemLoad, mem); + sqlite3VdbeAddOp1(v, OP_SCopy, mem); testAddr = sqlite3VdbeAddOp0(v, OP_If); assert( testAddr>0 || pParse->db->mallocFailed ); sqlite3VdbeAddOp2(v, OP_Integer, 1, mem); @@ -1966,7 +1965,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ AggInfo *pAggInfo = pExpr->pAggInfo; struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg]; if( !pAggInfo->directMode ){ - sqlite3VdbeAddOp1(v, OP_MemLoad, pCol->iMem); + sqlite3VdbeAddOp1(v, OP_SCopy, pCol->iMem); break; }else if( pAggInfo->useSortingIdx ){ sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdx, @@ -1980,7 +1979,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ if( pExpr->iTable<0 ){ /* This only happens when coding check constraints */ assert( pParse->ckOffset>0 ); - sqlite3VdbeAddOp2(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1); + sqlite3VdbeAddOp1(v, OP_SCopy, -(pParse->ckOffset-pExpr->iColumn-1)); }else{ sqlite3ExprCodeGetColumn(v, pExpr->pTab, pExpr->iColumn, pExpr->iTable, target); @@ -2029,7 +2028,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ break; } case TK_REGISTER: { - sqlite3VdbeAddOp1(v, OP_MemLoad, pExpr->iTable); + sqlite3VdbeAddOp1(v, OP_SCopy, pExpr->iTable); break; } #ifndef SQLITE_OMIT_CAST @@ -2138,7 +2137,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ sqlite3ErrorMsg(pParse, "misuse of aggregate: %T", &pExpr->span); }else{ - sqlite3VdbeAddOp1(v, OP_MemLoad, pInfo->aFunc[pExpr->iAgg].iMem); + sqlite3VdbeAddOp1(v, OP_SCopy, pInfo->aFunc[pExpr->iAgg].iMem); } break; } @@ -2202,7 +2201,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ if( pExpr->iColumn==0 ){ sqlite3CodeSubselect(pParse, pExpr); } - sqlite3VdbeAddOp1(v, OP_MemLoad, pExpr->iColumn); + sqlite3VdbeAddOp1(v, OP_SCopy, pExpr->iColumn); VdbeComment((v, "load subquery result")); break; } @@ -2254,7 +2253,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ struct ExprList_item *pLItem = pExpr->pList->a; Expr *pRight = pLItem->pExpr; sqlite3ExprCode(pParse, pLeft, 0); - sqlite3VdbeAddOp0(v, OP_Dup); + sqlite3VdbeAddOp0(v, OP_Copy); sqlite3ExprCode(pParse, pRight, 0); codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0); sqlite3VdbeAddOp1(v, OP_Pull, 1); @@ -2291,7 +2290,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ for(i=0; i<nExpr; i=i+2){ sqlite3ExprCode(pParse, aListelem[i].pExpr, 0); if( pExpr->pLeft ){ - sqlite3VdbeAddOp2(v, OP_Dup, 1, 1); + sqlite3VdbeAddOp1(v, OP_SCopy, -1); jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr, OP_Ne, 0, 1); sqlite3VdbeAddOp1(v, OP_Pop, 1); @@ -2339,7 +2338,7 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ #endif } if( target && !inReg ){ - sqlite3VdbeAddOp2(v, OP_MemStore, target, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, target); stackChng = 0; } if( pParse->ckOffset ){ @@ -2372,7 +2371,7 @@ void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr){ if( addr2>addr1+1 || ((pOp = sqlite3VdbeGetOp(v, addr1))!=0 && pOp->opcode==OP_Function) ){ iMem = pExpr->iTable = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_MemStore, iMem, 0); + sqlite3VdbeAddOp2(v, OP_Copy, 0, iMem); pExpr->op = TK_REGISTER; } } @@ -2479,7 +2478,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pList->a[0].pExpr; sqlite3ExprCode(pParse, pLeft, 0); - sqlite3VdbeAddOp2(v, OP_Dup, 0, 0); + sqlite3VdbeAddOp0(v, OP_Copy); sqlite3ExprCode(pParse, pRight, 0); addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull); @@ -2591,7 +2590,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pList->a[0].pExpr; sqlite3ExprCode(pParse, pLeft, 0); - sqlite3VdbeAddOp2(v, OP_Dup, 0, 0); + sqlite3VdbeAddOp0(v, OP_Copy); sqlite3ExprCode(pParse, pRight, 0); addr = sqlite3VdbeCurrentAddr(v); codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull); diff --git a/src/insert.c b/src/insert.c index 7d7bb7c62..9762ab739 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.211 2008/01/04 22:01:03 drh Exp $ +** $Id: insert.c,v 1.212 2008/01/05 04:06:04 drh Exp $ */ #include "sqliteInt.h" @@ -171,9 +171,9 @@ static int autoIncBegin( sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0); sqlite3VdbeAddOp2(v, OP_Ne, 0x100, addr+11); sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0); - sqlite3VdbeAddOp2(v, OP_MemStore, memId-1, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, memId-1); sqlite3VdbeAddOp2(v, OP_Column, iCur, 1); - sqlite3VdbeAddOp2(v, OP_MemStore, memId, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, memId); sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+12); sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+3); sqlite3VdbeAddOp2(v, OP_Close, iCur, 0); @@ -214,12 +214,12 @@ static void autoIncEnd( assert( v ); addr = sqlite3VdbeCurrentAddr(v); sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); - sqlite3VdbeAddOp2(v, OP_MemLoad, memId-1, 0); + sqlite3VdbeAddOp2(v, OP_SCopy, memId-1, 0); sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+6); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); sqlite3VdbeAddOp1(v, OP_NewRowid, iCur); sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0); - sqlite3VdbeAddOp2(v, OP_MemLoad, memId, 0); + sqlite3VdbeAddOp2(v, OP_SCopy, memId, 0); sqlite3VdbeAddOp2(v, OP_MakeRecord, 2, 0); sqlite3CodeInsert(pParse, iCur, OPFLAG_APPEND); sqlite3VdbeAddOp2(v, OP_Close, iCur, 0); @@ -728,9 +728,7 @@ void sqlite3Insert( if( useTempTable ){ sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, iRowid); }else if( pSelect ){ - sqlite3VdbeAddOp3(v, OP_Dup, nColumn - keyColumn - 1, 1, iRowid); - /* TODO: Avoid this use of the stack. */ - sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1); + sqlite3VdbeAddOp2(v, OP_SCopy, -(nColumn - keyColumn - 1), iRowid); }else{ VdbeOp *pOp; sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, 0); @@ -743,7 +741,7 @@ void sqlite3Insert( pOp->p3 = counterMem; }else{ /* TODO: Avoid this use of the stack. */ - sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, iRowid); } } /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid @@ -758,8 +756,7 @@ void sqlite3Insert( }else if( IsVirtual(pTab) ){ sqlite3VdbeAddOp2(v, OP_Null, 0, iRowid); }else{ - sqlite3VdbeAddOp3(v, OP_NewRowid, base, 0, counterMem); - sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1); + sqlite3VdbeAddOp3(v, OP_NewRowid, base, iRowid, counterMem); appendFlag = 1; } autoIncStep(pParse, counterMem, iRowid); @@ -796,9 +793,7 @@ void sqlite3Insert( }else if( useTempTable ){ sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore); }else if( pSelect ){ - sqlite3VdbeAddOp2(v, OP_Dup, nColumn-j-1, 1); - /* TODO: Avoid this use of the stack */ - sqlite3VdbeAddOp2(v, OP_MemStore, iRegStore, 1); + sqlite3VdbeAddOp2(v, OP_SCopy, -(nColumn-j-1), iRegStore); }else{ sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore); } @@ -1005,7 +1000,7 @@ void sqlite3GenerateConstraintChecks( if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){ onError = OE_Abort; } - sqlite3VdbeAddOp2(v, OP_Dup, nCol-1-i, 1); + sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol-1-i)); addr = sqlite3VdbeAddOp2(v, OP_NotNull, 1, 0); assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail || onError==OE_Ignore || onError==OE_Replace ); @@ -1027,7 +1022,7 @@ void sqlite3GenerateConstraintChecks( } case OE_Replace: { sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, 0); - sqlite3VdbeAddOp2(v, OP_Push, nCol-i, 0); + sqlite3VdbeAddOp1(v, OP_Push, nCol-i); break; } } @@ -1068,11 +1063,11 @@ void sqlite3GenerateConstraintChecks( } if( isUpdate ){ - sqlite3VdbeAddOp2(v, OP_Dup, nCol+1, 1); - sqlite3VdbeAddOp2(v, OP_Dup, nCol+1, 1); + sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol+1)); + sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol+1)); jumpInst1 = sqlite3VdbeAddOp2(v, OP_Eq, 0, 0); } - sqlite3VdbeAddOp2(v, OP_Dup, nCol, 1); + sqlite3VdbeAddOp1(v, OP_SCopy, -nCol); jumpInst2 = sqlite3VdbeAddOp2(v, OP_NotExists, base, 0); switch( onError ){ default: { @@ -1089,7 +1084,7 @@ void sqlite3GenerateConstraintChecks( case OE_Replace: { sqlite3GenerateRowIndexDelete(v, pTab, base, 0); if( isUpdate ){ - sqlite3VdbeAddOp2(v, OP_Dup, nCol+hasTwoRowids, 1); + sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol+hasTwoRowids)); sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0); } seenReplace = 1; @@ -1105,7 +1100,7 @@ void sqlite3GenerateConstraintChecks( sqlite3VdbeJumpHere(v, jumpInst2); if( isUpdate ){ sqlite3VdbeJumpHere(v, jumpInst1); - sqlite3VdbeAddOp2(v, OP_Dup, nCol+1, 1); + sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol+1)); sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0); } } @@ -1120,13 +1115,13 @@ void sqlite3GenerateConstraintChecks( extra++; /* Create a key for accessing the index entry */ - sqlite3VdbeAddOp2(v, OP_Dup, nCol+extra, 1); + sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol+extra)); for(i=0; i<pIdx->nColumn; i++){ int idx = pIdx->aiColumn[i]; if( idx==pTab->iPKey ){ - sqlite3VdbeAddOp2(v, OP_Dup, i+extra+nCol+1, 1); + sqlite3VdbeAddOp1(v, OP_SCopy, -(i+extra+nCol+1)); }else{ - sqlite3VdbeAddOp2(v, OP_Dup, i+extra+nCol-idx, 1); + sqlite3VdbeAddOp1(v, OP_SCopy, -(i+extra+nCol-idx)); } } jumpInst1 = sqlite3VdbeAddOp2(v, OP_MakeIdxRec, pIdx->nColumn, 0); @@ -1147,7 +1142,7 @@ void sqlite3GenerateConstraintChecks( /* Check to see if the new index entry will be unique */ - sqlite3VdbeAddOp2(v, OP_Dup, extra+nCol+1+hasTwoRowids, 1); + sqlite3VdbeAddOp1(v, OP_SCopy, -(extra+nCol+1+hasTwoRowids)); jumpInst2 = sqlite3VdbeAddOp2(v, OP_IsUnique, base+iCur+1, 0); /* Generate code that executes if the new index entry is not unique */ @@ -1193,7 +1188,7 @@ void sqlite3GenerateConstraintChecks( int iRowid = sqlite3StackToReg(pParse, 1); sqlite3GenerateRowDelete(pParse->db, v, pTab, base, iRowid, 0); if( isUpdate ){ - sqlite3VdbeAddOp2(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1); + sqlite3VdbeAddOp1(v, OP_SCopy, -(nCol+extra+1+hasTwoRowids)); sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0); } seenReplace = 1; @@ -1245,8 +1240,8 @@ void sqlite3CompleteInsertion( sqlite3TableAffinityStr(v, pTab); #ifndef SQLITE_OMIT_TRIGGER if( newIdx>=0 ){ - sqlite3VdbeAddOp2(v, OP_Dup, 1, 0); - sqlite3VdbeAddOp2(v, OP_Dup, 1, 0); + sqlite3VdbeAddOp1(v, OP_Copy, -1); + sqlite3VdbeAddOp1(v, OP_Copy, -1); sqlite3CodeInsert(pParse, newIdx, 0); } #endif @@ -1566,7 +1561,7 @@ static int xferOptimization( emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); if( pDest->iPKey>=0 ){ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, 0); - sqlite3VdbeAddOp2(v, OP_Dup, 0, 0); + sqlite3VdbeAddOp0(v, OP_Copy); addr2 = sqlite3VdbeAddOp2(v, OP_NotExists, iDest, 0); sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, "PRIMARY KEY must be unique", P4_STATIC); diff --git a/src/pragma.c b/src/pragma.c index 7db789563..a63459f42 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.158 2008/01/04 22:01:03 drh Exp $ +** $Id: pragma.c,v 1.159 2008/01/05 04:06:04 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -300,7 +300,7 @@ void sqlite3Pragma( static const VdbeOpList getCacheSize[] = { { OP_ReadCookie, 0, 0, 2}, /* 0 */ { OP_AbsValue, 0, 0, 0}, - { OP_Dup, 0, 0, 0}, + { OP_Copy, 0, 0, 0}, { OP_Integer, 0, 0, 0}, { OP_Ne, 0, 6, 0}, { OP_Integer, 0, 0, 0}, /* 5 */ @@ -830,7 +830,7 @@ void sqlite3Pragma( ** error message */ static const VdbeOpList endCode[] = { - { OP_MemLoad, 1, 0, 0}, + { OP_SCopy, 1, 0, 0}, { OP_Integer, 0, 0, 0}, { OP_Ne, 0, 0, 0}, /* 2 */ { OP_String8, 0, 0, 0}, /* 3 */ @@ -933,8 +933,8 @@ void sqlite3Pragma( { OP_Rewind, 0, 0, 0}, /* 1 */ { OP_MemIncr, 1, 3, 0}, { OP_Next, 0, 0, 0}, /* 3 */ - { OP_MemLoad, 2, 0, 0}, - { OP_MemLoad, 3, 0, 0}, + { OP_SCopy, 2, 0, 0}, + { OP_SCopy, 3, 0, 0}, { OP_Eq, 0, 0, 0}, /* 6 */ { OP_MemIncr, -1, 1, 0}, { OP_String8, 0, 0, 0}, /* 8 */ diff --git a/src/select.c b/src/select.c index 9d6f5873f..dd768646b 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.384 2008/01/04 22:01:03 drh Exp $ +** $Id: select.c,v 1.385 2008/01/05 04:06:04 drh Exp $ */ #include "sqliteInt.h" @@ -634,7 +634,7 @@ static int selectInnerLoop( ** ORDER BY in this case since the order of entries in the set ** does not matter. But there might be a LIMIT clause, in which ** case the order does matter */ - sqlite3VdbeAddOp2(v, OP_MemLoad, iMem+1, 0); + sqlite3VdbeAddOp2(v, OP_SCopy, iMem+1, 0); pushOntoSorter(pParse, pOrderBy, p); }else{ sqlite3VdbeAddOp4(v, OP_RegMakeRec, iMem, 0, 0, &p->affinity, 1); @@ -658,11 +658,11 @@ static int selectInnerLoop( */ case SRT_Mem: { assert( nColumn==1 ); - sqlite3VdbeAddOp2(v, OP_MemLoad, iMem+1, 0); + sqlite3VdbeAddOp2(v, OP_SCopy, iMem+1, 0); if( pOrderBy ){ pushOntoSorter(pParse, pOrderBy, p); }else{ - sqlite3VdbeAddOp2(v, OP_MemStore, iParm, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, iParm); /* The LIMIT clause will jump out of the loop for us */ } break; @@ -679,7 +679,7 @@ static int selectInnerLoop( sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0); pushOntoSorter(pParse, pOrderBy, p); }else if( eDest==SRT_Subroutine ){ - for(i=0; i<nColumn; i++) sqlite3VdbeAddOp2(v, OP_MemLoad, iMem+i+1, 0); + for(i=0; i<nColumn; i++) sqlite3VdbeAddOp2(v, OP_SCopy, iMem+i+1, 0); sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm); }else{ sqlite3VdbeAddOp2(v, OP_ResultRow, iMem+1, nColumn); @@ -806,7 +806,7 @@ static void generateSortTail( } case SRT_Mem: { assert( nColumn==1 ); - sqlite3VdbeAddOp2(v, OP_MemStore, iParm, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, iParm); /* The LIMIT clause will terminate the loop for us */ break; } @@ -1752,10 +1752,10 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ if( v==0 ) return; sqlite3ExprCode(pParse, p->pLimit, 0); sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0); - sqlite3VdbeAddOp2(v, OP_MemStore, iLimit, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit); VdbeComment((v, "LIMIT counter")); sqlite3VdbeAddOp2(v, OP_IfMemZero, iLimit, iBreak); - sqlite3VdbeAddOp2(v, OP_MemLoad, iLimit, 0); + sqlite3VdbeAddOp2(v, OP_SCopy, iLimit, 0); } if( p->pOffset ){ p->iOffset = iOffset = ++pParse->nMem; @@ -1763,7 +1763,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ if( v==0 ) return; sqlite3ExprCode(pParse, p->pOffset, 0); sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0); - sqlite3VdbeAddOp2(v, OP_MemStore, iOffset, p->pLimit==0); + sqlite3VdbeAddOp2(v, p->pLimit==0 ? OP_Move : OP_Copy, 0, iOffset); VdbeComment((v, "OFFSET counter")); addr1 = sqlite3VdbeAddOp2(v, OP_IfMemPos, iOffset, 0); sqlite3VdbeAddOp2(v, OP_Pop, 1, 0); @@ -1779,7 +1779,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ sqlite3VdbeAddOp2(v, OP_Integer, -1, iLimit+1); addr2 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); sqlite3VdbeJumpHere(v, addr1); - sqlite3VdbeAddOp2(v, OP_MemStore, iLimit+1, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, iLimit+1); VdbeComment((v, "LIMIT+OFFSET")); sqlite3VdbeJumpHere(v, addr2); } @@ -3547,13 +3547,13 @@ int sqlite3Select( sAggInfo.directMode = 1; sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, 0); } - sqlite3VdbeAddOp2(v, OP_MemStore, iBMem+j, j<pGroupBy->nExpr-1); + sqlite3VdbeAddOp2(v, j<pGroupBy->nExpr-1?OP_Move:OP_Copy, 0, iBMem+j); } for(j=pGroupBy->nExpr-1; j>=0; j--){ if( j<pGroupBy->nExpr-1 ){ - sqlite3VdbeAddOp2(v, OP_MemLoad, iBMem+j, 0); + sqlite3VdbeAddOp2(v, OP_SCopy, iBMem+j, 0); } - sqlite3VdbeAddOp2(v, OP_MemLoad, iAMem+j, 0); + sqlite3VdbeAddOp2(v, OP_SCopy, iAMem+j, 0); if( j==0 ){ sqlite3VdbeAddOp2(v, OP_Eq, 0x200, addrProcessRow); }else{ @@ -3573,7 +3573,7 @@ int sqlite3Select( */ sqlite3VdbeResolveLabel(v, addrGroupByChange); for(j=0; j<pGroupBy->nExpr; j++){ - sqlite3VdbeAddOp2(v, OP_MemMove, iAMem+j, iBMem+j); + sqlite3VdbeAddOp2(v, OP_Move, iBMem+j, iAMem+j); } sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow); VdbeComment((v, "output one row")); diff --git a/src/trigger.c b/src/trigger.c index c6ec0e081..9fe781f00 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -237,8 +237,8 @@ void sqlite3FinishTrigger( { OP_String8, 0, 0, 0 }, /* 6: SQL */ { OP_Concat, 0, 0, 0 }, { OP_MakeRecord, 5, 0, 0 }, /* 8: "aaada" */ - { OP_MemStore, 0, 1, 0 }, /* 9: Store data */ - { OP_MemStore, 0, 1, 0 }, /* 10: Store key */ + { OP_Move, 0, 0, 0 }, /* 9: Store data */ + { OP_Move, 0, 0, 0 }, /* 10: Store key */ { OP_Insert, 0, 0, 0 }, }; int addr; @@ -258,9 +258,9 @@ void sqlite3FinishTrigger( sqlite3VdbeChangeP4(v, addr+5, "CREATE TRIGGER ", P4_STATIC); sqlite3VdbeChangeP4(v, addr+6, (char*)pAll->z, pAll->n); sqlite3VdbeChangeP4(v, addr+8, "aaada", P4_STATIC); - sqlite3VdbeChangeP1(v, addr+9, iData); + sqlite3VdbeChangeP2(v, addr+9, iData); + sqlite3VdbeChangeP2(v, addr+10, iKey); sqlite3VdbeChangeP2(v, addr+11, iData); - sqlite3VdbeChangeP1(v, addr+10, iKey); sqlite3VdbeChangeP3(v, addr+11, iKey); sqlite3ChangeCookie(db, v, iDb); sqlite3VdbeAddOp2(v, OP_Close, 0, 0); diff --git a/src/update.c b/src/update.c index 1953711f1..467352cdf 100644 --- a/src/update.c +++ b/src/update.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.158 2008/01/04 22:01:03 drh Exp $ +** $Id: update.c,v 1.159 2008/01/05 04:06:04 drh Exp $ */ #include "sqliteInt.h" @@ -456,7 +456,7 @@ void sqlite3Update( ** So make the cursor point at the old record. */ sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid); - sqlite3VdbeAddOp2(v, OP_MemLoad, iRowid, 0); + sqlite3VdbeAddOp2(v, OP_SCopy, iRowid, 0); /* If the record number will change, push the record number as it ** will be after the update. (The old record number is currently diff --git a/src/vdbe.c b/src/vdbe.c index aea4fd33f..558b75bfd 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.679 2008/01/04 22:01:03 drh Exp $ +** $Id: vdbe.c,v 1.680 2008/01/05 04:06:04 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -470,6 +470,7 @@ int sqlite3VdbeExec( Mem *pIn1, *pIn2; /* Input operands */ Mem *pOut; /* Output operand */ int nPop = 0; /* Number of times to pop the stack */ + u8 opProperty; #ifdef VDBE_PROFILE unsigned long long start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ @@ -596,7 +597,8 @@ int sqlite3VdbeExec( ** then the output is pushed onto the stack. The P2 operand ** is initialized to a NULL. */ - if( (opcodeProperty[pOp->opcode]&OPFLG_OUT2_PRERELEASE)!=0 ){ + opProperty = opcodeProperty[pOp->opcode]; + if( (opProperty & OPFLG_OUT2_PRERELEASE)!=0 ){ assert( pOp->p2>=0 ); if( pOp->p2==0 ){ pOut = ++pTos; @@ -606,6 +608,71 @@ int sqlite3VdbeExec( sqlite3VdbeMemRelease(pOut); } pOut->flags = MEM_Null; + }else + + /* Do common setup for opcodes marked with one of the following + ** combinations of properties. + ** + ** in1 + ** in1 in2 + ** in1 in2 out3 + ** in1 in3 + ** in1 out2 + ** + ** Variables pIn1 and pIn2 are made to point to the first two + ** inputs and pOut points to the output. Variable nPop holds the + ** number of times that the stack should be popped after the + ** the instruction. + */ + if( (opProperty & OPFLG_IN1)!=0 ){ + assert( pOp->p1>=0 ); + if( pOp->p1==0 ){ + pIn1 = pTos; + nPop = 1; + }else{ + assert( pOp->p1<=p->nMem ); + pIn1 = &p->aMem[pOp->p1]; + } + if( (opProperty & OPFLG_IN2)!=0 ){ + assert( pOp->p2>=0 ); + if( pOp->p2==0 ){ + pIn2 = &pTos[-nPop]; + nPop++; + }else{ + assert( pOp->p2<=p->nMem ); + pIn2 = &p->aMem[pOp->p2]; + } + if( (opProperty & OPFLG_OUT3)!=0 ){ + assert( pOp->p3>=0 ); + if( pOp->p3==0 ){ + pTos++; + pOut = &pTos[-nPop]; + pOut->flags = MEM_Null; + }else{ + assert( pOp->p3<=p->nMem ); + pOut = &p->aMem[pOp->p3]; + } + } + }else if( (opProperty & OPFLG_IN3)!=0 ){ + assert( pOp->p3>=0 ); + if( pOp->p3==0 ){ + pIn2 = &pTos[-nPop]; + nPop++; + }else{ + assert( pOp->p3<=p->nMem ); + pIn2 = &p->aMem[pOp->p3]; + } + }else if( (opProperty & OPFLG_OUT2)!=0 ){ + assert( pOp->p2>=0 ); + if( pOp->p2==0 ){ + pTos++; + pOut = &pTos[-nPop]; + pOut->flags = MEM_Null; + }else{ + assert( pOp->p2<=p->nMem ); + pOut = &p->aMem[pOp->p2]; + } + } } switch( pOp->opcode ){ @@ -926,28 +993,77 @@ case OP_Pop: { /* no-push */ break; } -/* Opcode: Dup P1 P2 * +/* Opcode: Move P1 P2 * * * ** -** A copy of the P1-th element of the stack -** is made and pushed onto the top of the stack. -** The top of the stack is element 0. So the -** instruction "Dup 0 0 0" will make a copy of the -** top of the stack. +** Move the value in P1 into P2. If P1 is positive then read from the +** P1-th register. If P1 is zero or negative read from the stack. +** When P1 is 0 read from the top the stack. When P1 is -1 read from +** the next entry down on the stack. And so forth. ** -** If the content of the P1-th element is a dynamically -** allocated string, then a new copy of that string -** is made if P2==0. If P2!=0, then just a pointer -** to the string is copied. +** If P2 is zero, push the new value onto the top of the stack. +** If P2 is positive, write into the P2-th register. ** -** Also see the Pull instruction. +** If P1 is zero then the stack is popped once. The stack is +** unchanged for all other values of P1. The P1 value contains +** a NULL after this operation. */ -case OP_Dup: { - Mem *pFrom = &pTos[-pOp->p1]; - assert( pFrom<=pTos && pFrom>=p->aStack ); - pTos++; - sqlite3VdbeMemShallowCopy(pTos, pFrom, MEM_Ephem); - if( pOp->p2 ){ - Deephemeralize(pTos); +/* Opcode: Copy P1 P2 * * * +** +** Make a copy of P1 into P2. If P1 is positive then read from the +** P1-th register. If P1 is zero or negative read from the stack. +** When P1 is 0 read from the top the stack. When P1 is -1 read from +** the next entry down on the stack. And so forth. +** +** If P2 is zero, push the new value onto the top of the stack. +** If P2 is positive, write into the P2-th register. +** +** This instruction makes a deep copy of the value. A duplicate +** is made of any string or blob constant. See also OP_SCopy. +*/ +/* Opcode: SCopy P1 P2 * * * +** +** Make a shallow copy of P1 into P2. If P1 is positive then read from the +** P1-th register. If P1 is zero or negative read from the stack. +** When P1 is 0 read from the top the stack. When P1 is -1 read from +** the next entry down on the stack. And so forth. +** +** If P2 is zero, push the new value onto the top of the stack. +** If P2 is positive, write into the P2-th register. +** +** This instruction makes a shallow copy of the value. If the value +** is a string or blob, then the copy is only a pointer to the +** original and hence if the original changes so will the copy. +** Worse, if the original is deallocated, the copy becomes invalid. +** Thus the program must guarantee that the original will not change +** during the lifetime of the copy. Use OP_Copy to make a complete +** copy. +*/ +case OP_Move: +case OP_Copy: +case OP_SCopy: { + if( pOp->p1<=0 ){ + pIn1 = &pTos[pOp->p1]; + assert( pIn1>=p->aStack ); + }else{ + assert( pOp->p1<=p->nMem ); + pIn1 = &p->aMem[pOp->p1]; + } + assert( pOp->p2>=0 ); + if( pOp->p2==0 ){ + pOut = ++pTos; + pOut->flags = MEM_Null; + }else{ + assert( pOp->p2<=p->nMem ); + pOut = &p->aMem[pOp->p2]; + } + if( pOp->opcode==OP_Move ){ + rc = sqlite3VdbeMemMove(pOut, pIn1); + if( pOp->p1==0 ) pTos--; + }else{ + sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); + if( pOp->opcode==OP_Copy ){ + Deephemeralize(pOut); + } } break; } @@ -959,8 +1075,6 @@ case OP_Dup: { ** top of the stack is element 0, so "Pull 0 0 0" is ** a no-op. "Pull 1 0 0" swaps the top two elements of ** the stack. -** -** See also the Dup instruction. */ case OP_Pull: { /* no-push */ Mem *pFrom = &pTos[-pOp->p1]; @@ -2681,7 +2795,7 @@ case OP_Transaction: { /* no-push */ break; } -/* Opcode: ReadCookie P1 P2 P3 +/* Opcode: ReadCookie P1 P2 P3 * * ** ** Read cookie number P3 from database P1 and write it into register ** P2 or push it onto the stack if P2==0. @@ -4615,46 +4729,6 @@ case OP_ContextPop: { /* no-push */ } #endif /* #ifndef SQLITE_OMIT_TRIGGER */ -/* Opcode: MemStore P1 P2 * -** -** Write the top of the stack into memory location P1. -** P1 should be a small integer since space is allocated -** for all memory locations between 0 and P1 inclusive. -** -** After the data is stored in the memory location, the -** stack is popped once if P2 is 1. If P2 is zero, then -** the original data remains on the stack. -*/ -case OP_MemStore: { /* no-push */ - assert( pTos>=p->aStack ); - assert( pOp->p1>0 && pOp->p1<=p->nMem ); - rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], pTos); - pTos--; - - /* If P2 is 0 then fall thru to the next opcode, OP_MemLoad, that will - ** restore the top of the stack to its original value. - */ - if( pOp->p2 ){ - break; - } -} -/* Opcode: MemLoad P1 * * -** -** Push a copy of the value in memory location P1 onto the stack. -** -** If the value is a string, then the value pushed is a pointer to -** the string that is stored in the memory location. If the memory -** location is subsequently changed (using OP_MemStore) then the -** value pushed onto the stack will change too. -*/ -case OP_MemLoad: { - int i = pOp->p1; - assert( i>0 && i<=p->nMem ); - pTos++; - sqlite3VdbeMemShallowCopy(pTos, &p->aMem[i], MEM_Ephem); - break; -} - #ifndef SQLITE_OMIT_AUTOINCREMENT /* Opcode: MemMax P1 P2 * ** @@ -4768,19 +4842,6 @@ case OP_IfMemNull: { /* no-push, jump */ break; } -/* Opcode: MemMove P1 P2 * -** -** Move the content of memory cell P2 over to memory cell P1. -** Any prior content of P1 is erased. Memory cell P2 is left -** containing a NULL. -*/ -case OP_MemMove: { - assert( pOp->p1>0 && pOp->p1<=p->nMem ); - assert( pOp->p2>0 && pOp->p2<=p->nMem ); - rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], &p->aMem[pOp->p2]); - break; -} - /* Opcode: AggStep P1 P2 P4 ** ** Execute the step function for an aggregate. The @@ -5306,6 +5367,12 @@ default: { *****************************************************************************/ } + /* Pop the stack if necessary */ + if( nPop ){ + popStack(&pTos, nPop); + nPop = 0; + } + /* Make sure the stack limit was not exceeded */ assert( pTos>=&p->aStack[-1] && pTos<=pStackLimit ); diff --git a/src/where.c b/src/where.c index 0dbb614ff..5f512abb0 100644 --- a/src/where.c +++ b/src/where.c @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.273 2008/01/04 22:01:03 drh Exp $ +** $Id: where.c,v 1.274 2008/01/05 04:06:04 drh Exp $ */ #include "sqliteInt.h" @@ -1827,7 +1827,7 @@ static void codeAllEqualityTerms( sqlite3VdbeAddOp2(v, OP_IsNull, termsInMem ? -1 : -(j+1), pLevel->brk); } if( termsInMem ){ - sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem+j+1, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, pLevel->iMem+j+1); } } @@ -1835,7 +1835,7 @@ static void codeAllEqualityTerms( */ if( termsInMem ){ for(j=0; j<nEq; j++){ - sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem+j+1, 0); + sqlite3VdbeAddOp2(v, OP_SCopy, pLevel->iMem+j+1, 0); } } } @@ -2362,7 +2362,7 @@ WhereInfo *sqlite3WhereBegin( assert( pEnd->leftCursor==iCur ); sqlite3ExprCode(pParse, pX->pRight, 0); pLevel->iMem = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, pLevel->iMem); if( pX->op==TK_LT || pX->op==TK_GT ){ testOp = bRev ? OP_Le : OP_Ge; }else{ @@ -2376,7 +2376,7 @@ WhereInfo *sqlite3WhereBegin( pLevel->p2 = start; if( testOp!=OP_Noop ){ sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0); - sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem, 0); + sqlite3VdbeAddOp2(v, OP_SCopy, pLevel->iMem, 0); sqlite3VdbeAddOp2(v, testOp, SQLITE_AFF_NUMERIC|0x100, brk); } }else if( pLevel->flags & WHERE_COLUMN_RANGE ){ @@ -2410,7 +2410,7 @@ WhereInfo *sqlite3WhereBegin( ** start key. */ for(j=0; j<nEq; j++){ - sqlite3VdbeAddOp2(v, OP_Dup, nEq-1, 0); + sqlite3VdbeAddOp1(v, OP_Copy, 1-nEq); } /* Figure out what comparison operators to use for top and bottom @@ -2459,7 +2459,7 @@ WhereInfo *sqlite3WhereBegin( int op = topEq ? OP_MoveLe : OP_MoveLt; sqlite3VdbeAddOp2(v, op, iIdxCur, nxt); }else{ - sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, pLevel->iMem); } }else if( bRev ){ sqlite3VdbeAddOp2(v, OP_Last, iIdxCur, brk); @@ -2493,7 +2493,7 @@ WhereInfo *sqlite3WhereBegin( buildIndexProbe(v, nCol, pIdx); if( bRev ){ pLevel->iMem = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 1); + sqlite3VdbeAddOp2(v, OP_Move, 0, pLevel->iMem); testOp = OP_IdxLT; }else{ int op = btmEq ? OP_MoveGe : OP_MoveGt; @@ -2511,7 +2511,7 @@ WhereInfo *sqlite3WhereBegin( */ start = sqlite3VdbeCurrentAddr(v); if( testOp!=OP_Noop ){ - sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem, 0); + sqlite3VdbeAddOp2(v, OP_SCopy, pLevel->iMem, 0); sqlite3VdbeAddOp2(v, testOp, iIdxCur, nxt); if( (topEq && !bRev) || (!btmEq && bRev) ){ sqlite3VdbeChangeP4(v, -1, "+", P4_STATIC); @@ -2548,7 +2548,7 @@ WhereInfo *sqlite3WhereBegin( ** the search */ buildIndexProbe(v, nEq, pIdx); - sqlite3VdbeAddOp2(v, OP_MemStore, pLevel->iMem, 0); + sqlite3VdbeAddOp2(v, OP_Copy, 0, pLevel->iMem); /* Generate code (1) to move to the first matching element of the table. ** Then generate code (2) that jumps to "nxt" after the cursor is past @@ -2558,13 +2558,13 @@ WhereInfo *sqlite3WhereBegin( if( bRev ){ /* Scan in reverse order */ sqlite3VdbeAddOp2(v, OP_MoveLe, iIdxCur, nxt); - start = sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem, 0); + start = sqlite3VdbeAddOp2(v, OP_SCopy, pLevel->iMem, 0); sqlite3VdbeAddOp2(v, OP_IdxLT, iIdxCur, nxt); pLevel->op = OP_Prev; }else{ /* Scan in the forward order */ sqlite3VdbeAddOp2(v, OP_MoveGe, iIdxCur, nxt); - start = sqlite3VdbeAddOp2(v, OP_MemLoad, pLevel->iMem, 0); + start = sqlite3VdbeAddOp2(v, OP_SCopy, pLevel->iMem, 0); sqlite3VdbeAddOp4(v, OP_IdxGE, iIdxCur, nxt, 0, "+", P4_STATIC); pLevel->op = OP_Next; } |