/ Check-in [1a360da0]
Login

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

Overview
Comment:Merge the latest trunk changes into tree-explain branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tree-explain
Files: files | file ages | folders
SHA1:1a360da0f8314f232c224c71829646bc7558892b
User & Date: drh 2011-12-10 14:44:31
Context
2011-12-10
15:55
Import the experimental parse-tree explainer, with fixes, from the tree-explain branch. Disabled by default. Use SQLITE_ENABLE_TREE_EXPLAIN to turn it on. check-in: bcbc7152 user: drh tags: trunk
14:44
Merge the latest trunk changes into tree-explain branch. Closed-Leaf check-in: 1a360da0 user: drh tags: tree-explain
13:49
Always use _msize() to get memory allocation sizes on windows, without having to do anything special in the makefile. check-in: 256e27bd user: drh tags: trunk
2011-12-07
22:49
Additional detail added to the tree-explain output for SELECT statements. check-in: 7b457ea4 user: drh tags: tree-explain
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.msc.

    45     45   
    46     46   # C Compile and options for use in building executables that
    47     47   # will run on the target platform.  (BCC and TCC are usually the
    48     48   # same unless your are cross-compiling.)
    49     49   #
    50     50   TCC = cl.exe -W3 -DSQLITE_OS_WIN=1 -I. -I$(TOP)\src -fp:precise
    51     51   
    52         -# We always have the _msize function available when using MSVC.
    53         -TCC = $(TCC) -DHAVE_MALLOC_USABLE_SIZE -Dmalloc_usable_size=_msize
    54         -
    55     52   # The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in 
    56     53   # any extension header files by default.  For non-amalgamation
    57     54   # builds, we need to make sure the compiler can find these.
    58     55   #
    59     56   !IF $(USE_AMALGAMATION)==0
    60     57   TCC = $(TCC) -I$(TOP)\ext\fts3
    61     58   TCC = $(TCC) -I$(TOP)\ext\rtree

Changes to src/expr.c.

  1370   1370     if( IsVirtual(pTab) ) return 0;        /* FROM clause not a virtual table */
  1371   1371     pEList = p->pEList;
  1372   1372     if( pEList->nExpr!=1 ) return 0;       /* One column in the result set */
  1373   1373     if( pEList->a[0].pExpr->op!=TK_COLUMN ) return 0; /* Result is a column */
  1374   1374     return 1;
  1375   1375   }
  1376   1376   #endif /* SQLITE_OMIT_SUBQUERY */
         1377  +
         1378  +/*
         1379  +** Code an OP_Once instruction and allocate space for its flag. Return the 
         1380  +** address of the new instruction.
         1381  +*/
         1382  +int sqlite3CodeOnce(Parse *pParse){
         1383  +  Vdbe *v = sqlite3GetVdbe(pParse);      /* Virtual machine being coded */
         1384  +  return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++);
         1385  +}
  1377   1386   
  1378   1387   /*
  1379   1388   ** This function is used by the implementation of the IN (...) operator.
  1380   1389   ** It's job is to find or create a b-tree structure that may be used
  1381   1390   ** either to test for membership of the (...) set or to iterate through
  1382   1391   ** its members, skipping duplicates.
  1383   1392   **
................................................................................
  1431   1440   */
  1432   1441   #ifndef SQLITE_OMIT_SUBQUERY
  1433   1442   int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
  1434   1443     Select *p;                            /* SELECT to the right of IN operator */
  1435   1444     int eType = 0;                        /* Type of RHS table. IN_INDEX_* */
  1436   1445     int iTab = pParse->nTab++;            /* Cursor of the RHS table */
  1437   1446     int mustBeUnique = (prNotFound==0);   /* True if RHS must be unique */
         1447  +  Vdbe *v = sqlite3GetVdbe(pParse);     /* Virtual machine being coded */
  1438   1448   
  1439   1449     assert( pX->op==TK_IN );
  1440   1450   
  1441   1451     /* Check to see if an existing table or index can be used to
  1442   1452     ** satisfy the query.  This is preferable to generating a new 
  1443   1453     ** ephemeral table.
  1444   1454     */
  1445   1455     p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
  1446   1456     if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
  1447   1457       sqlite3 *db = pParse->db;              /* Database connection */
  1448         -    Vdbe *v = sqlite3GetVdbe(pParse);      /* Virtual machine being coded */
  1449   1458       Table *pTab;                           /* Table <table>. */
  1450   1459       Expr *pExpr;                           /* Expression <column> */
  1451   1460       int iCol;                              /* Index of column <column> */
  1452   1461       int iDb;                               /* Database idx for pTab */
  1453   1462   
  1454   1463       assert( p );                        /* Because of isCandidateForInOpt(p) */
  1455   1464       assert( p->pEList!=0 );             /* Because of isCandidateForInOpt(p) */
................................................................................
  1466   1475   
  1467   1476       /* This function is only called from two places. In both cases the vdbe
  1468   1477       ** has already been allocated. So assume sqlite3GetVdbe() is always
  1469   1478       ** successful here.
  1470   1479       */
  1471   1480       assert(v);
  1472   1481       if( iCol<0 ){
  1473         -      int iMem = ++pParse->nMem;
  1474   1482         int iAddr;
  1475   1483   
  1476         -      iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem);
         1484  +      iAddr = sqlite3CodeOnce(pParse);
  1477   1485   
  1478   1486         sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
  1479   1487         eType = IN_INDEX_ROWID;
  1480   1488   
  1481   1489         sqlite3VdbeJumpHere(v, iAddr);
  1482   1490       }else{
  1483   1491         Index *pIdx;                         /* Iterator variable */
................................................................................
  1495   1503         int affinity_ok = (pTab->aCol[iCol].affinity==aff||aff==SQLITE_AFF_NONE);
  1496   1504   
  1497   1505         for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
  1498   1506           if( (pIdx->aiColumn[0]==iCol)
  1499   1507            && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
  1500   1508            && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
  1501   1509           ){
  1502         -          int iMem = ++pParse->nMem;
  1503   1510             int iAddr;
  1504   1511             char *pKey;
  1505   1512     
  1506   1513             pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx);
  1507         -          iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem);
         1514  +          iAddr = sqlite3CodeOnce(pParse);
  1508   1515     
  1509   1516             sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
  1510   1517                                  pKey,P4_KEYINFO_HANDOFF);
  1511   1518             VdbeComment((v, "%s", pIdx->zName));
  1512   1519             eType = IN_INDEX_INDEX;
  1513   1520   
  1514   1521             sqlite3VdbeJumpHere(v, iAddr);
  1515   1522             if( prNotFound && !pTab->aCol[iCol].notNull ){
  1516   1523               *prNotFound = ++pParse->nMem;
         1524  +            sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
  1517   1525             }
  1518   1526           }
  1519   1527         }
  1520   1528       }
  1521   1529     }
  1522   1530   
  1523   1531     if( eType==0 ){
................................................................................
  1525   1533       ** We will have to generate an ephemeral table to do the job.
  1526   1534       */
  1527   1535       double savedNQueryLoop = pParse->nQueryLoop;
  1528   1536       int rMayHaveNull = 0;
  1529   1537       eType = IN_INDEX_EPH;
  1530   1538       if( prNotFound ){
  1531   1539         *prNotFound = rMayHaveNull = ++pParse->nMem;
         1540  +      sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
  1532   1541       }else{
  1533   1542         testcase( pParse->nQueryLoop>(double)1 );
  1534   1543         pParse->nQueryLoop = (double)1;
  1535   1544         if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
  1536   1545           eType = IN_INDEX_ROWID;
  1537   1546         }
  1538   1547       }
