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) */