~ubuntu-branches/ubuntu/saucy/digikam/saucy

« back to all changes in this revision

Viewing changes to core/libs/3rdparty/sqlite2/trigger.c

  • Committer: Package Import Robot
  • Author(s): Felix Geyer, Rohan Garg, Philip Muškovac, Felix Geyer
  • Date: 2011-09-23 18:18:55 UTC
  • mfrom: (1.2.36 upstream)
  • Revision ID: package-import@ubuntu.com-20110923181855-ifs67wxkugshev9k
Tags: 2:2.1.1-0ubuntu1
[ Rohan Garg ]
* New upstream release (LP: #834190)
  - debian/control
    + Build with libqtwebkit-dev
 - debian/kipi-plugins-common
    + Install libkvkontakte required by kipi-plugins
 - debian/digikam
    + Install panoramagui

[ Philip Muškovac ]
* New upstream release
  - debian/control:
    + Add libcv-dev, libcvaux-dev, libhighgui-dev, libboost-graph1.46-dev,
      libksane-dev, libxml2-dev, libxslt-dev, libqt4-opengl-dev, libqjson-dev,
      libgpod-dev and libqca2-dev to build-deps
    + Add packages for kipi-plugins, libmediawiki, libkface, libkgeomap and
      libkvkontakte
  - debian/rules:
    + Don't build with gphoto2 since it doesn't build with it.
  - Add kubuntu_fix_test_linking.diff to fix linking of the dngconverter test
  - update install files
  - update kubuntu_01_mysqld_executable_name.diff for new cmake layout
    and rename to kubuntu_mysqld_executable_name.diff
* Fix typo in digikam-data description (LP: #804894)
* Fix Vcs links

[ Felix Geyer ]
* Move library data files to the new packages libkface-data, libkgeomap-data
  and libkvkontakte-data.
* Override version of the embedded library packages to 1.0~digikam<version>.
* Exclude the library packages from digikam-dbg to prevent file conflicts in
  the future.
* Call dh_install with --list-missing.

Show diffs side-by-side

added added

removed removed

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