/ Check-in [9eb91efd]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Fixes for new triggers scheme.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9eb91efda5241609ff18ff15ef5eaa0e86788eab
User & Date: dan 2009-08-30 11:42:52
Context
2009-08-31
05:23
Fix another test problem and some instances where an OOM may cause a segfault. check-in: 31199db0 user: dan tags: trunk
2009-08-30
11:42
Fixes for new triggers scheme. check-in: 9eb91efd user: dan tags: trunk
2009-08-28
18:53
Changes to support recursive triggers. check-in: 9b9c1921 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/delete.c.

   404    404         sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid);
   405    405   
   406    406         /* Populate the OLD.* pseudo-table */
   407    407         assert( regOld==iRowid+1 );
   408    408         for(i=0; i<pTab->nCol; i++){
   409    409           if( mask==0xffffffff || mask&(1<<i) ){
   410    410             sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regOld+i);
          411  +          sqlite3ColumnDefault(v, pTab, i, regOld+i);
   411    412           }
   412    413         }
          414  +      sqlite3VdbeAddOp2(v, OP_Affinity, regOld, pTab->nCol);
          415  +      sqlite3TableAffinityStr(v, pTab);
   413    416   
   414    417         sqlite3CodeRowTrigger(pParse, pTrigger, 
   415         -          TK_DELETE, 0, TRIGGER_BEFORE, pTab, -1, regOld, OE_Default, addr
          418  +          TK_DELETE, 0, TRIGGER_BEFORE, pTab, -1, iRowid, OE_Default, addr
   416    419         );
   417    420       }
   418    421   
   419    422       if( !isView ){
   420    423         /* Delete the row */
   421    424   #ifndef SQLITE_OMIT_VIRTUALTABLE
   422    425         if( IsVirtual(pTab) ){
................................................................................
   428    431         {
   429    432           sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, pParse->nested==0);
   430    433         }
   431    434       }
   432    435   
   433    436       /* Code the AFTER triggers. This is a no-op if there are no triggers. */
   434    437       sqlite3CodeRowTrigger(pParse, 
   435         -      pTrigger, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1, regOld, OE_Default, addr
          438  +      pTrigger, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1, iRowid, OE_Default, addr
   436    439       );
   437    440   
   438    441       /* End of the delete loop */
   439    442       sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
   440    443       sqlite3VdbeResolveLabel(v, end);
   441    444   
   442    445       /* Close the cursors open on the table and its indexes. */

Changes to src/expr.c.

    86     86     CollSeq *pColl = 0;
    87     87     Expr *p = pExpr;
    88     88     while( ALWAYS(p) ){
    89     89       int op;
    90     90       pColl = p->pColl;
    91     91       if( pColl ) break;
    92     92       op = p->op;
    93         -    if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER) && p->pTab!=0 ){
           93  +    if( p->pTab!=0 && (
           94  +        op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER
           95  +    )){
    94     96         /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
    95     97         ** a TK_COLUMN but was previously evaluated and cached in a register */
    96     98         const char *zColl;
    97     99         int j = p->iColumn;
    98    100         if( j>=0 ){
    99    101           sqlite3 *db = pParse->db;
   100    102           zColl = p->pTab->aCol[j].zColl;
................................................................................
  2553   2555       }
  2554   2556       case TK_UPLUS: {
  2555   2557         inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
  2556   2558         break;
  2557   2559       }
  2558   2560   
  2559   2561       case TK_TRIGGER: {
  2560         -      sqlite3VdbeAddOp3(v, OP_TriggerVal, pExpr->iColumn, target,pExpr->iTable);
  2561         -      assert( pExpr->pTab );
  2562         -      VdbeComment((v, "%s.%s", 
         2562  +      int iVal = pExpr->iTable * (pExpr->pTab->nCol+1) + 1 + pExpr->iColumn;
         2563  +      sqlite3VdbeAddOp2(v, OP_Param, iVal, target);
         2564  +      VdbeComment((v, "%s.%s -> $%d", 
  2563   2565           (pExpr->iTable ? "new" : "old"), 
  2564         -        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName)
         2566  +        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
         2567  +	target
  2565   2568         ));
  2566   2569         break;
  2567   2570       }
  2568   2571   
  2569   2572   
  2570   2573       /*
  2571   2574       ** Form A:

Changes to src/insert.c.

   193    193   static int autoIncBegin(
   194    194     Parse *pParse,      /* Parsing context */
   195    195     int iDb,            /* Index of the database holding pTab */
   196    196     Table *pTab         /* The table we are writing to */
   197    197   ){
   198    198     int memId = 0;      /* Register holding maximum rowid */
   199    199     if( pTab->tabFlags & TF_Autoincrement ){
          200  +    Parse *pRoot = (pParse->pRoot ? pParse->pRoot : pParse);
   200    201       AutoincInfo *pInfo;
   201    202   
   202         -    pInfo = pParse->pAinc;
          203  +    pInfo = pRoot->pAinc;
   203    204       while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
   204    205       if( pInfo==0 ){
   205    206         pInfo = sqlite3DbMallocRaw(pParse->db, sizeof(*pInfo));
   206    207         if( pInfo==0 ) return 0;
   207         -      pInfo->pNext = pParse->pAinc;
   208         -      pParse->pAinc = pInfo;
          208  +      pInfo->pNext = pRoot->pAinc;
          209  +      pRoot->pAinc = pInfo;
   209    210         pInfo->pTab = pTab;
   210    211         pInfo->iDb = iDb;
   211         -      pParse->nMem++;                  /* Register to hold name of table */
   212         -      pInfo->regCtr = ++pParse->nMem;  /* Max rowid register */
   213         -      pParse->nMem++;                  /* Rowid in sqlite_sequence */
          212  +      pRoot->nMem++;                  /* Register to hold name of table */
          213  +      pInfo->regCtr = ++pRoot->nMem;  /* Max rowid register */
          214  +      pRoot->nMem++;                  /* Rowid in sqlite_sequence */
   214    215       }
   215    216       memId = pInfo->regCtr;
   216    217     }
   217    218     return memId;
   218    219   }
   219    220   
   220    221   /*
................................................................................
   224    225   void sqlite3AutoincrementBegin(Parse *pParse){
   225    226     AutoincInfo *p;            /* Information about an AUTOINCREMENT */
   226    227     sqlite3 *db = pParse->db;  /* The database connection */
   227    228     Db *pDb;                   /* Database only autoinc table */
   228    229     int memId;                 /* Register holding max rowid */
   229    230     int addr;                  /* A VDBE address */
   230    231     Vdbe *v = pParse->pVdbe;   /* VDBE under construction */
          232  +
          233  +  /* If currently generating a trigger program, this call is a no-op */
          234  +  if( pParse->pTriggerTab ) return;
   231    235   
   232    236     assert( v );   /* We failed long ago if this is not so */
   233    237     for(p = pParse->pAinc; p; p = p->pNext){
   234    238       pDb = &db->aDb[p->iDb];
   235    239       memId = p->regCtr;
   236    240       sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
   237    241       addr = sqlite3VdbeCurrentAddr(v);
................................................................................
   801    805     }
   802    806     regData = regRowid+1;
   803    807   
   804    808     /* Run the BEFORE and INSTEAD OF triggers, if there are any
   805    809     */
   806    810     endOfLoop = sqlite3VdbeMakeLabel(v);
   807    811     if( tmask & TRIGGER_BEFORE ){
   808         -    int regTrigRowid;
   809         -    int regCols;
          812  +    int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1);
   810    813   
   811    814       /* build the NEW.* reference row.  Note that if there is an INTEGER
   812    815       ** PRIMARY KEY into which a NULL is being inserted, that NULL will be
   813    816       ** translated into a unique ID for the row.  But on a BEFORE trigger,
   814    817       ** we do not know what the unique ID will be (because the insert has
   815    818       ** not happened yet) so we substitute a rowid of -1
   816    819       */
   817         -    regTrigRowid = sqlite3GetTempReg(pParse);
   818    820       if( keyColumn<0 ){
   819         -      sqlite3VdbeAddOp2(v, OP_Integer, -1, regTrigRowid);
          821  +      sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
   820    822       }else{
   821    823         int j1;
   822    824         if( useTempTable ){
   823         -        sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regTrigRowid);
          825  +        sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regCols);
   824    826         }else{
   825    827           assert( pSelect==0 );  /* Otherwise useTempTable is true */
   826         -        sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regTrigRowid);
          828  +        sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regCols);
   827    829         }
   828         -      j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regTrigRowid);
   829         -      sqlite3VdbeAddOp2(v, OP_Integer, -1, regTrigRowid);
          830  +      j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols);
          831  +      sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
   830    832         sqlite3VdbeJumpHere(v, j1);
   831         -      sqlite3VdbeAddOp1(v, OP_MustBeInt, regTrigRowid);
          833  +      sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols);
   832    834       }
   833    835   
   834    836       /* Cannot have triggers on a virtual table. If it were possible,
   835    837       ** this block would have to account for hidden column.
   836    838       */
   837    839       assert( !IsVirtual(pTab) );
   838    840   
   839    841       /* Create the new column data
   840    842       */
   841         -    regCols = sqlite3GetTempRange(pParse, pTab->nCol);
   842    843       for(i=0; i<pTab->nCol; i++){
   843    844         if( pColumn==0 ){
   844    845           j = i;
   845    846         }else{
   846    847           for(j=0; j<pColumn->nId; j++){
   847    848             if( pColumn->a[j].idx==i ) break;
   848    849           }
   849    850         }
   850    851         if( pColumn && j>=pColumn->nId ){
   851         -        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i);
          852  +        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1);
   852    853         }else if( useTempTable ){
   853         -        sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i); 
          854  +        sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1); 
   854    855         }else{
   855    856           assert( pSelect==0 ); /* Otherwise useTempTable is true */
   856         -        sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i);
          857  +        sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1);
   857    858         }
   858    859       }
   859    860   
   860    861       /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
   861    862       ** do not attempt any conversions before assembling the record.
   862    863       ** If this is a real table, attempt conversions as required by the
   863    864       ** table column affinities.
   864    865       */
   865    866       if( !isView ){
   866         -      sqlite3VdbeAddOp2(v, OP_Affinity, regCols, pTab->nCol);
          867  +      sqlite3VdbeAddOp2(v, OP_Affinity, regCols+1, pTab->nCol);
   867    868         sqlite3TableAffinityStr(v, pTab);
   868    869       }
   869    870   
   870    871       /* Fire BEFORE or INSTEAD OF triggers */
   871    872       sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, 
   872         -        pTab, regCols, -1, onError, endOfLoop);
          873  +        pTab, -1, regCols-pTab->nCol-1, onError, endOfLoop);
   873    874   
   874         -    sqlite3ReleaseTempReg(pParse, regTrigRowid);
   875         -    sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol);
          875  +    sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1);
   876    876     }
   877    877   
   878    878     /* Push the record number for the new entry onto the stack.  The
   879    879     ** record number is a randomly generate integer created by NewRowid
   880    880     ** except when the table has an INTEGER PRIMARY KEY column, in which
   881    881     ** case the record number is the same as that column. 
   882    882     */
