1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-19 21:43:15 +03:00

Added FOR EACH ROW triggers functionality (CVS 562)

FossilOrigin-Name: 794bf67b6b36fce8854d5daff12f21dbb943240c
This commit is contained in:
danielk1977
2002-05-15 08:30:12 +00:00
parent 9456bcc975
commit c3f9bad209
18 changed files with 2239 additions and 125 deletions

View File

@@ -25,7 +25,7 @@
** ROLLBACK
** PRAGMA
**
** $Id: build.c,v 1.87 2002/05/08 21:30:15 drh Exp $
** $Id: build.c,v 1.88 2002/05/15 08:30:13 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -250,6 +250,22 @@ void sqliteCommitInternalChanges(sqlite *db){
sqliteUnlinkAndDeleteIndex(db, pIndex);
}
sqliteHashClear(&db->idxDrop);
/* Set the commit flag on all triggers added this transaction */
for(pElem=sqliteHashFirst(&db->trigHash); pElem; pElem=sqliteHashNext(pElem)){
Trigger *pTrigger = sqliteHashData(pElem);
pTrigger->isCommit = 1;
}
/* Delete the structures for triggers removed this transaction */
pElem = sqliteHashFirst(&db->trigDrop);
while (pElem) {
Trigger *pTrigger = sqliteHashData(pElem);
sqliteDeleteTrigger(pTrigger);
pElem = sqliteHashNext(pElem);
}
sqliteHashClear(&db->trigDrop);
db->flags &= ~SQLITE_InternChanges;
}
@@ -304,6 +320,48 @@ void sqliteRollbackInternalChanges(sqlite *db){
assert( pOld==0 || pOld==p );
}
sqliteHashClear(&db->idxDrop);
/* Remove any triggers that haven't been commited yet */
for(pElem = sqliteHashFirst(&db->trigHash); pElem;
pElem = (pElem?sqliteHashNext(pElem):0)) {
Trigger * pTrigger = sqliteHashData(pElem);
if (!pTrigger->isCommit) {
Table * tbl = sqliteFindTable(db, pTrigger->table);
if (tbl) {
if (tbl->pTrigger == pTrigger)
tbl->pTrigger = pTrigger->pNext;
else {
Trigger * cc = tbl->pTrigger;
while (cc) {
if (cc->pNext == pTrigger) {
cc->pNext = cc->pNext->pNext;
break;
}
cc = cc->pNext;
}
assert(cc);
}
}
sqliteHashInsert(&db->trigHash, pTrigger->name,
1 + strlen(pTrigger->name), 0);
sqliteDeleteTrigger(pTrigger);
pElem = sqliteHashFirst(&db->trigHash);
}
}
/* Any triggers that were dropped - put 'em back in place */
for(pElem = sqliteHashFirst(&db->trigDrop); pElem;
pElem = sqliteHashNext(pElem)) {
Trigger * pTrigger = sqliteHashData(pElem);
Table * tab = sqliteFindTable(db, pTrigger->table);
sqliteHashInsert(&db->trigHash, pTrigger->name,
strlen(pTrigger->name) + 1, pTrigger);
pTrigger->pNext = tab->pTrigger;
tab->pTrigger = pTrigger;
}
sqliteHashClear(&db->trigDrop);
db->flags &= ~SQLITE_InternChanges;
}
@@ -595,7 +653,7 @@ void sqliteAddPrimaryKey(Parse *pParse, IdList *pList, int onError){
** and the probability of hitting the same cookie value is only
** 1 chance in 2^32. So we're safe enough.
*/
static void changeCookie(sqlite *db){
void changeCookie(sqlite *db){
if( db->next_cookie==db->schema_cookie ){
db->next_cookie = db->schema_cookie + sqliteRandomByte() + 1;
db->flags |= SQLITE_InternChanges;
@@ -1036,6 +1094,13 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){
};
Index *pIdx;
sqliteBeginWriteOperation(pParse);
/* Drop all triggers associated with the table being dropped */
while (pTable->pTrigger) {
Token tt;
tt.z = pTable->pTrigger->name;
tt.n = strlen(pTable->pTrigger->name);
sqliteDropTrigger(pParse, &tt, 1);
}
if( !pTable->isTemp ){
base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
sqliteVdbeChangeP3(v, base+2, pTable->zName, 0);
@@ -1653,6 +1718,7 @@ void sqliteBeginWriteOperation(Parse *pParse){
Vdbe *v;
v = sqliteGetVdbe(pParse);
if( v==0 ) return;
if (pParse->trigStack) return; /* if this is in a trigger */
if( (pParse->db->flags & SQLITE_InTrans)==0 ){
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0);
@@ -1672,6 +1738,7 @@ void sqliteBeginMultiWriteOperation(Parse *pParse){
Vdbe *v;
v = sqliteGetVdbe(pParse);
if( v==0 ) return;
if (pParse->trigStack) return; /* if this is in a trigger */
if( (pParse->db->flags & SQLITE_InTrans)==0 ){
sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0);
@@ -1689,6 +1756,7 @@ void sqliteBeginMultiWriteOperation(Parse *pParse){
*/
void sqliteEndWriteOperation(Parse *pParse){
Vdbe *v;
if (pParse->trigStack) return; /* if this is in a trigger */
v = sqliteGetVdbe(pParse);
if( v==0 ) return;
if( pParse->db->flags & SQLITE_InTrans ){
@@ -1915,6 +1983,14 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
}
}else
if( sqliteStrICmp(zLeft, "trigger_overhead_test")==0 ){
if( getBoolean(zRight) ){
always_code_trigger_setup = 1;
}else{
always_code_trigger_setup = 0;
}
}else
if( sqliteStrICmp(zLeft, "vdbe_trace")==0 ){
if( getBoolean(zRight) ){
db->flags |= SQLITE_VdbeTrace;