trigger.c

Go to the documentation of this file.
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 ** $Id: trigger.c,v 1.129 2008/08/20 16:35:10 drh Exp $
00014 */
00015 #include "sqliteInt.h"
00016 
00017 #ifndef SQLITE_OMIT_TRIGGER
00018 /*
00019 ** Delete a linked list of TriggerStep structures.
00020 */
00021 void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){
00022   while( pTriggerStep ){
00023     TriggerStep * pTmp = pTriggerStep;
00024     pTriggerStep = pTriggerStep->pNext;
00025 
00026     if( pTmp->target.dyn ) sqlite3DbFree(db, (char*)pTmp->target.z);
00027     sqlite3ExprDelete(db, pTmp->pWhere);
00028     sqlite3ExprListDelete(db, pTmp->pExprList);
00029     sqlite3SelectDelete(db, pTmp->pSelect);
00030     sqlite3IdListDelete(db, pTmp->pIdList);
00031 
00032     sqlite3DbFree(db, pTmp);
00033   }
00034 }
00035 
00036 /*
00037 ** This is called by the parser when it sees a CREATE TRIGGER statement
00038 ** up to the point of the BEGIN before the trigger actions.  A Trigger
00039 ** structure is generated based on the information available and stored
00040 ** in pParse->pNewTrigger.  After the trigger actions have been parsed, the
00041 ** sqlite3FinishTrigger() function is called to complete the trigger
00042 ** construction process.
00043 */
00044 void sqlite3BeginTrigger(
00045   Parse *pParse,      /* The parse context of the CREATE TRIGGER statement */
00046   Token *pName1,      /* The name of the trigger */
00047   Token *pName2,      /* The name of the trigger */
00048   int tr_tm,          /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
00049   int op,             /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
00050   IdList *pColumns,   /* column list if this is an UPDATE OF trigger */
00051   SrcList *pTableName,/* The name of the table/view the trigger applies to */
00052   Expr *pWhen,        /* WHEN clause */
00053   int isTemp,         /* True if the TEMPORARY keyword is present */
00054   int noErr           /* Suppress errors if the trigger already exists */
00055 ){
00056   Trigger *pTrigger = 0;
00057   Table *pTab;
00058   char *zName = 0;        /* Name of the trigger */
00059   sqlite3 *db = pParse->db;
00060   int iDb;                /* The database to store the trigger in */
00061   Token *pName;           /* The unqualified db name */
00062   DbFixer sFix;
00063   int iTabDb;
00064 
00065   assert( pName1!=0 );   /* pName1->z might be NULL, but not pName1 itself */
00066   assert( pName2!=0 );
00067   if( isTemp ){
00068     /* If TEMP was specified, then the trigger name may not be qualified. */
00069     if( pName2->n>0 ){
00070       sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name");
00071       goto trigger_cleanup;
00072     }
00073     iDb = 1;
00074     pName = pName1;
00075   }else{
00076     /* Figure out the db that the the trigger will be created in */
00077     iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
00078     if( iDb<0 ){
00079       goto trigger_cleanup;
00080     }
00081   }
00082 
00083   /* If the trigger name was unqualified, and the table is a temp table,
00084   ** then set iDb to 1 to create the trigger in the temporary database.
00085   ** If sqlite3SrcListLookup() returns 0, indicating the table does not
00086   ** exist, the error is caught by the block below.
00087   */
00088   if( !pTableName || db->mallocFailed ){
00089     goto trigger_cleanup;
00090   }
00091   pTab = sqlite3SrcListLookup(pParse, pTableName);
00092   if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
00093     iDb = 1;
00094   }
00095 
00096   /* Ensure the table name matches database name and that the table exists */
00097   if( db->mallocFailed ) goto trigger_cleanup;
00098   assert( pTableName->nSrc==1 );
00099   if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && 
00100       sqlite3FixSrcList(&sFix, pTableName) ){
00101     goto trigger_cleanup;
00102   }
00103   pTab = sqlite3SrcListLookup(pParse, pTableName);
00104   if( !pTab ){
00105     /* The table does not exist. */
00106     goto trigger_cleanup;
00107   }
00108   if( IsVirtual(pTab) ){
00109     sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables");
00110     goto trigger_cleanup;
00111   }
00112 
00113   /* Check that the trigger name is not reserved and that no trigger of the
00114   ** specified name exists */
00115   zName = sqlite3NameFromToken(db, pName);
00116   if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
00117     goto trigger_cleanup;
00118   }
00119   if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName,strlen(zName)) ){
00120     if( !noErr ){
00121       sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
00122     }
00123     goto trigger_cleanup;
00124   }
00125 
00126   /* Do not create a trigger on a system table */
00127   if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
00128     sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
00129     pParse->nErr++;
00130     goto trigger_cleanup;
00131   }
00132 
00133   /* INSTEAD of triggers are only for views and views only support INSTEAD
00134   ** of triggers.
00135   */
00136   if( pTab->pSelect && tr_tm!=TK_INSTEAD ){
00137     sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", 
00138         (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
00139     goto trigger_cleanup;
00140   }
00141   if( !pTab->pSelect && tr_tm==TK_INSTEAD ){
00142     sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF"
00143         " trigger on table: %S", pTableName, 0);
00144     goto trigger_cleanup;
00145   }
00146   iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
00147 
00148 #ifndef SQLITE_OMIT_AUTHORIZATION
00149   {
00150     int code = SQLITE_CREATE_TRIGGER;
00151     const char *zDb = db->aDb[iTabDb].zName;
00152     const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
00153     if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
00154     if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
00155       goto trigger_cleanup;
00156     }
00157     if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){
00158       goto trigger_cleanup;
00159     }
00160   }
00161 #endif
00162 
00163   /* INSTEAD OF triggers can only appear on views and BEFORE triggers
00164   ** cannot appear on views.  So we might as well translate every
00165   ** INSTEAD OF trigger into a BEFORE trigger.  It simplifies code
00166   ** elsewhere.
00167   */
00168   if (tr_tm == TK_INSTEAD){
00169     tr_tm = TK_BEFORE;
00170   }
00171 
00172   /* Build the Trigger object */
00173   pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger));
00174   if( pTrigger==0 ) goto trigger_cleanup;
00175   pTrigger->name = zName;
00176   zName = 0;
00177   pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName);
00178   pTrigger->pSchema = db->aDb[iDb].pSchema;
00179   pTrigger->pTabSchema = pTab->pSchema;
00180   pTrigger->op = op;
00181   pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
00182   pTrigger->pWhen = sqlite3ExprDup(db, pWhen);
00183   pTrigger->pColumns = sqlite3IdListDup(db, pColumns);
00184   sqlite3TokenCopy(db, &pTrigger->nameToken,pName);
00185   assert( pParse->pNewTrigger==0 );
00186   pParse->pNewTrigger = pTrigger;
00187 
00188 trigger_cleanup:
00189   sqlite3DbFree(db, zName);
00190   sqlite3SrcListDelete(db, pTableName);
00191   sqlite3IdListDelete(db, pColumns);
00192   sqlite3ExprDelete(db, pWhen);
00193   if( !pParse->pNewTrigger ){
00194     sqlite3DeleteTrigger(db, pTrigger);
00195   }else{
00196     assert( pParse->pNewTrigger==pTrigger );
00197   }
00198 }
00199 
00200 /*
00201 ** This routine is called after all of the trigger actions have been parsed
00202 ** in order to complete the process of building the trigger.
00203 */
00204 void sqlite3FinishTrigger(
00205   Parse *pParse,          /* Parser context */
00206   TriggerStep *pStepList, /* The triggered program */
00207   Token *pAll             /* Token that describes the complete CREATE TRIGGER */
00208 ){
00209   Trigger *pTrig = 0;     /* The trigger whose construction is finishing up */
00210   sqlite3 *db = pParse->db;  /* The database */
00211   DbFixer sFix;
00212   int iDb;                   /* Database containing the trigger */
00213 
00214   pTrig = pParse->pNewTrigger;
00215   pParse->pNewTrigger = 0;
00216   if( pParse->nErr || !pTrig ) goto triggerfinish_cleanup;
00217   iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
00218   pTrig->step_list = pStepList;
00219   while( pStepList ){
00220     pStepList->pTrig = pTrig;
00221     pStepList = pStepList->pNext;
00222   }
00223   if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &pTrig->nameToken) 
00224           && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
00225     goto triggerfinish_cleanup;
00226   }
00227 
00228   /* if we are not initializing, and this trigger is not on a TEMP table, 
00229   ** build the sqlite_master entry
00230   */
00231   if( !db->init.busy ){
00232     Vdbe *v;
00233     char *z;
00234 
00235     /* Make an entry in the sqlite_master table */
00236     v = sqlite3GetVdbe(pParse);
00237     if( v==0 ) goto triggerfinish_cleanup;
00238     sqlite3BeginWriteOperation(pParse, 0, iDb);
00239     z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
00240     sqlite3NestedParse(pParse,
00241        "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
00242        db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pTrig->name,
00243        pTrig->table, z);
00244     sqlite3DbFree(db, z);
00245     sqlite3ChangeCookie(pParse, iDb);
00246     sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, sqlite3MPrintf(
00247         db, "type='trigger' AND name='%q'", pTrig->name), P4_DYNAMIC
00248     );
00249   }
00250 
00251   if( db->init.busy ){
00252     int n;
00253     Table *pTab;
00254     Trigger *pDel;
00255     pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash, 
00256                      pTrig->name, strlen(pTrig->name), pTrig);
00257     if( pDel ){
00258       assert( pDel==pTrig );
00259       db->mallocFailed = 1;
00260       goto triggerfinish_cleanup;
00261     }
00262     n = strlen(pTrig->table) + 1;
00263     pTab = sqlite3HashFind(&pTrig->pTabSchema->tblHash, pTrig->table, n);
00264     assert( pTab!=0 );
00265     pTrig->pNext = pTab->pTrigger;
00266     pTab->pTrigger = pTrig;
00267     pTrig = 0;
00268   }
00269 
00270 triggerfinish_cleanup:
00271   sqlite3DeleteTrigger(db, pTrig);
00272   assert( !pParse->pNewTrigger );
00273   sqlite3DeleteTriggerStep(db, pStepList);
00274 }
00275 
00276 /*
00277 ** Make a copy of all components of the given trigger step.  This has
00278 ** the effect of copying all Expr.token.z values into memory obtained
00279 ** from sqlite3_malloc().  As initially created, the Expr.token.z values
00280 ** all point to the input string that was fed to the parser.  But that
00281 ** string is ephemeral - it will go away as soon as the sqlite3_exec()
00282 ** call that started the parser exits.  This routine makes a persistent
00283 ** copy of all the Expr.token.z strings so that the TriggerStep structure
00284 ** will be valid even after the sqlite3_exec() call returns.
00285 */
00286 static void sqlitePersistTriggerStep(sqlite3 *db, TriggerStep *p){
00287   if( p->target.z ){
00288     p->target.z = (u8*)sqlite3DbStrNDup(db, (char*)p->target.z, p->target.n);
00289     p->target.dyn = 1;
00290   }
00291   if( p->pSelect ){
00292     Select *pNew = sqlite3SelectDup(db, p->pSelect);
00293     sqlite3SelectDelete(db, p->pSelect);
00294     p->pSelect = pNew;
00295   }
00296   if( p->pWhere ){
00297     Expr *pNew = sqlite3ExprDup(db, p->pWhere);
00298     sqlite3ExprDelete(db, p->pWhere);
00299     p->pWhere = pNew;
00300   }
00301   if( p->pExprList ){
00302     ExprList *pNew = sqlite3ExprListDup(db, p->pExprList);
00303     sqlite3ExprListDelete(db, p->pExprList);
00304     p->pExprList = pNew;
00305   }
00306   if( p->pIdList ){
00307     IdList *pNew = sqlite3IdListDup(db, p->pIdList);
00308     sqlite3IdListDelete(db, p->pIdList);
00309     p->pIdList = pNew;
00310   }
00311 }
00312 
00313 /*
00314 ** Turn a SELECT statement (that the pSelect parameter points to) into
00315 ** a trigger step.  Return a pointer to a TriggerStep structure.
00316 **
00317 ** The parser calls this routine when it finds a SELECT statement in
00318 ** body of a TRIGGER.  
00319 */
00320 TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){
00321   TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
00322   if( pTriggerStep==0 ) {
00323     sqlite3SelectDelete(db, pSelect);
00324     return 0;
00325   }
00326 
00327   pTriggerStep->op = TK_SELECT;
00328   pTriggerStep->pSelect = pSelect;
00329   pTriggerStep->orconf = OE_Default;
00330   sqlitePersistTriggerStep(db, pTriggerStep);
00331 
00332   return pTriggerStep;
00333 }
00334 
00335 /*
00336 ** Build a trigger step out of an INSERT statement.  Return a pointer
00337 ** to the new trigger step.
00338 **
00339 ** The parser calls this routine when it sees an INSERT inside the
00340 ** body of a trigger.
00341 */
00342 TriggerStep *sqlite3TriggerInsertStep(
00343   sqlite3 *db,        /* The database connection */
00344   Token *pTableName,  /* Name of the table into which we insert */
00345   IdList *pColumn,    /* List of columns in pTableName to insert into */
00346   ExprList *pEList,   /* The VALUE clause: a list of values to be inserted */
00347   Select *pSelect,    /* A SELECT statement that supplies values */
00348   int orconf          /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
00349 ){
00350   TriggerStep *pTriggerStep;
00351 
00352   assert(pEList == 0 || pSelect == 0);
00353   assert(pEList != 0 || pSelect != 0 || db->mallocFailed);
00354 
00355   pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
00356   if( pTriggerStep ){
00357     pTriggerStep->op = TK_INSERT;
00358     pTriggerStep->pSelect = pSelect;
00359     pTriggerStep->target  = *pTableName;
00360     pTriggerStep->pIdList = pColumn;
00361     pTriggerStep->pExprList = pEList;
00362     pTriggerStep->orconf = orconf;
00363     sqlitePersistTriggerStep(db, pTriggerStep);
00364   }else{
00365     sqlite3IdListDelete(db, pColumn);
00366     sqlite3ExprListDelete(db, pEList);
00367     sqlite3SelectDelete(db, pSelect);
00368   }
00369 
00370   return pTriggerStep;
00371 }
00372 
00373 /*
00374 ** Construct a trigger step that implements an UPDATE statement and return
00375 ** a pointer to that trigger step.  The parser calls this routine when it
00376 ** sees an UPDATE statement inside the body of a CREATE TRIGGER.
00377 */
00378 TriggerStep *sqlite3TriggerUpdateStep(
00379   sqlite3 *db,         /* The database connection */
00380   Token *pTableName,   /* Name of the table to be updated */
00381   ExprList *pEList,    /* The SET clause: list of column and new values */
00382   Expr *pWhere,        /* The WHERE clause */
00383   int orconf           /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
00384 ){
00385   TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
00386   if( pTriggerStep==0 ){
00387      sqlite3ExprListDelete(db, pEList);
00388      sqlite3ExprDelete(db, pWhere);
00389      return 0;
00390   }
00391 
00392   pTriggerStep->op = TK_UPDATE;
00393   pTriggerStep->target  = *pTableName;
00394   pTriggerStep->pExprList = pEList;
00395   pTriggerStep->pWhere = pWhere;
00396   pTriggerStep->orconf = orconf;
00397   sqlitePersistTriggerStep(db, pTriggerStep);
00398 
00399   return pTriggerStep;
00400 }
00401 
00402 /*
00403 ** Construct a trigger step that implements a DELETE statement and return
00404 ** a pointer to that trigger step.  The parser calls this routine when it
00405 ** sees a DELETE statement inside the body of a CREATE TRIGGER.
00406 */
00407 TriggerStep *sqlite3TriggerDeleteStep(
00408   sqlite3 *db,            /* Database connection */
00409   Token *pTableName,      /* The table from which rows are deleted */
00410   Expr *pWhere            /* The WHERE clause */
00411 ){
00412   TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
00413   if( pTriggerStep==0 ){
00414     sqlite3ExprDelete(db, pWhere);
00415     return 0;
00416   }
00417 
00418   pTriggerStep->op = TK_DELETE;
00419   pTriggerStep->target  = *pTableName;
00420   pTriggerStep->pWhere = pWhere;
00421   pTriggerStep->orconf = OE_Default;
00422   sqlitePersistTriggerStep(db, pTriggerStep);
00423 
00424   return pTriggerStep;
00425 }
00426 
00427 /* 
00428 ** Recursively delete a Trigger structure
00429 */
00430 void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
00431   if( pTrigger==0 ) return;
00432   sqlite3DeleteTriggerStep(db, pTrigger->step_list);
00433   sqlite3DbFree(db, pTrigger->name);
00434   sqlite3DbFree(db, pTrigger->table);
00435   sqlite3ExprDelete(db, pTrigger->pWhen);
00436   sqlite3IdListDelete(db, pTrigger->pColumns);
00437   if( pTrigger->nameToken.dyn ) sqlite3DbFree(db, (char*)pTrigger->nameToken.z);
00438   sqlite3DbFree(db, pTrigger);
00439 }
00440 
00441 /*
00442 ** This function is called to drop a trigger from the database schema. 
00443 **
00444 ** This may be called directly from the parser and therefore identifies
00445 ** the trigger by name.  The sqlite3DropTriggerPtr() routine does the
00446 ** same job as this routine except it takes a pointer to the trigger
00447 ** instead of the trigger name.
00448 **/
00449 void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
00450   Trigger *pTrigger = 0;
00451   int i;
00452   const char *zDb;
00453   const char *zName;
00454   int nName;
00455   sqlite3 *db = pParse->db;
00456 
00457   if( db->mallocFailed ) goto drop_trigger_cleanup;
00458   if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
00459     goto drop_trigger_cleanup;
00460   }
00461 
00462   assert( pName->nSrc==1 );
00463   zDb = pName->a[0].zDatabase;
00464   zName = pName->a[0].zName;
00465   nName = strlen(zName);
00466   for(i=OMIT_TEMPDB; i<db->nDb; i++){
00467     int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
00468     if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
00469     pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName);
00470     if( pTrigger ) break;
00471   }
00472   if( !pTrigger ){
00473     if( !noErr ){
00474       sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
00475     }
00476     goto drop_trigger_cleanup;
00477   }
00478   sqlite3DropTriggerPtr(pParse, pTrigger);
00479 
00480 drop_trigger_cleanup:
00481   sqlite3SrcListDelete(db, pName);
00482 }
00483 
00484 /*
00485 ** Return a pointer to the Table structure for the table that a trigger
00486 ** is set on.
00487 */
00488 static Table *tableOfTrigger(Trigger *pTrigger){
00489   int n = strlen(pTrigger->table) + 1;
00490   return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table, n);
00491 }
00492 
00493 
00494 /*
00495 ** Drop a trigger given a pointer to that trigger. 
00496 */
00497 void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
00498   Table   *pTable;
00499   Vdbe *v;
00500   sqlite3 *db = pParse->db;
00501   int iDb;
00502 
00503   iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema);
00504   assert( iDb>=0 && iDb<db->nDb );
00505   pTable = tableOfTrigger(pTrigger);
00506   assert( pTable );
00507   assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
00508 #ifndef SQLITE_OMIT_AUTHORIZATION
00509   {
00510     int code = SQLITE_DROP_TRIGGER;
00511     const char *zDb = db->aDb[iDb].zName;
00512     const char *zTab = SCHEMA_TABLE(iDb);
00513     if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
00514     if( sqlite3AuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
00515       sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
00516       return;
00517     }
00518   }
00519 #endif
00520 
00521   /* Generate code to destroy the database record of the trigger.
00522   */
00523   assert( pTable!=0 );
00524   if( (v = sqlite3GetVdbe(pParse))!=0 ){
00525     int base;
00526     static const VdbeOpList dropTrigger[] = {
00527       { OP_Rewind,     0, ADDR(9),  0},
00528       { OP_String8,    0, 1,        0}, /* 1 */
00529       { OP_Column,     0, 1,        2},
00530       { OP_Ne,         2, ADDR(8),  1},
00531       { OP_String8,    0, 1,        0}, /* 4: "trigger" */
00532       { OP_Column,     0, 0,        2},
00533       { OP_Ne,         2, ADDR(8),  1},
00534       { OP_Delete,     0, 0,        0},
00535       { OP_Next,       0, ADDR(1),  0}, /* 8 */
00536     };
00537 
00538     sqlite3BeginWriteOperation(pParse, 0, iDb);
00539     sqlite3OpenMasterTable(pParse, iDb);
00540     base = sqlite3VdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
00541     sqlite3VdbeChangeP4(v, base+1, pTrigger->name, 0);
00542     sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC);
00543     sqlite3ChangeCookie(pParse, iDb);
00544     sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
00545     sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->name, 0);
00546   }
00547 }
00548 
00549 /*
00550 ** Remove a trigger from the hash tables of the sqlite* pointer.
00551 */
00552 void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
00553   Trigger *pTrigger;
00554   int nName = strlen(zName);
00555   pTrigger = sqlite3HashInsert(&(db->aDb[iDb].pSchema->trigHash),
00556                                zName, nName, 0);
00557   if( pTrigger ){
00558     Table *pTable = tableOfTrigger(pTrigger);
00559     assert( pTable!=0 );
00560     if( pTable->pTrigger == pTrigger ){
00561       pTable->pTrigger = pTrigger->pNext;
00562     }else{
00563       Trigger *cc = pTable->pTrigger;
00564       while( cc ){ 
00565         if( cc->pNext == pTrigger ){
00566           cc->pNext = cc->pNext->pNext;
00567           break;
00568         }
00569         cc = cc->pNext;
00570       }
00571       assert(cc);
00572     }
00573     sqlite3DeleteTrigger(db, pTrigger);
00574     db->flags |= SQLITE_InternChanges;
00575   }
00576 }
00577 
00578 /*
00579 ** pEList is the SET clause of an UPDATE statement.  Each entry
00580 ** in pEList is of the format <id>=<expr>.  If any of the entries
00581 ** in pEList have an <id> which matches an identifier in pIdList,
00582 ** then return TRUE.  If pIdList==NULL, then it is considered a
00583 ** wildcard that matches anything.  Likewise if pEList==NULL then
00584 ** it matches anything so always return true.  Return false only
00585 ** if there is no match.
00586 */
00587 static int checkColumnOverLap(IdList *pIdList, ExprList *pEList){
00588   int e;
00589   if( !pIdList || !pEList ) return 1;
00590   for(e=0; e<pEList->nExpr; e++){
00591     if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
00592   }
00593   return 0; 
00594 }
00595 
00596 /*
00597 ** Return a bit vector to indicate what kind of triggers exist for operation
00598 ** "op" on table pTab.  If pChanges is not NULL then it is a list of columns
00599 ** that are being updated.  Triggers only match if the ON clause of the
00600 ** trigger definition overlaps the set of columns being updated.
00601 **
00602 ** The returned bit vector is some combination of TRIGGER_BEFORE and
00603 ** TRIGGER_AFTER.
00604 */
00605 int sqlite3TriggersExist(
00606   Parse *pParse,          /* Used to check for recursive triggers */
00607   Table *pTab,            /* The table the contains the triggers */
00608   int op,                 /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
00609   ExprList *pChanges      /* Columns that change in an UPDATE statement */
00610 ){
00611   Trigger *pTrigger;
00612   int mask = 0;
00613 
00614   pTrigger = IsVirtual(pTab) ? 0 : pTab->pTrigger;
00615   while( pTrigger ){
00616     if( pTrigger->op==op && checkColumnOverLap(pTrigger->pColumns, pChanges) ){
00617       mask |= pTrigger->tr_tm;
00618     }
00619     pTrigger = pTrigger->pNext;
00620   }
00621   return mask;
00622 }
00623 
00624 /*
00625 ** Convert the pStep->target token into a SrcList and return a pointer
00626 ** to that SrcList.
00627 **
00628 ** This routine adds a specific database name, if needed, to the target when
00629 ** forming the SrcList.  This prevents a trigger in one database from
00630 ** referring to a target in another database.  An exception is when the
00631 ** trigger is in TEMP in which case it can refer to any other database it
00632 ** wants.
00633 */
00634 static SrcList *targetSrcList(
00635   Parse *pParse,       /* The parsing context */
00636   TriggerStep *pStep   /* The trigger containing the target token */
00637 ){
00638   Token sDb;           /* Dummy database name token */
00639   int iDb;             /* Index of the database to use */
00640   SrcList *pSrc;       /* SrcList to be returned */
00641 
00642   iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
00643   if( iDb==0 || iDb>=2 ){
00644     assert( iDb<pParse->db->nDb );
00645     sDb.z = (u8*)pParse->db->aDb[iDb].zName;
00646     sDb.n = strlen((char*)sDb.z);
00647     pSrc = sqlite3SrcListAppend(pParse->db, 0, &sDb, &pStep->target);
00648   } else {
00649     pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
00650   }
00651   return pSrc;
00652 }
00653 
00654 /*
00655 ** Generate VDBE code for zero or more statements inside the body of a
00656 ** trigger.  
00657 */
00658 static int codeTriggerProgram(
00659   Parse *pParse,            /* The parser context */
00660   TriggerStep *pStepList,   /* List of statements inside the trigger body */
00661   int orconfin              /* Conflict algorithm. (OE_Abort, etc) */  
00662 ){
00663   TriggerStep * pTriggerStep = pStepList;
00664   int orconf;
00665   Vdbe *v = pParse->pVdbe;
00666   sqlite3 *db = pParse->db;
00667 
00668   assert( pTriggerStep!=0 );
00669   assert( v!=0 );
00670   sqlite3VdbeAddOp2(v, OP_ContextPush, 0, 0);
00671   VdbeComment((v, "begin trigger %s", pStepList->pTrig->name));
00672   while( pTriggerStep ){
00673     orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
00674     pParse->trigStack->orconf = orconf;
00675     switch( pTriggerStep->op ){
00676       case TK_SELECT: {
00677         Select *ss = sqlite3SelectDup(db, pTriggerStep->pSelect);
00678         if( ss ){
00679           SelectDest dest;
00680 
00681           sqlite3SelectDestInit(&dest, SRT_Discard, 0);
00682           sqlite3Select(pParse, ss, &dest);
00683           sqlite3SelectDelete(db, ss);
00684         }
00685         break;
00686       }
00687       case TK_UPDATE: {
00688         SrcList *pSrc;
00689         pSrc = targetSrcList(pParse, pTriggerStep);
00690         sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0);
00691         sqlite3Update(pParse, pSrc,
00692                 sqlite3ExprListDup(db, pTriggerStep->pExprList), 
00693                 sqlite3ExprDup(db, pTriggerStep->pWhere), orconf);
00694         sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
00695         break;
00696       }
00697       case TK_INSERT: {
00698         SrcList *pSrc;
00699         pSrc = targetSrcList(pParse, pTriggerStep);
00700         sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0);
00701         sqlite3Insert(pParse, pSrc,
00702           sqlite3ExprListDup(db, pTriggerStep->pExprList), 
00703           sqlite3SelectDup(db, pTriggerStep->pSelect), 
00704           sqlite3IdListDup(db, pTriggerStep->pIdList), orconf);
00705         sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
00706         break;
00707       }
00708       case TK_DELETE: {
00709         SrcList *pSrc;
00710         sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0);
00711         pSrc = targetSrcList(pParse, pTriggerStep);
00712         sqlite3DeleteFrom(pParse, pSrc, 
00713                           sqlite3ExprDup(db, pTriggerStep->pWhere));
00714         sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
00715         break;
00716       }
00717       default:
00718         assert(0);
00719     } 
00720     pTriggerStep = pTriggerStep->pNext;
00721   }
00722   sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0);
00723   VdbeComment((v, "end trigger %s", pStepList->pTrig->name));
00724 
00725   return 0;
00726 }
00727 
00728 /*
00729 ** This is called to code FOR EACH ROW triggers.
00730 **
00731 ** When the code that this function generates is executed, the following 
00732 ** must be true:
00733 **
00734 ** 1. No cursors may be open in the main database.  (But newIdx and oldIdx
00735 **    can be indices of cursors in temporary tables.  See below.)
00736 **
00737 ** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then
00738 **    a temporary vdbe cursor (index newIdx) must be open and pointing at
00739 **    a row containing values to be substituted for new.* expressions in the
00740 **    trigger program(s).
00741 **
00742 ** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then
00743 **    a temporary vdbe cursor (index oldIdx) must be open and pointing at
00744 **    a row containing values to be substituted for old.* expressions in the
00745 **    trigger program(s).
00746 **
00747 ** If they are not NULL, the piOldColMask and piNewColMask output variables
00748 ** are set to values that describe the columns used by the trigger program
00749 ** in the OLD.* and NEW.* tables respectively. If column N of the 
00750 ** pseudo-table is read at least once, the corresponding bit of the output
00751 ** mask is set. If a column with an index greater than 32 is read, the
00752 ** output mask is set to the special value 0xffffffff.
00753 **
00754 */
00755 int sqlite3CodeRowTrigger(
00756   Parse *pParse,       /* Parse context */
00757   int op,              /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
00758   ExprList *pChanges,  /* Changes list for any UPDATE OF triggers */
00759   int tr_tm,           /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
00760   Table *pTab,         /* The table to code triggers from */
00761   int newIdx,          /* The indice of the "new" row to access */
00762   int oldIdx,          /* The indice of the "old" row to access */
00763   int orconf,          /* ON CONFLICT policy */
00764   int ignoreJump,      /* Instruction to jump to for RAISE(IGNORE) */
00765   u32 *piOldColMask,   /* OUT: Mask of columns used from the OLD.* table */
00766   u32 *piNewColMask    /* OUT: Mask of columns used from the NEW.* table */
00767 ){
00768   Trigger *p;
00769   sqlite3 *db = pParse->db;
00770   TriggerStack trigStackEntry;
00771 
00772   trigStackEntry.oldColMask = 0;
00773   trigStackEntry.newColMask = 0;
00774 
00775   assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
00776   assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER );
00777 
00778   assert(newIdx != -1 || oldIdx != -1);
00779 
00780   for(p=pTab->pTrigger; p; p=p->pNext){
00781     int fire_this = 0;
00782 
00783     /* Determine whether we should code this trigger */
00784     if( 
00785       p->op==op && 
00786       p->tr_tm==tr_tm && 
00787       (p->pSchema==p->pTabSchema || p->pSchema==db->aDb[1].pSchema) &&
00788       (op!=TK_UPDATE||!p->pColumns||checkColumnOverLap(p->pColumns,pChanges))
00789     ){
00790       TriggerStack *pS;      /* Pointer to trigger-stack entry */
00791       for(pS=pParse->trigStack; pS && p!=pS->pTrigger; pS=pS->pNext){}
00792       if( !pS ){
00793         fire_this = 1;
00794       }
00795 #if 0    /* Give no warning for recursive triggers.  Just do not do them */
00796       else{
00797         sqlite3ErrorMsg(pParse, "recursive triggers not supported (%s)",
00798             p->name);
00799         return SQLITE_ERROR;
00800       }
00801 #endif
00802     }
00803  
00804     if( fire_this ){
00805       int endTrigger;
00806       Expr * whenExpr;
00807       AuthContext sContext;
00808       NameContext sNC;
00809 
00810 #ifndef SQLITE_OMIT_TRACE
00811       sqlite3VdbeAddOp4(pParse->pVdbe, OP_Trace, 0, 0, 0,
00812                         sqlite3MPrintf(db, "-- TRIGGER %s", p->name),
00813                         P4_DYNAMIC);
00814 #endif
00815       memset(&sNC, 0, sizeof(sNC));
00816       sNC.pParse = pParse;
00817 
00818       /* Push an entry on to the trigger stack */
00819       trigStackEntry.pTrigger = p;
00820       trigStackEntry.newIdx = newIdx;
00821       trigStackEntry.oldIdx = oldIdx;
00822       trigStackEntry.pTab = pTab;
00823       trigStackEntry.pNext = pParse->trigStack;
00824       trigStackEntry.ignoreJump = ignoreJump;
00825       pParse->trigStack = &trigStackEntry;
00826       sqlite3AuthContextPush(pParse, &sContext, p->name);
00827 
00828       /* code the WHEN clause */
00829       endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe);
00830       whenExpr = sqlite3ExprDup(db, p->pWhen);
00831       if( db->mallocFailed || sqlite3ResolveExprNames(&sNC, whenExpr) ){
00832         pParse->trigStack = trigStackEntry.pNext;
00833         sqlite3ExprDelete(db, whenExpr);
00834         return 1;
00835       }
00836       sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, SQLITE_JUMPIFNULL);
00837       sqlite3ExprDelete(db, whenExpr);
00838 
00839       codeTriggerProgram(pParse, p->step_list, orconf); 
00840 
00841       /* Pop the entry off the trigger stack */
00842       pParse->trigStack = trigStackEntry.pNext;
00843       sqlite3AuthContextPop(&sContext);
00844 
00845       sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger);
00846     }
00847   }
00848   if( piOldColMask ) *piOldColMask |= trigStackEntry.oldColMask;
00849   if( piNewColMask ) *piNewColMask |= trigStackEntry.newColMask;
00850   return 0;
00851 }
00852 #endif /* !defined(SQLITE_OMIT_TRIGGER) */

ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:56 2011 by Doxygen 1.6.1