................................................................................
  1597   1606     **    *  The right-hand side is a correlated subquery
  1598   1607     **    *  The right-hand side is an expression list containing variables
  1599   1608     **    *  We are inside a trigger
  1600   1609     **
  1601   1610     ** If all of the above are false, then we can run this code just once
  1602   1611     ** save the results, and reuse the same result on subsequent invocations.
  1603   1612     */
  1604         -  if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->pTriggerTab ){
  1605         -    int mem = ++pParse->nMem;
  1606         -    testAddr = sqlite3VdbeAddOp1(v, OP_Once, mem);
         1613  +  if( !ExprHasAnyProperty(pExpr, EP_VarSelect) ){
         1614  +    testAddr = sqlite3CodeOnce(pParse);
  1607   1615     }
  1608   1616   
  1609   1617   #ifndef SQLITE_OMIT_EXPLAIN
  1610   1618     if( pParse->explain==2 ){
  1611   1619       char *zMsg = sqlite3MPrintf(
  1612   1620           pParse->db, "EXECUTE %s%s SUBQUERY %d", testAddr>=0?"":"CORRELATED ",
  1613   1621           pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId

Changes to src/insert.c.

   235    235   
   236    236     assert( v );   /* We failed long ago if this is not so */
   237    237     for(p = pParse->pAinc; p; p = p->pNext){
   238    238       pDb = &db->aDb[p->iDb];
   239    239       memId = p->regCtr;
   240    240       assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
   241    241       sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
          242  +    sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1);
   242    243       addr = sqlite3VdbeCurrentAddr(v);
   243    244       sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0);
   244    245       sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9);
   245    246       sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId);
   246    247       sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId);
   247    248       sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
   248    249       sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);

Changes to src/mem1.c.

    22     22   /*
    23     23   ** This version of the memory allocator is the default.  It is
    24     24   ** used when no other memory allocator is specified using compile-time
    25     25   ** macros.
    26     26   */
    27     27   #ifdef SQLITE_SYSTEM_MALLOC
    28     28   
           29  +/*
           30  +** Windows systems have malloc_usable_size() but it is called _msize()
           31  +*/
           32  +#if !defined(HAVE_MALLOC_USABLE_SIZE) && SQLITE_OS_WIN
           33  +# define HAVE_MALLOC_USABLE_SIZE 1
           34  +# define malloc_usable_size _msize
           35  +#endif
           36  +
           37  +#if defined(__APPLE__)
           38  +
           39  +/*
           40  +** Use the zone allocator available on apple products
           41  +*/
           42  +#include <sys/sysctl.h>
           43  +#include <malloc/malloc.h>
           44  +#include <libkern/OSAtomic.h>
           45  +static malloc_zone_t* _sqliteZone_;
           46  +#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
           47  +#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
           48  +#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y))
           49  +#define SQLITE_MALLOCSIZE(x) \
           50  +        (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x))
           51  +
           52  +#else /* if not __APPLE__ */
           53  +
           54  +/*
           55  +** Use standard C library malloc and free on non-Apple systems.
           56  +*/
           57  +#define SQLITE_MALLOC(x)    malloc(x)
           58  +#define SQLITE_FREE(x)      free(x)
           59  +#define SQLITE_REALLOC(x,y) realloc((x),(y))
           60  +
    29     61   #ifdef HAVE_MALLOC_USABLE_SIZE
    30     62   #include <malloc.h>
           63  +#define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
           64  +#else
           65  +#undef SQLITE_MALLOCSIZE
    31     66   #endif
           67  +
           68  +#endif /* __APPLE__ or not __APPLE__ */
    32     69   
    33     70   /*
    34     71   ** Like malloc(), but remember the size of the allocation
    35     72   ** so that we can find it later using sqlite3MemSize().
    36     73   **
    37     74   ** For this low-level routine, we are guaranteed that nByte>0 because
    38     75   ** cases of nByte<=0 will be intercepted and dealt with by higher level
    39     76   ** routines.
    40     77   */
    41     78   static void *sqlite3MemMalloc(int nByte){
    42         -#ifdef HAVE_MALLOC_USABLE_SIZE
    43         -  void *p = malloc( nByte );
           79  +#ifdef SQLITE_MALLOCSIZE
           80  +  void *p = SQLITE_MALLOC( nByte );
    44     81     if( p==0 ){
    45     82       testcase( sqlite3GlobalConfig.xLog!=0 );
    46     83       sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
    47     84     }
    48     85     return p;
    49     86   #else
    50     87     sqlite3_int64 *p;
    51     88     assert( nByte>0 );
    52     89     nByte = ROUND8(nByte);
    53         -  p = malloc( nByte+8 );
           90  +  p = SQLITE_MALLOC( nByte+8 );
    54     91     if( p ){
    55     92       p[0] = nByte;
    56     93       p++;
    57     94     }else{
    58     95       testcase( sqlite3GlobalConfig.xLog!=0 );
    59     96       sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
    60     97     }
................................................................................
    67    104   ** or sqlite3MemRealloc().
    68    105   **
    69    106   ** For this low-level routine, we already know that pPrior!=0 since
    70    107   ** cases where pPrior==0 will have been intecepted and dealt with
    71    108   ** by higher-level routines.
    72    109   */
    73    110   static void sqlite3MemFree(void *pPrior){
    74         -#if HAVE_MALLOC_USABLE_SIZE
    75         -  free(pPrior);
          111  +#ifdef SQLITE_MALLOCSIZE
          112  +  SQLITE_FREE(pPrior);
    76    113   #else
    77    114     sqlite3_int64 *p = (sqlite3_int64*)pPrior;
    78    115     assert( pPrior!=0 );
    79    116     p--;
    80         -  free(p);
          117  +  SQLITE_FREE(p);
    81    118   #endif
    82    119   }
    83    120   
    84    121   /*
    85    122   ** Report the allocated size of a prior return from xMalloc()
    86    123   ** or xRealloc().
    87    124   */
    88    125   static int sqlite3MemSize(void *pPrior){
    89         -#if HAVE_MALLOC_USABLE_SIZE
    90         -  return pPrior ? (int)malloc_usable_size(pPrior) : 0;
          126  +#ifdef SQLITE_MALLOCSIZE
          127  +  return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0;
    91    128   #else
    92    129     sqlite3_int64 *p;
    93    130     if( pPrior==0 ) return 0;
    94    131     p = (sqlite3_int64*)pPrior;
    95    132     p--;
    96    133     return (int)p[0];
    97    134   #endif
................................................................................
   104    141   ** For this low-level interface, we know that pPrior!=0.  Cases where
   105    142   ** pPrior==0 while have been intercepted by higher-level routine and
   106    143   ** redirected to xMalloc.  Similarly, we know that nByte>0 becauses
   107    144   ** cases where nByte<=0 will have been intercepted by higher-level
   108    145   ** routines and redirected to xFree.
   109    146   */
   110    147   static void *sqlite3MemRealloc(void *pPrior, int nByte){
   111         -#if HAVE_MALLOC_USABLE_SIZE
   112         -  void *p = realloc(pPrior, nByte);
          148  +#ifdef SQLITE_MALLOCSIZE
          149  +  void *p = SQLITE_REALLOC(pPrior, nByte);
   113    150     if( p==0 ){
   114    151       testcase( sqlite3GlobalConfig.xLog!=0 );
   115    152       sqlite3_log(SQLITE_NOMEM,
   116    153         "failed memory resize %u to %u bytes",
   117         -      malloc_usable_size(pPrior), nByte);
          154  +      SQLITE_MALLOCSIZE(pPrior), nByte);
   118    155     }
   119    156     return p;
   120    157   #else
   121    158     sqlite3_int64 *p = (sqlite3_int64*)pPrior;
   122    159     assert( pPrior!=0 && nByte>0 );
   123    160     assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */
   124    161     p--;
   125         -  p = realloc(p, nByte+8 );
          162  +  p = SQLITE_REALLOC(p, nByte+8 );
   126    163     if( p ){
   127    164       p[0] = nByte;
   128    165       p++;
   129    166     }else{
   130    167       testcase( sqlite3GlobalConfig.xLog!=0 );
   131    168       sqlite3_log(SQLITE_NOMEM,
   132    169         "failed memory resize %u to %u bytes",
................................................................................
   143    180     return ROUND8(n);
   144    181   }
   145    182   
   146    183   /*
   147    184   ** Initialize this module.
   148    185   */
   149    186   static int sqlite3MemInit(void *NotUsed){
          187  +#if defined(__APPLE__)
          188  +  int cpuCount;
          189  +  size_t len;
          190  +  if( _sqliteZone_ ){
          191  +    return SQLITE_OK;
          192  +  }
          193  +  len = sizeof(cpuCount);
          194  +  /* One usually wants to use hw.acctivecpu for MT decisions, but not here */
          195  +  sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0);
          196  +  if( cpuCount>1 ){
          197  +    /* defer MT decisions to system malloc */
          198  +    _sqliteZone_ = malloc_default_zone();
          199  +  }else{
          200  +    /* only 1 core, use our own zone to contention over global locks, 
          201  +    ** e.g. we have our own dedicated locks */
          202  +    bool success;		
          203  +    malloc_zone_t* newzone = malloc_create_zone(4096, 0);
          204  +    malloc_set_zone_name(newzone, "Sqlite_Heap");
          205  +    do{
          206  +      success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, 
          207  +                                 (void * volatile *)&_sqliteZone_);
          208  +    }while(!_sqliteZone_);
          209  +    if( !success ){	
          210  +      /* somebody registered a zone first */
          211  +      malloc_destroy_zone(newzone);
          212  +    }
          213  +  }
          214  +#endif
   150    215     UNUSED_PARAMETER(NotUsed);
   151    216     return SQLITE_OK;
   152    217   }
   153    218   
   154    219   /*
   155    220   ** Deinitialize this module.
   156    221   */

Changes to src/os.h.

    60     60   #  define SQLITE_OS_OS2 0
    61     61   # endif
    62     62   #else
    63     63   # ifndef SQLITE_OS_WIN
    64     64   #  define SQLITE_OS_WIN 0
    65     65   # endif
    66     66   #endif
    67         -
    68         -/*
    69         -** Determine if we are dealing with WindowsCE - which has a much
    70         -** reduced API.
    71         -*/
    72         -#if defined(_WIN32_WCE)
    73         -# define SQLITE_OS_WINCE 1
    74         -#else
    75         -# define SQLITE_OS_WINCE 0
    76         -#endif
    77         -
    78     67   
    79     68   /*
    80     69   ** Define the maximum size of a temporary filename
    81     70   */
    82     71   #if SQLITE_OS_WIN
    83     72   # include <windows.h>
    84     73   # define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
................................................................................
    96     85   # include <os2.h>
    97     86   # include <uconv.h>
    98     87   # define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP)
    99     88   #else
   100     89   # define SQLITE_TEMPNAME_SIZE 200
   101     90   #endif
   102     91   
           92  +/*
           93  +** Determine if we are dealing with Windows NT.
           94  +*/
           95  +#if defined(_WIN32_WINNT)
           96  +# define SQLITE_OS_WINNT 1
           97  +#else
           98  +# define SQLITE_OS_WINNT 0
           99  +#endif
          100  +
          101  +/*
          102  +** Determine if we are dealing with WindowsCE - which has a much
          103  +** reduced API.
          104  +*/
          105  +#if defined(_WIN32_WCE)
          106  +# define SQLITE_OS_WINCE 1
          107  +#else
          108  +# define SQLITE_OS_WINCE 0
          109  +#endif
          110  +
   103    111   /* If the SET_FULLSYNC macro is not defined above, then make it
   104    112   ** a no-op
   105    113   */
   106    114   #ifndef SET_FULLSYNC
   107    115   # define SET_FULLSYNC(x,y)
   108    116   #endif
   109    117   

Changes to src/os_win.c.

   177    177   ** testing and sandboxing.  The following array holds the names and pointers
   178    178   ** to all overrideable system calls.
   179    179   */
   180    180   #if !SQLITE_OS_WINCE
   181    181   #  define SQLITE_WIN32_HAS_ANSI
   182    182   #endif
   183    183   
   184         -#if SQLITE_OS_WINCE || defined(_WIN32_WINNT)
          184  +#if SQLITE_OS_WINCE || SQLITE_OS_WINNT
   185    185   #  define SQLITE_WIN32_HAS_WIDE
   186    186   #endif
   187    187   
   188    188   #ifndef SYSCALL
   189    189   #  define SYSCALL sqlite3_syscall_ptr
   190    190   #endif
   191    191   

Changes to src/select.c.

  3841   3841         int onceAddr = 0;
  3842   3842         int retAddr;
  3843   3843         assert( pItem->addrFillSub==0 );
  3844   3844         pItem->regReturn = ++pParse->nMem;
  3845   3845         topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
  3846   3846         pItem->addrFillSub = topAddr+1;
  3847   3847         VdbeNoopComment((v, "materialize %s", pItem->pTab->zName));
  3848         -      if( pItem->isCorrelated==0 && pParse->pTriggerTab==0 ){
         3848  +      if( pItem->isCorrelated==0 ){
  3849   3849           /* If the subquery is no correlated and if we are not inside of
  3850   3850           ** a trigger, then we only need to compute the value of the subquery
  3851   3851           ** once. */
  3852         -        int regOnce = ++pParse->nMem;
  3853         -        onceAddr = sqlite3VdbeAddOp1(v, OP_Once, regOnce);
         3852  +        onceAddr = sqlite3CodeOnce(pParse);
  3854   3853         }
  3855   3854         sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
  3856   3855         explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
  3857   3856         sqlite3Select(pParse, pSub, &dest);
  3858   3857         pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
  3859   3858         if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
  3860   3859         retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
................................................................................
  4151   4150         pParse->nMem += pGroupBy->nExpr;
  4152   4151         iBMem = pParse->nMem + 1;
  4153   4152         pParse->nMem += pGroupBy->nExpr;
  4154   4153         sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag);
  4155   4154         VdbeComment((v, "clear abort flag"));
  4156   4155         sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
  4157   4156         VdbeComment((v, "indicate accumulator empty"));
         4157  +      sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1);
  4158   4158   
  4159   4159         /* Begin a loop that will extract all source rows in GROUP BY order.
  4160   4160         ** This might involve two separate loops with an OP_Sort in between, or
  4161   4161         ** it might be a single loop that uses an index to extract information
  4162   4162         ** in the right order to begin with.
  4163   4163         */
  4164   4164         sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);