................................................................................
   990    990     if( (db->flags & SQLITE_CountRows)!=0 ){
   991    991       sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
   992    992     }
   993    993   
   994    994     if( pTrigger ){
   995    995       /* Code AFTER triggers */
   996    996       sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, 
   997         -          pTab, regData, -1, onError, endOfLoop);
          997  +        pTab, -1, regData-2-pTab->nCol, onError, endOfLoop);
   998    998     }
   999    999   
  1000   1000     /* The bottom of the main insertion loop, if the data source
  1001   1001     ** is a SELECT statement.
  1002   1002     */
  1003   1003     sqlite3VdbeResolveLabel(v, endOfLoop);
  1004   1004     if( useTempTable ){
................................................................................
  1149   1149   
  1150   1150     v = sqlite3GetVdbe(pParse);
  1151   1151     assert( v!=0 );
  1152   1152     assert( pTab->pSelect==0 );  /* This table is not a VIEW */
  1153   1153     nCol = pTab->nCol;
  1154   1154     regData = regRowid + 1;
  1155   1155   
  1156         -
  1157   1156     /* Test all NOT NULL constraints.
  1158   1157     */
  1159   1158     for(i=0; i<nCol; i++){
  1160   1159       if( i==pTab->iPKey ){
  1161   1160         continue;
  1162   1161       }
  1163   1162       onError = pTab->aCol[i].notNull;
................................................................................
  1225   1224         onError = overrideError;
  1226   1225       }else if( onError==OE_Default ){
  1227   1226         onError = OE_Abort;
  1228   1227       }
  1229   1228       
  1230   1229       if( onError!=OE_Replace || pTab->pIndex ){
  1231   1230         if( isUpdate ){
  1232         -        j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, regRowid-1);
         1231  +        j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, rowidChng);
  1233   1232         }
  1234   1233         j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
  1235   1234         switch( onError ){
  1236   1235           default: {
  1237   1236             onError = OE_Abort;
  1238   1237             /* Fall thru into the next case */
  1239   1238           }

Changes to src/main.c.

  1586   1586     db->nextPagesize = 0;
  1587   1587     db->flags |= SQLITE_ShortColNames
  1588   1588   #if SQLITE_DEFAULT_FILE_FORMAT<4
  1589   1589                    | SQLITE_LegacyFileFmt
  1590   1590   #endif
  1591   1591   #ifdef SQLITE_ENABLE_LOAD_EXTENSION
  1592   1592                    | SQLITE_LoadExtension
         1593  +#endif
         1594  +#ifdef SQLITE_DISABLE_RECURSIVE_TRIGGERS
         1595  +                 | SQLITE_NoRecTriggers
  1593   1596   #endif
  1594   1597         ;
  1595   1598     sqlite3HashInit(&db->aCollSeq);
  1596   1599   #ifndef SQLITE_OMIT_VIRTUALTABLE
  1597   1600     sqlite3HashInit(&db->aModule);
  1598   1601   #endif
  1599   1602   

Changes to src/pragma.c.

   186    186       /* The following is VERY experimental */
   187    187       { "writable_schema",          SQLITE_WriteSchema|SQLITE_RecoveryMode },
   188    188       { "omit_readlock",            SQLITE_NoReadlock    },
   189    189   
   190    190       /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
   191    191       ** flag if there are any active statements. */
   192    192       { "read_uncommitted",         SQLITE_ReadUncommitted },
          193  +    { "disable_recursive_triggers", SQLITE_NoRecTriggers },
   193    194     };
   194    195     int i;
   195    196     const struct sPragmaType *p;
   196    197     for(i=0, p=aPragma; i<ArraySize(aPragma); i++, p++){
   197    198       if( sqlite3StrICmp(zLeft, p->zName)==0 ){
   198    199         sqlite3 *db = pParse->db;
   199    200         Vdbe *v;

Changes to src/sqliteInt.h.

   907    907   #define SQLITE_ReadUncommitted 0x00004000 /* For shared-cache mode */
   908    908   #define SQLITE_LegacyFileFmt  0x00008000  /* Create new databases in format 1 */
   909    909   #define SQLITE_FullFSync      0x00010000  /* Use full fsync on the backend */
   910    910   #define SQLITE_LoadExtension  0x00020000  /* Enable load_extension */
   911    911   
   912    912   #define SQLITE_RecoveryMode   0x00040000  /* Ignore schema errors */
   913    913   #define SQLITE_ReverseOrder   0x00100000  /* Reverse unordered SELECTs */
          914  +#define SQLITE_NoRecTriggers  0x00200000  /* Disable recursive triggers */
   914    915   
   915    916   /*
   916    917   ** Possible values for the sqlite.magic field.
   917    918   ** The numbers are obtained at random and have no special meaning, other
   918    919   ** than being distinct from one another.
   919    920   */
   920    921   #define SQLITE_MAGIC_OPEN     0xa029a697  /* Database is open */

Changes to src/trigger.c.

   693    693       **     INSERT OR REPLACE INTO t2 VALUES(new.a, new.b);
   694    694       **   END;
   695    695       **
   696    696       **   INSERT INTO t1 ... ;            -- insert into t2 uses REPLACE policy
   697    697       **   INSERT OR IGNORE INTO t1 ... ;  -- insert into t2 uses IGNORE policy
   698    698       */
   699    699       pParse->orconf = (orconfin==OE_Default)?pStep->orconf:orconfin;
          700  +
          701  +    if( pStep->op!=TK_SELECT ){
          702  +      sqlite3VdbeAddOp1(v, OP_ResetCount, 0);
          703  +    }
   700    704   
   701    705       switch( pStep->op ){
   702    706         case TK_UPDATE: {
   703    707           sqlite3Update(pParse, 
   704    708             targetSrcList(pParse, pStep),
   705    709             sqlite3ExprListDup(db, pStep->pExprList, 0), 
   706    710             sqlite3ExprDup(db, pStep->pWhere, 0), 
................................................................................
   730    734           Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0);
   731    735           sqlite3SelectDestInit(&sDest, SRT_Discard, 0);
   732    736           sqlite3Select(pParse, pSelect, &sDest);
   733    737           sqlite3SelectDelete(db, pSelect);
   734    738           break;
   735    739         }
   736    740       } 
          741  +    if( pStep->op!=TK_SELECT ){
          742  +      sqlite3VdbeAddOp1(v, OP_ResetCount, 1);
          743  +    }
   737    744       pStep = pStep->pNext;
   738    745     }
   739    746   /* sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0); */
   740    747   
   741    748     return 0;
   742    749   }
   743    750   
