source: trunk/src/3rdparty/sqlite/trigger.c@ 205

Last change on this file since 205 was 205, checked in by rudi, 14 years ago

Added SQLite 2.8.17 sources. This allows to build at least one of the sql drivers / plugins.

File size: 24.9 KB
Line 
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*/
18void sqliteDeleteTriggerStep(TriggerStep *pTriggerStep){
19 while( pTriggerStep ){
20 TriggerStep * pTmp = pTriggerStep;
21 pTriggerStep = pTriggerStep->pNext;
22
23 if( pTmp->target.dyn ) sqliteFree((char*)pTmp->target.z);
24 sqliteExprDelete(pTmp->pWhere);
25 sqliteExprListDelete(pTmp->pExprList);
26 sqliteSelectDelete(pTmp->pSelect);
27 sqliteIdListDelete(pTmp->pIdList);
28
29 sqliteFree(pTmp);
30 }
31}
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*/
41void 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){
52 Trigger *nt;
53 Table *tab;
54 char *zName = 0; /* Name of the trigger */
55 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 if( sqlite_malloc_failed ) goto trigger_cleanup;
67 assert( pTableName->nSrc==1 );
68 if( db->init.busy
69 && sqliteFixInit(&sFix, pParse, db->init.iDb, "trigger", pName)
70 && sqliteFixSrcList(&sFix, pTableName)
71 ){
72 goto trigger_cleanup;
73 }
74 tab = sqliteSrcListLookup(pParse, pTableName);
75 if( !tab ){
76 goto trigger_cleanup;
77 }
78 iDb = isTemp ? 1 : tab->iDb;
79 if( iDb>=2 && !db->init.busy ){
80 sqliteErrorMsg(pParse, "triggers may not be added to auxiliary "
81 "database %s", db->aDb[tab->iDb].zName);
82 goto trigger_cleanup;
83 }
84
85 zName = sqliteStrNDup(pName->z, pName->n);
86 sqliteDequote(zName);
87 if( sqliteHashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){
88 sqliteErrorMsg(pParse, "trigger %T already exists", pName);
89 goto trigger_cleanup;
90 }
91 if( sqliteStrNICmp(tab->zName, "sqlite_", 7)==0 ){
92 sqliteErrorMsg(pParse, "cannot create trigger on system table");
93 pParse->nErr++;
94 goto trigger_cleanup;
95 }
96 if( tab->pSelect && tr_tm != TK_INSTEAD ){
97 sqliteErrorMsg(pParse, "cannot create %s trigger on view: %S",
98 (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
99 goto trigger_cleanup;
100 }
101 if( !tab->pSelect && tr_tm == TK_INSTEAD ){
102 sqliteErrorMsg(pParse, "cannot create INSTEAD OF"
103 " trigger on table: %S", pTableName, 0);
104 goto trigger_cleanup;
105 }
106#ifndef SQLITE_OMIT_AUTHORIZATION
107 {
108 int code = SQLITE_CREATE_TRIGGER;
109 const char *zDb = db->aDb[tab->iDb].zName;
110 const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
111 if( tab->iDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
112 if( sqliteAuthCheck(pParse, code, zName, tab->zName, zDbTrig) ){
113 goto trigger_cleanup;
114 }
115 if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(tab->iDb), 0, zDb)){
116 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 if (tr_tm == TK_INSTEAD){
127 tr_tm = TK_BEFORE;
128 }
129
130 /* Build the Trigger object */
131 nt = (Trigger*)sqliteMalloc(sizeof(Trigger));
132 if( nt==0 ) goto trigger_cleanup;
133 nt->name = zName;
134 zName = 0;
135 nt->table = sqliteStrDup(pTableName->a[0].zName);
136 if( sqlite_malloc_failed ) goto trigger_cleanup;
137 nt->iDb = iDb;
138 nt->iTabDb = tab->iDb;
139 nt->op = op;
140 nt->tr_tm = tr_tm;
141 nt->pWhen = sqliteExprDup(pWhen);
142 nt->pColumns = sqliteIdListDup(pColumns);
143 nt->foreach = foreach;
144 sqliteTokenCopy(&nt->nameToken,pName);
145 assert( pParse->pNewTrigger==0 );
146 pParse->pNewTrigger = nt;
147
148trigger_cleanup:
149 sqliteFree(zName);
150 sqliteSrcListDelete(pTableName);
151 sqliteIdListDelete(pColumns);
152 sqliteExprDelete(pWhen);
153}
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*/
159void sqliteFinishTrigger(
160 Parse *pParse, /* Parser context */
161 TriggerStep *pStepList, /* The triggered program */
162 Token *pAll /* Token that describes the complete CREATE TRIGGER */
163){
164 Trigger *nt = 0; /* The trigger whose construction is finishing up */
165 sqlite *db = pParse->db; /* The database */
166 DbFixer sFix;
167
168 if( pParse->nErr || pParse->pNewTrigger==0 ) goto triggerfinish_cleanup;
169 nt = pParse->pNewTrigger;
170 pParse->pNewTrigger = 0;
171 nt->step_list = pStepList;
172 while( pStepList ){
173 pStepList->pTrig = nt;
174 pStepList = pStepList->pNext;
175 }
176 if( sqliteFixInit(&sFix, pParse, nt->iDb, "trigger", &nt->nameToken)
177 && sqliteFixTriggerStep(&sFix, nt->step_list) ){
178 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 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 v = sqliteGetVdbe(pParse);
200 if( v==0 ) goto triggerfinish_cleanup;
201 sqliteBeginWriteOperation(pParse, 0, 0);
202 sqliteOpenMasterTable(v, nt->iDb);
203 addr = sqliteVdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
204 sqliteVdbeChangeP3(v, addr+2, nt->name, 0);
205 sqliteVdbeChangeP3(v, addr+3, nt->table, 0);
206 sqliteVdbeChangeP3(v, addr+5, pAll->z, pAll->n);
207 if( nt->iDb==0 ){
208 sqliteChangeCookie(db, v);
209 }
210 sqliteVdbeAddOp(v, OP_Close, 0, 0);
211 sqliteEndWriteOperation(pParse);
212 }
213
214 if( !pParse->explain ){
215 Table *pTab;
216 sqliteHashInsert(&db->aDb[nt->iDb].trigHash,
217 nt->name, strlen(nt->name)+1, nt);
218 pTab = sqliteLocateTable(pParse, nt->table, db->aDb[nt->iTabDb].zName);
219 assert( pTab!=0 );
220 nt->pNext = pTab->pTrigger;
221 pTab->pTrigger = nt;
222 nt = 0;
223 }
224
225triggerfinish_cleanup:
226 sqliteDeleteTrigger(nt);
227 sqliteDeleteTrigger(pParse->pNewTrigger);
228 pParse->pNewTrigger = 0;
229 sqliteDeleteTriggerStep(pStepList);
230}
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*/
242static void sqlitePersistTriggerStep(TriggerStep *p){
243 if( p->target.z ){
244 p->target.z = sqliteStrNDup(p->target.z, p->target.n);
245 p->target.dyn = 1;
246 }
247 if( p->pSelect ){
248 Select *pNew = sqliteSelectDup(p->pSelect);
249 sqliteSelectDelete(p->pSelect);
250 p->pSelect = pNew;
251 }
252 if( p->pWhere ){
253 Expr *pNew = sqliteExprDup(p->pWhere);
254 sqliteExprDelete(p->pWhere);
255 p->pWhere = pNew;
256 }
257 if( p->pExprList ){
258 ExprList *pNew = sqliteExprListDup(p->pExprList);
259 sqliteExprListDelete(p->pExprList);
260 p->pExprList = pNew;
261 }
262 if( p->pIdList ){
263 IdList *pNew = sqliteIdListDup(p->pIdList);
264 sqliteIdListDelete(p->pIdList);
265 p->pIdList = pNew;
266 }
267}
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*/
276TriggerStep *sqliteTriggerSelectStep(Select *pSelect){
277 TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
278 if( pTriggerStep==0 ) return 0;
279
280 pTriggerStep->op = TK_SELECT;
281 pTriggerStep->pSelect = pSelect;
282 pTriggerStep->orconf = OE_Default;
283 sqlitePersistTriggerStep(pTriggerStep);
284
285 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*/
295TriggerStep *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){
302 TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
303 if( pTriggerStep==0 ) return 0;
304
305 assert(pEList == 0 || pSelect == 0);
306 assert(pEList != 0 || pSelect != 0);
307
308 pTriggerStep->op = TK_INSERT;
309 pTriggerStep->pSelect = pSelect;
310 pTriggerStep->target = *pTableName;
311 pTriggerStep->pIdList = pColumn;
312 pTriggerStep->pExprList = pEList;
313 pTriggerStep->orconf = orconf;
314 sqlitePersistTriggerStep(pTriggerStep);
315
316 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*/
324TriggerStep *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){
330 TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
331 if( pTriggerStep==0 ) return 0;
332
333 pTriggerStep->op = TK_UPDATE;
334 pTriggerStep->target = *pTableName;
335 pTriggerStep->pExprList = pEList;
336 pTriggerStep->pWhere = pWhere;
337 pTriggerStep->orconf = orconf;
338 sqlitePersistTriggerStep(pTriggerStep);
339
340 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*/
348TriggerStep *sqliteTriggerDeleteStep(Token *pTableName, Expr *pWhere){
349 TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
350 if( pTriggerStep==0 ) return 0;
351
352 pTriggerStep->op = TK_DELETE;
353 pTriggerStep->target = *pTableName;
354 pTriggerStep->pWhere = pWhere;
355 pTriggerStep->orconf = OE_Default;
356 sqlitePersistTriggerStep(pTriggerStep);
357
358 return pTriggerStep;
359}
360
361/*
362** Recursively delete a Trigger structure
363*/
364void sqliteDeleteTrigger(Trigger *pTrigger){
365 if( pTrigger==0 ) return;
366 sqliteDeleteTriggerStep(pTrigger->step_list);
367 sqliteFree(pTrigger->name);
368 sqliteFree(pTrigger->table);
369 sqliteExprDelete(pTrigger->pWhen);
370 sqliteIdListDelete(pTrigger->pColumns);
371 if( pTrigger->nameToken.dyn ) sqliteFree((char*)pTrigger->nameToken.z);
372 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 */
388void sqliteDropTrigger(Parse *pParse, SrcList *pName){
389 Trigger *pTrigger;
390 int i;
391 const char *zDb;
392 const char *zName;
393 int nName;
394 sqlite *db = pParse->db;
395
396 if( sqlite_malloc_failed ) goto drop_trigger_cleanup;
397 assert( pName->nSrc==1 );
398 zDb = pName->a[0].zDatabase;
399 zName = pName->a[0].zName;
400 nName = strlen(zName);
401 for(i=0; i<db->nDb; i++){
402 int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
403 if( zDb && sqliteStrICmp(db->aDb[j].zName, zDb) ) continue;
404 pTrigger = sqliteHashFind(&(db->aDb[j].trigHash), zName, nName+1);
405 if( pTrigger ) break;
406 }
407 if( !pTrigger ){
408 sqliteErrorMsg(pParse, "no such trigger: %S", pName, 0);
409 goto drop_trigger_cleanup;
410 }
411 sqliteDropTriggerPtr(pParse, pTrigger, 0);
412
413drop_trigger_cleanup:
414 sqliteSrcListDelete(pName);
415}
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*/
422void sqliteDropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
423 Table *pTable;
424 Vdbe *v;
425 sqlite *db = pParse->db;
426
427 assert( pTrigger->iDb<db->nDb );
428 if( pTrigger->iDb>=2 ){
429 sqliteErrorMsg(pParse, "triggers may not be removed from "
430 "auxiliary database %s", db->aDb[pTrigger->iDb].zName);
431 return;
432 }
433 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 int code = SQLITE_DROP_TRIGGER;
439 const char *zDb = db->aDb[pTrigger->iDb].zName;
440 const char *zTab = SCHEMA_TABLE(pTrigger->iDb);
441 if( pTrigger->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
442 if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
443 sqliteAuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
444 return;
445 }
446 }
447#endif
448
449 /* Generate code to destroy the database record of the trigger.
450 */
451 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 sqliteBeginWriteOperation(pParse, 0, 0);
466 sqliteOpenMasterTable(v, pTrigger->iDb);
467 base = sqliteVdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
468 sqliteVdbeChangeP3(v, base+1, pTrigger->name, 0);
469 if( pTrigger->iDb==0 ){
470 sqliteChangeCookie(db, v);
471 }
472 sqliteVdbeAddOp(v, OP_Close, 0, 0);
473 sqliteEndWriteOperation(pParse);
474 }
475
476 /*
477 * If this is not an "explain", then delete the trigger structure.
478 */
479 if( !pParse->explain ){
480 const char *zName = pTrigger->name;
481 int nName = strlen(zName);
482 if( pTable->pTrigger == pTrigger ){
483 pTable->pTrigger = pTrigger->pNext;
484 }else{
485 Trigger *cc = pTable->pTrigger;
486 while( cc ){
487 if( cc->pNext == pTrigger ){
488 cc->pNext = cc->pNext->pNext;
489 break;
490 }
491 cc = cc->pNext;
492 }
493 assert(cc);
494 }
495 sqliteHashInsert(&(db->aDb[pTrigger->iDb].trigHash), zName, nName+1, 0);
496 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*/
509static int checkColumnOverLap(IdList *pIdList, ExprList *pEList){
510 int e;
511 if( !pIdList || !pEList ) return 1;
512 for(e=0; e<pEList->nExpr; e++){
513 if( sqliteIdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
514 }
515 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*/
526int 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 */
533int 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){
541 Trigger * pTriggerCursor;
542
543 if( always_code_trigger_setup ){
544 return 1;
545 }
546
547 pTriggerCursor = pTrigger;
548 while( pTriggerCursor ){
549 if( pTriggerCursor->op == op &&
550 pTriggerCursor->tr_tm == tr_tm &&
551 pTriggerCursor->foreach == foreach &&
552 checkColumnOverLap(pTriggerCursor->pColumns, pChanges) ){
553 TriggerStack * ss;
554 ss = pParse->trigStack;
555 while( ss && ss->pTrigger != pTrigger ){
556 ss = ss->pNext;
557 }
558 if( !ss )return 1;
559 }
560 pTriggerCursor = pTriggerCursor->pNext;
561 }
562
563 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*/
576static SrcList *targetSrcList(
577 Parse *pParse, /* The parsing context */
578 TriggerStep *pStep /* The trigger containing the target token */
579){
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 iDb = pStep->pTrig->iDb;
585 if( iDb==0 || iDb>=2 ){
586 assert( iDb<pParse->db->nDb );
587 sDb.z = pParse->db->aDb[iDb].zName;
588 sDb.n = strlen(sDb.z);
589 pSrc = sqliteSrcListAppend(0, &sDb, &pStep->target);
590 } else {
591 pSrc = sqliteSrcListAppend(0, &pStep->target, 0);
592 }
593 return pSrc;
594}
595
596/*
597** Generate VDBE code for zero or more statements inside the body of a
598** trigger.
599*/
600static 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){
605 TriggerStep * pTriggerStep = pStepList;
606 int orconf;
607
608 while( pTriggerStep ){
609 int saveNTab = pParse->nTab;
610
611 orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
612 pParse->trigStack->orconf = orconf;
613 switch( pTriggerStep->op ){
614 case TK_SELECT: {
615 Select * ss = sqliteSelectDup(pTriggerStep->pSelect);
616 assert(ss);
617 assert(ss->pSrc);
618 sqliteSelect(pParse, ss, SRT_Discard, 0, 0, 0, 0);
619 sqliteSelectDelete(ss);
620 break;
621 }
622 case TK_UPDATE: {
623 SrcList *pSrc;
624 pSrc = targetSrcList(pParse, pTriggerStep);
625 sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
626 sqliteUpdate(pParse, pSrc,
627 sqliteExprListDup(pTriggerStep->pExprList),
628 sqliteExprDup(pTriggerStep->pWhere), orconf);
629 sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
630 break;
631 }
632 case TK_INSERT: {
633 SrcList *pSrc;
634 pSrc = targetSrcList(pParse, pTriggerStep);
635 sqliteInsert(pParse, pSrc,
636 sqliteExprListDup(pTriggerStep->pExprList),
637 sqliteSelectDup(pTriggerStep->pSelect),
638 sqliteIdListDup(pTriggerStep->pIdList), orconf);
639 break;
640 }
641 case TK_DELETE: {
642 SrcList *pSrc;
643 sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
644 pSrc = targetSrcList(pParse, pTriggerStep);
645 sqliteDeleteFrom(pParse, pSrc, sqliteExprDup(pTriggerStep->pWhere));
646 sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
647 break;
648 }
649 default:
650 assert(0);
651 }
652 pParse->nTab = saveNTab;
653 pTriggerStep = pTriggerStep->pNext;
654 }
655
656 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*/
679int 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){
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 pTrigger = pTab->pTrigger;
699 while( pTrigger ){
700 int fire_this = 0;
701
702 /* determine whether we should code this trigger */
703 if( pTrigger->op == op && pTrigger->tr_tm == tr_tm &&
704 pTrigger->foreach == TK_ROW ){
705 fire_this = 1;
706 pTriggerStack = pParse->trigStack;
707 while( pTriggerStack ){
708 if( pTriggerStack->pTrigger == pTrigger ){
709 fire_this = 0;
710 }
711 pTriggerStack = pTriggerStack->pNext;
712 }
713 if( op == TK_UPDATE && pTrigger->pColumns &&
714 !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
715 fire_this = 0;
716 }
717 }
718
719 if( fire_this && (pTriggerStack = sqliteMalloc(sizeof(TriggerStack)))!=0 ){
720 int endTrigger;
721 SrcList dummyTablist;
722 Expr * whenExpr;
723 AuthContext sContext;
724
725 dummyTablist.nSrc = 0;
726
727 /* Push an entry on to the trigger stack */
728 pTriggerStack->pTrigger = pTrigger;
729 pTriggerStack->newIdx = newIdx;
730 pTriggerStack->oldIdx = oldIdx;
731 pTriggerStack->pTab = pTab;
732 pTriggerStack->pNext = pParse->trigStack;
733 pTriggerStack->ignoreJump = ignoreJump;
734 pParse->trigStack = pTriggerStack;
735 sqliteAuthContextPush(pParse, &sContext, pTrigger->name);
736
737 /* code the WHEN clause */
738 endTrigger = sqliteVdbeMakeLabel(pParse->pVdbe);
739 whenExpr = sqliteExprDup(pTrigger->pWhen);
740 if( sqliteExprResolveIds(pParse, &dummyTablist, 0, whenExpr) ){
741 pParse->trigStack = pParse->trigStack->pNext;
742 sqliteFree(pTriggerStack);
743 sqliteExprDelete(whenExpr);
744 return 1;
745 }
746 sqliteExprIfFalse(pParse, whenExpr, endTrigger, 1);
747 sqliteExprDelete(whenExpr);
748
749 sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPush, 0, 0);
750 codeTriggerProgram(pParse, pTrigger->step_list, orconf);
751 sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPop, 0, 0);
752
753 /* Pop the entry off the trigger stack */
754 pParse->trigStack = pParse->trigStack->pNext;
755 sqliteAuthContextPop(&sContext);
756 sqliteFree(pTriggerStack);
757
758 sqliteVdbeResolveLabel(pParse->pVdbe, endTrigger);
759 }
760 pTrigger = pTrigger->pNext;
761 }
762
763 return 0;
764}
Note: See TracBrowser for help on using the repository browser.