Changes to src/sqliteInt.h.

  2200   2200     int aTempReg[8];     /* Holding area for temporary registers */
  2201   2201     int nRangeReg;       /* Size of the temporary register block */
  2202   2202     int iRangeReg;       /* First register in temporary register block */
  2203   2203     int nErr;            /* Number of errors seen */
  2204   2204     int nTab;            /* Number of previously allocated VDBE cursors */
  2205   2205     int nMem;            /* Number of memory cells used so far */
  2206   2206     int nSet;            /* Number of sets used so far */
         2207  +  int nOnce;           /* Number of OP_Once instructions so far */
  2207   2208     int ckBase;          /* Base register of data during check constraints */
  2208   2209     int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
  2209   2210     int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
  2210   2211     u8 nColCache;        /* Number of entries in aColCache[] */
  2211   2212     u8 iColCache;        /* Next entry in aColCache[] to replace */
  2212   2213     struct yColCache {
  2213   2214       int iTable;           /* Table cursor number */
................................................................................
  2711   2712   void sqlite3AddCheckConstraint(Parse*, Expr*);
  2712   2713   void sqlite3AddColumnType(Parse*,Token*);
  2713   2714   void sqlite3AddDefaultValue(Parse*,ExprSpan*);
  2714   2715   void sqlite3AddCollateType(Parse*, Token*);
  2715   2716   void sqlite3EndTable(Parse*,Token*,Token*,Select*);
  2716   2717   int sqlite3ParseUri(const char*,const char*,unsigned int*,
  2717   2718                       sqlite3_vfs**,char**,char **);
         2719  +int sqlite3CodeOnce(Parse *);
  2718   2720   
  2719   2721   Bitvec *sqlite3BitvecCreate(u32);
  2720   2722   int sqlite3BitvecTest(Bitvec*, u32);
  2721   2723   int sqlite3BitvecSet(Bitvec*, u32);
  2722   2724   void sqlite3BitvecClear(Bitvec*, u32, void*);
  2723   2725   void sqlite3BitvecDestroy(Bitvec*);
  2724   2726   u32 sqlite3BitvecSize(Bitvec*);

Changes to src/trigger.c.

   900    900   
   901    901       transferParseError(pParse, pSubParse);
   902    902       if( db->mallocFailed==0 ){
   903    903         pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
   904    904       }
   905    905       pProgram->nMem = pSubParse->nMem;
   906    906       pProgram->nCsr = pSubParse->nTab;
          907  +    pProgram->nOnce = pSubParse->nOnce;
   907    908       pProgram->token = (void *)pTrigger;
   908    909       pPrg->aColmask[0] = pSubParse->oldmask;
   909    910       pPrg->aColmask[1] = pSubParse->newmask;
   910    911       sqlite3VdbeDelete(v);
   911    912     }
   912    913   
   913    914     assert( !pSubParse->pAinc       && !pSubParse->pZombieTab );