................................................................................
   814    821     pSubParse->pRoot = pRoot;
   815    822   
   816    823     /* Push an entry on to the auth context stack */
   817    824     sqlite3AuthContextPush(pParse, &sContext, pTrigger->name);
   818    825   
   819    826     v = sqlite3GetVdbe(pSubParse);
   820    827     if( v ){
   821         -    VdbeComment((v, "Trigger: %s (%s %s%s%s ON %s) (%s)", pTrigger->zName,
          828  +    VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", 
          829  +      pTrigger->zName, onErrorText(orconf),
   822    830         (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
   823    831           (op==TK_UPDATE ? "UPDATE" : ""),
   824    832           (op==TK_INSERT ? "INSERT" : ""),
   825    833           (op==TK_DELETE ? "DELETE" : ""),
   826         -      pTab->zName, onErrorText(orconf)
          834  +      pTab->zName
   827    835       ));
          836  +#ifndef SQLITE_OMIT_TRACE
          837  +    sqlite3VdbeChangeP4(v, -1, 
          838  +      sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
          839  +    );
          840  +#endif
   828    841   
   829    842       if( pTrigger->pWhen ){
   830    843         /* Code the WHEN clause. If it evaluates to false (or NULL) the 
   831    844         ** sub-vdbe is immediately halted.  */
   832    845         pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0);
   833    846         if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) ){
   834    847           iEndTrigger = sqlite3VdbeMakeLabel(v);
   835    848           sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
   836    849         }
   837    850         sqlite3ExprDelete(db, pWhen);
   838    851       }
   839    852   
   840    853       /* Code the trigger program into the sub-vdbe. */
   841         -    codeTriggerProgram(pSubParse, pTrigger->step_list, OE_Default);
          854  +    codeTriggerProgram(pSubParse, pTrigger->step_list, orconf);
   842    855       if( iEndTrigger ){
   843    856         sqlite3VdbeResolveLabel(v, iEndTrigger);
   844    857       }
   845    858       sqlite3VdbeAddOp0(v, OP_Halt);
          859  +    VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
          860  +
   846    861       transferParseError(pParse, pSubParse);
   847    862       pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pParse->nArg);
   848    863       pProgram->nMem = pSubParse->nMem;
   849    864       pProgram->nCsr = pSubParse->nTab;
   850    865       pProgram->token = (void *)pTrigger;
   851    866       pC->oldmask = pSubParse->oldmask;
   852    867       pC->newmask = pSubParse->newmask;
................................................................................
   957    972         CodedTrigger *pC;
   958    973         pC = getRowTrigger(pParse, p, op, pTab, orconf);
   959    974         assert( pC || pParse->nErr || pParse->db->mallocFailed );
   960    975   
   961    976         /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program 
   962    977         ** is a pointer to the sub-vdbe containing the trigger program.  */
   963    978         if( pC ){
   964         -        sqlite3VdbeAddOp3(v, OP_Program, oldIdx, newIdx, ++pParse->nMem);
          979  +        sqlite3VdbeAddOp3(v, OP_Program, oldIdx, ignoreJump, ++pParse->nMem);
   965    980           pC->pProgram->nRef++;
   966    981           sqlite3VdbeChangeP4(v, -1, (const char *)pC->pProgram, P4_SUBPROGRAM);
   967         -        VdbeComment((v, "Call trigger: %s (%s)", p->zName,onErrorText(orconf)));
          982  +        VdbeComment((v, "Call: %s.%s", p->zName, onErrorText(orconf)));
   968    983         }
   969    984       }
   970    985     }
   971    986   }
   972    987   
   973    988   void sqlite3TriggerUses(
   974    989     Parse *pParse,       /* Parse context */

Changes to src/update.c.

   126    126     /* Register Allocations */
   127    127     int regRowCount = 0;   /* A count of rows changed */
   128    128     int regOldRowid;       /* The old rowid */
   129    129     int regNewRowid;       /* The new rowid */
   130    130     int regNew;
   131    131     int regOld;
   132    132     int regRowSet = 0;     /* Rowset of rows to be updated */
          133  +  int regRec;            /* Register used for new table record to insert */
   133    134   
   134    135     memset(&sContext, 0, sizeof(sContext));
   135    136     db = pParse->db;
   136    137     if( pParse->nErr || db->mallocFailed ){
   137    138       goto update_cleanup;
   138    139     }
   139    140     assert( pTabList->nSrc==1 );
................................................................................
   141    142     /* Locate the table which we want to update. 
   142    143     */
   143    144     pTab = sqlite3SrcListLookup(pParse, pTabList);
   144    145     if( pTab==0 ) goto update_cleanup;
   145    146     iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
   146    147   
   147    148     /* Figure out if we have any triggers and if the table being
   148         -  ** updated is a view
          149  +  ** updated is a view.
   149    150     */
   150    151   #ifndef SQLITE_OMIT_TRIGGER
   151    152     pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, 0);
   152    153     isView = pTab->pSelect!=0;
   153    154   #else
   154    155   # define pTrigger 0
   155    156   # define isView 0
