1 : /*
2 : **
3 : ** The author disclaims copyright to this source code. In place of
4 : ** a legal notice, here is a blessing:
5 : **
6 : ** May you do good and not evil.
7 : ** May you find forgiveness for yourself and forgive others.
8 : ** May you share freely, never taking more than you give.
9 : **
10 : *************************************************************************
11 : *
12 : */
13 : #include "sqliteInt.h"
14 :
15 : /*
16 : ** Delete a linked list of TriggerStep structures.
17 : */
18 0 : void sqliteDeleteTriggerStep(TriggerStep *pTriggerStep){
19 0 : while( pTriggerStep ){
20 0 : TriggerStep * pTmp = pTriggerStep;
21 0 : pTriggerStep = pTriggerStep->pNext;
22 :
23 0 : if( pTmp->target.dyn ) sqliteFree((char*)pTmp->target.z);
24 0 : sqliteExprDelete(pTmp->pWhere);
25 0 : sqliteExprListDelete(pTmp->pExprList);
26 0 : sqliteSelectDelete(pTmp->pSelect);
27 0 : sqliteIdListDelete(pTmp->pIdList);
28 :
29 0 : sqliteFree(pTmp);
30 : }
31 0 : }
32 :
33 : /*
34 : ** This is called by the parser when it sees a CREATE TRIGGER statement
35 : ** up to the point of the BEGIN before the trigger actions. A Trigger
36 : ** structure is generated based on the information available and stored
37 : ** in pParse->pNewTrigger. After the trigger actions have been parsed, the
38 : ** sqliteFinishTrigger() function is called to complete the trigger
39 : ** construction process.
40 : */
41 : void sqliteBeginTrigger(
42 : Parse *pParse, /* The parse context of the CREATE TRIGGER statement */
43 : Token *pName, /* The name of the trigger */
44 : int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
45 : int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
46 : IdList *pColumns, /* column list if this is an UPDATE OF trigger */
47 : SrcList *pTableName,/* The name of the table/view the trigger applies to */
48 : int foreach, /* One of TK_ROW or TK_STATEMENT */
49 : Expr *pWhen, /* WHEN clause */
50 : int isTemp /* True if the TEMPORARY keyword is present */
51 0 : ){
52 : Trigger *nt;
53 : Table *tab;
54 0 : char *zName = 0; /* Name of the trigger */
55 0 : sqlite *db = pParse->db;
56 : int iDb; /* When database to store the trigger in */
57 : DbFixer sFix;
58 :
59 : /* Check that:
60 : ** 1. the trigger name does not already exist.
61 : ** 2. the table (or view) does exist in the same database as the trigger.
62 : ** 3. that we are not trying to create a trigger on the sqlite_master table
63 : ** 4. That we are not trying to create an INSTEAD OF trigger on a table.
64 : ** 5. That we are not trying to create a BEFORE or AFTER trigger on a view.
65 : */
66 0 : if( sqlite_malloc_failed ) goto trigger_cleanup;
67 : assert( pTableName->nSrc==1 );
68 0 : if( db->init.busy
69 : && sqliteFixInit(&sFix, pParse, db->init.iDb, "trigger", pName)
70 : && sqliteFixSrcList(&sFix, pTableName)
71 : ){
72 0 : goto trigger_cleanup;
73 : }
74 0 : tab = sqliteSrcListLookup(pParse, pTableName);
75 0 : if( !tab ){
76 0 : goto trigger_cleanup;
77 : }
78 0 : iDb = isTemp ? 1 : tab->iDb;
79 0 : if( iDb>=2 && !db->init.busy ){
80 0 : sqliteErrorMsg(pParse, "triggers may not be added to auxiliary "
81 : "database %s", db->aDb[tab->iDb].zName);
82 0 : goto trigger_cleanup;
83 : }
84 :
85 0 : zName = sqliteStrNDup(pName->z, pName->n);
86 0 : sqliteDequote(zName);
87 0 : if( sqliteHashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){
88 0 : sqliteErrorMsg(pParse, "trigger %T already exists", pName);
89 0 : goto trigger_cleanup;
90 : }
91 0 : if( sqliteStrNICmp(tab->zName, "sqlite_", 7)==0 ){
92 0 : sqliteErrorMsg(pParse, "cannot create trigger on system table");
93 0 : pParse->nErr++;
94 0 : goto trigger_cleanup;
95 : }
96 0 : if( tab->pSelect && tr_tm != TK_INSTEAD ){
97 0 : sqliteErrorMsg(pParse, "cannot create %s trigger on view: %S",
98 : (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
99 0 : goto trigger_cleanup;
100 : }
101 0 : if( !tab->pSelect && tr_tm == TK_INSTEAD ){
102 0 : sqliteErrorMsg(pParse, "cannot create INSTEAD OF"
103 : " trigger on table: %S", pTableName, 0);
104 0 : goto trigger_cleanup;
105 : }
106 : #ifndef SQLITE_OMIT_AUTHORIZATION
107 : {
108 0 : int code = SQLITE_CREATE_TRIGGER;
109 0 : const char *zDb = db->aDb[tab->iDb].zName;
110 0 : const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
111 0 : if( tab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
112 0 : if( sqliteAuthCheck(pParse, code, zName, tab->zName, zDbTrig) ){
113 0 : goto trigger_cleanup;
114 : }
115 0 : if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(tab->iDb), 0, zDb)){
116 0 : goto trigger_cleanup;
117 : }
118 : }
119 : #endif
120 :
121 : /* INSTEAD OF triggers can only appear on views and BEGIN triggers
122 : ** cannot appear on views. So we might as well translate every
123 : ** INSTEAD OF trigger into a BEFORE trigger. It simplifies code
124 : ** elsewhere.
125 : */
126 0 : if (tr_tm == TK_INSTEAD){
127 0 : tr_tm = TK_BEFORE;
128 : }
129 :
130 : /* Build the Trigger object */
131 0 : nt = (Trigger*)sqliteMalloc(sizeof(Trigger));
132 0 : if( nt==0 ) goto trigger_cleanup;
133 0 : nt->name = zName;
134 0 : zName = 0;
135 0 : nt->table = sqliteStrDup(pTableName->a[0].zName);
136 0 : if( sqlite_malloc_failed ) goto trigger_cleanup;
137 0 : nt->iDb = iDb;
138 0 : nt->iTabDb = tab->iDb;
139 0 : nt->op = op;
140 0 : nt->tr_tm = tr_tm;
141 0 : nt->pWhen = sqliteExprDup(pWhen);
142 0 : nt->pColumns = sqliteIdListDup(pColumns);
143 0 : nt->foreach = foreach;
144 0 : sqliteTokenCopy(&nt->nameToken,pName);
145 : assert( pParse->pNewTrigger==0 );
146 0 : pParse->pNewTrigger = nt;
147 :
148 0 : trigger_cleanup:
149 0 : sqliteFree(zName);
150 0 : sqliteSrcListDelete(pTableName);
151 0 : sqliteIdListDelete(pColumns);
152 0 : sqliteExprDelete(pWhen);
153 0 : }
154 :
155 : /*
156 : ** This routine is called after all of the trigger actions have been parsed
157 : ** in order to complete the process of building the trigger.
158 : */
159 : void sqliteFinishTrigger(
160 : Parse *pParse, /* Parser context */
161 : TriggerStep *pStepList, /* The triggered program */
162 : Token *pAll /* Token that describes the complete CREATE TRIGGER */
163 0 : ){
164 0 : Trigger *nt = 0; /* The trigger whose construction is finishing up */
165 0 : sqlite *db = pParse->db; /* The database */
166 : DbFixer sFix;
167 :
168 0 : if( pParse->nErr || pParse->pNewTrigger==0 ) goto triggerfinish_cleanup;
169 0 : nt = pParse->pNewTrigger;
170 0 : pParse->pNewTrigger = 0;
171 0 : nt->step_list = pStepList;
172 0 : while( pStepList ){
173 0 : pStepList->pTrig = nt;
174 0 : pStepList = pStepList->pNext;
175 : }
176 0 : if( sqliteFixInit(&sFix, pParse, nt->iDb, "trigger", &nt->nameToken)
177 : && sqliteFixTriggerStep(&sFix, nt->step_list) ){
178 0 : goto triggerfinish_cleanup;
179 : }
180 :
181 : /* if we are not initializing, and this trigger is not on a TEMP table,
182 : ** build the sqlite_master entry
183 : */
184 0 : if( !db->init.busy ){
185 : static VdbeOpList insertTrig[] = {
186 : { OP_NewRecno, 0, 0, 0 },
187 : { OP_String, 0, 0, "trigger" },
188 : { OP_String, 0, 0, 0 }, /* 2: trigger name */
189 : { OP_String, 0, 0, 0 }, /* 3: table name */
190 : { OP_Integer, 0, 0, 0 },
191 : { OP_String, 0, 0, 0 }, /* 5: SQL */
192 : { OP_MakeRecord, 5, 0, 0 },
193 : { OP_PutIntKey, 0, 0, 0 },
194 : };
195 : int addr;
196 : Vdbe *v;
197 :
198 : /* Make an entry in the sqlite_master table */
199 0 : v = sqliteGetVdbe(pParse);
200 0 : if( v==0 ) goto triggerfinish_cleanup;
201 0 : sqliteBeginWriteOperation(pParse, 0, 0);
202 0 : sqliteOpenMasterTable(v, nt->iDb);
203 0 : addr = sqliteVdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
204 0 : sqliteVdbeChangeP3(v, addr+2, nt->name, 0);
205 0 : sqliteVdbeChangeP3(v, addr+3, nt->table, 0);
206 0 : sqliteVdbeChangeP3(v, addr+5, pAll->z, pAll->n);
207 0 : if( nt->iDb==0 ){
208 0 : sqliteChangeCookie(db, v);
209 : }
210 0 : sqliteVdbeAddOp(v, OP_Close, 0, 0);
211 0 : sqliteEndWriteOperation(pParse);
212 : }
213 :
214 0 : if( !pParse->explain ){
215 : Table *pTab;
216 0 : sqliteHashInsert(&db->aDb[nt->iDb].trigHash,
217 : nt->name, strlen(nt->name)+1, nt);
218 0 : pTab = sqliteLocateTable(pParse, nt->table, db->aDb[nt->iTabDb].zName);
219 : assert( pTab!=0 );
220 0 : nt->pNext = pTab->pTrigger;
221 0 : pTab->pTrigger = nt;
222 0 : nt = 0;
223 : }
224 :
225 0 : triggerfinish_cleanup:
226 0 : sqliteDeleteTrigger(nt);
227 0 : sqliteDeleteTrigger(pParse->pNewTrigger);
228 0 : pParse->pNewTrigger = 0;
229 0 : sqliteDeleteTriggerStep(pStepList);
230 0 : }
231 :
232 : /*
233 : ** Make a copy of all components of the given trigger step. This has
234 : ** the effect of copying all Expr.token.z values into memory obtained
235 : ** from sqliteMalloc(). As initially created, the Expr.token.z values
236 : ** all point to the input string that was fed to the parser. But that
237 : ** string is ephemeral - it will go away as soon as the sqlite_exec()
238 : ** call that started the parser exits. This routine makes a persistent
239 : ** copy of all the Expr.token.z strings so that the TriggerStep structure
240 : ** will be valid even after the sqlite_exec() call returns.
241 : */
242 0 : static void sqlitePersistTriggerStep(TriggerStep *p){
243 0 : if( p->target.z ){
244 0 : p->target.z = sqliteStrNDup(p->target.z, p->target.n);
245 0 : p->target.dyn = 1;
246 : }
247 0 : if( p->pSelect ){
248 0 : Select *pNew = sqliteSelectDup(p->pSelect);
249 0 : sqliteSelectDelete(p->pSelect);
250 0 : p->pSelect = pNew;
251 : }
252 0 : if( p->pWhere ){
253 0 : Expr *pNew = sqliteExprDup(p->pWhere);
254 0 : sqliteExprDelete(p->pWhere);
255 0 : p->pWhere = pNew;
256 : }
257 0 : if( p->pExprList ){
258 0 : ExprList *pNew = sqliteExprListDup(p->pExprList);
259 0 : sqliteExprListDelete(p->pExprList);
260 0 : p->pExprList = pNew;
261 : }
262 0 : if( p->pIdList ){
263 0 : IdList *pNew = sqliteIdListDup(p->pIdList);
264 0 : sqliteIdListDelete(p->pIdList);
265 0 : p->pIdList = pNew;
266 : }
267 0 : }
268 :
269 : /*
270 : ** Turn a SELECT statement (that the pSelect parameter points to) into
271 : ** a trigger step. Return a pointer to a TriggerStep structure.
272 : **
273 : ** The parser calls this routine when it finds a SELECT statement in
274 : ** body of a TRIGGER.
275 : */
276 0 : TriggerStep *sqliteTriggerSelectStep(Select *pSelect){
277 0 : TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
278 0 : if( pTriggerStep==0 ) return 0;
279 :
280 0 : pTriggerStep->op = TK_SELECT;
281 0 : pTriggerStep->pSelect = pSelect;
282 0 : pTriggerStep->orconf = OE_Default;
283 0 : sqlitePersistTriggerStep(pTriggerStep);
284 :
285 0 : return pTriggerStep;
286 : }
287 :
288 : /*
289 : ** Build a trigger step out of an INSERT statement. Return a pointer
290 : ** to the new trigger step.
291 : **
292 : ** The parser calls this routine when it sees an INSERT inside the
293 : ** body of a trigger.
294 : */
295 : TriggerStep *sqliteTriggerInsertStep(
296 : Token *pTableName, /* Name of the table into which we insert */
297 : IdList *pColumn, /* List of columns in pTableName to insert into */
298 : ExprList *pEList, /* The VALUE clause: a list of values to be inserted */
299 : Select *pSelect, /* A SELECT statement that supplies values */
300 : int orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
301 0 : ){
302 0 : TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
303 0 : if( pTriggerStep==0 ) return 0;
304 :
305 : assert(pEList == 0 || pSelect == 0);
306 : assert(pEList != 0 || pSelect != 0);
307 :
308 0 : pTriggerStep->op = TK_INSERT;
309 0 : pTriggerStep->pSelect = pSelect;
310 0 : pTriggerStep->target = *pTableName;
311 0 : pTriggerStep->pIdList = pColumn;
312 0 : pTriggerStep->pExprList = pEList;
313 0 : pTriggerStep->orconf = orconf;
314 0 : sqlitePersistTriggerStep(pTriggerStep);
315 :
316 0 : return pTriggerStep;
317 : }
318 :
319 : /*
320 : ** Construct a trigger step that implements an UPDATE statement and return
321 : ** a pointer to that trigger step. The parser calls this routine when it
322 : ** sees an UPDATE statement inside the body of a CREATE TRIGGER.
323 : */
324 : TriggerStep *sqliteTriggerUpdateStep(
325 : Token *pTableName, /* Name of the table to be updated */
326 : ExprList *pEList, /* The SET clause: list of column and new values */
327 : Expr *pWhere, /* The WHERE clause */
328 : int orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
329 0 : ){
330 0 : TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
331 0 : if( pTriggerStep==0 ) return 0;
332 :
333 0 : pTriggerStep->op = TK_UPDATE;
334 0 : pTriggerStep->target = *pTableName;
335 0 : pTriggerStep->pExprList = pEList;
336 0 : pTriggerStep->pWhere = pWhere;
337 0 : pTriggerStep->orconf = orconf;
338 0 : sqlitePersistTriggerStep(pTriggerStep);
339 :
340 0 : return pTriggerStep;
341 : }
342 :
343 : /*
344 : ** Construct a trigger step that implements a DELETE statement and return
345 : ** a pointer to that trigger step. The parser calls this routine when it
346 : ** sees a DELETE statement inside the body of a CREATE TRIGGER.
347 : */
348 0 : TriggerStep *sqliteTriggerDeleteStep(Token *pTableName, Expr *pWhere){
349 0 : TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
350 0 : if( pTriggerStep==0 ) return 0;
351 :
352 0 : pTriggerStep->op = TK_DELETE;
353 0 : pTriggerStep->target = *pTableName;
354 0 : pTriggerStep->pWhere = pWhere;
355 0 : pTriggerStep->orconf = OE_Default;
356 0 : sqlitePersistTriggerStep(pTriggerStep);
357 :
358 0 : return pTriggerStep;
359 : }
360 :
361 : /*
362 : ** Recursively delete a Trigger structure
363 : */
364 0 : void sqliteDeleteTrigger(Trigger *pTrigger){
365 0 : if( pTrigger==0 ) return;
366 0 : sqliteDeleteTriggerStep(pTrigger->step_list);
367 0 : sqliteFree(pTrigger->name);
368 0 : sqliteFree(pTrigger->table);
369 0 : sqliteExprDelete(pTrigger->pWhen);
370 0 : sqliteIdListDelete(pTrigger->pColumns);
371 0 : if( pTrigger->nameToken.dyn ) sqliteFree((char*)pTrigger->nameToken.z);
372 0 : sqliteFree(pTrigger);
373 : }
374 :
375 : /*
376 : * This function is called to drop a trigger from the database schema.
377 : *
378 : * This may be called directly from the parser and therefore identifies
379 : * the trigger by name. The sqliteDropTriggerPtr() routine does the
380 : * same job as this routine except it take a spointer to the trigger
381 : * instead of the trigger name.
382 : *
383 : * Note that this function does not delete the trigger entirely. Instead it
384 : * removes it from the internal schema and places it in the trigDrop hash
385 : * table. This is so that the trigger can be restored into the database schema
386 : * if the transaction is rolled back.
387 : */
388 0 : void sqliteDropTrigger(Parse *pParse, SrcList *pName){
389 : Trigger *pTrigger;
390 : int i;
391 : const char *zDb;
392 : const char *zName;
393 : int nName;
394 0 : sqlite *db = pParse->db;
395 :
396 0 : if( sqlite_malloc_failed ) goto drop_trigger_cleanup;
397 : assert( pName->nSrc==1 );
398 0 : zDb = pName->a[0].zDatabase;
399 0 : zName = pName->a[0].zName;
400 0 : nName = strlen(zName);
401 0 : for(i=0; i<db->nDb; i++){
402 0 : int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
403 0 : if( zDb && sqliteStrICmp(db->aDb[j].zName, zDb) ) continue;
404 0 : pTrigger = sqliteHashFind(&(db->aDb[j].trigHash), zName, nName+1);
405 0 : if( pTrigger ) break;
406 : }
407 0 : if( !pTrigger ){
408 0 : sqliteErrorMsg(pParse, "no such trigger: %S", pName, 0);
409 0 : goto drop_trigger_cleanup;
410 : }
411 0 : sqliteDropTriggerPtr(pParse, pTrigger, 0);
412 :
413 0 : drop_trigger_cleanup:
414 0 : sqliteSrcListDelete(pName);
415 0 : }
416 :
417 : /*
418 : ** Drop a trigger given a pointer to that trigger. If nested is false,
419 : ** then also generate code to remove the trigger from the SQLITE_MASTER
420 : ** table.
421 : */
422 0 : void sqliteDropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
423 : Table *pTable;
424 : Vdbe *v;
425 0 : sqlite *db = pParse->db;
426 :
427 : assert( pTrigger->iDb<db->nDb );
428 0 : if( pTrigger->iDb>=2 ){
429 0 : sqliteErrorMsg(pParse, "triggers may not be removed from "
430 : "auxiliary database %s", db->aDb[pTrigger->iDb].zName);
431 0 : return;
432 : }
433 0 : pTable = sqliteFindTable(db, pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
434 : assert(pTable);
435 : assert( pTable->iDb==pTrigger->iDb || pTrigger->iDb==1 );
436 : #ifndef SQLITE_OMIT_AUTHORIZATION
437 : {
438 0 : int code = SQLITE_DROP_TRIGGER;
439 0 : const char *zDb = db->aDb[pTrigger->iDb].zName;
440 0 : const char *zTab = SCHEMA_TABLE(pTrigger->iDb);
441 0 : if( pTrigger->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
442 0 : if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
443 : sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
444 0 : return;
445 : }
446 : }
447 : #endif
448 :
449 : /* Generate code to destroy the database record of the trigger.
450 : */
451 0 : if( pTable!=0 && !nested && (v = sqliteGetVdbe(pParse))!=0 ){
452 : int base;
453 : static VdbeOpList dropTrigger[] = {
454 : { OP_Rewind, 0, ADDR(9), 0},
455 : { OP_String, 0, 0, 0}, /* 1 */
456 : { OP_Column, 0, 1, 0},
457 : { OP_Ne, 0, ADDR(8), 0},
458 : { OP_String, 0, 0, "trigger"},
459 : { OP_Column, 0, 0, 0},
460 : { OP_Ne, 0, ADDR(8), 0},
461 : { OP_Delete, 0, 0, 0},
462 : { OP_Next, 0, ADDR(1), 0}, /* 8 */
463 : };
464 :
465 0 : sqliteBeginWriteOperation(pParse, 0, 0);
466 0 : sqliteOpenMasterTable(v, pTrigger->iDb);
467 0 : base = sqliteVdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
468 0 : sqliteVdbeChangeP3(v, base+1, pTrigger->name, 0);
469 0 : if( pTrigger->iDb==0 ){
470 0 : sqliteChangeCookie(db, v);
471 : }
472 0 : sqliteVdbeAddOp(v, OP_Close, 0, 0);
473 0 : sqliteEndWriteOperation(pParse);
474 : }
475 :
476 : /*
477 : * If this is not an "explain", then delete the trigger structure.
478 : */
479 0 : if( !pParse->explain ){
480 0 : const char *zName = pTrigger->name;
481 0 : int nName = strlen(zName);
482 0 : if( pTable->pTrigger == pTrigger ){
483 0 : pTable->pTrigger = pTrigger->pNext;
484 : }else{
485 0 : Trigger *cc = pTable->pTrigger;
486 0 : while( cc ){
487 0 : if( cc->pNext == pTrigger ){
488 0 : cc->pNext = cc->pNext->pNext;
489 0 : break;
490 : }
491 0 : cc = cc->pNext;
492 : }
493 : assert(cc);
494 : }
495 0 : sqliteHashInsert(&(db->aDb[pTrigger->iDb].trigHash), zName, nName+1, 0);
496 0 : sqliteDeleteTrigger(pTrigger);
497 : }
498 : }
499 :
500 : /*
501 : ** pEList is the SET clause of an UPDATE statement. Each entry
502 : ** in pEList is of the format <id>=<expr>. If any of the entries
503 : ** in pEList have an <id> which matches an identifier in pIdList,
504 : ** then return TRUE. If pIdList==NULL, then it is considered a
505 : ** wildcard that matches anything. Likewise if pEList==NULL then
506 : ** it matches anything so always return true. Return false only
507 : ** if there is no match.
508 : */
509 0 : static int checkColumnOverLap(IdList *pIdList, ExprList *pEList){
510 : int e;
511 0 : if( !pIdList || !pEList ) return 1;
512 0 : for(e=0; e<pEList->nExpr; e++){
513 0 : if( sqliteIdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
514 : }
515 0 : return 0;
516 : }
517 :
518 : /* A global variable that is TRUE if we should always set up temp tables for
519 : * for triggers, even if there are no triggers to code. This is used to test
520 : * how much overhead the triggers algorithm is causing.
521 : *
522 : * This flag can be set or cleared using the "trigger_overhead_test" pragma.
523 : * The pragma is not documented since it is not really part of the interface
524 : * to SQLite, just the test procedure.
525 : */
526 : int always_code_trigger_setup = 0;
527 :
528 : /*
529 : * Returns true if a trigger matching op, tr_tm and foreach that is NOT already
530 : * on the Parse objects trigger-stack (to prevent recursive trigger firing) is
531 : * found in the list specified as pTrigger.
532 : */
533 : int sqliteTriggersExist(
534 : Parse *pParse, /* Used to check for recursive triggers */
535 : Trigger *pTrigger, /* A list of triggers associated with a table */
536 : int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
537 : int tr_tm, /* one of TK_BEFORE, TK_AFTER */
538 : int foreach, /* one of TK_ROW or TK_STATEMENT */
539 : ExprList *pChanges /* Columns that change in an UPDATE statement */
540 530 : ){
541 : Trigger * pTriggerCursor;
542 :
543 530 : if( always_code_trigger_setup ){
544 0 : return 1;
545 : }
546 :
547 530 : pTriggerCursor = pTrigger;
548 1060 : while( pTriggerCursor ){
549 0 : if( pTriggerCursor->op == op &&
550 : pTriggerCursor->tr_tm == tr_tm &&
551 : pTriggerCursor->foreach == foreach &&
552 : checkColumnOverLap(pTriggerCursor->pColumns, pChanges) ){
553 : TriggerStack * ss;
554 0 : ss = pParse->trigStack;
555 0 : while( ss && ss->pTrigger != pTrigger ){
556 0 : ss = ss->pNext;
557 : }
558 0 : if( !ss )return 1;
559 : }
560 0 : pTriggerCursor = pTriggerCursor->pNext;
561 : }
562 :
563 530 : return 0;
564 : }
565 :
566 : /*
567 : ** Convert the pStep->target token into a SrcList and return a pointer
568 : ** to that SrcList.
569 : **
570 : ** This routine adds a specific database name, if needed, to the target when
571 : ** forming the SrcList. This prevents a trigger in one database from
572 : ** referring to a target in another database. An exception is when the
573 : ** trigger is in TEMP in which case it can refer to any other database it
574 : ** wants.
575 : */
576 : static SrcList *targetSrcList(
577 : Parse *pParse, /* The parsing context */
578 : TriggerStep *pStep /* The trigger containing the target token */
579 0 : ){
580 : Token sDb; /* Dummy database name token */
581 : int iDb; /* Index of the database to use */
582 : SrcList *pSrc; /* SrcList to be returned */
583 :
584 0 : iDb = pStep->pTrig->iDb;
585 0 : if( iDb==0 || iDb>=2 ){
586 : assert( iDb<pParse->db->nDb );
587 0 : sDb.z = pParse->db->aDb[iDb].zName;
588 0 : sDb.n = strlen(sDb.z);
589 0 : pSrc = sqliteSrcListAppend(0, &sDb, &pStep->target);
590 : } else {
591 0 : pSrc = sqliteSrcListAppend(0, &pStep->target, 0);
592 : }
593 0 : return pSrc;
594 : }
595 :
596 : /*
597 : ** Generate VDBE code for zero or more statements inside the body of a
598 : ** trigger.
599 : */
600 : static int codeTriggerProgram(
601 : Parse *pParse, /* The parser context */
602 : TriggerStep *pStepList, /* List of statements inside the trigger body */
603 : int orconfin /* Conflict algorithm. (OE_Abort, etc) */
604 0 : ){
605 0 : TriggerStep * pTriggerStep = pStepList;
606 : int orconf;
607 :
608 0 : while( pTriggerStep ){
609 0 : int saveNTab = pParse->nTab;
610 :
611 0 : orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
612 0 : pParse->trigStack->orconf = orconf;
613 0 : switch( pTriggerStep->op ){
614 : case TK_SELECT: {
615 0 : Select * ss = sqliteSelectDup(pTriggerStep->pSelect);
616 : assert(ss);
617 : assert(ss->pSrc);
618 0 : sqliteSelect(pParse, ss, SRT_Discard, 0, 0, 0, 0);
619 0 : sqliteSelectDelete(ss);
620 0 : break;
621 : }
622 : case TK_UPDATE: {
623 : SrcList *pSrc;
624 0 : pSrc = targetSrcList(pParse, pTriggerStep);
625 0 : sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
626 0 : sqliteUpdate(pParse, pSrc,
627 : sqliteExprListDup(pTriggerStep->pExprList),
628 : sqliteExprDup(pTriggerStep->pWhere), orconf);
629 0 : sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
630 0 : break;
631 : }
632 : case TK_INSERT: {
633 : SrcList *pSrc;
634 0 : pSrc = targetSrcList(pParse, pTriggerStep);
635 0 : sqliteInsert(pParse, pSrc,
636 : sqliteExprListDup(pTriggerStep->pExprList),
637 : sqliteSelectDup(pTriggerStep->pSelect),
638 : sqliteIdListDup(pTriggerStep->pIdList), orconf);
639 0 : break;
640 : }
641 : case TK_DELETE: {
642 : SrcList *pSrc;
643 0 : sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
644 0 : pSrc = targetSrcList(pParse, pTriggerStep);
645 0 : sqliteDeleteFrom(pParse, pSrc, sqliteExprDup(pTriggerStep->pWhere));
646 0 : sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
647 : break;
648 : }
649 : default:
650 : assert(0);
651 : }
652 0 : pParse->nTab = saveNTab;
653 0 : pTriggerStep = pTriggerStep->pNext;
654 : }
655 :
656 0 : return 0;
657 : }
658 :
659 : /*
660 : ** This is called to code FOR EACH ROW triggers.
661 : **
662 : ** When the code that this function generates is executed, the following
663 : ** must be true:
664 : **
665 : ** 1. No cursors may be open in the main database. (But newIdx and oldIdx
666 : ** can be indices of cursors in temporary tables. See below.)
667 : **
668 : ** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then
669 : ** a temporary vdbe cursor (index newIdx) must be open and pointing at
670 : ** a row containing values to be substituted for new.* expressions in the
671 : ** trigger program(s).
672 : **
673 : ** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then
674 : ** a temporary vdbe cursor (index oldIdx) must be open and pointing at
675 : ** a row containing values to be substituted for old.* expressions in the
676 : ** trigger program(s).
677 : **
678 : */
679 : int sqliteCodeRowTrigger(
680 : Parse *pParse, /* Parse context */
681 : int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
682 : ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
683 : int tr_tm, /* One of TK_BEFORE, TK_AFTER */
684 : Table *pTab, /* The table to code triggers from */
685 : int newIdx, /* The indice of the "new" row to access */
686 : int oldIdx, /* The indice of the "old" row to access */
687 : int orconf, /* ON CONFLICT policy */
688 : int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
689 0 : ){
690 : Trigger * pTrigger;
691 : TriggerStack * pTriggerStack;
692 :
693 : assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
694 : assert(tr_tm == TK_BEFORE || tr_tm == TK_AFTER );
695 :
696 : assert(newIdx != -1 || oldIdx != -1);
697 :
698 0 : pTrigger = pTab->pTrigger;
699 0 : while( pTrigger ){
700 0 : int fire_this = 0;
701 :
702 : /* determine whether we should code this trigger */
703 0 : if( pTrigger->op == op && pTrigger->tr_tm == tr_tm &&
704 : pTrigger->foreach == TK_ROW ){
705 0 : fire_this = 1;
706 0 : pTriggerStack = pParse->trigStack;
707 0 : while( pTriggerStack ){
708 0 : if( pTriggerStack->pTrigger == pTrigger ){
709 0 : fire_this = 0;
710 : }
711 0 : pTriggerStack = pTriggerStack->pNext;
712 : }
713 0 : if( op == TK_UPDATE && pTrigger->pColumns &&
714 : !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
715 0 : fire_this = 0;
716 : }
717 : }
718 :
719 0 : if( fire_this && (pTriggerStack = sqliteMalloc(sizeof(TriggerStack)))!=0 ){
720 : int endTrigger;
721 : SrcList dummyTablist;
722 : Expr * whenExpr;
723 : AuthContext sContext;
724 :
725 0 : dummyTablist.nSrc = 0;
726 :
727 : /* Push an entry on to the trigger stack */
728 0 : pTriggerStack->pTrigger = pTrigger;
729 0 : pTriggerStack->newIdx = newIdx;
730 0 : pTriggerStack->oldIdx = oldIdx;
731 0 : pTriggerStack->pTab = pTab;
732 0 : pTriggerStack->pNext = pParse->trigStack;
733 0 : pTriggerStack->ignoreJump = ignoreJump;
734 0 : pParse->trigStack = pTriggerStack;
735 0 : sqliteAuthContextPush(pParse, &sContext, pTrigger->name);
736 :
737 : /* code the WHEN clause */
738 0 : endTrigger = sqliteVdbeMakeLabel(pParse->pVdbe);
739 0 : whenExpr = sqliteExprDup(pTrigger->pWhen);
740 0 : if( sqliteExprResolveIds(pParse, &dummyTablist, 0, whenExpr) ){
741 0 : pParse->trigStack = pParse->trigStack->pNext;
742 0 : sqliteFree(pTriggerStack);
743 0 : sqliteExprDelete(whenExpr);
744 0 : return 1;
745 : }
746 0 : sqliteExprIfFalse(pParse, whenExpr, endTrigger, 1);
747 0 : sqliteExprDelete(whenExpr);
748 :
749 0 : sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPush, 0, 0);
750 0 : codeTriggerProgram(pParse, pTrigger->step_list, orconf);
751 0 : sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPop, 0, 0);
752 :
753 : /* Pop the entry off the trigger stack */
754 0 : pParse->trigStack = pParse->trigStack->pNext;
755 0 : sqliteAuthContextPop(&sContext);
756 0 : sqliteFree(pTriggerStack);
757 :
758 0 : sqliteVdbeResolveLabel(pParse->pVdbe, endTrigger);
759 : }
760 0 : pTrigger = pTrigger->pNext;
761 : }
762 :
763 0 : return 0;
764 : }
|