Changes to src/update.c.

   122    122   #endif
   123    123     int newmask;           /* Mask of NEW.* columns accessed by BEFORE triggers */
   124    124   
   125    125     /* Register Allocations */
   126    126     int regRowCount = 0;   /* A count of rows changed */
   127    127     int regOldRowid;       /* The old rowid */
   128    128     int regNewRowid;       /* The new rowid */
   129         -  int regNew;
   130         -  int regOld = 0;
          129  +  int regNew;            /* Content of the NEW.* table in triggers */
          130  +  int regOld = 0;        /* Content of OLD.* table in triggers */
   131    131     int regRowSet = 0;     /* Rowset of rows to be updated */
   132    132   
   133    133     memset(&sContext, 0, sizeof(sContext));
   134    134     db = pParse->db;
   135    135     if( pParse->nErr || db->mallocFailed ){
   136    136       goto update_cleanup;
   137    137     }
................................................................................
   272    272       pWhere = 0;
   273    273       pTabList = 0;
   274    274       goto update_cleanup;
   275    275     }
   276    276   #endif
   277    277   
   278    278     /* Allocate required registers. */
          279  +  regRowSet = ++pParse->nMem;
   279    280     regOldRowid = regNewRowid = ++pParse->nMem;
   280    281     if( pTrigger || hasFK ){
   281    282       regOld = pParse->nMem + 1;
   282    283       pParse->nMem += pTab->nCol;
   283    284     }
   284    285     if( chngRowid || pTrigger || hasFK ){
   285    286       regNewRowid = ++pParse->nMem;
................................................................................
   306    307     */
   307    308     if( sqlite3ResolveExprNames(&sNC, pWhere) ){
   308    309       goto update_cleanup;
   309    310     }
   310    311   
   311    312     /* Begin the database scan
   312    313     */
   313         -  sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid);
          314  +  sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
   314    315     pWInfo = sqlite3WhereBegin(
   315    316         pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED
   316    317     );
   317    318     if( pWInfo==0 ) goto update_cleanup;
   318    319     okOnePass = pWInfo->okOnePass;
   319    320   
   320    321     /* Remember the rowid of every item to be updated.
   321    322     */
   322    323     sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regOldRowid);
   323    324     if( !okOnePass ){
   324         -    regRowSet = ++pParse->nMem;
   325    325       sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
   326    326     }
   327    327   
   328    328     /* End the database scan loop.
   329    329     */
   330    330     sqlite3WhereEnd(pWInfo);
   331    331   
