DBD-SQLite2
view release on metacpan or search on metacpan
TriggerStep * pTriggerStep = pStepList;
int orconf;
while( pTriggerStep ){
int saveNTab = pParse->nTab;
orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
pParse->trigStack->orconf = orconf;
switch( pTriggerStep->op ){
case TK_SELECT: {
Select * ss = sqliteSelectDup(pTriggerStep->pSelect);
assert(ss);
assert(ss->pSrc);
sqliteSelect(pParse, ss, SRT_Discard, 0, 0, 0, 0);
sqliteSelectDelete(ss);
break;
}
case TK_UPDATE: {
SrcList *pSrc;
pSrc = targetSrcList(pParse, pTriggerStep);
sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
sqliteUpdate(pParse, pSrc,
sqliteExprListDup(pTriggerStep->pExprList),
sqliteExprDup(pTriggerStep->pWhere), orconf);
sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
break;
}
case TK_INSERT: {
SrcList *pSrc;
pSrc = targetSrcList(pParse, pTriggerStep);
sqliteInsert(pParse, pSrc,
sqliteExprListDup(pTriggerStep->pExprList),
sqliteSelectDup(pTriggerStep->pSelect),
sqliteIdListDup(pTriggerStep->pIdList), orconf);
break;
}
case TK_DELETE: {
SrcList *pSrc;
sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
pSrc = targetSrcList(pParse, pTriggerStep);
sqliteDeleteFrom(pParse, pSrc, sqliteExprDup(pTriggerStep->pWhere));
sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
break;
}
default:
assert(0);
}
pParse->nTab = saveNTab;
pTriggerStep = pTriggerStep->pNext;
}
return 0;
}
/*
** This is called to code FOR EACH ROW triggers.
**
** When the code that this function generates is executed, the following
** must be true:
**
** 1. No cursors may be open in the main database. (But newIdx and oldIdx
** can be indices of cursors in temporary tables. See below.)
**
** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then
** a temporary vdbe cursor (index newIdx) must be open and pointing at
** a row containing values to be substituted for new.* expressions in the
** trigger program(s).
**
** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then
** a temporary vdbe cursor (index oldIdx) must be open and pointing at
** a row containing values to be substituted for old.* expressions in the
** trigger program(s).
**
*/
int sqliteCodeRowTrigger(
Parse *pParse, /* Parse context */
int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
int tr_tm, /* One of TK_BEFORE, TK_AFTER */
Table *pTab, /* The table to code triggers from */
int newIdx, /* The indice of the "new" row to access */
int oldIdx, /* The indice of the "old" row to access */
int orconf, /* ON CONFLICT policy */
int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
){
Trigger * pTrigger;
TriggerStack * pTriggerStack;
assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
assert(tr_tm == TK_BEFORE || tr_tm == TK_AFTER );
assert(newIdx != -1 || oldIdx != -1);
pTrigger = pTab->pTrigger;
while( pTrigger ){
int fire_this = 0;
/* determine whether we should code this trigger */
if( pTrigger->op == op && pTrigger->tr_tm == tr_tm &&
pTrigger->foreach == TK_ROW ){
fire_this = 1;
pTriggerStack = pParse->trigStack;
while( pTriggerStack ){
if( pTriggerStack->pTrigger == pTrigger ){
fire_this = 0;
}
pTriggerStack = pTriggerStack->pNext;
}
if( op == TK_UPDATE && pTrigger->pColumns &&
!checkColumnOverLap(pTrigger->pColumns, pChanges) ){
fire_this = 0;
}
}
if( fire_this && (pTriggerStack = sqliteMalloc(sizeof(TriggerStack)))!=0 ){
int endTrigger;
SrcList dummyTablist;
Expr * whenExpr;
AuthContext sContext;
dummyTablist.nSrc = 0;
/* Push an entry on to the trigger stack */
pTriggerStack->pTrigger = pTrigger;
pTriggerStack->newIdx = newIdx;
pTriggerStack->oldIdx = oldIdx;
pTriggerStack->pTab = pTab;
pTriggerStack->pNext = pParse->trigStack;
pTriggerStack->ignoreJump = ignoreJump;
pParse->trigStack = pTriggerStack;
( run in 0.415 second using v1.01-cache-2.11-cpan-13bb782fe5a )