Back to index

php5  5.3.10
Functions | Variables
trigger.c File Reference
#include "sqliteInt.h"

Go to the source code of this file.

Functions

void sqliteDeleteTriggerStep (TriggerStep *pTriggerStep)
void sqliteBeginTrigger (Parse *pParse, Token *pName, int tr_tm, int op, IdList *pColumns, SrcList *pTableName, int foreach, Expr *pWhen, int isTemp)
void sqliteFinishTrigger (Parse *pParse, TriggerStep *pStepList, Token *pAll)
static void sqlitePersistTriggerStep (TriggerStep *p)
TriggerStepsqliteTriggerSelectStep (Select *pSelect)
TriggerStepsqliteTriggerInsertStep (Token *pTableName, IdList *pColumn, ExprList *pEList, Select *pSelect, int orconf)
TriggerStepsqliteTriggerUpdateStep (Token *pTableName, ExprList *pEList, Expr *pWhere, int orconf)
TriggerStepsqliteTriggerDeleteStep (Token *pTableName, Expr *pWhere)
void sqliteDeleteTrigger (Trigger *pTrigger)
void sqliteDropTrigger (Parse *pParse, SrcList *pName)
void sqliteDropTriggerPtr (Parse *pParse, Trigger *pTrigger, int nested)
static int checkColumnOverLap (IdList *pIdList, ExprList *pEList)
int sqliteTriggersExist (Parse *pParse, Trigger *pTrigger, int op, int tr_tm, int foreach, ExprList *pChanges)
static SrcListtargetSrcList (Parse *pParse, TriggerStep *pStep)
static int codeTriggerProgram (Parse *pParse, TriggerStep *pStepList, int orconfin)
int sqliteCodeRowTrigger (Parse *pParse, int op, ExprList *pChanges, int tr_tm, Table *pTab, int newIdx, int oldIdx, int orconf, int ignoreJump)

Variables

int always_code_trigger_setup = 0

Function Documentation

static int checkColumnOverLap ( IdList pIdList,
ExprList pEList 
) [static]