................................................................................
   278    279       pParse->nMem += pTab->nCol;
   279    280     }
   280    281     if( chngRowid || pTrigger ){
   281    282       regNewRowid = ++pParse->nMem;
   282    283     }
   283    284     regNew = pParse->nMem + 1;
   284    285     pParse->nMem += pTab->nCol;
          286  +  regRec = ++pParse->nMem;
   285    287   
   286    288     /* Start the view context. */
   287    289     if( isView ){
   288    290       sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
   289    291     }
   290    292   
   291    293     /* If there are any triggers, set old_col_mask and new_col_mask. */
................................................................................
   416    418           sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i);
   417    419           sqlite3ColumnDefault(v, pTab, i, regNew+i);
   418    420         }else{
   419    421           sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
   420    422         }
   421    423       }
   422    424     }
          425  +
          426  +  /* If this is not a view, create the record that will be inserted into
          427  +  ** the table (assuming no constraint checks fail). A side effect of
          428  +  ** creating the record is applying affinity transformations to the
          429  +  ** array of registers populated by the block above. This needs to be
          430  +  ** done before the BEFORE triggers are fired.  */
          431  +#if 0
          432  +  if( !isView ){
          433  +    sqlite3VdbeAddOp3(v, OP_MakeRecord, regNew, pTab->nCol, regRec);
          434  +    sqlite3TableAffinityStr(v, pTab);
          435  +    sqlite3ExprCacheAffinityChange(pParse, regNew, pTab->nCol);
          436  +  }
          437  +#endif
   423    438   
   424    439     /* Fire any BEFORE UPDATE triggers. This happens before constraints are
   425    440     ** verified. One could argue that this is wrong.  */
   426    441     sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, 
   427         -      TRIGGER_BEFORE, pTab, regNew, regOld, onError, addr);
          442  +      TRIGGER_BEFORE, pTab, -1, regOldRowid, onError, addr);
   428    443   
   429    444     if( !isView ){
   430    445   
   431    446       /* Do constraint checks. */
   432    447       sqlite3GenerateConstraintChecks(pParse, pTab, iCur, regNewRowid,
   433         -        aRegIdx, chngRowid, 1, onError, addr, 0);
          448  +        aRegIdx, (chngRowid?regOldRowid:0), 1, onError, addr, 0);
   434    449   
   435    450       /* Delete the index entries associated with the current record.  */
   436    451       j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid);
   437    452       sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);
   438    453     
   439    454       /* If changing the record number, delete the old record.  */
   440    455       if( chngRowid ){
   441    456         sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0);
   442    457       }
   443    458       sqlite3VdbeJumpHere(v, j1);
   444    459     
   445         -    /* Create the new index entries and the new record.  */
   446         -    sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, aRegIdx,1,-1,0,0);
          460  +    /* Insert the new index entries and the new record. */
          461  +    sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, aRegIdx, 1, -1, 0, 0);
          462  +
          463  +#if 0
          464  +    for(i=0; i<nIdx; i++){
          465  +      if( aRegIdx[i] ){
          466  +        sqlite3VdbeAddOp2(v, OP_IdxInsert, iCur+1+i, aRegIdx[i]);
          467  +      }
          468  +    }
          469  +    sqlite3VdbeAddOp3(v, OP_Insert, iCur, regRec, regNewRowid);
          470  +    if( !pParse->nested ){
          471  +      sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
          472  +      sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_ISUPDATE);
          473  +    }
          474  +#endif
   447    475     }
   448    476   
   449    477     /* Increment the row counter 
   450    478     */
   451    479     if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){
   452    480       sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
   453    481     }
   454    482   
   455    483     sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, 
   456         -      TRIGGER_AFTER, pTab, regNew, regOld, onError, addr);
          484  +      TRIGGER_AFTER, pTab, -1, regOldRowid, onError, addr);
   457    485   
   458    486     /* Repeat the above with the next record to be updated, until
   459    487     ** all record selected by the WHERE clause have been updated.
   460    488     */
   461    489     sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
   462    490     sqlite3VdbeJumpHere(v, addr);
   463    491   