................................................................................
   421    421     ** the database after the BEFORE triggers are fired anyway (as the trigger 
   422    422     ** may have modified them). So not loading those that are not going to
   423    423     ** be used eliminates some redundant opcodes.
   424    424     */
   425    425     newmask = sqlite3TriggerColmask(
   426    426         pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
   427    427     );
          428  +  sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);
   428    429     for(i=0; i<pTab->nCol; i++){
   429    430       if( i==pTab->iPKey ){
   430         -      sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
          431  +      /*sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);*/
   431    432       }else{
   432    433         j = aXRef[i];
   433    434         if( j>=0 ){
   434    435           sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
   435    436         }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask&(1<<i)) ){
   436    437           /* This branch loads the value of a column that will not be changed 
   437    438           ** into a register. This is done if there are no BEFORE triggers, or

Changes to src/vdbe.c.

   760    760   }
   761    761   
   762    762   /* Opcode:  Gosub P1 P2 * * *
   763    763   **
   764    764   ** Write the current address onto register P1
   765    765   ** and then jump to address P2.
   766    766   */
   767         -case OP_Gosub: {            /* jump, in1 */
          767  +case OP_Gosub: {            /* jump */
          768  +  assert( pOp->p1>0 && pOp->p1<=p->nMem );
   768    769     pIn1 = &aMem[pOp->p1];
   769    770     assert( (pIn1->flags & MEM_Dyn)==0 );
   770    771     memAboutToChange(p, pIn1);
   771    772     pIn1->flags = MEM_Int;
   772    773     pIn1->u.i = pc;
   773    774     REGISTER_TRACE(pOp->p1, pIn1);
   774    775     pc = pOp->p2 - 1;
................................................................................
   957    958     pOut->z = pOp->p4.z;
   958    959     pOut->n = pOp->p1;
   959    960     pOut->enc = encoding;
   960    961     UPDATE_MAX_BLOBSIZE(pOut);
   961    962     break;
   962    963   }
   963    964   
   964         -/* Opcode: Null * P2 * * *
          965  +/* Opcode: Null * P2 P3 * *
   965    966   **
   966         -** Write a NULL into register P2.
          967  +** Write a NULL into registers P2.  If P3 greater than P2, then also write
          968  +** NULL into register P3 and ever register in between P2 and P3.  If P3
          969  +** is less than P2 (typically P3 is zero) then only register P2 is
          970  +** set to NULL
   967    971   */
   968    972   case OP_Null: {           /* out2-prerelease */
          973  +  int cnt;
          974  +  cnt = pOp->p3-pOp->p2;
          975  +  assert( pOp->p3<=p->nMem );
   969    976     pOut->flags = MEM_Null;
          977  +  while( cnt>0 ){
          978  +    pOut++;
          979  +    memAboutToChange(p, pOut);
          980  +    MemReleaseExt(pOut);
          981  +    pOut->flags = MEM_Null;
          982  +    cnt--;
          983  +  }
   970    984     break;
   971    985   }
   972    986   
   973    987   
   974    988   /* Opcode: Blob P1 P2 * P4
   975    989   **
   976    990   ** P4 points to a blob of data P1 bytes long.  Store this
................................................................................
  2019   2033       sqlite3VdbeMemSetInt64(pOut, ~sqlite3VdbeIntValue(pIn1));
  2020   2034     }
  2021   2035     break;
  2022   2036   }
  2023   2037   
  2024   2038   /* Opcode: Once P1 P2 * * *
  2025   2039   **
  2026         -** Jump to P2 if the value in register P1 is a not null or zero.  If
  2027         -** the value is NULL or zero, fall through and change the P1 register
  2028         -** to an integer 1.
         2040  +** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
         2041  +** set the flag and fall through to the next instruction.
  2029   2042   **
  2030         -** When P1 is not used otherwise in a program, this opcode falls through
  2031         -** once and jumps on all subsequent invocations.  It is the equivalent
  2032         -** of "OP_If P1 P2", followed by "OP_Integer 1 P1".
         2043  +** See also: JumpOnce
  2033   2044   */
         2045  +case OP_Once: {             /* jump */
         2046  +  assert( pOp->p1<p->nOnceFlag );
         2047  +  if( p->aOnceFlag[pOp->p1] ){
         2048  +    pc = pOp->p2-1;
         2049  +  }else{
         2050  +    p->aOnceFlag[pOp->p1] = 1;
         2051  +  }
         2052  +  break;
         2053  +}
         2054  +
  2034   2055   /* Opcode: If P1 P2 P3 * *
  2035   2056   **
  2036   2057   ** Jump to P2 if the value in register P1 is true.  The value
  2037   2058   ** is considered true if it is numeric and non-zero.  If the value
  2038         -** in P1 is NULL then take the jump if P3 is true.
         2059  +** in P1 is NULL then take the jump if P3 is non-zero.
  2039   2060   */
  2040   2061   /* Opcode: IfNot P1 P2 P3 * *
  2041   2062   **
  2042   2063   ** Jump to P2 if the value in register P1 is False.  The value
  2043         -** is considered true if it has a numeric value of zero.  If the value
  2044         -** in P1 is NULL then take the jump if P3 is true.
         2064  +** is considered false if it has a numeric value of zero.  If the value
         2065  +** in P1 is NULL then take the jump if P3 is zero.
  2045   2066   */
  2046         -case OP_Once:               /* jump, in1 */
  2047   2067   case OP_If:                 /* jump, in1 */
  2048   2068   case OP_IfNot: {            /* jump, in1 */
  2049   2069     int c;
  2050   2070     pIn1 = &aMem[pOp->p1];
  2051   2071     if( pIn1->flags & MEM_Null ){
  2052   2072       c = pOp->p3;
  2053   2073     }else{
................................................................................
  2056   2076   #else
  2057   2077       c = sqlite3VdbeRealValue(pIn1)!=0.0;
  2058   2078   #endif
  2059   2079       if( pOp->opcode==OP_IfNot ) c = !c;
  2060   2080     }
  2061   2081     if( c ){
  2062   2082       pc = pOp->p2-1;
  2063         -  }else if( pOp->opcode==OP_Once ){
  2064         -    assert( (pIn1->flags & (MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))==0 );
  2065         -    memAboutToChange(p, pIn1);
  2066         -    pIn1->flags = MEM_Int;
  2067         -    pIn1->u.i = 1;
  2068         -    REGISTER_TRACE(pOp->p1, pIn1);
  2069   2083     }
  2070   2084     break;
  2071   2085   }
  2072   2086   
  2073   2087   /* Opcode: IsNull P1 P2 * * *
  2074   2088   **
  2075   2089   ** Jump to P2 if the value in register P1 is NULL.
................................................................................
  5067   5081     Mem *pEnd;              /* Last memory cell in new array */
  5068   5082     VdbeFrame *pFrame;      /* New vdbe frame to execute in */
  5069   5083     SubProgram *pProgram;   /* Sub-program to execute */
  5070   5084     void *t;                /* Token identifying trigger */
  5071   5085   
  5072   5086     pProgram = pOp->p4.pProgram;
  5073   5087     pRt = &aMem[pOp->p3];
  5074         -  assert( memIsValid(pRt) );
  5075   5088     assert( pProgram->nOp>0 );
  5076   5089     
  5077   5090     /* If the p5 flag is clear, then recursive invocation of triggers is 
  5078   5091     ** disabled for backwards compatibility (p5 is set if this sub-program
  5079   5092     ** is really a trigger, not a foreign key action, and the flag set
  5080   5093     ** and cleared by the "PRAGMA recursive_triggers" command is clear).
  5081   5094     ** 
................................................................................
  5106   5119       ** program stored in SubProgram.aOp. As well as these, one memory
  5107   5120       ** cell is required for each cursor used by the program. Set local
  5108   5121       ** variable nMem (and later, VdbeFrame.nChildMem) to this value.
  5109   5122       */
  5110   5123       nMem = pProgram->nMem + pProgram->nCsr;
  5111   5124       nByte = ROUND8(sizeof(VdbeFrame))
  5112   5125                 + nMem * sizeof(Mem)
  5113         -              + pProgram->nCsr * sizeof(VdbeCursor *);
         5126  +              + pProgram->nCsr * sizeof(VdbeCursor *)
         5127  +              + pProgram->nOnce * sizeof(u8);
  5114   5128       pFrame = sqlite3DbMallocZero(db, nByte);
  5115   5129       if( !pFrame ){
  5116   5130         goto no_mem;
  5117   5131       }
  5118   5132       sqlite3VdbeMemRelease(pRt);
  5119   5133       pRt->flags = MEM_Frame;
  5120   5134       pRt->u.pFrame = pFrame;
................................................................................
  5126   5140       pFrame->aMem = p->aMem;
  5127   5141       pFrame->nMem = p->nMem;
  5128   5142       pFrame->apCsr = p->apCsr;
  5129   5143       pFrame->nCursor = p->nCursor;
  5130   5144       pFrame->aOp = p->aOp;
  5131   5145       pFrame->nOp = p->nOp;
  5132   5146       pFrame->token = pProgram->token;
         5147  +    pFrame->aOnceFlag = p->aOnceFlag;
         5148  +    pFrame->nOnceFlag = p->nOnceFlag;
  5133   5149   
  5134   5150       pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
  5135   5151       for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
  5136         -      pMem->flags = MEM_Null;
         5152  +      pMem->flags = MEM_Invalid;
  5137   5153         pMem->db = db;
  5138   5154       }
  5139   5155     }else{
  5140   5156       pFrame = pRt->u.pFrame;
  5141   5157       assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
  5142   5158       assert( pProgram->nCsr==pFrame->nChildCsr );
  5143   5159       assert( pc==pFrame->pc );
................................................................................
  5151   5167     p->pFrame = pFrame;
  5152   5168     p->aMem = aMem = &VdbeFrameMem(pFrame)[-1];
  5153   5169     p->nMem = pFrame->nChildMem;
  5154   5170     p->nCursor = (u16)pFrame->nChildCsr;
  5155   5171     p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
  5156   5172     p->aOp = aOp = pProgram->aOp;
  5157   5173     p->nOp = pProgram->nOp;
         5174  +  p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
         5175  +  p->nOnceFlag = pProgram->nOnce;
         5176  +  p->nOp = pProgram->nOp;
  5158   5177     pc = -1;
         5178  +  memset(p->aOnceFlag, 0, p->nOnceFlag);
  5159   5179   
  5160   5180     break;
  5161   5181   }
  5162   5182   
  5163   5183   /* Opcode: Param P1 P2 * * *
  5164   5184   **
  5165   5185   ** This opcode is only ever present in sub-programs called via the 

Changes to src/vdbe.h.

    78     78   ** A sub-routine used to implement a trigger program.
    79     79   */
    80     80   struct SubProgram {
    81     81     VdbeOp *aOp;                  /* Array of opcodes for sub-program */
    82     82     int nOp;                      /* Elements in aOp[] */
    83     83     int nMem;                     /* Number of memory cells required */
    84     84     int nCsr;                     /* Number of cursors required */
           85  +  int nOnce;                    /* Number of OP_Once instructions */
    85     86     void *token;                  /* id that may be used to recursive triggers */
    86     87     SubProgram *pNext;            /* Next sub-program already visited */
    87     88   };
    88     89   
    89     90   /*
    90     91   ** A smaller version of VdbeOp used for the VdbeAddOpList() function because
    91     92   ** it takes up less space.

Changes to src/vdbeInt.h.

   116    116   struct VdbeFrame {
   117    117     Vdbe *v;                /* VM this frame belongs to */
   118    118     int pc;                 /* Program Counter in parent (calling) frame */
   119    119     Op *aOp;                /* Program instructions for parent frame */
   120    120     int nOp;                /* Size of aOp array */
   121    121     Mem *aMem;              /* Array of memory cells for parent frame */
   122    122     int nMem;               /* Number of entries in aMem */
          123  +  u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
          124  +  int nOnceFlag;          /* Number of entries in aOnceFlag */
   123    125     VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
   124    126     u16 nCursor;            /* Number of entries in apCsr */
   125    127     void *token;            /* Copy of SubProgram.token */
   126    128     int nChildMem;          /* Number of memory cells for child frame */
   127    129     int nChildCsr;          /* Number of cursors for child frame */
   128    130     i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
   129    131     int nChange;            /* Statement changes (Vdbe.nChanges)     */
