mirror of
				https://github.com/sqlite/sqlite.git
				synced 2025-11-03 16:53:36 +03:00 
			
		
		
		
	Prevent an infinite loop when deleting a table that has a TEMP trigger. (CVS 984)
FossilOrigin-Name: c8c823b068916711857fa67db10fb479999b55c2
This commit is contained in:
		
							
								
								
									
										20
									
								
								manifest
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								manifest
									
									
									
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
C Version\s2.8.2\s(CVS\s983)
 | 
					C Prevent\san\sinfinite\sloop\swhen\sdeleting\sa\stable\sthat\shas\sa\sTEMP\strigger.\s(CVS\s984)
 | 
				
			||||||
D 2003-05-17T17:52:34
 | 
					D 2003-05-17T19:04:04
 | 
				
			||||||
F Makefile.in 1ff85c27d4350c74118341024e8a4fb2a04a3a43
 | 
					F Makefile.in 1ff85c27d4350c74118341024e8a4fb2a04a3a43
 | 
				
			||||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 | 
					F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 | 
				
			||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
 | 
					F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
 | 
				
			||||||
@@ -24,7 +24,7 @@ F src/auth.c c8f50d4507e37779d96ff3c55417bc2b612dfed6
 | 
				
			|||||||
F src/btree.c 8092dca45dcdb69c61273db0213cbb85760673c7
 | 
					F src/btree.c 8092dca45dcdb69c61273db0213cbb85760673c7
 | 
				
			||||||
F src/btree.h 23c50e00709de16a5dce1fcea9c0429cc955ff0e
 | 
					F src/btree.h 23c50e00709de16a5dce1fcea9c0429cc955ff0e
 | 
				
			||||||
F src/btree_rb.c 1d809e703aab8bef916ebb0b6ba9254a1c36d9a6
 | 
					F src/btree_rb.c 1d809e703aab8bef916ebb0b6ba9254a1c36d9a6
 | 
				
			||||||
F src/build.c 95dfb188f448e6299108396546a8333ecdcb1716
 | 
					F src/build.c 3f5d1798e40020e3a038dbe058406f665b4a51a4
 | 
				
			||||||
F src/copy.c 5e5d558d283536592cd67b5dc1519c3152bd7e20
 | 
					F src/copy.c 5e5d558d283536592cd67b5dc1519c3152bd7e20
 | 
				
			||||||
F src/delete.c 0f81e6799c089487615d38e042a2de4d2d6192bc
 | 
					F src/delete.c 0f81e6799c089487615d38e042a2de4d2d6192bc
 | 
				
			||||||
F src/encode.c ed720e54ec4ef4d4de651592f1dd1c74d422bbd2
 | 
					F src/encode.c ed720e54ec4ef4d4de651592f1dd1c74d422bbd2
 | 
				
			||||||
@@ -39,7 +39,7 @@ F src/os.c 94b618c0c0a76210e53857d77c96d2f042dc33b1
 | 
				
			|||||||
F src/os.h 9e5bbddff123187295e3d00d49af06192cd1cd49
 | 
					F src/os.h 9e5bbddff123187295e3d00d49af06192cd1cd49
 | 
				
			||||||
F src/pager.c 51fdfda63e2d8c01fff8f7fe0c49f2636d5b1321
 | 
					F src/pager.c 51fdfda63e2d8c01fff8f7fe0c49f2636d5b1321
 | 
				
			||||||
F src/pager.h 5da62c83443f26b1792cfd72c96c422f91aadd31
 | 
					F src/pager.h 5da62c83443f26b1792cfd72c96c422f91aadd31
 | 
				
			||||||
F src/parse.y 39b5240cb78047dc56d6d37c398baed7ba556779
 | 
					F src/parse.y 917250e5d86bdee752355e6617ea2e8ee12438bf
 | 
				
			||||||
F src/pragma.c ec64704e61286948f39157617f1ce2f506dd1b74
 | 
					F src/pragma.c ec64704e61286948f39157617f1ce2f506dd1b74
 | 
				
			||||||
F src/printf.c fc5fdef6e92ad205005263661fe9716f55a49f3e
 | 
					F src/printf.c fc5fdef6e92ad205005263661fe9716f55a49f3e
 | 
				
			||||||
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
 | 
					F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
 | 
				
			||||||
