-C Changes\sto\slemon.c\sso\sthat\sit\scompiles\son\sOpenWatcom\s1.3.\s\sTicket\s#665.\s(CVS\s1307)
-D 2004-04-24T12:59:13
+C Fix\sa\sstack\soverflow\sproblem\swith\sINSTEAD\sOF\striggers.\s(CVS\s1310)
+D 2004-04-29T16:16:29
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/test4.c 6e3e31acfaf21d66420fc35fda5b17dc0000cc8d
F src/tokenize.c 6676b946fd8825b67ab52140af4fdc57a70bda48
F src/trigger.c a9927b57c865b6f3df3fb5e40c9824d722660ded
-F src/update.c 4c50328ebc127852bde8e2950eb8933234802c21
+F src/update.c bd391079138e67d09c9af34528ca4137c29242d1
F src/util.c 122bc174f6c8c2eb6a9127d9f13c4c74f83b85e4
F src/vacuum.c a4e8464c9f6d60659c5343e9d62c742463227820
-F src/vdbe.c 7c33f761fdc799633468766fb53eda4301daa6b3
+F src/vdbe.c f006200348ef3feded56bef8714e052da74a885a
F src/vdbe.h ac987945e4dd6f987bca534c6005899f089fc270
F src/vdbeInt.h b40ff02ce39fd076e6ff3369e19c1bbfe1986682
F src/vdbeaux.c e2cdd1ab63604a390612c73e26bdd2ef910e9438
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 635f674d20ca3e0b534eba54313004e859de16e9
-R 9c976d5c8583c7ac8ea10461b8760357
+P b8b8ce5c81ef614d488e0f79df8935ef609dc4f2
+R 09116ec27eaf3c7f0c80f307e42d61db
U drh
-Z 6726be1b9326ca3188d590be44166ddf
+Z f5047c70c45fb9bcbbd3fb6ce59d57f5
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
-** $Id: update.c,v 1.70 2004/02/22 20:05:02 drh Exp $
+** $Id: update.c,v 1.70.2.1 2004/04/29 16:16:29 drh Exp $
*/
#include "sqliteInt.h"
){
int i, j; /* Loop counters */
Table *pTab; /* The table to be updated */
- int addr; /* VDBE instruction address of the start of the loop */
+ int loopStart; /* VDBE instruction address of the start of the loop */
+ int jumpInst; /* Addr of VDBE instruction to jump out of loop */
WhereInfo *pWInfo; /* Information about the WHERE clause */
Vdbe *v; /* The virtual database engine */
Index *pIdx; /* For looping over indices */
Expr *pRecnoExpr; /* Expression defining the new record number */
int openAll; /* True if all indices need to be opened */
int isView; /* Trying to update a view */
+ int iStackDepth; /* Index of memory cell holding stack depth */
AuthContext sContext; /* The authorization context */
int before_triggers; /* True if there are any BEFORE triggers */
if( pParse->nErr || sqlite_malloc_failed ) goto update_cleanup;
db = pParse->db;
assert( pTabList->nSrc==1 );
+ iStackDepth = pParse->nMem++;
/* Locate the table which we want to update.
*/
/* The top of the update loop for when there are triggers.
*/
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
- addr = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
+ sqliteVdbeAddOp(v, OP_StackDepth, 0, 0);
+ sqliteVdbeAddOp(v, OP_MemStore, iStackDepth, 1);
+ loopStart = sqliteVdbeAddOp(v, OP_MemLoad, iStackDepth, 0);
+ sqliteVdbeAddOp(v, OP_StackReset, 0, 0);
+ jumpInst = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
/* Open a cursor and make it point to the record that is
/* Fire the BEFORE and INSTEAD OF triggers
*/
if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_BEFORE, pTab,
- newIdx, oldIdx, onError, addr) ){
+ newIdx, oldIdx, onError, loopStart) ){
goto update_cleanup;
}
}
*/
if( !row_triggers_exist ){
sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
- addr = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
+ jumpInst = loopStart = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
}
- sqliteVdbeAddOp(v, OP_NotExists, iCur, addr);
+ sqliteVdbeAddOp(v, OP_NotExists, iCur, loopStart);
/* If the record number will change, push the record number as it
** will be after the update. (The old record number is currently
/* Do constraint checks
*/
sqliteGenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRecno, 1,
- onError, addr);
+ onError, loopStart);
/* Delete the old indices for the current record.
*/
pParse->nTab = iCur;
}
if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_AFTER, pTab,
- newIdx, oldIdx, onError, addr) ){
+ newIdx, oldIdx, onError, loopStart) ){
goto update_cleanup;
}
}
/* Repeat the above with the next record to be updated, until
** all record selected by the WHERE clause have been updated.
*/
- sqliteVdbeAddOp(v, OP_Goto, 0, addr);
- sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
+ sqliteVdbeAddOp(v, OP_Goto, 0, loopStart);
+ sqliteVdbeChangeP2(v, jumpInst, sqliteVdbeCurrentAddr(v));
sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
/* Close all tables if there were no FOR EACH ROW triggers */
** 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.268 2004/03/03 01:51:25 drh Exp $
+** $Id: vdbe.c,v 1.268.2.1 2004/04/29 16:16:30 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
break;
}
+/* Opcode: StackDepth * * *
+**
+** Push an integer onto the stack which is the depth of the stack prior
+** to that integer being pushed.
+*/
+case OP_StackDepth: {
+ int depth = (&pTos[1]) - p->aStack;
+ pTos++;
+ pTos->i = depth;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: StackReset * * *
+**
+** Pop a single integer off of the stack. Then pop the stack
+** as many times as necessary to get the depth of the stack down
+** to the value of the integer that was popped.
+*/
+case OP_StackReset: {
+ int depth, goal;
+ assert( pTos>=p->aStack );
+ Integerify(pTos);
+ goal = pTos->i;
+ depth = (&pTos[1]) - p->aStack;
+ assert( goal<depth );
+ popStack(&pTos, depth-goal);
+ break;
+}
+
/* An other opcode is illegal...
*/
default: {