................................................................................
   339    341     char *zExplain;         /* Explanation of data structures */
   340    342   #endif
   341    343     VdbeFrame *pFrame;      /* Parent frame */
   342    344     VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
   343    345     int nFrame;             /* Number of frames in pFrame list */
   344    346     u32 expmask;            /* Binding to these vars invalidates VM */
   345    347     SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
          348  +  int nOnceFlag;          /* Size of array aOnceFlag[] */
          349  +  u8 *aOnceFlag;          /* Flags for OP_Once */
   346    350   };
   347    351   
   348    352   /*
   349    353   ** The following are allowed values for Vdbe.magic
   350    354   */
   351    355   #define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
   352    356   #define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */

Changes to src/vdbeaux.c.

   909    909       }
   910    910       case P4_REAL: {
   911    911         sqlite3_snprintf(nTemp, zTemp, "%.16g", *pOp->p4.pReal);
   912    912         break;
   913    913       }
   914    914       case P4_MEM: {
   915    915         Mem *pMem = pOp->p4.pMem;
   916         -      assert( (pMem->flags & MEM_Null)==0 );
   917    916         if( pMem->flags & MEM_Str ){
   918    917           zP4 = pMem->z;
   919    918         }else if( pMem->flags & MEM_Int ){
   920    919           sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
   921    920         }else if( pMem->flags & MEM_Real ){
   922    921           sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r);
          922  +      }else if( pMem->flags & MEM_Null ){
          923  +        sqlite3_snprintf(nTemp, zTemp, "NULL");
   923    924         }else{
   924    925           assert( pMem->flags & MEM_Blob );
   925    926           zP4 = "(blob)";
   926    927         }
   927    928         break;
   928    929       }
   929    930   #ifndef SQLITE_OMIT_VIRTUALTABLE
................................................................................
  1090   1091         if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
  1091   1092           sqlite3VdbeMemRelease(p);
  1092   1093         }else if( p->zMalloc ){
  1093   1094           sqlite3DbFree(db, p->zMalloc);
  1094   1095           p->zMalloc = 0;
  1095   1096         }
  1096   1097   
  1097         -      p->flags = MEM_Null;
         1098  +      p->flags = MEM_Invalid;
  1098   1099       }
  1099   1100       db->mallocFailed = malloc_failed;
  1100   1101     }
  1101   1102   }
  1102   1103   
  1103   1104   /*
  1104   1105   ** Delete a VdbeFrame object and its contents. VdbeFrame objects are
................................................................................
  1465   1466     Parse *pParse                  /* Parsing context */
  1466   1467   ){
  1467   1468     sqlite3 *db;                   /* The database connection */
  1468   1469     int nVar;                      /* Number of parameters */
  1469   1470     int nMem;                      /* Number of VM memory registers */
  1470   1471     int nCursor;                   /* Number of cursors required */
  1471   1472     int nArg;                      /* Number of arguments in subprograms */
         1473  +  int nOnce;                     /* Number of OP_Once instructions */
  1472   1474     int n;                         /* Loop counter */
  1473   1475     u8 *zCsr;                      /* Memory available for allocation */
  1474   1476     u8 *zEnd;                      /* First byte past allocated memory */
  1475   1477     int nByte;                     /* How much extra memory is needed */
  1476   1478   
  1477   1479     assert( p!=0 );
  1478   1480     assert( p->nOp>0 );
................................................................................
  1480   1482     assert( p->magic==VDBE_MAGIC_INIT );
  1481   1483     db = p->db;
  1482   1484     assert( db->mallocFailed==0 );
  1483   1485     nVar = pParse->nVar;
  1484   1486     nMem = pParse->nMem;
  1485   1487     nCursor = pParse->nTab;
  1486   1488     nArg = pParse->nMaxArg;
         1489  +  nOnce = pParse->nOnce;
  1487   1490     
  1488   1491     /* For each cursor required, also allocate a memory cell. Memory
  1489   1492     ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
  1490   1493     ** the vdbe program. Instead they are used to allocate space for
  1491   1494     ** VdbeCursor/BtCursor structures. The blob of memory associated with 
  1492   1495     ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
  1493   1496     ** stores the blob of memory associated with cursor 1, etc.
................................................................................
  1526   1529       nByte = 0;
  1527   1530       p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
  1528   1531       p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
  1529   1532       p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
  1530   1533       p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
  1531   1534       p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
  1532   1535                             &zCsr, zEnd, &nByte);
         1536  +    p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte);
  1533   1537       if( nByte ){
  1534   1538         p->pFree = sqlite3DbMallocZero(db, nByte);
  1535   1539       }
  1536   1540       zCsr = p->pFree;
  1537   1541       zEnd = &zCsr[nByte];
  1538   1542     }while( nByte && !db->mallocFailed );
  1539   1543   
  1540   1544     p->nCursor = (u16)nCursor;
         1545  +  p->nOnceFlag = nOnce;
  1541   1546     if( p->aVar ){
  1542   1547       p->nVar = (ynVar)nVar;
  1543   1548       for(n=0; n<nVar; n++){
  1544   1549         p->aVar[n].flags = MEM_Null;
  1545   1550         p->aVar[n].db = db;
  1546   1551       }
  1547   1552     }
................................................................................
  1550   1555       memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0]));
  1551   1556       memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0]));
  1552   1557     }
  1553   1558     if( p->aMem ){
  1554   1559       p->aMem--;                      /* aMem[] goes from 1..nMem */
  1555   1560       p->nMem = nMem;                 /*       not from 0..nMem-1 */
  1556   1561       for(n=1; n<=nMem; n++){
  1557         -      p->aMem[n].flags = MEM_Null;
         1562  +      p->aMem[n].flags = MEM_Invalid;
  1558   1563         p->aMem[n].db = db;
  1559   1564       }
  1560   1565     }
  1561   1566     p->explain = pParse->explain;
  1562   1567     sqlite3VdbeRewind(p);
  1563   1568   }
  1564   1569   
................................................................................
  1592   1597   /*
  1593   1598   ** Copy the values stored in the VdbeFrame structure to its Vdbe. This
  1594   1599   ** is used, for example, when a trigger sub-program is halted to restore
  1595   1600   ** control to the main program.
  1596   1601   */
  1597   1602   int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
  1598   1603     Vdbe *v = pFrame->v;
         1604  +  v->aOnceFlag = pFrame->aOnceFlag;
         1605  +  v->nOnceFlag = pFrame->nOnceFlag;
  1599   1606     v->aOp = pFrame->aOp;
  1600   1607     v->nOp = pFrame->nOp;
  1601   1608     v->aMem = pFrame->aMem;
  1602   1609     v->nMem = pFrame->nMem;
  1603   1610     v->apCsr = pFrame->apCsr;
  1604   1611     v->nCursor = pFrame->nCursor;
  1605   1612     v->db->lastRowid = pFrame->lastRowid;
................................................................................
  1654   1661   static void Cleanup(Vdbe *p){
  1655   1662     sqlite3 *db = p->db;
  1656   1663   
  1657   1664   #ifdef SQLITE_DEBUG
  1658   1665     /* Execute assert() statements to ensure that the Vdbe.apCsr[] and 
  1659   1666     ** Vdbe.aMem[] arrays have already been cleaned up.  */
  1660   1667     int i;
  1661         -  for(i=0; i<p->nCursor; i++) assert( p->apCsr==0 || p->apCsr[i]==0 );
  1662         -  for(i=1; i<=p->nMem; i++) assert( p->aMem==0 || p->aMem[i].flags==MEM_Null );
         1668  +  if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
         1669  +  if( p->aMem ){
         1670  +    for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Invalid );
         1671  +  }
  1663   1672   #endif
  1664   1673   
  1665   1674     sqlite3DbFree(db, p->zErrMsg);
  1666   1675     p->zErrMsg = 0;
  1667   1676     p->pResultSet = 0;
  1668   1677   }
  1669   1678   