@@ -47,7 +47,7 @@ F src/select.c 15d921308065c9320363af6f43c01d9f09ea7118
 | 
				
			|||||||
F src/shell.c 2565cb32cd862024bcfd88400e05437636cf21a1
 | 
					F src/shell.c 2565cb32cd862024bcfd88400e05437636cf21a1
 | 
				
			||||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
 | 
					F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
 | 
				
			||||||
F src/sqlite.h.in eec06462cba262c0ee03f38462a18a4bc66dda4e
 | 
					F src/sqlite.h.in eec06462cba262c0ee03f38462a18a4bc66dda4e
 | 
				
			||||||
F src/sqliteInt.h cab919e43875a561603ca6e0d060fd0690c2ee7c
 | 
					F src/sqliteInt.h 3ba355793a1e0b891cfa414901759189c9287a18
 | 
				
			||||||
F src/table.c 4301926464d88d2c2c7cd21c3360aa75bf068b95
 | 
					F src/table.c 4301926464d88d2c2c7cd21c3360aa75bf068b95
 | 
				
			||||||
F src/tclsqlite.c 9e25f98f1765afa0716144ef57abda75c88f688d
 | 
					F src/tclsqlite.c 9e25f98f1765afa0716144ef57abda75c88f688d
 | 
				
			||||||
F src/test1.c 4596acd9d9f2a49fda0160a8a6dee5bfc7c6c325
 | 
					F src/test1.c 4596acd9d9f2a49fda0160a8a6dee5bfc7c6c325
 | 
				
			||||||
@@ -55,7 +55,7 @@ F src/test2.c 5014337d8576b731cce5b5a14bec4f0daf432700
 | 
				
			|||||||
F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5
 | 
					F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5
 | 
				
			||||||
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
 | 
					F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
 | 
				
			||||||
F src/tokenize.c 2ba93fe10d5f57f0cc20b07417c3244a30c324b3
 | 
					F src/tokenize.c 2ba93fe10d5f57f0cc20b07417c3244a30c324b3
 | 
				
			||||||
F src/trigger.c 8ee811986080de60d9d883ad96daffea82014f27
 | 
					F src/trigger.c 7607b209e6de07371e94f3266a850562f522297e
 | 
				
			||||||
F src/update.c 8e657c7b3d27b5592d8caa362d9c4765e0b3cd6a
 | 
					F src/update.c 8e657c7b3d27b5592d8caa362d9c4765e0b3cd6a
 | 
				
			||||||
F src/util.c 8065b78806a5132119452d9e0417cf071e6f02f9
 | 
					F src/util.c 8065b78806a5132119452d9e0417cf071e6f02f9
 | 
				
			||||||
F src/vacuum.c 0820984615786c9ccdaad8032a792309b354a8eb
 | 
					F src/vacuum.c 0820984615786c9ccdaad8032a792309b354a8eb
 | 
				
			||||||
@@ -119,7 +119,7 @@ F test/tclsqlite.test d9bdfc0afca9ee605c50ecb39e94ae4dea8c222b
 | 
				
			|||||||
F test/temptable.test c82bd6f800f10e8cf96921af6315e5f1c21e2692
 | 
					F test/temptable.test c82bd6f800f10e8cf96921af6315e5f1c21e2692
 | 
				
			||||||
F test/tester.tcl d7a5835edaf118539241145d8188f0822b673488
 | 
					F test/tester.tcl d7a5835edaf118539241145d8188f0822b673488
 | 
				
			||||||
F test/trans.test 75e7a171b5d2d94ee56766459113e2ad0e5f809d
 | 
					F test/trans.test 75e7a171b5d2d94ee56766459113e2ad0e5f809d
 | 
				
			||||||
F test/trigger1.test 61ef41666f066ac417730dc26056053a7c36cd11
 | 
					F test/trigger1.test 589fb8f3015613b1158736e9a29771efbbe989dd
 | 
				
			||||||
F test/trigger2.test 00ceb8aff6bddd511bbac7c837af2863fa0c9cb4
 | 
					F test/trigger2.test 00ceb8aff6bddd511bbac7c837af2863fa0c9cb4
 | 
				
			||||||
F test/trigger3.test 870afef7997a5b86bf3ea893ce0c2e85d6356c72
 | 
					F test/trigger3.test 870afef7997a5b86bf3ea893ce0c2e85d6356c72
 | 
				
			||||||
