/*
 ** Return a list of all triggers on table pTab if there exists at least
 ** one trigger that must be fired when an operation of type 'op' is
 ** performed on the table, and, if that operation is an UPDATE, if at
 ** least one of the columns in pChanges is being modified.
 */
SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
                                             Parse *pParse,          /* Parse context */
                                             Table *pTab,            /* The table the contains the triggers */
                                             int op,                 /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
                                             ExprList *pChanges,     /* Columns that change in an UPDATE statement */
                                             int *pMask              /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
){
    int mask = 0;
    Trigger *pList = 0;
    Trigger *p;
    
    if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){
        pList = sqlite3TriggerList(pParse, pTab);
    }
    assert( pList==0 || IsVirtual(pTab)==0 );
    for(p=pList; p; p=p->pNext){
        if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){
            mask |= p->tr_tm;
        }
    }
    if( pMask ){
        *pMask = mask;
    }
    return (mask ? pList : 0);
}
示例#2
0
/*
** Generate the text of a WHERE expression which can be used to select all
** temporary triggers on table pTab from the sqlite_temp_master table. If
** table pTab has no temporary triggers, or is itself stored in the
** temporary database, NULL is returned.
*/
static char *whereTempTriggers(Parse *pParse, Table *pTab){
  Trigger *pTrig;
  char *zWhere = 0;
  const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */

  /* If the table is not located in the temp-db (in which case NULL is
  ** returned, loop through the tables list of triggers. For each trigger
  ** that is not part of the temp-db schema, add a clause to the WHERE
  ** expression being built up in zWhere.
  */
  if( pTab->pSchema!=pTempSchema ){
    sqlite3 *db = pParse->db;
    for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
      if( pTrig->pSchema==pTempSchema ){
        zWhere = whereOrName(db, zWhere, pTrig->zName);
      }
    }
  }
  if( zWhere ){
    char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere);
    sqlite3DbFree(pParse->db, zWhere);
    zWhere = zNew;
  }
  return zWhere;
}
示例#3
0
/*
** Generate code to drop and reload the internal representation of table
** pTab from the database, including triggers and temporary triggers.
** Argument zName is the name of the table in the database schema at
** the time the generated code is executed. This can be different from
** pTab->zName if this function is being called to code part of an 
** "ALTER TABLE RENAME TO" statement.
生成代码删除和重新加载从数据库表pTab的内部表达示,
包括触发器和临时触发器。
参数zName在数据库模式中的表的名称生成的代码执行。
这可以不同于pTab - > zName如果这个函数被调用的代码的一部分“ALTER TABLE RENAME TO”声明。
*/
static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
  Vdbe *v;
  char *zWhere;
  int iDb;                   /* Index of database containing pTab 包含pTab数据库索引*/
#ifndef SQLITE_OMIT_TRIGGER
  Trigger *pTrig;
#endif

  v = sqlite3GetVdbe(pParse);
  if( NEVER(v==0) ) return;
  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  assert( iDb>=0 );

#ifndef SQLITE_OMIT_TRIGGER
  /* Drop any table triggers from the internal schema. 降低任何表触发器内部模式。*/
  for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
    int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
    assert( iTrigDb==iDb || iTrigDb==1 );
    sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0);
  }
#endif

  /* Drop the table and index from the internal schema.  从内部模式中降低表和索引*/
  sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);

  /* Reload the table, index and permanent trigger schemas. 重载表、索引和不变的触发器模式*/
  zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName);
  if( !zWhere ) return;
  sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);

#ifndef SQLITE_OMIT_TRIGGER
  /* Now, if the table is not stored in the temp database, reload any temp 
  ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. 
  现在,如果表没有在临时数据库中存储,那么重载任何临时触发器。
  不要用IN(...)在 SQLITE_OMIT_SUBQUERY被默认的情况下。
  */
  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
    sqlite3VdbeAddParseSchemaOp(v, 1, zWhere);
  }
#endif
}