blob: d26ddb9eaa09724a36c38e7022551ffd39cc35d2 [file] [log] [blame]
danielk1977c3f9bad2002-05-15 08:30:12 +00001/*
danielk1977633ed082002-05-17 00:05:58 +00002**
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*
drh9adf9ac2002-05-15 11:44:13 +000012*/
danielk1977c3f9bad2002-05-15 08:30:12 +000013#include "sqliteInt.h"
drh9adf9ac2002-05-15 11:44:13 +000014
danielk1977c3f9bad2002-05-15 08:30:12 +000015/*
danielk1977633ed082002-05-17 00:05:58 +000016** This is called by the parser when it sees a CREATE TRIGGER statement. See
17** comments surrounding struct Trigger in sqliteInt.h for a description of
18** how triggers are stored.
drh9adf9ac2002-05-15 11:44:13 +000019*/
20void sqliteCreateTrigger(
21 Parse *pParse, /* The parse context of the CREATE TRIGGER statement */
danielk1977633ed082002-05-17 00:05:58 +000022 Token *pName, /* The name of the trigger */
drh9adf9ac2002-05-15 11:44:13 +000023 int tr_tm, /* One of TK_BEFORE, TK_AFTER */
24 int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
danielk1977633ed082002-05-17 00:05:58 +000025 IdList *pColumns, /* column list if this is an UPDATE OF trigger */
26 Token *pTableName, /* The name of the table/view the trigger applies to */
drh9adf9ac2002-05-15 11:44:13 +000027 int foreach, /* One of TK_ROW or TK_STATEMENT */
28 Expr *pWhen, /* WHEN clause */
danielk1977633ed082002-05-17 00:05:58 +000029 TriggerStep *pStepList, /* The triggered program */
30 char const *zData, /* The string data to make persistent */
31 int zDataLen
drh9adf9ac2002-05-15 11:44:13 +000032){
33 Trigger *nt;
34 Table *tab;
danielk1977c3f9bad2002-05-15 08:30:12 +000035 int offset;
drh9adf9ac2002-05-15 11:44:13 +000036 TriggerStep *ss;
danielk1977c3f9bad2002-05-15 08:30:12 +000037
38 /* Check that:
drh9adf9ac2002-05-15 11:44:13 +000039 ** 1. the trigger name does not already exist.
40 ** 2. the table (or view) does exist.
41 */
danielk1977c3f9bad2002-05-15 08:30:12 +000042 {
danielk1977633ed082002-05-17 00:05:58 +000043 char *tmp_str = sqliteStrNDup(pName->z, pName->n);
44 if( sqliteHashFind(&(pParse->db->trigHash), tmp_str, pName->n + 1) ){
danielk1977c3f9bad2002-05-15 08:30:12 +000045 sqliteSetNString(&pParse->zErrMsg, "trigger ", -1,
danielk1977633ed082002-05-17 00:05:58 +000046 pName->z, pName->n, " already exists", -1, 0);
danielk1977c3f9bad2002-05-15 08:30:12 +000047 sqliteFree(tmp_str);
48 pParse->nErr++;
49 goto trigger_cleanup;
50 }
51 sqliteFree(tmp_str);
52 }
53 {
danielk1977633ed082002-05-17 00:05:58 +000054 char *tmp_str = sqliteStrNDup(pTableName->z, pTableName->n);
danielk1977c3f9bad2002-05-15 08:30:12 +000055 tab = sqliteFindTable(pParse->db, tmp_str);
56 sqliteFree(tmp_str);
drh9adf9ac2002-05-15 11:44:13 +000057 if( !tab ){
danielk1977c3f9bad2002-05-15 08:30:12 +000058 sqliteSetNString(&pParse->zErrMsg, "no such table: ", -1,
danielk1977633ed082002-05-17 00:05:58 +000059 pTableName->z, pTableName->n, 0);
danielk1977c3f9bad2002-05-15 08:30:12 +000060 pParse->nErr++;
61 goto trigger_cleanup;
62 }
63 }
64
65 /* Build the Trigger object */
drh9adf9ac2002-05-15 11:44:13 +000066 nt = (Trigger*)sqliteMalloc(sizeof(Trigger));
danielk1977633ed082002-05-17 00:05:58 +000067 nt->name = sqliteStrNDup(pName->z, pName->n);
68 nt->table = sqliteStrNDup(pTableName->z, pTableName->n);
danielk1977c3f9bad2002-05-15 08:30:12 +000069 nt->op = op;
70 nt->tr_tm = tr_tm;
71 nt->pWhen = pWhen;
danielk1977633ed082002-05-17 00:05:58 +000072 nt->pColumns = pColumns;
danielk1977c3f9bad2002-05-15 08:30:12 +000073 nt->foreach = foreach;
danielk1977633ed082002-05-17 00:05:58 +000074 nt->step_list = pStepList;
danielk1977c3f9bad2002-05-15 08:30:12 +000075 nt->isCommit = 0;
76
danielk1977633ed082002-05-17 00:05:58 +000077 nt->strings = sqliteStrNDup(zData, zDataLen);
78 offset = (int)(nt->strings - zData);
danielk1977c3f9bad2002-05-15 08:30:12 +000079
80 sqliteExprMoveStrings(nt->pWhen, offset);
81
82 ss = nt->step_list;
danielk1977f29ce552002-05-19 23:43:12 +000083 while( ss ){
danielk1977c3f9bad2002-05-15 08:30:12 +000084 sqliteSelectMoveStrings(ss->pSelect, offset);
danielk1977f29ce552002-05-19 23:43:12 +000085 if( ss->target.z ){
86 ss->target.z += offset;
87 }
danielk1977c3f9bad2002-05-15 08:30:12 +000088 sqliteExprMoveStrings(ss->pWhere, offset);
89 sqliteExprListMoveStrings(ss->pExprList, offset);
90
91 ss = ss->pNext;
92 }
93
94 /* if we are not initializing, and this trigger is not on a TEMP table,
drh9adf9ac2002-05-15 11:44:13 +000095 ** build the sqlite_master entry
96 */
97 if( !pParse->initFlag && !tab->isTemp ){
drhc977f7f2002-05-21 11:38:11 +000098 static VdbeOp insertTrig[] = {
99 { OP_OpenWrite, 0, 2, MASTER_NAME},
100 { OP_NewRecno, 0, 0, 0 },
101 { OP_String, 0, 0, "trigger" },
102 { OP_String, 0, 0, 0 }, /* 3: trigger name */
103 { OP_String, 0, 0, 0 }, /* 4: table name */
104 { OP_Integer, 0, 0, 0 },
105 { OP_String, 0, 0, 0 }, /* 6: SQL */
106 { OP_MakeRecord, 5, 0, 0 },
107 { OP_PutIntKey, 0, 0, 0 },
108 { OP_Integer, 0, 0, 0 }, /* 9: Next cookie */
109 { OP_SetCookie, 0, 0, 0 },
110 { OP_Close, 0, 0, 0 },
111 };
112 int addr;
113 Vdbe *v;
danielk1977c3f9bad2002-05-15 08:30:12 +0000114
115 /* Make an entry in the sqlite_master table */
drhc977f7f2002-05-21 11:38:11 +0000116 v = sqliteGetVdbe(pParse);
117 sqliteBeginWriteOperation(pParse, 0);
118 addr = sqliteVdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
119 sqliteVdbeChangeP3(v, addr+3, nt->name, 0);
120 sqliteVdbeChangeP3(v, addr+4, nt->table, 0);
121 sqliteVdbeChangeP3(v, addr+6, nt->strings, 0);
drhdc379452002-05-15 12:45:43 +0000122 sqliteChangeCookie(pParse->db);
drhc977f7f2002-05-21 11:38:11 +0000123 sqliteVdbeChangeP1(v, addr+9, pParse->db->next_cookie);
danielk1977c3f9bad2002-05-15 08:30:12 +0000124 sqliteEndWriteOperation(pParse);
125 }
126
danielk1977633ed082002-05-17 00:05:58 +0000127 if( !pParse->explain ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000128 /* Stick it in the hash-table */
danielk1977633ed082002-05-17 00:05:58 +0000129 sqliteHashInsert(&(pParse->db->trigHash), nt->name, pName->n + 1, nt);
danielk1977c3f9bad2002-05-15 08:30:12 +0000130
131 /* Attach it to the table object */
132 nt->pNext = tab->pTrigger;
133 tab->pTrigger = nt;
134 return;
danielk1977f29ce552002-05-19 23:43:12 +0000135 }else{
danielk1977c3f9bad2002-05-15 08:30:12 +0000136 sqliteFree(nt->strings);
137 sqliteFree(nt->name);
138 sqliteFree(nt->table);
139 sqliteFree(nt);
140 }
141
142trigger_cleanup:
143
danielk1977633ed082002-05-17 00:05:58 +0000144 sqliteIdListDelete(pColumns);
danielk1977c3f9bad2002-05-15 08:30:12 +0000145 sqliteExprDelete(pWhen);
146 {
147 TriggerStep * pp;
148 TriggerStep * nn;
149
danielk1977633ed082002-05-17 00:05:58 +0000150 pp = pStepList;
danielk1977f29ce552002-05-19 23:43:12 +0000151 while( pp ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000152 nn = pp->pNext;
153 sqliteExprDelete(pp->pWhere);
154 sqliteExprListDelete(pp->pExprList);
155 sqliteSelectDelete(pp->pSelect);
156 sqliteIdListDelete(pp->pIdList);
157 sqliteFree(pp);
158 pp = nn;
159 }
160 }
161}
162
drhc977f7f2002-05-21 11:38:11 +0000163/*
164** Turn a SELECT statement (that the pSelect parameter points to) into
165** a trigger step. Return a pointer to a TriggerStep structure.
166**
167** The parser calls this routine when it finds a SELECT statement in
168** body of a TRIGGER.
169*/
170TriggerStep *sqliteTriggerSelectStep(Select *pSelect){
danielk1977633ed082002-05-17 00:05:58 +0000171 TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
danielk1977c3f9bad2002-05-15 08:30:12 +0000172
danielk1977633ed082002-05-17 00:05:58 +0000173 pTriggerStep->op = TK_SELECT;
174 pTriggerStep->pSelect = pSelect;
175 pTriggerStep->orconf = OE_Default;
danielk1977c3f9bad2002-05-15 08:30:12 +0000176
danielk1977633ed082002-05-17 00:05:58 +0000177 return pTriggerStep;
danielk1977c3f9bad2002-05-15 08:30:12 +0000178}
179
drhc977f7f2002-05-21 11:38:11 +0000180/*
181** Build a trigger step out of an INSERT statement. Return a pointer
182** to the new trigger step.
183**
184** The parser calls this routine when it sees an INSERT inside the
185** body of a trigger.
186*/
danielk1977633ed082002-05-17 00:05:58 +0000187TriggerStep *sqliteTriggerInsertStep(
drhc977f7f2002-05-21 11:38:11 +0000188 Token *pTableName, /* Name of the table into which we insert */
189 IdList *pColumn, /* List of columns in pTableName to insert into */
190 ExprList *pEList, /* The VALUE clause: a list of values to be inserted */
191 Select *pSelect, /* A SELECT statement that supplies values */
192 int orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
danielk1977633ed082002-05-17 00:05:58 +0000193){
194 TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
danielk1977c3f9bad2002-05-15 08:30:12 +0000195
danielk1977633ed082002-05-17 00:05:58 +0000196 assert(pEList == 0 || pSelect == 0);
197 assert(pEList != 0 || pSelect != 0);
danielk1977c3f9bad2002-05-15 08:30:12 +0000198
danielk1977633ed082002-05-17 00:05:58 +0000199 pTriggerStep->op = TK_INSERT;
200 pTriggerStep->pSelect = pSelect;
201 pTriggerStep->target = *pTableName;
202 pTriggerStep->pIdList = pColumn;
203 pTriggerStep->pExprList = pEList;
204 pTriggerStep->orconf = orconf;
danielk1977c3f9bad2002-05-15 08:30:12 +0000205
danielk1977633ed082002-05-17 00:05:58 +0000206 return pTriggerStep;
danielk1977c3f9bad2002-05-15 08:30:12 +0000207}
208
drhc977f7f2002-05-21 11:38:11 +0000209/*
210** Construct a trigger step that implements an UPDATE statement and return
211** a pointer to that trigger step. The parser calls this routine when it
212** sees an UPDATE statement inside the body of a CREATE TRIGGER.
213*/
danielk1977633ed082002-05-17 00:05:58 +0000214TriggerStep *sqliteTriggerUpdateStep(
drhc977f7f2002-05-21 11:38:11 +0000215 Token *pTableName, /* Name of the table to be updated */
216 ExprList *pEList, /* The SET clause: list of column and new values */
217 Expr *pWhere, /* The WHERE clause */
218 int orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
219){
danielk1977633ed082002-05-17 00:05:58 +0000220 TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
danielk1977c3f9bad2002-05-15 08:30:12 +0000221
danielk1977633ed082002-05-17 00:05:58 +0000222 pTriggerStep->op = TK_UPDATE;
223 pTriggerStep->target = *pTableName;
224 pTriggerStep->pExprList = pEList;
225 pTriggerStep->pWhere = pWhere;
226 pTriggerStep->orconf = orconf;
danielk1977c3f9bad2002-05-15 08:30:12 +0000227
danielk1977633ed082002-05-17 00:05:58 +0000228 return pTriggerStep;
danielk1977c3f9bad2002-05-15 08:30:12 +0000229}
230
drhc977f7f2002-05-21 11:38:11 +0000231/*
232** Construct a trigger step that implements a DELETE statement and return
233** a pointer to that trigger step. The parser calls this routine when it
234** sees a DELETE statement inside the body of a CREATE TRIGGER.
235*/
236TriggerStep *sqliteTriggerDeleteStep(Token *pTableName, Expr *pWhere){
danielk1977633ed082002-05-17 00:05:58 +0000237 TriggerStep * pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
danielk1977c3f9bad2002-05-15 08:30:12 +0000238
danielk1977633ed082002-05-17 00:05:58 +0000239 pTriggerStep->op = TK_DELETE;
240 pTriggerStep->target = *pTableName;
241 pTriggerStep->pWhere = pWhere;
242 pTriggerStep->orconf = OE_Default;
danielk1977c3f9bad2002-05-15 08:30:12 +0000243
danielk1977633ed082002-05-17 00:05:58 +0000244 return pTriggerStep;
danielk1977c3f9bad2002-05-15 08:30:12 +0000245}
246
danielk1977633ed082002-05-17 00:05:58 +0000247/*
248** Recursively delete a Trigger structure
249*/
250void sqliteDeleteTrigger(Trigger *pTrigger)
danielk1977c3f9bad2002-05-15 08:30:12 +0000251{
danielk1977633ed082002-05-17 00:05:58 +0000252 TriggerStep *pTriggerStep;
danielk1977c3f9bad2002-05-15 08:30:12 +0000253
danielk1977633ed082002-05-17 00:05:58 +0000254 pTriggerStep = pTrigger->step_list;
danielk1977f29ce552002-05-19 23:43:12 +0000255 while( pTriggerStep ){
danielk1977633ed082002-05-17 00:05:58 +0000256 TriggerStep * pTmp = pTriggerStep;
257 pTriggerStep = pTriggerStep->pNext;
danielk1977c3f9bad2002-05-15 08:30:12 +0000258
danielk1977633ed082002-05-17 00:05:58 +0000259 sqliteExprDelete(pTmp->pWhere);
260 sqliteExprListDelete(pTmp->pExprList);
261 sqliteSelectDelete(pTmp->pSelect);
262 sqliteIdListDelete(pTmp->pIdList);
danielk1977c3f9bad2002-05-15 08:30:12 +0000263
danielk1977633ed082002-05-17 00:05:58 +0000264 sqliteFree(pTmp);
danielk1977c3f9bad2002-05-15 08:30:12 +0000265 }
266
danielk1977633ed082002-05-17 00:05:58 +0000267 sqliteFree(pTrigger->name);
268 sqliteFree(pTrigger->table);
269 sqliteExprDelete(pTrigger->pWhen);
270 sqliteIdListDelete(pTrigger->pColumns);
271 sqliteFree(pTrigger->strings);
272 sqliteFree(pTrigger);
danielk1977c3f9bad2002-05-15 08:30:12 +0000273}
274
275/*
danielk1977633ed082002-05-17 00:05:58 +0000276 * This function is called to drop a trigger from the database schema.
277 *
278 * This may be called directly from the parser, or from within
279 * sqliteDropTable(). In the latter case the "nested" argument is true.
280 *
281 * Note that this function does not delete the trigger entirely. Instead it
282 * removes it from the internal schema and places it in the trigDrop hash
283 * table. This is so that the trigger can be restored into the database schema
284 * if the transaction is rolled back.
danielk1977c3f9bad2002-05-15 08:30:12 +0000285 */
danielk1977633ed082002-05-17 00:05:58 +0000286void sqliteDropTrigger(Parse *pParse, Token *pName, int nested)
danielk1977c3f9bad2002-05-15 08:30:12 +0000287{
danielk1977633ed082002-05-17 00:05:58 +0000288 char *zName;
289 Trigger *pTrigger;
290 Table *pTable;
danielk1977c3f9bad2002-05-15 08:30:12 +0000291
danielk1977633ed082002-05-17 00:05:58 +0000292 zName = sqliteStrNDup(pName->z, pName->n);
danielk1977c3f9bad2002-05-15 08:30:12 +0000293
294 /* ensure that the trigger being dropped exists */
danielk1977633ed082002-05-17 00:05:58 +0000295 pTrigger = sqliteHashFind(&(pParse->db->trigHash), zName, pName->n + 1);
296 if( !pTrigger ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000297 sqliteSetNString(&pParse->zErrMsg, "no such trigger: ", -1,
danielk1977633ed082002-05-17 00:05:58 +0000298 zName, -1, 0);
299 sqliteFree(zName);
danielk1977c3f9bad2002-05-15 08:30:12 +0000300 return;
301 }
302
303 /*
304 * If this is not an "explain", do the following:
305 * 1. Remove the trigger from its associated table structure
306 * 2. Move the trigger from the trigHash hash to trigDrop
307 */
danielk1977633ed082002-05-17 00:05:58 +0000308 if( !pParse->explain ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000309 /* 1 */
danielk1977633ed082002-05-17 00:05:58 +0000310 pTable = sqliteFindTable(pParse->db, pTrigger->table);
311 assert(pTable);
312 if( pTable->pTrigger == pTrigger ){
313 pTable->pTrigger = pTrigger->pNext;
danielk1977f29ce552002-05-19 23:43:12 +0000314 }else{
danielk1977633ed082002-05-17 00:05:58 +0000315 Trigger *cc = pTable->pTrigger;
316 while( cc ){
317 if( cc->pNext == pTrigger ){
drh9adf9ac2002-05-15 11:44:13 +0000318 cc->pNext = cc->pNext->pNext;
319 break;
320 }
321 cc = cc->pNext;
danielk1977c3f9bad2002-05-15 08:30:12 +0000322 }
323 assert(cc);
324 }
325
326 /* 2 */
danielk1977633ed082002-05-17 00:05:58 +0000327 sqliteHashInsert(&(pParse->db->trigHash), zName,
328 pName->n + 1, NULL);
329 sqliteHashInsert(&(pParse->db->trigDrop), pTrigger->name,
330 pName->n + 1, pTrigger);
danielk1977c3f9bad2002-05-15 08:30:12 +0000331 }
332
333 /* Unless this is a trigger on a TEMP TABLE, generate code to destroy the
334 * database record of the trigger */
danielk1977633ed082002-05-17 00:05:58 +0000335 if( !pTable->isTemp ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000336 int base;
337 static VdbeOp dropTrigger[] = {
338 { OP_OpenWrite, 0, 2, MASTER_NAME},
339 { OP_Rewind, 0, ADDR(9), 0},
340 { OP_String, 0, 0, 0}, /* 2 */
341 { OP_MemStore, 1, 1, 0},
342 { OP_MemLoad, 1, 0, 0}, /* 4 */
343 { OP_Column, 0, 1, 0},
344 { OP_Ne, 0, ADDR(8), 0},
345 { OP_Delete, 0, 0, 0},
346 { OP_Next, 0, ADDR(4), 0}, /* 8 */
347 { OP_Integer, 0, 0, 0}, /* 9 */
348 { OP_SetCookie, 0, 0, 0},
349 { OP_Close, 0, 0, 0},
350 };
351
drhdc379452002-05-15 12:45:43 +0000352 if( !nested ){
drhc977f7f2002-05-21 11:38:11 +0000353 sqliteBeginWriteOperation(pParse, 0);
drhdc379452002-05-15 12:45:43 +0000354 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000355 base = sqliteVdbeAddOpList(pParse->pVdbe,
drh9adf9ac2002-05-15 11:44:13 +0000356 ArraySize(dropTrigger), dropTrigger);
danielk1977633ed082002-05-17 00:05:58 +0000357 sqliteVdbeChangeP3(pParse->pVdbe, base+2, zName, 0);
drhdc379452002-05-15 12:45:43 +0000358 if( !nested ){
359 sqliteChangeCookie(pParse->db);
360 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000361 sqliteVdbeChangeP1(pParse->pVdbe, base+9, pParse->db->next_cookie);
drhdc379452002-05-15 12:45:43 +0000362 if( !nested ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000363 sqliteEndWriteOperation(pParse);
drhdc379452002-05-15 12:45:43 +0000364 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000365 }
366
danielk1977633ed082002-05-17 00:05:58 +0000367 sqliteFree(zName);
danielk1977c3f9bad2002-05-15 08:30:12 +0000368}
369
drhc977f7f2002-05-21 11:38:11 +0000370/*
371** pEList is the SET clause of an UPDATE statement. Each entry
372** in pEList is of the format <id>=<expr>. If any of the entries
373** in pEList have an <id> which matches an identifier in pIdList,
374** then return TRUE. If pIdList==NULL, then it is considered a
375** wildcard that matches anything. Likewise if pEList==NULL then
376** it matches anything so always return true. Return false only
377** if there is no match.
378*/
379static int checkColumnOverLap(IdList *pIdList, ExprList *pEList){
danielk1977c3f9bad2002-05-15 08:30:12 +0000380 int i, e;
danielk1977f29ce552002-05-19 23:43:12 +0000381 if( !pIdList )return 1;
382 if( !pEList )return 1;
danielk1977c3f9bad2002-05-15 08:30:12 +0000383
danielk1977f29ce552002-05-19 23:43:12 +0000384 for(i = 0; i < pIdList->nId; i++){
385 for(e = 0; e < pEList->nExpr; e++){
386 if( !sqliteStrICmp(pIdList->a[i].zName, pEList->a[e].zName) ){
drh9adf9ac2002-05-15 11:44:13 +0000387 return 1;
danielk1977f29ce552002-05-19 23:43:12 +0000388 }
389 }
390 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000391
392 return 0;
393}
394
395/* A global variable that is TRUE if we should always set up temp tables for
396 * for triggers, even if there are no triggers to code. This is used to test
397 * how much overhead the triggers algorithm is causing.
398 *
399 * This flag can be set or cleared using the "trigger_overhead_test" pragma.
400 * The pragma is not documented since it is not really part of the interface
401 * to SQLite, just the test procedure.
402*/
403int always_code_trigger_setup = 0;
404
405/*
406 * Returns true if a trigger matching op, tr_tm and foreach that is NOT already
407 * on the Parse objects trigger-stack (to prevent recursive trigger firing) is
408 * found in the list specified as pTrigger.
409 */
410int sqliteTriggersExist(
drhc977f7f2002-05-21 11:38:11 +0000411 Parse *pParse, /* Used to check for recursive triggers */
412 Trigger *pTrigger, /* A list of triggers associated with a table */
danielk1977633ed082002-05-17 00:05:58 +0000413 int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
414 int tr_tm, /* one of TK_BEFORE, TK_AFTER */
415 int foreach, /* one of TK_ROW or TK_STATEMENT */
drhc977f7f2002-05-21 11:38:11 +0000416 ExprList *pChanges /* Columns that change in an UPDATE statement */
417){
danielk1977633ed082002-05-17 00:05:58 +0000418 Trigger * pTriggerCursor;
danielk1977c3f9bad2002-05-15 08:30:12 +0000419
danielk1977633ed082002-05-17 00:05:58 +0000420 if( always_code_trigger_setup ){
421 return 1;
422 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000423
danielk1977633ed082002-05-17 00:05:58 +0000424 pTriggerCursor = pTrigger;
425 while( pTriggerCursor ){
426 if( pTriggerCursor->op == op &&
427 pTriggerCursor->tr_tm == tr_tm &&
428 pTriggerCursor->foreach == foreach &&
429 checkColumnOverLap(pTriggerCursor->pColumns, pChanges) ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000430 TriggerStack * ss;
431 ss = pParse->trigStack;
danielk1977f29ce552002-05-19 23:43:12 +0000432 while( ss && ss->pTrigger != pTrigger ){
433 ss = ss->pNext;
434 }
435 if( !ss )return 1;
danielk1977c3f9bad2002-05-15 08:30:12 +0000436 }
danielk1977633ed082002-05-17 00:05:58 +0000437 pTriggerCursor = pTriggerCursor->pNext;
danielk1977c3f9bad2002-05-15 08:30:12 +0000438 }
439
440 return 0;
441}
442
drhc977f7f2002-05-21 11:38:11 +0000443/*
444** Generate VDBE code for zero or more statements inside the body of a
445** trigger.
446*/
danielk1977c3f9bad2002-05-15 08:30:12 +0000447static int codeTriggerProgram(
drhc977f7f2002-05-21 11:38:11 +0000448 Parse *pParse, /* The parser context */
449 TriggerStep *pStepList, /* List of statements inside the trigger body */
450 int orconfin /* Conflict algorithm. (OE_Abort, etc) */
danielk1977633ed082002-05-17 00:05:58 +0000451){
452 TriggerStep * pTriggerStep = pStepList;
453 int orconf;
danielk1977c3f9bad2002-05-15 08:30:12 +0000454
danielk1977633ed082002-05-17 00:05:58 +0000455 while( pTriggerStep ){
456 int saveNTab = pParse->nTab;
457 orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
458 pParse->trigStack->orconf = orconf;
459 switch( pTriggerStep->op ){
460 case TK_SELECT: {
461 int tmp_tbl = pParse->nTab++;
462 sqliteVdbeAddOp(pParse->pVdbe, OP_OpenTemp, tmp_tbl, 0);
463 sqliteVdbeAddOp(pParse->pVdbe, OP_KeyAsData, tmp_tbl, 1);
464 sqliteSelect(pParse, pTriggerStep->pSelect, SRT_Union,
465 tmp_tbl, 0, 0, 0);
466 sqliteVdbeAddOp(pParse->pVdbe, OP_Close, tmp_tbl, 0);
467 pParse->nTab--;
468 break;
469 }
470 case TK_UPDATE: {
471 sqliteVdbeAddOp(pParse->pVdbe, OP_PushList, 0, 0);
472 sqliteUpdate(pParse, &pTriggerStep->target,
473 sqliteExprListDup(pTriggerStep->pExprList),
474 sqliteExprDup(pTriggerStep->pWhere), orconf);
475 sqliteVdbeAddOp(pParse->pVdbe, OP_PopList, 0, 0);
476 break;
477 }
478 case TK_INSERT: {
479 sqliteInsert(pParse, &pTriggerStep->target,
480 sqliteExprListDup(pTriggerStep->pExprList),
481 sqliteSelectDup(pTriggerStep->pSelect),
482 sqliteIdListDup(pTriggerStep->pIdList), orconf);
483 break;
484 }
485 case TK_DELETE: {
486 sqliteVdbeAddOp(pParse->pVdbe, OP_PushList, 0, 0);
487 sqliteDeleteFrom(pParse, &pTriggerStep->target,
488 sqliteExprDup(pTriggerStep->pWhere));
489 sqliteVdbeAddOp(pParse->pVdbe, OP_PopList, 0, 0);
490 break;
491 }
492 default:
493 assert(0);
494 }
495 pParse->nTab = saveNTab;
496 pTriggerStep = pTriggerStep->pNext;
497 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000498
danielk1977633ed082002-05-17 00:05:58 +0000499 return 0;
danielk1977c3f9bad2002-05-15 08:30:12 +0000500}
501
danielk1977633ed082002-05-17 00:05:58 +0000502/*
503** This is called to code FOR EACH ROW triggers.
504**
505** When the code that this function generates is executed, the following
506** must be true:
drhc977f7f2002-05-21 11:38:11 +0000507**
508** 1. No cursors may be open in the main database. (But newIdx and oldIdx
509** can be indices of cursors in temporary tables. See below.)
510**
danielk1977633ed082002-05-17 00:05:58 +0000511** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then
512** a temporary vdbe cursor (index newIdx) must be open and pointing at
513** a row containing values to be substituted for new.* expressions in the
514** trigger program(s).
drhc977f7f2002-05-21 11:38:11 +0000515**
danielk1977633ed082002-05-17 00:05:58 +0000516** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then
517** a temporary vdbe cursor (index oldIdx) must be open and pointing at
518** a row containing values to be substituted for old.* expressions in the
519** trigger program(s).
520**
521*/
danielk1977c3f9bad2002-05-15 08:30:12 +0000522int sqliteCodeRowTrigger(
danielk1977633ed082002-05-17 00:05:58 +0000523 Parse *pParse, /* Parse context */
524 int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
525 ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
526 int tr_tm, /* One of TK_BEFORE, TK_AFTER */
527 Table *pTab, /* The table to code triggers from */
528 int newIdx, /* The indice of the "new" row to access */
529 int oldIdx, /* The indice of the "old" row to access */
drhc977f7f2002-05-21 11:38:11 +0000530 int orconf /* ON CONFLICT policy */
531){
danielk1977c3f9bad2002-05-15 08:30:12 +0000532 Trigger * pTrigger;
533 TriggerStack * pTriggerStack;
534
danielk1977c3f9bad2002-05-15 08:30:12 +0000535 assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
536 assert(tr_tm == TK_BEFORE || tr_tm == TK_AFTER);
537
danielk1977633ed082002-05-17 00:05:58 +0000538 assert(newIdx != -1 || oldIdx != -1);
danielk1977c3f9bad2002-05-15 08:30:12 +0000539
danielk1977633ed082002-05-17 00:05:58 +0000540 pTrigger = pTab->pTrigger;
danielk1977f29ce552002-05-19 23:43:12 +0000541 while( pTrigger ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000542 int fire_this = 0;
543
544 /* determine whether we should code this trigger */
danielk1977f29ce552002-05-19 23:43:12 +0000545 if( pTrigger->op == op && pTrigger->tr_tm == tr_tm &&
546 pTrigger->foreach == TK_ROW ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000547 fire_this = 1;
548 pTriggerStack = pParse->trigStack;
danielk1977f29ce552002-05-19 23:43:12 +0000549 while( pTriggerStack ){
550 if( pTriggerStack->pTrigger == pTrigger ){
551 fire_this = 0;
552 }
drh9adf9ac2002-05-15 11:44:13 +0000553 pTriggerStack = pTriggerStack->pNext;
danielk1977c3f9bad2002-05-15 08:30:12 +0000554 }
danielk1977f29ce552002-05-19 23:43:12 +0000555 if( op == TK_UPDATE && pTrigger->pColumns &&
556 !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
drh9adf9ac2002-05-15 11:44:13 +0000557 fire_this = 0;
danielk1977f29ce552002-05-19 23:43:12 +0000558 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000559 }
560
danielk1977f29ce552002-05-19 23:43:12 +0000561 if( fire_this ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000562 int endTrigger;
563 IdList dummyTablist;
564 Expr * whenExpr;
565
566 dummyTablist.nId = 0;
567 dummyTablist.a = 0;
568
569 /* Push an entry on to the trigger stack */
570 pTriggerStack = sqliteMalloc(sizeof(TriggerStack));
571 pTriggerStack->pTrigger = pTrigger;
danielk1977633ed082002-05-17 00:05:58 +0000572 pTriggerStack->newIdx = newIdx;
573 pTriggerStack->oldIdx = oldIdx;
574 pTriggerStack->pTab = pTab;
danielk1977c3f9bad2002-05-15 08:30:12 +0000575 pTriggerStack->pNext = pParse->trigStack;
576 pParse->trigStack = pTriggerStack;
577
578 /* code the WHEN clause */
579 endTrigger = sqliteVdbeMakeLabel(pParse->pVdbe);
580 whenExpr = sqliteExprDup(pTrigger->pWhen);
danielk1977f29ce552002-05-19 23:43:12 +0000581 if( sqliteExprResolveIds(pParse, 0, &dummyTablist, 0, whenExpr) ){
drh9adf9ac2002-05-15 11:44:13 +0000582 pParse->trigStack = pParse->trigStack->pNext;
583 sqliteFree(pTriggerStack);
584 sqliteExprDelete(whenExpr);
585 return 1;
danielk1977c3f9bad2002-05-15 08:30:12 +0000586 }
587 sqliteExprIfFalse(pParse, whenExpr, endTrigger);
588 sqliteExprDelete(whenExpr);
589
danielk1977633ed082002-05-17 00:05:58 +0000590 codeTriggerProgram(pParse, pTrigger->step_list, orconf);
danielk1977c3f9bad2002-05-15 08:30:12 +0000591
592 /* Pop the entry off the trigger stack */
593 pParse->trigStack = pParse->trigStack->pNext;
594 sqliteFree(pTriggerStack);
595
596 sqliteVdbeResolveLabel(pParse->pVdbe, endTrigger);
597 }
598 pTrigger = pTrigger->pNext;
599 }
600
601 return 0;
602}
603
604/*
danielk1977633ed082002-05-17 00:05:58 +0000605 * This function is called to code ON UPDATE and ON DELETE triggers on
606 * views.
607 *
608 * This function deletes the data pointed at by the pWhere and pChanges
609 * arguments before it completes.
danielk1977c3f9bad2002-05-15 08:30:12 +0000610 */
danielk1977633ed082002-05-17 00:05:58 +0000611void sqliteViewTriggers(
612 Parse *pParse,
613 Table *pTab, /* The view to code triggers on */
614 Expr *pWhere, /* The WHERE clause of the statement causing triggers*/
615 int orconf, /* The ON CONFLICT policy specified as part of the
616 statement causing these triggers */
617 ExprList *pChanges /* If this is an statement causing triggers to fire
618 is an UPDATE, then this list holds the columns
619 to update and the expressions to update them to.
620 See comments for sqliteUpdate(). */
621){
danielk1977c3f9bad2002-05-15 08:30:12 +0000622 int oldIdx = -1;
623 int newIdx = -1;
624 int *aXRef = 0;
625 Vdbe *v;
626 int endOfLoop;
627 int startOfLoop;
628 Select theSelect;
629 Token tblNameToken;
630
631 assert(pTab->pSelect);
632
633 tblNameToken.z = pTab->zName;
634 tblNameToken.n = strlen(pTab->zName);
635
636 theSelect.isDistinct = 0;
637 theSelect.pEList = sqliteExprListAppend(0, sqliteExpr(TK_ALL, 0, 0, 0), 0);
638 theSelect.pSrc = sqliteIdListAppend(0, &tblNameToken);
639 theSelect.pWhere = pWhere; pWhere = 0;
640 theSelect.pGroupBy = 0;
641 theSelect.pHaving = 0;
642 theSelect.pOrderBy = 0;
643 theSelect.op = TK_SELECT; /* ?? */
644 theSelect.pPrior = 0;
645 theSelect.nLimit = -1;
646 theSelect.nOffset = -1;
647 theSelect.zSelect = 0;
648 theSelect.base = 0;
649
650 v = sqliteGetVdbe(pParse);
651 assert(v);
drhc977f7f2002-05-21 11:38:11 +0000652 sqliteBeginWriteOperation(pParse, 1);
danielk1977c3f9bad2002-05-15 08:30:12 +0000653
654 /* Allocate temp tables */
655 oldIdx = pParse->nTab++;
656 sqliteVdbeAddOp(v, OP_OpenTemp, oldIdx, 0);
danielk1977633ed082002-05-17 00:05:58 +0000657 if( pChanges ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000658 newIdx = pParse->nTab++;
659 sqliteVdbeAddOp(v, OP_OpenTemp, newIdx, 0);
660 }
661
662 /* Snapshot the view */
danielk1977633ed082002-05-17 00:05:58 +0000663 if( sqliteSelect(pParse, &theSelect, SRT_Table, oldIdx, 0, 0, 0) ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000664 goto trigger_cleanup;
665 }
666
667 /* loop thru the view snapshot, executing triggers for each row */
668 endOfLoop = sqliteVdbeMakeLabel(v);
669 sqliteVdbeAddOp(v, OP_Rewind, oldIdx, endOfLoop);
670
671 /* Loop thru the view snapshot, executing triggers for each row */
672 startOfLoop = sqliteVdbeCurrentAddr(v);
673
674 /* Build the updated row if required */
danielk1977633ed082002-05-17 00:05:58 +0000675 if( pChanges ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000676 int ii, jj;
677
678 aXRef = sqliteMalloc( sizeof(int) * pTab->nCol );
679 if( aXRef==0 ) goto trigger_cleanup;
danielk1977633ed082002-05-17 00:05:58 +0000680 for(ii = 0; ii < pTab->nCol; ii++){
danielk1977c3f9bad2002-05-15 08:30:12 +0000681 aXRef[ii] = -1;
danielk1977633ed082002-05-17 00:05:58 +0000682 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000683
684 for(ii=0; ii<pChanges->nExpr; ii++){
685 int jj;
686 if( sqliteExprResolveIds(pParse, oldIdx, theSelect.pSrc , 0,
danielk1977f29ce552002-05-19 23:43:12 +0000687 pChanges->a[ii].pExpr) ){
drh9adf9ac2002-05-15 11:44:13 +0000688 goto trigger_cleanup;
danielk1977f29ce552002-05-19 23:43:12 +0000689 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000690
691 if( sqliteExprCheck(pParse, pChanges->a[ii].pExpr, 0, 0) )
drh9adf9ac2002-05-15 11:44:13 +0000692 goto trigger_cleanup;
danielk1977c3f9bad2002-05-15 08:30:12 +0000693
694 for(jj=0; jj<pTab->nCol; jj++){
drh9adf9ac2002-05-15 11:44:13 +0000695 if( sqliteStrICmp(pTab->aCol[jj].zName, pChanges->a[ii].zName)==0 ){
696 aXRef[jj] = ii;
697 break;
698 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000699 }
700 if( jj>=pTab->nCol ){
drh9adf9ac2002-05-15 11:44:13 +0000701 sqliteSetString(&pParse->zErrMsg, "no such column: ",
702 pChanges->a[ii].zName, 0);
703 pParse->nErr++;
704 goto trigger_cleanup;
danielk1977c3f9bad2002-05-15 08:30:12 +0000705 }
706 }
707
708 sqliteVdbeAddOp(v, OP_Integer, 13, 0);
709
danielk1977633ed082002-05-17 00:05:58 +0000710 for(ii = 0; ii<pTab->nCol; ii++){
711 if( aXRef[ii] < 0 ){
drh9adf9ac2002-05-15 11:44:13 +0000712 sqliteVdbeAddOp(v, OP_Column, oldIdx, ii);
danielk1977f29ce552002-05-19 23:43:12 +0000713 }else{
drh9adf9ac2002-05-15 11:44:13 +0000714 sqliteExprCode(pParse, pChanges->a[aXRef[ii]].pExpr);
danielk1977633ed082002-05-17 00:05:58 +0000715 }
716 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000717
718 sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
719 sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
720 sqliteVdbeAddOp(v, OP_Rewind, newIdx, 0);
721
722 sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_BEFORE,
danielk1977633ed082002-05-17 00:05:58 +0000723 pTab, newIdx, oldIdx, orconf);
danielk1977c3f9bad2002-05-15 08:30:12 +0000724 sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_AFTER,
danielk1977633ed082002-05-17 00:05:58 +0000725 pTab, newIdx, oldIdx, orconf);
danielk1977f29ce552002-05-19 23:43:12 +0000726 }else{
danielk1977c3f9bad2002-05-15 08:30:12 +0000727 sqliteCodeRowTrigger(pParse, TK_DELETE, 0, TK_BEFORE, pTab, -1, oldIdx,
danielk1977633ed082002-05-17 00:05:58 +0000728 orconf);
danielk1977c3f9bad2002-05-15 08:30:12 +0000729 sqliteCodeRowTrigger(pParse, TK_DELETE, 0, TK_AFTER, pTab, -1, oldIdx,
danielk1977633ed082002-05-17 00:05:58 +0000730 orconf);
danielk1977c3f9bad2002-05-15 08:30:12 +0000731 }
732
733 sqliteVdbeAddOp(v, OP_Next, oldIdx, startOfLoop);
734
735 sqliteVdbeResolveLabel(v, endOfLoop);
736 sqliteEndWriteOperation(pParse);
737
738trigger_cleanup:
739 sqliteFree(aXRef);
740 sqliteExprListDelete(pChanges);
741 sqliteExprDelete(pWhere);
742 sqliteExprListDelete(theSelect.pEList);
743 sqliteIdListDelete(theSelect.pSrc);
744 sqliteExprDelete(theSelect.pWhere);
745 return;
746}