Index: src/sqlite.h.in ================================================================== --- src/sqlite.h.in +++ src/sqlite.h.in @@ -28,11 +28,11 @@ ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** -** @(#) $Id: sqlite.h.in,v 1.276 2007/12/06 02:42:08 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.277 2007/12/12 12:25:22 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include /* Needed for the definition of va_list */ @@ -296,11 +296,11 @@ ** */ #define SQLITE_OK 0 /* Successful result */ /* beginning-of-error-codes */ #define SQLITE_ERROR 1 /* SQL error or missing database */ -#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */ +#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */ #define SQLITE_PERM 3 /* Access permission denied */ #define SQLITE_ABORT 4 /* Callback routine requested an abort */ #define SQLITE_BUSY 5 /* The database file is locked */ #define SQLITE_LOCKED 6 /* A table in the database is locked */ #define SQLITE_NOMEM 7 /* A malloc() failed */ Index: src/update.c ================================================================== --- src/update.c +++ src/update.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.142 2007/12/12 12:00:46 drh Exp $ +** $Id: update.c,v 1.143 2007/12/12 12:25:22 drh Exp $ */ #include "sqliteInt.h" #ifndef SQLITE_OMIT_VIRTUALTABLE /* Forward declaration */ @@ -103,10 +103,11 @@ int openAll = 0; /* True if all indices need to be opened */ AuthContext sContext; /* The authorization context */ NameContext sNC; /* The name-context to resolve expressions in */ int iDb; /* Database containing the table being updated */ int memCnt = 0; /* Memory cell used for counting rows changed */ + int mem1; /* Memory address storing the rowid for next row to update */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* Trying to update a view */ int triggers_exist = 0; /* True if any row triggers exist */ #endif @@ -259,10 +260,11 @@ */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto update_cleanup; if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, 1, iDb); + mem1 = pParse->nMem++; #ifndef SQLITE_OMIT_VIRTUALTABLE /* Virtual tables must be handled separately */ if( IsVirtual(pTab) ){ updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef, @@ -316,11 +318,10 @@ memCnt = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt); } if( triggers_exist ){ - int mem1; /* Memory address storing the rowid for next row to update */ /* Create pseudo-tables for NEW and OLD */ sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0); sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol); @@ -329,11 +330,10 @@ /* The top of the update loop for when there are triggers. */ addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0); sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0); - mem1 = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemStore, mem1, 0); if( !isView ){ /* Open a cursor and make it point to the record that is ** being updated. @@ -385,11 +385,10 @@ goto update_cleanup; } if( !isView ){ sqlite3VdbeAddOp(v, OP_MemLoad, mem1, 0); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); } } if( !isView && !IsVirtual(pTab) ){ /* @@ -427,13 +426,14 @@ ** So make the cursor point at the old record. */ if( !triggers_exist ){ addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0); sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0); - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); + sqlite3VdbeAddOp(v, OP_MemStore, mem1, 0); } sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr); + sqlite3VdbeAddOp(v, OP_MemLoad, mem1, 0); /* If the record number will change, push the record number as it ** will be after the update. (The old record number is currently ** on top of the stack.) */ Index: src/vdbe.c ================================================================== --- src/vdbe.c +++ src/vdbe.c @@ -41,11 +41,11 @@ ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** 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.657 2007/12/12 12:00:46 drh Exp $ +** $Id: vdbe.c,v 1.658 2007/12/12 12:25:22 drh Exp $ */ #include "sqliteInt.h" #include #include "vdbeInt.h" @@ -703,14 +703,14 @@ case OP_StackDepth: { /* no-push */ if( pOp->p1<0 ){ pOp->p1 = pTos - p->aStack + 1; }else if( pOp->p1!=pTos - p->aStack + 1 ){ p->pTos = pTos; - p->rc = SQLITE_ERROR; + p->rc = rc = SQLITE_INTERNAL; p->pc = pc; p->errorAction = OE_Rollback; - sqlite3SetString(&p->zErrMsg, "internal VDBE stack overflow", (char*)0); + sqlite3SetString(&p->zErrMsg, "internal error: VDBE stack leak", (char*)0); goto vdbe_return; } break; }