................................................................................
  2123   2132     ** state.  We need to rollback the statement transaction, if there is
  2124   2133     ** one, or the complete transaction if there is no statement transaction.
  2125   2134     */
  2126   2135   
  2127   2136     if( p->db->mallocFailed ){
  2128   2137       p->rc = SQLITE_NOMEM;
  2129   2138     }
         2139  +  if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag);
  2130   2140     closeAllCursors(p);
  2131   2141     if( p->magic!=VDBE_MAGIC_RUN ){
  2132   2142       return SQLITE_OK;
  2133   2143     }
  2134   2144     checkActiveVdbeCnt(db);
  2135   2145   
  2136   2146     /* No commit or rollback needed if the program never started */

Changes to src/wal.c.

  1776   1776       }
  1777   1777     }
  1778   1778   
  1779   1779    walcheckpoint_out:
  1780   1780     walIteratorFree(pIter);
  1781   1781     return rc;
  1782   1782   }
         1783  +
         1784  +/*
         1785  +** Attempt to limit the WAL size to the size limit defined by
         1786  +** PRAGMA journal_size_limit.
         1787  +*/
         1788  +static void walLimitSize(Wal *pWal){
         1789  +  if( pWal->mxWalSize>=0 ){
         1790  +    i64 sz;
         1791  +    int rx;
         1792  +    sqlite3BeginBenignMalloc();
         1793  +    rx = sqlite3OsFileSize(pWal->pWalFd, &sz);
         1794  +    if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){
         1795  +      rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize);
         1796  +    }
         1797  +    sqlite3EndBenignMalloc();
         1798  +    if( rx ){
         1799  +      sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
         1800  +    }
         1801  +  }
         1802  +}
  1783   1803   
  1784   1804   /*
  1785   1805   ** Close a connection to a log file.
  1786   1806   */
  1787   1807   int sqlite3WalClose(
  1788   1808     Wal *pWal,                      /* Wal to close */
  1789   1809     int sync_flags,                 /* Flags to pass to OsSync() (or 0) */
................................................................................
  1810   1830         }
  1811   1831         rc = sqlite3WalCheckpoint(
  1812   1832             pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
  1813   1833         );
  1814   1834         sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersistWal);
  1815   1835         if( rc==SQLITE_OK && bPersistWal!=1 ){
  1816   1836           isDelete = 1;
         1837  +      }else{
         1838  +        walLimitSize(pWal);
  1817   1839         }
  1818   1840       }
  1819   1841   
  1820   1842       walIndexClose(pWal, isDelete);
  1821   1843       sqlite3OsClose(pWal->pWalFd);
  1822   1844       if( isDelete ){
  1823   1845         sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0);
................................................................................
  2513   2535       pWal->hdr.aFrameCksum[0] = aWalData[1];
  2514   2536       pWal->hdr.aFrameCksum[1] = aWalData[2];
  2515   2537       walCleanupHash(pWal);
  2516   2538     }
  2517   2539   
  2518   2540     return rc;
  2519   2541   }
         2542  +
  2520   2543   
  2521   2544   /*
  2522   2545   ** This function is called just before writing a set of frames to the log
  2523   2546   ** file (see sqlite3WalFrames()). It checks to see if, instead of appending
  2524   2547   ** to the current log file, it is possible to overwrite the start of the
  2525   2548   ** existing log file with the new frames (i.e. "reset" the log). If so,
  2526   2549   ** it sets pWal->hdr.mxFrame to 0. Otherwise, pWal->hdr.mxFrame is left
................................................................................
  2551   2574           ** at this point. But updating the actual wal-index header is also
  2552   2575           ** safe and means there is no special case for sqlite3WalUndo()
  2553   2576           ** to handle if this transaction is rolled back.
  2554   2577           */
  2555   2578           int i;                    /* Loop counter */
  2556   2579           u32 *aSalt = pWal->hdr.aSalt;       /* Big-endian salt values */
  2557   2580   
  2558         -        /* Limit the size of WAL file if the journal_size_limit PRAGMA is
  2559         -        ** set to a non-negative value.  Log errors encountered
  2560         -        ** during the truncation attempt. */
  2561         -        if( pWal->mxWalSize>=0 ){
  2562         -          i64 sz;
  2563         -          int rx;
  2564         -          sqlite3BeginBenignMalloc();
  2565         -          rx = sqlite3OsFileSize(pWal->pWalFd, &sz);
  2566         -          if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){
  2567         -            rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize);
  2568         -          }
  2569         -          sqlite3EndBenignMalloc();
  2570         -          if( rx ){
  2571         -            sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
  2572         -          }
  2573         -        }
  2574         -
         2581  +        walLimitSize(pWal);
  2575   2582           pWal->nCkpt++;
  2576   2583           pWal->hdr.mxFrame = 0;
  2577   2584           sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
  2578   2585           aSalt[1] = salt1;
  2579   2586           walIndexWriteHdr(pWal);
  2580   2587           pInfo->nBackfill = 0;
  2581   2588           for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;