Definition at line 509 of file trigger.c.

                                                                {
  int e;
  if( !pIdList || !pEList ) return 1;
  for(e=0; e<pEList->nExpr; e++){
    if( sqliteIdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
  }
  return 0; 
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int codeTriggerProgram ( Parse pParse,
TriggerStep pStepList,
int  orconfin 
) [static]

Definition at line 600 of file trigger.c.

 {
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void sqliteBeginTrigger ( Parse pParse,
Token pName,
int  tr_tm,
int  op,
IdList pColumns,
SrcList pTableName,
int  foreach,
Expr pWhen,
int  isTemp 
)

Definition at line 41 of file trigger.c.

 {
  Trigger *nt;
  Table   *tab;
  char *zName = 0;        /* Name of the trigger */
  sqlite *db = pParse->db;
  int iDb;                /* When database to store the trigger in */
  DbFixer sFix;

  /* Check that: 
  ** 1. the trigger name does not already exist.
  ** 2. the table (or view) does exist in the same database as the trigger.
  ** 3. that we are not trying to create a trigger on the sqlite_master table
  ** 4. That we are not trying to create an INSTEAD OF trigger on a table.
  ** 5. That we are not trying to create a BEFORE or AFTER trigger on a view.
  */
  if( sqlite_malloc_failed ) goto trigger_cleanup;
  assert( pTableName->nSrc==1 );
  if( db->init.busy
   && sqliteFixInit(&sFix, pParse, db->init.iDb, "trigger", pName)
   && sqliteFixSrcList(&sFix, pTableName)
  ){
    goto trigger_cleanup;
  }
  tab = sqliteSrcListLookup(pParse, pTableName);
  if( !tab ){
    goto trigger_cleanup;
  }
  iDb = isTemp ? 1 : tab->iDb;
  if( iDb>=2 && !db->init.busy ){
    sqliteErrorMsg(pParse, "triggers may not be added to auxiliary "
       "database %s", db->aDb[tab->iDb].zName);
    goto trigger_cleanup;
  }

  zName = sqliteStrNDup(pName->z, pName->n);
  sqliteDequote(zName);
  if( sqliteHashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){
    sqliteErrorMsg(pParse, "trigger %T already exists", pName);
    goto trigger_cleanup;
  }
  if( sqliteStrNICmp(tab->zName, "sqlite_", 7)==0 ){
    sqliteErrorMsg(pParse, "cannot create trigger on system table");
    pParse->nErr++;
    goto trigger_cleanup;
  }
  if( tab->pSelect && tr_tm != TK_INSTEAD ){
    sqliteErrorMsg(pParse, "cannot create %s trigger on view: %S", 
        (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
    goto trigger_cleanup;
  }
  if( !tab->pSelect && tr_tm == TK_INSTEAD ){
    sqliteErrorMsg(pParse, "cannot create INSTEAD OF"
        " trigger on table: %S", pTableName, 0);
    goto trigger_cleanup;
  }
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_CREATE_TRIGGER;
    const char *zDb = db->aDb[tab->iDb].zName;
    const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
    if( tab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
    if( sqliteAuthCheck(pParse, code, zName, tab->zName, zDbTrig) ){
      goto trigger_cleanup;
    }
    if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(tab->iDb), 0, zDb)){
      goto trigger_cleanup;
    }
  }
#endif

  /* INSTEAD OF triggers can only appear on views and BEGIN triggers
  ** cannot appear on views.  So we might as well translate every
  ** INSTEAD OF trigger into a BEFORE trigger.  It simplifies code
  ** elsewhere.
  */
  if (tr_tm == TK_INSTEAD){
    tr_tm = TK_BEFORE;
  }

  /* Build the Trigger object */
  nt = (Trigger*)sqliteMalloc(sizeof(Trigger));
  if( nt==0 ) goto trigger_cleanup;
  nt->name = zName;
  zName = 0;
  nt->table = sqliteStrDup(pTableName->a[0].zName);
  if( sqlite_malloc_failed ) goto trigger_cleanup;
  nt->iDb = iDb;
  nt->iTabDb = tab->iDb;
  nt->op = op;
  nt->tr_tm = tr_tm;
  nt->pWhen = sqliteExprDup(pWhen);
  nt->pColumns = sqliteIdListDup(pColumns);
  nt->foreach = foreach;
  sqliteTokenCopy(&nt->nameToken,pName);
  assert( pParse->pNewTrigger==0 );
  pParse->pNewTrigger = nt;

trigger_cleanup:
  sqliteFree(zName);
  sqliteSrcListDelete(pTableName);
  sqliteIdListDelete(pColumns);
  sqliteExprDelete(pWhen);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int sqliteCodeRowTrigger ( Parse pParse,
int  op,
ExprList pChanges,
int  tr_tm,
Table pTab,
int  newIdx,
int  oldIdx,
int  orconf,
int  ignoreJump 
)

Definition at line 679 of file trigger.c.

 {
  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;
      sqliteAuthContextPush(pParse, &sContext, pTrigger->name);

      /* code the WHEN clause */
      endTrigger = sqliteVdbeMakeLabel(pParse->pVdbe);
      whenExpr = sqliteExprDup(pTrigger->pWhen);
      if( sqliteExprResolveIds(pParse, &dummyTablist, 0, whenExpr) ){
        pParse->trigStack = pParse->trigStack->pNext;
        sqliteFree(pTriggerStack);
        sqliteExprDelete(whenExpr);
        return 1;
      }
      sqliteExprIfFalse(pParse, whenExpr, endTrigger, 1);
      sqliteExprDelete(whenExpr);

      sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPush, 0, 0);
      codeTriggerProgram(pParse, pTrigger->step_list, orconf); 
      sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPop, 0, 0);

      /* Pop the entry off the trigger stack */
      pParse->trigStack = pParse->trigStack->pNext;
      sqliteAuthContextPop(&sContext);
      sqliteFree(pTriggerStack);

      sqliteVdbeResolveLabel(pParse->pVdbe, endTrigger);
    }
    pTrigger = pTrigger->pNext;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void sqliteDeleteTrigger ( Trigger pTrigger)

Definition at line 364 of file trigger.c.

                                           {
  if( pTrigger==0 ) return;
  sqliteDeleteTriggerStep(pTrigger->step_list);
  sqliteFree(pTrigger->name);
  sqliteFree(pTrigger->table);
  sqliteExprDelete(pTrigger->pWhen);
  sqliteIdListDelete(pTrigger->pColumns);
  if( pTrigger->nameToken.dyn ) sqliteFree((char*)pTrigger->nameToken.z);
  sqliteFree(pTrigger);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void sqliteDeleteTriggerStep ( TriggerStep pTriggerStep)

Definition at line 18 of file trigger.c.

                                                       {
  while( pTriggerStep ){
    TriggerStep * pTmp = pTriggerStep;
    pTriggerStep = pTriggerStep->pNext;

    if( pTmp->target.dyn ) sqliteFree((char*)pTmp->target.z);
    sqliteExprDelete(pTmp->pWhere);
    sqliteExprListDelete(pTmp->pExprList);
    sqliteSelectDelete(pTmp->pSelect);
    sqliteIdListDelete(pTmp->pIdList);

    sqliteFree(pTmp);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void sqliteDropTrigger ( Parse pParse,
SrcList pName 
)

Definition at line 388 of file trigger.c.

                                                     {
  Trigger *pTrigger;
  int i;
  const char *zDb;
  const char *zName;
  int nName;
  sqlite *db = pParse->db;

  if( sqlite_malloc_failed ) goto drop_trigger_cleanup;
  assert( pName->nSrc==1 );
  zDb = pName->a[0].zDatabase;
  zName = pName->a[0].zName;
  nName = strlen(zName);
  for(i=0; i<db->nDb; i++){
    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
    if( zDb && sqliteStrICmp(db->aDb[j].zName, zDb) ) continue;
    pTrigger = sqliteHashFind(&(db->aDb[j].trigHash), zName, nName+1);
    if( pTrigger ) break;
  }
  if( !pTrigger ){
    sqliteErrorMsg(pParse, "no such trigger: %S", pName, 0);
    goto drop_trigger_cleanup;
  }
  sqliteDropTriggerPtr(pParse, pTrigger, 0);

drop_trigger_cleanup:
  sqliteSrcListDelete(pName);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void sqliteDropTriggerPtr ( Parse pParse,
Trigger pTrigger,
int  nested 
)

Definition at line 422 of file trigger.c.

                                                                       {
  Table   *pTable;
  Vdbe *v;
  sqlite *db = pParse->db;

  assert( pTrigger->iDb<db->nDb );
  if( pTrigger->iDb>=2 ){
    sqliteErrorMsg(pParse, "triggers may not be removed from "
       "auxiliary database %s", db->aDb[pTrigger->iDb].zName);
    return;
  }
  pTable = sqliteFindTable(db, pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
  assert(pTable);
  assert( pTable->iDb==pTrigger->iDb || pTrigger->iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_TRIGGER;
    const char *zDb = db->aDb[pTrigger->iDb].zName;
    const char *zTab = SCHEMA_TABLE(pTrigger->iDb);
    if( pTrigger->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
    if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
      sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
      return;
    }
  }
#endif

  /* Generate code to destroy the database record of the trigger.
  */
  if( pTable!=0 && !nested && (v = sqliteGetVdbe(pParse))!=0 ){
    int base;
    static VdbeOpList dropTrigger[] = {
      { OP_Rewind,     0, ADDR(9),  0},
      { OP_String,     0, 0,        0}, /* 1 */
      { OP_Column,     0, 1,        0},
      { OP_Ne,         0, ADDR(8),  0},
      { OP_String,     0, 0,        "trigger"},
      { OP_Column,     0, 0,        0},
      { OP_Ne,         0, ADDR(8),  0},
      { OP_Delete,     0, 0,        0},
      { OP_Next,       0, ADDR(1),  0}, /* 8 */
    };

    sqliteBeginWriteOperation(pParse, 0, 0);
    sqliteOpenMasterTable(v, pTrigger->iDb);
    base = sqliteVdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
    sqliteVdbeChangeP3(v, base+1, pTrigger->name, 0);
    if( pTrigger->iDb==0 ){
      sqliteChangeCookie(db, v);
    }
    sqliteVdbeAddOp(v, OP_Close, 0, 0);
    sqliteEndWriteOperation(pParse);
  }

  /*
   * If this is not an "explain", then delete the trigger structure.
   */
  if( !pParse->explain ){
    const char *zName = pTrigger->name;
    int nName = strlen(zName);
    if( pTable->pTrigger == pTrigger ){
      pTable->pTrigger = pTrigger->pNext;
    }else{
      Trigger *cc = pTable->pTrigger;
      while( cc ){ 
        if( cc->pNext == pTrigger ){
          cc->pNext = cc->pNext->pNext;
          break;
        }
        cc = cc->pNext;
      }
      assert(cc);
    }
    sqliteHashInsert(&(db->aDb[pTrigger->iDb].trigHash), zName, nName+1, 0);
    sqliteDeleteTrigger(pTrigger);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void sqliteFinishTrigger ( Parse pParse,
TriggerStep pStepList,
Token pAll 
)

Definition at line 159 of file trigger.c.

 {
  Trigger *nt = 0;          /* The trigger whose construction is finishing up */
  sqlite *db = pParse->db;  /* The database */
  DbFixer sFix;

  if( pParse->nErr || pParse->pNewTrigger==0 ) goto triggerfinish_cleanup;
  nt = pParse->pNewTrigger;
  pParse->pNewTrigger = 0;
  nt->step_list = pStepList;
  while( pStepList ){
    pStepList->pTrig = nt;
    pStepList = pStepList->pNext;
  }
  if( sqliteFixInit(&sFix, pParse, nt->iDb, "trigger", &nt->nameToken) 
          && sqliteFixTriggerStep(&sFix, nt->step_list) ){
    goto triggerfinish_cleanup;
  }

  /* if we are not initializing, and this trigger is not on a TEMP table, 
  ** build the sqlite_master entry
  */
  if( !db->init.busy ){
    static VdbeOpList insertTrig[] = {
      { OP_NewRecno,   0, 0,  0          },
      { OP_String,     0, 0,  "trigger"  },
      { OP_String,     0, 0,  0          },  /* 2: trigger name */
      { OP_String,     0, 0,  0          },  /* 3: table name */
      { OP_Integer,    0, 0,  0          },
      { OP_String,     0, 0,  0          },  /* 5: SQL */
      { OP_MakeRecord, 5, 0,  0          },
      { OP_PutIntKey,  0, 0,  0          },
    };
    int addr;
    Vdbe *v;

    /* Make an entry in the sqlite_master table */
    v = sqliteGetVdbe(pParse);
    if( v==0 ) goto triggerfinish_cleanup;
    sqliteBeginWriteOperation(pParse, 0, 0);
    sqliteOpenMasterTable(v, nt->iDb);
    addr = sqliteVdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
    sqliteVdbeChangeP3(v, addr+2, nt->name, 0); 
    sqliteVdbeChangeP3(v, addr+3, nt->table, 0); 
    sqliteVdbeChangeP3(v, addr+5, pAll->z, pAll->n);
    if( nt->iDb==0 ){
      sqliteChangeCookie(db, v);
    }
    sqliteVdbeAddOp(v, OP_Close, 0, 0);
    sqliteEndWriteOperation(pParse);
  }

  if( !pParse->explain ){
    Table *pTab;
    sqliteHashInsert(&db->aDb[nt->iDb].trigHash, 
                     nt->name, strlen(nt->name)+1, nt);
    pTab = sqliteLocateTable(pParse, nt->table, db->aDb[nt->iTabDb].zName);
    assert( pTab!=0 );
    nt->pNext = pTab->pTrigger;
    pTab->pTrigger = nt;
    nt = 0;
  }

triggerfinish_cleanup:
  sqliteDeleteTrigger(nt);
  sqliteDeleteTrigger(pParse->pNewTrigger);
  pParse->pNewTrigger = 0;
  sqliteDeleteTriggerStep(pStepList);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void sqlitePersistTriggerStep ( TriggerStep p) [static]

Definition at line 242 of file trigger.c.

                                                    {
  if( p->target.z ){
    p->target.z = sqliteStrNDup(p->target.z, p->target.n);
    p->target.dyn = 1;
  }
  if( p->pSelect ){
    Select *pNew = sqliteSelectDup(p->pSelect);
    sqliteSelectDelete(p->pSelect);
    p->pSelect = pNew;
  }
  if( p->pWhere ){
    Expr *pNew = sqliteExprDup(p->pWhere);
    sqliteExprDelete(p->pWhere);
    p->pWhere = pNew;
  }
  if( p->pExprList ){
    ExprList *pNew = sqliteExprListDup(p->pExprList);
    sqliteExprListDelete(p->pExprList);
    p->pExprList = pNew;
  }
  if( p->pIdList ){
    IdList *pNew = sqliteIdListDup(p->pIdList);
    sqliteIdListDelete(p->pIdList);
    p->pIdList = pNew;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

TriggerStep* sqliteTriggerDeleteStep ( Token pTableName,
Expr pWhere 
)

Definition at line 348 of file trigger.c.

                                                                     {
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) return 0;

  pTriggerStep->op = TK_DELETE;
  pTriggerStep->target  = *pTableName;
  pTriggerStep->pWhere = pWhere;
  pTriggerStep->orconf = OE_Default;
  sqlitePersistTriggerStep(pTriggerStep);

  return pTriggerStep;
}

Here is the call graph for this function:

Here is the caller graph for this function:

TriggerStep* sqliteTriggerInsertStep ( Token pTableName,
IdList pColumn,
ExprList pEList,
Select pSelect,
int  orconf 
)

Definition at line 295 of file trigger.c.

 {
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) return 0;

  assert(pEList == 0 || pSelect == 0);
  assert(pEList != 0 || pSelect != 0);

  pTriggerStep->op = TK_INSERT;
  pTriggerStep->pSelect = pSelect;
  pTriggerStep->target  = *pTableName;
  pTriggerStep->pIdList = pColumn;
  pTriggerStep->pExprList = pEList;
  pTriggerStep->orconf = orconf;
  sqlitePersistTriggerStep(pTriggerStep);

  return pTriggerStep;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 276 of file trigger.c.

                                                     {
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) return 0;

  pTriggerStep->op = TK_SELECT;
  pTriggerStep->pSelect = pSelect;
  pTriggerStep->orconf = OE_Default;
  sqlitePersistTriggerStep(pTriggerStep);

  return pTriggerStep;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int sqliteTriggersExist ( Parse pParse,
Trigger pTrigger,
int  op,
int  tr_tm,
int  foreach,
ExprList pChanges 
)

Definition at line 533 of file trigger.c.

 {
  Trigger * pTriggerCursor;

  if( always_code_trigger_setup ){
    return 1;
  }

  pTriggerCursor = pTrigger;
  while( pTriggerCursor ){
    if( pTriggerCursor->op == op && 
       pTriggerCursor->tr_tm == tr_tm && 
       pTriggerCursor->foreach == foreach &&
       checkColumnOverLap(pTriggerCursor->pColumns, pChanges) ){
      TriggerStack * ss;
      ss = pParse->trigStack;
      while( ss && ss->pTrigger != pTrigger ){
       ss = ss->pNext;
      }
      if( !ss )return 1;
    }
    pTriggerCursor = pTriggerCursor->pNext;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

TriggerStep* sqliteTriggerUpdateStep ( Token pTableName,
ExprList pEList,
Expr pWhere,
int  orconf 
)

Definition at line 324 of file trigger.c.

 {
  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
  if( pTriggerStep==0 ) return 0;

  pTriggerStep->op = TK_UPDATE;
  pTriggerStep->target  = *pTableName;
  pTriggerStep->pExprList = pEList;
  pTriggerStep->pWhere = pWhere;
  pTriggerStep->orconf = orconf;
  sqlitePersistTriggerStep(pTriggerStep);

  return pTriggerStep;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SrcList* targetSrcList ( Parse pParse,
TriggerStep pStep 
) [static]

Definition at line 576 of file trigger.c.

 {
  Token sDb;           /* Dummy database name token */
  int iDb;             /* Index of the database to use */
  SrcList *pSrc;       /* SrcList to be returned */

  iDb = pStep->pTrig->iDb;
  if( iDb==0 || iDb>=2 ){
    assert( iDb<pParse->db->nDb );
    sDb.z = pParse->db->aDb[iDb].zName;
    sDb.n = strlen(sDb.z);
    pSrc = sqliteSrcListAppend(0, &sDb, &pStep->target);
  } else {
    pSrc = sqliteSrcListAppend(0, &pStep->target, 0);
  }
  return pSrc;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 526 of file trigger.c.