Changes to src/vdbe.c.

   848    848   case OP_Halt: {
   849    849     if( pOp->p1==SQLITE_OK && p->pFrame ){
   850    850       VdbeFrame *pFrame = p->pFrame;
   851    851       p->pFrame = pFrame->pParent;
   852    852       p->nFrame--;
   853    853       pc = sqlite3VdbeFrameRestore(pFrame);
   854    854       if( pOp->p2==OE_Ignore ){
          855  +      pc = p->aOp[pc].p2-1;
   855    856       }
   856    857       break;
   857    858     }
   858    859     p->rc = pOp->p1;
   859    860     p->errorAction = (u8)pOp->p2;
   860    861     p->pc = pc;
   861    862     if( pOp->p4.z ){
................................................................................
  3542   3543   /* Opcode: NewRowid P1 P2 P3 * *
  3543   3544   **
  3544   3545   ** Get a new integer record number (a.k.a "rowid") used as the key to a table.
  3545   3546   ** The record number is not previously used as a key in the database
  3546   3547   ** table that cursor P1 points to.  The new record number is written
  3547   3548   ** written to register P2.
  3548   3549   **
  3549         -** If P3>0 then P3 is a register that holds the largest previously
  3550         -** generated record number.  No new record numbers are allowed to be less
  3551         -** than this value.  When this value reaches its maximum, a SQLITE_FULL
  3552         -** error is generated.  The P3 register is updated with the generated
  3553         -** record number.  This P3 mechanism is used to help implement the
         3550  +** If P3>0 then P3 is a register in the root frame of this VDBE that holds 
         3551  +** the largest previously generated record number. No new record numbers are
         3552  +** allowed to be less than this value. When this value reaches its maximum, 
         3553  +** a SQLITE_FULL error is generated. The P3 register is updated with the '
         3554  +** generated record number. This P3 mechanism is used to help implement the
  3554   3555   ** AUTOINCREMENT feature.
  3555   3556   */
  3556   3557   case OP_NewRowid: {           /* out2-prerelease */
  3557   3558     i64 v;                 /* The new rowid */
  3558   3559     VdbeCursor *pC;        /* Cursor of table to get the new rowid */
  3559   3560     int res;               /* Result of an sqlite3BtreeLast() */
  3560   3561     int cnt;               /* Counter to limit the number of searches */
  3561   3562     Mem *pMem;             /* Register holding largest rowid for AUTOINCREMENT */
         3563  +  VdbeFrame *pFrame;     /* Root frame of VDBE */
  3562   3564   
  3563   3565     v = 0;
  3564   3566     res = 0;
  3565   3567     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  3566   3568     pC = p->apCsr[pOp->p1];
  3567   3569     assert( pC!=0 );
  3568   3570     if( NEVER(pC->pCursor==0) ){
................................................................................
  3613   3615               v++;
  3614   3616             }
  3615   3617           }
  3616   3618         }
  3617   3619   
  3618   3620   #ifndef SQLITE_OMIT_AUTOINCREMENT
  3619   3621         if( pOp->p3 ){
  3620         -        assert( pOp->p3>0 && pOp->p3<=p->nMem ); /* P3 is a valid memory cell */
  3621         -        pMem = &p->aMem[pOp->p3];
  3622         -	REGISTER_TRACE(pOp->p3, pMem);
         3622  +        if( p->pFrame ){
         3623  +          for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
         3624  +          pMem = &pFrame->aMem[pOp->p3];
         3625  +        }else{
         3626  +          pMem = &p->aMem[pOp->p3];
         3627  +        }
         3628  +        /* Assert that P3 is a valid memory cell. */
         3629  +        assert( pOp->p3>0 && pOp->p3<=(p->pFrame ? pFrame->nMem : p->nMem) );
         3630  +
         3631  +        REGISTER_TRACE(pOp->p3, pMem);
  3623   3632           sqlite3VdbeMemIntegerify(pMem);
  3624   3633           assert( (pMem->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
  3625   3634           if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
  3626   3635             rc = SQLITE_FULL;
  3627   3636             goto abort_due_to_error;
  3628   3637           }
  3629   3638           if( v<pMem->u.i+1 ){
................................................................................
  4736   4745       sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
  4737   4746     }
  4738   4747     break;
  4739   4748   }
  4740   4749   
  4741   4750   
  4742   4751   #ifndef SQLITE_OMIT_TRIGGER
  4743         -/* Opcode: ContextPush * * * 
  4744         -**
  4745         -** Save the current Vdbe context such that it can be restored by a ContextPop
  4746         -** opcode. The context stores the last insert row id, the last statement change
  4747         -** count, and the current statement change count.
  4748         -*/
  4749         -case OP_ContextPush: {
  4750         -  int i;
  4751         -  Context *pContext;
  4752         -
  4753         -  i = p->contextStackTop++;
  4754         -  assert( i>=0 );
  4755         -  /* FIX ME: This should be allocated as part of the vdbe at compile-time */
  4756         -  if( i>=p->contextStackDepth ){
  4757         -    p->contextStackDepth = i+1;
  4758         -    p->contextStack = sqlite3DbReallocOrFree(db, p->contextStack,
  4759         -                                          sizeof(Context)*(i+1));
  4760         -    if( p->contextStack==0 ) goto no_mem;
  4761         -  }
  4762         -  pContext = &p->contextStack[i];
  4763         -  pContext->lastRowid = db->lastRowid;
  4764         -  pContext->nChange = p->nChange;
  4765         -  break;
  4766         -}
  4767         -
  4768         -/* Opcode: ContextPop * * * 
  4769         -**
  4770         -** Restore the Vdbe context to the state it was in when contextPush was last
  4771         -** executed. The context stores the last insert row id, the last statement
  4772         -** change count, and the current statement change count.
  4773         -*/
  4774         -case OP_ContextPop: {
  4775         -  Context *pContext;
  4776         -  pContext = &p->contextStack[--p->contextStackTop];
  4777         -  assert( p->contextStackTop>=0 );
  4778         -  db->lastRowid = pContext->lastRowid;
  4779         -  p->nChange = pContext->nChange;
  4780         -  break;
  4781         -}
  4782   4752   
  4783   4753   /* Opcode: Program P1 P2 P3 P4 *
  4784   4754   **
  4785         -** Execute a trigger program. P1 contains the address of the memory cell
  4786         -** that contains the left-most column of the old.* table (unless the trigger
  4787         -** program is firing as a result of an INSERT statement). P2 is the address 
  4788         -** of the corresponding column in the new.* table (unless the trigger 
  4789         -** program is being fired due to a DELETE).
         4755  +** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). 
  4790   4756   **
  4791         -** Register P3 contains the address of a memory cell in this (the parent)
  4792         -** VM that is used to allocate the memory required by the sub-vdbe at 
  4793         -** runtime.
         4757  +** P1 contains the address of the memory cell that contains the first memory 
         4758  +** cell in an array of values used as arguments to the sub-program. P2 
         4759  +** contains the address to jump to if the sub-program throws an IGNORE 
         4760  +** exception using the RAISE() function. Register P3 contains the address 
         4761  +** of a memory cell in this (the parent) VM that is used to allocate the 
         4762  +** memory required by the sub-vdbe at runtime.
  4794   4763   **
  4795   4764   ** P4 is a pointer to the VM containing the trigger program.
  4796   4765   */
  4797         -case OP_Program: {
         4766  +case OP_Program: {        /* jump */
  4798   4767     VdbeFrame *pFrame;
  4799   4768     SubProgram *pProgram = pOp->p4.pProgram;
  4800   4769     Mem *pRt = &p->aMem[pOp->p3];        /* Register to allocate runtime space */
  4801   4770     assert( pProgram->nOp>0 );
  4802   4771     
  4803         -  /* If noRecTrigger is true, then recursive invocation of triggers is
  4804         -  ** disabled for backwards compatibility. 
         4772  +  /* If the SQLITE_NoRecTriggers flag it set, then recursive invocation of
         4773  +  ** triggers is disabled for backwards compatibility (flag set/cleared by
         4774  +  ** the "PRAGMA disable_recursive_triggers" command). 
  4805   4775     ** 
  4806   4776     ** It is recursive invocation of triggers, at the SQL level, that is 
  4807   4777     ** disabled. In some cases a single trigger may generate more than one 
  4808   4778     ** SubProgram (if the trigger may be executed with more than one different 
  4809   4779     ** ON CONFLICT algorithm). SubProgram structures associated with a
  4810   4780     ** single trigger all have the same value for the SubProgram.token 
  4811   4781     ** variable.
  4812   4782     */
  4813         -  if( 1 || p->noRecTrigger ){
         4783  +  if( db->flags&SQLITE_NoRecTriggers ){
  4814   4784       void *t = pProgram->token;
  4815   4785       for(pFrame=p->pFrame; pFrame && pFrame->token!=t; pFrame=pFrame->pParent);
  4816   4786       if( pFrame ) break;
  4817   4787     }
  4818   4788   
  4819   4789     /* TODO: This constant should be configurable. */
  4820   4790     if( p->nFrame>1000 ){
................................................................................
  4870   4840       assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
  4871   4841       assert( pProgram->nCsr==pFrame->nChildCsr );
  4872   4842       assert( pc==pFrame->pc );
  4873   4843     }
  4874   4844   
  4875   4845     p->nFrame++;
  4876   4846     pFrame->pParent = p->pFrame;
         4847  +  pFrame->lastRowid = db->lastRowid;
         4848  +  pFrame->nChange = p->nChange;
  4877   4849     p->pFrame = pFrame;
  4878   4850     p->aMem = &VdbeFrameMem(pFrame)[-1];
  4879   4851     p->nMem = pFrame->nChildMem;
  4880   4852     p->nCursor = pFrame->nChildCsr;
  4881   4853     p->apCsr = (VdbeCursor **)&p->aMem[p->nMem+1];
  4882   4854     p->aOp = pProgram->aOp;
  4883   4855     p->nOp = pProgram->nOp;
  4884   4856     pc = -1;
  4885   4857   
  4886   4858     break;
  4887   4859   }
  4888   4860   
  4889         -/* Opcode: TriggerVal P1 P2 P3 * *
         4861  +/* Opcode: Param P1 P2 * * *
  4890   4862   **
  4891         -** Copy a value currently stored in a memory cell of the parent VM to
  4892         -** a cell in this VMs address space. This is used by trigger programs
  4893         -** to access the new.* and old.* values.
         4863  +** This opcode is only ever present in sub-programs called via the 
         4864  +** OP_Program instruction. Copy a value currently stored in a memory 
         4865  +** cell of the calling (parent) frame to cell P2 in the current frames 
         4866  +** address space. This is used by trigger programs to access the new.* 
         4867  +** and old.* values.
  4894   4868   **
  4895         -** If parameter P3 is non-zero, then the value read is from the new.*
  4896         -** table. If P3 is zero, then the value is read from the old.* table.
  4897         -** Parameter P1 is the index of the required new.* or old.* column (or
  4898         -** -1 for rowid). 
  4899         -**
  4900         -** Parameter P2 is the index of the memory cell in this VM to copy the 
  4901         -** value to.
         4869  +** The address of the cell in the parent frame is determined by adding
         4870  +** the value of the P1 argument to the value of the P1 argument to the
         4871  +** calling OP_Program instruction.
  4902   4872   */
  4903         -case OP_TriggerVal: {           /* out2-prerelease */
  4904         -  VdbeFrame *pF = p->pFrame;
  4905         -  Mem *pIn;
  4906         -  int iFrom = pOp->p1;           /* Memory cell in parent frame */
  4907         -  iFrom += (pOp->p3 ? pF->aOp[pF->pc].p2 : pF->aOp[pF->pc].p1);
  4908         -  pIn = &pF->aMem[iFrom];
         4873  +case OP_Param: {           /* out2-prerelease */
         4874  +  VdbeFrame *pFrame = p->pFrame;
         4875  +  Mem *pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1];   
  4909   4876     sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem);
  4910   4877     break;
  4911   4878   }
  4912   4879   
  4913   4880   #endif /* #ifndef SQLITE_OMIT_TRIGGER */
  4914   4881   
  4915   4882   #ifndef SQLITE_OMIT_AUTOINCREMENT
  4916   4883   /* Opcode: MemMax P1 P2 * * *
  4917   4884   **
  4918         -** Set the value of register P1 to the maximum of its current value
  4919         -** and the value in register P2.
         4885  +** P1 is a register in the root frame of this VM (the root frame is
         4886  +** different from the current frame if this instruction is being executed
         4887  +** within a sub-program). Set the value of register P1 to the maximum of 
         4888  +** its current value and the value in register P2.
  4920   4889   **
  4921   4890   ** This instruction throws an error if the memory cell is not initially
  4922   4891   ** an integer.
  4923   4892   */
  4924         -case OP_MemMax: {        /* in1, in2 */
         4893  +case OP_MemMax: {        /* in2 */
         4894  +  Mem *pIn1;
         4895  +  VdbeFrame *pFrame;
         4896  +  if( p->pFrame ){
         4897  +    for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
         4898  +    pIn1 = &pFrame->aMem[pOp->p1];
         4899  +  }else{
         4900  +    pIn1 = &p->aMem[pOp->p1];
         4901  +  }
  4925   4902     sqlite3VdbeMemIntegerify(pIn1);
  4926   4903     sqlite3VdbeMemIntegerify(pIn2);
  4927   4904     if( pIn1->u.i<pIn2->u.i){
  4928   4905       pIn1->u.i = pIn2->u.i;
  4929   4906     }
  4930   4907     break;
  4931   4908   }

Changes to src/vdbeInt.h.

    99     99     int nMem;               /* Number of entries in aMem */
   100    100     VdbeCursor **apCsr;     /* Element of Vdbe cursors */
   101    101     u16 nCursor;            /* Number of entries in apCsr */
   102    102     VdbeFrame *pParent;     /* Parent of this frame */
   103    103     void *token;            /* Copy of SubProgram.token */
   104    104     int nChildMem;          /* Number of memory cells for child frame */
   105    105     int nChildCsr;          /* Number of cursors for child frame */
          106  +  i64 lastRowid;    /* Last insert rowid (sqlite3.lastRowid) */
          107  +  int nChange;      /* Statement changes (Vdbe.nChanges)     */
   106    108   };
   107    109   
   108    110   #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
   109    111   
   110    112   /*
   111    113   ** A value for VdbeCursor.cacheValid that means the cache is always invalid.
   112    114   */
................................................................................
   239    241   */
   240    242   typedef struct Set Set;
   241    243   struct Set {
   242    244     Hash hash;             /* A set is just a hash table */
   243    245     HashElem *prev;        /* Previously accessed hash elemen */
   244    246   };
   245    247   
   246         -/*
   247         -** A Context stores the last insert rowid, the last statement change count,
   248         -** and the current statement change count (i.e. changes since last statement).
   249         -** The current keylist is also stored in the context.
   250         -** Elements of Context structure type make up the ContextStack, which is
   251         -** updated by the ContextPush and ContextPop opcodes (used by triggers).
   252         -** The context is pushed before executing a trigger a popped when the
   253         -** trigger finishes.
   254         -*/
   255         -typedef struct Context Context;
   256         -struct Context {
   257         -  i64 lastRowid;    /* Last insert rowid (sqlite3.lastRowid) */
   258         -  int nChange;      /* Statement changes (Vdbe.nChanges)     */
   259         -};
   260         -
   261    248   /*
   262    249   ** An instance of the virtual machine.  This structure contains the complete
   263    250   ** state of the virtual machine.
   264    251   **
   265    252   ** The "sqlite3_stmt" structure pointer that is returned by sqlite3_compile()
   266    253   ** is really a pointer to an instance of this structure.
   267    254   **
................................................................................
   293    280     u16 nVar;               /* Number of entries in aVar[] */
   294    281     Mem *aVar;              /* Values for the OP_Variable opcode. */
   295    282     char **azVar;           /* Name of variables */
   296    283     u32 magic;              /* Magic number for sanity checking */
   297    284     int nMem;               /* Number of memory locations currently allocated */
   298    285     Mem *aMem;              /* The memory locations */
   299    286     int cacheCtr;           /* VdbeCursor row cache generation counter */
   300         -  int contextStackTop;    /* Index of top element in the context stack */
   301         -  int contextStackDepth;  /* The size of the "context" stack */
   302         -  Context *contextStack;  /* Stack used by opcodes ContextPush & ContextPop*/
   303    287     int pc;                 /* The program counter */
   304    288     int rc;                 /* Value to return */
   305    289     char *zErrMsg;          /* Error message written here */
   306    290     u8 explain;             /* True if EXPLAIN present on SQL command */
   307    291     u8 changeCntOn;         /* True to update the change-counter */
   308    292     u8 expired;             /* True if the VM needs to be recompiled */
   309    293     u8 minWriteFileFormat;  /* Minimum file format for writable database files */

Changes to src/vdbeaux.c.

   291    291         hasStatementBegin = 1;
   292    292         p->usesStmtJournal = 1;
   293    293       }else if( opcode==OP_Destroy ){
   294    294         doesStatementRollback = 1;
   295    295       }else if( opcode==OP_Transaction && pOp->p2!=0 ){
   296    296         p->readOnly = 0;
   297    297   #ifndef SQLITE_OMIT_VIRTUALTABLE
   298         -    }else if( opcode==OP_VUpdate || opcode==OP_VRename ){
          298  +    }else if( opcode==OP_VUpdate || opcode==OP_VRename || opcode==OP_Program ){
   299    299         doesStatementRollback = 1;
   300    300       }else if( opcode==OP_VFilter ){
   301    301         int n;
   302    302         assert( p->nOp - i >= 3 );
   303    303         assert( pOp[-1].opcode==OP_Integer );
   304    304         n = pOp[-1].p1;
   305    305         if( n>nMaxArgs ) nMaxArgs = n;
................................................................................
  1332   1332     Vdbe *v = pFrame->v;
  1333   1333     v->aOp = pFrame->aOp;
  1334   1334     v->nOp = pFrame->nOp;
  1335   1335     v->aMem = pFrame->aMem;
  1336   1336     v->nMem = pFrame->nMem;
  1337   1337     v->apCsr = pFrame->apCsr;
  1338   1338     v->nCursor = pFrame->nCursor;
         1339  +  v->db->lastRowid = pFrame->lastRowid;
         1340  +  v->nChange = pFrame->nChange;
  1339   1341     return pFrame->pc;
  1340   1342   }
  1341   1343   
  1342   1344   /*
  1343   1345   ** Close all cursors. 
  1344   1346   **
  1345   1347   ** Also release any dynamic memory held by the VM in the Vdbe.aMem memory 
................................................................................
  1383   1385     /* Execute assert() statements to ensure that the Vdbe.apCsr[] and 
  1384   1386     ** Vdbe.aMem[] arrays have already been cleaned up.  */
  1385   1387     int i;
  1386   1388     for(i=0; i<p->nCursor; i++){ assert( p->apCsr[i]==0 ); }
  1387   1389     for(i=1; i<=p->nMem; i++){ assert( p->aMem[i].flags==MEM_Null ); }
  1388   1390   #endif
  1389   1391   
  1390         -  if( p->contextStack ){
  1391         -    sqlite3DbFree(db, p->contextStack);
  1392         -  }
  1393         -  p->contextStack = 0;
  1394         -  p->contextStackDepth = 0;
  1395         -  p->contextStackTop = 0;
  1396   1392     sqlite3DbFree(db, p->zErrMsg);
  1397   1393     p->zErrMsg = 0;
  1398   1394     p->pResultSet = 0;
  1399   1395   }
  1400   1396   
  1401   1397   /*
  1402   1398   ** Set the number of result columns that will be returned by this SQL

Changes to test/autoinc.test.

   553    553       INSERT INTO t2 VALUES(NULL, 1);
   554    554       CREATE TABLE t3(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
   555    555       INSERT INTO t3 SELECT * FROM t2 WHERE y>1;
   556    556   
   557    557       SELECT * FROM sqlite_sequence WHERE name='t3';
   558    558     }
   559    559   } {t3 0}
          560  +
          561  +catchsql { pragma disable_recursive_triggers = 1 } 
   560    562   
   561    563   # Ticket #3928.  Make sure that triggers to not make extra slots in
   562    564   # the SQLITE_SEQUENCE table.
   563    565   #
   564    566   do_test autoinc-3928.1 {
   565    567     db eval {
   566    568       CREATE TABLE t3928(a INTEGER PRIMARY KEY AUTOINCREMENT, b);

Changes to test/misc2.test.

    14     14   # left out of other test files.
    15     15   #
    16     16   # $Id: misc2.test,v 1.28 2007/09/12 17:01:45 danielk1977 Exp $
    17     17   
    18     18   set testdir [file dirname $argv0]
    19     19   source $testdir/tester.tcl
    20     20   
           21  +# The tests in this file were written before SQLite supported recursive
           22  +# trigger invocation, and some tests depend on that to pass. So disable
           23  +# recursive triggers for this file.
           24  +catchsql { pragma disable_recursive_triggers = 1 } 
           25  +
    21     26   ifcapable {trigger} {
    22     27   # Test for ticket #360
    23     28   #
    24     29   do_test misc2-1.1 {
    25     30     catchsql {
    26     31       CREATE TABLE FOO(bar integer);
    27     32       CREATE TRIGGER foo_insert BEFORE INSERT ON foo BEGIN
................................................................................
   354    359       execsql {SELECT * FROM t1}
   355    360     } {1 2 3 4 5 6 7 8 9 10}
   356    361   }
   357    362   
   358    363   db close
   359    364   file delete -force test.db
   360    365   sqlite3 db test.db
          366  +catchsql { pragma disable_recursive_triggers = 1 } 
   361    367   
   362    368   # Ticket #453.  If the SQL ended with "-", the tokenizer was calling that
   363    369   # an incomplete token, which caused problem.  The solution was to just call
   364    370   # it a minus sign.
   365    371   #
   366    372   do_test misc2-8.1 {
   367    373     catchsql {-}

Changes to test/tkt3731.test.

    13     13   
    14     14   set testdir [file dirname $argv0]
    15     15   source $testdir/tester.tcl
    16     16   ifcapable {!trigger} {
    17     17     finish_test
    18     18     return
    19     19   }
           20  +
           21  +# The tests in this file were written before SQLite supported recursive
           22  +# trigger invocation, and some tests depend on that to pass. So disable
           23  +# recursive triggers for this file.
           24  +catchsql { pragma disable_recursive_triggers = 1 } 
    20     25   
    21     26   do_test tkt3731-1.1 {
    22     27     execsql {
    23     28       CREATE TABLE t1(a PRIMARY KEY, b);
    24     29       CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
    25     30         INSERT INTO t1 VALUES(new.a || '+', new.b || '+');
    26     31       END;

Changes to test/tkt3992.test.

    25     25       CREATE TABLE parameters2(
    26     26          mountcnt    INT NOT NULL CHECK (typeof(mountcnt) == 'integer'),
    27     27          version     REAL CHECK (typeof(version) == 'real')
    28     28       );
    29     29       INSERT INTO parameters2(mountcnt, version) VALUES(1, 1.0);
    30     30     }
    31     31   } {}
           32  +puts [execsql { SELECT *,typeof(mountcnt),typeof(version) FROM parameters1 }]
    32     33   
    33     34   do_test tkt3992-1.2 {
    34     35     execsql {
    35     36       UPDATE parameters1 SET mountcnt = mountcnt + 1;
    36     37       SELECT * FROM parameters1;
    37     38     }
    38     39   } {2 1.0}
    39     40   
    40     41   do_test tkt3992-1.3 {
           42  +    explain { UPDATE parameters2 SET mountcnt = mountcnt + 1 }
           43  +breakpoint
    41     44     execsql {
           45  +  pragma vdbe_trace = 1;
    42     46       UPDATE parameters2 SET mountcnt = mountcnt + 1;
           47  +  pragma vdbe_trace = 0;
    43     48       SELECT * FROM parameters2;
    44     49     }
    45     50   } {2 1.0}
    46     51   
    47     52   do_test tkt3992-2.1 {
    48     53     execsql {
    49     54       CREATE TABLE t1(a, b);
................................................................................
    68     73         SELECT tcl('set res', typeof(new.c));
    69     74       END;
    70     75   
    71     76       UPDATE t2 SET a = 'I';
    72     77     }
    73     78     set res
    74     79   } {real}
    75         -explain {
    76         -    UPDATE t2 SET a = 'I';
    77         -}
    78     80   
    79     81   
    80     82   finish_test

Changes to test/trigger2.test.

    49     49   
    50     50   set testdir [file dirname $argv0]
    51     51   source $testdir/tester.tcl
    52     52   ifcapable {!trigger} {
    53     53     finish_test
    54     54     return
    55     55   }
           56  +
           57  +# The tests in this file were written before SQLite supported recursive
           58  +# trigger invocation, and some tests depend on that to pass. So disable
           59  +# recursive triggers for this file.
           60  +catchsql { pragma disable_recursive_triggers = 1 } 
    56     61   
    57     62   # 1.
    58     63   ifcapable subquery {
    59     64     set ii 0
    60     65     set tbl_definitions [list \
    61     66     	{CREATE TABLE tbl (a, b);}                                      \
    62     67     	{CREATE TABLE tbl (a INTEGER PRIMARY KEY, b);}                  \

Changes to test/trigger3.test.

    13     13   
    14     14   set testdir [file dirname $argv0]
    15     15   source $testdir/tester.tcl
    16     16   ifcapable {!trigger} {
    17     17     finish_test
    18     18     return
    19     19   }
           20  +
           21  +# The tests in this file were written before SQLite supported recursive }
           22  +# trigger invocation, and some tests depend on that to pass. So disable
           23  +# recursive triggers for this file.
           24  +catchsql { pragma disable_recursive_triggers = 1 } 
    20     25   
    21     26   # Test that we can cause ROLLBACK, FAIL and ABORT correctly
    22         -# catchsql { DROP TABLE tbl; }
    23         -catchsql { CREATE TABLE tbl (a, b, c) }
    24         -
           27  +#
           28  +catchsql { CREATE TABLE tbl(a, b ,c) }
    25     29   execsql {
    26     30       CREATE TRIGGER before_tbl_insert BEFORE INSERT ON tbl BEGIN SELECT CASE 
    27     31   	WHEN (new.a = 4) THEN RAISE(IGNORE) END;
    28     32       END;
    29     33   
    30     34       CREATE TRIGGER after_tbl_insert AFTER INSERT ON tbl BEGIN SELECT CASE 
    31     35   	WHEN (new.a = 1) THEN RAISE(ABORT,    'Trigger abort') 
................................................................................
    50     54   do_test trigger3-1.3 {
    51     55       execsql {SELECT * FROM tbl}
    52     56   } {}
    53     57   
    54     58   # FAIL
    55     59   do_test trigger3-2.1 {
    56     60       catchsql {
    57         -	BEGIN;
           61  +        BEGIN;
    58     62           INSERT INTO tbl VALUES (5, 5, 6);
    59     63           INSERT INTO tbl VALUES (2, 5, 6);
    60     64       }
    61     65   } {1 {Trigger fail}}
    62     66   do_test trigger3-2.2 {
    63     67       execsql {
    64     68   	SELECT * FROM tbl;

Changes to test/trigger9.test.

    71     71         END;
    72     72         DELETE FROM t1;
    73     73         SELECT * FROM t2;
    74     74     }
    75     75   } {1 2 3}
    76     76   do_test trigger9-1.3.2 {
    77     77     has_rowdata {DELETE FROM t1}
    78         -} 1
           78  +} 0
    79     79   do_test trigger9-1.3.3 { execsql { ROLLBACK } } {}
    80     80   
    81     81   do_test trigger9-1.4.1 {
    82     82     execsql {
    83     83       BEGIN;
    84     84         CREATE TRIGGER trig1 BEFORE DELETE ON t1 WHEN old.x='1' BEGIN
    85     85           INSERT INTO t2 VALUES(old.rowid);
................................................................................
    86     86         END;
    87     87         DELETE FROM t1;
    88     88         SELECT * FROM t2;
    89     89     }
    90     90   } {1}
    91     91   do_test trigger9-1.4.2 {
    92     92     has_rowdata {DELETE FROM t1}
    93         -} 1
           93  +} 0
    94     94   do_test trigger9-1.4.3 { execsql { ROLLBACK } } {}
    95     95   
    96     96   do_test trigger9-1.5.1 {
    97     97     execsql {
    98     98       BEGIN;
    99     99         CREATE TRIGGER trig1 BEFORE UPDATE ON t1 BEGIN
   100    100           INSERT INTO t2 VALUES(old.rowid);
................................................................................
   116    116         END;
   117    117         UPDATE t1 SET y = '';
   118    118         SELECT * FROM t2;
   119    119     }
   120    120   } {1 2 3}
   121    121   do_test trigger9-1.6.2 {
   122    122     has_rowdata {UPDATE t1 SET y = ''}
   123         -} 1
          123  +} 0
   124    124   do_test trigger9-1.6.3 { execsql { ROLLBACK } } {}
   125    125   
   126    126   do_test trigger9-1.7.1 {
   127    127     execsql {
   128    128       BEGIN;
   129    129         CREATE TRIGGER trig1 BEFORE UPDATE ON t1 WHEN old.x>='2' BEGIN
   130    130           INSERT INTO t2 VALUES(old.x);
................................................................................
   131    131         END;
   132    132         UPDATE t1 SET y = '';
   133    133         SELECT * FROM t2;
   134    134     }
   135    135   } {2 3}
   136    136   do_test trigger9-1.7.2 {
   137    137     has_rowdata {UPDATE t1 SET y = ''}
   138         -} 1
          138  +} 0
   139    139   do_test trigger9-1.7.3 { execsql { ROLLBACK } } {}
   140    140   
   141    141   do_test trigger9-3.1 {
   142    142     execsql {
   143    143       CREATE TABLE t3(a, b);
   144    144       INSERT INTO t3 VALUES(1, 'one');
   145    145       INSERT INTO t3 VALUES(2, 'two');