Main Page | Directories | File List

trigger.c

00001 /*
00002 **
00003 ** The author disclaims copyright to this source code.  In place of
00004 ** a legal notice, here is a blessing:
00005 **
00006 **    May you do good and not evil.
00007 **    May you find forgiveness for yourself and forgive others.
00008 **    May you share freely, never taking more than you give.
00009 **
00010 *************************************************************************
00011 *
00012 */
00013 #include "sqliteInt.h"
00014 
00015 /*
00016 ** Delete a linked list of TriggerStep structures.
00017 */
00018 void sqliteDeleteTriggerStep(TriggerStep *pTriggerStep){
00019   while( pTriggerStep ){
00020     TriggerStep * pTmp = pTriggerStep;
00021     pTriggerStep = pTriggerStep->pNext;
00022 
00023     if( pTmp->target.dyn ) sqliteFree((char*)pTmp->target.z);
00024     sqliteExprDelete(pTmp->pWhere);
00025     sqliteExprListDelete(pTmp->pExprList);
00026     sqliteSelectDelete(pTmp->pSelect);
00027     sqliteIdListDelete(pTmp->pIdList);
00028 
00029     sqliteFree(pTmp);
00030   }
00031 }
00032 
00033 /*
00034 ** This is called by the parser when it sees a CREATE TRIGGER statement
00035 ** up to the point of the BEGIN before the trigger actions.  A Trigger
00036 ** structure is generated based on the information available and stored
00037 ** in pParse->pNewTrigger.  After the trigger actions have been parsed, the
00038 ** sqliteFinishTrigger() function is called to complete the trigger
00039 ** construction process.
00040 */
00041 void sqliteBeginTrigger(
00042   Parse *pParse,      /* The parse context of the CREATE TRIGGER statement */
00043   Token *pName,       /* The name of the trigger */
00044   int tr_tm,          /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
00045   int op,             /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
00046   IdList *pColumns,   /* column list if this is an UPDATE OF trigger */
00047   SrcList *pTableName,/* The name of the table/view the trigger applies to */
00048   int foreach,        /* One of TK_ROW or TK_STATEMENT */
00049   Expr *pWhen,        /* WHEN clause */
00050   int isTemp          /* True if the TEMPORARY keyword is present */
00051 ){
00052   Trigger *nt;
00053   Table   *tab;
00054   char *zName = 0;        /* Name of the trigger */
00055   sqlite *db = pParse->db;
00056   int iDb;                /* When database to store the trigger in */
00057   DbFixer sFix;
00058 
00059   /* Check that: 
00060   ** 1. the trigger name does not already exist.
00061   ** 2. the table (or view) does exist in the same database as the trigger.
00062   ** 3. that we are not trying to create a trigger on the sqlite_master table
00063   ** 4. That we are not trying to create an INSTEAD OF trigger on a table.
00064   ** 5. That we are not trying to create a BEFORE or AFTER trigger on a view.
00065   */
00066   if( sqlite_malloc_failed ) goto trigger_cleanup;
00067   assert( pTableName->nSrc==1 );
00068   if( db->init.busy
00069    && sqliteFixInit(&sFix, pParse, db->init.iDb, "trigger", pName)
00070    && sqliteFixSrcList(&sFix, pTableName)
00071   ){
00072     goto trigger_cleanup;
00073   }
00074   tab = sqliteSrcListLookup(pParse, pTableName);
00075   if( !tab ){
00076     goto trigger_cleanup;
00077   }
00078   iDb = isTemp ? 1 : tab->iDb;
00079   if( iDb>=2 && !db->init.busy ){
00080     sqliteErrorMsg(pParse, "triggers may not be added to auxiliary "
00081        "database %s", db->aDb[tab->iDb].zName);
00082     goto trigger_cleanup;
00083   }
00084 
00085   zName = sqliteStrNDup(pName->z, pName->n);
00086   sqliteDequote(zName);
00087   if( sqliteHashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){
00088     sqliteErrorMsg(pParse, "trigger %T already exists", pName);
00089     goto trigger_cleanup;
00090   }
00091   if( sqliteStrNICmp(tab->zName, "sqlite_", 7)==0 ){
00092     sqliteErrorMsg(pParse, "cannot create trigger on system table");
00093     pParse->nErr++;
00094     goto trigger_cleanup;
00095   }
00096   if( tab->pSelect && tr_tm != TK_INSTEAD ){
00097     sqliteErrorMsg(pParse, "cannot create %s trigger on view: %S", 
00098         (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
00099     goto trigger_cleanup;
00100   }
00101   if( !tab->pSelect && tr_tm == TK_INSTEAD ){
00102     sqliteErrorMsg(pParse, "cannot create INSTEAD OF"
00103         " trigger on table: %S", pTableName, 0);
00104     goto trigger_cleanup;
00105   }
00106 #ifndef SQLITE_OMIT_AUTHORIZATION
00107   {
00108     int code = SQLITE_CREATE_TRIGGER;
00109     const char *zDb = db->aDb[tab->iDb].zName;
00110     const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
00111     if( tab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
00112     if( sqliteAuthCheck(pParse, code, zName, tab->zName, zDbTrig) ){
00113       goto trigger_cleanup;
00114     }
00115     if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(tab->iDb), 0, zDb)){
00116       goto trigger_cleanup;
00117     }
00118   }
00119 #endif
00120 
00121   /* INSTEAD OF triggers can only appear on views and BEGIN triggers
00122   ** cannot appear on views.  So we might as well translate every
00123   ** INSTEAD OF trigger into a BEFORE trigger.  It simplifies code
00124   ** elsewhere.
00125   */
00126   if (tr_tm == TK_INSTEAD){
00127     tr_tm = TK_BEFORE;
00128   }
00129 
00130   /* Build the Trigger object */
00131   nt = (Trigger*)sqliteMalloc(sizeof(Trigger));
00132   if( nt==0 ) goto trigger_cleanup;
00133   nt->name = zName;
00134   zName = 0;
00135   nt->table = sqliteStrDup(pTableName->a[0].zName);
00136   if( sqlite_malloc_failed ) goto trigger_cleanup;
00137   nt->iDb = iDb;
00138   nt->iTabDb = tab->iDb;
00139   nt->op = op;
00140   nt->tr_tm = tr_tm;
00141   nt->pWhen = sqliteExprDup(pWhen);
00142   nt->pColumns = sqliteIdListDup(pColumns);
00143   nt->foreach = foreach;
00144   sqliteTokenCopy(&nt->nameToken,pName);
00145   assert( pParse->pNewTrigger==0 );
00146   pParse->pNewTrigger = nt;
00147 
00148 trigger_cleanup:
00149   sqliteFree(zName);
00150   sqliteSrcListDelete(pTableName);
00151   sqliteIdListDelete(pColumns);
00152   sqliteExprDelete(pWhen);
00153 }
00154 
00155 /*
00156 ** This routine is called after all of the trigger actions have been parsed
00157 ** in order to complete the process of building the trigger.
00158 */
00159 void sqliteFinishTrigger(
00160   Parse *pParse,          /* Parser context */
00161   TriggerStep *pStepList, /* The triggered program */
00162   Token *pAll             /* Token that describes the complete CREATE TRIGGER */
00163 ){
00164   Trigger *nt = 0;          /* The trigger whose construction is finishing up */
00165   sqlite *db = pParse->db;  /* The database */
00166   DbFixer sFix;
00167 
00168   if( pParse->nErr || pParse->pNewTrigger==0 ) goto triggerfinish_cleanup;
00169   nt = pParse->pNewTrigger;
00170   pParse->pNewTrigger = 0;
00171   nt->step_list = pStepList;
00172   while( pStepList ){
00173     pStepList->pTrig = nt;
00174     pStepList = pStepList->pNext;
00175   }
00176   if( sqliteFixInit(&sFix, pParse, nt->iDb, "trigger", &nt->nameToken) 
00177           && sqliteFixTriggerStep(&sFix, nt->step_list) ){
00178     goto triggerfinish_cleanup;
00179   }
00180 
00181   /* if we are not initializing, and this trigger is not on a TEMP table, 
00182   ** build the sqlite_master entry
00183   */
00184   if( !db->init.busy ){
00185     static VdbeOpList insertTrig[] = {
00186       { OP_NewRecno,   0, 0,  0          },
00187       { OP_String,     0, 0,  "trigger"  },
00188       { OP_String,     0, 0,  0          },  /* 2: trigger name */
00189       { OP_String,     0, 0,  0          },  /* 3: table name */
00190       { OP_Integer,    0, 0,  0          },
00191       { OP_String,     0, 0,  0          },  /* 5: SQL */
00192       { OP_MakeRecord, 5, 0,  0          },
00193       { OP_PutIntKey,  0, 0,  0          },
00194     };
00195     int addr;
00196     Vdbe *v;
00197 
00198     /* Make an entry in the sqlite_master table */
00199     v = sqliteGetVdbe(pParse);
00200     if( v==0 ) goto triggerfinish_cleanup;
00201     sqliteBeginWriteOperation(pParse, 0, 0);
00202     sqliteOpenMasterTable(v, nt->iDb);
00203     addr = sqliteVdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
00204     sqliteVdbeChangeP3(v, addr+2, nt->name, 0); 
00205     sqliteVdbeChangeP3(v, addr+3, nt->table, 0); 
00206     sqliteVdbeChangeP3(v, addr+5, pAll->z, pAll->n);
00207     if( nt->iDb==0 ){
00208       sqliteChangeCookie(db, v);
00209     }
00210     sqliteVdbeAddOp(v, OP_Close, 0, 0);
00211     sqliteEndWriteOperation(pParse);
00212   }
00213 
00214   if( !pParse->explain ){
00215     Table *pTab;
00216     sqliteHashInsert(&db->aDb[nt->iDb].trigHash, 
00217                      nt->name, strlen(nt->name)+1, nt);
00218     pTab = sqliteLocateTable(pParse, nt->table, db->aDb[nt->iTabDb].zName);
00219     assert( pTab!=0 );
00220     nt->pNext = pTab->pTrigger;
00221     pTab->pTrigger = nt;
00222     nt = 0;
00223   }
00224 
00225 triggerfinish_cleanup:
00226   sqliteDeleteTrigger(nt);
00227   sqliteDeleteTrigger(pParse->pNewTrigger);
00228   pParse->pNewTrigger = 0;
00229   sqliteDeleteTriggerStep(pStepList);
00230 }
00231 
00232 /*
00233 ** Make a copy of all components of the given trigger step.  This has
00234 ** the effect of copying all Expr.token.z values into memory obtained
00235 ** from sqliteMalloc().  As initially created, the Expr.token.z values
00236 ** all point to the input string that was fed to the parser.  But that
00237 ** string is ephemeral - it will go away as soon as the sqlite_exec()
00238 ** call that started the parser exits.  This routine makes a persistent
00239 ** copy of all the Expr.token.z strings so that the TriggerStep structure
00240 ** will be valid even after the sqlite_exec() call returns.
00241 */
00242 static void sqlitePersistTriggerStep(TriggerStep *p){
00243   if( p->target.z ){
00244     p->target.z = sqliteStrNDup(p->target.z, p->target.n);
00245     p->target.dyn = 1;
00246   }
00247   if( p->pSelect ){
00248     Select *pNew = sqliteSelectDup(p->pSelect);
00249     sqliteSelectDelete(p->pSelect);
00250     p->pSelect = pNew;
00251   }
00252   if( p->pWhere ){
00253     Expr *pNew = sqliteExprDup(p->pWhere);
00254     sqliteExprDelete(p->pWhere);
00255     p->pWhere = pNew;
00256   }
00257   if( p->pExprList ){
00258     ExprList *pNew = sqliteExprListDup(p->pExprList);
00259     sqliteExprListDelete(p->pExprList);
00260     p->pExprList = pNew;
00261   }
00262   if( p->pIdList ){
00263     IdList *pNew = sqliteIdListDup(p->pIdList);
00264     sqliteIdListDelete(p->pIdList);
00265     p->pIdList = pNew;
00266   }
00267 }
00268 
00269 /*
00270 ** Turn a SELECT statement (that the pSelect parameter points to) into
00271 ** a trigger step.  Return a pointer to a TriggerStep structure.
00272 **
00273 ** The parser calls this routine when it finds a SELECT statement in
00274 ** body of a TRIGGER.  
00275 */
00276 TriggerStep *sqliteTriggerSelectStep(Select *pSelect){
00277   TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
00278   if( pTriggerStep==0 ) return 0;
00279 
00280   pTriggerStep->op = TK_SELECT;
00281   pTriggerStep->pSelect = pSelect;
00282   pTriggerStep->orconf = OE_Default;
00283   sqlitePersistTriggerStep(pTriggerStep);
00284 
00285   return pTriggerStep;
00286 }
00287 
00288 /*
00289 ** Build a trigger step out of an INSERT statement.  Return a pointer
00290 ** to the new trigger step.
00291 **
00292 ** The parser calls this routine when it sees an INSERT inside the
00293 ** body of a trigger.
00294 */
00295 TriggerStep *sqliteTriggerInsertStep(
00296   Token *pTableName,  /* Name of the table into which we insert */
00297   IdList *pColumn,    /* List of columns in pTableName to insert into */
00298   ExprList *pEList,   /* The VALUE clause: a list of values to be inserted */
00299   Select *pSelect,    /* A SELECT statement that supplies values */
00300   int orconf          /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
00301 ){
00302   TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
00303   if( pTriggerStep==0 ) return 0;
00304 
00305   assert(pEList == 0 || pSelect == 0);
00306   assert(pEList != 0 || pSelect != 0);
00307 
00308   pTriggerStep->op = TK_INSERT;
00309   pTriggerStep->pSelect = pSelect;
00310   pTriggerStep->target  = *pTableName;
00311   pTriggerStep->pIdList = pColumn;
00312   pTriggerStep->pExprList = pEList;
00313   pTriggerStep->orconf = orconf;
00314   sqlitePersistTriggerStep(pTriggerStep);
00315 
00316   return pTriggerStep;
00317 }
00318 
00319 /*
00320 ** Construct a trigger step that implements an UPDATE statement and return
00321 ** a pointer to that trigger step.  The parser calls this routine when it
00322 ** sees an UPDATE statement inside the body of a CREATE TRIGGER.
00323 */
00324 TriggerStep *sqliteTriggerUpdateStep(
00325   Token *pTableName,   /* Name of the table to be updated */
00326   ExprList *pEList,    /* The SET clause: list of column and new values */
00327   Expr *pWhere,        /* The WHERE clause */
00328   int orconf           /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
00329 ){
00330   TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
00331   if( pTriggerStep==0 ) return 0;
00332 
00333   pTriggerStep->op = TK_UPDATE;
00334   pTriggerStep->target  = *pTableName;
00335   pTriggerStep->pExprList = pEList;
00336   pTriggerStep->pWhere = pWhere;
00337   pTriggerStep->orconf = orconf;
00338   sqlitePersistTriggerStep(pTriggerStep);
00339 
00340   return pTriggerStep;
00341 }
00342 
00343 /*
00344 ** Construct a trigger step that implements a DELETE statement and return
00345 ** a pointer to that trigger step.  The parser calls this routine when it
00346 ** sees a DELETE statement inside the body of a CREATE TRIGGER.
00347 */
00348 TriggerStep *sqliteTriggerDeleteStep(Token *pTableName, Expr *pWhere){
00349   TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
00350   if( pTriggerStep==0 ) return 0;
00351 
00352   pTriggerStep->op = TK_DELETE;
00353   pTriggerStep->target  = *pTableName;
00354   pTriggerStep->pWhere = pWhere;
00355   pTriggerStep->orconf = OE_Default;
00356   sqlitePersistTriggerStep(pTriggerStep);
00357 
00358   return pTriggerStep;
00359 }
00360 
00361 /* 
00362 ** Recursively delete a Trigger structure
00363 */
00364 void sqliteDeleteTrigger(Trigger *pTrigger){
00365   if( pTrigger==0 ) return;
00366   sqliteDeleteTriggerStep(pTrigger->step_list);
00367   sqliteFree(pTrigger->name);
00368   sqliteFree(pTrigger->table);
00369   sqliteExprDelete(pTrigger->pWhen);
00370   sqliteIdListDelete(pTrigger->pColumns);
00371   if( pTrigger->nameToken.dyn ) sqliteFree((char*)pTrigger->nameToken.z);
00372   sqliteFree(pTrigger);
00373 }
00374 
00375 /*
00376  * This function is called to drop a trigger from the database schema. 
00377  *
00378  * This may be called directly from the parser and therefore identifies
00379  * the trigger by name.  The sqliteDropTriggerPtr() routine does the
00380  * same job as this routine except it take a spointer to the trigger
00381  * instead of the trigger name.
00382  *
00383  * Note that this function does not delete the trigger entirely. Instead it
00384  * removes it from the internal schema and places it in the trigDrop hash 
00385  * table. This is so that the trigger can be restored into the database schema
00386  * if the transaction is rolled back.
00387  */
00388 void sqliteDropTrigger(Parse *pParse, SrcList *pName){
00389   Trigger *pTrigger;
00390   int i;
00391   const char *zDb;
00392   const char *zName;
00393   int nName;
00394   sqlite *db = pParse->db;
00395 
00396   if( sqlite_malloc_failed ) goto drop_trigger_cleanup;
00397   assert( pName->nSrc==1 );
00398   zDb = pName->a[0].zDatabase;
00399   zName = pName->a[0].zName;
00400   nName = strlen(zName);
00401   for(i=0; i<db->nDb; i++){
00402     int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
00403     if( zDb && sqliteStrICmp(db->aDb[j].zName, zDb) ) continue;
00404     pTrigger = sqliteHashFind(&(db->aDb[j].trigHash), zName, nName+1);
00405     if( pTrigger ) break;
00406   }
00407   if( !pTrigger ){
00408     sqliteErrorMsg(pParse, "no such trigger: %S", pName, 0);
00409     goto drop_trigger_cleanup;
00410   }
00411   sqliteDropTriggerPtr(pParse, pTrigger, 0);
00412 
00413 drop_trigger_cleanup:
00414   sqliteSrcListDelete(pName);
00415 }
00416 
00417 /*
00418 ** Drop a trigger given a pointer to that trigger.  If nested is false,
00419 ** then also generate code to remove the trigger from the SQLITE_MASTER
00420 ** table.
00421 */
00422 void sqliteDropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
00423   Table   *pTable;
00424   Vdbe *v;
00425   sqlite *db = pParse->db;
00426 
00427   assert( pTrigger->iDb<db->nDb );
00428   if( pTrigger->iDb>=2 ){
00429     sqliteErrorMsg(pParse, "triggers may not be removed from "
00430        "auxiliary database %s", db->aDb[pTrigger->iDb].zName);
00431     return;
00432   }
00433   pTable = sqliteFindTable(db, pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
00434   assert(pTable);
00435   assert( pTable->iDb==pTrigger->iDb || pTrigger->iDb==1 );
00436 #ifndef SQLITE_OMIT_AUTHORIZATION
00437   {
00438     int code = SQLITE_DROP_TRIGGER;
00439     const char *zDb = db->aDb[pTrigger->iDb].zName;
00440     const char *zTab = SCHEMA_TABLE(pTrigger->iDb);
00441     if( pTrigger->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
00442     if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
00443       sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
00444       return;
00445     }
00446   }
00447 #endif
00448 
00449   /* Generate code to destroy the database record of the trigger.
00450   */
00451   if( pTable!=0 && !nested && (v = sqliteGetVdbe(pParse))!=0 ){
00452     int base;
00453     static VdbeOpList dropTrigger[] = {
00454       { OP_Rewind,     0, ADDR(9),  0},
00455       { OP_String,     0, 0,        0}, /* 1 */
00456       { OP_Column,     0, 1,        0},
00457       { OP_Ne,         0, ADDR(8),  0},
00458       { OP_String,     0, 0,        "trigger"},
00459       { OP_Column,     0, 0,        0},
00460       { OP_Ne,         0, ADDR(8),  0},
00461       { OP_Delete,     0, 0,        0},
00462       { OP_Next,       0, ADDR(1),  0}, /* 8 */
00463     };
00464 
00465     sqliteBeginWriteOperation(pParse, 0, 0);
00466     sqliteOpenMasterTable(v, pTrigger->iDb);
00467     base = sqliteVdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
00468     sqliteVdbeChangeP3(v, base+1, pTrigger->name, 0);
00469     if( pTrigger->iDb==0 ){
00470       sqliteChangeCookie(db, v);
00471     }
00472     sqliteVdbeAddOp(v, OP_Close, 0, 0);
00473     sqliteEndWriteOperation(pParse);
00474   }
00475 
00476   /*
00477    * If this is not an "explain", then delete the trigger structure.
00478    */
00479   if( !pParse->explain ){
00480     const char *zName = pTrigger->name;
00481     int nName = strlen(zName);
00482     if( pTable->pTrigger == pTrigger ){
00483       pTable->pTrigger = pTrigger->pNext;
00484     }else{
00485       Trigger *cc = pTable->pTrigger;
00486       while( cc ){ 
00487         if( cc->pNext == pTrigger ){
00488           cc->pNext = cc->pNext->pNext;
00489           break;
00490         }
00491         cc = cc->pNext;
00492       }
00493       assert(cc);
00494     }
00495     sqliteHashInsert(&(db->aDb[pTrigger->iDb].trigHash), zName, nName+1, 0);
00496     sqliteDeleteTrigger(pTrigger);
00497   }
00498 }
00499 
00500 /*
00501 ** pEList is the SET clause of an UPDATE statement.  Each entry
00502 ** in pEList is of the format <id>=<expr>.  If any of the entries
00503 ** in pEList have an <id> which matches an identifier in pIdList,
00504 ** then return TRUE.  If pIdList==NULL, then it is considered a
00505 ** wildcard that matches anything.  Likewise if pEList==NULL then
00506 ** it matches anything so always return true.  Return false only
00507 ** if there is no match.
00508 */
00509 static int checkColumnOverLap(IdList *pIdList, ExprList *pEList){
00510   int e;
00511   if( !pIdList || !pEList ) return 1;
00512   for(e=0; e<pEList->nExpr; e++){
00513     if( sqliteIdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
00514   }
00515   return 0; 
00516 }
00517 
00518 /* A global variable that is TRUE if we should always set up temp tables for
00519  * for triggers, even if there are no triggers to code. This is used to test 
00520  * how much overhead the triggers algorithm is causing.
00521  *
00522  * This flag can be set or cleared using the "trigger_overhead_test" pragma.
00523  * The pragma is not documented since it is not really part of the interface
00524  * to SQLite, just the test procedure.
00525 */
00526 int always_code_trigger_setup = 0;
00527 
00528 /*
00529  * Returns true if a trigger matching op, tr_tm and foreach that is NOT already
00530  * on the Parse objects trigger-stack (to prevent recursive trigger firing) is
00531  * found in the list specified as pTrigger.
00532  */
00533 int sqliteTriggersExist(
00534   Parse *pParse,          /* Used to check for recursive triggers */
00535   Trigger *pTrigger,      /* A list of triggers associated with a table */
00536   int op,                 /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
00537   int tr_tm,              /* one of TK_BEFORE, TK_AFTER */
00538   int foreach,            /* one of TK_ROW or TK_STATEMENT */
00539   ExprList *pChanges      /* Columns that change in an UPDATE statement */
00540 ){
00541   Trigger * pTriggerCursor;
00542 
00543   if( always_code_trigger_setup ){
00544     return 1;
00545   }
00546 
00547   pTriggerCursor = pTrigger;
00548   while( pTriggerCursor ){
00549     if( pTriggerCursor->op == op && 
00550         pTriggerCursor->tr_tm == tr_tm && 
00551         pTriggerCursor->foreach == foreach &&
00552         checkColumnOverLap(pTriggerCursor->pColumns, pChanges) ){
00553       TriggerStack * ss;
00554       ss = pParse->trigStack;
00555       while( ss && ss->pTrigger != pTrigger ){
00556         ss = ss->pNext;
00557       }
00558       if( !ss )return 1;
00559     }
00560     pTriggerCursor = pTriggerCursor->pNext;
00561   }
00562 
00563   return 0;
00564 }
00565 
00566 /*
00567 ** Convert the pStep->target token into a SrcList and return a pointer
00568 ** to that SrcList.
00569 **
00570 ** This routine adds a specific database name, if needed, to the target when
00571 ** forming the SrcList.  This prevents a trigger in one database from
00572 ** referring to a target in another database.  An exception is when the
00573 ** trigger is in TEMP in which case it can refer to any other database it
00574 ** wants.
00575 */
00576 static SrcList *targetSrcList(
00577   Parse *pParse,       /* The parsing context */
00578   TriggerStep *pStep   /* The trigger containing the target token */
00579 ){
00580   Token sDb;           /* Dummy database name token */
00581   int iDb;             /* Index of the database to use */
00582   SrcList *pSrc;       /* SrcList to be returned */
00583 
00584   iDb = pStep->pTrig->iDb;
00585   if( iDb==0 || iDb>=2 ){
00586     assert( iDb<pParse->db->nDb );
00587     sDb.z = pParse->db->aDb[iDb].zName;
00588     sDb.n = strlen(sDb.z);
00589     pSrc = sqliteSrcListAppend(0, &sDb, &pStep->target);
00590   } else {
00591     pSrc = sqliteSrcListAppend(0, &pStep->target, 0);
00592   }
00593   return pSrc;
00594 }
00595 
00596 /*
00597 ** Generate VDBE code for zero or more statements inside the body of a
00598 ** trigger.  
00599 */
00600 static int codeTriggerProgram(
00601   Parse *pParse,            /* The parser context */
00602   TriggerStep *pStepList,   /* List of statements inside the trigger body */
00603   int orconfin              /* Conflict algorithm. (OE_Abort, etc) */  
00604 ){
00605   TriggerStep * pTriggerStep = pStepList;
00606   int orconf;
00607 
00608   while( pTriggerStep ){
00609     int saveNTab = pParse->nTab;
00610  
00611     orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
00612     pParse->trigStack->orconf = orconf;
00613     switch( pTriggerStep->op ){
00614       case TK_SELECT: {
00615         Select * ss = sqliteSelectDup(pTriggerStep->pSelect);             
00616         assert(ss);
00617         assert(ss->pSrc);
00618         sqliteSelect(pParse, ss, SRT_Discard, 0, 0, 0, 0);
00619         sqliteSelectDelete(ss);
00620         break;
00621       }
00622       case TK_UPDATE: {
00623         SrcList *pSrc;
00624         pSrc = targetSrcList(pParse, pTriggerStep);
00625         sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
00626         sqliteUpdate(pParse, pSrc,
00627                 sqliteExprListDup(pTriggerStep->pExprList), 
00628                 sqliteExprDup(pTriggerStep->pWhere), orconf);
00629         sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
00630         break;
00631       }
00632       case TK_INSERT: {
00633         SrcList *pSrc;
00634         pSrc = targetSrcList(pParse, pTriggerStep);
00635         sqliteInsert(pParse, pSrc,
00636           sqliteExprListDup(pTriggerStep->pExprList), 
00637           sqliteSelectDup(pTriggerStep->pSelect), 
00638           sqliteIdListDup(pTriggerStep->pIdList), orconf);
00639         break;
00640       }
00641       case TK_DELETE: {
00642         SrcList *pSrc;
00643         sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
00644         pSrc = targetSrcList(pParse, pTriggerStep);
00645         sqliteDeleteFrom(pParse, pSrc, sqliteExprDup(pTriggerStep->pWhere));
00646         sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
00647         break;
00648       }
00649       default:
00650         assert(0);
00651     } 
00652     pParse->nTab = saveNTab;
00653     pTriggerStep = pTriggerStep->pNext;
00654   }
00655 
00656   return 0;
00657 }
00658 
00659 /*
00660 ** This is called to code FOR EACH ROW triggers.
00661 **
00662 ** When the code that this function generates is executed, the following 
00663 ** must be true:
00664 **
00665 ** 1. No cursors may be open in the main database.  (But newIdx and oldIdx
00666 **    can be indices of cursors in temporary tables.  See below.)
00667 **
00668 ** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then
00669 **    a temporary vdbe cursor (index newIdx) must be open and pointing at
00670 **    a row containing values to be substituted for new.* expressions in the
00671 **    trigger program(s).
00672 **
00673 ** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then
00674 **    a temporary vdbe cursor (index oldIdx) must be open and pointing at
00675 **    a row containing values to be substituted for old.* expressions in the
00676 **    trigger program(s).
00677 **
00678 */
00679 int sqliteCodeRowTrigger(
00680   Parse *pParse,       /* Parse context */
00681   int op,              /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
00682   ExprList *pChanges,  /* Changes list for any UPDATE OF triggers */
00683   int tr_tm,           /* One of TK_BEFORE, TK_AFTER */
00684   Table *pTab,         /* The table to code triggers from */
00685   int newIdx,          /* The indice of the "new" row to access */
00686   int oldIdx,          /* The indice of the "old" row to access */
00687   int orconf,          /* ON CONFLICT policy */
00688   int ignoreJump       /* Instruction to jump to for RAISE(IGNORE) */
00689 ){
00690   Trigger * pTrigger;
00691   TriggerStack * pTriggerStack;
00692 
00693   assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
00694   assert(tr_tm == TK_BEFORE || tr_tm == TK_AFTER );
00695 
00696   assert(newIdx != -1 || oldIdx != -1);
00697 
00698   pTrigger = pTab->pTrigger;
00699   while( pTrigger ){
00700     int fire_this = 0;
00701 
00702     /* determine whether we should code this trigger */
00703     if( pTrigger->op == op && pTrigger->tr_tm == tr_tm && 
00704         pTrigger->foreach == TK_ROW ){
00705       fire_this = 1;
00706       pTriggerStack = pParse->trigStack;
00707       while( pTriggerStack ){
00708         if( pTriggerStack->pTrigger == pTrigger ){
00709           fire_this = 0;
00710         }
00711         pTriggerStack = pTriggerStack->pNext;
00712       }
00713       if( op == TK_UPDATE && pTrigger->pColumns &&
00714           !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
00715         fire_this = 0;
00716       }
00717     }
00718 
00719     if( fire_this && (pTriggerStack = sqliteMalloc(sizeof(TriggerStack)))!=0 ){
00720       int endTrigger;
00721       SrcList dummyTablist;
00722       Expr * whenExpr;
00723       AuthContext sContext;
00724 
00725       dummyTablist.nSrc = 0;
00726 
00727       /* Push an entry on to the trigger stack */
00728       pTriggerStack->pTrigger = pTrigger;
00729       pTriggerStack->newIdx = newIdx;
00730       pTriggerStack->oldIdx = oldIdx;
00731       pTriggerStack->pTab = pTab;
00732       pTriggerStack->pNext = pParse->trigStack;
00733       pTriggerStack->ignoreJump = ignoreJump;
00734       pParse->trigStack = pTriggerStack;
00735       sqliteAuthContextPush(pParse, &sContext, pTrigger->name);
00736 
00737       /* code the WHEN clause */
00738       endTrigger = sqliteVdbeMakeLabel(pParse->pVdbe);
00739       whenExpr = sqliteExprDup(pTrigger->pWhen);
00740       if( sqliteExprResolveIds(pParse, &dummyTablist, 0, whenExpr) ){
00741         pParse->trigStack = pParse->trigStack->pNext;
00742         sqliteFree(pTriggerStack);
00743         sqliteExprDelete(whenExpr);
00744         return 1;
00745       }
00746       sqliteExprIfFalse(pParse, whenExpr, endTrigger, 1);
00747       sqliteExprDelete(whenExpr);
00748 
00749       sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPush, 0, 0);
00750       codeTriggerProgram(pParse, pTrigger->step_list, orconf); 
00751       sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPop, 0, 0);
00752 
00753       /* Pop the entry off the trigger stack */
00754       pParse->trigStack = pParse->trigStack->pNext;
00755       sqliteAuthContextPop(&sContext);
00756       sqliteFree(pTriggerStack);
00757 
00758       sqliteVdbeResolveLabel(pParse->pVdbe, endTrigger);
00759     }
00760     pTrigger = pTrigger->pNext;
00761   }
00762 
00763   return 0;
00764 }

Generated on Sun Dec 25 12:29:52 2005 for sqlite 2.8.17 by  doxygen 1.4.2