Modify OP_VUpdate to read arguments from a range of memory cells instead of from the stack. (CVS 4668)
FossilOrigin-Name: 955b15a020e9ea6401fe03a36f5139a03ea80b8a
diff --git a/src/delete.c b/src/delete.c
index b97ce70..6e7f85e 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.142 2008/01/03 09:51:55 danielk1977 Exp $
+** $Id: delete.c,v 1.143 2008/01/03 17:31:45 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -75,6 +75,24 @@
}
/*
+** Allocate nVal contiguous memory cells and return the index of the
+** first. Also pop nVal elements from the stack and store them in the
+** registers. The element on the top of the stack is stored in the
+** register with the largest index.
+*/
+int sqlite3StackToReg(Parse *p, int nVal){
+ int i;
+ int iRet = p->nMem;
+ Vdbe *v = sqlite3GetVdbe(p);
+ assert(v);
+ p->nMem += nVal;
+ for(i=nVal-1; i>=0; i--){
+ sqlite3VdbeAddOp2(v, OP_MemStore, iRet+i, 1);
+ }
+ return iRet;
+}
+
+/*
** Generate code that will open a table for reading.
*/
void sqlite3OpenTable(
@@ -354,8 +372,9 @@
/* Delete the row */
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
+ int iReg = sqlite3StackToReg(pParse, 1);
pParse->pVirtualLock = pTab;
- sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, 0,
+ sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iReg,
(const char*)pTab->pVtab, P4_VTAB);
}else
#endif
diff --git a/src/insert.c b/src/insert.c
index 5ef9295..068bc8e 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.205 2008/01/03 11:50:30 danielk1977 Exp $
+** $Id: insert.c,v 1.206 2008/01/03 17:31:45 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -795,8 +795,9 @@
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
+ int iReg = sqlite3StackToReg(pParse, pTab->nCol+2);
pParse->pVirtualLock = pTab;
- sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, 0,
+ sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, iReg,
(const char*)pTab->pVtab, P4_VTAB);
}else
#endif
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 912a318..fad6ca9 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.633 2008/01/03 11:50:30 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.634 2008/01/03 17:31:45 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -1919,7 +1919,7 @@
char *sqlite3StrAccumFinish(StrAccum*);
void sqlite3StrAccumReset(StrAccum*);
void sqlite3CodeInsert(Parse *, int, u8);
-
+int sqlite3StackToReg(Parse *, int);
/*
** The interface to the LEMON-generated parser
diff --git a/src/update.c b/src/update.c
index d7ae939..60fd195 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.152 2008/01/03 09:51:55 danielk1977 Exp $
+** $Id: update.c,v 1.153 2008/01/03 17:31:45 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -647,8 +647,10 @@
sqlite3VdbeAddOp2(v, OP_Column, ephemTab, i+1+(pRowid!=0));
}
pParse->pVirtualLock = pTab;
- sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, 0,
- (const char*)pTab->pVtab, P4_VTAB);
+ sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2,
+ sqlite3StackToReg(pParse, pTab->nCol+2),
+ (const char*)pTab->pVtab, P4_VTAB
+ );
sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr);
sqlite3VdbeJumpHere(v, addr-1);
sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
diff --git a/src/vdbe.c b/src/vdbe.c
index 0ecee75..47079cf 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.669 2008/01/03 11:50:30 danielk1977 Exp $
+** $Id: vdbe.c,v 1.670 2008/01/03 17:31:45 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -5198,21 +5198,21 @@
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VUpdate P1 P2 P4
+/* Opcode: VUpdate P1 P2 P3 P4
**
** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
** This opcode invokes the corresponding xUpdate method. P2 values
-** are taken from the stack to pass to the xUpdate invocation. The
-** value on the top of the stack corresponds to the p2th element
-** of the argv array passed to xUpdate.
+** are contiguous memory cells starting at P3 to pass to the xUpdate
+** invocation. The value in register (P3+P2-1) corresponds to the
+** p2th element of the argv array passed to xUpdate.
**
** The xUpdate method will do a DELETE or an INSERT or both.
-** The argv[0] element (which corresponds to the P2-th element down
-** on the stack) is the rowid of a row to delete. If argv[0] is
-** NULL then no deletion occurs. The argv[1] element is the rowid
-** of the new row. This can be NULL to have the virtual table
-** select the new rowid for itself. The higher elements in the
-** stack are the values of columns in the new row.
+** The argv[0] element (which corresponds to memory cell P3)
+** is the rowid of a row to delete. If argv[0] is NULL then no
+** deletion occurs. The argv[1] element is the rowid of the new
+** row. This can be NULL to have the virtual table select the new
+** rowid for itself. The subsequent elements in the array are
+** the values of columns in the new row.
**
** If P2==1 then no insert is performed. argv[0] is the rowid of
** a row to delete.
@@ -5233,10 +5233,11 @@
int i;
sqlite_int64 rowid;
Mem **apArg = p->apArg;
- Mem *pX = &pTos[1-nArg];
- for(i = 0; i<nArg; i++, pX++){
+ Mem *pX = &p->aMem[pOp->p3];
+ for(i=0; i<nArg; i++){
storeTypeInfo(pX, 0);
apArg[i] = pX;
+ pX++;
}
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
sqlite3VtabLock(pVtab);
@@ -5248,7 +5249,6 @@
db->lastRowid = rowid;
}
}
- popStack(&pTos, nArg);
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */