blob: 3f6139d9a7b8a6ad279114e90d39105a57a580db [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*/
drh1d1f3052002-05-21 13:18:25 +0000250void sqliteDeleteTrigger(Trigger *pTrigger){
danielk1977633ed082002-05-17 00:05:58 +0000251 TriggerStep *pTriggerStep;
danielk1977c3f9bad2002-05-15 08:30:12 +0000252
danielk1977633ed082002-05-17 00:05:58 +0000253 pTriggerStep = pTrigger->step_list;
danielk1977f29ce552002-05-19 23:43:12 +0000254 while( pTriggerStep ){
danielk1977633ed082002-05-17 00:05:58 +0000255 TriggerStep * pTmp = pTriggerStep;
256 pTriggerStep = pTriggerStep->pNext;
danielk1977c3f9bad2002-05-15 08:30:12 +0000257
danielk1977633ed082002-05-17 00:05:58 +0000258 sqliteExprDelete(pTmp->pWhere);
259 sqliteExprListDelete(pTmp->pExprList);
260 sqliteSelectDelete(pTmp->pSelect);
261 sqliteIdListDelete(pTmp->pIdList);
danielk1977c3f9bad2002-05-15 08:30:12 +0000262
danielk1977633ed082002-05-17 00:05:58 +0000263 sqliteFree(pTmp);
danielk1977c3f9bad2002-05-15 08:30:12 +0000264 }
265
danielk1977633ed082002-05-17 00:05:58 +0000266 sqliteFree(pTrigger->name);
267 sqliteFree(pTrigger->table);
268 sqliteExprDelete(pTrigger->pWhen);
269 sqliteIdListDelete(pTrigger->pColumns);
270 sqliteFree(pTrigger->strings);
271 sqliteFree(pTrigger);
danielk1977c3f9bad2002-05-15 08:30:12 +0000272}
273
274/*
danielk1977633ed082002-05-17 00:05:58 +0000275 * This function is called to drop a trigger from the database schema.
276 *
277 * This may be called directly from the parser, or from within
278 * sqliteDropTable(). In the latter case the "nested" argument is true.
279 *
280 * Note that this function does not delete the trigger entirely. Instead it
281 * removes it from the internal schema and places it in the trigDrop hash
282 * table. This is so that the trigger can be restored into the database schema
283 * if the transaction is rolled back.
danielk1977c3f9bad2002-05-15 08:30:12 +0000284 */
danielk1977633ed082002-05-17 00:05:58 +0000285void sqliteDropTrigger(Parse *pParse, Token *pName, int nested)
danielk1977c3f9bad2002-05-15 08:30:12 +0000286{
danielk1977633ed082002-05-17 00:05:58 +0000287 char *zName;
288 Trigger *pTrigger;
289 Table *pTable;
danielk1977c3f9bad2002-05-15 08:30:12 +0000290
danielk1977633ed082002-05-17 00:05:58 +0000291 zName = sqliteStrNDup(pName->z, pName->n);
danielk1977c3f9bad2002-05-15 08:30:12 +0000292
293 /* ensure that the trigger being dropped exists */
danielk1977633ed082002-05-17 00:05:58 +0000294 pTrigger = sqliteHashFind(&(pParse->db->trigHash), zName, pName->n + 1);
295 if( !pTrigger ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000296 sqliteSetNString(&pParse->zErrMsg, "no such trigger: ", -1,
danielk1977633ed082002-05-17 00:05:58 +0000297 zName, -1, 0);
298 sqliteFree(zName);
danielk1977c3f9bad2002-05-15 08:30:12 +0000299 return;
300 }
301
302 /*
303 * If this is not an "explain", do the following:
304 * 1. Remove the trigger from its associated table structure
305 * 2. Move the trigger from the trigHash hash to trigDrop
306 */
danielk1977633ed082002-05-17 00:05:58 +0000307 if( !pParse->explain ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000308 /* 1 */
danielk1977633ed082002-05-17 00:05:58 +0000309 pTable = sqliteFindTable(pParse->db, pTrigger->table);
310 assert(pTable);
311 if( pTable->pTrigger == pTrigger ){
312 pTable->pTrigger = pTrigger->pNext;
danielk1977f29ce552002-05-19 23:43:12 +0000313 }else{
danielk1977633ed082002-05-17 00:05:58 +0000314 Trigger *cc = pTable->pTrigger;
315 while( cc ){
316 if( cc->pNext == pTrigger ){
drh9adf9ac2002-05-15 11:44:13 +0000317 cc->pNext = cc->pNext->pNext;
318 break;
319 }
320 cc = cc->pNext;
danielk1977c3f9bad2002-05-15 08:30:12 +0000321 }
322 assert(cc);
323 }
324
325 /* 2 */
danielk1977633ed082002-05-17 00:05:58 +0000326 sqliteHashInsert(&(pParse->db->trigHash), zName,
327 pName->n + 1, NULL);
328 sqliteHashInsert(&(pParse->db->trigDrop), pTrigger->name,
329 pName->n + 1, pTrigger);
danielk1977c3f9bad2002-05-15 08:30:12 +0000330 }
331
332 /* Unless this is a trigger on a TEMP TABLE, generate code to destroy the
333 * database record of the trigger */
danielk1977633ed082002-05-17 00:05:58 +0000334 if( !pTable->isTemp ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000335 int base;
336 static VdbeOp dropTrigger[] = {
337 { OP_OpenWrite, 0, 2, MASTER_NAME},
338 { OP_Rewind, 0, ADDR(9), 0},
339 { OP_String, 0, 0, 0}, /* 2 */
340 { OP_MemStore, 1, 1, 0},
341 { OP_MemLoad, 1, 0, 0}, /* 4 */
342 { OP_Column, 0, 1, 0},
343 { OP_Ne, 0, ADDR(8), 0},
344 { OP_Delete, 0, 0, 0},
345 { OP_Next, 0, ADDR(4), 0}, /* 8 */
346 { OP_Integer, 0, 0, 0}, /* 9 */
347 { OP_SetCookie, 0, 0, 0},
348 { OP_Close, 0, 0, 0},
349 };
350
drhdc379452002-05-15 12:45:43 +0000351 if( !nested ){
drhc977f7f2002-05-21 11:38:11 +0000352 sqliteBeginWriteOperation(pParse, 0);
drhdc379452002-05-15 12:45:43 +0000353 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000354 base = sqliteVdbeAddOpList(pParse->pVdbe,
drh9adf9ac2002-05-15 11:44:13 +0000355 ArraySize(dropTrigger), dropTrigger);
danielk1977633ed082002-05-17 00:05:58 +0000356 sqliteVdbeChangeP3(pParse->pVdbe, base+2, zName, 0);
drhdc379452002-05-15 12:45:43 +0000357 if( !nested ){
358 sqliteChangeCookie(pParse->db);
359 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000360 sqliteVdbeChangeP1(pParse->pVdbe, base+9, pParse->db->next_cookie);
drhdc379452002-05-15 12:45:43 +0000361 if( !nested ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000362 sqliteEndWriteOperation(pParse);
drhdc379452002-05-15 12:45:43 +0000363 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000364 }
365
danielk1977633ed082002-05-17 00:05:58 +0000366 sqliteFree(zName);
danielk1977c3f9bad2002-05-15 08:30:12 +0000367}
368
drhc977f7f2002-05-21 11:38:11 +0000369/*
370** pEList is the SET clause of an UPDATE statement. Each entry
371** in pEList is of the format <id>=<expr>. If any of the entries
372** in pEList have an <id> which matches an identifier in pIdList,
373** then return TRUE. If pIdList==NULL, then it is considered a
374** wildcard that matches anything. Likewise if pEList==NULL then
375** it matches anything so always return true. Return false only
376** if there is no match.
377*/
378static int checkColumnOverLap(IdList *pIdList, ExprList *pEList){
danielk1977c3f9bad2002-05-15 08:30:12 +0000379 int i, e;
danielk1977f29ce552002-05-19 23:43:12 +0000380 if( !pIdList )return 1;
381 if( !pEList )return 1;
danielk1977c3f9bad2002-05-15 08:30:12 +0000382
danielk1977f29ce552002-05-19 23:43:12 +0000383 for(i = 0; i < pIdList->nId; i++){
384 for(e = 0; e < pEList->nExpr; e++){
385 if( !sqliteStrICmp(pIdList->a[i].zName, pEList->a[e].zName) ){
drh9adf9ac2002-05-15 11:44:13 +0000386 return 1;
danielk1977f29ce552002-05-19 23:43:12 +0000387 }
388 }
389 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000390
391 return 0;
392}
393
394/* A global variable that is TRUE if we should always set up temp tables for
395 * for triggers, even if there are no triggers to code. This is used to test
396 * how much overhead the triggers algorithm is causing.
397 *
398 * This flag can be set or cleared using the "trigger_overhead_test" pragma.
399 * The pragma is not documented since it is not really part of the interface
400 * to SQLite, just the test procedure.
401*/
402int always_code_trigger_setup = 0;
403
404/*
405 * Returns true if a trigger matching op, tr_tm and foreach that is NOT already
406 * on the Parse objects trigger-stack (to prevent recursive trigger firing) is
407 * found in the list specified as pTrigger.
408 */
409int sqliteTriggersExist(
drhc977f7f2002-05-21 11:38:11 +0000410 Parse *pParse, /* Used to check for recursive triggers */
411 Trigger *pTrigger, /* A list of triggers associated with a table */
danielk1977633ed082002-05-17 00:05:58 +0000412 int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
413 int tr_tm, /* one of TK_BEFORE, TK_AFTER */
414 int foreach, /* one of TK_ROW or TK_STATEMENT */
drhc977f7f2002-05-21 11:38:11 +0000415 ExprList *pChanges /* Columns that change in an UPDATE statement */
416){
danielk1977633ed082002-05-17 00:05:58 +0000417 Trigger * pTriggerCursor;
danielk1977c3f9bad2002-05-15 08:30:12 +0000418
danielk1977633ed082002-05-17 00:05:58 +0000419 if( always_code_trigger_setup ){
420 return 1;
421 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000422
danielk1977633ed082002-05-17 00:05:58 +0000423 pTriggerCursor = pTrigger;
424 while( pTriggerCursor ){
425 if( pTriggerCursor->op == op &&
426 pTriggerCursor->tr_tm == tr_tm &&
427 pTriggerCursor->foreach == foreach &&
428 checkColumnOverLap(pTriggerCursor->pColumns, pChanges) ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000429 TriggerStack * ss;
430 ss = pParse->trigStack;
danielk1977f29ce552002-05-19 23:43:12 +0000431 while( ss && ss->pTrigger != pTrigger ){
432 ss = ss->pNext;
433 }
434 if( !ss )return 1;
danielk1977c3f9bad2002-05-15 08:30:12 +0000435 }
danielk1977633ed082002-05-17 00:05:58 +0000436 pTriggerCursor = pTriggerCursor->pNext;
danielk1977c3f9bad2002-05-15 08:30:12 +0000437 }
438
439 return 0;
440}
441
drhc977f7f2002-05-21 11:38:11 +0000442/*
443** Generate VDBE code for zero or more statements inside the body of a
444** trigger.
445*/
danielk1977c3f9bad2002-05-15 08:30:12 +0000446static int codeTriggerProgram(
drhc977f7f2002-05-21 11:38:11 +0000447 Parse *pParse, /* The parser context */
448 TriggerStep *pStepList, /* List of statements inside the trigger body */
449 int orconfin /* Conflict algorithm. (OE_Abort, etc) */
danielk1977633ed082002-05-17 00:05:58 +0000450){
451 TriggerStep * pTriggerStep = pStepList;
452 int orconf;
danielk1977c3f9bad2002-05-15 08:30:12 +0000453
danielk1977633ed082002-05-17 00:05:58 +0000454 while( pTriggerStep ){
455 int saveNTab = pParse->nTab;
456 orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
457 pParse->trigStack->orconf = orconf;
458 switch( pTriggerStep->op ){
459 case TK_SELECT: {
460 int tmp_tbl = pParse->nTab++;
461 sqliteVdbeAddOp(pParse->pVdbe, OP_OpenTemp, tmp_tbl, 0);
462 sqliteVdbeAddOp(pParse->pVdbe, OP_KeyAsData, tmp_tbl, 1);
463 sqliteSelect(pParse, pTriggerStep->pSelect, SRT_Union,
464 tmp_tbl, 0, 0, 0);
465 sqliteVdbeAddOp(pParse->pVdbe, OP_Close, tmp_tbl, 0);
466 pParse->nTab--;
467 break;
468 }
469 case TK_UPDATE: {
470 sqliteVdbeAddOp(pParse->pVdbe, OP_PushList, 0, 0);
471 sqliteUpdate(pParse, &pTriggerStep->target,
472 sqliteExprListDup(pTriggerStep->pExprList),
473 sqliteExprDup(pTriggerStep->pWhere), orconf);
474 sqliteVdbeAddOp(pParse->pVdbe, OP_PopList, 0, 0);
475 break;
476 }
477 case TK_INSERT: {
478 sqliteInsert(pParse, &pTriggerStep->target,
479 sqliteExprListDup(pTriggerStep->pExprList),
480 sqliteSelectDup(pTriggerStep->pSelect),
481 sqliteIdListDup(pTriggerStep->pIdList), orconf);
482 break;
483 }
484 case TK_DELETE: {
485 sqliteVdbeAddOp(pParse->pVdbe, OP_PushList, 0, 0);
486 sqliteDeleteFrom(pParse, &pTriggerStep->target,
487 sqliteExprDup(pTriggerStep->pWhere));
488 sqliteVdbeAddOp(pParse->pVdbe, OP_PopList, 0, 0);
489 break;
490 }
491 default:
492 assert(0);
493 }
494 pParse->nTab = saveNTab;
495 pTriggerStep = pTriggerStep->pNext;
496 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000497
danielk1977633ed082002-05-17 00:05:58 +0000498 return 0;
danielk1977c3f9bad2002-05-15 08:30:12 +0000499}
500
danielk1977633ed082002-05-17 00:05:58 +0000501/*
502** This is called to code FOR EACH ROW triggers.
503**
504** When the code that this function generates is executed, the following
505** must be true:
drhc977f7f2002-05-21 11:38:11 +0000506**
507** 1. No cursors may be open in the main database. (But newIdx and oldIdx
508** can be indices of cursors in temporary tables. See below.)
509**
danielk1977633ed082002-05-17 00:05:58 +0000510** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then
511** a temporary vdbe cursor (index newIdx) must be open and pointing at
512** a row containing values to be substituted for new.* expressions in the
513** trigger program(s).
drhc977f7f2002-05-21 11:38:11 +0000514**
danielk1977633ed082002-05-17 00:05:58 +0000515** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then
516** a temporary vdbe cursor (index oldIdx) must be open and pointing at
517** a row containing values to be substituted for old.* expressions in the
518** trigger program(s).
519**
520*/
danielk1977c3f9bad2002-05-15 08:30:12 +0000521int sqliteCodeRowTrigger(
danielk1977633ed082002-05-17 00:05:58 +0000522 Parse *pParse, /* Parse context */
523 int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
524 ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
525 int tr_tm, /* One of TK_BEFORE, TK_AFTER */
526 Table *pTab, /* The table to code triggers from */
527 int newIdx, /* The indice of the "new" row to access */
528 int oldIdx, /* The indice of the "old" row to access */
drhc977f7f2002-05-21 11:38:11 +0000529 int orconf /* ON CONFLICT policy */
530){
danielk1977c3f9bad2002-05-15 08:30:12 +0000531 Trigger * pTrigger;
532 TriggerStack * pTriggerStack;
533
danielk1977c3f9bad2002-05-15 08:30:12 +0000534 assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
535 assert(tr_tm == TK_BEFORE || tr_tm == TK_AFTER);
536
danielk1977633ed082002-05-17 00:05:58 +0000537 assert(newIdx != -1 || oldIdx != -1);
danielk1977c3f9bad2002-05-15 08:30:12 +0000538
danielk1977633ed082002-05-17 00:05:58 +0000539 pTrigger = pTab->pTrigger;
danielk1977f29ce552002-05-19 23:43:12 +0000540 while( pTrigger ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000541 int fire_this = 0;
542
543 /* determine whether we should code this trigger */
danielk1977f29ce552002-05-19 23:43:12 +0000544 if( pTrigger->op == op && pTrigger->tr_tm == tr_tm &&
545 pTrigger->foreach == TK_ROW ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000546 fire_this = 1;
547 pTriggerStack = pParse->trigStack;
danielk1977f29ce552002-05-19 23:43:12 +0000548 while( pTriggerStack ){
549 if( pTriggerStack->pTrigger == pTrigger ){
550 fire_this = 0;
551 }
drh9adf9ac2002-05-15 11:44:13 +0000552 pTriggerStack = pTriggerStack->pNext;
danielk1977c3f9bad2002-05-15 08:30:12 +0000553 }
danielk1977f29ce552002-05-19 23:43:12 +0000554 if( op == TK_UPDATE && pTrigger->pColumns &&
555 !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
drh9adf9ac2002-05-15 11:44:13 +0000556 fire_this = 0;
danielk1977f29ce552002-05-19 23:43:12 +0000557 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000558 }
559
danielk1977f29ce552002-05-19 23:43:12 +0000560 if( fire_this ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000561 int endTrigger;
562 IdList dummyTablist;
563 Expr * whenExpr;
564
565 dummyTablist.nId = 0;
566 dummyTablist.a = 0;
567
568 /* Push an entry on to the trigger stack */
569 pTriggerStack = sqliteMalloc(sizeof(TriggerStack));
570 pTriggerStack->pTrigger = pTrigger;
danielk1977633ed082002-05-17 00:05:58 +0000571 pTriggerStack->newIdx = newIdx;
572 pTriggerStack->oldIdx = oldIdx;
573 pTriggerStack->pTab = pTab;
danielk1977c3f9bad2002-05-15 08:30:12 +0000574 pTriggerStack->pNext = pParse->trigStack;
575 pParse->trigStack = pTriggerStack;
576
577 /* code the WHEN clause */
578 endTrigger = sqliteVdbeMakeLabel(pParse->pVdbe);
579 whenExpr = sqliteExprDup(pTrigger->pWhen);
danielk1977f29ce552002-05-19 23:43:12 +0000580 if( sqliteExprResolveIds(pParse, 0, &dummyTablist, 0, whenExpr) ){
drh9adf9ac2002-05-15 11:44:13 +0000581 pParse->trigStack = pParse->trigStack->pNext;
582 sqliteFree(pTriggerStack);
583 sqliteExprDelete(whenExpr);
584 return 1;
danielk1977c3f9bad2002-05-15 08:30:12 +0000585 }
586 sqliteExprIfFalse(pParse, whenExpr, endTrigger);
587 sqliteExprDelete(whenExpr);
588
danielk1977633ed082002-05-17 00:05:58 +0000589 codeTriggerProgram(pParse, pTrigger->step_list, orconf);
danielk1977c3f9bad2002-05-15 08:30:12 +0000590
591 /* Pop the entry off the trigger stack */
592 pParse->trigStack = pParse->trigStack->pNext;
593 sqliteFree(pTriggerStack);
594
595 sqliteVdbeResolveLabel(pParse->pVdbe, endTrigger);
596 }
597 pTrigger = pTrigger->pNext;
598 }
599
600 return 0;
601}
602
603/*
danielk1977633ed082002-05-17 00:05:58 +0000604 * This function is called to code ON UPDATE and ON DELETE triggers on
605 * views.
606 *
607 * This function deletes the data pointed at by the pWhere and pChanges
608 * arguments before it completes.
danielk1977c3f9bad2002-05-15 08:30:12 +0000609 */
danielk1977633ed082002-05-17 00:05:58 +0000610void sqliteViewTriggers(
611 Parse *pParse,
612 Table *pTab, /* The view to code triggers on */
613 Expr *pWhere, /* The WHERE clause of the statement causing triggers*/
614 int orconf, /* The ON CONFLICT policy specified as part of the
615 statement causing these triggers */
616 ExprList *pChanges /* If this is an statement causing triggers to fire
617 is an UPDATE, then this list holds the columns
618 to update and the expressions to update them to.
619 See comments for sqliteUpdate(). */
620){
danielk1977c3f9bad2002-05-15 08:30:12 +0000621 int oldIdx = -1;
622 int newIdx = -1;
623 int *aXRef = 0;
624 Vdbe *v;
625 int endOfLoop;
626 int startOfLoop;
627 Select theSelect;
628 Token tblNameToken;
629
630 assert(pTab->pSelect);
631
632 tblNameToken.z = pTab->zName;
633 tblNameToken.n = strlen(pTab->zName);
634
635 theSelect.isDistinct = 0;
636 theSelect.pEList = sqliteExprListAppend(0, sqliteExpr(TK_ALL, 0, 0, 0), 0);
637 theSelect.pSrc = sqliteIdListAppend(0, &tblNameToken);
638 theSelect.pWhere = pWhere; pWhere = 0;
639 theSelect.pGroupBy = 0;
640 theSelect.pHaving = 0;
641 theSelect.pOrderBy = 0;
642 theSelect.op = TK_SELECT; /* ?? */
643 theSelect.pPrior = 0;
644 theSelect.nLimit = -1;
645 theSelect.nOffset = -1;
646 theSelect.zSelect = 0;
647 theSelect.base = 0;
648
649 v = sqliteGetVdbe(pParse);
650 assert(v);
drhc977f7f2002-05-21 11:38:11 +0000651 sqliteBeginWriteOperation(pParse, 1);
danielk1977c3f9bad2002-05-15 08:30:12 +0000652
653 /* Allocate temp tables */
654 oldIdx = pParse->nTab++;
655 sqliteVdbeAddOp(v, OP_OpenTemp, oldIdx, 0);
danielk1977633ed082002-05-17 00:05:58 +0000656 if( pChanges ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000657 newIdx = pParse->nTab++;
658 sqliteVdbeAddOp(v, OP_OpenTemp, newIdx, 0);
659 }
660
661 /* Snapshot the view */
danielk1977633ed082002-05-17 00:05:58 +0000662 if( sqliteSelect(pParse, &theSelect, SRT_Table, oldIdx, 0, 0, 0) ){
danielk1977c3f9bad2002-05-15 08:30:12 +0000663 goto trigger_cleanup;
664 }
665
666 /* loop thru the view snapshot, executing triggers for each row */
667 endOfLoop = sqliteVdbeMakeLabel(v);
668 sqliteVdbeAddOp(v, OP_Rewind, oldIdx, endOfLoop);
669
670 /* Loop thru the view snapshot, executing triggers for each row */
671 startOfLoop = sqliteVdbeCurrentAddr(v);
672
673 /* Build the updated row if required */
danielk1977633ed082002-05-17 00:05:58 +0000674 if( pChanges ){
drh1d1f3052002-05-21 13:18:25 +0000675 int ii;
danielk1977c3f9bad2002-05-15 08:30:12 +0000676
677 aXRef = sqliteMalloc( sizeof(int) * pTab->nCol );
678 if( aXRef==0 ) goto trigger_cleanup;
danielk1977633ed082002-05-17 00:05:58 +0000679 for(ii = 0; ii < pTab->nCol; ii++){
danielk1977c3f9bad2002-05-15 08:30:12 +0000680 aXRef[ii] = -1;
danielk1977633ed082002-05-17 00:05:58 +0000681 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000682
683 for(ii=0; ii<pChanges->nExpr; ii++){
684 int jj;
685 if( sqliteExprResolveIds(pParse, oldIdx, theSelect.pSrc , 0,
danielk1977f29ce552002-05-19 23:43:12 +0000686 pChanges->a[ii].pExpr) ){
drh9adf9ac2002-05-15 11:44:13 +0000687 goto trigger_cleanup;
danielk1977f29ce552002-05-19 23:43:12 +0000688 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000689
690 if( sqliteExprCheck(pParse, pChanges->a[ii].pExpr, 0, 0) )
drh9adf9ac2002-05-15 11:44:13 +0000691 goto trigger_cleanup;
danielk1977c3f9bad2002-05-15 08:30:12 +0000692
693 for(jj=0; jj<pTab->nCol; jj++){
drh9adf9ac2002-05-15 11:44:13 +0000694 if( sqliteStrICmp(pTab->aCol[jj].zName, pChanges->a[ii].zName)==0 ){
695 aXRef[jj] = ii;
696 break;
697 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000698 }
699 if( jj>=pTab->nCol ){
drh9adf9ac2002-05-15 11:44:13 +0000700 sqliteSetString(&pParse->zErrMsg, "no such column: ",
701 pChanges->a[ii].zName, 0);
702 pParse->nErr++;
703 goto trigger_cleanup;
danielk1977c3f9bad2002-05-15 08:30:12 +0000704 }
705 }
706
707 sqliteVdbeAddOp(v, OP_Integer, 13, 0);
708
danielk1977633ed082002-05-17 00:05:58 +0000709 for(ii = 0; ii<pTab->nCol; ii++){
710 if( aXRef[ii] < 0 ){
drh9adf9ac2002-05-15 11:44:13 +0000711 sqliteVdbeAddOp(v, OP_Column, oldIdx, ii);
danielk1977f29ce552002-05-19 23:43:12 +0000712 }else{
drh9adf9ac2002-05-15 11:44:13 +0000713 sqliteExprCode(pParse, pChanges->a[aXRef[ii]].pExpr);
danielk1977633ed082002-05-17 00:05:58 +0000714 }
715 }
danielk1977c3f9bad2002-05-15 08:30:12 +0000716
717 sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
718 sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
719 sqliteVdbeAddOp(v, OP_Rewind, newIdx, 0);
720
721 sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_BEFORE,
danielk1977633ed082002-05-17 00:05:58 +0000722 pTab, newIdx, oldIdx, orconf);
danielk1977c3f9bad2002-05-15 08:30:12 +0000723 sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_AFTER,
danielk1977633ed082002-05-17 00:05:58 +0000724 pTab, newIdx, oldIdx, orconf);
danielk1977f29ce552002-05-19 23:43:12 +0000725 }else{
danielk1977c3f9bad2002-05-15 08:30:12 +0000726 sqliteCodeRowTrigger(pParse, TK_DELETE, 0, TK_BEFORE, pTab, -1, oldIdx,
danielk1977633ed082002-05-17 00:05:58 +0000727 orconf);
danielk1977c3f9bad2002-05-15 08:30:12 +0000728 sqliteCodeRowTrigger(pParse, TK_DELETE, 0, TK_AFTER, pTab, -1, oldIdx,
danielk1977633ed082002-05-17 00:05:58 +0000729 orconf);
danielk1977c3f9bad2002-05-15 08:30:12 +0000730 }
731
732 sqliteVdbeAddOp(v, OP_Next, oldIdx, startOfLoop);
733
734 sqliteVdbeResolveLabel(v, endOfLoop);
735 sqliteEndWriteOperation(pParse);
736
737trigger_cleanup:
738 sqliteFree(aXRef);
739 sqliteExprListDelete(pChanges);
740 sqliteExprDelete(pWhere);
741 sqliteExprListDelete(theSelect.pEList);
742 sqliteIdListDelete(theSelect.pSrc);
743 sqliteExprDelete(theSelect.pWhere);
744 return;
745}