/ Check-in [9fa904d9]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Simplification of the trigger code. (CVS 1976)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9fa904d94ec1787bc8b97ec06a5423248fcb67fb
User & Date: drh 2004-09-24 12:24:36
Context
2004-09-24
12:48
Avoid a segfault in sqlite3_bind_parameter_index when there are unnamed parameters. Ticket #918. (CVS 1977) check-in: 49f25ddf user: drh tags: trunk
12:24
Simplification of the trigger code. (CVS 1976) check-in: 9fa904d9 user: drh tags: trunk
12:24
Fix for tickets #912 and #922. Problem introduced by check-in (1973). (CVS 1975) check-in: 9001e222 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/trigger.c.

   646    646     TriggerStep * pTriggerStep = pStepList;
   647    647     int orconf;
   648    648     Vdbe *v = pParse->pVdbe;
   649    649   
   650    650     assert( pTriggerStep!=0 );
   651    651     assert( v!=0 );
   652    652     sqlite3VdbeAddOp(v, OP_ContextPush, 0, 0);
          653  +  VdbeComment((v, "# begin trigger %s", pStepList->pTrig->name));
   653    654     while( pTriggerStep ){
   654    655       orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
   655    656       pParse->trigStack->orconf = orconf;
   656    657       switch( pTriggerStep->op ){
   657    658         case TK_SELECT: {
   658    659   	Select * ss = sqlite3SelectDup(pTriggerStep->pSelect);		  
   659    660   	assert(ss);
................................................................................
   693    694         }
   694    695         default:
   695    696           assert(0);
   696    697       } 
   697    698       pTriggerStep = pTriggerStep->pNext;
   698    699     }
   699    700     sqlite3VdbeAddOp(v, OP_ContextPop, 0, 0);
          701  +  VdbeComment((v, "# end trigger %s", pStepList->pTrig->name));
   700    702   
   701    703     return 0;
   702    704   }
   703    705   
   704    706   /*
   705    707   ** This is called to code FOR EACH ROW triggers.
   706    708   **
................................................................................
   728    730     int tr_tm,           /* One of TK_BEFORE, TK_AFTER */
   729    731     Table *pTab,         /* The table to code triggers from */
   730    732     int newIdx,          /* The indice of the "new" row to access */
   731    733     int oldIdx,          /* The indice of the "old" row to access */
   732    734     int orconf,          /* ON CONFLICT policy */
   733    735     int ignoreJump       /* Instruction to jump to for RAISE(IGNORE) */
   734    736   ){
   735         -  Trigger * pTrigger;
   736         -  TriggerStack * pTriggerStack;
          737  +  Trigger *pTrigger;
          738  +  TriggerStack *pStack;
          739  +  TriggerStack trigStackEntry;
   737    740   
   738    741     assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
   739    742     assert(tr_tm == TK_BEFORE || tr_tm == TK_AFTER );
   740    743   
   741    744     assert(newIdx != -1 || oldIdx != -1);
   742    745   
   743    746     pTrigger = pTab->pTrigger;
................................................................................
   744    747     while( pTrigger ){
   745    748       int fire_this = 0;
   746    749   
   747    750       /* determine whether we should code this trigger */
   748    751       if( pTrigger->op == op && pTrigger->tr_tm == tr_tm && 
   749    752           pTrigger->foreach == TK_ROW ){
   750    753         fire_this = 1;
   751         -      pTriggerStack = pParse->trigStack;
   752         -      while( pTriggerStack ){
   753         -        if( pTriggerStack->pTrigger == pTrigger ){
          754  +      for(pStack=pParse->trigStack; pStack; pStack=pStack->pNext){
          755  +        if( pStack->pTrigger==pTrigger ){
   754    756   	  fire_this = 0;
   755    757   	}
   756         -        pTriggerStack = pTriggerStack->pNext;
   757    758         }
   758    759         if( op == TK_UPDATE && pTrigger->pColumns &&
   759    760             !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
   760    761           fire_this = 0;
   761    762         }
   762    763       }
   763    764    
   764         -    /* FIX ME:  Can we not omit the sqliteMalloc() and make pTriggerStack
   765         -    ** point to a stack variable?
   766         -    */
   767         -    if( fire_this && (pTriggerStack = sqliteMalloc(sizeof(TriggerStack)))!=0 ){
          765  +    if( fire_this ){
   768    766         int endTrigger;
   769    767         SrcList dummyTablist;
   770    768         Expr * whenExpr;
   771    769         AuthContext sContext;
   772    770   
   773    771         dummyTablist.nSrc = 0;
   774    772   
   775    773         /* Push an entry on to the trigger stack */
   776         -      pTriggerStack->pTrigger = pTrigger;
   777         -      pTriggerStack->newIdx = newIdx;
   778         -      pTriggerStack->oldIdx = oldIdx;
   779         -      pTriggerStack->pTab = pTab;
   780         -      pTriggerStack->pNext = pParse->trigStack;
   781         -      pTriggerStack->ignoreJump = ignoreJump;
   782         -      pParse->trigStack = pTriggerStack;
          774  +      trigStackEntry.pTrigger = pTrigger;
          775  +      trigStackEntry.newIdx = newIdx;
          776  +      trigStackEntry.oldIdx = oldIdx;
          777  +      trigStackEntry.pTab = pTab;
          778  +      trigStackEntry.pNext = pParse->trigStack;
          779  +      trigStackEntry.ignoreJump = ignoreJump;
          780  +      pParse->trigStack = &trigStackEntry;
   783    781         sqlite3AuthContextPush(pParse, &sContext, pTrigger->name);
   784    782   
   785    783         /* code the WHEN clause */
   786    784         endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe);
   787    785         whenExpr = sqlite3ExprDup(pTrigger->pWhen);
   788    786         if( sqlite3ExprResolveIds(pParse, &dummyTablist, 0, whenExpr) ){
   789         -        pParse->trigStack = pParse->trigStack->pNext;
   790         -        sqliteFree(pTriggerStack);
          787  +        pParse->trigStack = trigStackEntry.pNext;
   791    788           sqlite3ExprDelete(whenExpr);
   792    789           return 1;
   793    790         }
   794    791         sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, 1);
   795    792         sqlite3ExprDelete(whenExpr);
   796    793   
   797    794         codeTriggerProgram(pParse, pTrigger->step_list, orconf); 
   798    795   
   799    796         /* Pop the entry off the trigger stack */
   800         -      pParse->trigStack = pParse->trigStack->pNext;
          797  +      pParse->trigStack = trigStackEntry.pNext;
   801    798         sqlite3AuthContextPop(&sContext);
   802         -      sqliteFree(pTriggerStack);
   803    799   
   804    800         sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger);
   805    801       }
   806    802       pTrigger = pTrigger->pNext;
   807    803     }
   808    804     return 0;
   809    805   }