Some modifications to insert.c to work without using the stack. (CVS 4678)
FossilOrigin-Name: d9ac6beef538376d0ea0a1daa95cf1dfe36143cf
diff --git a/src/insert.c b/src/insert.c
index 710175b..a53d0f7 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.209 2008/01/04 13:24:29 danielk1977 Exp $
+** $Id: insert.c,v 1.210 2008/01/04 19:10:29 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -189,9 +189,9 @@
** larger than the maximum rowid in the memId memory cell, then the
** memory cell is updated. The stack is unchanged.
*/
-static void autoIncStep(Parse *pParse, int memId){
+static void autoIncStep(Parse *pParse, int memId, int iRowid){
if( memId>0 ){
- sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, 0);
+ sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, iRowid);
}
}
@@ -231,7 +231,7 @@
** above are all no-ops
*/
# define autoIncBegin(A,B,C) (0)
-# define autoIncStep(A,B)
+# define autoIncStep(A,B,C)
# define autoIncEnd(A,B,C,D)
#endif /* SQLITE_OMIT_AUTOINCREMENT */
@@ -716,15 +716,21 @@
** case the record number is the same as that column.
*/
if( !isView ){
+ int iReg = pParse->nMem+1;
+ int iRowid = iReg+(IsVirtual(pTab)?1:0);
+ pParse->nMem += pTab->nCol + (IsVirtual(pTab)?2:1);
+
if( IsVirtual(pTab) ){
- /* The row that the VUpdate opcode will delete: none */
- sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
+ /* The row that the VUpdate opcode will delete: none */
+ sqlite3VdbeAddOp2(v, OP_MemNull, 0, iReg);
}
if( keyColumn>=0 ){
if( useTempTable ){
- sqlite3VdbeAddOp2(v, OP_Column, srcTab, keyColumn);
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, iRowid);
}else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_Dup, nColumn - keyColumn - 1, 1);
+ sqlite3VdbeAddOp3(v, OP_Dup, nColumn - keyColumn - 1, 1, iRowid);
+ /* TODO: Avoid this use of the stack. */
+ sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1);
}else{
VdbeOp *pOp;
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, 0);
@@ -734,36 +740,42 @@
pOp->opcode = OP_NewRowid;
pOp->p1 = base;
pOp->p2 = counterMem;
+ pOp->p3 = iRowid;
+ }else{
+ /* TODO: Avoid this use of the stack. */
+ sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1);
}
}
/* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
** to generate a unique primary key value.
*/
if( !appendFlag ){
- sqlite3VdbeAddOp2(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
- sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
- sqlite3VdbeAddOp2(v, OP_NewRowid, base, counterMem);
- sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
+ sqlite3VdbeAddOp2(v, OP_IfMemNull, iRowid, sqlite3VdbeCurrentAddr(v)+2);
+ sqlite3VdbeAddOp2(v, OP_Goto, -1, sqlite3VdbeCurrentAddr(v)+2);
+ sqlite3VdbeAddOp3(v, OP_NewRowid, base, counterMem, iRowid);
+ sqlite3VdbeAddOp3(v, OP_MustBeInt, 0, 0, iRowid);
}
}else if( IsVirtual(pTab) ){
- sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
+ sqlite3VdbeAddOp2(v, OP_MemNull, 0, iRowid);
}else{
sqlite3VdbeAddOp2(v, OP_NewRowid, base, counterMem);
+ sqlite3VdbeAddOp2(v, OP_MemStore, iRowid, 1);
appendFlag = 1;
}
- autoIncStep(pParse, counterMem);
+ autoIncStep(pParse, counterMem, iRowid);
/* Push onto the stack, data for all columns of the new entry, beginning
** with the first column.
*/
nHidden = 0;
for(i=0; i<pTab->nCol; i++){
+ int iRegStore = iRowid+1+i;
if( i==pTab->iPKey ){
/* The value of the INTEGER PRIMARY KEY column is always a NULL.
** Whenever this column is read, the record number will be substituted
** in its place. So will fill this column with a NULL to avoid
** taking up data space with information that will never be used. */
- sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
+ sqlite3VdbeAddOp2(v, OP_MemNull, 0, iRegStore);
continue;
}
if( pColumn==0 ){
@@ -780,13 +792,15 @@
}
}
if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, 0);
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iRegStore);
}else if( useTempTable ){
- sqlite3VdbeAddOp2(v, OP_Column, srcTab, j);
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore);
}else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_Dup, i+nColumn-j+IsVirtual(pTab), 1);
+ sqlite3VdbeAddOp2(v, OP_Dup, nColumn-j-1, 1);
+ /* TODO: Avoid this use of the stack */
+ sqlite3VdbeAddOp2(v, OP_MemStore, iRegStore, 1);
}else{
- sqlite3ExprCode(pParse, pList->a[j].pExpr, 0);
+ sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore);
}
}
@@ -795,13 +809,13 @@
*/
#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, iReg,
(const char*)pTab->pVtab, P4_VTAB);
}else
#endif
{
+ sqlite3RegToStack(pParse, iReg, pTab->nCol+1);
sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
0, onError, endOfLoop);
sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0,
@@ -1557,7 +1571,7 @@
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
"PRIMARY KEY must be unique", P4_STATIC);
sqlite3VdbeJumpHere(v, addr2);
- autoIncStep(pParse, counterMem);
+ autoIncStep(pParse, counterMem, 0);
}else if( pDest->pIndex==0 ){
addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, 0);
}else{