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 | ** This file contains the implementation for TRIGGERs |
12 | */ |
13 | #include "sqliteInt.h" |
14 | |
15 | #ifndef SQLITE_OMIT_TRIGGER |
16 | /* |
17 | ** Delete a linked list of TriggerStep structures. |
18 | */ |
19 | void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){ |
20 | while( pTriggerStep ){ |
21 | TriggerStep * pTmp = pTriggerStep; |
22 | pTriggerStep = pTriggerStep->pNext; |
23 | |
24 | sqlite3ExprDelete(db, pTmp->pWhere); |
25 | sqlite3ExprListDelete(db, pTmp->pExprList); |
26 | sqlite3SelectDelete(db, pTmp->pSelect); |
27 | sqlite3IdListDelete(db, pTmp->pIdList); |
28 | sqlite3UpsertDelete(db, pTmp->pUpsert); |
29 | sqlite3SrcListDelete(db, pTmp->pFrom); |
30 | sqlite3DbFree(db, pTmp->zSpan); |
31 | |
32 | sqlite3DbFree(db, pTmp); |
33 | } |
34 | } |
35 | |
36 | /* |
37 | ** Given table pTab, return a list of all the triggers attached to |
38 | ** the table. The list is connected by Trigger.pNext pointers. |
39 | ** |
40 | ** All of the triggers on pTab that are in the same database as pTab |
41 | ** are already attached to pTab->pTrigger. But there might be additional |
42 | ** triggers on pTab in the TEMP schema. This routine prepends all |
43 | ** TEMP triggers on pTab to the beginning of the pTab->pTrigger list |
44 | ** and returns the combined list. |
45 | ** |
46 | ** To state it another way: This routine returns a list of all triggers |
47 | ** that fire off of pTab. The list will include any TEMP triggers on |
48 | ** pTab as well as the triggers lised in pTab->pTrigger. |
49 | */ |
50 | Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ |
51 | Schema *pTmpSchema; /* Schema of the pTab table */ |
52 | Trigger *pList; /* List of triggers to return */ |
53 | HashElem *p; /* Loop variable for TEMP triggers */ |
54 | |
55 | assert( pParse->disableTriggers==0 ); |
56 | pTmpSchema = pParse->db->aDb[1].pSchema; |
57 | p = sqliteHashFirst(&pTmpSchema->trigHash); |
58 | pList = pTab->pTrigger; |
59 | while( p ){ |
60 | Trigger *pTrig = (Trigger *)sqliteHashData(p); |
61 | if( pTrig->pTabSchema==pTab->pSchema |
62 | && pTrig->table |
63 | && 0==sqlite3StrICmp(pTrig->table, pTab->zName) |
64 | && (pTrig->pTabSchema!=pTmpSchema || pTrig->bReturning) |
65 | ){ |
66 | pTrig->pNext = pList; |
67 | pList = pTrig; |
68 | }else if( pTrig->op==TK_RETURNING ){ |
69 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
70 | assert( pParse->db->pVtabCtx==0 ); |
71 | #endif |
72 | assert( pParse->bReturning ); |
73 | assert( &(pParse->u1.pReturning->retTrig) == pTrig ); |
74 | pTrig->table = pTab->zName; |
75 | pTrig->pTabSchema = pTab->pSchema; |
76 | pTrig->pNext = pList; |
77 | pList = pTrig; |
78 | } |
79 | p = sqliteHashNext(p); |
80 | } |
81 | #if 0 |
82 | if( pList ){ |
83 | Trigger *pX; |
84 | printf("Triggers for %s:" , pTab->zName); |
85 | for(pX=pList; pX; pX=pX->pNext){ |
86 | printf(" %s" , pX->zName); |
87 | } |
88 | printf("\n" ); |
89 | fflush(stdout); |
90 | } |
91 | #endif |
92 | return pList; |
93 | } |
94 | |
95 | /* |
96 | ** This is called by the parser when it sees a CREATE TRIGGER statement |
97 | ** up to the point of the BEGIN before the trigger actions. A Trigger |
98 | ** structure is generated based on the information available and stored |
99 | ** in pParse->pNewTrigger. After the trigger actions have been parsed, the |
100 | ** sqlite3FinishTrigger() function is called to complete the trigger |
101 | ** construction process. |
102 | */ |
103 | void sqlite3BeginTrigger( |
104 | Parse *pParse, /* The parse context of the CREATE TRIGGER statement */ |
105 | Token *pName1, /* The name of the trigger */ |
106 | Token *pName2, /* The name of the trigger */ |
107 | int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */ |
108 | int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */ |
109 | IdList *pColumns, /* column list if this is an UPDATE OF trigger */ |
110 | SrcList *pTableName,/* The name of the table/view the trigger applies to */ |
111 | Expr *pWhen, /* WHEN clause */ |
112 | int isTemp, /* True if the TEMPORARY keyword is present */ |
113 | int noErr /* Suppress errors if the trigger already exists */ |
114 | ){ |
115 | Trigger *pTrigger = 0; /* The new trigger */ |
116 | Table *pTab; /* Table that the trigger fires off of */ |
117 | char *zName = 0; /* Name of the trigger */ |
118 | sqlite3 *db = pParse->db; /* The database connection */ |
119 | int iDb; /* The database to store the trigger in */ |
120 | Token *pName; /* The unqualified db name */ |
121 | DbFixer sFix; /* State vector for the DB fixer */ |
122 | |
123 | assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */ |
124 | assert( pName2!=0 ); |
125 | assert( op==TK_INSERT || op==TK_UPDATE || op==TK_DELETE ); |
126 | assert( op>0 && op<0xff ); |
127 | if( isTemp ){ |
128 | /* If TEMP was specified, then the trigger name may not be qualified. */ |
129 | if( pName2->n>0 ){ |
130 | sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name" ); |
131 | goto trigger_cleanup; |
132 | } |
133 | iDb = 1; |
134 | pName = pName1; |
135 | }else{ |
136 | /* Figure out the db that the trigger will be created in */ |
137 | iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); |
138 | if( iDb<0 ){ |
139 | goto trigger_cleanup; |
140 | } |
141 | } |
142 | if( !pTableName || db->mallocFailed ){ |
143 | goto trigger_cleanup; |
144 | } |
145 | |
146 | /* A long-standing parser bug is that this syntax was allowed: |
147 | ** |
148 | ** CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab .... |
149 | ** ^^^^^^^^ |
150 | ** |
151 | ** To maintain backwards compatibility, ignore the database |
152 | ** name on pTableName if we are reparsing out of the schema table |
153 | */ |
154 | if( db->init.busy && iDb!=1 ){ |
155 | sqlite3DbFree(db, pTableName->a[0].zDatabase); |
156 | pTableName->a[0].zDatabase = 0; |
157 | } |
158 | |
159 | /* If the trigger name was unqualified, and the table is a temp table, |
160 | ** then set iDb to 1 to create the trigger in the temporary database. |
161 | ** If sqlite3SrcListLookup() returns 0, indicating the table does not |
162 | ** exist, the error is caught by the block below. |
163 | */ |
164 | pTab = sqlite3SrcListLookup(pParse, pTableName); |
165 | if( db->init.busy==0 && pName2->n==0 && pTab |
166 | && pTab->pSchema==db->aDb[1].pSchema ){ |
167 | iDb = 1; |
168 | } |
169 | |
170 | /* Ensure the table name matches database name and that the table exists */ |
171 | if( db->mallocFailed ) goto trigger_cleanup; |
172 | assert( pTableName->nSrc==1 ); |
173 | sqlite3FixInit(&sFix, pParse, iDb, "trigger" , pName); |
174 | if( sqlite3FixSrcList(&sFix, pTableName) ){ |
175 | goto trigger_cleanup; |
176 | } |
177 | pTab = sqlite3SrcListLookup(pParse, pTableName); |
178 | if( !pTab ){ |
179 | /* The table does not exist. */ |
180 | goto trigger_orphan_error; |
181 | } |
182 | if( IsVirtual(pTab) ){ |
183 | sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables" ); |
184 | goto trigger_orphan_error; |
185 | } |
186 | |
187 | /* Check that the trigger name is not reserved and that no trigger of the |
188 | ** specified name exists */ |
189 | zName = sqlite3NameFromToken(db, pName); |
190 | if( zName==0 ){ |
191 | assert( db->mallocFailed ); |
192 | goto trigger_cleanup; |
193 | } |
194 | if( sqlite3CheckObjectName(pParse, zName, "trigger" , pTab->zName) ){ |
195 | goto trigger_cleanup; |
196 | } |
197 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
198 | if( !IN_RENAME_OBJECT ){ |
199 | if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ |
200 | if( !noErr ){ |
201 | sqlite3ErrorMsg(pParse, "trigger %T already exists" , pName); |
202 | }else{ |
203 | assert( !db->init.busy ); |
204 | sqlite3CodeVerifySchema(pParse, iDb); |
205 | } |
206 | goto trigger_cleanup; |
207 | } |
208 | } |
209 | |
210 | /* Do not create a trigger on a system table */ |
211 | if( sqlite3StrNICmp(pTab->zName, "sqlite_" , 7)==0 ){ |
212 | sqlite3ErrorMsg(pParse, "cannot create trigger on system table" ); |
213 | goto trigger_cleanup; |
214 | } |
215 | |
216 | /* INSTEAD of triggers are only for views and views only support INSTEAD |
217 | ** of triggers. |
218 | */ |
219 | if( IsView(pTab) && tr_tm!=TK_INSTEAD ){ |
220 | sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S" , |
221 | (tr_tm == TK_BEFORE)?"BEFORE" :"AFTER" , pTableName->a); |
222 | goto trigger_orphan_error; |
223 | } |
224 | if( !IsView(pTab) && tr_tm==TK_INSTEAD ){ |
225 | sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF" |
226 | " trigger on table: %S" , pTableName->a); |
227 | goto trigger_orphan_error; |
228 | } |
229 | |
230 | #ifndef SQLITE_OMIT_AUTHORIZATION |
231 | if( !IN_RENAME_OBJECT ){ |
232 | int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
233 | int code = SQLITE_CREATE_TRIGGER; |
234 | const char *zDb = db->aDb[iTabDb].zDbSName; |
235 | const char *zDbTrig = isTemp ? db->aDb[1].zDbSName : zDb; |
236 | if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER; |
237 | if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){ |
238 | goto trigger_cleanup; |
239 | } |
240 | if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){ |
241 | goto trigger_cleanup; |
242 | } |
243 | } |
244 | #endif |
245 | |
246 | /* INSTEAD OF triggers can only appear on views and BEFORE triggers |
247 | ** cannot appear on views. So we might as well translate every |
248 | ** INSTEAD OF trigger into a BEFORE trigger. It simplifies code |
249 | ** elsewhere. |
250 | */ |
251 | if (tr_tm == TK_INSTEAD){ |
252 | tr_tm = TK_BEFORE; |
253 | } |
254 | |
255 | /* Build the Trigger object */ |
256 | pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger)); |
257 | if( pTrigger==0 ) goto trigger_cleanup; |
258 | pTrigger->zName = zName; |
259 | zName = 0; |
260 | pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName); |
261 | pTrigger->pSchema = db->aDb[iDb].pSchema; |
262 | pTrigger->pTabSchema = pTab->pSchema; |
263 | pTrigger->op = (u8)op; |
264 | pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; |
265 | if( IN_RENAME_OBJECT ){ |
266 | sqlite3RenameTokenRemap(pParse, pTrigger->table, pTableName->a[0].zName); |
267 | pTrigger->pWhen = pWhen; |
268 | pWhen = 0; |
269 | }else{ |
270 | pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); |
271 | } |
272 | pTrigger->pColumns = pColumns; |
273 | pColumns = 0; |
274 | assert( pParse->pNewTrigger==0 ); |
275 | pParse->pNewTrigger = pTrigger; |
276 | |
277 | trigger_cleanup: |
278 | sqlite3DbFree(db, zName); |
279 | sqlite3SrcListDelete(db, pTableName); |
280 | sqlite3IdListDelete(db, pColumns); |
281 | sqlite3ExprDelete(db, pWhen); |
282 | if( !pParse->pNewTrigger ){ |
283 | sqlite3DeleteTrigger(db, pTrigger); |
284 | }else{ |
285 | assert( pParse->pNewTrigger==pTrigger ); |
286 | } |
287 | return; |
288 | |
289 | trigger_orphan_error: |
290 | if( db->init.iDb==1 ){ |
291 | /* Ticket #3810. |
292 | ** Normally, whenever a table is dropped, all associated triggers are |
293 | ** dropped too. But if a TEMP trigger is created on a non-TEMP table |
294 | ** and the table is dropped by a different database connection, the |
295 | ** trigger is not visible to the database connection that does the |
296 | ** drop so the trigger cannot be dropped. This results in an |
297 | ** "orphaned trigger" - a trigger whose associated table is missing. |
298 | ** |
299 | ** 2020-11-05 see also https://sqlite.org/forum/forumpost/157dc791df |
300 | */ |
301 | db->init.orphanTrigger = 1; |
302 | } |
303 | goto trigger_cleanup; |
304 | } |
305 | |
306 | /* |
307 | ** This routine is called after all of the trigger actions have been parsed |
308 | ** in order to complete the process of building the trigger. |
309 | */ |
310 | void sqlite3FinishTrigger( |
311 | Parse *pParse, /* Parser context */ |
312 | TriggerStep *pStepList, /* The triggered program */ |
313 | Token *pAll /* Token that describes the complete CREATE TRIGGER */ |
314 | ){ |
315 | Trigger *pTrig = pParse->pNewTrigger; /* Trigger being finished */ |
316 | char *zName; /* Name of trigger */ |
317 | sqlite3 *db = pParse->db; /* The database */ |
318 | DbFixer sFix; /* Fixer object */ |
319 | int iDb; /* Database containing the trigger */ |
320 | Token nameToken; /* Trigger name for error reporting */ |
321 | |
322 | pParse->pNewTrigger = 0; |
323 | if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup; |
324 | zName = pTrig->zName; |
325 | iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); |
326 | pTrig->step_list = pStepList; |
327 | while( pStepList ){ |
328 | pStepList->pTrig = pTrig; |
329 | pStepList = pStepList->pNext; |
330 | } |
331 | sqlite3TokenInit(&nameToken, pTrig->zName); |
332 | sqlite3FixInit(&sFix, pParse, iDb, "trigger" , &nameToken); |
333 | if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) |
334 | || sqlite3FixExpr(&sFix, pTrig->pWhen) |
335 | ){ |
336 | goto triggerfinish_cleanup; |
337 | } |
338 | |
339 | #ifndef SQLITE_OMIT_ALTERTABLE |
340 | if( IN_RENAME_OBJECT ){ |
341 | assert( !db->init.busy ); |
342 | pParse->pNewTrigger = pTrig; |
343 | pTrig = 0; |
344 | }else |
345 | #endif |
346 | |
347 | /* if we are not initializing, |
348 | ** build the sqlite_schema entry |
349 | */ |
350 | if( !db->init.busy ){ |
351 | Vdbe *v; |
352 | char *z; |
353 | |
354 | /* If this is a new CREATE TABLE statement, and if shadow tables |
355 | ** are read-only, and the trigger makes a change to a shadow table, |
356 | ** then raise an error - do not allow the trigger to be created. */ |
357 | if( sqlite3ReadOnlyShadowTables(db) ){ |
358 | TriggerStep *pStep; |
359 | for(pStep=pTrig->step_list; pStep; pStep=pStep->pNext){ |
360 | if( pStep->zTarget!=0 |
361 | && sqlite3ShadowTableName(db, pStep->zTarget) |
362 | ){ |
363 | sqlite3ErrorMsg(pParse, |
364 | "trigger \"%s\" may not write to shadow table \"%s\"" , |
365 | pTrig->zName, pStep->zTarget); |
366 | goto triggerfinish_cleanup; |
367 | } |
368 | } |
369 | } |
370 | |
371 | /* Make an entry in the sqlite_schema table */ |
372 | v = sqlite3GetVdbe(pParse); |
373 | if( v==0 ) goto triggerfinish_cleanup; |
374 | sqlite3BeginWriteOperation(pParse, 0, iDb); |
375 | z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); |
376 | testcase( z==0 ); |
377 | sqlite3NestedParse(pParse, |
378 | "INSERT INTO %Q." LEGACY_SCHEMA_TABLE |
379 | " VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')" , |
380 | db->aDb[iDb].zDbSName, zName, |
381 | pTrig->table, z); |
382 | sqlite3DbFree(db, z); |
383 | sqlite3ChangeCookie(pParse, iDb); |
384 | sqlite3VdbeAddParseSchemaOp(v, iDb, |
385 | sqlite3MPrintf(db, "type='trigger' AND name='%q'" , zName), 0); |
386 | } |
387 | |
388 | if( db->init.busy ){ |
389 | Trigger *pLink = pTrig; |
390 | Hash *pHash = &db->aDb[iDb].pSchema->trigHash; |
391 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
392 | assert( pLink!=0 ); |
393 | pTrig = sqlite3HashInsert(pHash, zName, pTrig); |
394 | if( pTrig ){ |
395 | sqlite3OomFault(db); |
396 | }else if( pLink->pSchema==pLink->pTabSchema ){ |
397 | Table *pTab; |
398 | pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table); |
399 | assert( pTab!=0 ); |
400 | pLink->pNext = pTab->pTrigger; |
401 | pTab->pTrigger = pLink; |
402 | } |
403 | } |
404 | |
405 | triggerfinish_cleanup: |
406 | sqlite3DeleteTrigger(db, pTrig); |
407 | assert( IN_RENAME_OBJECT || !pParse->pNewTrigger ); |
408 | sqlite3DeleteTriggerStep(db, pStepList); |
409 | } |
410 | |
411 | /* |
412 | ** Duplicate a range of text from an SQL statement, then convert all |
413 | ** whitespace characters into ordinary space characters. |
414 | */ |
415 | static char *triggerSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ |
416 | char *z = sqlite3DbSpanDup(db, zStart, zEnd); |
417 | int i; |
418 | if( z ) for(i=0; z[i]; i++) if( sqlite3Isspace(z[i]) ) z[i] = ' '; |
419 | return z; |
420 | } |
421 | |
422 | /* |
423 | ** Turn a SELECT statement (that the pSelect parameter points to) into |
424 | ** a trigger step. Return a pointer to a TriggerStep structure. |
425 | ** |
426 | ** The parser calls this routine when it finds a SELECT statement in |
427 | ** body of a TRIGGER. |
428 | */ |
429 | TriggerStep *sqlite3TriggerSelectStep( |
430 | sqlite3 *db, /* Database connection */ |
431 | Select *pSelect, /* The SELECT statement */ |
432 | const char *zStart, /* Start of SQL text */ |
433 | const char *zEnd /* End of SQL text */ |
434 | ){ |
435 | TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); |
436 | if( pTriggerStep==0 ) { |
437 | sqlite3SelectDelete(db, pSelect); |
438 | return 0; |
439 | } |
440 | pTriggerStep->op = TK_SELECT; |
441 | pTriggerStep->pSelect = pSelect; |
442 | pTriggerStep->orconf = OE_Default; |
443 | pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); |
444 | return pTriggerStep; |
445 | } |
446 | |
447 | /* |
448 | ** Allocate space to hold a new trigger step. The allocated space |
449 | ** holds both the TriggerStep object and the TriggerStep.target.z string. |
450 | ** |
451 | ** If an OOM error occurs, NULL is returned and db->mallocFailed is set. |
452 | */ |
453 | static TriggerStep *triggerStepAllocate( |
454 | Parse *pParse, /* Parser context */ |
455 | u8 op, /* Trigger opcode */ |
456 | Token *pName, /* The target name */ |
457 | const char *zStart, /* Start of SQL text */ |
458 | const char *zEnd /* End of SQL text */ |
459 | ){ |
460 | sqlite3 *db = pParse->db; |
461 | TriggerStep *pTriggerStep; |
462 | |
463 | if( pParse->nErr ) return 0; |
464 | pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); |
465 | if( pTriggerStep ){ |
466 | char *z = (char*)&pTriggerStep[1]; |
467 | memcpy(z, pName->z, pName->n); |
468 | sqlite3Dequote(z); |
469 | pTriggerStep->zTarget = z; |
470 | pTriggerStep->op = op; |
471 | pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); |
472 | if( IN_RENAME_OBJECT ){ |
473 | sqlite3RenameTokenMap(pParse, pTriggerStep->zTarget, pName); |
474 | } |
475 | } |
476 | return pTriggerStep; |
477 | } |
478 | |
479 | /* |
480 | ** Build a trigger step out of an INSERT statement. Return a pointer |
481 | ** to the new trigger step. |
482 | ** |
483 | ** The parser calls this routine when it sees an INSERT inside the |
484 | ** body of a trigger. |
485 | */ |
486 | TriggerStep *sqlite3TriggerInsertStep( |
487 | Parse *pParse, /* Parser */ |
488 | Token *pTableName, /* Name of the table into which we insert */ |
489 | IdList *pColumn, /* List of columns in pTableName to insert into */ |
490 | Select *pSelect, /* A SELECT statement that supplies values */ |
491 | u8 orconf, /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ |
492 | Upsert *pUpsert, /* ON CONFLICT clauses for upsert */ |
493 | const char *zStart, /* Start of SQL text */ |
494 | const char *zEnd /* End of SQL text */ |
495 | ){ |
496 | sqlite3 *db = pParse->db; |
497 | TriggerStep *pTriggerStep; |
498 | |
499 | assert(pSelect != 0 || db->mallocFailed); |
500 | |
501 | pTriggerStep = triggerStepAllocate(pParse, TK_INSERT, pTableName,zStart,zEnd); |
502 | if( pTriggerStep ){ |
503 | if( IN_RENAME_OBJECT ){ |
504 | pTriggerStep->pSelect = pSelect; |
505 | pSelect = 0; |
506 | }else{ |
507 | pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); |
508 | } |
509 | pTriggerStep->pIdList = pColumn; |
510 | pTriggerStep->pUpsert = pUpsert; |
511 | pTriggerStep->orconf = orconf; |
512 | if( pUpsert ){ |
513 | sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget); |
514 | } |
515 | }else{ |
516 | testcase( pColumn ); |
517 | sqlite3IdListDelete(db, pColumn); |
518 | testcase( pUpsert ); |
519 | sqlite3UpsertDelete(db, pUpsert); |
520 | } |
521 | sqlite3SelectDelete(db, pSelect); |
522 | |
523 | return pTriggerStep; |
524 | } |
525 | |
526 | /* |
527 | ** Construct a trigger step that implements an UPDATE statement and return |
528 | ** a pointer to that trigger step. The parser calls this routine when it |
529 | ** sees an UPDATE statement inside the body of a CREATE TRIGGER. |
530 | */ |
531 | TriggerStep *sqlite3TriggerUpdateStep( |
532 | Parse *pParse, /* Parser */ |
533 | Token *pTableName, /* Name of the table to be updated */ |
534 | SrcList *pFrom, /* FROM clause for an UPDATE-FROM, or NULL */ |
535 | ExprList *pEList, /* The SET clause: list of column and new values */ |
536 | Expr *pWhere, /* The WHERE clause */ |
537 | u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */ |
538 | const char *zStart, /* Start of SQL text */ |
539 | const char *zEnd /* End of SQL text */ |
540 | ){ |
541 | sqlite3 *db = pParse->db; |
542 | TriggerStep *pTriggerStep; |
543 | |
544 | pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTableName,zStart,zEnd); |
545 | if( pTriggerStep ){ |
546 | if( IN_RENAME_OBJECT ){ |
547 | pTriggerStep->pExprList = pEList; |
548 | pTriggerStep->pWhere = pWhere; |
549 | pTriggerStep->pFrom = pFrom; |
550 | pEList = 0; |
551 | pWhere = 0; |
552 | pFrom = 0; |
553 | }else{ |
554 | pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); |
555 | pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); |
556 | pTriggerStep->pFrom = sqlite3SrcListDup(db, pFrom, EXPRDUP_REDUCE); |
557 | } |
558 | pTriggerStep->orconf = orconf; |
559 | } |
560 | sqlite3ExprListDelete(db, pEList); |
561 | sqlite3ExprDelete(db, pWhere); |
562 | sqlite3SrcListDelete(db, pFrom); |
563 | return pTriggerStep; |
564 | } |
565 | |
566 | /* |
567 | ** Construct a trigger step that implements a DELETE statement and return |
568 | ** a pointer to that trigger step. The parser calls this routine when it |
569 | ** sees a DELETE statement inside the body of a CREATE TRIGGER. |
570 | */ |
571 | TriggerStep *sqlite3TriggerDeleteStep( |
572 | Parse *pParse, /* Parser */ |
573 | Token *pTableName, /* The table from which rows are deleted */ |
574 | Expr *pWhere, /* The WHERE clause */ |
575 | const char *zStart, /* Start of SQL text */ |
576 | const char *zEnd /* End of SQL text */ |
577 | ){ |
578 | sqlite3 *db = pParse->db; |
579 | TriggerStep *pTriggerStep; |
580 | |
581 | pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTableName,zStart,zEnd); |
582 | if( pTriggerStep ){ |
583 | if( IN_RENAME_OBJECT ){ |
584 | pTriggerStep->pWhere = pWhere; |
585 | pWhere = 0; |
586 | }else{ |
587 | pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); |
588 | } |
589 | pTriggerStep->orconf = OE_Default; |
590 | } |
591 | sqlite3ExprDelete(db, pWhere); |
592 | return pTriggerStep; |
593 | } |
594 | |
595 | /* |
596 | ** Recursively delete a Trigger structure |
597 | */ |
598 | void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ |
599 | if( pTrigger==0 || pTrigger->bReturning ) return; |
600 | sqlite3DeleteTriggerStep(db, pTrigger->step_list); |
601 | sqlite3DbFree(db, pTrigger->zName); |
602 | sqlite3DbFree(db, pTrigger->table); |
603 | sqlite3ExprDelete(db, pTrigger->pWhen); |
604 | sqlite3IdListDelete(db, pTrigger->pColumns); |
605 | sqlite3DbFree(db, pTrigger); |
606 | } |
607 | |
608 | /* |
609 | ** This function is called to drop a trigger from the database schema. |
610 | ** |
611 | ** This may be called directly from the parser and therefore identifies |
612 | ** the trigger by name. The sqlite3DropTriggerPtr() routine does the |
613 | ** same job as this routine except it takes a pointer to the trigger |
614 | ** instead of the trigger name. |
615 | **/ |
616 | void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ |
617 | Trigger *pTrigger = 0; |
618 | int i; |
619 | const char *zDb; |
620 | const char *zName; |
621 | sqlite3 *db = pParse->db; |
622 | |
623 | if( db->mallocFailed ) goto drop_trigger_cleanup; |
624 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ |
625 | goto drop_trigger_cleanup; |
626 | } |
627 | |
628 | assert( pName->nSrc==1 ); |
629 | zDb = pName->a[0].zDatabase; |
630 | zName = pName->a[0].zName; |
631 | assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); |
632 | for(i=OMIT_TEMPDB; i<db->nDb; i++){ |
633 | int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ |
634 | if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue; |
635 | assert( sqlite3SchemaMutexHeld(db, j, 0) ); |
636 | pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName); |
637 | if( pTrigger ) break; |
638 | } |
639 | if( !pTrigger ){ |
640 | if( !noErr ){ |
641 | sqlite3ErrorMsg(pParse, "no such trigger: %S" , pName->a); |
642 | }else{ |
643 | sqlite3CodeVerifyNamedSchema(pParse, zDb); |
644 | } |
645 | pParse->checkSchema = 1; |
646 | goto drop_trigger_cleanup; |
647 | } |
648 | sqlite3DropTriggerPtr(pParse, pTrigger); |
649 | |
650 | drop_trigger_cleanup: |
651 | sqlite3SrcListDelete(db, pName); |
652 | } |
653 | |
654 | /* |
655 | ** Return a pointer to the Table structure for the table that a trigger |
656 | ** is set on. |
657 | */ |
658 | static Table *tableOfTrigger(Trigger *pTrigger){ |
659 | return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table); |
660 | } |
661 | |
662 | |
663 | /* |
664 | ** Drop a trigger given a pointer to that trigger. |
665 | */ |
666 | void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ |
667 | Table *pTable; |
668 | Vdbe *v; |
669 | sqlite3 *db = pParse->db; |
670 | int iDb; |
671 | |
672 | iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema); |
673 | assert( iDb>=0 && iDb<db->nDb ); |
674 | pTable = tableOfTrigger(pTrigger); |
675 | assert( (pTable && pTable->pSchema==pTrigger->pSchema) || iDb==1 ); |
676 | #ifndef SQLITE_OMIT_AUTHORIZATION |
677 | if( pTable ){ |
678 | int code = SQLITE_DROP_TRIGGER; |
679 | const char *zDb = db->aDb[iDb].zDbSName; |
680 | const char *zTab = SCHEMA_TABLE(iDb); |
681 | if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER; |
682 | if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) || |
683 | sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ |
684 | return; |
685 | } |
686 | } |
687 | #endif |
688 | |
689 | /* Generate code to destroy the database record of the trigger. |
690 | */ |
691 | if( (v = sqlite3GetVdbe(pParse))!=0 ){ |
692 | sqlite3NestedParse(pParse, |
693 | "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'" , |
694 | db->aDb[iDb].zDbSName, pTrigger->zName |
695 | ); |
696 | sqlite3ChangeCookie(pParse, iDb); |
697 | sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); |
698 | } |
699 | } |
700 | |
701 | /* |
702 | ** Remove a trigger from the hash tables of the sqlite* pointer. |
703 | */ |
704 | void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){ |
705 | Trigger *pTrigger; |
706 | Hash *pHash; |
707 | |
708 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
709 | pHash = &(db->aDb[iDb].pSchema->trigHash); |
710 | pTrigger = sqlite3HashInsert(pHash, zName, 0); |
711 | if( ALWAYS(pTrigger) ){ |
712 | if( pTrigger->pSchema==pTrigger->pTabSchema ){ |
713 | Table *pTab = tableOfTrigger(pTrigger); |
714 | if( pTab ){ |
715 | Trigger **pp; |
716 | for(pp=&pTab->pTrigger; *pp; pp=&((*pp)->pNext)){ |
717 | if( *pp==pTrigger ){ |
718 | *pp = (*pp)->pNext; |
719 | break; |
720 | } |
721 | } |
722 | } |
723 | } |
724 | sqlite3DeleteTrigger(db, pTrigger); |
725 | db->mDbFlags |= DBFLAG_SchemaChange; |
726 | } |
727 | } |
728 | |
729 | /* |
730 | ** pEList is the SET clause of an UPDATE statement. Each entry |
731 | ** in pEList is of the format <id>=<expr>. If any of the entries |
732 | ** in pEList have an <id> which matches an identifier in pIdList, |
733 | ** then return TRUE. If pIdList==NULL, then it is considered a |
734 | ** wildcard that matches anything. Likewise if pEList==NULL then |
735 | ** it matches anything so always return true. Return false only |
736 | ** if there is no match. |
737 | */ |
738 | static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){ |
739 | int e; |
740 | if( pIdList==0 || NEVER(pEList==0) ) return 1; |
741 | for(e=0; e<pEList->nExpr; e++){ |
742 | if( sqlite3IdListIndex(pIdList, pEList->a[e].zEName)>=0 ) return 1; |
743 | } |
744 | return 0; |
745 | } |
746 | |
747 | /* |
748 | ** Return true if any TEMP triggers exist |
749 | */ |
750 | static int tempTriggersExist(sqlite3 *db){ |
751 | if( NEVER(db->aDb[1].pSchema==0) ) return 0; |
752 | if( sqliteHashFirst(&db->aDb[1].pSchema->trigHash)==0 ) return 0; |
753 | return 1; |
754 | } |
755 | |
756 | /* |
757 | ** Return a list of all triggers on table pTab if there exists at least |
758 | ** one trigger that must be fired when an operation of type 'op' is |
759 | ** performed on the table, and, if that operation is an UPDATE, if at |
760 | ** least one of the columns in pChanges is being modified. |
761 | */ |
762 | static SQLITE_NOINLINE Trigger *triggersReallyExist( |
763 | Parse *pParse, /* Parse context */ |
764 | Table *pTab, /* The table the contains the triggers */ |
765 | int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ |
766 | ExprList *pChanges, /* Columns that change in an UPDATE statement */ |
767 | int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ |
768 | ){ |
769 | int mask = 0; |
770 | Trigger *pList = 0; |
771 | Trigger *p; |
772 | |
773 | pList = sqlite3TriggerList(pParse, pTab); |
774 | assert( pList==0 || IsVirtual(pTab)==0 |
775 | || (pList->bReturning && pList->pNext==0) ); |
776 | if( pList!=0 ){ |
777 | p = pList; |
778 | if( (pParse->db->flags & SQLITE_EnableTrigger)==0 |
779 | && pTab->pTrigger!=0 |
780 | ){ |
781 | /* The SQLITE_DBCONFIG_ENABLE_TRIGGER setting is off. That means that |
782 | ** only TEMP triggers are allowed. Truncate the pList so that it |
783 | ** includes only TEMP triggers */ |
784 | if( pList==pTab->pTrigger ){ |
785 | pList = 0; |
786 | goto exit_triggers_exist; |
787 | } |
788 | while( ALWAYS(p->pNext) && p->pNext!=pTab->pTrigger ) p = p->pNext; |
789 | p->pNext = 0; |
790 | p = pList; |
791 | } |
792 | do{ |
793 | if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ |
794 | mask |= p->tr_tm; |
795 | }else if( p->op==TK_RETURNING ){ |
796 | /* The first time a RETURNING trigger is seen, the "op" value tells |
797 | ** us what time of trigger it should be. */ |
798 | assert( sqlite3IsToplevel(pParse) ); |
799 | p->op = op; |
800 | if( IsVirtual(pTab) ){ |
801 | if( op!=TK_INSERT ){ |
802 | sqlite3ErrorMsg(pParse, |
803 | "%s RETURNING is not available on virtual tables" , |
804 | op==TK_DELETE ? "DELETE" : "UPDATE" ); |
805 | } |
806 | p->tr_tm = TRIGGER_BEFORE; |
807 | }else{ |
808 | p->tr_tm = TRIGGER_AFTER; |
809 | } |
810 | mask |= p->tr_tm; |
811 | }else if( p->bReturning && p->op==TK_INSERT && op==TK_UPDATE |
812 | && sqlite3IsToplevel(pParse) ){ |
813 | /* Also fire a RETURNING trigger for an UPSERT */ |
814 | mask |= p->tr_tm; |
815 | } |
816 | p = p->pNext; |
817 | }while( p ); |
818 | } |
819 | exit_triggers_exist: |
820 | if( pMask ){ |
821 | *pMask = mask; |
822 | } |
823 | return (mask ? pList : 0); |
824 | } |
825 | Trigger *sqlite3TriggersExist( |
826 | Parse *pParse, /* Parse context */ |
827 | Table *pTab, /* The table the contains the triggers */ |
828 | int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ |
829 | ExprList *pChanges, /* Columns that change in an UPDATE statement */ |
830 | int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ |
831 | ){ |
832 | assert( pTab!=0 ); |
833 | if( (pTab->pTrigger==0 && !tempTriggersExist(pParse->db)) |
834 | || pParse->disableTriggers |
835 | ){ |
836 | if( pMask ) *pMask = 0; |
837 | return 0; |
838 | } |
839 | return triggersReallyExist(pParse,pTab,op,pChanges,pMask); |
840 | } |
841 | |
842 | /* |
843 | ** Convert the pStep->zTarget string into a SrcList and return a pointer |
844 | ** to that SrcList. |
845 | ** |
846 | ** This routine adds a specific database name, if needed, to the target when |
847 | ** forming the SrcList. This prevents a trigger in one database from |
848 | ** referring to a target in another database. An exception is when the |
849 | ** trigger is in TEMP in which case it can refer to any other database it |
850 | ** wants. |
851 | */ |
852 | SrcList *sqlite3TriggerStepSrc( |
853 | Parse *pParse, /* The parsing context */ |
854 | TriggerStep *pStep /* The trigger containing the target token */ |
855 | ){ |
856 | sqlite3 *db = pParse->db; |
857 | SrcList *pSrc; /* SrcList to be returned */ |
858 | char *zName = sqlite3DbStrDup(db, pStep->zTarget); |
859 | pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); |
860 | assert( pSrc==0 || pSrc->nSrc==1 ); |
861 | assert( zName || pSrc==0 ); |
862 | if( pSrc ){ |
863 | Schema *pSchema = pStep->pTrig->pSchema; |
864 | pSrc->a[0].zName = zName; |
865 | if( pSchema!=db->aDb[1].pSchema ){ |
866 | pSrc->a[0].pSchema = pSchema; |
867 | } |
868 | if( pStep->pFrom ){ |
869 | SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0); |
870 | if( pDup && pDup->nSrc>1 && !IN_RENAME_OBJECT ){ |
871 | Select *pSubquery; |
872 | Token as; |
873 | pSubquery = sqlite3SelectNew(pParse,0,pDup,0,0,0,0,SF_NestedFrom,0); |
874 | as.n = 0; |
875 | as.z = 0; |
876 | pDup = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0); |
877 | } |
878 | pSrc = sqlite3SrcListAppendList(pParse, pSrc, pDup); |
879 | } |
880 | }else{ |
881 | sqlite3DbFree(db, zName); |
882 | } |
883 | return pSrc; |
884 | } |
885 | |
886 | /* |
887 | ** Return true if the pExpr term from the RETURNING clause argument |
888 | ** list is of the form "*". Raise an error if the terms if of the |
889 | ** form "table.*". |
890 | */ |
891 | static int isAsteriskTerm( |
892 | Parse *pParse, /* Parsing context */ |
893 | Expr *pTerm /* A term in the RETURNING clause */ |
894 | ){ |
895 | assert( pTerm!=0 ); |
896 | if( pTerm->op==TK_ASTERISK ) return 1; |
897 | if( pTerm->op!=TK_DOT ) return 0; |
898 | assert( pTerm->pRight!=0 ); |
899 | assert( pTerm->pLeft!=0 ); |
900 | if( pTerm->pRight->op!=TK_ASTERISK ) return 0; |
901 | sqlite3ErrorMsg(pParse, "RETURNING may not use \"TABLE.*\" wildcards" ); |
902 | return 1; |
903 | } |
904 | |
905 | /* The input list pList is the list of result set terms from a RETURNING |
906 | ** clause. The table that we are returning from is pTab. |
907 | ** |
908 | ** This routine makes a copy of the pList, and at the same time expands |
909 | ** any "*" wildcards to be the complete set of columns from pTab. |
910 | */ |
911 | static ExprList *sqlite3ExpandReturning( |
912 | Parse *pParse, /* Parsing context */ |
913 | ExprList *pList, /* The arguments to RETURNING */ |
914 | Table *pTab /* The table being updated */ |
915 | ){ |
916 | ExprList *pNew = 0; |
917 | sqlite3 *db = pParse->db; |
918 | int i; |
919 | |
920 | for(i=0; i<pList->nExpr; i++){ |
921 | Expr *pOldExpr = pList->a[i].pExpr; |
922 | if( NEVER(pOldExpr==0) ) continue; |
923 | if( isAsteriskTerm(pParse, pOldExpr) ){ |
924 | int jj; |
925 | for(jj=0; jj<pTab->nCol; jj++){ |
926 | Expr *pNewExpr; |
927 | if( IsHiddenColumn(pTab->aCol+jj) ) continue; |
928 | pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zCnName); |
929 | pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); |
930 | if( !db->mallocFailed ){ |
931 | struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; |
932 | pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zCnName); |
933 | pItem->fg.eEName = ENAME_NAME; |
934 | } |
935 | } |
936 | }else{ |
937 | Expr *pNewExpr = sqlite3ExprDup(db, pOldExpr, 0); |
938 | pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); |
939 | if( !db->mallocFailed && ALWAYS(pList->a[i].zEName!=0) ){ |
940 | struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; |
941 | pItem->zEName = sqlite3DbStrDup(db, pList->a[i].zEName); |
942 | pItem->fg.eEName = pList->a[i].fg.eEName; |
943 | } |
944 | } |
945 | } |
946 | return pNew; |
947 | } |
948 | |
949 | /* |
950 | ** Generate code for the RETURNING trigger. Unlike other triggers |
951 | ** that invoke a subprogram in the bytecode, the code for RETURNING |
952 | ** is generated in-line. |
953 | */ |
954 | static void codeReturningTrigger( |
955 | Parse *pParse, /* Parse context */ |
956 | Trigger *pTrigger, /* The trigger step that defines the RETURNING */ |
957 | Table *pTab, /* The table to code triggers from */ |
958 | int regIn /* The first in an array of registers */ |
959 | ){ |
960 | Vdbe *v = pParse->pVdbe; |
961 | sqlite3 *db = pParse->db; |
962 | ExprList *pNew; |
963 | Returning *pReturning; |
964 | Select sSelect; |
965 | SrcList sFrom; |
966 | |
967 | assert( v!=0 ); |
968 | assert( pParse->bReturning ); |
969 | assert( db->pParse==pParse ); |
970 | pReturning = pParse->u1.pReturning; |
971 | assert( pTrigger == &(pReturning->retTrig) ); |
972 | memset(&sSelect, 0, sizeof(sSelect)); |
973 | memset(&sFrom, 0, sizeof(sFrom)); |
974 | sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); |
975 | sSelect.pSrc = &sFrom; |
976 | sFrom.nSrc = 1; |
977 | sFrom.a[0].pTab = pTab; |
978 | sFrom.a[0].iCursor = -1; |
979 | sqlite3SelectPrep(pParse, &sSelect, 0); |
980 | if( pParse->nErr==0 ){ |
981 | assert( db->mallocFailed==0 ); |
982 | sqlite3GenerateColumnNames(pParse, &sSelect); |
983 | } |
984 | sqlite3ExprListDelete(db, sSelect.pEList); |
985 | pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); |
986 | if( !db->mallocFailed ){ |
987 | NameContext sNC; |
988 | memset(&sNC, 0, sizeof(sNC)); |
989 | if( pReturning->nRetCol==0 ){ |
990 | pReturning->nRetCol = pNew->nExpr; |
991 | pReturning->iRetCur = pParse->nTab++; |
992 | } |
993 | sNC.pParse = pParse; |
994 | sNC.uNC.iBaseReg = regIn; |
995 | sNC.ncFlags = NC_UBaseReg; |
996 | pParse->eTriggerOp = pTrigger->op; |
997 | pParse->pTriggerTab = pTab; |
998 | if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK |
999 | && ALWAYS(!db->mallocFailed) |
1000 | ){ |
1001 | int i; |
1002 | int nCol = pNew->nExpr; |
1003 | int reg = pParse->nMem+1; |
1004 | pParse->nMem += nCol+2; |
1005 | pReturning->iRetReg = reg; |
1006 | for(i=0; i<nCol; i++){ |
1007 | Expr *pCol = pNew->a[i].pExpr; |
1008 | assert( pCol!=0 ); /* Due to !db->mallocFailed ~9 lines above */ |
1009 | sqlite3ExprCodeFactorable(pParse, pCol, reg+i); |
1010 | if( sqlite3ExprAffinity(pCol)==SQLITE_AFF_REAL ){ |
1011 | sqlite3VdbeAddOp1(v, OP_RealAffinity, reg+i); |
1012 | } |
1013 | } |
1014 | sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, i, reg+i); |
1015 | sqlite3VdbeAddOp2(v, OP_NewRowid, pReturning->iRetCur, reg+i+1); |
1016 | sqlite3VdbeAddOp3(v, OP_Insert, pReturning->iRetCur, reg+i, reg+i+1); |
1017 | } |
1018 | } |
1019 | sqlite3ExprListDelete(db, pNew); |
1020 | pParse->eTriggerOp = 0; |
1021 | pParse->pTriggerTab = 0; |
1022 | } |
1023 | |
1024 | |
1025 | |
1026 | /* |
1027 | ** Generate VDBE code for the statements inside the body of a single |
1028 | ** trigger. |
1029 | */ |
1030 | static int codeTriggerProgram( |
1031 | Parse *pParse, /* The parser context */ |
1032 | TriggerStep *pStepList, /* List of statements inside the trigger body */ |
1033 | int orconf /* Conflict algorithm. (OE_Abort, etc) */ |
1034 | ){ |
1035 | TriggerStep *pStep; |
1036 | Vdbe *v = pParse->pVdbe; |
1037 | sqlite3 *db = pParse->db; |
1038 | |
1039 | assert( pParse->pTriggerTab && pParse->pToplevel ); |
1040 | assert( pStepList ); |
1041 | assert( v!=0 ); |
1042 | for(pStep=pStepList; pStep; pStep=pStep->pNext){ |
1043 | /* Figure out the ON CONFLICT policy that will be used for this step |
1044 | ** of the trigger program. If the statement that caused this trigger |
1045 | ** to fire had an explicit ON CONFLICT, then use it. Otherwise, use |
1046 | ** the ON CONFLICT policy that was specified as part of the trigger |
1047 | ** step statement. Example: |
1048 | ** |
1049 | ** CREATE TRIGGER AFTER INSERT ON t1 BEGIN; |
1050 | ** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b); |
1051 | ** END; |
1052 | ** |
1053 | ** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy |
1054 | ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy |
1055 | */ |
1056 | pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf; |
1057 | assert( pParse->okConstFactor==0 ); |
1058 | |
1059 | #ifndef SQLITE_OMIT_TRACE |
1060 | if( pStep->zSpan ){ |
1061 | sqlite3VdbeAddOp4(v, OP_Trace, 0x7fffffff, 1, 0, |
1062 | sqlite3MPrintf(db, "-- %s" , pStep->zSpan), |
1063 | P4_DYNAMIC); |
1064 | } |
1065 | #endif |
1066 | |
1067 | switch( pStep->op ){ |
1068 | case TK_UPDATE: { |
1069 | sqlite3Update(pParse, |
1070 | sqlite3TriggerStepSrc(pParse, pStep), |
1071 | sqlite3ExprListDup(db, pStep->pExprList, 0), |
1072 | sqlite3ExprDup(db, pStep->pWhere, 0), |
1073 | pParse->eOrconf, 0, 0, 0 |
1074 | ); |
1075 | sqlite3VdbeAddOp0(v, OP_ResetCount); |
1076 | break; |
1077 | } |
1078 | case TK_INSERT: { |
1079 | sqlite3Insert(pParse, |
1080 | sqlite3TriggerStepSrc(pParse, pStep), |
1081 | sqlite3SelectDup(db, pStep->pSelect, 0), |
1082 | sqlite3IdListDup(db, pStep->pIdList), |
1083 | pParse->eOrconf, |
1084 | sqlite3UpsertDup(db, pStep->pUpsert) |
1085 | ); |
1086 | sqlite3VdbeAddOp0(v, OP_ResetCount); |
1087 | break; |
1088 | } |
1089 | case TK_DELETE: { |
1090 | sqlite3DeleteFrom(pParse, |
1091 | sqlite3TriggerStepSrc(pParse, pStep), |
1092 | sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0 |
1093 | ); |
1094 | sqlite3VdbeAddOp0(v, OP_ResetCount); |
1095 | break; |
1096 | } |
1097 | default: assert( pStep->op==TK_SELECT ); { |
1098 | SelectDest sDest; |
1099 | Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0); |
1100 | sqlite3SelectDestInit(&sDest, SRT_Discard, 0); |
1101 | sqlite3Select(pParse, pSelect, &sDest); |
1102 | sqlite3SelectDelete(db, pSelect); |
1103 | break; |
1104 | } |
1105 | } |
1106 | } |
1107 | |
1108 | return 0; |
1109 | } |
1110 | |
1111 | #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS |
1112 | /* |
1113 | ** This function is used to add VdbeComment() annotations to a VDBE |
1114 | ** program. It is not used in production code, only for debugging. |
1115 | */ |
1116 | static const char *onErrorText(int onError){ |
1117 | switch( onError ){ |
1118 | case OE_Abort: return "abort" ; |
1119 | case OE_Rollback: return "rollback" ; |
1120 | case OE_Fail: return "fail" ; |
1121 | case OE_Replace: return "replace" ; |
1122 | case OE_Ignore: return "ignore" ; |
1123 | case OE_Default: return "default" ; |
1124 | } |
1125 | return "n/a" ; |
1126 | } |
1127 | #endif |
1128 | |
1129 | /* |
1130 | ** Parse context structure pFrom has just been used to create a sub-vdbe |
1131 | ** (trigger program). If an error has occurred, transfer error information |
1132 | ** from pFrom to pTo. |
1133 | */ |
1134 | static void transferParseError(Parse *pTo, Parse *pFrom){ |
1135 | assert( pFrom->zErrMsg==0 || pFrom->nErr ); |
1136 | assert( pTo->zErrMsg==0 || pTo->nErr ); |
1137 | if( pTo->nErr==0 ){ |
1138 | pTo->zErrMsg = pFrom->zErrMsg; |
1139 | pTo->nErr = pFrom->nErr; |
1140 | pTo->rc = pFrom->rc; |
1141 | }else{ |
1142 | sqlite3DbFree(pFrom->db, pFrom->zErrMsg); |
1143 | } |
1144 | } |
1145 | |
1146 | /* |
1147 | ** Create and populate a new TriggerPrg object with a sub-program |
1148 | ** implementing trigger pTrigger with ON CONFLICT policy orconf. |
1149 | */ |
1150 | static TriggerPrg *codeRowTrigger( |
1151 | Parse *pParse, /* Current parse context */ |
1152 | Trigger *pTrigger, /* Trigger to code */ |
1153 | Table *pTab, /* The table pTrigger is attached to */ |
1154 | int orconf /* ON CONFLICT policy to code trigger program with */ |
1155 | ){ |
1156 | Parse *pTop = sqlite3ParseToplevel(pParse); |
1157 | sqlite3 *db = pParse->db; /* Database handle */ |
1158 | TriggerPrg *pPrg; /* Value to return */ |
1159 | Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */ |
1160 | Vdbe *v; /* Temporary VM */ |
1161 | NameContext sNC; /* Name context for sub-vdbe */ |
1162 | SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */ |
1163 | int iEndTrigger = 0; /* Label to jump to if WHEN is false */ |
1164 | Parse sSubParse; /* Parse context for sub-vdbe */ |
1165 | |
1166 | assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); |
1167 | assert( pTop->pVdbe ); |
1168 | |
1169 | /* Allocate the TriggerPrg and SubProgram objects. To ensure that they |
1170 | ** are freed if an error occurs, link them into the Parse.pTriggerPrg |
1171 | ** list of the top-level Parse object sooner rather than later. */ |
1172 | pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg)); |
1173 | if( !pPrg ) return 0; |
1174 | pPrg->pNext = pTop->pTriggerPrg; |
1175 | pTop->pTriggerPrg = pPrg; |
1176 | pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram)); |
1177 | if( !pProgram ) return 0; |
1178 | sqlite3VdbeLinkSubProgram(pTop->pVdbe, pProgram); |
1179 | pPrg->pTrigger = pTrigger; |
1180 | pPrg->orconf = orconf; |
1181 | pPrg->aColmask[0] = 0xffffffff; |
1182 | pPrg->aColmask[1] = 0xffffffff; |
1183 | |
1184 | /* Allocate and populate a new Parse context to use for coding the |
1185 | ** trigger sub-program. */ |
1186 | sqlite3ParseObjectInit(&sSubParse, db); |
1187 | memset(&sNC, 0, sizeof(sNC)); |
1188 | sNC.pParse = &sSubParse; |
1189 | sSubParse.pTriggerTab = pTab; |
1190 | sSubParse.pToplevel = pTop; |
1191 | sSubParse.zAuthContext = pTrigger->zName; |
1192 | sSubParse.eTriggerOp = pTrigger->op; |
1193 | sSubParse.nQueryLoop = pParse->nQueryLoop; |
1194 | sSubParse.prepFlags = pParse->prepFlags; |
1195 | |
1196 | v = sqlite3GetVdbe(&sSubParse); |
1197 | if( v ){ |
1198 | VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)" , |
1199 | pTrigger->zName, onErrorText(orconf), |
1200 | (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER" ), |
1201 | (pTrigger->op==TK_UPDATE ? "UPDATE" : "" ), |
1202 | (pTrigger->op==TK_INSERT ? "INSERT" : "" ), |
1203 | (pTrigger->op==TK_DELETE ? "DELETE" : "" ), |
1204 | pTab->zName |
1205 | )); |
1206 | #ifndef SQLITE_OMIT_TRACE |
1207 | if( pTrigger->zName ){ |
1208 | sqlite3VdbeChangeP4(v, -1, |
1209 | sqlite3MPrintf(db, "-- TRIGGER %s" , pTrigger->zName), P4_DYNAMIC |
1210 | ); |
1211 | } |
1212 | #endif |
1213 | |
1214 | /* If one was specified, code the WHEN clause. If it evaluates to false |
1215 | ** (or NULL) the sub-vdbe is immediately halted by jumping to the |
1216 | ** OP_Halt inserted at the end of the program. */ |
1217 | if( pTrigger->pWhen ){ |
1218 | pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0); |
1219 | if( db->mallocFailed==0 |
1220 | && SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) |
1221 | ){ |
1222 | iEndTrigger = sqlite3VdbeMakeLabel(&sSubParse); |
1223 | sqlite3ExprIfFalse(&sSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); |
1224 | } |
1225 | sqlite3ExprDelete(db, pWhen); |
1226 | } |
1227 | |
1228 | /* Code the trigger program into the sub-vdbe. */ |
1229 | codeTriggerProgram(&sSubParse, pTrigger->step_list, orconf); |
1230 | |
1231 | /* Insert an OP_Halt at the end of the sub-program. */ |
1232 | if( iEndTrigger ){ |
1233 | sqlite3VdbeResolveLabel(v, iEndTrigger); |
1234 | } |
1235 | sqlite3VdbeAddOp0(v, OP_Halt); |
1236 | VdbeComment((v, "End: %s.%s" , pTrigger->zName, onErrorText(orconf))); |
1237 | transferParseError(pParse, &sSubParse); |
1238 | |
1239 | if( pParse->nErr==0 ){ |
1240 | assert( db->mallocFailed==0 ); |
1241 | pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); |
1242 | } |
1243 | pProgram->nMem = sSubParse.nMem; |
1244 | pProgram->nCsr = sSubParse.nTab; |
1245 | pProgram->token = (void *)pTrigger; |
1246 | pPrg->aColmask[0] = sSubParse.oldmask; |
1247 | pPrg->aColmask[1] = sSubParse.newmask; |
1248 | sqlite3VdbeDelete(v); |
1249 | }else{ |
1250 | transferParseError(pParse, &sSubParse); |
1251 | } |
1252 | |
1253 | assert( !sSubParse.pTriggerPrg && !sSubParse.nMaxArg ); |
1254 | sqlite3ParseObjectReset(&sSubParse); |
1255 | return pPrg; |
1256 | } |
1257 | |
1258 | /* |
1259 | ** Return a pointer to a TriggerPrg object containing the sub-program for |
1260 | ** trigger pTrigger with default ON CONFLICT algorithm orconf. If no such |
1261 | ** TriggerPrg object exists, a new object is allocated and populated before |
1262 | ** being returned. |
1263 | */ |
1264 | static TriggerPrg *getRowTrigger( |
1265 | Parse *pParse, /* Current parse context */ |
1266 | Trigger *pTrigger, /* Trigger to code */ |
1267 | Table *pTab, /* The table trigger pTrigger is attached to */ |
1268 | int orconf /* ON CONFLICT algorithm. */ |
1269 | ){ |
1270 | Parse *pRoot = sqlite3ParseToplevel(pParse); |
1271 | TriggerPrg *pPrg; |
1272 | |
1273 | assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); |
1274 | |
1275 | /* It may be that this trigger has already been coded (or is in the |
1276 | ** process of being coded). If this is the case, then an entry with |
1277 | ** a matching TriggerPrg.pTrigger field will be present somewhere |
1278 | ** in the Parse.pTriggerPrg list. Search for such an entry. */ |
1279 | for(pPrg=pRoot->pTriggerPrg; |
1280 | pPrg && (pPrg->pTrigger!=pTrigger || pPrg->orconf!=orconf); |
1281 | pPrg=pPrg->pNext |
1282 | ); |
1283 | |
1284 | /* If an existing TriggerPrg could not be located, create a new one. */ |
1285 | if( !pPrg ){ |
1286 | pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf); |
1287 | pParse->db->errByteOffset = -1; |
1288 | } |
1289 | |
1290 | return pPrg; |
1291 | } |
1292 | |
1293 | /* |
1294 | ** Generate code for the trigger program associated with trigger p on |
1295 | ** table pTab. The reg, orconf and ignoreJump parameters passed to this |
1296 | ** function are the same as those described in the header function for |
1297 | ** sqlite3CodeRowTrigger() |
1298 | */ |
1299 | void sqlite3CodeRowTriggerDirect( |
1300 | Parse *pParse, /* Parse context */ |
1301 | Trigger *p, /* Trigger to code */ |
1302 | Table *pTab, /* The table to code triggers from */ |
1303 | int reg, /* Reg array containing OLD.* and NEW.* values */ |
1304 | int orconf, /* ON CONFLICT policy */ |
1305 | int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ |
1306 | ){ |
1307 | Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */ |
1308 | TriggerPrg *pPrg; |
1309 | pPrg = getRowTrigger(pParse, p, pTab, orconf); |
1310 | assert( pPrg || pParse->nErr ); |
1311 | |
1312 | /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program |
1313 | ** is a pointer to the sub-vdbe containing the trigger program. */ |
1314 | if( pPrg ){ |
1315 | int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers)); |
1316 | |
1317 | sqlite3VdbeAddOp4(v, OP_Program, reg, ignoreJump, ++pParse->nMem, |
1318 | (const char *)pPrg->pProgram, P4_SUBPROGRAM); |
1319 | VdbeComment( |
1320 | (v, "Call: %s.%s" , (p->zName?p->zName:"fkey" ), onErrorText(orconf))); |
1321 | |
1322 | /* Set the P5 operand of the OP_Program instruction to non-zero if |
1323 | ** recursive invocation of this trigger program is disallowed. Recursive |
1324 | ** invocation is disallowed if (a) the sub-program is really a trigger, |
1325 | ** not a foreign key action, and (b) the flag to enable recursive triggers |
1326 | ** is clear. */ |
1327 | sqlite3VdbeChangeP5(v, (u8)bRecursive); |
1328 | } |
1329 | } |
1330 | |
1331 | /* |
1332 | ** This is called to code the required FOR EACH ROW triggers for an operation |
1333 | ** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE) |
1334 | ** is given by the op parameter. The tr_tm parameter determines whether the |
1335 | ** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then |
1336 | ** parameter pChanges is passed the list of columns being modified. |
1337 | ** |
1338 | ** If there are no triggers that fire at the specified time for the specified |
1339 | ** operation on pTab, this function is a no-op. |
1340 | ** |
1341 | ** The reg argument is the address of the first in an array of registers |
1342 | ** that contain the values substituted for the new.* and old.* references |
1343 | ** in the trigger program. If N is the number of columns in table pTab |
1344 | ** (a copy of pTab->nCol), then registers are populated as follows: |
1345 | ** |
1346 | ** Register Contains |
1347 | ** ------------------------------------------------------ |
1348 | ** reg+0 OLD.rowid |
1349 | ** reg+1 OLD.* value of left-most column of pTab |
1350 | ** ... ... |
1351 | ** reg+N OLD.* value of right-most column of pTab |
1352 | ** reg+N+1 NEW.rowid |
1353 | ** reg+N+2 NEW.* value of left-most column of pTab |
1354 | ** ... ... |
1355 | ** reg+N+N+1 NEW.* value of right-most column of pTab |
1356 | ** |
1357 | ** For ON DELETE triggers, the registers containing the NEW.* values will |
1358 | ** never be accessed by the trigger program, so they are not allocated or |
1359 | ** populated by the caller (there is no data to populate them with anyway). |
1360 | ** Similarly, for ON INSERT triggers the values stored in the OLD.* registers |
1361 | ** are never accessed, and so are not allocated by the caller. So, for an |
1362 | ** ON INSERT trigger, the value passed to this function as parameter reg |
1363 | ** is not a readable register, although registers (reg+N) through |
1364 | ** (reg+N+N+1) are. |
1365 | ** |
1366 | ** Parameter orconf is the default conflict resolution algorithm for the |
1367 | ** trigger program to use (REPLACE, IGNORE etc.). Parameter ignoreJump |
1368 | ** is the instruction that control should jump to if a trigger program |
1369 | ** raises an IGNORE exception. |
1370 | */ |
1371 | void sqlite3CodeRowTrigger( |
1372 | Parse *pParse, /* Parse context */ |
1373 | Trigger *pTrigger, /* List of triggers on table pTab */ |
1374 | int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */ |
1375 | ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ |
1376 | int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ |
1377 | Table *pTab, /* The table to code triggers from */ |
1378 | int reg, /* The first in an array of registers (see above) */ |
1379 | int orconf, /* ON CONFLICT policy */ |
1380 | int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ |
1381 | ){ |
1382 | Trigger *p; /* Used to iterate through pTrigger list */ |
1383 | |
1384 | assert( op==TK_UPDATE || op==TK_INSERT || op==TK_DELETE ); |
1385 | assert( tr_tm==TRIGGER_BEFORE || tr_tm==TRIGGER_AFTER ); |
1386 | assert( (op==TK_UPDATE)==(pChanges!=0) ); |
1387 | |
1388 | for(p=pTrigger; p; p=p->pNext){ |
1389 | |
1390 | /* Sanity checking: The schema for the trigger and for the table are |
1391 | ** always defined. The trigger must be in the same schema as the table |
1392 | ** or else it must be a TEMP trigger. */ |
1393 | assert( p->pSchema!=0 ); |
1394 | assert( p->pTabSchema!=0 ); |
1395 | assert( p->pSchema==p->pTabSchema |
1396 | || p->pSchema==pParse->db->aDb[1].pSchema ); |
1397 | |
1398 | /* Determine whether we should code this trigger. One of two choices: |
1399 | ** 1. The trigger is an exact match to the current DML statement |
1400 | ** 2. This is a RETURNING trigger for INSERT but we are currently |
1401 | ** doing the UPDATE part of an UPSERT. |
1402 | */ |
1403 | if( (p->op==op || (p->bReturning && p->op==TK_INSERT && op==TK_UPDATE)) |
1404 | && p->tr_tm==tr_tm |
1405 | && checkColumnOverlap(p->pColumns, pChanges) |
1406 | ){ |
1407 | if( !p->bReturning ){ |
1408 | sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); |
1409 | }else if( sqlite3IsToplevel(pParse) ){ |
1410 | codeReturningTrigger(pParse, p, pTab, reg); |
1411 | } |
1412 | } |
1413 | } |
1414 | } |
1415 | |
1416 | /* |
1417 | ** Triggers may access values stored in the old.* or new.* pseudo-table. |
1418 | ** This function returns a 32-bit bitmask indicating which columns of the |
1419 | ** old.* or new.* tables actually are used by triggers. This information |
1420 | ** may be used by the caller, for example, to avoid having to load the entire |
1421 | ** old.* record into memory when executing an UPDATE or DELETE command. |
1422 | ** |
1423 | ** Bit 0 of the returned mask is set if the left-most column of the |
1424 | ** table may be accessed using an [old|new].<col> reference. Bit 1 is set if |
1425 | ** the second leftmost column value is required, and so on. If there |
1426 | ** are more than 32 columns in the table, and at least one of the columns |
1427 | ** with an index greater than 32 may be accessed, 0xffffffff is returned. |
1428 | ** |
1429 | ** It is not possible to determine if the old.rowid or new.rowid column is |
1430 | ** accessed by triggers. The caller must always assume that it is. |
1431 | ** |
1432 | ** Parameter isNew must be either 1 or 0. If it is 0, then the mask returned |
1433 | ** applies to the old.* table. If 1, the new.* table. |
1434 | ** |
1435 | ** Parameter tr_tm must be a mask with one or both of the TRIGGER_BEFORE |
1436 | ** and TRIGGER_AFTER bits set. Values accessed by BEFORE triggers are only |
1437 | ** included in the returned mask if the TRIGGER_BEFORE bit is set in the |
1438 | ** tr_tm parameter. Similarly, values accessed by AFTER triggers are only |
1439 | ** included in the returned mask if the TRIGGER_AFTER bit is set in tr_tm. |
1440 | */ |
1441 | u32 sqlite3TriggerColmask( |
1442 | Parse *pParse, /* Parse context */ |
1443 | Trigger *pTrigger, /* List of triggers on table pTab */ |
1444 | ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ |
1445 | int isNew, /* 1 for new.* ref mask, 0 for old.* ref mask */ |
1446 | int tr_tm, /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ |
1447 | Table *pTab, /* The table to code triggers from */ |
1448 | int orconf /* Default ON CONFLICT policy for trigger steps */ |
1449 | ){ |
1450 | const int op = pChanges ? TK_UPDATE : TK_DELETE; |
1451 | u32 mask = 0; |
1452 | Trigger *p; |
1453 | |
1454 | assert( isNew==1 || isNew==0 ); |
1455 | for(p=pTrigger; p; p=p->pNext){ |
1456 | if( p->op==op |
1457 | && (tr_tm&p->tr_tm) |
1458 | && checkColumnOverlap(p->pColumns,pChanges) |
1459 | ){ |
1460 | if( p->bReturning ){ |
1461 | mask = 0xffffffff; |
1462 | }else{ |
1463 | TriggerPrg *pPrg; |
1464 | pPrg = getRowTrigger(pParse, p, pTab, orconf); |
1465 | if( pPrg ){ |
1466 | mask |= pPrg->aColmask[isNew]; |
1467 | } |
1468 | } |
1469 | } |
1470 | } |
1471 | |
1472 | return mask; |
1473 | } |
1474 | |
1475 | #endif /* !defined(SQLITE_OMIT_TRIGGER) */ |
1476 | |