F test/trigger4.test 9a5c1406344d743020c2753ae8d6dfe6eb75f818
 | 
					F test/trigger4.test 9a5c1406344d743020c2753ae8d6dfe6eb75f818
 | 
				
			||||||
@@ -165,7 +165,7 @@ F www/speed.tcl cb4c10a722614aea76d2c51f32ee43400d5951be
 | 
				
			|||||||
F www/sqlite.tcl 4bd1729e320f5fa9125f0022b281fbe839192125
 | 
					F www/sqlite.tcl 4bd1729e320f5fa9125f0022b281fbe839192125
 | 
				
			||||||
F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 | 
					F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 | 
				
			||||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
 | 
					F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
 | 
				
			||||||
P e134459d653b03bfacb98eec2c5d91eef7e4ed24
 | 
					P f542e5fc8896111e5165cc625607f95e4993bb16
 | 
				
			||||||
R 9ef2fffc5f0c5816e46decff70d83cb0
 | 
					R fa932d99cd2f240b0dbcaa691638c769
 | 
				
			||||||
U drh
 | 
					U drh
 | 
				
			||||||
Z 035b9ad097ef44ba8b7f0d2886016b52
 | 
					Z c96cb30883171b8cc67337276b3d728f
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
f542e5fc8896111e5165cc625607f95e4993bb16
 | 
					c8c823b068916711857fa67db10fb479999b55c2
 | 
				
			||||||
@@ -23,7 +23,7 @@
 | 
				
			|||||||
**     ROLLBACK
 | 
					**     ROLLBACK
 | 
				
			||||||
**     PRAGMA
 | 
					**     PRAGMA
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** $Id: build.c,v 1.153 2003/05/17 17:35:11 drh Exp $
 | 
					** $Id: build.c,v 1.154 2003/05/17 19:04:04 drh Exp $
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#include "sqliteInt.h"
 | 
					#include "sqliteInt.h"
 | 
				
			||||||
#include <ctype.h>
 | 
					#include <ctype.h>
 | 
				
			||||||