Changes to src/where.c.

  2001   2001   ){
  2002   2002     int nColumn;                /* Number of columns in the constructed index */
  2003   2003     WhereTerm *pTerm;           /* A single term of the WHERE clause */
  2004   2004     WhereTerm *pWCEnd;          /* End of pWC->a[] */
  2005   2005     int nByte;                  /* Byte of memory needed for pIdx */
  2006   2006     Index *pIdx;                /* Object describing the transient index */
  2007   2007     Vdbe *v;                    /* Prepared statement under construction */
  2008         -  int regIsInit;              /* Register set by initialization */
  2009   2008     int addrInit;               /* Address of the initialization bypass jump */
  2010   2009     Table *pTable;              /* The table being indexed */
  2011   2010     KeyInfo *pKeyinfo;          /* Key information for the index */   
  2012   2011     int addrTop;                /* Top of the index fill loop */
  2013   2012     int regRecord;              /* Register holding an index record */
  2014   2013     int n;                      /* Column counter */
  2015   2014     int i;                      /* Loop counter */
................................................................................
  2018   2017     Bitmask idxCols;            /* Bitmap of columns used for indexing */
  2019   2018     Bitmask extraCols;          /* Bitmap of additional columns */
  2020   2019   
  2021   2020     /* Generate code to skip over the creation and initialization of the
  2022   2021     ** transient index on 2nd and subsequent iterations of the loop. */
  2023   2022     v = pParse->pVdbe;
  2024   2023     assert( v!=0 );
  2025         -  regIsInit = ++pParse->nMem;
  2026         -  addrInit = sqlite3VdbeAddOp1(v, OP_Once, regIsInit);
         2024  +  addrInit = sqlite3CodeOnce(pParse);
  2027   2025   
  2028   2026     /* Count the number of columns that will be added to the index
  2029   2027     ** and used to match WHERE clause constraints */
  2030   2028     nColumn = 0;
  2031   2029     pTable = pSrc->pTab;
  2032   2030     pWCEnd = &pWC->a[pWC->nTerm];
  2033   2031     idxCols = 0;

Added test/tkt-7bbfb7d442.test.

            1  +# 2011 December 9
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.
           12  +#
           13  +# This file implements tests to verify that ticket [7bbfb7d442] has been
           14  +# fixed.  
           15  +#
           16  +
           17  +set testdir [file dirname $argv0]
           18  +source $testdir/tester.tcl
           19  +set testprefix tkt-7bbfb7d442
           20  +
           21  +do_execsql_test 1.1 {
           22  +  CREATE TABLE t1(a, b);
           23  +  INSERT INTO t1 VALUES(1, 'one');
           24  +  INSERT INTO t1 VALUES(2, 'two');
           25  +  INSERT INTO t1 VALUES(3, 'three');
           26  +
           27  +  CREATE TABLE t2(c, d);
           28  +  INSERT INTO t2 VALUES('one', 'I');
           29  +  INSERT INTO t2 VALUES('two', 'II');
           30  +  INSERT INTO t2 VALUES('three', 'III');
           31  +
           32  +  CREATE TABLE t3(t3_a PRIMARY KEY, t3_d);
           33  +  CREATE TRIGGER t3t AFTER INSERT ON t3 WHEN new.t3_d IS NULL BEGIN
           34  +    UPDATE t3 SET t3_d = (
           35  +      SELECT d FROM 
           36  +        (SELECT * FROM t2 WHERE (new.t3_a%2)=(rowid%2) LIMIT 10),
           37  +        (SELECT * FROM t1 WHERE (new.t3_a%2)=(rowid%2) LIMIT 10)
           38  +      WHERE a = new.t3_a AND b = c
           39  +    ) WHERE t3_a = new.t3_a;
           40  +  END;
           41  +}
           42  +
           43  +do_execsql_test 1.2 {
           44  +  INSERT INTO t3(t3_a) VALUES(1);
           45  +  INSERT INTO t3(t3_a) VALUES(2);
           46  +  INSERT INTO t3(t3_a) VALUES(3);
           47  +  SELECT * FROM t3;
           48  +} {1 I 2 II 3 III}
           49  +
           50  +do_execsql_test 1.3 { DELETE FROM t3 }
           51  +
           52  +do_execsql_test 1.4 {
           53  +  INSERT INTO t3(t3_a) SELECT 1 UNION SELECT 2 UNION SELECT 3;
           54  +  SELECT * FROM t3;
           55  +} {1 I 2 II 3 III}
           56  +
           57  +
           58  +
           59  +#-------------------------------------------------------------------------
           60  +# The following test case - 2.* - is from the original bug report as 
           61  +# posted to the mailing list.
           62  +#
           63  +do_execsql_test 2.1 {
           64  +  CREATE TABLE InventoryControl (
           65  +    InventoryControlId INTEGER PRIMARY KEY AUTOINCREMENT,
           66  +    SKU INTEGER NOT NULL,
           67  +    Variant INTEGER NOT NULL DEFAULT 0,
           68  +    ControlDate DATE NOT NULL,
           69  +    ControlState INTEGER NOT NULL DEFAULT -1,
           70  +    DeliveredQty VARCHAR(30)
           71  +  );
           72  +  
           73  +  CREATE TRIGGER TGR_InventoryControl_AfterInsert
           74  +  AFTER INSERT ON InventoryControl 
           75  +  FOR EACH ROW WHEN NEW.ControlState=-1 BEGIN 
           76  +
           77  +  INSERT OR REPLACE INTO InventoryControl(
           78  +        InventoryControlId,SKU,Variant,ControlDate,ControlState,DeliveredQty
           79  +  ) SELECT
           80  +          T1.InventoryControlId AS InventoryControlId,
           81  +          T1.SKU AS SKU,
           82  +          T1.Variant AS Variant,
           83  +          T1.ControlDate AS ControlDate,
           84  +          1 AS ControlState,
           85  +          COALESCE(T2.DeliveredQty,0) AS DeliveredQty
           86  +      FROM (
           87  +          SELECT
           88  +              NEW.InventoryControlId AS InventoryControlId,
           89  +              II.SKU AS SKU,
           90  +              II.Variant AS Variant,
           91  +              COALESCE(LastClosedIC.ControlDate,NEW.ControlDate) AS ControlDate
           92  +          FROM
           93  +              InventoryItem II
           94  +          LEFT JOIN
           95  +              InventoryControl LastClosedIC
           96  +              ON  LastClosedIC.InventoryControlId IN ( SELECT 99999 )
           97  +          WHERE
           98  +              II.SKU=NEW.SKU AND
           99  +              II.Variant=NEW.Variant
          100  +      )   T1
          101  +      LEFT JOIN (
          102  +          SELECT
          103  +              TD.SKU AS SKU,
          104  +              TD.Variant AS Variant,
          105  +              10 AS DeliveredQty
          106  +          FROM
          107  +              TransactionDetail TD
          108  +          WHERE
          109  +              TD.SKU=NEW.SKU AND
          110  +              TD.Variant=NEW.Variant
          111  +      )   T2
          112  +      ON  T2.SKU=T1.SKU AND
          113  +          T2.Variant=T1.Variant;
          114  +  END;
          115  +  
          116  +  CREATE TABLE InventoryItem (
          117  +    SKU INTEGER NOT NULL,
          118  +    Variant INTEGER NOT NULL DEFAULT 0,
          119  +    DeptCode INTEGER NOT NULL,
          120  +    GroupCode INTEGER NOT NULL,
          121  +    ItemDescription VARCHAR(120) NOT NULL,
          122  +    PRIMARY KEY(SKU, Variant)
          123  +  );
          124  +  
          125  +  INSERT INTO InventoryItem VALUES(220,0,1,170,'Scoth Tampon Recurer');
          126  +  INSERT INTO InventoryItem VALUES(31,0,1,110,'Fromage');
          127  +  
          128  +  CREATE TABLE TransactionDetail (
          129  +    TransactionId INTEGER NOT NULL,
          130  +    SKU INTEGER NOT NULL,
          131  +    Variant INTEGER NOT NULL DEFAULT 0,
          132  +    PRIMARY KEY(TransactionId, SKU, Variant)
          133  +  );
          134  +  INSERT INTO TransactionDetail(TransactionId, SKU, Variant) VALUES(44, 31, 0);
          135  +  
          136  +  
          137  +  INSERT INTO InventoryControl(SKU, Variant, ControlDate) SELECT 
          138  +      II.SKU AS SKU, II.Variant AS Variant, '2011-08-30' AS ControlDate 
          139  +      FROM InventoryItem II;
          140  +}
          141  +
          142  +do_execsql_test 2.2 {
          143  +  SELECT SKU, DeliveredQty FROM InventoryControl WHERE SKU=31
          144  +} {31 10}
          145  +
          146  +do_execsql_test 2.3 {
          147  +  SELECT CASE WHEN DeliveredQty=10 THEN "TEST PASSED!" ELSE "TEST FAILED!" END 
          148  +  FROM InventoryControl WHERE SKU=31; 
          149  +} {{TEST PASSED!}}
          150  +
          151  +
          152  +finish_test
          153  +
          154  +

Changes to test/walpersist.test.

    63     63     file_control_persist_wal db 1
    64     64   } {0 1}
    65     65   do_test walpersist-1.11 {
    66     66     db close
    67     67     list [file exists test.db] [file exists test.db-wal] [file exists test.db-shm]
    68     68   } {1 1 1}
    69     69   
    70         -  
    71         -
           70  +# Make sure the journal_size_limit works to limit the size of the
           71  +# persisted wal file.
           72  +forcedelete test.db test.db-shm test.db-wal
           73  +do_test walpersist-2.1 {
           74  +  sqlite3 db test.db
           75  +  db eval {
           76  +    PRAGMA journal_mode=WAL;
           77  +    PRAGMA wal_autocheckpoint=OFF;
           78  +    PRAGMA journal_size_limit=12000;
           79  +    CREATE TABLE t1(x);
           80  +    INSERT INTO t1 VALUES(randomblob(50000));
           81  +    UPDATE t1 SET x=randomblob(50000);
           82  +  }
           83  +  expr {[file size test.db-wal]>100000}
           84  +} {1}
           85  +do_test walpersist-2.2 {
           86  +  file_control_persist_wal db 1
           87  +  db close
           88  +  file size test.db-wal
           89  +} {12000}
    72     90   
    73     91   finish_test