extensions/sqlite/sqlite-source/trigger.c
changeset 1203 633c25ce6405
child 1645 27307df4d711
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/extensions/sqlite/sqlite-source/trigger.c	Sun Jul 29 01:15:31 2007 +0000
     1.3 @@ -0,0 +1,828 @@
     1.4 +/*
     1.5 +**
     1.6 +** The author disclaims copyright to this source code.  In place of
     1.7 +** a legal notice, here is a blessing:
     1.8 +**
     1.9 +**    May you do good and not evil.
    1.10 +**    May you find forgiveness for yourself and forgive others.
    1.11 +**    May you share freely, never taking more than you give.
    1.12 +**
    1.13 +*************************************************************************
    1.14 +*
    1.15 +*/
    1.16 +#include "sqliteInt.h"
    1.17 +
    1.18 +#ifndef SQLITE_OMIT_TRIGGER
    1.19 +/*
    1.20 +** Delete a linked list of TriggerStep structures.
    1.21 +*/
    1.22 +void sqlite3DeleteTriggerStep(TriggerStep *pTriggerStep){
    1.23 +  while( pTriggerStep ){
    1.24 +    TriggerStep * pTmp = pTriggerStep;
    1.25 +    pTriggerStep = pTriggerStep->pNext;
    1.26 +
    1.27 +    if( pTmp->target.dyn ) sqliteFree((char*)pTmp->target.z);
    1.28 +    sqlite3ExprDelete(pTmp->pWhere);
    1.29 +    sqlite3ExprListDelete(pTmp->pExprList);
    1.30 +    sqlite3SelectDelete(pTmp->pSelect);
    1.31 +    sqlite3IdListDelete(pTmp->pIdList);
    1.32 +
    1.33 +    sqliteFree(pTmp);
    1.34 +  }
    1.35 +}
    1.36 +
    1.37 +/*
    1.38 +** This is called by the parser when it sees a CREATE TRIGGER statement
    1.39 +** up to the point of the BEGIN before the trigger actions.  A Trigger
    1.40 +** structure is generated based on the information available and stored
    1.41 +** in pParse->pNewTrigger.  After the trigger actions have been parsed, the
    1.42 +** sqlite3FinishTrigger() function is called to complete the trigger
    1.43 +** construction process.
    1.44 +*/
    1.45 +void sqlite3BeginTrigger(
    1.46 +  Parse *pParse,      /* The parse context of the CREATE TRIGGER statement */
    1.47 +  Token *pName1,      /* The name of the trigger */
    1.48 +  Token *pName2,      /* The name of the trigger */
    1.49 +  int tr_tm,          /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
    1.50 +  int op,             /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
    1.51 +  IdList *pColumns,   /* column list if this is an UPDATE OF trigger */
    1.52 +  SrcList *pTableName,/* The name of the table/view the trigger applies to */
    1.53 +  Expr *pWhen,        /* WHEN clause */
    1.54 +  int isTemp,         /* True if the TEMPORARY keyword is present */
    1.55 +  int noErr           /* Suppress errors if the trigger already exists */
    1.56 +){
    1.57 +  Trigger *pTrigger = 0;
    1.58 +  Table *pTab;
    1.59 +  char *zName = 0;        /* Name of the trigger */
    1.60 +  sqlite3 *db = pParse->db;
    1.61 +  int iDb;                /* The database to store the trigger in */
    1.62 +  Token *pName;           /* The unqualified db name */
    1.63 +  DbFixer sFix;
    1.64 +  int iTabDb;
    1.65 +
    1.66 +  assert( pName1!=0 );   /* pName1->z might be NULL, but not pName1 itself */
    1.67 +  assert( pName2!=0 );
    1.68 +  if( isTemp ){
    1.69 +    /* If TEMP was specified, then the trigger name may not be qualified. */
    1.70 +    if( pName2->n>0 ){
    1.71 +      sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name");
    1.72 +      goto trigger_cleanup;
    1.73 +    }
    1.74 +    iDb = 1;
    1.75 +    pName = pName1;
    1.76 +  }else{
    1.77 +    /* Figure out the db that the the trigger will be created in */
    1.78 +    iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
    1.79 +    if( iDb<0 ){
    1.80 +      goto trigger_cleanup;
    1.81 +    }
    1.82 +  }
    1.83 +
    1.84 +  /* If the trigger name was unqualified, and the table is a temp table,
    1.85 +  ** then set iDb to 1 to create the trigger in the temporary database.
    1.86 +  ** If sqlite3SrcListLookup() returns 0, indicating the table does not
    1.87 +  ** exist, the error is caught by the block below.
    1.88 +  */
    1.89 +  if( !pTableName || sqlite3MallocFailed() ){
    1.90 +    goto trigger_cleanup;
    1.91 +  }
    1.92 +  pTab = sqlite3SrcListLookup(pParse, pTableName);
    1.93 +  if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
    1.94 +    iDb = 1;
    1.95 +  }
    1.96 +
    1.97 +  /* Ensure the table name matches database name and that the table exists */
    1.98 +  if( sqlite3MallocFailed() ) goto trigger_cleanup;
    1.99 +  assert( pTableName->nSrc==1 );
   1.100 +  if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && 
   1.101 +      sqlite3FixSrcList(&sFix, pTableName) ){
   1.102 +    goto trigger_cleanup;
   1.103 +  }
   1.104 +  pTab = sqlite3SrcListLookup(pParse, pTableName);
   1.105 +  if( !pTab ){
   1.106 +    /* The table does not exist. */
   1.107 +    goto trigger_cleanup;
   1.108 +  }
   1.109 +  if( IsVirtual(pTab) ){
   1.110 +    sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables");
   1.111 +    goto trigger_cleanup;
   1.112 +  }
   1.113 +
   1.114 +  /* Check that the trigger name is not reserved and that no trigger of the
   1.115 +  ** specified name exists */
   1.116 +  zName = sqlite3NameFromToken(pName);
   1.117 +  if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
   1.118 +    goto trigger_cleanup;
   1.119 +  }
   1.120 +  if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName,strlen(zName)) ){
   1.121 +    if( !noErr ){
   1.122 +      sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
   1.123 +    }
   1.124 +    goto trigger_cleanup;
   1.125 +  }
   1.126 +
   1.127 +  /* Do not create a trigger on a system table */
   1.128 +  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
   1.129 +    sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
   1.130 +    pParse->nErr++;
   1.131 +    goto trigger_cleanup;
   1.132 +  }
   1.133 +
   1.134 +  /* INSTEAD of triggers are only for views and views only support INSTEAD
   1.135 +  ** of triggers.
   1.136 +  */
   1.137 +  if( pTab->pSelect && tr_tm!=TK_INSTEAD ){
   1.138 +    sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", 
   1.139 +        (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
   1.140 +    goto trigger_cleanup;
   1.141 +  }
   1.142 +  if( !pTab->pSelect && tr_tm==TK_INSTEAD ){
   1.143 +    sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF"
   1.144 +        " trigger on table: %S", pTableName, 0);
   1.145 +    goto trigger_cleanup;
   1.146 +  }
   1.147 +  iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
   1.148 +
   1.149 +#ifndef SQLITE_OMIT_AUTHORIZATION
   1.150 +  {
   1.151 +    int code = SQLITE_CREATE_TRIGGER;
   1.152 +    const char *zDb = db->aDb[iTabDb].zName;
   1.153 +    const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
   1.154 +    if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
   1.155 +    if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
   1.156 +      goto trigger_cleanup;
   1.157 +    }
   1.158 +    if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){
   1.159 +      goto trigger_cleanup;
   1.160 +    }
   1.161 +  }
   1.162 +#endif
   1.163 +
   1.164 +  /* INSTEAD OF triggers can only appear on views and BEFORE triggers
   1.165 +  ** cannot appear on views.  So we might as well translate every
   1.166 +  ** INSTEAD OF trigger into a BEFORE trigger.  It simplifies code
   1.167 +  ** elsewhere.
   1.168 +  */
   1.169 +  if (tr_tm == TK_INSTEAD){
   1.170 +    tr_tm = TK_BEFORE;
   1.171 +  }
   1.172 +
   1.173 +  /* Build the Trigger object */
   1.174 +  pTrigger = (Trigger*)sqliteMalloc(sizeof(Trigger));
   1.175 +  if( pTrigger==0 ) goto trigger_cleanup;
   1.176 +  pTrigger->name = zName;
   1.177 +  zName = 0;
   1.178 +  pTrigger->table = sqliteStrDup(pTableName->a[0].zName);
   1.179 +  pTrigger->pSchema = db->aDb[iDb].pSchema;
   1.180 +  pTrigger->pTabSchema = pTab->pSchema;
   1.181 +  pTrigger->op = op;
   1.182 +  pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
   1.183 +  pTrigger->pWhen = sqlite3ExprDup(pWhen);
   1.184 +  pTrigger->pColumns = sqlite3IdListDup(pColumns);
   1.185 +  sqlite3TokenCopy(&pTrigger->nameToken,pName);
   1.186 +  assert( pParse->pNewTrigger==0 );
   1.187 +  pParse->pNewTrigger = pTrigger;
   1.188 +
   1.189 +trigger_cleanup:
   1.190 +  sqliteFree(zName);
   1.191 +  sqlite3SrcListDelete(pTableName);
   1.192 +  sqlite3IdListDelete(pColumns);
   1.193 +  sqlite3ExprDelete(pWhen);
   1.194 +  if( !pParse->pNewTrigger ){
   1.195 +    sqlite3DeleteTrigger(pTrigger);
   1.196 +  }else{
   1.197 +    assert( pParse->pNewTrigger==pTrigger );
   1.198 +  }
   1.199 +}
   1.200 +
   1.201 +/*
   1.202 +** This routine is called after all of the trigger actions have been parsed
   1.203 +** in order to complete the process of building the trigger.
   1.204 +*/
   1.205 +void sqlite3FinishTrigger(
   1.206 +  Parse *pParse,          /* Parser context */
   1.207 +  TriggerStep *pStepList, /* The triggered program */
   1.208 +  Token *pAll             /* Token that describes the complete CREATE TRIGGER */
   1.209 +){
   1.210 +  Trigger *pTrig = 0;     /* The trigger whose construction is finishing up */
   1.211 +  sqlite3 *db = pParse->db;  /* The database */
   1.212 +  DbFixer sFix;
   1.213 +  int iDb;                   /* Database containing the trigger */
   1.214 +
   1.215 +  pTrig = pParse->pNewTrigger;
   1.216 +  pParse->pNewTrigger = 0;
   1.217 +  if( pParse->nErr || !pTrig ) goto triggerfinish_cleanup;
   1.218 +  iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
   1.219 +  pTrig->step_list = pStepList;
   1.220 +  while( pStepList ){
   1.221 +    pStepList->pTrig = pTrig;
   1.222 +    pStepList = pStepList->pNext;
   1.223 +  }
   1.224 +  if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &pTrig->nameToken) 
   1.225 +          && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
   1.226 +    goto triggerfinish_cleanup;
   1.227 +  }
   1.228 +
   1.229 +  /* if we are not initializing, and this trigger is not on a TEMP table, 
   1.230 +  ** build the sqlite_master entry
   1.231 +  */
   1.232 +  if( !db->init.busy ){
   1.233 +    static const VdbeOpList insertTrig[] = {
   1.234 +      { OP_NewRowid,   0, 0,  0          },
   1.235 +      { OP_String8,    0, 0,  "trigger"  },
   1.236 +      { OP_String8,    0, 0,  0          },  /* 2: trigger name */
   1.237 +      { OP_String8,    0, 0,  0          },  /* 3: table name */
   1.238 +      { OP_Integer,    0, 0,  0          },
   1.239 +      { OP_String8,    0, 0,  "CREATE TRIGGER "},
   1.240 +      { OP_String8,    0, 0,  0          },  /* 6: SQL */
   1.241 +      { OP_Concat,     0, 0,  0          }, 
   1.242 +      { OP_MakeRecord, 5, 0,  "aaada"    },
   1.243 +      { OP_Insert,     0, 0,  0          },
   1.244 +    };
   1.245 +    int addr;
   1.246 +    Vdbe *v;
   1.247 +
   1.248 +    /* Make an entry in the sqlite_master table */
   1.249 +    v = sqlite3GetVdbe(pParse);
   1.250 +    if( v==0 ) goto triggerfinish_cleanup;
   1.251 +    sqlite3BeginWriteOperation(pParse, 0, iDb);
   1.252 +    sqlite3OpenMasterTable(pParse, iDb);
   1.253 +    addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
   1.254 +    sqlite3VdbeChangeP3(v, addr+2, pTrig->name, 0); 
   1.255 +    sqlite3VdbeChangeP3(v, addr+3, pTrig->table, 0); 
   1.256 +    sqlite3VdbeChangeP3(v, addr+6, (char*)pAll->z, pAll->n);
   1.257 +    sqlite3ChangeCookie(db, v, iDb);
   1.258 +    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
   1.259 +    sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, 
   1.260 +       sqlite3MPrintf("type='trigger' AND name='%q'", pTrig->name), P3_DYNAMIC);
   1.261 +  }
   1.262 +
   1.263 +  if( db->init.busy ){
   1.264 +    int n;
   1.265 +    Table *pTab;
   1.266 +    Trigger *pDel;
   1.267 +    pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash, 
   1.268 +                     pTrig->name, strlen(pTrig->name), pTrig);
   1.269 +    if( pDel ){
   1.270 +      assert( sqlite3MallocFailed() && pDel==pTrig );
   1.271 +      goto triggerfinish_cleanup;
   1.272 +    }
   1.273 +    n = strlen(pTrig->table) + 1;
   1.274 +    pTab = sqlite3HashFind(&pTrig->pTabSchema->tblHash, pTrig->table, n);
   1.275 +    assert( pTab!=0 );
   1.276 +    pTrig->pNext = pTab->pTrigger;
   1.277 +    pTab->pTrigger = pTrig;
   1.278 +    pTrig = 0;
   1.279 +  }
   1.280 +
   1.281 +triggerfinish_cleanup:
   1.282 +  sqlite3DeleteTrigger(pTrig);
   1.283 +  assert( !pParse->pNewTrigger );
   1.284 +  sqlite3DeleteTriggerStep(pStepList);
   1.285 +}
   1.286 +
   1.287 +/*
   1.288 +** Make a copy of all components of the given trigger step.  This has
   1.289 +** the effect of copying all Expr.token.z values into memory obtained
   1.290 +** from sqliteMalloc().  As initially created, the Expr.token.z values
   1.291 +** all point to the input string that was fed to the parser.  But that
   1.292 +** string is ephemeral - it will go away as soon as the sqlite3_exec()
   1.293 +** call that started the parser exits.  This routine makes a persistent
   1.294 +** copy of all the Expr.token.z strings so that the TriggerStep structure
   1.295 +** will be valid even after the sqlite3_exec() call returns.
   1.296 +*/
   1.297 +static void sqlitePersistTriggerStep(TriggerStep *p){
   1.298 +  if( p->target.z ){
   1.299 +    p->target.z = (u8*)sqliteStrNDup((char*)p->target.z, p->target.n);
   1.300 +    p->target.dyn = 1;
   1.301 +  }
   1.302 +  if( p->pSelect ){
   1.303 +    Select *pNew = sqlite3SelectDup(p->pSelect);
   1.304 +    sqlite3SelectDelete(p->pSelect);
   1.305 +    p->pSelect = pNew;
   1.306 +  }
   1.307 +  if( p->pWhere ){
   1.308 +    Expr *pNew = sqlite3ExprDup(p->pWhere);
   1.309 +    sqlite3ExprDelete(p->pWhere);
   1.310 +    p->pWhere = pNew;
   1.311 +  }
   1.312 +  if( p->pExprList ){
   1.313 +    ExprList *pNew = sqlite3ExprListDup(p->pExprList);
   1.314 +    sqlite3ExprListDelete(p->pExprList);
   1.315 +    p->pExprList = pNew;
   1.316 +  }
   1.317 +  if( p->pIdList ){
   1.318 +    IdList *pNew = sqlite3IdListDup(p->pIdList);
   1.319 +    sqlite3IdListDelete(p->pIdList);
   1.320 +    p->pIdList = pNew;
   1.321 +  }
   1.322 +}
   1.323 +
   1.324 +/*
   1.325 +** Turn a SELECT statement (that the pSelect parameter points to) into
   1.326 +** a trigger step.  Return a pointer to a TriggerStep structure.
   1.327 +**
   1.328 +** The parser calls this routine when it finds a SELECT statement in
   1.329 +** body of a TRIGGER.  
   1.330 +*/
   1.331 +TriggerStep *sqlite3TriggerSelectStep(Select *pSelect){
   1.332 +  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
   1.333 +  if( pTriggerStep==0 ) {
   1.334 +    sqlite3SelectDelete(pSelect);
   1.335 +    return 0;
   1.336 +  }
   1.337 +
   1.338 +  pTriggerStep->op = TK_SELECT;
   1.339 +  pTriggerStep->pSelect = pSelect;
   1.340 +  pTriggerStep->orconf = OE_Default;
   1.341 +  sqlitePersistTriggerStep(pTriggerStep);
   1.342 +
   1.343 +  return pTriggerStep;
   1.344 +}
   1.345 +
   1.346 +/*
   1.347 +** Build a trigger step out of an INSERT statement.  Return a pointer
   1.348 +** to the new trigger step.
   1.349 +**
   1.350 +** The parser calls this routine when it sees an INSERT inside the
   1.351 +** body of a trigger.
   1.352 +*/
   1.353 +TriggerStep *sqlite3TriggerInsertStep(
   1.354 +  Token *pTableName,  /* Name of the table into which we insert */
   1.355 +  IdList *pColumn,    /* List of columns in pTableName to insert into */
   1.356 +  ExprList *pEList,   /* The VALUE clause: a list of values to be inserted */
   1.357 +  Select *pSelect,    /* A SELECT statement that supplies values */
   1.358 +  int orconf          /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
   1.359 +){
   1.360 +  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
   1.361 +
   1.362 +  assert(pEList == 0 || pSelect == 0);
   1.363 +  assert(pEList != 0 || pSelect != 0);
   1.364 +
   1.365 +  if( pTriggerStep ){
   1.366 +    pTriggerStep->op = TK_INSERT;
   1.367 +    pTriggerStep->pSelect = pSelect;
   1.368 +    pTriggerStep->target  = *pTableName;
   1.369 +    pTriggerStep->pIdList = pColumn;
   1.370 +    pTriggerStep->pExprList = pEList;
   1.371 +    pTriggerStep->orconf = orconf;
   1.372 +    sqlitePersistTriggerStep(pTriggerStep);
   1.373 +  }else{
   1.374 +    sqlite3IdListDelete(pColumn);
   1.375 +    sqlite3ExprListDelete(pEList);
   1.376 +    sqlite3SelectDup(pSelect);
   1.377 +  }
   1.378 +
   1.379 +  return pTriggerStep;
   1.380 +}
   1.381 +
   1.382 +/*
   1.383 +** Construct a trigger step that implements an UPDATE statement and return
   1.384 +** a pointer to that trigger step.  The parser calls this routine when it
   1.385 +** sees an UPDATE statement inside the body of a CREATE TRIGGER.
   1.386 +*/
   1.387 +TriggerStep *sqlite3TriggerUpdateStep(
   1.388 +  Token *pTableName,   /* Name of the table to be updated */
   1.389 +  ExprList *pEList,    /* The SET clause: list of column and new values */
   1.390 +  Expr *pWhere,        /* The WHERE clause */
   1.391 +  int orconf           /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
   1.392 +){
   1.393 +  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
   1.394 +  if( pTriggerStep==0 ){
   1.395 +     sqlite3ExprListDelete(pEList);
   1.396 +     sqlite3ExprDelete(pWhere);
   1.397 +     return 0;
   1.398 +  }
   1.399 +
   1.400 +  pTriggerStep->op = TK_UPDATE;
   1.401 +  pTriggerStep->target  = *pTableName;
   1.402 +  pTriggerStep->pExprList = pEList;
   1.403 +  pTriggerStep->pWhere = pWhere;
   1.404 +  pTriggerStep->orconf = orconf;
   1.405 +  sqlitePersistTriggerStep(pTriggerStep);
   1.406 +
   1.407 +  return pTriggerStep;
   1.408 +}
   1.409 +
   1.410 +/*
   1.411 +** Construct a trigger step that implements a DELETE statement and return
   1.412 +** a pointer to that trigger step.  The parser calls this routine when it
   1.413 +** sees a DELETE statement inside the body of a CREATE TRIGGER.
   1.414 +*/
   1.415 +TriggerStep *sqlite3TriggerDeleteStep(Token *pTableName, Expr *pWhere){
   1.416 +  TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
   1.417 +  if( pTriggerStep==0 ){
   1.418 +    sqlite3ExprDelete(pWhere);
   1.419 +    return 0;
   1.420 +  }
   1.421 +
   1.422 +  pTriggerStep->op = TK_DELETE;
   1.423 +  pTriggerStep->target  = *pTableName;
   1.424 +  pTriggerStep->pWhere = pWhere;
   1.425 +  pTriggerStep->orconf = OE_Default;
   1.426 +  sqlitePersistTriggerStep(pTriggerStep);
   1.427 +
   1.428 +  return pTriggerStep;
   1.429 +}
   1.430 +
   1.431 +/* 
   1.432 +** Recursively delete a Trigger structure
   1.433 +*/
   1.434 +void sqlite3DeleteTrigger(Trigger *pTrigger){
   1.435 +  if( pTrigger==0 ) return;
   1.436 +  sqlite3DeleteTriggerStep(pTrigger->step_list);
   1.437 +  sqliteFree(pTrigger->name);
   1.438 +  sqliteFree(pTrigger->table);
   1.439 +  sqlite3ExprDelete(pTrigger->pWhen);
   1.440 +  sqlite3IdListDelete(pTrigger->pColumns);
   1.441 +  if( pTrigger->nameToken.dyn ) sqliteFree((char*)pTrigger->nameToken.z);
   1.442 +  sqliteFree(pTrigger);
   1.443 +}
   1.444 +
   1.445 +/*
   1.446 +** This function is called to drop a trigger from the database schema. 
   1.447 +**
   1.448 +** This may be called directly from the parser and therefore identifies
   1.449 +** the trigger by name.  The sqlite3DropTriggerPtr() routine does the
   1.450 +** same job as this routine except it takes a pointer to the trigger
   1.451 +** instead of the trigger name.
   1.452 +**/
   1.453 +void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
   1.454 +  Trigger *pTrigger = 0;
   1.455 +  int i;
   1.456 +  const char *zDb;
   1.457 +  const char *zName;
   1.458 +  int nName;
   1.459 +  sqlite3 *db = pParse->db;
   1.460 +
   1.461 +  if( sqlite3MallocFailed() ) goto drop_trigger_cleanup;
   1.462 +  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
   1.463 +    goto drop_trigger_cleanup;
   1.464 +  }
   1.465 +
   1.466 +  assert( pName->nSrc==1 );
   1.467 +  zDb = pName->a[0].zDatabase;
   1.468 +  zName = pName->a[0].zName;
   1.469 +  nName = strlen(zName);
   1.470 +  for(i=OMIT_TEMPDB; i<db->nDb; i++){
   1.471 +    int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
   1.472 +    if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
   1.473 +    pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName);
   1.474 +    if( pTrigger ) break;
   1.475 +  }
   1.476 +  if( !pTrigger ){
   1.477 +    if( !noErr ){
   1.478 +      sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
   1.479 +    }
   1.480 +    goto drop_trigger_cleanup;
   1.481 +  }
   1.482 +  sqlite3DropTriggerPtr(pParse, pTrigger);
   1.483 +
   1.484 +drop_trigger_cleanup:
   1.485 +  sqlite3SrcListDelete(pName);
   1.486 +}
   1.487 +
   1.488 +/*
   1.489 +** Return a pointer to the Table structure for the table that a trigger
   1.490 +** is set on.
   1.491 +*/
   1.492 +static Table *tableOfTrigger(Trigger *pTrigger){
   1.493 +  int n = strlen(pTrigger->table) + 1;
   1.494 +  return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table, n);
   1.495 +}
   1.496 +
   1.497 +
   1.498 +/*
   1.499 +** Drop a trigger given a pointer to that trigger. 
   1.500 +*/
   1.501 +void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
   1.502 +  Table   *pTable;
   1.503 +  Vdbe *v;
   1.504 +  sqlite3 *db = pParse->db;
   1.505 +  int iDb;
   1.506 +
   1.507 +  iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema);
   1.508 +  assert( iDb>=0 && iDb<db->nDb );
   1.509 +  pTable = tableOfTrigger(pTrigger);
   1.510 +  assert( pTable );
   1.511 +  assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
   1.512 +#ifndef SQLITE_OMIT_AUTHORIZATION
   1.513 +  {
   1.514 +    int code = SQLITE_DROP_TRIGGER;
   1.515 +    const char *zDb = db->aDb[iDb].zName;
   1.516 +    const char *zTab = SCHEMA_TABLE(iDb);
   1.517 +    if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
   1.518 +    if( sqlite3AuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
   1.519 +      sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
   1.520 +      return;
   1.521 +    }
   1.522 +  }
   1.523 +#endif
   1.524 +
   1.525 +  /* Generate code to destroy the database record of the trigger.
   1.526 +  */
   1.527 +  assert( pTable!=0 );
   1.528 +  if( (v = sqlite3GetVdbe(pParse))!=0 ){
   1.529 +    int base;
   1.530 +    static const VdbeOpList dropTrigger[] = {
   1.531 +      { OP_Rewind,     0, ADDR(9),  0},
   1.532 +      { OP_String8,    0, 0,        0}, /* 1 */
   1.533 +      { OP_Column,     0, 1,        0},
   1.534 +      { OP_Ne,         0, ADDR(8),  0},
   1.535 +      { OP_String8,    0, 0,        "trigger"},
   1.536 +      { OP_Column,     0, 0,        0},
   1.537 +      { OP_Ne,         0, ADDR(8),  0},
   1.538 +      { OP_Delete,     0, 0,        0},
   1.539 +      { OP_Next,       0, ADDR(1),  0}, /* 8 */
   1.540 +    };
   1.541 +
   1.542 +    sqlite3BeginWriteOperation(pParse, 0, iDb);
   1.543 +    sqlite3OpenMasterTable(pParse, iDb);
   1.544 +    base = sqlite3VdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
   1.545 +    sqlite3VdbeChangeP3(v, base+1, pTrigger->name, 0);
   1.546 +    sqlite3ChangeCookie(db, v, iDb);
   1.547 +    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
   1.548 +    sqlite3VdbeOp3(v, OP_DropTrigger, iDb, 0, pTrigger->name, 0);
   1.549 +  }
   1.550 +}
   1.551 +
   1.552 +/*
   1.553 +** Remove a trigger from the hash tables of the sqlite* pointer.
   1.554 +*/
   1.555 +void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
   1.556 +  Trigger *pTrigger;
   1.557 +  int nName = strlen(zName);
   1.558 +  pTrigger = sqlite3HashInsert(&(db->aDb[iDb].pSchema->trigHash),
   1.559 +                               zName, nName, 0);
   1.560 +  if( pTrigger ){
   1.561 +    Table *pTable = tableOfTrigger(pTrigger);
   1.562 +    assert( pTable!=0 );
   1.563 +    if( pTable->pTrigger == pTrigger ){
   1.564 +      pTable->pTrigger = pTrigger->pNext;
   1.565 +    }else{
   1.566 +      Trigger *cc = pTable->pTrigger;
   1.567 +      while( cc ){ 
   1.568 +        if( cc->pNext == pTrigger ){
   1.569 +          cc->pNext = cc->pNext->pNext;
   1.570 +          break;
   1.571 +        }
   1.572 +        cc = cc->pNext;
   1.573 +      }
   1.574 +      assert(cc);
   1.575 +    }
   1.576 +    sqlite3DeleteTrigger(pTrigger);
   1.577 +    db->flags |= SQLITE_InternChanges;
   1.578 +  }
   1.579 +}
   1.580 +
   1.581 +/*
   1.582 +** pEList is the SET clause of an UPDATE statement.  Each entry
   1.583 +** in pEList is of the format <id>=<expr>.  If any of the entries
   1.584 +** in pEList have an <id> which matches an identifier in pIdList,
   1.585 +** then return TRUE.  If pIdList==NULL, then it is considered a
   1.586 +** wildcard that matches anything.  Likewise if pEList==NULL then
   1.587 +** it matches anything so always return true.  Return false only
   1.588 +** if there is no match.
   1.589 +*/
   1.590 +static int checkColumnOverLap(IdList *pIdList, ExprList *pEList){
   1.591 +  int e;
   1.592 +  if( !pIdList || !pEList ) return 1;
   1.593 +  for(e=0; e<pEList->nExpr; e++){
   1.594 +    if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
   1.595 +  }
   1.596 +  return 0; 
   1.597 +}
   1.598 +
   1.599 +/*
   1.600 +** Return a bit vector to indicate what kind of triggers exist for operation
   1.601 +** "op" on table pTab.  If pChanges is not NULL then it is a list of columns
   1.602 +** that are being updated.  Triggers only match if the ON clause of the
   1.603 +** trigger definition overlaps the set of columns being updated.
   1.604 +**
   1.605 +** The returned bit vector is some combination of TRIGGER_BEFORE and
   1.606 +** TRIGGER_AFTER.
   1.607 +*/
   1.608 +int sqlite3TriggersExist(
   1.609 +  Parse *pParse,          /* Used to check for recursive triggers */
   1.610 +  Table *pTab,            /* The table the contains the triggers */
   1.611 +  int op,                 /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
   1.612 +  ExprList *pChanges      /* Columns that change in an UPDATE statement */
   1.613 +){
   1.614 +  Trigger *pTrigger;
   1.615 +  int mask = 0;
   1.616 +
   1.617 +  pTrigger = IsVirtual(pTab) ? 0 : pTab->pTrigger;
   1.618 +  while( pTrigger ){
   1.619 +    if( pTrigger->op==op && checkColumnOverLap(pTrigger->pColumns, pChanges) ){
   1.620 +      mask |= pTrigger->tr_tm;
   1.621 +    }
   1.622 +    pTrigger = pTrigger->pNext;
   1.623 +  }
   1.624 +  return mask;
   1.625 +}
   1.626 +
   1.627 +/*
   1.628 +** Convert the pStep->target token into a SrcList and return a pointer
   1.629 +** to that SrcList.
   1.630 +**
   1.631 +** This routine adds a specific database name, if needed, to the target when
   1.632 +** forming the SrcList.  This prevents a trigger in one database from
   1.633 +** referring to a target in another database.  An exception is when the
   1.634 +** trigger is in TEMP in which case it can refer to any other database it
   1.635 +** wants.
   1.636 +*/
   1.637 +static SrcList *targetSrcList(
   1.638 +  Parse *pParse,       /* The parsing context */
   1.639 +  TriggerStep *pStep   /* The trigger containing the target token */
   1.640 +){
   1.641 +  Token sDb;           /* Dummy database name token */
   1.642 +  int iDb;             /* Index of the database to use */
   1.643 +  SrcList *pSrc;       /* SrcList to be returned */
   1.644 +
   1.645 +  iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
   1.646 +  if( iDb==0 || iDb>=2 ){
   1.647 +    assert( iDb<pParse->db->nDb );
   1.648 +    sDb.z = (u8*)pParse->db->aDb[iDb].zName;
   1.649 +    sDb.n = strlen((char*)sDb.z);
   1.650 +    pSrc = sqlite3SrcListAppend(0, &sDb, &pStep->target);
   1.651 +  } else {
   1.652 +    pSrc = sqlite3SrcListAppend(0, &pStep->target, 0);
   1.653 +  }
   1.654 +  return pSrc;
   1.655 +}
   1.656 +
   1.657 +/*
   1.658 +** Generate VDBE code for zero or more statements inside the body of a
   1.659 +** trigger.  
   1.660 +*/
   1.661 +static int codeTriggerProgram(
   1.662 +  Parse *pParse,            /* The parser context */
   1.663 +  TriggerStep *pStepList,   /* List of statements inside the trigger body */
   1.664 +  int orconfin              /* Conflict algorithm. (OE_Abort, etc) */  
   1.665 +){
   1.666 +  TriggerStep * pTriggerStep = pStepList;
   1.667 +  int orconf;
   1.668 +  Vdbe *v = pParse->pVdbe;
   1.669 +
   1.670 +  assert( pTriggerStep!=0 );
   1.671 +  assert( v!=0 );
   1.672 +  sqlite3VdbeAddOp(v, OP_ContextPush, 0, 0);
   1.673 +  VdbeComment((v, "# begin trigger %s", pStepList->pTrig->name));
   1.674 +  while( pTriggerStep ){
   1.675 +    orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
   1.676 +    pParse->trigStack->orconf = orconf;
   1.677 +    switch( pTriggerStep->op ){
   1.678 +      case TK_SELECT: {
   1.679 +	Select *ss = sqlite3SelectDup(pTriggerStep->pSelect);
   1.680 +        if( ss ){
   1.681 +          sqlite3SelectResolve(pParse, ss, 0);
   1.682 +          sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0, 0);
   1.683 +          sqlite3SelectDelete(ss);
   1.684 +        }
   1.685 +	break;
   1.686 +      }
   1.687 +      case TK_UPDATE: {
   1.688 +        SrcList *pSrc;
   1.689 +        pSrc = targetSrcList(pParse, pTriggerStep);
   1.690 +        sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
   1.691 +        sqlite3Update(pParse, pSrc,
   1.692 +		sqlite3ExprListDup(pTriggerStep->pExprList), 
   1.693 +		sqlite3ExprDup(pTriggerStep->pWhere), orconf);
   1.694 +        sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
   1.695 +        break;
   1.696 +      }
   1.697 +      case TK_INSERT: {
   1.698 +        SrcList *pSrc;
   1.699 +        pSrc = targetSrcList(pParse, pTriggerStep);
   1.700 +        sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
   1.701 +        sqlite3Insert(pParse, pSrc,
   1.702 +          sqlite3ExprListDup(pTriggerStep->pExprList), 
   1.703 +          sqlite3SelectDup(pTriggerStep->pSelect), 
   1.704 +          sqlite3IdListDup(pTriggerStep->pIdList), orconf);
   1.705 +        sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
   1.706 +        break;
   1.707 +      }
   1.708 +      case TK_DELETE: {
   1.709 +        SrcList *pSrc;
   1.710 +        sqlite3VdbeAddOp(v, OP_ResetCount, 0, 0);
   1.711 +        pSrc = targetSrcList(pParse, pTriggerStep);
   1.712 +        sqlite3DeleteFrom(pParse, pSrc, sqlite3ExprDup(pTriggerStep->pWhere));
   1.713 +        sqlite3VdbeAddOp(v, OP_ResetCount, 1, 0);
   1.714 +        break;
   1.715 +      }
   1.716 +      default:
   1.717 +        assert(0);
   1.718 +    } 
   1.719 +    pTriggerStep = pTriggerStep->pNext;
   1.720 +  }
   1.721 +  sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
   1.722 +  VdbeComment((v, "# end trigger %s", pStepList->pTrig->name));
   1.723 +
   1.724 +  return 0;
   1.725 +}
   1.726 +
   1.727 +/*
   1.728 +** This is called to code FOR EACH ROW triggers.
   1.729 +**
   1.730 +** When the code that this function generates is executed, the following 
   1.731 +** must be true:
   1.732 +**
   1.733 +** 1. No cursors may be open in the main database.  (But newIdx and oldIdx
   1.734 +**    can be indices of cursors in temporary tables.  See below.)
   1.735 +**
   1.736 +** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then
   1.737 +**    a temporary vdbe cursor (index newIdx) must be open and pointing at
   1.738 +**    a row containing values to be substituted for new.* expressions in the
   1.739 +**    trigger program(s).
   1.740 +**
   1.741 +** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then
   1.742 +**    a temporary vdbe cursor (index oldIdx) must be open and pointing at
   1.743 +**    a row containing values to be substituted for old.* expressions in the
   1.744 +**    trigger program(s).
   1.745 +**
   1.746 +*/
   1.747 +int sqlite3CodeRowTrigger(
   1.748 +  Parse *pParse,       /* Parse context */
   1.749 +  int op,              /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
   1.750 +  ExprList *pChanges,  /* Changes list for any UPDATE OF triggers */
   1.751 +  int tr_tm,           /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
   1.752 +  Table *pTab,         /* The table to code triggers from */
   1.753 +  int newIdx,          /* The indice of the "new" row to access */
   1.754 +  int oldIdx,          /* The indice of the "old" row to access */
   1.755 +  int orconf,          /* ON CONFLICT policy */
   1.756 +  int ignoreJump       /* Instruction to jump to for RAISE(IGNORE) */
   1.757 +){
   1.758 +  Trigger *p;
   1.759 +  TriggerStack trigStackEntry;
   1.760 +
   1.761 +  assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
   1.762 +  assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER );
   1.763 +
   1.764 +  assert(newIdx != -1 || oldIdx != -1);
   1.765 +
   1.766 +  for(p=pTab->pTrigger; p; p=p->pNext){
   1.767 +    int fire_this = 0;
   1.768 +
   1.769 +    /* Determine whether we should code this trigger */
   1.770 +    if( 
   1.771 +      p->op==op && 
   1.772 +      p->tr_tm==tr_tm && 
   1.773 +      (p->pSchema==p->pTabSchema || p->pSchema==pParse->db->aDb[1].pSchema) &&
   1.774 +      (op!=TK_UPDATE||!p->pColumns||checkColumnOverLap(p->pColumns,pChanges))
   1.775 +    ){
   1.776 +      TriggerStack *pS;      /* Pointer to trigger-stack entry */
   1.777 +      for(pS=pParse->trigStack; pS && p!=pS->pTrigger; pS=pS->pNext){}
   1.778 +      if( !pS ){
   1.779 +        fire_this = 1;
   1.780 +      }
   1.781 +#if 0    /* Give no warning for recursive triggers.  Just do not do them */
   1.782 +      else{
   1.783 +        sqlite3ErrorMsg(pParse, "recursive triggers not supported (%s)",
   1.784 +            p->name);
   1.785 +        return SQLITE_ERROR;
   1.786 +      }
   1.787 +#endif
   1.788 +    }
   1.789 + 
   1.790 +    if( fire_this ){
   1.791 +      int endTrigger;
   1.792 +      Expr * whenExpr;
   1.793 +      AuthContext sContext;
   1.794 +      NameContext sNC;
   1.795 +
   1.796 +      memset(&sNC, 0, sizeof(sNC));
   1.797 +      sNC.pParse = pParse;
   1.798 +
   1.799 +      /* Push an entry on to the trigger stack */
   1.800 +      trigStackEntry.pTrigger = p;
   1.801 +      trigStackEntry.newIdx = newIdx;
   1.802 +      trigStackEntry.oldIdx = oldIdx;
   1.803 +      trigStackEntry.pTab = pTab;
   1.804 +      trigStackEntry.pNext = pParse->trigStack;
   1.805 +      trigStackEntry.ignoreJump = ignoreJump;
   1.806 +      pParse->trigStack = &trigStackEntry;
   1.807 +      sqlite3AuthContextPush(pParse, &sContext, p->name);
   1.808 +
   1.809 +      /* code the WHEN clause */
   1.810 +      endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe);
   1.811 +      whenExpr = sqlite3ExprDup(p->pWhen);
   1.812 +      if( sqlite3ExprResolveNames(&sNC, whenExpr) ){
   1.813 +        pParse->trigStack = trigStackEntry.pNext;
   1.814 +        sqlite3ExprDelete(whenExpr);
   1.815 +        return 1;
   1.816 +      }
   1.817 +      sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1);
   1.818 +      sqlite3ExprDelete(whenExpr);
   1.819 +
   1.820 +      codeTriggerProgram(pParse, p->step_list, orconf); 
   1.821 +
   1.822 +      /* Pop the entry off the trigger stack */
   1.823 +      pParse->trigStack = trigStackEntry.pNext;
   1.824 +      sqlite3AuthContextPop(&sContext);
   1.825 +
   1.826 +      sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger);
   1.827 +    }
   1.828 +  }
   1.829 +  return 0;
   1.830 +}
   1.831 +#endif /* !defined(SQLITE_OMIT_TRIGGER) */