@@ -1297,12 +1297,8 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){
 | 
				
			|||||||
    /* Drop all triggers associated with the table being dropped */
 | 
					    /* Drop all triggers associated with the table being dropped */
 | 
				
			||||||
    pTrigger = pTable->pTrigger;
 | 
					    pTrigger = pTable->pTrigger;
 | 
				
			||||||
    while( pTrigger ){
 | 
					    while( pTrigger ){
 | 
				
			||||||
      SrcList *pNm;
 | 
					 | 
				
			||||||
      assert( pTrigger->iDb==pTable->iDb || pTrigger->iDb==1 );
 | 
					      assert( pTrigger->iDb==pTable->iDb || pTrigger->iDb==1 );
 | 
				
			||||||
      pNm = sqliteSrcListAppend(0, 0, 0);
 | 
					      sqliteDropTriggerPtr(pParse, pTrigger, 1);
 | 
				
			||||||
      pNm->a[0].zName = sqliteStrDup(pTrigger->name);
 | 
					 | 
				
			||||||
      pNm->a[0].zDatabase = sqliteStrDup(db->aDb[pTable->iDb].zName);
 | 
					 | 
				
			||||||
      sqliteDropTrigger(pParse, pNm, 1);
 | 
					 | 
				
			||||||
      if( pParse->explain ){
 | 
					      if( pParse->explain ){
 | 
				
			||||||
        pTrigger = pTrigger->pNext;
 | 
					        pTrigger = pTrigger->pNext;
 | 
				
			||||||
      }else{
 | 
					      }else{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@
 | 
				
			|||||||
** the parser.  Lemon will also generate a header file containing
 | 
					** the parser.  Lemon will also generate a header file containing
 | 
				
			||||||
** numeric codes for all of the tokens.
 | 
					** numeric codes for all of the tokens.
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** @(#) $Id: parse.y,v 1.97 2003/04/29 17:19:18 drh Exp $
 | 
					** @(#) $Id: parse.y,v 1.98 2003/05/17 19:04:04 drh Exp $
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
%token_prefix TK_
 | 
					%token_prefix TK_
 | 
				
			||||||
%token_type {Token}
 | 
					%token_type {Token}
 | 
				
			||||||
@@ -848,7 +848,7 @@ expr(A) ::= RAISE(X) LP FAIL COMMA nm(Z) RP(Y).  {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
////////////////////////  DROP TRIGGER statement //////////////////////////////
 | 
					////////////////////////  DROP TRIGGER statement //////////////////////////////
 | 
				
			||||||
cmd ::= DROP TRIGGER nm(X) dbnm(D). {
 | 
					cmd ::= DROP TRIGGER nm(X) dbnm(D). {
 | 
				
			||||||
  sqliteDropTrigger(pParse,sqliteSrcListAppend(0,&X,&D),0);
 | 
					  sqliteDropTrigger(pParse,sqliteSrcListAppend(0,&X,&D));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//////////////////////// ATTACH DATABASE file AS name /////////////////////////
 | 
					//////////////////////// ATTACH DATABASE file AS name /////////////////////////
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@
 | 
				
			|||||||
*************************************************************************
 | 
					*************************************************************************
 | 
				
			||||||
** Internal interface definitions for SQLite.
 | 
					** Internal interface definitions for SQLite.
 | 
				
			||||||
**
 | 
					**
 | 
				
			||||||
** @(#) $Id: sqliteInt.h,v 1.185 2003/05/17 17:35:12 drh Exp $
 | 
					** @(#) $Id: sqliteInt.h,v 1.186 2003/05/17 19:04:04 drh Exp $
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
#include "sqlite.h"
 | 
					#include "sqlite.h"
 | 
				
			||||||
@@ -893,6 +893,7 @@ struct Trigger {
 | 
				
			|||||||
  char *name;             /* The name of the trigger                        */
 | 
					  char *name;             /* The name of the trigger                        */
 | 
				
			||||||
  char *table;            /* The table or view to which the trigger applies */
 | 
					  char *table;            /* The table or view to which the trigger applies */
 | 
				
			||||||
  u8 iDb;                 /* Database containing this trigger               */
 | 
					  u8 iDb;                 /* Database containing this trigger               */
 | 
				
			||||||
 | 
					  u8 iTabDb;              /* Database containing Trigger.table              */
 | 
				
			||||||
  u8 op;                  /* One of TK_DELETE, TK_UPDATE, TK_INSERT         */
 | 
					  u8 op;                  /* One of TK_DELETE, TK_UPDATE, TK_INSERT         */
 | 
				
			||||||
  u8 tr_tm;               /* One of TK_BEFORE, TK_AFTER */
 | 
					  u8 tr_tm;               /* One of TK_BEFORE, TK_AFTER */
 | 
				
			||||||
  Expr *pWhen;            /* The WHEN clause of the expresion (may be NULL) */
 | 
					  Expr *pWhen;            /* The WHEN clause of the expresion (may be NULL) */
 | 
				
			||||||
@@ -1135,7 +1136,8 @@ int sqliteSafetyCheck(sqlite*);
 | 
				
			|||||||
void sqliteChangeCookie(sqlite*, Vdbe*);
 | 
					void sqliteChangeCookie(sqlite*, Vdbe*);
 | 
				
			||||||
void sqliteBeginTrigger(Parse*, Token*,int,int,IdList*,SrcList*,int,Expr*,int);
 | 
					void sqliteBeginTrigger(Parse*, Token*,int,int,IdList*,SrcList*,int,Expr*,int);
 | 
				
			||||||
void sqliteFinishTrigger(Parse*, TriggerStep*, Token*);
 | 
					void sqliteFinishTrigger(Parse*, TriggerStep*, Token*);
 | 
				
			||||||
void sqliteDropTrigger(Parse*, SrcList*, int);
 | 
					void sqliteDropTrigger(Parse*, SrcList*);
 | 
				
			||||||
 | 
					void sqliteDropTriggerPtr(Parse*, Trigger*, int);
 | 
				
			||||||
int sqliteTriggersExist(Parse* , Trigger* , int , int , int, ExprList*);
 | 
					int sqliteTriggersExist(Parse* , Trigger* , int , int , int, ExprList*);
 | 
				
			||||||
int sqliteCodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int, 
 | 
					int sqliteCodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int, 
 | 
				
			||||||
                         int, int);
 | 
					                         int, int);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -127,6 +127,7 @@ void sqliteBeginTrigger(
 | 
				
			|||||||
  nt->table = sqliteStrDup(pTableName->a[0].zName);
 | 
					  nt->table = sqliteStrDup(pTableName->a[0].zName);
 | 
				
			||||||
  if( sqlite_malloc_failed ) goto trigger_cleanup;
 | 
					  if( sqlite_malloc_failed ) goto trigger_cleanup;
 | 
				
			||||||
  nt->iDb = iDb;
 | 
					  nt->iDb = iDb;
 | 
				
			||||||
 | 
					  nt->iTabDb = tab->iDb;
 | 
				
			||||||
  nt->op = op;
 | 
					  nt->op = op;
 | 
				
			||||||
  nt->tr_tm = tr_tm;
 | 
					  nt->tr_tm = tr_tm;
 | 
				
			||||||
  nt->pWhen = sqliteExprDup(pWhen);
 | 
					  nt->pWhen = sqliteExprDup(pWhen);
 | 
				
			||||||
@@ -184,7 +185,7 @@ void sqliteFinishTrigger(
 | 
				
			|||||||
    v = sqliteGetVdbe(pParse);
 | 
					    v = sqliteGetVdbe(pParse);
 | 
				
			||||||
    if( v==0 ) goto triggerfinish_cleanup;
 | 
					    if( v==0 ) goto triggerfinish_cleanup;
 | 
				
			||||||
    sqliteBeginWriteOperation(pParse, 0, 0);
 | 
					    sqliteBeginWriteOperation(pParse, 0, 0);
 | 
				
			||||||
    sqliteOpenMasterTable(v, nt->iDb==1);
 | 
					    sqliteOpenMasterTable(v, nt->iDb);
 | 
				
			||||||
    addr = sqliteVdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
 | 
					    addr = sqliteVdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
 | 
				
			||||||
    sqliteVdbeChangeP3(v, addr+2, nt->name, 0); 
 | 
					    sqliteVdbeChangeP3(v, addr+2, nt->name, 0); 
 | 
				
			||||||
    sqliteVdbeChangeP3(v, addr+3, nt->table, 0); 
 | 
					    sqliteVdbeChangeP3(v, addr+3, nt->table, 0); 
 | 
				
			||||||
@@ -359,18 +360,18 @@ void sqliteDeleteTrigger(Trigger *pTrigger){
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * This function is called to drop a trigger from the database schema. 
 | 
					 * This function is called to drop a trigger from the database schema. 
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This may be called directly from the parser, or from within 
 | 
					 * This may be called directly from the parser and therefore identifies
 | 
				
			||||||
 * sqliteDropTable(). In the latter case the "nested" argument is true.
 | 
					 * the trigger by name.  The sqliteDropTriggerPtr() routine does the
 | 
				
			||||||
 | 
					 * same job as this routine except it take a spointer to the trigger
 | 
				
			||||||
 | 
					 * instead of the trigger name.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Note that this function does not delete the trigger entirely. Instead it
 | 
					 * Note that this function does not delete the trigger entirely. Instead it
 | 
				
			||||||
 * removes it from the internal schema and places it in the trigDrop hash 
 | 
					 * removes it from the internal schema and places it in the trigDrop hash 
 | 
				
			||||||
 * table. This is so that the trigger can be restored into the database schema
 | 
					 * table. This is so that the trigger can be restored into the database schema
 | 
				
			||||||
 * if the transaction is rolled back.
 | 
					 * if the transaction is rolled back.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void sqliteDropTrigger(Parse *pParse, SrcList *pName, int nested){
 | 
					void sqliteDropTrigger(Parse *pParse, SrcList *pName){
 | 
				
			||||||
  Trigger *pTrigger;
 | 
					  Trigger *pTrigger;
 | 
				
			||||||
  Table   *pTable;
 | 
					 | 
				
			||||||
  Vdbe *v;
 | 
					 | 
				
			||||||
  int i;
 | 
					  int i;
 | 
				
			||||||
  const char *zDb;
 | 
					  const char *zDb;
 | 
				
			||||||
  const char *zName;
 | 
					  const char *zName;
 | 
				
			||||||
@@ -392,13 +393,29 @@ void sqliteDropTrigger(Parse *pParse, SrcList *pName, int nested){
 | 
				
			|||||||
    sqliteErrorMsg(pParse, "no such trigger: %S", pName, 0);
 | 
					    sqliteErrorMsg(pParse, "no such trigger: %S", pName, 0);
 | 
				
			||||||
    goto drop_trigger_cleanup;
 | 
					    goto drop_trigger_cleanup;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  sqliteDropTriggerPtr(pParse, pTrigger, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					drop_trigger_cleanup:
 | 
				
			||||||
 | 
					  sqliteSrcListDelete(pName);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					** Drop a trigger given a pointer to that trigger.  If nested is false,
 | 
				
			||||||
 | 
					** then also generate code to remove the trigger from the SQLITE_MASTER
 | 
				
			||||||
 | 
					** table.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					void sqliteDropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
 | 
				
			||||||
 | 
					  Table   *pTable;
 | 
				
			||||||
 | 
					  Vdbe *v;
 | 
				
			||||||
 | 
					  sqlite *db = pParse->db;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  assert( pTrigger->iDb<db->nDb );
 | 
					  assert( pTrigger->iDb<db->nDb );
 | 
				
			||||||
  if( pTrigger->iDb>=2 ){
 | 
					  if( pTrigger->iDb>=2 ){
 | 
				
			||||||
    sqliteErrorMsg(pParse, "triggers may not be removed from "
 | 
					    sqliteErrorMsg(pParse, "triggers may not be removed from "
 | 
				
			||||||
       "auxiliary database %s", db->aDb[pTrigger->iDb].zName);
 | 
					       "auxiliary database %s", db->aDb[pTrigger->iDb].zName);
 | 
				
			||||||
    goto drop_trigger_cleanup;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  pTable = sqliteFindTable(db, pTrigger->table, db->aDb[pTrigger->iDb].zName);
 | 
					  pTable = sqliteFindTable(db, pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
 | 
				
			||||||
  assert(pTable);
 | 
					  assert(pTable);
 | 
				
			||||||
  assert( pTable->iDb==pTrigger->iDb || pTrigger->iDb==1 );
 | 
					  assert( pTable->iDb==pTrigger->iDb || pTrigger->iDb==1 );
 | 
				
			||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
 | 
					#ifndef SQLITE_OMIT_AUTHORIZATION
 | 
				
			||||||
@@ -409,7 +426,7 @@ void sqliteDropTrigger(Parse *pParse, SrcList *pName, int nested){
 | 
				
			|||||||
    if( pTrigger->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
 | 
					    if( pTrigger->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
 | 
				
			||||||
    if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
 | 
					    if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
 | 
				
			||||||
      sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
 | 
					      sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
 | 
				
			||||||
      goto drop_trigger_cleanup;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -432,7 +449,7 @@ void sqliteDropTrigger(Parse *pParse, SrcList *pName, int nested){
 | 
				
			|||||||
    sqliteBeginWriteOperation(pParse, 0, 0);
 | 
					    sqliteBeginWriteOperation(pParse, 0, 0);
 | 
				
			||||||
    sqliteOpenMasterTable(v, pTrigger->iDb);
 | 
					    sqliteOpenMasterTable(v, pTrigger->iDb);
 | 
				
			||||||
    base = sqliteVdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
 | 
					    base = sqliteVdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
 | 
				
			||||||
    sqliteVdbeChangeP3(v, base+1, zName, 0);
 | 
					    sqliteVdbeChangeP3(v, base+1, pTrigger->name, 0);
 | 
				
			||||||
    if( pTrigger->iDb==0 ){
 | 
					    if( pTrigger->iDb==0 ){
 | 
				
			||||||
      sqliteChangeCookie(db, v);
 | 
					      sqliteChangeCookie(db, v);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -444,6 +461,8 @@ void sqliteDropTrigger(Parse *pParse, SrcList *pName, int nested){
 | 
				
			|||||||
   * If this is not an "explain", then delete the trigger structure.
 | 
					   * If this is not an "explain", then delete the trigger structure.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  if( !pParse->explain ){
 | 
					  if( !pParse->explain ){
 | 
				
			||||||
 | 
					    const char *zName = pTrigger->name;
 | 
				
			||||||
 | 
					    int nName = strlen(zName);
 | 
				
			||||||
    if( pTable->pTrigger == pTrigger ){
 | 
					    if( pTable->pTrigger == pTrigger ){
 | 
				
			||||||
      pTable->pTrigger = pTrigger->pNext;
 | 
					      pTable->pTrigger = pTrigger->pNext;
 | 
				
			||||||
    }else{
 | 
					    }else{
 | 
				
			||||||
@@ -460,9 +479,6 @@ void sqliteDropTrigger(Parse *pParse, SrcList *pName, int nested){
 | 
				
			|||||||
    sqliteHashInsert(&(db->aDb[pTrigger->iDb].trigHash), zName, nName+1, 0);
 | 
					    sqliteHashInsert(&(db->aDb[pTrigger->iDb].trigHash), zName, nName+1, 0);
 | 
				
			||||||
    sqliteDeleteTrigger(pTrigger);
 | 
					    sqliteDeleteTrigger(pTrigger);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
drop_trigger_cleanup:
 | 
					 | 
				
			||||||
  sqliteSrcListDelete(pName);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,13 +30,20 @@
 | 
				
			|||||||
set testdir [file dirname $argv0]
 | 
					set testdir [file dirname $argv0]
 | 
				
			||||||
source $testdir/tester.tcl
 | 
					source $testdir/tester.tcl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
do_test trigger1-1.1 {
 | 
					do_test trigger1-1.1.2 {
 | 
				
			||||||
   catchsql {
 | 
					   catchsql {
 | 
				
			||||||
     CREATE TRIGGER trig UPDATE ON no_such_table BEGIN
 | 
					     CREATE TRIGGER trig UPDATE ON no_such_table BEGIN
 | 
				
			||||||
       SELECT * from sqlite_master;
 | 
					       SELECT * from sqlite_master;
 | 
				
			||||||
     END;
 | 
					     END;
 | 
				
			||||||
   } 
 | 
					   } 
 | 
				
			||||||
} {1 {no such table: no_such_table}}
 | 
					} {1 {no such table: no_such_table}}
 | 
				
			||||||
 | 
					do_test trigger1-1.1.2 {
 | 
				
			||||||
 | 
					   catchsql {
 | 
				
			||||||
 | 
					     CREATE TEMP TRIGGER trig UPDATE ON no_such_table BEGIN
 | 
				
			||||||
 | 
					       SELECT * from sqlite_master;
 | 
				
			||||||
 | 
					     END;
 | 
				
			||||||
 | 
					   } 
 | 
				
			||||||
 | 
					} {1 {no such table: no_such_table}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
execsql {
 | 
					execsql {
 | 
				
			||||||
    CREATE TABLE t1(a);
 | 
					    CREATE TABLE t1(a);
 | 
				
			||||||
@@ -267,4 +274,38 @@ do_test trigger-3.9 {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
} {1 2 3 4 5 6 3 4}
 | 
					} {1 2 3 4 5 6 3 4}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					do_test trigger-4.1 {
 | 
				
			||||||
 | 
					  execsql {
 | 
				
			||||||
 | 
					    CREATE TEMP TRIGGER r1 BEFORE INSERT ON t1 BEGIN
 | 
				
			||||||
 | 
					      INSERT INTO t2 VALUES(NEW.a,NEW.b);
 | 
				
			||||||
 | 
					    END;
 | 
				
			||||||
 | 
					    INSERT INTO t1 VALUES(7,8);
 | 
				
			||||||
 | 
					    SELECT * FROM t2;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					} {3 4 7 8}
 | 
				
			||||||
 | 
					do_test trigger-4.2 {
 | 
				
			||||||
 | 
					  sqlite db2 test.db
 | 
				
			||||||
 | 
					  execsql {
 | 
				
			||||||
 | 
					    INSERT INTO t1 VALUES(9,10);
 | 
				
			||||||
 | 
					  } db2;
 | 
				
			||||||
 | 
					  db2 close
 | 
				
			||||||
 | 
					  execsql {
 | 
				
			||||||
 | 
					    SELECT * FROM t2;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					} {3 4 7 8}
 | 
				
			||||||
 | 
					do_test trigger-4.3 {
 | 
				
			||||||
 | 
					  execsql {
 | 
				
			||||||
 | 
					    DROP TABLE t1;
 | 
				
			||||||
 | 
					    SELECT * FROM t2;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					} {3 4 7 8}
 | 
				
			||||||
 | 
					do_test trigger-4.4 {
 | 
				
			||||||
 | 
					  db close
 | 
				
			||||||
 | 
					  sqlite db test.db
 | 
				
			||||||
 | 
					  execsql {
 | 
				
			||||||
 | 
					    SELECT * FROM t2;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					} {3 4 7 8}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
finish_test
 | 
					finish_test
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user