aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2008-01-05 04:06:03 +0000
committerdrh <drh@noemail.net>2008-01-05 04:06:03 +0000
commitb1fdb2adea877989a87abb4e7426a34254e43b6c (patch)
treed83d76b1424e3f9f14762ed988348d95315d25cd /src
parent4c583128bd7c86d535a81af38665866213020164 (diff)
downloadsqlite-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.c19
-rw-r--r--src/build.c10
-rw-r--r--src/delete.c12
-rw-r--r--src/expr.c33
-rw-r--r--src/insert.c53
-rw-r--r--src/pragma.c10
-rw-r--r--src/select.c28
-rw-r--r--src/trigger.c8
-rw-r--r--src/update.c4
-rw-r--r--src/vdbe.c219
-rw-r--r--src/where.c24
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;
}