Take advantage of the fact that b-tree cursors need not be closed while other cursors modify their tables to simplify trigger program generation code. (CVS 4654)
FossilOrigin-Name: f1966a8a47fca85f7862c0797a527ab01ac8b0c1
This commit is contained in:
parent
eb9ae90137
commit
e448dc4abf
20
manifest
20
manifest
@ -1,5 +1,5 @@
|
||||
C Add\ssome\sextra\stests\sfor\sthe\srecent\strigger\scompilation\soptimization.\s(CVS\s4653)
|
||||
D 2008-01-02T04:41:25
|
||||
C Take\sadvantage\sof\sthe\sfact\sthat\sb-tree\scursors\sneed\snot\sbe\sclosed\swhile\sother\scursors\smodify\stheir\stables\sto\ssimplify\strigger\sprogram\sgeneration\scode.\s(CVS\s4654)
|
||||
D 2008-01-02T11:50:51
|
||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@ -83,20 +83,20 @@ F src/analyze.c cb25936f0148ee65c825a49f8064292a98050a50
|
||||
F src/attach.c 95658e74e3e0d1cbdb8658817516d4d1467fc13d
|
||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||
F src/btmutex.c 5d39da37c9d1282f3c6f9967afae6a34ee36b7ff
|
||||
F src/btree.c 6c3ded4f31046de72993a440921ad50a7eb4a65d
|
||||
F src/btree.c 5164b32950cfd41f2c5c31e8ff82c4a499918aef
|
||||
F src/btree.h 19dcf5ad23c17b98855da548e9a8e3eb4429d5eb
|
||||
F src/btreeInt.h 1c5a9da165718ef7de81e35ce9ab5d9ba9283f76
|
||||
F src/build.c cbfd98ceb95c61c226cd60a845fa7967b66c8931
|
||||
F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
|
||||
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
||||
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
|
||||
F src/delete.c a4843531af1354882ea7dbe53fa5f46b581ae73c
|
||||
F src/delete.c e750b537a77da4971c39e3fbb569de55fe4cf095
|
||||
F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
|
||||
F src/expr.c c3fb939d6801071ce19243521ca444eca40b057a
|
||||
F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d
|
||||
F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c
|
||||
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
||||
F src/insert.c 355c482603c8c5151b23c3c7661cf1044ec34d29
|
||||
F src/insert.c 1946d8c7431fc2b614a4b15155f960f999b14ba5
|
||||
F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2
|
||||
F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66
|
||||
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
|
||||
@ -164,7 +164,7 @@ F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59
|
||||
F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730
|
||||
F src/tokenize.c a4e04438c11fed2c67ec47fe3edbef9cca2d1b48
|
||||
F src/trigger.c f8e2d42cf1782ffc14a9d7cee1d1a406f9b0c8c4
|
||||
F src/update.c fee857007be57b68a7539c26cc5563d8fbaf3f82
|
||||
F src/update.c 24ab2157d360bc20ac4447f50d3a70cd993a7d98
|
||||
F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
|
||||
F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
|
||||
F src/vacuum.c 25ffbd766f25bca099ead1c1e11f5528c86102b8
|
||||
@ -172,7 +172,7 @@ F src/vdbe.c 56a6e80d3357622305cffe6ea509e5d643e7dadb
|
||||
F src/vdbe.h a042e6d3b567ac81f182ca5b4639807621355822
|
||||
F src/vdbeInt.h 2985f1369273e635898cf5952237efcb3fdb21f3
|
||||
F src/vdbeapi.c 4acfaab3e10c99eb66c5332979d7b14a1c3505ae
|
||||
F src/vdbeaux.c bca64691ad6bb11e45b5ccf494d9f088d23b3575
|
||||
F src/vdbeaux.c 9c2ce05e86502ac3dd148ed13535886e82678e04
|
||||
F src/vdbeblob.c 82f51cdf9b0c0af729732fde48c824e498c0a1ca
|
||||
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
|
||||
F src/vdbemem.c 123994fcd344993d2fb050a83b91b341bbbd08b4
|
||||
@ -603,7 +603,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P 051ec01f2799e095516015f2ef0180e50fac387c
|
||||
R b1162a1e7d20a24c20501e40bc7dde0f
|
||||
P de54dad800f0b62740ad4ebb3780464b44eb6dff
|
||||
R a86b5c6a0f11cd9be312d89f90e2feb5
|
||||
U danielk1977
|
||||
Z 75dbf0acf2e3e5d3feebf07dfd171fca
|
||||
Z 5595cb26a9237dd9d189ded057a3e630
|
||||
|
@ -1 +1 @@
|
||||
de54dad800f0b62740ad4ebb3780464b44eb6dff
|
||||
f1966a8a47fca85f7862c0797a527ab01ac8b0c1
|
@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btree.c,v 1.435 2008/01/01 06:19:02 danielk1977 Exp $
|
||||
** $Id: btree.c,v 1.436 2008/01/02 11:50:51 danielk1977 Exp $
|
||||
**
|
||||
** This file implements a external (disk-based) database using BTrees.
|
||||
** See the header comment on "btreeInt.h" for additional information.
|
||||
@ -6229,7 +6229,9 @@ int sqlite3BtreeFlags(BtCursor *pCur){
|
||||
/* TODO: What about CURSOR_REQUIRESEEK state? Probably need to call
|
||||
** restoreOrClearCursorPosition() here.
|
||||
*/
|
||||
MemPage *pPage = pCur->pPage;
|
||||
MemPage *pPage;
|
||||
restoreOrClearCursorPosition(pCur);
|
||||
pPage = pCur->pPage;
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pPage->pBt==pCur->pBt );
|
||||
return pPage ? pPage->aData[pPage->hdrOffset] : 0;
|
||||
|
54
src/delete.c
54
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.136 2008/01/02 00:34:37 drh Exp $
|
||||
** $Id: delete.c,v 1.137 2008/01/02 11:50:51 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -175,6 +175,9 @@ void sqlite3DeleteFrom(
|
||||
*/
|
||||
assert( pTabList->nSrc==1 );
|
||||
iCur = pTabList->a[0].iCursor = pParse->nTab++;
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
pParse->nTab++;
|
||||
}
|
||||
memset(&sNC, 0, sizeof(sNC));
|
||||
sNC.pParse = pParse;
|
||||
sNC.pSrcList = pTabList;
|
||||
@ -293,19 +296,26 @@ void sqlite3DeleteFrom(
|
||||
*/
|
||||
end = sqlite3VdbeMakeLabel(v);
|
||||
|
||||
/* This is the beginning of the delete loop when there are
|
||||
** row triggers.
|
||||
if( !isView ){
|
||||
/* Open cursors for the table we are deleting from and
|
||||
** all its indices.
|
||||
*/
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
|
||||
}
|
||||
|
||||
/* This is the beginning of the delete loop. If a trigger encounters
|
||||
** an IGNORE constraint, it jumps back to here.
|
||||
*/
|
||||
if( triggers_exist ){
|
||||
int mem1 = pParse->nMem++;
|
||||
int addr_rowdata;
|
||||
u32 mask;
|
||||
sqlite3VdbeResolveLabel(v, addr);
|
||||
addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);
|
||||
sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, mem1, 0);
|
||||
}
|
||||
addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);
|
||||
sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
|
||||
|
||||
if( triggers_exist ){
|
||||
int mem1 = pParse->nMem++;
|
||||
if( !isView ){
|
||||
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, mem1, 0);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
|
||||
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||
@ -329,21 +339,6 @@ void sqlite3DeleteFrom(
|
||||
}
|
||||
|
||||
if( !isView ){
|
||||
/* Open cursors for the table we are deleting from and all its
|
||||
** indices. If there are row triggers, this happens inside the
|
||||
** OP_FifoRead loop because the cursor have to all be closed
|
||||
** before the trigger fires. If there are no row triggers, the
|
||||
** cursors are opened only once on the outside the loop.
|
||||
*/
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
|
||||
|
||||
/* This is the beginning of the delete loop when there are no
|
||||
** row triggers */
|
||||
if( !triggers_exist ){
|
||||
addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, end);
|
||||
sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
|
||||
}
|
||||
|
||||
/* Delete the row */
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( IsVirtual(pTab) ){
|
||||
@ -360,13 +355,6 @@ void sqlite3DeleteFrom(
|
||||
** the AFTER triggers
|
||||
*/
|
||||
if( triggers_exist ){
|
||||
if( !isView ){
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}
|
||||
|
||||
/* Jump back and run the AFTER triggers */
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iBeginAfterTrigger);
|
||||
sqlite3VdbeJumpHere(v, iEndAfterTrigger);
|
||||
@ -377,7 +365,7 @@ void sqlite3DeleteFrom(
|
||||
sqlite3VdbeResolveLabel(v, end);
|
||||
|
||||
/* Close the cursors after the loop if there are no row triggers */
|
||||
if( !triggers_exist && !IsVirtual(pTab) ){
|
||||
if( !isView && !IsVirtual(pTab) ){
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
|
||||
}
|
||||
|
24
src/insert.c
24
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.199 2008/01/02 00:34:37 drh Exp $
|
||||
** $Id: insert.c,v 1.200 2008/01/02 11:50:51 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -625,8 +625,8 @@ void sqlite3Insert(
|
||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, iCntMem);
|
||||
}
|
||||
|
||||
/* Open tables and indices if there are no row triggers */
|
||||
if( !triggers_exist ){
|
||||
/* If this is not a view, open the table and and all indices */
|
||||
if( !isView ){
|
||||
base = pParse->nTab;
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite);
|
||||
}
|
||||
@ -713,14 +713,6 @@ void sqlite3Insert(
|
||||
}
|
||||
}
|
||||
|
||||
/* If any triggers exists, the opening of tables and indices is deferred
|
||||
** until now.
|
||||
*/
|
||||
if( triggers_exist && !isView ){
|
||||
base = pParse->nTab;
|
||||
sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite);
|
||||
}
|
||||
|
||||
/* Push the record number for the new entry onto the stack. The
|
||||
** record number is a randomly generate integer created by NewRowid
|
||||
** except when the table has an INTEGER PRIMARY KEY column, in which
|
||||
@ -827,14 +819,6 @@ void sqlite3Insert(
|
||||
}
|
||||
|
||||
if( triggers_exist ){
|
||||
/* Close all tables opened */
|
||||
if( !isView ){
|
||||
sqlite3VdbeAddOp(v, OP_Close, base, 0);
|
||||
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
||||
sqlite3VdbeAddOp(v, OP_Close, idx+base, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Code AFTER triggers */
|
||||
if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_AFTER, pTab,
|
||||
newIdx, -1, onError, endOfLoop, 0, 0) ){
|
||||
@ -855,7 +839,7 @@ void sqlite3Insert(
|
||||
sqlite3VdbeResolveLabel(v, iCleanup);
|
||||
}
|
||||
|
||||
if( !triggers_exist && !IsVirtual(pTab) ){
|
||||
if( !IsVirtual(pTab) && !isView ){
|
||||
/* Close all tables opened */
|
||||
sqlite3VdbeAddOp(v, OP_Close, base, 0);
|
||||
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
||||
|
131
src/update.c
131
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.146 2008/01/02 00:34:37 drh Exp $
|
||||
** $Id: update.c,v 1.147 2008/01/02 11:50:51 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -298,7 +298,16 @@ void sqlite3Update(
|
||||
/* Generate the code for triggers.
|
||||
*/
|
||||
if( triggers_exist ){
|
||||
int iGoto = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
||||
int iGoto;
|
||||
|
||||
/* Create pseudo-tables for NEW and OLD
|
||||
*/
|
||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
|
||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);
|
||||
|
||||
iGoto = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
||||
addr = sqlite3VdbeMakeLabel(v);
|
||||
iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v);
|
||||
if( sqlite3CodeRowTrigger(pParse, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab,
|
||||
@ -347,27 +356,50 @@ void sqlite3Update(
|
||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt);
|
||||
}
|
||||
|
||||
if( triggers_exist ){
|
||||
/* Create pseudo-tables for NEW and OLD
|
||||
if( !isView && !IsVirtual(pTab) ){
|
||||
/*
|
||||
** Open every index that needs updating. Note that if any
|
||||
** index could potentially invoke a REPLACE conflict resolution
|
||||
** action, then we need to open all indices because we might need
|
||||
** to be deleting some records.
|
||||
*/
|
||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol);
|
||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);
|
||||
|
||||
/* The top of the update loop for when there are triggers.
|
||||
*/
|
||||
sqlite3VdbeResolveLabel(v, addr);
|
||||
addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, mem1, 0);
|
||||
|
||||
if( !isView ){
|
||||
/* Open a cursor and make it point to the record that is
|
||||
** being updated.
|
||||
*/
|
||||
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
|
||||
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite);
|
||||
if( onError==OE_Replace ){
|
||||
openAll = 1;
|
||||
}else{
|
||||
openAll = 0;
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
if( pIdx->onError==OE_Replace ){
|
||||
openAll = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
if( openAll || aIdxUsed[i] ){
|
||||
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
||||
sqlite3VdbeOp3(v, OP_OpenWrite, iCur+i+1, pIdx->tnum,
|
||||
(char*)pKey, P3_KEYINFO_HANDOFF);
|
||||
assert( pParse->nTab>iCur+i+1 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Jump back to this point if a trigger encounters an IGNORE constraint. */
|
||||
if( triggers_exist ){
|
||||
sqlite3VdbeResolveLabel(v, addr);
|
||||
}
|
||||
|
||||
/* Top of the update loop */
|
||||
addr = sqlite3VdbeAddOp(v, OP_FifoRead, 0, 0);
|
||||
sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, mem1, 0);
|
||||
|
||||
if( triggers_exist ){
|
||||
/* Make cursor iCur point to the record that is being updated.
|
||||
*/
|
||||
sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
|
||||
|
||||
/* Generate the OLD table
|
||||
@ -410,9 +442,6 @@ void sqlite3Update(
|
||||
}
|
||||
if( pParse->nErr ) goto update_cleanup;
|
||||
sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
|
||||
if( !isView ){
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}
|
||||
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iBeginBeforeTrigger);
|
||||
sqlite3VdbeJumpHere(v, iEndBeforeTrigger);
|
||||
@ -423,33 +452,6 @@ void sqlite3Update(
|
||||
}
|
||||
|
||||
if( !isView && !IsVirtual(pTab) ){
|
||||
/*
|
||||
** Open every index that needs updating. Note that if any
|
||||
** index could potentially invoke a REPLACE conflict resolution
|
||||
** action, then we need to open all indices because we might need
|
||||
** to be deleting some records.
|
||||
*/
|
||||
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite);
|
||||
if( onError==OE_Replace ){
|
||||
openAll = 1;
|
||||
}else{
|
||||
openAll = 0;
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
if( pIdx->onError==OE_Replace ){
|
||||
openAll = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
if( openAll || aIdxUsed[i] ){
|
||||
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
||||
sqlite3VdbeOp3(v, OP_OpenWrite, iCur+i+1, pIdx->tnum,
|
||||
(char*)pKey, P3_KEYINFO_HANDOFF);
|
||||
assert( pParse->nTab>iCur+i+1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop over every record that needs updating. We have to load
|
||||
** the old data for each record to be updated because some columns
|
||||
@ -457,11 +459,6 @@ void sqlite3Update(
|
||||
** Also, the old data is needed to delete the old index entries.
|
||||
** 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_MemStore, mem1, 0);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_NotExists, iCur, addr);
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, mem1, 0);
|
||||
|
||||
@ -520,13 +517,6 @@ void sqlite3Update(
|
||||
** through the loop. The fire the after triggers.
|
||||
*/
|
||||
if( triggers_exist ){
|
||||
if( !isView ){
|
||||
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
if( openAll || aIdxUsed[i] )
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iBeginAfterTrigger);
|
||||
sqlite3VdbeJumpHere(v, iEndAfterTrigger);
|
||||
}
|
||||
@ -537,15 +527,14 @@ void sqlite3Update(
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addr);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
|
||||
/* Close all tables if there were no FOR EACH ROW triggers */
|
||||
if( !triggers_exist ){
|
||||
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
if( openAll || aIdxUsed[i] ){
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
|
||||
}
|
||||
/* Close all tables */
|
||||
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
if( openAll || aIdxUsed[i] ){
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur+i+1, 0);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
}else{
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
if( triggers_exist ){
|
||||
sqlite3VdbeAddOp(v, OP_Close, newIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, oldIdx, 0);
|
||||
}
|
||||
|
@ -701,10 +701,12 @@ static char *displayP3(Op *pOp, char *zTemp, int nTemp){
|
||||
}
|
||||
}
|
||||
assert( zP3!=0 );
|
||||
#ifdef SQLITE_DEBUG
|
||||
if( pOp->zComment && zP3==zTemp && (nP3 = strlen(zP3))<nTemp ){
|
||||
sqlite3_snprintf(nTemp-nP3, &zP3[nP3], "%s# %s",
|
||||
nP3>0 ? " " : "", pOp->zComment);
|
||||
}
|
||||
#endif
|
||||
return zP3;
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user